jfreechart中的堆积间隔条形图

时间:2014-05-09 14:59:18

标签: jfreechart

我正在尝试为特定时段创建堆栈间隔条形图。以下是我的数据集

private static DefaultIntervalCategoryDataset createDataSetForCountryStackBar() {

String[] seriesKeys = {"Pre polluted", "Post polluted"}
String[] categoryKeys = {"Thames"};

Number[][] starts = {{1987},{1985}};
Number[][] ends = {{1985},{1983}};

DefaultIntervalCategoryDataset dataset =

      new DefaultIntervalCategoryDataset(seriesKeys,categoryKeys,starts,ends);




    return dataset;
}

...

IntervalBarRenderer renderer = new IntervalBarRenderer();

CategoryPlot plot = new CategoryPlot(dataset,domainAxis,valueAxis1,renderer);

chart = new JFreeChart("DefaultIntervalCategory Demo",plot);   

我想在堆叠条形渲染器中使用相同的数据集。我已经尝试过使用它,但它的价值总是以最小值开始......它产生了从1980年到1985年和1985年到1987年的堆栈栏

如何使用间隔数据集实现堆栈栏而不从最小值开始?

3 个答案:

答案 0 :(得分:0)

如果设置范围

,对我来说没问题
CategoryPlot plot = (CategoryPlot) chart.getPlot();

ValueAxis rageAxis = plot.getRangeAxis();
rageAxis.setRange(new Range(1980, 1990));

IntervalBarRenderer renderer = new IntervalBarRenderer();
plot.setRenderer(renderer);

enter image description here

答案 1 :(得分:0)

我得到了我的要求的解决方案。我创建了多个数据集/间隔条渲染器。第一个数据集和渲染器设置在索引位置0(默认值),另一个数据集/渲染器设置在索引位置1.这会使用间隔条渲染器生成堆栈栏的效果。

答案 2 :(得分:0)

Jfree图表没有给出任何适当的api来制作堆积区间条形图。 您有适当的api来制作间隔条形图,如上面的答案中所示。但是上面列出的间隔并没有堆叠。

要沿Y轴制作堆叠间隔条形图,我发现这样做的唯一方法是非常脏和黑客,因此,我选择使用间隔条形图,即使这不是理想的。 / p>

要制作堆叠间隔条形图,您可以做的是。

(a)说两个数据系列 数据系列1 - 边缘的行程时间 数据系列2 - 边缘结束时的等待时间

(b)你会有以下形式的间隔:

double [] [] lowerBoundInterval = { {startTravelTimeEdge1, StartStravelTimeEdge2}, {startSleepingAtEdge1, startSleepingAtEdge2} }

(c)你将拥有相同的两个时间序列,其上限为

double [] [] upperBoundInterval = { {endTravelTimeEdge1, endTravelTimeEdge2}, {endSleepingAtEdge1, endSleepTimeEdge2} }

现在,如果你尝试使用ChartFactory.createStackedBarChar t,你会发生什么事情,JfreeChart会将每个间隔(tralveTime)和(sleepTime)视为与末端长度叠加在一起的全长条时间。 你的酒吧将从零开始。所以你根本看不到任何间隔。 对于你想要实际表达的内容,你会发现任何事情都没有意义。

为了解决这个限制,我发现了一些工作" - 但是我不使用它,因为它太脏我的味道,是以下。

您可以创建第三个数据系列,我称之为隐形人工数据系列。

此数据系列对应于您要堆叠在一起的其他两个数据系列的下限值。 在我给出的示例中,startTravelTimeOnEdge(i)对应于我们要复制到我们的艺术数据系列的值。

之后,您需要转换您关心的真实数据系列,数据系列大小。 在这种情况下,这意味着我们将计算from的间隔数据系列: [0 - (Endtralve-timeEdge1 - StarttravelTimeEdge1)]。 为什么? 因为第一个不可见的时间序列确保相关的起始系列从当前时间点开始堆叠在一起。 通过使相关的间隔成为长度,您可以绘制一个图表区域,该区域与您想要看到的内容相对应。

要隐藏不可见的时间序列,您需要调整GroupedStackedBarRenderer renderer = new GroupedStackedBarRenderer() E.g。

renderer.setSeriesPaint(0, new Color(0, 0, 0, 0));

像上面那样。

这样做的原因是,你有一个第一个假的aritifial时间序列,用于移动你将要在正确的高度绘制的第一个时间序列。

注意: 要非常清楚我对数据系列的hacky算法的意义。 我将说明hacky数据系列的外观。

您的下限和上限时间序列变为:

      double [] [] lowerBoundInterval = {
 // atificial invisible data series
 {startTravelTimeEdge1, StartStravelTimeEdge2},
 // start travel time series
 {0, 0},
 // start sleep time series
 {0, 0} }


        double [] [] upperBoundInterval = { 
// atificial invisible data series
 {startTravelTimeEdge1, StartStravelTimeEdge2}
,
{endTravelTimeEdge1 - startTravelTimeEdge1, endTravelTimeEdge2 - startTravelTimeEdge2}, {endSleepingAtEdge1 - startSleepingAtEdge1, endSleepTimeEdge2 - startSleepTimeEdge2} }

通过上面的例子,我相信你可以了解jfree图表apis的黑客背后的逻辑。

总结解决方案是: (A)创建一个新的无用的时间序列,以便为您关注的数据系列移动条形图。并使人工数据系列的栏变得不可见 (b)将数据系列从它们所代表的实际间隔转换为它们在堆叠时所代表的长度

使第一个数据系列不可见,这样你就可以在堆栈中留下空白。 让您的间隔范围数据系列着色。

你得到你的间隔数据系列。

这是太多的工作,没有人必须维护代码来渲染基于区间的堆栈图表,我们希望看看这样的代码。 因此,我建议如果允许,请使用未堆叠的纯间隔图表。enter image description here 你可以在同一类别的X中获得更多的数据...但是在维护成本方面,它要低得多,而且可读性也很高......也许它不是那么直观,但在任何情况下都不是那么遥远

下图显示了使用此方法的堆叠invterval条形图。