import java.awt.*; import java.awt.image.*; public class plot extends Canvas { double x[], y[]; int h[] = null; int v[] = null; int zv = -1; Rectangle r = null; double xmin = 0, xmax = 10, ymin = -1, ymax = 1; fit f1, f2, f3, f4; applet4 app; int selected = -1; Image buf = null; public plot(applet4 a) { super(); app = a; setBackground(Color.white); } public void update(Graphics g) { paint(g); } public void paint(Graphics g2) { set_rect(); //int hh = size().height; //int ww = size().width; if (buf == null) buf = createImage(size().width, size().height); Graphics g = buf.getGraphics(); g.setColor(Color.white); g.fillRect(0, 0, size().width, size().height); g.setColor(Color.blue); g.drawLine(r.x, r.y, r.x, r.y + r.height); g.drawLine(r.x, r.y, r.x - 5, r.y); g.drawLine(r.x, r.y + r.height, r.x - 5, r.y + r.height); String s = format_num(ymax); g.drawString(s, r.x - 7 - g.getFontMetrics().stringWidth(s), r.y + 4); s = format_num(ymin); g.drawString(s, r.x - 7 - g.getFontMetrics().stringWidth(s), r.y + r.height + 4); g.drawLine(r.x, r.y + r.height, r.x + r.width, r.y + r.height); g.drawLine(r.x, r.y + r.height, r.x, r.y + r.height + 5); g.drawLine(r.x + r.width, r.y + r.height, r.x + r.width, r.y + r.height + 5); s = format_num(xmin); g.drawString(s, r.x - g.getFontMetrics().stringWidth(s) / 2, r.y + r.height + 17); s = format_num(xmax); g.drawString(s, r.x + r.width - g.getFontMetrics().stringWidth(s) / 2, r.y + r.height + 17); if (zv >= r.y && zv <= r.y + r.height) { g.drawLine(r.x, zv, r.x + r.width, zv); if (zv >= r.y + 10 && zv <= r.y + r.height - 10) { g.drawLine(r.x - 5, zv, r.x, zv); s = format_num(0); g.drawString(s, r.x - 7 - g.getFontMetrics().stringWidth(s), zv + 4); } } g.drawLine(r.x, r.y, r.x + r.width, r.y); g.drawLine(r.x + r.width, r.y, r.x + r.width, r.y + r.height); if (h != null && v != null) { g.setColor(Color.blue); if (zv >= r.y && zv <= r.y + r.height) g.drawLine(r.x, zv, r.x + r.width, zv); for (int i = 0; i < h.length; i ++) draw_point(g, h[i], v[i], i == selected); g.setColor(Color.black); s = new String("Fit Values"); g.drawString(s, r.x + r.width + 90, 15); FontMetrics fm = g.getFontMetrics(); g.drawLine(r.x + r.width + 90, 17, r.x + r.width + 90 + fm.stringWidth(s), 17); f1.draw(g, r.x + r.width + 10, 20); f2.draw(g, r.x + r.width + 10, 90); f3.draw(g, r.x + r.width + 140, 20); f4.draw(g, r.x + r.width + 140, 90); } if (selected > -1) { s = "Selected point: " + format_num(x[selected]) + ", " + format_num(y[selected]); g.drawString(s, r.x + r.width + 30, 180); } g2.drawImage(buf, 0, 0, this); } void draw_point(Graphics g, int h, int v, boolean flag) { g.setColor(Color.black); int dz = 5; if (flag) { drawThickLine(g, h - dz, v - dz, h + dz, v + dz); drawThickLine(g, h - dz, v + dz, h + dz, v - dz); } else { g.drawLine(h - dz, v - dz, h + dz, v + dz); g.drawLine(h - dz, v + dz, h + dz, v - dz); } } public void fit(double x[], double y[]) { set_rect(); selected = -1; this.x = new double[x.length]; for (int i = 0; i < x.length; i ++) this.x[i] = x[i]; this.y = new double[y.length]; for (int i = 0; i < y.length; i ++) this.y[i] = y[i]; h = new int[x.length]; xmin = x[0]; xmax = x[0]; for (int i = 0; i < x.length; i ++) if (x[i] > xmax) xmax = x[i]; else if (x[i] < xmin) xmin = x[i]; double dxdh = r.width / (xmax - xmin); for (int i = 0; i < x.length; i ++) h[i] = (int) (r.x + (x[i] - xmin) * dxdh); v = new int[x.length]; ymin = y[0]; ymax = y[0]; for (int i = 0; i < x.length; i ++) if (y[i] > ymax) ymax = y[i]; else if (y[i] < ymin) ymin = y[i]; if (ymin == ymax) { ymin -= 1; ymax += 1; } f1 = new lin_fit(this, 0); f2 = new ln_fit(this, 1); f3 = new exp_fit(this, 2); f4 = new pow_fit(this, 3); f1.adjust_scale(); f2.adjust_scale(); f3.adjust_scale(); f4.adjust_scale(); f1.calc_v(); f2.calc_v(); f3.calc_v(); f4.calc_v(); double dydv = r.height / (ymax - ymin); for (int i = 0; i < x.length; i ++) v[i] = (int) (r.y + r.height - (y[i] - ymin) * dydv); zv = (int) (r.y + r.height - (0 - ymin) * dydv); repaint(); } void set_rect() { //r = new Rectangle(75, 10, size().width / 2, size().height - 30); r = new Rectangle(75, 10, size().height - 30, size().height - 30); } String truncate_num(double x, int maxc) { String s = String.valueOf(x); String s2 = ""; int dec = 0; int count = 0; for (int i = 0; i < s.length(); i ++) { char c = s.charAt(i); if (c == '.') dec = 1; else if (Character.isDigit(c)) { if (dec == 1) { if (count >= maxc) continue; count ++; } } else dec = 0; if (!(c == '.' && maxc == 0)) s2 += c; } return s2; } String format_num(double x) { return format_num(x, 3); } String format_num(double x, int maxc) { double y = x; if (Double.isInfinite(y)) return new String("INF"); if (Double.isNaN(y)) return new String("NaN"); if (y == 0.0) return new String("0"); // no trailing zeros if (maxc < 0) maxc = 0; //double factor = Math.pow(10.0, (double) maxc); long factor = 1; for (int i = 0; i < maxc; i ++) factor *= 10; y = Math.rint(y * factor) / factor; return truncate_num(y, maxc); } public Dimension minimumSize() { Dimension d = getParent().size(); return new Dimension(d.width, (int) (d.height * 0.60)); } public Dimension preferredSize() { Dimension d = getParent().size(); return new Dimension(d.width, (int) (d.height * 0.60)); } public boolean mouseDown(Event evt, int xx, int yy) { for (int i = 0; i < h.length; i ++) { if (Math.abs(xx - h[i]) <= 5 && Math.abs(yy - v[i]) <= 5) { if (selected != i) { selected = i; repaint(); } return true; } } if (selected != -1) { selected = -1; repaint(); } return true; } void drawThickLine(Graphics g, int x0, int y0, int x1, int y1) { g.drawLine(x0, y0, x1, y1); g.drawLine(x0 + 1, y0, x1 + 1, y1); g.drawLine(x0, y0 + 1, x1, y1 + 1); g.drawLine(x0 + 1, y0 + 1, x1 + 1, y1 + 1); } }