admin管理员组文章数量:1424429
EXTJS 4 - I am trying to customize the renderer function for the 'series' in StackedBarChart. I want to conditionally color the bars.
renderer: function(sprite, record, curAttr, index, store) {
return Ext.apply(curAttr, {
fill: color
});
return curAttr;
},
My Question is, how to find out which element its currently rendering. I want to give white color to the first element of each record in my data store/series.
Thank you.
EXTJS 4 - I am trying to customize the renderer function for the 'series' in StackedBarChart. I want to conditionally color the bars.
renderer: function(sprite, record, curAttr, index, store) {
return Ext.apply(curAttr, {
fill: color
});
return curAttr;
},
My Question is, how to find out which element its currently rendering. I want to give white color to the first element of each record in my data store/series.
Thank you.
Share Improve this question asked Apr 28, 2011 at 17:12 M99M99 1,90710 gold badges30 silver badges51 bronze badges 1- did you solve this? would you share if so? ty – Armance Commented Jan 4, 2012 at 11:43
2 Answers
Reset to default 2I found a way to detect exactly which element is currently being rendered. First, you'll need the following override, which addresses several issues with the renderer parameters. It shouldn't affect the normal bar charts, but I haven't tested them.
Ext.override(Ext.chart.series.Bar,{
drawSeries: function() {
var me = this,
chart = me.chart,
store = chart.getChartStore(),
surface = chart.surface,
animate = chart.animate,
stacked = me.stacked,
column = me.column,
enableShadows = chart.shadow,
shadowGroups = me.shadowGroups,
shadowGroupsLn = shadowGroups.length,
group = me.group,
seriesStyle = me.seriesStyle,
items, ln, i, j, baseAttrs, sprite, rendererAttributes, shadowIndex, shadowGroup,
bounds, endSeriesStyle, barAttr, attrs, anim;
// ---- start edit ----
var currentCol, currentStoreIndex;
// ---- end edit ----
if (!store || !store.getCount()) {
return;
}
//fill colors are taken from the colors array.
delete seriesStyle.fill;
endSeriesStyle = Ext.apply(seriesStyle, this.style);
me.unHighlightItem();
me.cleanHighlights();
me.getPaths();
bounds = me.bounds;
items = me.items;
baseAttrs = column ? {
y: bounds.zero,
height: 0
} : {
x: bounds.zero,
width: 0
};
ln = items.length;
// Create new or reuse sprites and animate/display
for (i = 0; i < ln; i++) {
sprite = group.getAt(i);
barAttr = items[i].attr;
if (enableShadows) {
items[i].shadows = me.renderShadows(i, barAttr, baseAttrs, bounds);
}
// ---- start edit ----
if (stacked && items[i].storeItem.index != currentStoreIndex) {
//console.log("i: %o, barsLen: %o, j: %o, items[i]: %o",i,bounds.barsLen,i / bounds.barsLen,items[i]);
currentStoreIndex = items[i].storeItem.index;
currentCol = 0;
}
else {
++currentCol;
}
// ---- end edit ----
// Create a new sprite if needed (no height)
if (!sprite) {
attrs = Ext.apply({}, baseAttrs, barAttr);
attrs = Ext.apply(attrs, endSeriesStyle || {});
sprite = surface.add(Ext.apply({}, {
type: 'rect',
group: group
}, attrs));
}
if (animate) {
// ---- start edit ----
rendererAttributes = me.renderer(sprite, items[i].storeItem, barAttr, (stacked? currentStoreIndex : i), store, (stacked? currentCol : undefined));
// ---- end edit ----
sprite._to = rendererAttributes;
anim = me.onAnimate(sprite, { to: Ext.apply(rendererAttributes, endSeriesStyle) });
if (enableShadows && stacked && (i % bounds.barsLen === 0)) {
j = i / bounds.barsLen;
for (shadowIndex = 0; shadowIndex < shadowGroupsLn; shadowIndex++) {
anim.on('afteranimate', function() {
this.show(true);
}, shadowGroups[shadowIndex].getAt(j));
}
}
}
else {
// ---- start edit ----
rendererAttributes = me.renderer(sprite, items[i].storeItem, Ext.apply(barAttr, { hidden: false }), (stacked? currentStoreIndex : i), store, (stacked? currentCol : undefined));
// ---- end edit ----
sprite.setAttributes(Ext.apply(rendererAttributes, endSeriesStyle), true);
}
items[i].sprite = sprite;
}
// Hide unused sprites
ln = group.getCount();
for (j = i; j < ln; j++) {
group.getAt(j).hide(true);
}
// Hide unused shadows
if (enableShadows) {
for (shadowIndex = 0; shadowIndex < shadowGroupsLn; shadowIndex++) {
shadowGroup = shadowGroups[shadowIndex];
ln = shadowGroup.getCount();
for (j = i; j < ln; j++) {
shadowGroup.getAt(j).hide(true);
}
}
}
me.renderLabels();
}
});
Here's the change list for renderer()
:
- The second parameter is now mapped to the correct store item
- The fourth parameter is now the store index number instead of the internal item number (worthless otherwise IMO)
- Added a sixth parameter that tells the current segment index within the record, not counting other properties in the record that don't belong to the axis.
Example: for a record that looks like{name: 'metric': segment1: 12, segment2: 22}
, the index forsegment1
will be0
instead of1
, because the first item in the record does not belong to its axis (it's the category name)
So, to answer your question, now you can use the renderer like so:
renderer: function(sprite, record, attr, storeIndex, store, col) {
// set the color to white for the first item in every record
return (col == 0)? Ext.apply(attr, { fill: '#fff' }) : attr;
}
If you want to set the color for a named item, you may also do it like this:
// let's say that every record looks like this:
// {name: 'metric one', user1: 23, user2: 50, user3: 10}
renderer: function(sprite, record, attr, storeIndex, store, col) {
// retrieve the segment property name from the record using its numeric index.
// remember that 'col' doesn't take into account other fields that don't
// belong to the axis, so in this case we have to add 1 to the index
var uid = Ext.Object.getAt(record.data, col+1)[0];
// set the color to red for 'user2'
return (uid == 'user2')? Ext.apply(attr, { fill: '#f00' }) : attr;
}
For that last one, you'll need this function, which allows you to retrieve a property from an object using a numeric index:
/**
* Returns the key and its value at the idx position
* @return {Array} Array containing [key, value] or null
*/
Ext.Object.getAt = function(obj, idx) {
var keys = Ext.Object.getKeys(obj);
if (idx < keys.length) {
return [keys[idx],obj[keys[idx]]];
}
return null;
}
The index tells you which element is rendering. I've noticed however that in some situations renderer() is called 3 times before the elements start getting processed. I asked in the Sencha forums about this but to no avail.
本文标签: javascriptExtJSStacked Bar Chart Conditional ColoringStack Overflow
版权声明:本文标题:javascript - ExtJS - Stacked Bar Chart Conditional Coloring - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745422747a2657975.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论