Jump to content
We've recently updated our Privacy Statement, available here ×

Bind chart color to values from datasource


Pethrus

Recommended Posts

Hi,

 

I've a datasource with three columns : one label, one number, and one color (rgb html-style). I want to draw a chart (for instance a pie or a stacked bar) with for each part the color defined in the datasource.

 

Let's assume it's a survey where there are two questions (labels here): "good" or "bad". 95 people answered "good" and 17 "bad". I want to force the color of the "good" part to be green and the "bad" part to be red.

 

Series color are not enough, as we can't control which color are given to a part. I really want to take the color value in my database.

 

I've found a solution, thanks to this forum, with chart customizers. I put the color I want in the "key" field of my chart, and I apply the customizer class following

 

Code:
import java.awt.Color;
import net.sf.jasperreports.engine.JRChartCustomizer;
import org.jfree.chart.plot.PiePlot;
import org.jfree.data.general.PieDataset;

public class custReport implements JRChartCustomizer {
public void customize(org.jfree.chart.JFreeChart param1, net.sf.jasperreports.engine.JRChart param2) {
PiePlot plot = (PiePlot)param1.getPlot();
PieDataset pd = plot.getDataset();
for (int i = 0; i < pd.getItemCount(); i++) {
plot.setSectionPaint(i, Color.decode( (String) pd.getKey(i)));
}
}
}

 

This works. However, it's not a very good solution : first, it's not clean, second, it may create issues (if I do not put color in my DB, the key of the chart serie will be null, creating running error).

 

Would you have another cleaner solution ? Thanks !

Link to comment
Share on other sites

  • Replies 2
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

I would really like to find another solution. Using the key expression create legend issues, and is not clean.

 

Maybe could we do that using the section hyperlink ? I did not suceeded to do so. I am hoping somebody could help me.

Link to comment
Share on other sites

  • 2 weeks later...

I have still no clean solution, but I've done another chart customizer which might help some people (at least it would have helped me to find this in the forum earlier).

 

This aim is to draw a stacked bar chart with the color fetched from the datasource.

 

Let's assume that we have three item in each row fetched from the datasource :

- $F{LIBELLE} : the label (String) used to create a legend

- $F{NBRES} : an integerused as chart value

- $F{GRAPHCOLOR} : the color we want to link to this chart part, formated HTML-RGB-like (for instance #FF0000)

 

In the "Chart properties" I put :

- Series expression (key): $F{LIBELLE}+$F{GRAPHCOLOR}

- Category expression : one unuseful parameter (it's a stacked bar char with only one category)

- Value expression : $F{NBRES}

- Label expression : $F{LIBELLE}

 

Then I use a chart customizer, which put the right color in the right part, and delete the color information from the series expression (I don't want the color to be displayed in the legend). In order to do so, I created a new dataset in which in insert the same information, without the color.

 

Code:


import java.awt.Color;
import java.math.BigDecimal;
import net.sf.jasperreports.engine.JRChartCustomizer;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.StackedBarRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.Dataset;



public class HorizontalChartClass implements JRChartCustomizer {
public void customize(org.jfree.chart.JFreeChart param1, net.sf.jasperreports.engine.JRChart param2) {
// get the "plot" from the JFreeChart
CategoryPlot plot = (CategoryPlot)param1.getPlot();
// get the dataset
CategoryDataset pd = plot.getDataset();
// create a new empty dataset
DefaultCategoryDataset pdWithoutColor = new DefaultCategoryDataset();
StackedBarRenderer renderer = new StackedBarRenderer(true);
// simple counter
int serieNum = 0;
// loop on series
for(int i = 0; i < pd.getRowCount(); i++) {
// get the key. Here it is the legend followed by the color
String serie = (String) pd.getRowKey(i);
// get the legend only
String legende = serie.substring(0,serie.length()-7);
// get the color only
String graphcolor = serie.substring(serie.length()-7);
// get the value
BigDecimal valeur = (BigDecimal)pd.getValue(i, 0);
// set the bar filling color
renderer.setSeriesPaint(serieNum, Color.decode(graphcolor));
// set the border filling collor
renderer.setSeriesOutlinePaint(serieNum, Color.decode(graphcolor));
// add the cleaned key/legend to the new dataset
pdWithoutColor.setValue(valeur, (Comparable)legende, (Comparable)(new Integer(0)));
serieNum++;
}
// set the renderer (which contains our colors)
plot.setRenderer(renderer);
// set the new (cleaned) dataset
plot.setDataset(pdWithoutColor);

}
}

 

(you may note that it would be cleaner to add a small regexp to check if there is really a color at the end of the key).

Post edited by: Pethrus, at: 2008/07/16 08:43

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...