图表问题 [英] Graph Plotting Issue

查看:356
本文介绍了图表问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用来自线程的输出创建线图,线程是在52秒的时间内运行的入站和出站帐单的模拟,这将在如下所示的线图上显示,以显示银行余额52秒!

I am creating line graph using outputs from a thread, the threads are simulations of incoming and outgoing bill that run over a course of 52 seconds and this will be dipicted on a line graph as shown below to show the bank balance over the 52 seconds!

当前程序运行正常,当我点击开始点被更新,但每一个新的点被放置在图上,前一个消失。

Currently the program runs fine, when I click start the point gets updated but every a new point is placed on the graph the previous one disappears. How i can i keep all the points on the graph.

我假设我必须创建2个新的int变量... prevX& prevY。

I would assume i would have to create 2 new int variable... prevX & prevY.

>

import java.awt.*;
import javax.swing.*;

public class DrawPanel extends JPanel {

   private static final int X_AXIS_LENGTH = 700;
   private static final int Y_AXIS_LENGTH = 230; // could be changed
   private static final int X_AXIS_OFFSET = 200;
   private static final int Y_AXIS_OFFSET = 85;
   private static final int PanelHeight = 365;
   private static final int PanelWidth = 1000;

   public DrawPanel() {
      this.setBackground(Color.white);
      this.setPreferredSize(new Dimension(PanelWidth, PanelHeight));
   }

   public void paintComponent(Graphics g) {

      int y = ControlPanel.bk1.getBalance(); // balance
      int x = ControlPanel.bk1.getWeek(); // weeks //
      int prevX, prevY;
      int maxX = ContentPanel.controlPanel.getDuration();
      int maxY = 100000;

      int Xleft = 200;
      int Xright = 900;
      int Ytop = 50;
      int Ybottom = 330;// defining axis

      while (ControlPanel.bk1.getBalance() > maxY) {
         int i = maxY / 4;
         maxY = maxY + i;
      }

      Graphics2D g2 = (Graphics2D) g;
      super.paintComponent(g2);
      g2.setColor(Color.BLUE);

      BasicStroke pen = new BasicStroke(4F);
      g2.setStroke(pen);

      g2.drawLine(Xleft, Ytop, Xleft, Ybottom); // set axis
      g2.drawLine(Xleft, 280, Xright, 280);

      int i = X_AXIS_OFFSET + (X_AXIS_LENGTH / 2);
      int ii = X_AXIS_OFFSET + (X_AXIS_LENGTH / 4);
      int iii = ((X_AXIS_LENGTH / 4)) * 3 + X_AXIS_OFFSET;
      BasicStroke spaces = new BasicStroke(1F);
      g2.setStroke(spaces);
      g2.drawLine(i, 280, i, 300);
      g2.drawLine(ii, 280, ii, 300);
      g2.drawLine(iii, 280, iii, 300);

      g2.setStroke(pen);

      Font f = new Font("Serif", Font.BOLD, 14);
      g2.setFont(f);
      g2.drawString("Account Balance (£)", 35, 200);
      g2.drawString("Elapsed Time (Weeks)", 475, 340);

      g2.setColor(Color.BLACK);
      String maxXDisplay = Integer.toString(maxX);
      String maxYDisplay = Integer.toString(maxY);
      g2.drawString(maxYDisplay, 160, 45);
      g2.drawString(maxXDisplay, 900, 300);

      // retrieve values from your model for the declared variables

      // calculate the coords line on the canvas

      double balance = PanelHeight
            - ((((double) y / maxY) * Y_AXIS_LENGTH) + Y_AXIS_OFFSET);
      double weeks = (((double) x / maxX) * X_AXIS_LENGTH) + X_AXIS_OFFSET;

      int xPos = (int) Math.round(weeks);
      int yPos = (int) Math.round(balance); // changing back to int to be used
                                            // in drawing oval

      g2.setColor(Color.RED);
      g.drawOval(xPos, yPos, 2, 2);

   }

