add chart widget
This commit is contained in:
parent
ebc9fc3fd7
commit
2dbe98bb98
1 changed files with 138 additions and 0 deletions
138
source/Ox.UI/js/List/Ox.Chart.js
Normal file
138
source/Ox.UI/js/List/Ox.Chart.js
Normal 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;
|
||||||
|
|
||||||
|
};
|
Loading…
Reference in a new issue