【问题标题】:JFreeCharts - Making a chart with X as category and Y as TimeIntervalJFreeCharts - 使用 X 作为类别和 Y 作为 TimeInterval 制作图表
【发布时间】:2017-05-10 19:04:30
【问题描述】:

我正在尝试在 JFreeChart 中查找 api,这将允许我建立一个图表,其中 X 轴较长,我将有类别,Y 轴间隔值对应于时间。

Y 轴应该代表时间。 X轴类。

这类似于谷歌日历场景,其中在 X 轴上,例如星期几。在 Y 轴上,您可以写下您在特定时间区域内所做的事情。

下面的 JFREE 图表代表了我想要代表的内容。 但是,我的 Y 轴以毫秒为单位而不是时间单位(例如秒)。

在下图中,我说明了沿 X 的类别,我们可以想象它们就像图上的一条边。

在 Y 轴上,我们有一些时间花在旅行上,然后在旅行后花时间说培养它。

Y 轴由 double 值组成,最好能够使用适当的时间轴。使用类别数据集时,这似乎是个问题。 为了制作下面的图表,必须实施许多技巧,以使堆栈不会从 0 开始呈现 - 通过具有不可见的数据系列。

【问题讨论】:

  • 为什么没有像this 这样的DateAxis 但对于范围轴?
  • 如果将 Y 轴操作为日期轴。您究竟是如何构建 DataSeries 的?当您创建日期系列时: final DefaultIntervalCategoryDataset dataset = new DefaultIntervalCategoryDataset(seriesKeys, categoryKeys, intervalLowerBound, intervalUpperBound);
  • inverval下限和上限中的所有数据,在这种情况下将Y轴间隔时间定义为毫秒。
  • 我的印象是,JFree 图表中的时间不会与标签混合时间。但我可能弄错了。在这种情况下,我不知道如何使用适当的 API 构建我想要的东西。我似乎暗示的数据系列类,轴类仅与数字混合。时间序列轴与时间或数字混合,但不与标签混合。想要有一个时间间隔并用一个条形占据一个时间间隔是我希望成为一个常见用例的事情。在这里,我的印象是条形字符总是有重力将它们从零开始。而不是间隔开始。
  • 注意:我相信 ChartFactory.createXYBarChart 可以解决这个问题。有一个演示应用程序github.com/ngadde/playground/blob/master/com.iis.sample1/src/… 演示了一些非常灵活的东西。玩弄时间和符号。而且他能够在布局中的任何地方绘制条形图。我将看到如何使用 IntervalXYDataSet 的非类别数据集创建上面的示例,其中一个轴是时间,另一个用于制作条形厚度的人工间隔。我稍后会发布代码作为答案

标签: jfreechart


【解决方案1】:

Althgout 如何使用 JFreeChart 来解决上面发布的问题肯定不是很明显,基于我的 cmets 中提到的 demo7 示例,我现在可以说绝对可以使用 XYBarChart 作为引擎来渲染条形图问题的正确位置,同时有一个代表时间的轴和另一个代表您想要的任何内容(例如类别)的轴。

sample7 示例使用数轴并将数轴的间隔分配为使用条形进行渲染的步骤。

这样,问题可以很容易地适应我上面的问题,这里是适应的应用程序,它以适当的方式伪实现我的问题上的图表。

import java.awt.Color;

import javax.swing.JPanel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.SymbolAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.data.xy.IntervalXYDataset;
import org.jfree.data.xy.XYIntervalSeries;
import org.jfree.data.xy.XYIntervalSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
public class XYBarChartDemo7VarianRepresentingStackOverFlowQuestion extends ApplicationFrame {

    /**
     * Constructs the demo application.
     *
     * @param title
     *            the frame title.
     */
    public XYBarChartDemo7VarianRepresentingStackOverFlowQuestion(String title) {
        super(title);
        JPanel chartPanel = createDemoPanel();
        chartPanel.setPreferredSize(new java.awt.Dimension(500, 300));
        setContentPane(chartPanel);
    }

