PDA

View Full Version : How to pass userdefined color for each bars in column chart?



mrprabu
20 Feb 2014, 7:24 PM
HI,

How to pass color for each bars in column chart? can any any one give me the idea

Regards,
Prabu

scottmartin
20 Feb 2014, 8:01 PM
You can use theme, or renderer

//theme


var colors = ['rgb(47, 162, 223)',
'rgb(60, 133, 46)',
'rgb(234, 102, 17)',
'rgb(154, 176, 213)',
'rgb(40, 40, 40)'];

Ext.chart.theme.Browser = Ext.extend(Ext.chart.theme.Base, {
constructor: function(config) {
Ext.chart.theme.Base.prototype.constructor.call(this, Ext.apply({
colors: colors
}, config));
}
});

...

xtype: 'chart',
theme: 'Browser',
...






// renderer


Ext.application({
name : 'Fiddle',

launch : function() {

var store = Ext.create('Ext.data.JsonStore', {
fields: ['name', 'data'],
data: [
{ 'name': 'metric one', 'data':10 },
{ 'name': 'metric two', 'data': 7 },
{ 'name': 'metric three', 'data': 5 },
{ 'name': 'metric four', 'data': 2 },
{ 'name': 'metric five', 'data':27 }
]
});

Ext.create('Ext.chart.Chart', {
renderTo: Ext.getBody(),
width: 500,
height: 300,
animate: true,
store: store,
axes: [{
type: 'Numeric',
position: 'bottom',
fields: ['data'],
label: {
renderer: Ext.util.Format.numberRenderer('0,0')
},
title: 'Sample Values',
grid: true,
minimum: 0
}, {
type: 'Category',
position: 'left',
fields: ['name'],
title: 'Sample Metrics'
}],
series: [{
type: 'bar',
axis: 'bottom',
highlight: true,
tips: {
trackMouse: true,
width: 140,
height: 28,
renderer: function(storeItem, item) {
this.setTitle(storeItem.get('name') + ': ' + storeItem.get('data') + ' views');
}
},
label: {
display: 'insideEnd',
field: 'data',
renderer: Ext.util.Format.numberRenderer('0'),
orientation: 'horizontal',
color: '#333',
'text-anchor': 'middle'
},
xField: 'name',
yField: 'data',

renderer: function(sprite, record, attr, index, store) {
var value = (record.get('data') >> 1) % 5;
var color = ['rgb(213, 70, 121)',
'rgb(44, 153, 201)',
'rgb(146, 6, 157)',
'rgb(49, 149, 0)',
'rgb(249, 153, 0)'][value]; // [color][element]

return Ext.apply(attr, {
fill: color
});
}

}]
});


}
});

mrprabu
20 Feb 2014, 8:12 PM
Hi scottmartin,

Thanks for code and suggestion.

I applied the same which you mentioned. its working fine and same color applying for all the bars. My requirement is have to apply different color for each and every bar in column chart.

kindly give me more suggestion,
47988
Regards,
Prabu

scottmartin
20 Feb 2014, 8:44 PM
How did you setup your renderer? Mine was just and example

This uses index to use a different color in the array instead of value


renderer: function(sprite, record, attr, index, store) {
// var value = (record.get('data1') >> 0) % 6; // 6 color elements
var color = [ '#94ae0a', '#115fa6', '#a61120', '#ff8809', '#ffd13e', '#a61187'][index];

return Ext.apply(attr, {
fill: color
});
}

scottmartin
20 Feb 2014, 8:46 PM
So you would see this:

47989

mrprabu
20 Feb 2014, 10:00 PM
Thanks scottmartin,

above code works fine

mrprabu
26 Feb 2014, 5:37 PM
Dear ScottMartin,

Could you please suggest me to create my chart label in center position and how to pass each label different color programmatically.

code:-

{
type: 'Category',
position: 'bottom',
title: false,
fields: me.xField,
dashSize: 0,
label: {
rotate: {
degrees: -70
}
}
}

48085


Regards,
Prabu

scottmartin
27 Feb 2014, 5:57 AM
create my chart label in center position

Can you reword this .. not sure I understand the requirement.

mrprabu
27 Feb 2014, 6:10 AM
Hi Scott,

1. while setting rotate degree to label, label end should positioning in center of chart bar

2. Have to set each and every label different color(user defined color)

Regards,
Prabu

scottmartin
27 Feb 2014, 6:56 AM
You would need to override the drawing of the labels to perform this.

I tried quickly to override:



