JFreeCharts字幕显示在传奇下面?

时间:2015-07-01 16:50:10

标签: java alignment jfreechart legend

我正在使用JFreeCharts,我将图例和字幕都放在图表的顶部。但是,我的愿望是拥有标题,然后是第二行的副标题,然后是下面的图例。相反,它有标题,然后是传奇,然后是副标题。这是当前的布局:

正如您所看到的,图例位于字幕上方,而它应该是另一种方式。所有这一切,标题,图例和副标题都应该在图表上方。

我制作图表和自定义标题,副标题和图例的当前代码是:

public JFreeChart createStackedChart(final CategoryDataset categorydataset, String Title) throws DocumentException, IOException {
    final JFreeChart chart = ChartFactory.createStackedBarChart(
            Title, // chart title
            "", // domain axis label
            "", // range axis label
            categorydataset, // data
            PlotOrientation.VERTICAL, // the plot orientation
            true, // legend
            true, // tooltips
            false // urls
    );

    chart.setTitle(
            new org.jfree.chart.title.TextTitle(Title,
                    new java.awt.Font("Calibri", java.awt.Font.PLAIN, 12)
            ));
    chart.getTitle().setPaint(Color.GRAY);
    Color subExc = new Color(237,125,49);
    chart.addSubtitle(new TextTitle("Title",
            new Font("Calibri", Font.PLAIN, 12), subExc,
            RectangleEdge.TOP, HorizontalAlignment.CENTER,
            VerticalAlignment.TOP, RectangleInsets.ZERO_INSETS));
    chart.addSubtitle(new TextTitle("Title2",
            new Font("Calibri", Font.PLAIN, 12), Color.GRAY,
            RectangleEdge.TOP, HorizontalAlignment.CENTER,
            VerticalAlignment.TOP, RectangleInsets.ZERO_INSETS));


    LegendTitle legend = chart.getLegend();
    legend.setPosition(RectangleEdge.TOP);
    chart.getLegend().setFrame(BlockBorder.NONE);
    legend.setItemPaint(Color.GRAY);
    Font labelFont = new Font("Calibri", Font.PLAIN, 8);
    legend.setItemFont(labelFont);

    int columnCount = categorydataset.getColumnCount();
    chart.setBackgroundPaint(Color.white);
    chart.getTitle().setPadding(10, 2, 0, 2);
    chart.setBorderVisible(true);
    chart.setBorderPaint(Color.lightGray);

    final CategoryPlot plot = chart.getCategoryPlot();
    plot.setBackgroundPaint(Color.white);

    plot.setDomainGridlinePaint(Color.lightGray);
    plot.setRangeGridlinePaint(Color.lightGray);
    plot.setDomainGridlineStroke(new BasicStroke(0.5f));
    plot.setRangeGridlineStroke(new BasicStroke(0.5f));
    plot.setOutlineVisible(true);
    plot.setOutlinePaint(Color.lightGray);
    plot.setAxisOffset(new RectangleInsets(0, 0, 0, 0));

    final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
    rangeAxis.setTickLabelFont(new Font("Calibri", Font.PLAIN, 9)); 
    rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
    rangeAxis.setAutoRangeStickyZero(false);
    rangeAxis.setLowerMargin(0.0);

    rangeAxis.setTickLabelPaint(Color.GRAY);
    rangeAxis.setTickMarkPaint(Color.lightGray);
    rangeAxis.setTickMarkStroke(new BasicStroke(0.3f));
    rangeAxis.setAxisLineStroke(new BasicStroke(0.3f));
    rangeAxis.setLowerBound(0.0f);
    rangeAxis.setAxisLinePaint(Color.lightGray);

    GroupedStackedBarRenderer renderer = new GroupedStackedBarRenderer();
    renderer.setDrawBarOutline(false);
    renderer.setBarPainter(new StandardBarPainter());

    Paint p1 = new GradientPaint(
            0.0f, 0.0f, new Color(0x22, 0x22, 0xFF), 0.0f, 0.0f, new Color(0x88, 0x88, 0xFF)
    );
    renderer.setSeriesPaint(0, p1);
    renderer.setSeriesPaint(4, p1);
    renderer.setSeriesPaint(8, p1);

    Paint p2 = new GradientPaint(
            0.0f, 0.0f, new Color(0x22, 0xFF, 0x22), 0.0f, 0.0f, new Color(0x88, 0xFF, 0x88)
    );
    renderer.setSeriesPaint(1, p2);
    renderer.setSeriesPaint(5, p2);
    renderer.setSeriesPaint(9, p2);

    Paint p3 = new GradientPaint(
            0.0f, 0.0f, new Color(0xFF, 0x22, 0x22), 0.0f, 0.0f, new Color(0xFF, 0x88, 0x88)
    );
    renderer.setSeriesPaint(2, p3);
    renderer.setSeriesPaint(6, p3);
    renderer.setSeriesPaint(10, p3);

    Paint p4 = new GradientPaint(
            0.0f, 0.0f, new Color(0xFF, 0xFF, 0x22), 0.0f, 0.0f, new Color(0xFF, 0xFF, 0x88)
    );
    renderer.setSeriesPaint(3, p4);
    renderer.setSeriesPaint(7, p4);
    renderer.setSeriesPaint(11, p4);
    renderer.setGradientPaintTransformer(
            new StandardGradientPaintTransformer(GradientPaintTransformType.HORIZONTAL)
    );

    final CategoryAxis domainAxis = plot.getDomainAxis();
    domainAxis.setTickLabelPaint(Color.GRAY);
    domainAxis.setTickLabelFont(new Font("Calibri", Font.PLAIN, 9));
    Color transparent = new Color(0, 0, 0, 0);
    domainAxis.setAxisLinePaint(transparent);
    domainAxis.setTickMarkPaint(Color.lightGray);
    domainAxis.setTickMarkStroke(new BasicStroke(0.3f));
    domainAxis.setMaximumCategoryLabelWidthRatio(4f);

    if (columnCount == 2) {
        domainAxis.setCategoryMargin(.6);
        domainAxis.setLowerMargin(0.015);
        domainAxis.setUpperMargin(0.015);
    } else if (columnCount == 3) {
        domainAxis.setCategoryMargin(.35);
        domainAxis.setLowerMargin(0.15);
        domainAxis.setUpperMargin(0.15);
    } else {
        domainAxis.setCategoryMargin(.55);
        domainAxis.setLowerMargin(0.015);
        domainAxis.setUpperMargin(0.015);
    }

    if (columnCount >= 5) {
        domainAxis.setCategoryLabelPositions(
                CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 4.0));
        chart.setPadding(new RectangleInsets(0, 5, 0, 5));
    } else {
        domainAxis.setCategoryLabelPositions(
                STANDARD);
    }
    plot.setDomainAxis(domainAxis);

    return chart;

}

