Setting BIRT chart series palette dynamically
BIRT series palette is static by default, meaning colours are applied in the specified order without being tied to the actual category values. This is ok in most cases, however consider the following scenario. In our data we expect three category values, “1-Low”, “2-Mid” and “3-High” and the chart series palette has been set to reflect this. Red colour is first in the list, so it will used for the first category value (“1-Low”) etc.:
With all three category values in the dataset everything works as expected:
However, suppose that for a particular dataset the value “1-Low” is not present (perhaps a month when the business is performing well?). In this case the palette colours will still be applied in the same order starting with red, leading to inconsistency and quite possibly confusing the users:
This problem can be overcome by dynamically scripting the series colours based on the category value. Two methods need to be scripted, one for the chart itself and the other for the legend (otherwise the chart and the legend will not match!).
function beforeDrawDataPoint( dph, fill, icsc )
{
var sValue = dph.getBaseDisplayValue();
if( sValue == "1-Low" )
{
fill.set( 242, 88, 106, 255 );
}
else if( sValue == "2-Mid" )
{
fill.set( 232, 172, 57, 255 );
}
else if( sValue == "3-High" )
{
fill.set( 128, 255, 128, 255 );
}
}
function beforeDrawLegendItem( lerh, bounds, icsc )
{
var sValue = lerh.getLabel().getCaption().getValue();
var fill = lerh.getFill();
if( sValue == "1-Low" )
{
fill.set( 242, 88, 106, 255 );
}
else if( sValue == "2-Mid" )
{
fill.set( 232, 172, 57, 255 );
}
else if( sValue == "3-High" )
{
fill.set( 128, 255, 128, 255 );
}
}
The set
method can take either three integer parameters with values between 0 and 255 for Red, Green, Blue or four integer parameters (RGB + Alpha channel for opacity). After including the above scripts the chart is generated with the correct colours for the category values:
Can I use this function for Bar charts? Also, is there a way to debug this script? Like displaying the value of sValue in a label or something like that?
Hi Dan, for bar charts please take a look at this post: http://www.martinhammer.com/blog/?p=575
What if one of the caregories has data but a null value in the category name. Is there a way to assign a textual description to the category name in the legend? I have done this with bar charts but I cannot seem to get it to work on a pie chart. Thank you.
Hi Mark, in such a case wouldn’t it be easier to catch the null values earlier on, e.g. in your datasource by using an NVL/ISNULL function in the query, or by using a calculated field which replaces the null value with the description you want? I’m sure there’s a way to it through a script on the chart, but my approach is to use scripting only if there isn’t another way of achieving the same result.
hi,
how can i define the color for the lines in a line chart…. the markers and the legend works…. but the lines?
thx
Hi Mark,
I tried it with flash pie chart and I changed the funciton like this but it doesn’t work.
function beforeDrawDataPoint( fcdph, fill, fcsc )
{
var sValue = fcdph.getClass().;
if( sValue == “Incomplete PPMs” )
{
fill.set( 242, 88, 106, 255 );
}
/* else if( sValue == “2-Mid” )
{
fill.set( 232, 172, 57, 255 );
}*/
else if( sValue == “Complete PPMs” )
{
fill.set( 128, 255, 128, 255 );
}
}
I cannot even find any function for legend.
Do you know how can I do this for flash pie chart?
thanks
Hi, I have no experience with flash charts since I don’t have access to the paid-for Actuate offering. You will need to check in the supplied documentation for chart scripting API reference.
Regards,
Martin
Hi Martin,
You can download a 45 days trial version to check it.
Download the commercial version of Actuate BIRT Designer Professional, I’m using that one as well.
http://www.birt-exchange.com/be/downloads/
Thanks,
toksib
Hi toksib, at this point I have no interest in the paid Actuate product and as such won’t be downloading any trial / evaluation version. Just looking over your code I think it’s pretty certain that var sValue = fcdph.getClass().; is (1) incorrect syntax (why the . at the end?) and (2) will not return the value you want but rather the class name. That’s as far as I can help.