001 /* 002 * Copyright 2011 Christian Kumpe http://kumpe.de/christian/java 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package de.kumpe.hadooptimizer.examples.functions; 017 018 import java.awt.Color; 019 import java.awt.Dimension; 020 import java.awt.FontMetrics; 021 import java.awt.Graphics; 022 import java.awt.Graphics2D; 023 024 import javax.swing.JPanel; 025 026 /** 027 * @author Christian Kumpe <christian@kumpe.de> 028 */ 029 public class AxisPanel extends JPanel { 030 private static final long serialVersionUID = 1L; 031 032 private double dx = 0; 033 private double dy = 0; 034 private int odx = 0; 035 private int ody = 0; 036 private double s = 1d / 50; 037 private int ox; 038 private int oy; 039 040 public AxisPanel() { 041 setForeground(Color.BLACK); 042 setBackground(Color.WHITE); 043 } 044 045 @Override 046 protected void paintComponent(final Graphics graphics) { 047 super.paintComponent(graphics); 048 049 final Graphics2D g = (Graphics2D) graphics; 050 final FontMetrics fm = g.getFontMetrics(); 051 052 final int w = getWidth(); 053 final int h = getHeight(); 054 ox = w / 2 + odx; 055 oy = h / 2 + ody; 056 057 // x-axis 058 g.drawLine(0, oy, w, oy); 059 g.drawLine(w - 10, oy - 10, w, oy); 060 g.drawLine(w - 10, oy + 10, w, oy); 061 062 final double stepX = Math.floor(w / 10 * s); 063 final double stepY = Math.floor(h / 10 * s); 064 double step = Math.max(stepX, stepY); 065 if (0 >= step) { 066 step = 0.1; 067 } 068 069 final double minX = Math.ceil(revX(0) + 1); 070 final double maxX = Math.floor(revX(w) - 1); 071 for (double i = minX; i < maxX; i += step) { 072 final int x = x(i); 073 final int y = oy; 074 if (x < 10 || x > w - 10 || Math.abs(x - ox) < 10) { 075 continue; 076 } 077 final String text = format(i); 078 g.drawLine(x, y - 5, x, y + 5); 079 g.drawString(text, x - fm.stringWidth(text) / 2, 080 y + 5 + fm.getHeight()); 081 } 082 083 // y-axis 084 g.drawLine(ox, h, ox, 0); 085 g.drawLine(ox - 10, 10, ox, 0); 086 g.drawLine(ox + 10, 10, ox, 0); 087 088 final double minY = Math.ceil(revY(0) + 1); 089 final double maxY = Math.floor(revY(h) - 1); 090 for (double i = minY; i < maxY; i += step) { 091 final int x = ox; 092 final int y = y(i); 093 if (y < 10 || y > h - 10 || Math.abs(y - oy) < 10) { 094 continue; 095 } 096 final String text = format(i); 097 g.drawLine(x - 5, y, x + 5, y); 098 099 g.drawString(text, x - 10 - fm.stringWidth(text), 100 y + fm.getHeight() / 2); 101 } 102 103 } 104 105 protected String format(final double i) { 106 return String.format("%.2f", i); 107 } 108 109 protected int x(final double x) { 110 return (int) Math.round((x + dx) / s) + ox; 111 } 112 113 protected double revX(final int x) { 114 return (x - ox) * s - dx; 115 } 116 117 protected int y(final double y) { 118 return oy - (int) Math.round((y + dy) / s); 119 } 120 121 protected double revY(final int y) { 122 return (y - oy) * s - dy; 123 } 124 125 @Override 126 public Dimension getPreferredSize() { 127 return new Dimension(600, 400); 128 } 129 130 public void setOriginTranslation(final int dx, final int dy) { 131 odx = dx; 132 ody = dy; 133 repaint(); 134 } 135 136 public void setValueTranslation(final double dx, final int dy) { 137 this.dx = dx; 138 this.dy = dy; 139 repaint(); 140 } 141 142 public void setScale(final double s) { 143 this.s = s; 144 repaint(); 145 } 146 }