除了RectangleEdge TOP,我还能做些什么才能确定图例和字幕的堆叠顺序?谢谢!

2 个答案:

答案 0 :(得分:2)

实际上,我找到了一个解决方案。以防这有助于其他人。答案的灵感来源于:

http://www.jfree.org/phpBB2/viewtopic.php?f=3&t=23187

我必须更改我的代码才能合并它。我写了

    chart.addSubtitle(0,new TextTitle("Title",
            new Font("Calibri", Font.PLAIN, 12), subExc,
            RectangleEdge.TOP, HorizontalAlignment.CENTER,
            VerticalAlignment.TOP, RectangleInsets.ZERO_INSETS));
    chart.addSubtitle(1,new TextTitle("Title2",
            new Font("Calibri", Font.PLAIN, 12), Color.GRAY,
            RectangleEdge.TOP, HorizontalAlignment.CENTER,
            VerticalAlignment.TOP, RectangleInsets.ZERO_INSETS));

添加0和1会使这些字幕在图例之前写入。

答案 1 :(得分:1)

这是一个可以解决这个问题的解决办法:

  • 请勿在图表中绘制图例:chart.removeLegend();
  • ChartPanel包裹在JPanel内(BorderLayout
  • 在面板的南部位置,添加手动生成的图例:

应该是这样的:

public static JPanel wrapChart(ChartPanel chartPanel) {
    JPanel panel = new JPanel(new BorderLayout());
    panel.add(chartPanel, BorderLayout.CENTER);
    panel.add(createLegend(chartPanel.getChart().getPlot()), BorderLayout.SOUTH);
    return panel;
}

private static JPanel createLegend(Plot plot) {
    JPanel panel = new JPanel(); // Using FlowLayout here
    Iterator iterator = plot.getLegendItems().iterator();
    while (iterator.hasNext()) {
        LegendItem item = (LegendItem) iterator.next();
        JLabel label = new JLabel(item.getLabel());
        label.setIcon(new ColorIcon(8, item.getFillPaint()));
        panel.add(label);
    }
    return panel;
}

(从this answer借来的createLegend()方法)