Reputation: 131
I am using JFreechart and I'm trying to get what would be similar to the XYDifferenceRenderer
but for a CategoryPlot
. Issue I am running into is being able to plot multiple StackedAreaRenderer
s on the same plot. The following has one StackedArea that looks like it is floating. This is what I'm wanting.
package test;
import java.awt.Color;
import java.awt.Dimension;
import java.util.List;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.labels.StandardCategoryToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.AreaRendererEndType;
import org.jfree.chart.renderer.category.StackedAreaRenderer;
import org.jfree.chart.ui.ApplicationFrame;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.RefineryUtilities;
/**
*
* @author buxk
*/
public class DifferenceWithCategories extends ApplicationFrame{
public DifferenceWithCategories(String title){
super(title);
final JFreeChart chart = createChart();
final ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new Dimension(500,270));
setContentPane(chartPanel);
}
/**
* Returns a sample dataset.
*
* @return The dataset.
*/
private CategoryDataset createDataset1() {
// row keys...
String series1 = "First";
// column keys...
String category1 = "Category 1";
String category2 = "Category 2";
String category3 = "Category 3";
String category4 = "Category 4";
String category5 = "Category 5";
// create the dataset...
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(4.0, series1, category1);
dataset.addValue(4.0, series1, category2);
dataset.addValue(3.0, series1, category3);
dataset.addValue(5.0, series1, category4);
dataset.addValue(5.0, series1, category5);
return dataset;
}
/**
* Returns a sample dataset.
*
* @return The dataset.
*/
private CategoryDataset createDataset2() {
// row keys...
String series2 = "Second";
// column keys...
String category1 = "Category 1";
String category2 = "Category 2";
String category3 = "Category 3";
String category4 = "Category 4";
String category5 = "Category 5";
// create the dataset...
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(5.0, series2, category1);
dataset.addValue(7.0, series2, category2);
dataset.addValue(6.0, series2, category3);
dataset.addValue(8.0, series2, category4);
dataset.addValue(6.0, series2, category5);
return dataset;
}
/**
* Returns a sample dataset.
*
* @return The dataset.
*/
private CategoryDataset createDataset3() {
// row keys...
String series3 = "Third";
// column keys...
String category1 = "Category 1";
String category2 = "Category 2";
String category3 = "Category 3";
String category4 = "Category 4";
String category5 = "Category 5";
// create the dataset...
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(1.0, series3, category1);
dataset.addValue(3.0, series3, category2);
dataset.addValue(2.0, series3, category3);
dataset.addValue(3.0, series3, category4);
dataset.addValue(4.0, series3, category5);
return dataset;
}
private CategoryDataset merge4StackedDataset(CategoryDataset d1, CategoryDataset d2){
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
List<Comparable> columnKeys = d1.getColumnKeys();
List<Comparable> d1RowKeys = d1.getRowKeys();
List<Comparable> d2RowKeys = d2.getRowKeys();
double minValue, maxValue;
for (Comparable columnKey : columnKeys) {
for (Comparable rowKey : d1RowKeys) {
for (Comparable d2RowKey : d2RowKeys) {
minValue = Math.min(d1.getValue(rowKey, columnKey).doubleValue(),d2.getValue(d2RowKey, columnKey).doubleValue());
maxValue = Math.max(d1.getValue(rowKey, columnKey).doubleValue(),d2.getValue(d2RowKey, columnKey).doubleValue());
dataset.addValue(minValue, rowKey, columnKey);
dataset.addValue(maxValue - minValue, d2RowKey, columnKey);
// dataset.addValue(d2.getValue(d2RowKey, columnKey).doubleValue(), d2RowKey, columnKey);
}
}
}
return dataset;
}
private JFreeChart createChart() {
CategoryDataset dataset1 = merge4StackedDataset(createDataset1(), createDataset2());
CategoryDataset dataset2 = merge4StackedDataset(createDataset1(), createDataset3());
//create chart with empty dataset
final JFreeChart chart = ChartFactory.createAreaChart(
"Testing",
"Categories",
"Values",
dataset1,
PlotOrientation.VERTICAL,
true, // legend
true, // tool tips
false // URLs
);
//make the chart have a white background
chart.setBackgroundPaint(Color.white);
//get the chart's plot
final CategoryPlot plot = chart.getCategoryPlot();
//color the plot
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
//make a stacked area renderer for the first dataset
final StackedAreaRenderer renderer1 = new StackedAreaRenderer();
renderer1.setEndType(AreaRendererEndType.LEVEL);
renderer1.setDefaultToolTipGenerator(new StandardCategoryToolTipGenerator());
//turn off the first data set that lets the stack float
renderer1.setSeriesPaint(0, new Color(Color.blue.getRed(), Color.blue.getGreen(), Color.blue.getBlue(), 0));
renderer1.setSeriesVisibleInLegend(0, false);
plot.setRenderer(0, renderer1);
plot.setRenderer(1, renderer1);
// plot.setDataset(2, dataset2);
// final StackedAreaRenderer renderer2 = new StackedAreaRenderer();
// renderer2.setEndType(AreaRendererEndType.LEVEL);
// renderer2.setDefaultToolTipGenerator(new StandardCategoryToolTipGenerator());
// renderer2.setSeriesPaint(2, new Color(Color.green.getRed(), Color.green.getGreen(), Color.green.getBlue(), 0));
// renderer2.setSeriesVisibleInLegend(2, false);
// renderer1.setSeriesPaint(2, new Color(Color.green.getRed(), Color.green.getGreen(), Color.green.getBlue(), 0));
// renderer1.setSeriesPaint(3, new Color(Color.black.getRed(), Color.black.getGreen(), Color.black.getBlue(), 255));
// renderer1.setSeriesVisibleInLegend(2, false);
// plot.setRenderer(2, renderer2);
// plot.setRenderer(3, renderer2);
// plot.setRenderer(2, renderer1);
// plot.setRenderer(3, renderer1);
plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
plot.getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.DOWN_45);
plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(true);
return chart;
}
public static void main(String[] args) {
final DifferenceWithCategories demo = new DifferenceWithCategories("Diference With Categories");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}
version 1
If I uncomment the sections of code for dataset2
and renderer2
then I get some weird results where, I have three areas present and three items listed in the legend.
version 2
If I uncomment the sections of code for dataset2
and renderer1
the I get what I think is close to what I want but, the area for both is red and the legend on both is Second
which is not present for dataset2
.
Does anyone know how I can get the coloring of version 1 but the area sets of version 2?
Upvotes: 1
Views: 454
Reputation: 131
I found out how to get what I'm looking for. The issue comes from the renderer needing to know the index of the datasets relative to itself vs index of the datasets relative to the plot.
So it was fixed with a second renderer using dataset indexing relative to itself when the renderer is added to the plot.
import java.awt.Dimension;
import java.util.List;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.labels.StandardCategoryToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.AreaRendererEndType;
import org.jfree.chart.renderer.category.StackedAreaRenderer;
import org.jfree.chart.ui.ApplicationFrame;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.RefineryUtilities;
/**
*
* @author lemming622
*/
public class DifferenceWithCategories extends ApplicationFrame{
public DifferenceWithCategories(String title){
super(title);
final JFreeChart chart = createChart();
final ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new Dimension(500,270));
setContentPane(chartPanel);
}
/**
* Returns a sample dataset.
*
* @return The dataset.
*/
private CategoryDataset createDataset1() {
// row keys...
String series1 = "First";
// column keys...
String category1 = "Category 1";
String category2 = "Category 2";
String category3 = "Category 3";
String category4 = "Category 4";
String category5 = "Category 5";
// create the dataset...
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(4.0, series1, category1);
dataset.addValue(4.0, series1, category2);
dataset.addValue(3.0, series1, category3);
dataset.addValue(5.0, series1, category4);
dataset.addValue(5.0, series1, category5);
return dataset;
}
/**
* Returns a sample dataset.
*
* @return The dataset.
*/
private CategoryDataset createDataset2() {
// row keys...
String series2 = "Second";
// column keys...
String category1 = "Category 1";
String category2 = "Category 2";
String category3 = "Category 3";
String category4 = "Category 4";
String category5 = "Category 5";
// create the dataset...
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(5.0, series2, category1);
dataset.addValue(7.0, series2, category2);
dataset.addValue(6.0, series2, category3);
dataset.addValue(8.0, series2, category4);
dataset.addValue(6.0, series2, category5);
return dataset;
}
/**
* Returns a sample dataset.
*
* @return The dataset.
*/
private CategoryDataset createDataset3() {
// row keys...
String series3 = "Third";
// column keys...
String category1 = "Category 1";
String category2 = "Category 2";
String category3 = "Category 3";
String category4 = "Category 4";
String category5 = "Category 5";
// create the dataset...
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(1.0, series3, category1);
dataset.addValue(3.0, series3, category2);
dataset.addValue(2.0, series3, category3);
dataset.addValue(3.0, series3, category4);
dataset.addValue(4.0, series3, category5);
return dataset;
}
private CategoryDataset merge4StackedDataset(CategoryDataset d1, CategoryDataset d2){
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
List<Comparable> columnKeys = d1.getColumnKeys();
List<Comparable> d1RowKeys = d1.getRowKeys();
List<Comparable> d2RowKeys = d2.getRowKeys();
double minValue, maxValue;
for (Comparable columnKey : columnKeys) {
for (Comparable rowKey : d1RowKeys) {
for (Comparable d2RowKey : d2RowKeys) {
minValue = Math.min(d1.getValue(rowKey, columnKey).doubleValue(),d2.getValue(d2RowKey, columnKey).doubleValue());
maxValue = Math.max(d1.getValue(rowKey, columnKey).doubleValue(),d2.getValue(d2RowKey, columnKey).doubleValue());
dataset.addValue(minValue, rowKey, columnKey);
dataset.addValue(maxValue - minValue, d2RowKey, columnKey);
// dataset.addValue(d2.getValue(d2RowKey, columnKey).doubleValue(), d2RowKey, columnKey);
}
}
}
return dataset;
}
private JFreeChart createChart() {
CategoryDataset dataset1 = merge4StackedDataset(createDataset1(), createDataset2());
CategoryDataset dataset2 = merge4StackedDataset(createDataset1(), createDataset3());
//create chart with empty dataset
final JFreeChart chart = ChartFactory.createAreaChart(
"Testing",
"Categories",
"Values",
dataset1,
PlotOrientation.VERTICAL,
true, // legend
true, // tool tips
false // URLs
);
//make the chart have a white background
chart.setBackgroundPaint(Color.white);
//get the chart's plot
final CategoryPlot plot = chart.getCategoryPlot();
//color the plot
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
//make a stacked area renderer for the first dataset
final StackedAreaRenderer renderer1 = new StackedAreaRenderer();
renderer1.setEndType(AreaRendererEndType.LEVEL);
renderer1.setDefaultToolTipGenerator(new StandardCategoryToolTipGenerator());
//turn off the first data set that lets the stack float
renderer1.setSeriesPaint(0, new Color(Color.blue.getRed(), Color.blue.getGreen(), Color.blue.getBlue(), 0));
renderer1.setSeriesVisibleInLegend(0, false);
plot.setRenderer(0, renderer1);
plot.setRenderer(1, renderer1);
plot.setDataset(2, dataset2);
final StackedAreaRenderer renderer2 = new StackedAreaRenderer();
renderer2.setEndType(AreaRendererEndType.LEVEL);
renderer2.setDefaultToolTipGenerator(new StandardCategoryToolTipGenerator());
renderer2.setSeriesPaint(0, new Color(Color.green.getRed(), Color.green.getGreen(), Color.green.getBlue(), 0));
renderer2.setSeriesVisibleInLegend(0, false);
plot.setRenderer(2, renderer2);
plot.setRenderer(3, renderer2);
plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
plot.getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.DOWN_45);
plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(true);
return chart;
}
public static void main(String[] args) {
final DifferenceWithCategories demo = new DifferenceWithCategories("Diference With Categories");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}
Upvotes: 1