[英]Graph plotting in Java Swing only draws points
I'm currently working on a program where certain numerical variables, which evolve over time, have their value displayed on each iteration. 我目前正在开发一个程序,其中某些随时间演变的数值变量在每次迭代时都会显示其值。 That works well enough, but now I want to plot a graph that shows their evolution over time.
这很好用,但现在我想绘制一张图表,显示它们随时间的演变。 So, I looked into an example of code for plotting graphs in Swing.
所以,我查看了一个用于在Swing中绘制图形的代码示例。 My final code looks like this:
我的最终代码如下所示:
public class Populus3 extends JPanel
{
public static void main(String[] args) throws IOException {
final Populus3 pop = new Populus3();
JFrame f = new JFrame(); //where I want to plot the graph
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new GraphingData());
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
frame = new JFrame("Animation Frame"); //where I'm running animation for another element of the program
frame.add(pop, BorderLayout.CENTER);
frame.setSize(graphSize, graphSize);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//insert all sort of things
}
public void paint(Graphics g)
{
super.paint(g);
paintCell(g, 1);
Toolkit.getDefaultToolkit().sync(); // necessary for linux users to draw and animate image correctly
g.dispose();
}
public void actionPerformed(ActionEvent e) {
repaint();
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
for(int i = 0; i < particleType.length; i++)
paintCell(g, i); //a method that draws a small circle for the animation panel
}
public static class GraphingData extends JPanel {
int[] data = {
21, 14, 18, 03, 86, 88, 74, 87, 54, 77,
61, 55, 48, 60, 49, 36, 38, 27, 20, 18
};
final int PAD = 20;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int w = getWidth();
int h = getHeight();
// Draw ordinate.
g2.draw(new Line2D.Double(PAD, PAD, PAD, h-PAD));
// Draw abcissa.
g2.draw(new Line2D.Double(PAD, h-PAD, w-PAD, h-PAD));
double xInc = (double)(w - 2*PAD)/(data.length-1);
double scale = (double)(h - 2*PAD)/getMax();
// Mark data points.
g2.setPaint(Color.red);
for(int i = 0; i < data.length; i++) {
double x = PAD + i*xInc;
double y = h - PAD - scale*data[i];
g2.fill(new Ellipse2D.Double(x-2, y-2, 4, 4));
}
}
private int getMax() {
int max = -Integer.MAX_VALUE;
for(int i = 0; i < data.length; i++) {
if(data[i] > max)
max = data[i];
}
return max;
}
}
}
Now, the animation panel works just fine. 现在,动画面板工作得很好。 The graph panel, on the other hand...when I run the program, it displays a bunch of red dots, without lines to connect them.
另一方面,图形面板......当我运行程序时,它会显示一堆红点,没有连接它们的线条。 What am I doing wrong?
我究竟做错了什么?
In addition to @Hovercraft's helpful suggestions, also consider these other approaches: 除了@ Hovercraft的有用建议,还要考虑以下其他方法:
GeneralPath
that may be rendered as required, for example . GeneralPath
可以呈现为需要的, 例如 。 drawLine()
using a suitable coordinate system, outlined here . drawLine()
使用合适的坐标系,概括这里 。 JFreeChart
. JFreeChart
。 Your code confuses me: 你的代码让我困惑:
paintCell(...)
. paintCell(...)
。 Toolkit.getDefaultToolkit().sync();
Toolkit.getDefaultToolkit().sync();
for Swing applications. Consider isolating your problem more and posting an sscce , a minimal test program that we can compile, run, modify and correct and that shows us your problem, but has no extra code not related to the problem or required for demonstration. 考虑更多地隔离你的问题并发布一个sscce ,一个我们可以编译,运行,修改和纠正的最小测试程序,它向我们展示你的问题,但是没有与问题无关或演示所需的额外代码。
The following code demonstrates a real-time Java chart using XChart where the line is updated as the data evolves over time. 以下代码演示了使用XChart的实时Java图表,其中随着数据随时间的推移而更新行。 Creating real-time charts is as simple as calling
updateXYSeries
for one or more series objects through the XYChart
instance and triggering a redraw of the JPanel
containing the chart. 创建实时图表就像通过
XYChart
实例调用一个或多个系列对象的updateXYSeries
并触发包含图表的JPanel
的重绘一样简单。 This works for all chart types including XYChart
, CategoryChart
, BubbleChart
and PieChart
, for which example source code can be found here: https://github.com/timmolter/XChart/tree/develop/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/realtime . 这适用于所有的图表类型,包括
XYChart
, CategoryChart
, BubbleChart
和PieChart
,为此示例源代码可以在这里找到: https://github.com/timmolter/XChart/tree/develop/xchart-demo/src/main/java / org / knowm / xchart / demo / charts / realtime 。 Examples demonstrate using the SwingWrapper
with repaintChart()
method as well as XChartPanel
with revalidate()
and repaint()
. 示例演示了
SwingWrapper
将SwingWrapper
与repaintChart()
方法一起使用,以及将XChartPanel
与revalidate()
和repaint()
。 Disclaimer, I'm the main developer of the XChart library. 免责声明,我是XChart库的主要开发人员。
public class SimpleRealTime {
public static void main(String[] args) throws Exception {
double phase = 0;
double[][] initdata = getSineData(phase);
// Create Chart
final XYChart chart = QuickChart.getChart("Simple XChart Real-time Demo", "Radians", "Sine", "sine", initdata[0], initdata[1]);
// Show it
final SwingWrapper<XYChart> sw = new SwingWrapper<XYChart>(chart);
sw.displayChart();
while (true) {
phase += 2 * Math.PI * 2 / 20.0;
Thread.sleep(100);
final double[][] data = getSineData(phase);
chart.updateXYSeries("sine", data[0], data[1], null);
sw.repaintChart();
}
}
private static double[][] getSineData(double phase) {
double[] xData = new double[100];
double[] yData = new double[100];
for (int i = 0; i < xData.length; i++) {
double radians = phase + (2 * Math.PI / xData.length * i);
xData[i] = radians;
yData[i] = Math.sin(radians);
}
return new double[][] { xData, yData };
}
}
This results in the following Java Swing real-time chart app: 这导致以下Java Swing实时图表应用程序:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.