Setting BIRT chart series palette dynamically

January 13th, 2010 | Tags: ,

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.:

Chart series palette

With all three category values in the dataset everything works as expected:

Pie chart with static palette colours and all categories

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:

Pie chart with colours from a static palette

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:

Pie chart with colours dynamically reflecting category values

  1. eDan
    June 24th, 2010 at 14:09
    Reply | Quote | #1

    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?

  2. September 9th, 2010 at 13:58
    Reply | Quote | #2

    Hi Dan, for bar charts please take a look at this post: http://www.martinhammer.com/blog/?p=575

  3. June 16th, 2011 at 21:56
    Reply | Quote | #3

    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.

    • June 17th, 2011 at 17:32
      Reply | Quote | #4

      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.

  4. florian
    July 2nd, 2011 at 00:10
    Reply | Quote | #5

    hi,

    how can i define the color for the lines in a line chart…. the markers and the legend works…. but the lines?

    thx

  5. toksib
    August 11th, 2011 at 16:59
    Reply | Quote | #6

    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

  6. August 12th, 2011 at 03:32
    Reply | Quote | #7

    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

  7. toksib
    August 12th, 2011 at 08:49
    Reply | Quote | #8

    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

    • August 13th, 2011 at 07:36
      Reply | Quote | #9

      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.