如何在动态JFreechart上绘制三行?

时间:2016-01-10 13:47:03

标签: java jfreechart

我想在xy轴上的时间图上为三个值绘制三条线。从这个有用的页面How to adjust the xand y axis line in jfreecharts我可以在时间图上为一个值绘制一行,所以我的问题是如何在时间图上绘制三行?

请注意,绘制三行简化为绘制两行,因此如果您可以绘制两行,那么您就能够回答这个问题,我只想在此代码中找到关键角色一行,以便添加另一行。

在某种程度上,我尝试将以下this.series.add(new Millisecond(), this.lastValue2);放在actionPerformed()上并定义一个新的dataset,但这没有用。

这是从上一个链接[1]获取的代码。

public class DynamicLineAndTimeSeriesChart extends ApplicationFrame implements ActionListener {

/** The time series data. */
private TimeSeries series;

/** The most recent value added. */
private double lastValue = 100.0;

/** Timer to refresh graph after every 1/4th of a second */
private Timer timer = new Timer((1000), this);//1/4th = 250 ms, to put 1 minute then = 1000*60. 1 second = 1000 ms, 1/4 secon = 250 ms
private double lastValue2 = 1.0;
/**
 * Constructs a new dynamic chart application.
 *
 * @param title  the frame title.
 */
public DynamicLineAndTimeSeriesChart(final String title) {

    super(title);
    this.series = new TimeSeries("Random Data", Millisecond.class);

    final TimeSeriesCollection dataset = new TimeSeriesCollection(this.series);

    final JFreeChart chart = createChart(dataset, dataset);

    timer.setInitialDelay(1000);

    //Sets background color of chart
    chart.setBackgroundPaint(Color.LIGHT_GRAY);

    //Created JPanel to show graph on screen
    final JPanel content = new JPanel(new BorderLayout());

    //Created Chartpanel for chart area
    final ChartPanel chartPanel = new ChartPanel(chart);

    //Added chartpanel to main panel
    content.add(chartPanel);

    //Sets the size of whole window (JPanel)
    chartPanel.setPreferredSize(new java.awt.Dimension(800, 500));

    //Puts the whole content on a Frame
    setContentPane(content);

    timer.start();

}

/**
 * Creates a sample chart.
 *
 * @param dataset  the dataset.
 *
 * @return A sample chart.
 */
private JFreeChart createChart(final XYDataset dataset, final XYDataset dataset2) 
{
    final JFreeChart result = ChartFactory.createTimeSeriesChart("Dynamic Line And TimeSeries Chart",
        "Time (every 2 minutes)",
        "Value of binary bits",
        dataset,
        true,
        true,
        false
    );
//        
//        final JFreeChart result2 = ChartFactory.createTimeSeriesChart("Dynamic Line And TimeSeries Chart",
//            "Time (every 2 minutes)",
//            "Value of binary bits",
//            dataset,
//            true,
//            true,
//            false
 //        );
//        


    final XYPlot plot = result.getXYPlot();
//        final XYPlot plot2 = result2.getXYPlot();

//        plot2.setBackgroundPaint(Color.BLACK);
//        plot2.setDomainGridlinesVisible(true);
//        

    plot.setBackgroundPaint(new Color(0xffffe0));
    plot.setDomainGridlinesVisible(true);
    plot.setDomainGridlinePaint(Color.lightGray);
    plot.setRangeGridlinesVisible(true);
    plot.setRangeGridlinePaint(Color.lightGray);

    ValueAxis xaxis = plot.getDomainAxis();

    xaxis.setAutoRange(true);

    //Domain axis would show data of 60 seconds for a time
    xaxis.setFixedAutoRange((1*60.0*1000.0));  // 60 seconds = 1 minutes, 60*60.0*1000.0= 1 hour of graph
    xaxis.setVerticalTickLabels(true);

    ValueAxis yaxis = plot.getRangeAxis();
    yaxis.setRange(0.0, 300.0);

//        ValueAxis xaxis2 = plot2.getDomainAxis();

//        xaxis2.setAutoRange(true);
//
//        //Domain axis would show data of 60 seconds for a time
//        xaxis2.setFixedAutoRange((1*60.0*1000.0));  // 60 seconds = 1 minutes, 60*60.0*1000.0= 1 hour of graph
//        xaxis2.setVerticalTickLabels(true);

    ValueAxis yaxis2 = plot.getRangeAxis();
    yaxis2.setRange(0.0, 1000.0);

    return result;
}

public void actionPerformed(final ActionEvent e) {

    final double factor = 0.9 + 0.2*Math.random();
    this.lastValue = this.lastValue * factor;

    this.lastValue2 = Math.random();
   // final Millisecond now = new Millisecond();
    this.series.add(new Millisecond(), this.lastValue);

   // System.out.println("Current Time in Milliseconds = " + now.toString()+", Current Value : "+this.lastValue);
}
}