   public void reDraw() {
      repaint();
   }

}


推荐答案

您似乎只是在paintComponent方法中绘制一点:

You appear to be only trying to plot one point in your paintComponent method:

g.drawOval(xPos, yPos, 2, 2);

通常,你将循环遍历这个方法中的所有点。例如:

Usually you'll loop through a for loop drawing all the points in this method. For example something like:

  for (int j = 0; j < maxPointCount; j++) {
     x = someMethodToGetX(j);
     y = someMethodToGetY(j);
     double balance = PanelHeight - ((((double) y / maxY) * 
           Y_AXIS_LENGTH) + Y_AXIS_OFFSET);
     double weeks = (((double) x / maxX) * X_AXIS_LENGTH) + 
           X_AXIS_OFFSET;

     int xPos = (int) Math.round(weeks);
     int yPos = (int) Math.round(balance); 

     g2.setColor(Color.RED);
     g.drawOval(xPos, yPos, 2, 2);
  }

编辑1

关于您最近的评论:

Edit 1
Regarding your recent comment:


尝试使用for循环,对程序没有影响

Tryed that for loop and it makes no difference to the program

我上面的代码肯定不是可以剪切和粘贴到你的程序中的代码,并且期望工作,而是仅仅被看作一个概念的例子。如果实现正确,一个for循环将工作,因为它为我工作了很多次,但你的工作不工作,所以我们必须修复你的实现,为了做到这一点,我们需要更多的信息:

My code above is certainly not code that can be cut and pasted into your program and be expected to work, but rather is only to be seen as an example of a concept. A for loop will work if implemented correctly as it's worked for me many times, but yours is not working, so we have to fix your implementation, and in order to do that, we need more information:


  • 如何生成数据点?

  • 您是否使用Swing计时器模仿实时数据收集?

  • 您需要在收集数据时存储数据点你的paintComponent可以遍历它们。如何存储您的数据点?是在ArrayList中吗?我们可以看到该代码吗?

  • 一旦我们看到所有这些,我们可以看到您尝试实施for循环以绘制所有数据点的代码吗?

  • How are you generating your data points?
  • Are you using a Swing Timer to imitate real-time collection of data?
  • You will need to store your data points as you collect them so your paintComponent can iterate over them. How are you storing your data points? Is it in an ArrayList? Can we see that code?
  • Once we see all this, can we see the code where you try to implement a for loop to draw all the data points?

您需要对问题进行修改才能显示此新信息。

You will need to make an edit to your question to show this new information. If you do this, please notify me by commenting in this answer.

编辑2

这是一个更完整的我描述的例子,一个具有功能的循环,绘制所有缩放的数据点。当然,没有这些代码可以复制和粘贴到你的应用程序,但希望包含的概念可以传输。请问是否有什么看起来很混乱:

Edit 2
This is a more complete example of what I'm describing, one with a functioning for loop that draws all scaled data points. Of course none of this code can be copied and pasted into your app, but hopefully the concepts contained can be transferred. Please ask if anything looks confusing:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.*;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

public class TestShowGraph {
   private static final int MAX_POINTS = 30;
   private static final int TIMER_DELAY = 800;

   private static void createAndShowGui() {
      ShowGraph showGraphPanel = new ShowGraph(MAX_POINTS);
      TimerListener timerListener = new TimerListener(MAX_POINTS, showGraphPanel);

      JFrame frame = new JFrame("TestShowGraph");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(showGraphPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);

      new Timer(TIMER_DELAY, timerListener).start();
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }  
}

class TimerListener implements ActionListener {
   private static final double EXP_MULTIPLIER = 0.2;

   // array of points created in constructor to hold data that
   // will eventually be displayed in real time.
   // A Swing Timer will copy a point into the pointsList above. 
   private Point2D[] initPoints;

   private int maxPoints;
   private int count = 0;
   private ShowGraph showGraph;

