我正在尝试创建一个监控汽油价格的应用程序。目前,我的应用程序有一个GUI,它将信息显示为文本-因此作为一个列表。但是,我现在想添加一个显示器,它将以图形方式显示价格。用户可以选择显示多种类型的汽油,图表每5秒自动更新一次。
我对如何在java中绘制一个非常简单的散点图感到困惑。谁能提建议呢
试试
import javax.swing.*;
import java.awt.geom.*;
import java.awt.Graphics;
import java.util.*;
public class Scatterplot extends JFrame {
private List points = new ArrayList();
public Scatterplot() {
super("Scatterplot");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
points.add(new Point2D.Float(2, 4));
points.add(new Point2D.Float(16, 15));
points.add(new Point2D.Float(20, 14));
points.add(new Point2D.Float(62, 24));
points.add(new Point2D.Float(39, 84));
JPanel panel = new JPanel() {
public void paintComponent(Graphics g) {
for(Iterator i=points.iterator(); i.hasNext(); ) {
Point2D.Float pt = (Point2D.Float)i.next();
g.drawString("X", (int)pt.x, (int)pt.y);
}
}
};
setContentPane(panel);
setBounds(20, 20, 200, 200);
setVisible(true);
}
public static void main(String[] args) {
new Scatterplot();
}
}
使用JavaFX。这是一个简单的线形图示例:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
public class LineChartSample extends Application {
@Override public void start(Stage stage) {
stage.setTitle("Line Chart Sample");
final CategoryAxis xAxis = new CategoryAxis();
final NumberAxis yAxis = new NumberAxis();
xAxis.setLabel("Month");
final LineChart<String,Number> lineChart =
new LineChart<String,Number>(xAxis,yAxis);
lineChart.setTitle("Stock Monitoring, 2010");
XYChart.Series series = new XYChart.Series();
series.setName("My portfolio");
series.getData().add(new XYChart.Data("Jan", 23));
series.getData().add(new XYChart.Data("Feb", 14));
series.getData().add(new XYChart.Data("Mar", 15));
series.getData().add(new XYChart.Data("Apr", 24));
series.getData().add(new XYChart.Data("May", 34));
series.getData().add(new XYChart.Data("Jun", 36));
series.getData().add(new XYChart.Data("Jul", 22));
series.getData().add(new XYChart.Data("Aug", 45));
series.getData().add(new XYChart.Data("Sep", 43));
series.getData().add(new XYChart.Data("Oct", 17));
series.getData().add(new XYChart.Data("Nov", 29));
series.getData().add(new XYChart.Data("Dec", 25));
Scene scene = new Scene(lineChart,800,600);
lineChart.getData().add(series);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
可以增加一个方法,在用户输入新数据后更新stage
。
然而,更好的方法是使用JavaFX中的动画特性和图表。直接从API获取:
JavaFX图表非常适合实时或动态图表(如在线股票,网络流量等)从实时数据集。这里有一个使用模拟数据创建的动态图表示例。时间轴是用于模拟股票价格变化的动态数据时间(小时).
在API中有一个很好的例子:
private XYChart.Series<Number,Number> hourDataSeries;
private NumberAxis xAxis;
private Timeline animation;
private double hours = 0;
private double timeInHours = 0;
private double prevY = 10;
private double y = 10;
// timeline to add new data every 60th of a second
animation = new Timeline();
animation.getKeyFrames().add(new KeyFrame(Duration.millis(1000 / 60), new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent actionEvent) {
// 6 minutes data per frame
for(int count=0; count < 6; count++) {
nextTime();
plotTime();
}
}
}));
animation.setCycleCount(Animation.INDEFINITE);
xAxis = new NumberAxis(0,24,3);
final NumberAxis yAxis = new NumberAxis(0,100,10);
final LineChart<Number,Number> lc = new LineChart<Number,Number>(xAxis,yAxis);
lc.setCreateSymbols(false);
lc.setAnimated(false);
lc.setLegendVisible(false);
lc.setTitle("ACME Company Stock");
xAxis.setLabel("Time");
xAxis.setForceZeroInRange(false);
yAxis.setLabel("Share Price");
yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis,"$",null));
hourDataSeries = new XYChart.Series<Number,Number>();
hourDataSeries.setName("Hourly Data");
hourDataSeries.getData().add(new XYChart.Data<Number,Number>(timeInHours,prevY));
lc.getData().add(hourDataSeries);
private void nextTime() {
if (minutes == 59) {
hours ++;
minutes = 0;
} else {
minutes ++;
}
timeInHours = hours + ((1d/60d)*minutes);
}
private void plotTime() {
if ((timeInHours % 1) == 0) {
// change of hour
double oldY = y;
y = prevY - 10 + (Math.random()*20);
prevY = oldY;
while (y < 10 || y > 90) y = y - 10 + (Math.random()*20);
hourDataSeries.getData().add(new XYChart.Data<Number, Number>(timeInHours, prevY));
// after 25hours delete old data
if (timeInHours > 25) hourDataSeries.getData().remove(0);
// every hour after 24 move range 1 hour
if (timeInHours > 24) {
xAxis.setLowerBound(xAxis.getLowerBound()+1);
xAxis.setUpperBound(xAxis.getUpperBound()+1);
}
}
}