Multiple Colors in Bar
Multiple Colors in Bar
Hello,
Is it possible to assign a single Bar in a Bar Chart multiple colors? I would like to be able to assign specific colors to a range of values such that, for example, the bar would be green from 0-500 units, yellow from 501-1000 units, and red from 1001-1500 units. So, if the bar is to display a value of 1500, the colors displayed would be as described above, however, if the value to be displayed is 506, the bar would show the green color from 0-500 and yellow from 501-506.
The appearance of the StackedBarChart (with green, yellow, and red bars) is what I'm trying for, but would like to be able to achieve this effect by assigning multiple colors to one bar.
Thanks!
Is it possible to assign a single Bar in a Bar Chart multiple colors? I would like to be able to assign specific colors to a range of values such that, for example, the bar would be green from 0-500 units, yellow from 501-1000 units, and red from 1001-1500 units. So, if the bar is to display a value of 1500, the colors displayed would be as described above, however, if the value to be displayed is 506, the bar would show the green color from 0-500 and yellow from 501-506.
The appearance of the StackedBarChart (with green, yellow, and red bars) is what I'm trying for, but would like to be able to achieve this effect by assigning multiple colors to one bar.
Thanks!
-
- Posts: 13
- Joined: Thu Apr 06, 2006 7:55 pm
Different colors for positive and negative values
Interesting idea sdd. I hope you find a solution. You might consider (I haven't even looked at trying this) extending BarRenderer.
I want to do almost an identical thing: for a single category, I want the positive values to have one color and the negative values to have a different color.
For ("row", "column", 5), the bar should be colored blue.
For ("row", "column", -3), the bar should be colored red.
And so on...
Do I need to extend the BarRenderer?
Thanks for the help.
I want to do almost an identical thing: for a single category, I want the positive values to have one color and the negative values to have a different color.
For ("row", "column", 5), the bar should be colored blue.
For ("row", "column", -3), the bar should be colored red.
And so on...
Do I need to extend the BarRenderer?
Thanks for the help.
Subclass the renderer and override
Code: Select all
public Paint getItemPaint(int series, int item)
Hey..SomeOtherUser wrote:Thank you.
Can you please shed some light on how to override this method?
this is the code snippet for my renderer.
LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot
.getRenderer();
renderer.setShapesVisible(true);
renderer.setDrawOutlines(true);
renderer.setUseFillPaint(true);
renderer.setFillPaint(Color.white);
-
- Posts: 13
- Joined: Thu Apr 06, 2006 7:55 pm
I am trying to create a XYLine graph where values less that 50 should be filled with black colour and rest red.
Code: Select all
JFreeChart chart = ChartFactory.createLineChart(
"Reading Status for MOTE# " + moteId, // chart title
"Date/Time", // x axis label
"Reading", // y axis label
getDataset(reading), // data
PlotOrientation.VERTICAL,
true, // include legend
true, // tooltips
false // urls
);
chart.setBackgroundPaint(Color.white);
CategoryPlot plot = (CategoryPlot) chart.getPlot();
plot.setBackgroundPaint(Color.lightGray);
plot.setRangeGridlinePaint(Color.white);
// customise the range axis...
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
// customize the renderer...
LineAndShapeRenderer renderer = new MyRenderer();
renderer = (LineAndShapeRenderer) plot
.getRenderer();
renderer.setShapesVisible(true);
renderer.setDrawOutlines(true);
renderer.setUseFillPaint(true);
renderer.setFillPaint(Color.BLACK);
ChartUtilities.saveChartAsJPEG(new File("test.jpg"), chart, 500, 300);
return chart;
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
You've got this in your code:
That creates a new renderer then immediately overwrites it with the plot's renderer. I doubt that's what you intended...
Code: Select all
LineAndShapeRenderer renderer = new MyRenderer();
renderer = (LineAndShapeRenderer) plot.getRenderer();
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


-
- Posts: 13
- Joined: Thu Apr 06, 2006 7:55 pm
Thank you for the added info, kanishk. I think I can help you. The problem is that the Renderer knows nothing about the dataset. The only time it ever is given information about the dataset is in drawItem, which is called when the chart needs to be repainted. (See http://java.sun.com/docs/books/tutorial ... editrender to understand the mechanism employed here.) So simply overriding getItemPaint will be insufficient for your purposes.
I'm using a BarRenderer and wanted negative values to be one color and positive another. What I had to do was subclass BarRenderer and add a data structure to remember the other colors, then override methods for setting the Paint (setPaint or setSeriesPaint) to allow me to add my alternate colors, getItemPaint to return my alternate color when a condition is met, and drawItem to establish the conditions that determine which Paint to use.
I've included my code below. It's a bit of a hack, but it gets the job done.
If you have further questions, just ask.
I'm using a BarRenderer and wanted negative values to be one color and positive another. What I had to do was subclass BarRenderer and add a data structure to remember the other colors, then override methods for setting the Paint (setPaint or setSeriesPaint) to allow me to add my alternate colors, getItemPaint to return my alternate color when a condition is met, and drawItem to establish the conditions that determine which Paint to use.
I've included my code below. It's a bit of a hack, but it gets the job done.
Code: Select all
public class NegativeBarRenderer extends BarRenderer
{
private boolean negative = false;
private HashMap negativePaint = new HashMap();
public void setSeriesPaint(int series, Paint positive, Paint negative)
{
negativePaint.put(positive, negative);
setSeriesPaint(series, positive);
}
public Paint getNegativeSeriesPaint(int series)
{
return (Paint)negativePaint.get(getSeriesPaint(series));
}
public Paint getItemPaint(int series, int item)
{
if(negative)
return (Paint)negativePaint.get(super.getItemPaint(series, item));
else
return super.getItemPaint(series, item);
}
public void drawItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot,
CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, int pass)
{
// This is the only place we have access to the data values. Establish positive or negative here.
if(dataset.getValue(row, column).doubleValue() < 0)
negative = true;
// Draw like normal, which will call getItemPaint()
super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column, pass);
// Return to normal
negative = false;
}
}
How about this?
In the real world you might want a few null checks. If you have multiple datasets in the plot you would need to modify the code accordingly.
Code: Select all
plot.setRenderer(new BarRenderer() {
public java.awt.Paint getItemPaint(int row, int column) {
double v = getPlot().getDataset().getValue(row, column).doubleValue();
if (v < 0)
return Color.red;
else
return Color.green;
}
});
-
- Posts: 13
- Joined: Thu Apr 06, 2006 7:55 pm
I am not sure how will this work when using XY chart? I tried using skunk's code and it painted the line AND the dot as BLACK..where as I wanted ONLY the dot to be black. here is the code...
Code: Select all
public class MyRenderer extends LineAndShapeRenderer {
private Boolean[] anomaly;
/**
*
*
*/
public MyRenderer(Boolean[] anomaly) {
super();
this.anomaly = anomaly;
}
/**
*
*/
public Paint getItemPaint(int series, int item) {
if(anomaly[item].booleanValue())
return Color.BLACK;
return super.getItemPaint(series,item);
}
}