在XYDifference(渲染器)图下创建区域图 [英] Creating an area graph below a XYDifference(Renderer) graph
问题描述
上周我一直在努力寻找一种方法让JFreeChart显示类似于下面的图片。基本上,你正在看三个系列(上,中,下)和填充。在下面有一个(浅绿色)填充颜色,或者是一些区域图,有些人可能会这样称呼它 - 没有意义,只是为了看起来。
最后一部分:底部填充/面积图:
找到一篇旧文章描述如何在同一个情节中使用两个渲染器,这只是在这种情况下的事情。
要获得底下的填充,您需要
- 创建两个新系列
- 其中一个是差异图的下限
- 另一个是绘图底部的值 - 通常只是零。轻松通过调用
plot.getRangeAxis()。getLowerBound()
- 其中一个是差异图的下限
- 将它们添加到新数据集并将其添加到绘图中
我不知道一个绘图可能有多个数据集。原来可以使用索引来访问它们。
- 为填充数据集创建新的呈现器
- 创建新的渲染器
- 设置正确的填充颜色
- 将新数据集的渲染器设置为新渲染器 >
代码与以下内容相似,fill Paint显然取决于您:
static void addFill(Plot plot){
XYSeries lowerLimitSeries =((XYSeriesCollection)(plot 。.getDataset()))getSeries(1);
XYSeriesCollection fillSet = new XYSeriesCollection();
double lowerBound = plot.getRangeAxis()。getLowerBound();
fillSet.addSeries(lowerLimitSeries);
fillSet.addSeries(createLowerFillSeries(lowerLimitSeries,lowerBound));
plot.setDataset(1,fillSet);
Paint fillPaint = Color.GREEN;
XYDifferenceRenderer fillRenderer = new XYDifferenceRenderer(fillPaint,fillPaint,false);
fillRenderer.setSeriesStroke(0,new BasicStroke(0)); //不显示
fillRenderer.setSeriesStroke(1,new BasicStroke(0)); //不显示
plot.setRenderer(1,fillRenderer);
...
static XYSeries createLowerFillSeries(XYSeries lowerLimitSeries,double lowerLimit){
int size = lowerLimitSeries.getItems()。size();
XYSeries res = new XYSeries(lowerFillSeries);
for(int i = 0; i< size; i ++)res.add(new XYDataItem(lowerLimitSeries.getX(i),lowerLimit));
return res;
}
I have been trying for the last week to find a way to make JFreeChart display something similar to the image below. Basically you are looking at three series (upper, middle, lower) with a fill inbetween. And underneath there is a (light green) fill color, or an area chart as some would perhaps call it - no meaning, just for looks.
The only thing really missing from what I have come up with is the last part: the fill underneath / area chart:
I even tried to subclass XYDifferenceRenderer and combine it with the renderer for Areachart, but I could not control the height of the areachart, basically filling up the plot to the top. So that was a no-go. Having created as simple rendererer to create rounded bar charts earlier, I thought that I might be able to change the code for XYDifferenceRenderer. But the code for XYDifferenceRenderer is quite a handful of geometry and inner workings of JFree chart, and the task was a bit overwhelming. So any tips on how to achieve this effect in any "normal" way (that does not involve hacking JFreeChart's inner workings)?
Found an old post describing how to use two renderers in the same plot, which was just the thing in this case.
To get a fill underneath you need to
- create two new series
- one is the lower bound of the difference plot
- the other is the values at the bottom of the plot - often just zero. Easily got by calling
plot.getRangeAxis().getLowerBound()
- add them to a new dataset and add this to the plot I was unaware that a plot could have several datasets. Turns out one can just use an index to access them.
- create a new renderer for the "fill" dataset
- create a new renderer
- set the right fill paint
- set the rendererer for the new dataset to be the new renderer
The code is something akin to the following, where the fill Paint obviously is up to you:
static void addFill(Plot plot) {
XYSeries lowerLimitSeries = ((XYSeriesCollection) (plot.getDataset())).getSeries(1);
XYSeriesCollection fillSet = new XYSeriesCollection();
double lowerBound = plot.getRangeAxis().getLowerBound();
fillSet.addSeries(lowerLimitSeries);
fillSet.addSeries(createLowerFillSeries(lowerLimitSeries, lowerBound));
plot.setDataset(1, fillSet);
Paint fillPaint = Color.GREEN;
XYDifferenceRenderer fillRenderer = new XYDifferenceRenderer(fillPaint, fillPaint, false);
fillRenderer.setSeriesStroke(0, new BasicStroke(0)); //do not show
fillRenderer.setSeriesStroke(1, new BasicStroke(0)); //do not show
plot.setRenderer(1, fillRenderer);
...
}
static XYSeries createLowerFillSeries(XYSeries lowerLimitSeries, double lowerLimit) {
int size = lowerLimitSeries.getItems().size();
XYSeries res = new XYSeries("lowerFillSeries");
for (int i = 0; i < size; i++) res.add(new XYDataItem(lowerLimitSeries.getX(i), lowerLimit));
return res;
}
这篇关于在XYDifference(渲染器)图下创建区域图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!