将与部分无关的文本添加到 JFreeChart PieChart 中的图例中

发布于 2024-12-08 09:48:23 字数 2357 浏览 0 评论 0原文

有没有办法在 JFreeChart 饼图的图例中包含一些任意文本?我知道可以分配一个 PieSectionLabelGenerator 来自定义图表图例上显示的每个饼图部分的标签。

我想在图例中插入一些与饼图部分完全无关的文本,例如“图例”。

我正在像这样构建图表:

private JFreeChart constructChart() {
    List<Object[]> llistaValorsArr;

    ParamsDTO dto = (ParamsDTO) getModelObject();
    List llistaValors = statisticsService.getStatistics(dto);
    if (!llistaValors.isEmpty() && !(llistaValors.get(0) instanceof Object[])){
        llistaValorsArr = new ArrayList<Object[]>();
        llistaValorsArr.add(new Object[]{llistaValors.get(0), ""});
    }
    else{
        llistaValorsArr = (List<Object[]>) llistaValors;
    }
    DefaultPieDataset dataSet = new DefaultPieDataset();
    for (Object[] objects : llistaValorsArr) {
        dataSet.setValue((Comparable) objects[1], (Number)objects[0]);
    }

    String title = "Total: " +  new Double(DatasetUtilities.calculatePieDatasetTotal(dataSet)).intValue();
    JFreeChart chart = ChartFactory.createPieChart(title, dataSet, true, false, true);

    final PiePlot plot = (PiePlot) chart.getPlot();
    plot.setForegroundAlpha(0.5f);
    plot.setNoDataMessage("No data");

    PieSectionLabelGenerator labelGenerator = new StandardPieSectionLabelGenerator("{0} - {1} ({2})"){
        @Override
        protected Object[] createItemArray(PieDataset dataset, Comparable key) {
            // TODO Auto-generated method stub
            Object[] array = super.createItemArray(dataset, key);
            array[0] = getEntityLabel(key);
            return array;
        }
    };
    plot.setLabelGenerator(labelGenerator);
    plot.setLegendLabelGenerator(labelGenerator);        
    //plot.setStartAngle(290);
    boolean circular = true;
    plot.setCircular(circular);
    return chart;
}

更新:我刚刚发现JFreeChart.addSubtitle(),希望它允许定位它就在图例上方,但它只会在图表标题旁边添加一个副标题。

更新2:我一直在尝试将TextTitle放入LegendTitle的包装器中,但在图表构建时它似乎为空。

LegendTitle legend = chart.getLegend();
BlockContainer container = legend.getWrapper();
container.add(new TextTitle("Legend"));

添加“图例”文本来装饰图例实际上不应该那么复杂。

Is there a way to include some arbitrary text in the legend in a JFreeChart PieChart? I know it's possible to assign a PieSectionLabelGenerator in order to customize the labels of each of the Pie's sections that appear on the chart's legend.

I'd like to insert some text into the legend, completely unrelated to any of the pie sections, like, for instance, "Legend".

I'm building the Chart like this:

private JFreeChart constructChart() {
    List<Object[]> llistaValorsArr;

    ParamsDTO dto = (ParamsDTO) getModelObject();
    List llistaValors = statisticsService.getStatistics(dto);
    if (!llistaValors.isEmpty() && !(llistaValors.get(0) instanceof Object[])){
        llistaValorsArr = new ArrayList<Object[]>();
        llistaValorsArr.add(new Object[]{llistaValors.get(0), ""});
    }
    else{
        llistaValorsArr = (List<Object[]>) llistaValors;
    }
    DefaultPieDataset dataSet = new DefaultPieDataset();
    for (Object[] objects : llistaValorsArr) {
        dataSet.setValue((Comparable) objects[1], (Number)objects[0]);
    }

    String title = "Total: " +  new Double(DatasetUtilities.calculatePieDatasetTotal(dataSet)).intValue();
    JFreeChart chart = ChartFactory.createPieChart(title, dataSet, true, false, true);

    final PiePlot plot = (PiePlot) chart.getPlot();
    plot.setForegroundAlpha(0.5f);
    plot.setNoDataMessage("No data");

    PieSectionLabelGenerator labelGenerator = new StandardPieSectionLabelGenerator("{0} - {1} ({2})"){
        @Override
        protected Object[] createItemArray(PieDataset dataset, Comparable key) {
            // TODO Auto-generated method stub
            Object[] array = super.createItemArray(dataset, key);
            array[0] = getEntityLabel(key);
            return array;
        }
    };
    plot.setLabelGenerator(labelGenerator);
    plot.setLegendLabelGenerator(labelGenerator);        
    //plot.setStartAngle(290);
    boolean circular = true;
    plot.setCircular(circular);
    return chart;
}

UPDATE: I just found out JFreeChart.addSubtitle(), hoping it would allow to position it just above the legend, but it will just add a subtitle next to the chart's Title.

UPDATE 2: I've been trying to place a TextTitle inside the LegendTitle's wrapper, but it appears to be null at chart construction time.

LegendTitle legend = chart.getLegend();
BlockContainer container = legend.getWrapper();
container.add(new TextTitle("Legend"));

It shouldn't really be that complicated to add a 'Legend' text to decorate the legend.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

陌路黄昏 2024-12-15 09:48:23

