Discussions
Categories
Groups
Community Home
Categories
INTERNAL ENABLEMENT
POPULAR
PUBLIC CLOUD
PRIVATE CLOUD
Quick Links
MY LINKS
HELPFUL TIPS
Back to website
Home
Intelligence (Analytics)
Side-to-side bar chart is there a way to hide empty bar?
hanl1
<p>Hi all,</p>
<p> </p>
<p>I am trying to create a side-by-side bar chart and use different colors for each value series AND category. Something like Capture.png I attached. (never mind the shaded bar I know that this not possible. This image is from Excel). </p>
<p>First of all, I dont think this is naturally supported by BIRT (correct me if I am wrong!). So the workaround I figured out, is to create as many series as there are X-axis categories, and for each category, only 1 pair of series have non-zero data. This way it will look like each category and each series has different colors. However, to my dismay, the bar with zero data still takes the space on the chart, and I ended up with something like Capture2.png. </p>
<p> </p>
<p>I hope I made myself clear what I want to achieve. Please advise on if I can somehow remove or hide those bars with 0 value, or is there any other way for me to make a chart like Capture1.PNG (but to replace shaded bar with bar of yet a different color) in BIRT.</p>
<p> </p>
<p>Thanks in advance. </p>
<p> </p>
Find more posts tagged with
Comments
mwilliams
You could just change the colors of the bars in script. If you want a legend, you might have to create a custom one outside the chart. What is your BIRT version? I'll try a few things out and let you know. Are you wanting the legend to display all of the different colors and their series?
hanl1
<p>Thanks Michael for the response. If you could show me a simple example of the scripts you mentioned that would be awesome. And no I do not need the legend. Unfortunately I am restricted to using version 2.5.2 at my development environment. Hopefully that is not too ancient for your method. Many thanks!</p>
mwilliams
Try this script in your chart:<br><br><pre class="_prettyXprint _lang-auto _linenums:0">
i=0;
palette = null;
importPackage( Packages.org.eclipse.birt.chart.model.attribute.impl );
function beforeGeneration( chart, icsc )
{
palette = chart.getAxes()[0].getAssociatedAxes()[0].getSeriesDefinitions( ).get( 0 ).getSeriesPalette( ).getEntries( );
}
function beforeDrawDataPoint( dph, fill, icsc )
{
r = palette[i].getRed();
g = palette[i].getGreen();
b = palette[i].getBlue();
fill.set(r,g,b);
i++;
}
</pre>
hanl1
<p>Thanks Michael this is great. This is exactly what I want to see. I have one follow-up question that might sound ridiculous, but please bear with me one more time. In my development environment I have to use an in-house developed Java event handler, the side effect of which is that ALL chart scripting will be ignored. This means I cannot override any of the chart onRender() functions directly, but overriding events on other elements are fine. So my question is, is there a way for me to get and modify the Fill objects from outside this event context. For example, currently I do a lot of customization on charts by writing scripts somewhere else and use 'reportContext' to get and modify any chart. I have put something like this in onRender() of the Cell element to modify a chart:</p>
<pre class="_prettyXprint _lang-js">
...
cht = reportContext.getDesignHandle().findElement("ChartActiveRisk");
chart = cht.getReportItem().getProperty("chart.instance");
var xAxis = chart.getAxes().get(0);
var yAxis = xAxis.getAssociatedAxes().get(0);
var ranges = yAxis.getMarkerRanges();
... //do cool stuff with all these things
</pre>
<p>I have little knowledge how to simulate 'beforeDrawDataPoint()' since it is called once for each datapoint, and I have no idea where to get all the Fill objects passed in to this function. I hope I have made myself clear. If this is possible, please advise on how I should go about it. The help is very much appreciated. </p>
<p> </p>
<p> </p>
mwilliams
I have not tried this. I might try it out here in a bit, but on a chart, you can call a function , "setScript(java.lang.String value)". In the same fashion you say you've modified a chart through script, you might try passing the script I posted through this function with something like:<br> <br><pre class="_prettyXprint _lang-auto _linenums:0">chart.setScript("i=0;palette = null;importPackage( Packages.org.eclipse.birt.chart.model.attribute.impl );function beforeGeneration( chart, icsc ){ palette = chart.getAxes()[0].getAssociatedAxes()[0].getSeriesDefinitions( ).get( 0 ).getSeriesPalette( ).getEntries( );}function beforeDrawDataPoint( dph, fill, icsc ){ r = palette[i].getRed(); g = palette[i].getGreen(); b = palette[i].getBlue(); fill.set(r,g,b); i++;}");</pre>Again, I've not tried this, but I will here shortly. I'll let you know.
mwilliams
FYI - This does work. Hopefully it works for you to get around your issue.<br> <br><pre class="_prettyXprint _lang-auto _linenums:0">cht = reportContext.getDesignHandle().findElement("MyChart");
chart = cht.getReportItem().getProperty("chart.instance");
chart.setScript("i=0;palette = null;importPackage( Packages.org.eclipse.birt.chart.model.attribute.impl );function beforeGeneration( chart, icsc ){ palette = chart.getAxes()[0].getAssociatedAxes()[0].getSeriesDefinitions( ).get( 0 ).getSeriesPalette( ).getEntries( );}function beforeDrawDataPoint( dph, fill, icsc ){ r = palette[i].getRed(); g = palette[i].getGreen(); b = palette[i].getBlue(); fill.set(r,g,b); i++;}");
</pre>
hanl1
<p>Fantastic. Thanks a lot! (I should've read the API more thoroughly, though)</p>
mwilliams
Not a problem. Let us know whenever you have questions!