如何在动态 JFreechart 上绘制三条线?
How to draw three lines on dynamic JFreechart?
我想在时间图表的 xy 轴上为三个值绘制三条线。从这个有用的页面 How to adjust the xand y axis line in jfreecharts 我可以在时间图表上为一个值画一条线,所以我的问题是如何在时间图表上画三条线?
注意画三线简化为画两条线,所以如果你能画两条线,那么你就可以回答这个问题,我只是想找到这段代码中的关键作用绘制一条线以添加另一条线。
为了做到这一点,我尝试将以下 this.series.add(new Millisecond(), this.lastValue2);
放在 actionPerformed()
上并定义一个新的 dataset
但这没有帮助。
这是取自之前 link [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);
}
}
好吧,显然你什么都没试过,比如改变样本。尽管如此,我还是会尝试通过简单地更改 "your" 示例来帮助您,因此我不会显示所有代码,只显示更改的部分。
首先,您需要三个数据集,因为将同一个数据集绘制三次是没有意义的:
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;
}
这是修改后的例子运行:
如您所见,这是生成图表的固定示例,您可以更改示例以动态方式生成。
我想在时间图表的 xy 轴上为三个值绘制三条线。从这个有用的页面 How to adjust the xand y axis line in jfreecharts 我可以在时间图表上为一个值画一条线,所以我的问题是如何在时间图表上画三条线?
注意画三线简化为画两条线,所以如果你能画两条线,那么你就可以回答这个问题,我只是想找到这段代码中的关键作用绘制一条线以添加另一条线。
为了做到这一点,我尝试将以下 this.series.add(new Millisecond(), this.lastValue2);
放在 actionPerformed()
上并定义一个新的 dataset
但这没有帮助。
这是取自之前 link [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);
}
}
好吧,显然你什么都没试过,比如改变样本。尽管如此,我还是会尝试通过简单地更改 "your" 示例来帮助您,因此我不会显示所有代码,只显示更改的部分。
首先,您需要三个数据集,因为将同一个数据集绘制三次是没有意义的:
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;
}
这是修改后的例子运行:
如您所见,这是生成图表的固定示例,您可以更改示例以动态方式生成。