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 }