我正在使用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,我还能做些什么才能确定图例和字幕的堆叠顺序?谢谢!
答案 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()
方法)