jfreechart - JFreechart 中的多个堆叠区域数据集
问题描述
我正在使用 JFreechart,我正在尝试获得XYDifferenceRenderer
与CategoryPlot
. 我遇到的问题是能够StackedAreaRenderer
在同一个图上绘制多个 s。下面有一个 StackedArea 看起来像是浮动的。这就是我想要的。
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);
}
}
版本 1
如果我取消注释代码部分,dataset2
然后renderer2
我得到一些奇怪的结果,我有三个区域存在,三个项目列在图例中。
版本 2
如果我取消注释代码的部分dataset2
并且renderer1
我得到我认为接近我想要的但是,两者的区域都是红色的,并且两者的图例都是Second
不存在的dataset2
。
有谁知道我如何获得版本 1 的颜色,但版本 2 的区域集?
解决方案
我发现了如何获得我想要的东西。问题来自渲染器需要知道数据集相对于自身的索引与数据集相对于绘图的索引。
因此,当渲染器添加到绘图时,它使用第二个渲染器使用相对于自身的数据集索引来修复。
具有预期输出的代码:
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);
}
}
推荐阅读
- introspection - Eiffel:内省的文档和调用者类
- java - 如何从静态“无上下文” main() 方法启动主活动?
- http - 如何在golang中获取http请求的初始时间戳?
- c# - Asp.Net Core 检查打开请求
- angular - TypeScript:向 HtmlElement 添加类型属性
- authorization - 如何创建自定义指令来保护我的 GraphQL API?
- php - 无法从 Laravel 控制器连接到 Asterisk AMI
- python - 根据位置将_后缀添加到列名
- java - Thymeleaf 不承认班级中的公共枚举
- reactjs - 轮播未在反应中显示