    private static JFreeChart createChart(IntervalXYDataset dataset) {
        JFreeChart chart = ChartFactory.createXYBarChart("XYBarChartDemo7", "Date", true, "Y", dataset,
                PlotOrientation.HORIZONTAL, true, false, false);

        XYPlot plot = (XYPlot) chart.getPlot();

        // The Y axis is turned into a date axis
        plot.setRangeAxis(new DateAxis("Date"));

        // The X axis is turned is turned into a label axis
        SymbolAxis xAxis = new SymbolAxis("Series",
                new String[] { "R107 => R101", "R101 => R5", "R5 => R15", "R15 => R16" });
        xAxis.setGridBandsVisible(false);
        plot.setDomainAxis(xAxis);

        // Enables using Y interval
        XYBarRenderer renderer = (XYBarRenderer) plot.getRenderer();
        renderer.setUseYInterval(true);
        plot.setRenderer(renderer);
        plot.setBackgroundPaint(Color.lightGray);
        plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);

        ChartUtilities.applyCurrentTheme(chart);

        return chart;
    }

    /**
     * Creates a sample dataset.
     *
     * @return A dataset.
     */
    private static IntervalXYDataset createDataset() {
        // Time points to represnet
        // Edge: "R107 => R101"
        RegularTimePeriod d0 = new Day(12, 6, 2007);
        RegularTimePeriod d1 = new Day(13, 6, 2007);
        RegularTimePeriod d2 = new Day(14, 6, 2007);

        // "R101 => R5"
        RegularTimePeriod d3 = new Day(15, 6, 2007);
        RegularTimePeriod d4 = new Day(16, 6, 2007);
        RegularTimePeriod d5 = new Day(17, 6, 2007);

        // "R5 => R15"
        RegularTimePeriod d6 = new Day(18, 6, 2007);
        RegularTimePeriod d7 = new Day(19, 6, 2007);
        RegularTimePeriod d8 = new Day(20, 6, 2007);

        // "R15 => R16"
        RegularTimePeriod d9 = new Day(21, 6, 2007);
        RegularTimePeriod d10 = new Day(22, 6, 2007);
        RegularTimePeriod d11 = new Day(23, 6, 2007);

        /// Next edge that is not part of the path
        RegularTimePeriod d12 = new Day(24, 6, 2007);

        // Create three interval series (each series has a different color)
        XYIntervalSeriesCollection dataset = new XYIntervalSeriesCollection();
        XYIntervalSeries s1 = new XYIntervalSeries("ProductiveTime");
        XYIntervalSeries s2 = new XYIntervalSeries("WaitTime");

        // Series 1 and series2 along edge1
        addItem(s1, d0, d1, 0);
        addItem(s2, d1, d3, 0);
        // Series 1 and series2 along edge2
        addItem(s1, d3, d4, 1);
        addItem(s2, d4, d6, 1);
        // Series 1 and series2 along edge3
        addItem(s1, d6, d7, 2);
        addItem(s2, d7, d9, 2);
        // Series 1 and series2 along edge4
        addItem(s1, d9, d10, 3);
        addItem(s2, d10, d12, 3);

        // puts in the data set the data series
        dataset.addSeries(s1);
        dataset.addSeries(s2);
        return dataset;
    }

    private static void addItem(XYIntervalSeries s, RegularTimePeriod p0, RegularTimePeriod p1, int index) {
        s.add(index,
                // xLow x xHigh we see this on the Y because chart is horizontal
                index - 0.45, index + 0.45, p0.getFirstMillisecond(),
                // yLow yHigh (time interval) - we see this on the X because chart is set as horizontal
                // NOTE: - notice how miliseconds are being used to make the xy interval and not
                // actually a date object. But then on the date axis we shall have a proper DateAxis for rendering
                // these miliseconds values
                p0.getFirstMillisecond(), p1.getFirstMillisecond());
    }

    /**
     * Creates a panel for the demo.
     *
     * @return A panel.
     */
    public static JPanel createDemoPanel() {
        return new ChartPanel(createChart(createDataset()));
    }

    /**
     * Starting point for the demonstration application.
     *
     * @param args
     *            ignored.
     */
    public static void main(String[] args) {
        XYBarChartDemo7VarianRepresentingStackOverFlowQuestion demo = new XYBarChartDemo7VarianRepresentingStackOverFlowQuestion(
                "JFreeChart : XYBarChartDemo7.java");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }

}

下面的图片说明了如何离开 BarChart 和类别数据集,进入 XYBarChart 和 IntervalXYDataSets,我们可以在我们想要的地方渲染条形图。

请注意,如果我们垂直绘制图表,它将看起来与问题中的第一个图表完全相同。 Y 轴为时间轴,X 轴为类别。

所以,另一个满意的用户。

【讨论】:

  • 检查了一个类似的问题here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-17
相关资源
最近更新 更多