From 2dbe98bb98dc8b7b1e4a927d1c99f88c4836b469 Mon Sep 17 00:00:00 2001 From: rlx <0x0073@0x2620.org> Date: Thu, 22 Mar 2012 20:04:35 +0000 Subject: [PATCH] add chart widget --- source/Ox.UI/js/List/Ox.Chart.js | 138 +++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 source/Ox.UI/js/List/Ox.Chart.js diff --git a/source/Ox.UI/js/List/Ox.Chart.js b/source/Ox.UI/js/List/Ox.Chart.js new file mode 100644 index 00000000..7b202654 --- /dev/null +++ b/source/Ox.UI/js/List/Ox.Chart.js @@ -0,0 +1,138 @@ +'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; + +};