   public TimerListener(int maxPoints, ShowGraph showGraph) {
      initPoints = new Point2D[maxPoints];
      this.maxPoints = maxPoints;
      this.showGraph = showGraph;

      // create all data points that will eventually be 
      // graphed. This is to simulate real-time data collection
      for (int i = 0; i < initPoints.length; i++) {
         double x = (double) i / initPoints.length;
         double y = 1.0 - Math.exp(-1.0 * i * EXP_MULTIPLIER);        
         initPoints[i] = new Point2D.Double(x, y);
      }
   }

   public void actionPerformed(ActionEvent e) {
      if (count < maxPoints) {
         // simply push data from initPoints into the list that will
         // be used to draw the graph
         showGraph.addPoint(initPoints[count]);
         count++;
      } else {
         // unless we've run out of points. Then simply start over
         count = 0;
         showGraph.clearPointsList();
      }

      // repaint so that the GUI will show the points
      showGraph.repaint();
   }
}

@SuppressWarnings("serial")
class ShowGraph extends JPanel {

   private static final int PREF_W = 800;
   private static final int PREF_H = 600;
   private static final int BORDER_GAP = 50;
   private static final Color AXIS_COLOR = Color.blue;
   private static final Color POINTS_COLOR = Color.red;
   private static final Color BACKGRND_COLOR = Color.white;
   private static final Stroke AXIS_STROKE = new BasicStroke(3f);
   private static final Stroke POINTS_STROKE = new BasicStroke(2f);
   private static final double X_SCALE = PREF_W - 2 * BORDER_GAP;
   private static final double Y_SCALE = PREF_H - 2 * BORDER_GAP;
   private static final int POINT_RADIUS = 3;

   // list that the paintComponent method loops through to
   // draw points
   private List<Point2D> pointsList = new ArrayList<Point2D>();


   public ShowGraph(int maxPoints) {
      setBackground(BACKGRND_COLOR);
   }

   public void addPoint(Point2D point2d) {
      pointsList.add(point2d);
   }

   public void clearPointsList() {
      pointsList.clear();
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
            RenderingHints.VALUE_ANTIALIAS_ON);
      drawAxises(g2);
      drawPoints(g2);
   }

   private void drawAxises(Graphics g2) {
      // derive a Graphics2D object from the one provided by the 
      // JVM so we can change settings on it without effecting 
      // the Graphics object provided by the JVM
      Graphics2D g2Axises = (Graphics2D) g2.create();
      g2Axises.setStroke(AXIS_STROKE);
      g2Axises.setColor(AXIS_COLOR);
      int x1XAxis = BORDER_GAP;
      int y1XAxis = PREF_H - BORDER_GAP;
      int x2XAxis = PREF_W - BORDER_GAP;
      int y2XAxis = PREF_H - BORDER_GAP;
      g2Axises.drawLine(x1XAxis, y1XAxis, x2XAxis, y2XAxis);
      int x1YAxis = BORDER_GAP;
      int y1YAxis = BORDER_GAP;
      int x2YAxis = BORDER_GAP;
      int y2YAxis = PREF_H - BORDER_GAP;
      g2Axises.drawLine(x1YAxis, y1YAxis, x2YAxis, y2YAxis);
      g2Axises.dispose(); // because we derived this we must dispose it
   }

   private void drawPoints(Graphics2D g2) {
      Graphics2D g2Points = (Graphics2D) g2.create();
      g2Points.setStroke(POINTS_STROKE);
      g2Points.setColor(POINTS_COLOR); 

      for (Point2D p : pointsList) {
         // p points hold data between 0 and 1
         // we must scale our points to fit the display
         // before displaying them
         int pX = (int)(X_SCALE * p.getX()) + BORDER_GAP;
         int pY = PREF_H - (int)(Y_SCALE * p.getY()) - BORDER_GAP;

         // displayed the scaled points
         int radius = POINT_RADIUS;
         g2Points.drawOval(pX - radius, pY - radius, 2 * radius, 2 * radius);
      }
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

}

运气。

这篇关于图表问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