extjs-gpl
Version:
GPL licensed version of Sencha Ext JS
222 lines (214 loc) • 8.63 kB
JavaScript
/**
* Demonstrates how to use Ext.chart.ColumnChart with a renderer function
*/
Ext.define('KitchenSink.view.chart.ColumnWithRenderer', {
extend: 'Ext.Panel',
requires: [
'Ext.chart.CartesianChart',
'Ext.chart.series.Line',
'Ext.chart.axis.Numeric',
'Ext.draw.modifier.Highlight',
'Ext.chart.axis.Time',
'Ext.chart.interactions.ItemHighlight'
],
controller: 'renderer',
// <example>
otherContent: [{
type: 'Controller',
path: 'modern/src/view/chart/RendererController.js'
}, {
type: 'Store',
path: 'modern/src/store/Pie.js'
}],
// </example>
layout: 'fit',
shadow: true,
items: [{
xtype: 'toolbar',
docked: 'top',
cls: 'charttoolbar',
items: [{
xtype: 'spacer'
}, {
iconCls: 'x-fa fa-refresh',
text: 'Refresh',
handler: 'onRefresh'
}]
}, {
xtype: 'cartesian',
reference: 'chart',
store: {
type: 'pie',
numRecords: 10
},
background: 'white',
series: [{
type: 'bar',
xField: 'name',
yField: ['g1'],
style: {
lineWidth: 2,
maxBarWidth: 30,
stroke: 'dodgerblue',
fill: 'palegreen',
opacity: 0.6
},
renderer: function(sprite, config, rendererData, index) {
var store = rendererData.store,
storeItems = store.getData().items,
record = storeItems[index],
diff = record && (record.data['g2'] - record.data['g1']),
last = storeItems.length - 1,
surface = sprite.getParent(),
changes = {},
lineSprites, firstColumnConfig, firstData, lastData, growth, string;
if (!record) {
return;
}
// This renderer function paints the back column red instead
// of palegreen if series #2 is greater than series #1.
changes.fillStyle = (diff > 0 ? 'tomato' : 'palegreen');
// Make the first and last columns larger.
if (index == 0 || index == last) {
changes.x = config.x - config.width * 0.4;
changes.y = config.y;
changes.width = config.width * 1.8;
changes.lineWidth = 4;
// Draw a line between the first and last columns
lineSprites = surface.myLineSprites;
if (!lineSprites) {
lineSprites = surface.myLineSprites = [];
lineSprites[0] = surface.add({
type: 'path'
});
lineSprites[1] = surface.add({
type: 'text'
});
}
if (index == 0) {
surface.myFirstColumnConfig = Ext.clone(changes);
} else if (index == last) {
firstData = storeItems[0].data['g1'];
lastData = storeItems[last].data['g1'];
firstColumnConfig = surface.myFirstColumnConfig;
var x1 = firstColumnConfig.x + firstColumnConfig.width,
y1 = firstColumnConfig.y,
x2 = changes.x,
y2 = changes.y;
lineSprites[0].setAttributes({
lineWidth: 1,
stroke: 'blue',
zIndex: 10000,
opacity: 0.4,
path: "M" + x2 + " " + y2 + " L" + x1 + " " + y1 + " L" + x2 + " " + y1 + (lastData < firstData ? " L" : " M") + x2 + " " + y2 + " Z"
});
growth = Math.round(100 * (lastData - firstData) / (firstData || 1));
string = (growth > 0 ? "+ " : "- ") + Math.abs(growth) + " %";
lineSprites[1].setAttributes({
text: string,
x: changes.x - 12,
y: firstColumnConfig.y + (changes.y - firstColumnConfig.y) / 2 + 10,
fill: '#00c',
fontSize: 20,
zIndex: 10000,
opacity: 0.6,
scalingY: -1,
textAlign: "center",
rotate: -90
});
}
} else {
changes.lineWidth = 2;
}
return changes;
}
}, {
type: 'bar',
xField: 'name',
yField: ['g2'],
style: {
lineWidth: 2,
maxBarWidth: 12,
stroke: 'tomato',
fill: 'lightyellow',
radius: 20
},
renderer: function(sprite, config, rendererData, index) {
var store = rendererData.store,
storeItems = store.getData().items,
last = storeItems.length - 1,
record = storeItems[index],
diff = record && Math.round(record.data['g2'] - record.data['g1']),
surface = sprite.getParent(),
textSprites, textSprite, rectSprite;
if (!record) {
return;
}
// This renderer function draws a red label if series #2 is greater than series #1.
// The label displays the difference between the values of series #1 and series #2.
//
// Note: The two renderer functions in this test case cannot be consolidated. The red labels
// are rendered here because they are positioned relatively to the series #2 columns.
if (diff > 0) {
textSprites = surface.myTextSprites;
if (!textSprites) {
textSprites = surface.myTextSprites = [];
}
textSprite = textSprites[index];
if (!textSprite) {
textSprite = textSprites[index] = surface.add({
type: 'text'
});
rectSprite = textSprite.rectSprite = surface.add({
type: 'rect'
});
} else {
rectSprite = textSprite.rectSprite;
textSprite.show();
rectSprite.show();
}
rectSprite.setAttributes({
x: config.x + (index == last ? -18 : 20),
y: config.y - 36,
width: 36 + (diff >= 10 ? (diff >= 100 ? (diff >= 1000 ? 30 : 20) : 10) : 0),
height: 22,
fill: 'tomato',
stroke: 'black',
radius: 4,
opacity: 1,
zIndex: 10000
});
textSprite.setAttributes({
text: "+ " + diff,
x: config.x + (index == last ? -12 : 28),
y: config.y - 20,
fill: 'black',
fontSize: 16,
zIndex: 10001,
scalingY: -1
});
} else {
textSprites = surface.myTextSprites;
if (textSprites) {
textSprite = textSprites[index];
if (textSprite) {
textSprite.rectSprite.hide();
textSprite.hide();
}
}
}
return null;
}
}],
axes: [{
type: 'numeric',
position: 'left',
fields: ['g1', 'g2'],
minimum: 0
}, {
type: 'category',
position: 'bottom',
fields: 'name'
}]
}]
});