1 个答案:

答案 0 :(得分:2)

好吧,显然你没有尝试过任何改变样本的事情。即便如此,我也会通过简单地改变你的"来帮助你。示例,所以我不会显示所有代码,只显示已更改的部分。

首先,您需要三个数据集,因为没有意义三次绘制相同的数据集:

private final TimeSeries series;
private final TimeSeries secondSeries;
private final TimeSeries thirdSeries;

在构造函数中看起来像这样:

series = new TimeSeries("Random Data 1");
secondSeries = new TimeSeries("Random Data 2");
thirdSeries = new TimeSeries("Random Data 3");

为了简化数据集创建,我将采用以下方法:

private XYDataset createDataset(final TimeSeries series) {
    return new TimeSeriesCollection(series);
}

我将原始时间序列放在方法中,只是为了组织源:

private void firstTimeSeries(final XYPlot plot) {
    final ValueAxis xaxis = plot.getDomainAxis();
    xaxis.setAutoRange(true);

    // Domain axis would show data of 60 seconds for a time
    xaxis.setFixedAutoRange(60000.0); // 60 seconds
    xaxis.setVerticalTickLabels(true);

    final ValueAxis yaxis = plot.getRangeAxis();
    yaxis.setRange(0.0, 300.0);

    final XYItemRenderer renderer = plot.getRenderer();
    renderer.setSeriesPaint(0, Color.RED);

    final NumberAxis yAxis1 = (NumberAxis) plot.getRangeAxis();
    yAxis1.setTickLabelPaint(Color.RED);
}

" xaxis"和" yaxis"可以是相同的,我们只需要对新数据集使用不同的渲染器,如下所示:

private void secondTimeSeries(final XYPlot plot) {
    final XYDataset secondDataset = this.createDataset(secondSeries);
    plot.setDataset(1, secondDataset); // the second dataset (datasets are zero-based numbering)
    plot.mapDatasetToDomainAxis(1, 0); // same axis, different dataset
    plot.mapDatasetToRangeAxis(1, 0); // same axis, different dataset

    final XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false);
    renderer.setSeriesPaint(0, Color.BLUE);
    plot.setRenderer(1, renderer);
}

private void thirdTimeSeries(final XYPlot plot) {
    final XYDataset thirdDataset = this.createDataset(thirdSeries);
    plot.setDataset(2, thirdDataset); // the third dataset (datasets are zero-based numbering)
    plot.mapDatasetToDomainAxis(2, 0); // same axis, different dataset
    plot.mapDatasetToRangeAxis(2, 0); // same axis, different dataset

    final XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false);
    renderer.setSeriesPaint(0, Color.GREEN);
    plot.setRenderer(2, renderer);
}

createChart方法现在看起来像这样:

private JFreeChart createChart() {
    final XYDataset dataset = this.createDataset(series);
    final JFreeChart result = ChartFactory.createTimeSeriesChart("Dynamic Line And TimeSeries Chart", "Time", "Value", dataset, true, true, false);

    final XYPlot plot = result.getXYPlot();
    plot.setBackgroundPaint(new Color(0xffffe0));
    plot.setDomainGridlinesVisible(true);
    plot.setDomainGridlinePaint(Color.LIGHT_GRAY);
    plot.setRangeGridlinesVisible(true);
    plot.setRangeGridlinePaint(Color.LIGHT_GRAY);

    // first time series
    this.firstTimeSeries(plot);

    // second time series
    this.secondTimeSeries(plot);

    // third time series
    this.thirdTimeSeries(plot);

    return result;
}

正如您所看到的,我更改了createChart,现在它没有参数,因此请在DynamicLineAndTimeSeriesChart中进行更改。

最后,现在我们有三个数据集,所以我们需要生成三个最后的值,如下所示:

@Override
public void actionPerformed(final ActionEvent e) {
    final double factor = 0.9 + 0.2 * Math.random();
    lastValue = this.generateValue(lastValue, factor);
    series.add(new Millisecond(), lastValue);

    final double factor2 = 0.9 + 0.2 * Math.random();
    lastValue2 = this.generateValue(lastValue2, factor2);
    secondSeries.add(new Millisecond(), lastValue2);

    final double factor3 = 0.9 + 0.2 * Math.random();
    lastValue3 = this.generateValue(lastValue3, factor3);
    thirdSeries.add(new Millisecond(), lastValue3);
}

要调整生成的值,请使用:

private double generateValue(final double lastValue, final double factor) {
    final double result = lastValue * factor;
    if (result <= 0.0 || result >= 300.0) {
        return 100.00;
    }
    return result;
}

这是运行修改示例的示例:

正如您所看到的,这是一个生成图表的固定样本,您可以更改样本以动态方式生成。

相关问题