Ext.define('Ext.chart.axis.override.Axis', {
override: 'Ext.chart.axis.Axis',

drawHorizontalLabels: function () {

..

textLabel.setAttributes({
hidden: false,
x: x,
y: y-100 // quick change of offest
}, true);

..

});


But this draws the labels under the bars.

You may have better luck overriding the series label and paints the label inside the bar and adjust the offset there:



// override code to create 'insideCenter'
label : {
display : 'insideStart', // insideEnd
field : 'name',
},


Have a look at:
Ext.chart.series.Bar :: onPlaceLabel

mrprabu
27 Feb 2014, 7:01 AM
Thanks Scott.

regarding different color for x-axis ( Eg: January, Febuary, March, etc) each and every label, I couldn't get your point. Kindly explain me more


Regards,
Prabu

scottmartin
27 Feb 2014, 8:46 AM
You can use the following renderer to color the labels on bar



series: [{
type: 'column',
axis: 'left',
highlight: true,
tips: {
trackMouse: true,
width: 140,
height: 28,
renderer: function(storeItem, item) {
this.setTitle(storeItem.get('name') + ': ' + storeItem.get('data') + ' $');
}
},
label: {
display: 'insideEnd',
'text-anchor': 'middle',
field: 'data',
// renderer: Ext.util.Format.numberRenderer('0'),

renderer: function(value, label, record, chart, index) {
var color = ['#000000', '#115fa6', '#a61120', '#ff8809', '#ffd13e', '#a61187'][index];

Ext.apply(label.attr, {
fill: color,
color: color
});
return value;
},

orientation: 'vertical',
color: '#333', // default
font: '15px Helvetica, sans-serif'
},
xField: 'name',
yField: 'data'
}]


48098

mrprabu
27 Feb 2014, 1:41 PM
Thanks Scott,

But requirement have to change the color for x axes category label, pls refer below image

48101

scottmartin
27 Feb 2014, 2:24 PM
1. while setting rotate degree to label, label end should positioning in center of chart bar

As mentioned in the previous post (#10), I thought the requirement was to have these labels in the middle of the bar and rotated? In this case the axis labels were painted under the bars. This is why I decided to present the label for the series instead of the axis.

Ext.chart.series.Bar :: onPlaceLabel

Is this still correct?

mrprabu
27 Feb 2014, 2:30 PM
Yes correct..

scottmartin
27 Feb 2014, 2:31 PM
So essentially like this: ( override still needed to center exactly in bar )

48102

mrprabu
27 Feb 2014, 2:34 PM
sorry Scott.. I conveyed wrongly to you. I posted two questions.

Simple requirement

just need to change the color for x axes label( each and every label different color)

Refer below image
48103

scottmartin
27 Feb 2014, 3:30 PM
You will need to override, as the label renderer only passes the label value.

Have a look at the following ( labelConf )
I was hoping the labelConf renderer would fire, but I had no luck.



Ext.define('Ext.chart.axis.override.Axis', {
override: 'Ext.chart.axis.Axis',

drawHorizontalLabels: function () {
var me = this,
labelConf = me.label,
floor = Math.floor,
max = Math.max,
axes = me.chart.axes,
insetPadding = me.chart.insetPadding,
gutters = me.chart.maxGutters,
position = me.position,
inflections = me.inflections,
ln = inflections.length,
labels = me.labels,
maxHeight = 0,
ratio,
bbox, point, prevLabel, prevLabelId,
adjustEnd = me.adjustEnd,
hasLeft = axes.findIndex('position', 'left') != -1,
hasRight = axes.findIndex('position', 'right') != -1,
reverse = me.reverse,
textLabel, text, idx,
last, x, y, i, firstLabel,
colors = [ '#000000', '#115fa6', '#a61120', '#ff8809', '#ffd13e', '#a61187']; // NEW: add colors array

last = ln - 1;
//get a reference to the first text label dimensions
point = inflections[0];
firstLabel = me.getOrCreateLabel(0, me.label.renderer(labels[0]));
ratio = Math.floor(Math.abs(Math.sin(labelConf.rotate && (labelConf.rotate.degrees * Math.PI / 180) || 0)));

for (i = 0; i < ln; i++) {
point = inflections[i];
idx = i;
if (reverse) {
idx = ln - i - 1;
}
text = me.label.renderer(labels[idx]);
textLabel = me.getOrCreateLabel(i, text);
bbox = textLabel._bbox;
maxHeight = max(maxHeight, bbox.height + me.dashSize + me.label.padding);
x = floor(point[0] - (ratio ? bbox.height : bbox.width) / 2);
if (adjustEnd && gutters.left == 0 && gutters.right == 0) {
if (i == 0 && !hasLeft) {
x = point[0];
}
else if (i == last && !hasRight) {
x = Math.min(x, point[0] - bbox.width + insetPadding);
}
}
if (position == 'top') {
y = point[1] - (me.dashSize * 2) - me.label.padding - (bbox.height / 2);
}
else {
y = point[1] + (me.dashSize * 2) + me.label.padding + (bbox.height / 2);
}

labelConf.fill = colors[i]; // NEW: change color

textLabel.setAttributes({
hidden: false,
x: x,
y: y
}, true);

// Skip label if there isn't available minimum space
if (i != 0 && (me.intersect(textLabel, prevLabel)
|| me.intersect(textLabel, firstLabel))) {
if (i === last && prevLabelId !== 0) {
prevLabel.hide(true);
} else {
textLabel.hide(true);
continue;
}
}

prevLabel = textLabel;
prevLabelId = i;
}

return maxHeight;
}

});

mrprabu
28 Feb 2014, 3:24 AM
Many thanks Scott.

it works..