add chart widget

This commit is contained in:
rlx 2012-03-22 20:04:35 +00:00
parent ebc9fc3fd7
commit 2dbe98bb98

View file

@ -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(
$('<div>')
.css({margin: '1px 0 0 4px'})
.html(self.options.title)
)
.appendTo(that);
self.$chart = $('<div>')
.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: '<div>',
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;
};