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    }