1、核心公式:
实际像素高度 pixY = (实际值 y - 集合中最小实际值 minY) * 显示区高度 h / (集合中最大实际值 maxY - 集合中最小实际值 minY)
实现代码如下:
public int pixY(int y, int h) {
int maxY = Collections.max(yList);
int minY = Collections.min(yList);
if (maxY - minY == 0) {
return 0;
}
return (y - minY) * h / (maxY - minY);
}
2、Demo
PaintPanel.java
package all;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class PaintPanel extends JPanel {
private List<Integer> yList = new ArrayList<Integer>();
public int nextY = 0;
protected void paintComponent(Graphics g) {
// Gray Frame Background
g.setColor(new Color(204, 204, 204));
g.fillRect(0, 0, this.getWidth(), this.getHeight());
// Client Zone
int w = (int) (this.getWidth() * 0.8);
int h = (int) (this.getHeight() * 0.8);
// Axis Original Point
int x = (this.getWidth() - w) / 2;
int y = (this.getHeight() - h) / 2;
// White Client Background
g.setColor(new Color(255, 255, 255));
g.fillRect(x, y, w, h);
// Draw Axis
g.setColor(new Color(0, 0, 0));
g.drawRect(x, y, w, h);
// Draw Graph Title
String title = "Ramdom Graph";
FontMetrics fm = g.getFontMetrics();
int titleWidth = fm.stringWidth(title);
int xx = x + (w - titleWidth) / 2;
g.drawString(title, xx, y - 10);
// Prepare Data
yList.add(nextY);
if (yList.size() > w) {
yList.remove(0);
}
// Draw Short Cut Line And Norms
int numY = 10, hh = h / numY;
int maxY = Collections.max(yList);
int minY = Collections.min(yList);
int gapY = (maxY - minY) / numY;
for (int i = 0; i <= numY; i++) {
String norm = "" + (maxY - gapY * i);
int normWidth = fm.stringWidth(norm);
g.drawString(norm, x - normWidth - 4, y + hh * i + 5);
g.drawLine(x, y + hh * i, x + 4, y + hh * i);
g.drawLine(x + w - 4, y + hh * i, x + w, y + hh * i);
}
int ww = w / 9;
for (int i = 0; i <= 9; i++) {
g.drawString("" + i, x + ww * i - 3, y + h + 15);
g.drawLine(x + ww * i, y, x + ww * i, y + 4);
g.drawLine(x + ww * i, y, x + ww * i, y + 4);
g.drawLine(x + ww * i, y + h - 4, x + ww * i, y + h);
}
// Draw Random Graph
g.setColor(new Color(0, 0, 255));
for (int i = 1; i < yList.size(); i++) {
int curY = y + this.pixY(yList.get(i - 1), h);
int nextY = y + this.pixY(yList.get(i), h);
g.drawLine(x + i - 1, curY, x + i, nextY);
}
}
public int pixY(int y, int h) {
int maxY = Collections.max(yList);
int minY = Collections.min(yList);
if (maxY - minY == 0) {
return 0;
}
return (y - minY) * h / (maxY - minY);
}
}
Main.java
package all;
import java.awt.Toolkit;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
public class Main {
public static void main(String[] args) {
// Main Frame
JFrame frame = new JFrame();
// Initialize Frame
int h = (int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight() * 0.618);
frame.setSize((int) (h / 0.618), h);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Graphic Content
final PaintPanel panel = new PaintPanel();
frame.setContentPane(panel);
// Show Main Frame
frame.setVisible(true);
// Update Random Graph
Timer timer = new Timer();
final Random random = new Random();
timer.schedule(new TimerTask() {
public void run() {
panel.nextY += (random.nextDouble() - 0.5) * 50;
panel.updateUI();
}
}, 0, 1);
}
}