'use strict'; Ox.Chart = function(options, self) { self = self || {}; var that = Ox.Element({}, self) .defaults({ color: [128, 128, 128], data: {}, formatKey: null, keyAlign: 'right', keyWidth: 128, rows: 1, sort: {key: 'value', operator: '-'}, title: '', width: 512 }) .options(options || {}) .addClass('OxChart') .css({ width: self.options.width + 'px', height: 16 + Ox.len(self.options.data) * 16 + 'px', overflowY: 'hidden' }); self.sort = {}; Ox.forEach(self.options.data, function(value, key) { self.sort[key] = key.replace(/(\d+)/g, function(number) { return Ox.pad(number, 16); }); }); self.keys = Object.keys(self.options.data); self.items = self.keys.map(function(key) { return {key: key, value: self.options.data[key]}; }) .sort(function(a, b) { var key = self.options.sort.key, aValue = key == 'key' ? self.sort[a.key] : a.value, bValue = key == 'key' ? self.sort[b.key] : b.value; return aValue < bValue ? (self.options.sort.operator == '+' ? -1 : 1) : aValue > bValue ? (self.options.sort.operator == '+' ? 1 : -1) : self.sort[a.key] < self.sort[b.key] ? -1 : self.sort[a.key] > self.sort[b.key] ? 1 : 0; }); self.values = self.items.map(function(item) { return item.value; }); self.max = Ox.max(self.values); self.sum = Ox.sum(self.values); self.valueWidth = self.options.width - self.options.keyWidth; self.$title = Ox.Bar({size: 16}) .append( $('
') .css({margin: '1px 0 0 4px'}) .html(self.options.title) ) .appendTo(that); self.$chart = $('
') .css({position: 'absolute', top: '16px'}) .append(renderChart()) .appendTo(that); function getColumns() { return [ { align: self.options.keyAlign, format: self.options.formatKey, id: 'key', width: self.options.keyWidth, visible: true, }, { format: renderValue, id: 'value', width: self.valueWidth, visible: true } ]; } function renderChart() { return Ox.TextList({ columns: getColumns(), items: self.items, max: 0, min: 0, pageLength: self.items.length, sort: [self.options.sort], width: self.options.width }) .css({ left: 0, top: 0, width: self.options.width + 'px', height: self.items.length * 16 + 'px' }); } function renderValue(value, data) { var color = Ox.isFunction(self.options.color) ? self.options.color(data.key) : self.options.color, $element = Ox.Element({ element: '
', tooltip: Ox.formatNumber(value) + ' (' + Ox.formatPercent(value * self.options.rows, self.sum, 2) + ')' }) .css({ width: Math.round(value / self.max * self.valueWidth) + 'px', height: '14px', borderRadius: '4px', marginLeft: '-4px', }); ['moz', 'o', 'webkit'].forEach(function(browser) { $element.css({ backgroundImage: '-' + browser + '-linear-gradient(top, rgb(' + color.map(function(v) { return Ox.limit(v + 16, 0, 255); }).join(', ') + '), rgb(' + color.map(function(v) { return Ox.limit(v - 16, 0, 255); }) + '))' }); }); return $element; } self.setOption = function(key, value) { if (key == 'width') { self.$chart.empty(); renderChart(); } } return that; };