查看 org.jfree 的源代码.chart.JFreeChart,看到 addLegend() 只不过是幕后的 addSubtitle(),一切都表明这应该可以使用addSubtitle()来实现。

查看 org.jfree 的部分。 Chart.JFreeChart 添加了自己的 LegendTitle 项,我们可以找到 JFreeChart 用于放置图例 此处

因此,解决方案是以类似的方式将 TextTitle 添加到 Chart 中。这里的相关设置是setPosition(RECTANGLE.BOTTOM)

TextTitle legendText = new TextTitle("This is LEGEND: ");
legendText.setPosition(RectangleEdge.BOTTOM);
chart.addSubtitle(legendText);

Looking at the source code of org.jfree.chart.JFreeChart, and seeing that addLegend() is nothing more than addSubtitle() behind the scenes, everything indicates that this should be achieved using addSubtitle().

Looking at the part where org.jfree.chart.JFreeChart adds its own LegendTitle item, we can find the setup JFreeChart uses for placing the Legend here.

So, the solution is to add, for instance, a TextTitle to the Chart in an analogous way. The relevant setting here is setPosition(RECTANGLE.BOTTOM).

TextTitle legendText = new TextTitle("This is LEGEND: ");
legendText.setPosition(RectangleEdge.BOTTOM);
chart.addSubtitle(legendText);
入怼 2024-12-15 09:48:23

我最近构建了一个多轴图表,并提出了此方案来区分我显示的时间段,使用折线图显示前 12 个月,而条形图显示当前 12 个月。

如果您想在其他系列之前添加文本,使您的图例看起来像这样:

前 12 个月:* 费用 * adj * 现金 当前 12 个月:* 费用 * adj * 现金

其中 * 是形状/颜色你的系列。 (我本来会包含一张图片,但我没有足够的代表点...这是我第一篇堆栈溢出的帖子=))

然后我建议添加一个系列并将其作为图表中的第一个系列(系列0)。将这个系列命名为您想要显示的任何文本(我的示例是“前 12 个月:”。然后您可以使用一些 java 来自定义系列 0,以便数据不会显示在图表上,但您仍然可以在图例中获得标签这

就是我使折线图线条/形状不可见的自定义方法:

@Override
public void customize(JFreeChart chart, JRChart jasperChart) {
    LineAndShapeRenderer renderer = (LineAndShapeRenderer) chart.getCategoryPlot().getRenderer();

    renderer.setSeriesLinesVisible(0, false);
    renderer.setSeriesShapesVisible(0, false);

    etc ....
}

如果它是另一种类型的图表(例如条形图),则只需使系列 0 的颜色与背景相匹配并为其指定一个值(例如 1)。确实增加了更多空间条形图之间的额外空间使其看起来更好,但如果您喜欢图表条形图之间的间距,则这不是一个好的解决方案,

但不确定这是否有助于回答最初的问题 。对于任何想要在图表图例中添加文本的人来说,这是另一个选择,

享受吧!

I have a Multi Axis chart that i recently built and came up with this scheme to distinguish the time periods i was displaying using a line chart to show the previous 12 months imposed over a bar chart showing the current 12 months.

If you want to add text before your other series so that your legend looks something like this:

Previous 12 Months: * charges * adj * cash Current 12 Months: * charges * adj * cash

where the *'s are the shapes/colors of your series. (i would have included a pic, but i dont have enough rep points ... this is my first post to stack overflow =) )

Then i would suggest adding a series and making it the first series in your chart(s) (series 0). Name this series whatever text you want to display (my example is "Previous 12 Months: ". Then you can use some java to customize series 0 so that the data is not show on the chart, but you still get the label in the legend.

This is what my custmoize method for making a line chart line/shape not visible:

@Override
public void customize(JFreeChart chart, JRChart jasperChart) {
    LineAndShapeRenderer renderer = (LineAndShapeRenderer) chart.getCategoryPlot().getRenderer();

    renderer.setSeriesLinesVisible(0, false);
    renderer.setSeriesShapesVisible(0, false);

    etc ....
}

If it is another type of chart like the bar chart then just make series 0's color to match the background and give it a value like 1. Note that this does add more space between the bars! The extra space between the bars on my chart made it look better, but this wouldn't be a good solution if you like the spacing between your charts bars.

Not sure if this is useful for answering the initial question but its another option for anyone looking to add text the their charts legend.

Enjoy!

一刻暧昧 2024-12-15 09:48:23

另一种可能性是创建一个实现接口 org.jfree.chart.LegendItemSource 的类,该接口提供所有其他图例项。然后,将您自己的 LegendItemSource 添加到您的 LegendTitle 对象(唯一的其他项目源是 PieChart)。

chart.getLegend().setSources(sourcesContainingTheOriginalAndYourNewOne);

如果您想控制图例项的放置位置或每个项源的顺序,您可以覆盖 LegendTitle。

Another possibility is to create a class implementing the interface org.jfree.chart.LegendItemSource which provides all your additional legend items. Then you add your own LegendItemSource to your LegendTitle object (the only other item source is the PieChart).

chart.getLegend().setSources(sourcesContainingTheOriginalAndYourNewOne);

If you want to control where to place the legend items or in which orderm of each item source, you can override LegendTitle.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文