通过Java Swing可以绘制动态数据折线图。
调用下面addData()方法向折线图窗口动态地追加数据,参数t为横轴时间,参数v为纵轴数值,运行效果如上图所示:
Java Swing绘制数据折线图的代码如下:
/* DataWindow.java */
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import java.text.DateFormat;
import java.util.Date;
/**
* Create a new window to graph the sensor readings in.
*
* @author Ron Goldman
*/
public class DataWindow extends JFrame {
private static final int MAX_SAMPLES = 10000;
private int index = 0;
private long[] time = new long[MAX_SAMPLES];
private int[] val = new int[MAX_SAMPLES];
DateFormat fmt = DateFormat.getDateTimeInstance();
/** Creates new form DataWindow */
public DataWindow() {
initComponents();
}
public DataWindow(String ieee) {
initComponents();
setTitle(ieee);
}
public void addData(long t, int v) {
time[index] = t;
val[index++] = v;
dataTextArea.append(fmt.format(new Date(t)) + " value = " + v + "\n");
dataTextArea.setCaretPosition(dataTextArea.getText().length());
repaint();
}
// Graph the sensor values in the dataPanel JPanel
public void paint(Graphics g) {
super.paint(g);
int left = dataPanel.getX() + 10; // get size of pane
int top = dataPanel.getY() + 30;
int right = left + dataPanel.getWidth() - 20;
int bottom = top + dataPanel.getHeight() - 20;
int y0 = bottom - 20; // leave some room for margins
int yn = top;
int x0 = left + 33;
int xn = right;
double vscale = (yn - y0) / 120.0; // light values range from 0 to 800
double tscale = 1.0 / 2000.0; // 1 pixel = 2 seconds = 2000 milliseconds
// draw X axis = time
g.setColor(Color.BLACK);
g.drawLine(x0, yn, x0, y0);
g.drawLine(x0, y0, xn, y0);
int tickInt = 60 / 2;
for (int xt = x0 + tickInt; xt < xn; xt += tickInt) { // tick every 1 minute
g.drawLine(xt, y0 + 5, xt, y0 - 5);
int min = (xt - x0) / (60 / 2);
g.drawString(Integer.toString(min), xt - (min < 10 ? 3 : 7) , y0 + 20);
}
// draw Y axis = sensor reading
g.setColor(Color.BLUE);
for (int vt = 120; vt > 0; vt -= 20) { // tick every 200
int v = y0 + (int)(vt * vscale);
g.drawLine(x0 - 5, v, x0 + 5, v);
g.drawString(Integer.toString(vt), x0 - 38 , v + 5);
}
// graph sensor values
int xp = -1;
int vp = -1;
for (int i = 0; i < index; i++) {
int x = x0 + (int)((time[i] - time[0]) * tscale);
int v = y0 + (int)(val[i] * vscale);
if (xp > 0) {
g.drawLine(xp, vp, x, v);
}
xp = x;
vp = v;
}
}
public static void main (String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new DataWindow().setVisible(true);
}
});
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// //GEN-BEGIN:initComponents
private void initComponents() {
dataPanel = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
dataTextArea = new javax.swing.JTextArea();
dataPanel.setBackground(new java.awt.Color(255, 255, 255));
dataPanel.setMinimumSize(new java.awt.Dimension(400, 250));
dataPanel.setPreferredSize(new java.awt.Dimension(400, 250));
getContentPane().add(dataPanel, java.awt.BorderLayout.CENTER);
jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
jScrollPane1.setMinimumSize(new java.awt.Dimension(400, 100));
jScrollPane1.setPreferredSize(new java.awt.Dimension(400, 100));
dataTextArea.setColumns(20);
dataTextArea.setEditable(false);
dataTextArea.setRows(4);
jScrollPane1.setViewportView(dataTextArea);
getContentPane().add(jScrollPane1, java.awt.BorderLayout.SOUTH);
pack();
}// //GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel dataPanel;
private javax.swing.JTextArea dataTextArea;
private javax.swing.JScrollPane jScrollPane1;
// End of variables declaration//GEN-END:variables
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
本文链接:http://bookshadow.com/weblog/2014/05/16/java-swing-line-chart/
请尊重作者的劳动成果,转载请注明出处!书影博客保留对文章的所有权利。
调用addData( )那个函数,要怎么调用叻?
传入两个参数t和v:分别代表数据时间和数值
我想每秒从文档里或者数据库里每秒读取一个数据出来,是应该把这个函数写在主函数里面么?话说,你示例的那个图的数据的读取部分的程序可不可以发我一份叻??有没有私信之类的功能><
可以用线程实现异步地追加数据。这个程序的历史过于久远。。。目前只能找到这个代码片段了>_<
把代码里的main方法替换成下面的片段就可以看到随机数据构造的折线图了。
private static final DataWindow dw = new DataWindow();
public static void main (String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
dw.setVisible(true);
}
});
Thread thread = new Thread() {
public void run() {
while (true) {
long t = System.currentTimeMillis();
int v = new Random().nextInt(50);
dw.addData(t, v);
dw.repaint();
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
thread.run();
}
哇塞,,好感动,。非常感谢。
可以一次画多条折线吗?
在main方法中调用addDate()方法吗?