如何将标签值和误差线添加到JFreeChart折线图?

我正在使用JFreeChart创建折线图,这些折线图作为图像导出并嵌入到自动生成的文档中。 例如,一个简单的折线图如下所示:

简单的线条图

我用来显示值的代码是:

LineAndShapeRenderer renderer = new LineAndShapeRenderer(true, false); chart.getCategoryPlot().setRenderer(renderer); renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator("{2}", NumberFormat.getNumberInstance())); renderer.setBaseItemLabelsVisible(true); 

我还想添加错误条来显示每个点的标准偏差,这可以通过使用StatisticalLineAndShapeRenderer(当然还有错误值添加到数据集)来完成,这样上面的chode现在变为:

 StatisticalLineAndShapeRenderer renderer = new StatisticalLineAndShapeRenderer(true, false); chart.getCategoryPlot().setRenderer(renderer); renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator("{2}", NumberFormat.getNumberInstance())); renderer.setBaseItemLabelsVisible(true); 

使用此代码,图表将生成错误栏,但标签已消失。 从图中可以看出:

带有误差线的线图

我试图找到一个包含错误栏和标签的在线示例,但我没有这样做。 使用Statustical Renderer时为什么标签会消失,有什么方法吗?

编辑:添加了最小和自包含的示例。

 DefaultStatisticalCategoryDataset dataset = new DefaultStatisticalCategoryDataset(); dataset.add(1, 0.1, "serie", "A"); dataset.add(2, 0.4, "serie", "B"); dataset.add(2, 0.2, "serie", "C"); JFreeChart chart = ChartFactory.createLineChart("Chart", null, null, dataset, PlotOrientation.VERTICAL, false, true, true); LineAndShapeRenderer renderer = new LineAndShapeRenderer(true, false); chart.getCategoryPlot().setRenderer(renderer); renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator("{2}", NumberFormat.getNumberInstance())); renderer.setBaseItemLabelsVisible(true); JFreeChart chartErrorBars = ChartFactory.createLineChart("ErrorBars", null, null, dataset, PlotOrientation.VERTICAL, false, true, true); StatisticalLineAndShapeRenderer statisticalRenderer = new StatisticalLineAndShapeRenderer(true, false); chartErrorBars.getCategoryPlot().setRenderer(statisticalRenderer); statisticalRenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator("{2}", NumberFormat.getNumberInstance())); statisticalRenderer.setBaseItemLabelsVisible(true); int width = 1500; int height = 400; try { FileOutputStream fos = new FileOutputStream(new File("chart.png")); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ChartUtilities.writeChartAsPNG(baos, chart, width, height); baos.writeTo(fos); baos.close(); fos.close(); fos = new FileOutputStream(new File("chartErrorBars.png")); baos = new ByteArrayOutputStream(); ChartUtilities.writeChartAsPNG(baos, chartErrorBars, width, height); baos.writeTo(fos); baos.close(); fos.close(); } catch (IOException e) { e.printStackTrace(); } 

并且由该代码生成的两个图像。

带值的简单示例带错误条的简单示例

当父LineAndShapeRenderer方法getItemShapeVisible()返回true时, StatisticalLineAndShapeRenderer显示标签。 在下面的示例中,我避开了图表工厂并使用了显式的StatisticalLineAndShapeRenderer构造函数来启用形状和线条。

 StatisticalLineAndShapeRenderer renderer = new StatisticalLineAndShapeRenderer(true, true); 

是否有任何特定的理由要避免使用ChartFactory

虽然重新利用ChartFactory是有利的,但它让人想起在烤面包上点鸡,拿鸡,烤面包 。 更重要的是, 丢弃的 LineAndShapeRenderer带有所请求的工具提示和URL生成器,可能令未来的维护者感到困惑。

有什么方法可以禁用形状?

如你所知 ,空Shape是有效的,例如

 renderer.setSeriesShape(0, new Rectangle2D.Double(0, 0, 0, 0)); 

图片

 import java.awt.Dimension; import java.awt.EventQueue; import java.text.NumberFormat; import javax.swing.JFrame; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.StandardChartTheme; import org.jfree.chart.axis.CategoryAxis; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.renderer.category.StatisticalLineAndShapeRenderer; import org.jfree.data.statistics.DefaultStatisticalCategoryDataset; /** * @see https://stackoverflow.com/a/38080778/230513 */ public class Test { private void display() { JFrame f = new JFrame("Test"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); DefaultStatisticalCategoryDataset dataset = new DefaultStatisticalCategoryDataset(); dataset.add(1, 0.1, "series", "A"); dataset.add(2, 0.4, "series", "B"); dataset.add(2, 0.2, "series", "C"); CategoryAxis domain = new CategoryAxis(); ValueAxis range = new NumberAxis(); StatisticalLineAndShapeRenderer renderer = new StatisticalLineAndShapeRenderer(true, true); CategoryPlot plot = new CategoryPlot(dataset, domain, range, renderer); JFreeChart chart = new JFreeChart( "ErrorBars", JFreeChart.DEFAULT_TITLE_FONT, plot, false); renderer.setBaseItemLabelGenerator( new StandardCategoryItemLabelGenerator("{2}", NumberFormat.getNumberInstance())); renderer.setBaseItemLabelsVisible(true); renderer.setSeriesShape(0, new Rectangle2D.Double(0, 0, 0, 0)); new StandardChartTheme("JFree").apply(chart); f.add(new ChartPanel(chart) { @Override public Dimension getPreferredSize() { return new Dimension(600, 300); } }); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(new Test()::display); } }