1 package fr.ifremer.tutti.ui.swing.util;
2
3 /*
4 * #%L
5 * Tutti :: UI
6 * $Id:$
7 * $HeadURL:$
8 * %%
9 * Copyright (C) 2012 - 2014 Ifremer
10 * %%
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation, either version 3 of the
14 * License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public
22 * License along with this program. If not, see
23 * <http://www.gnu.org/licenses/gpl-3.0.html>.
24 * #L%
25 */
26
27 /* ===========================================================
28 * JFreeChart : a free chart library for the Java(tm) platform
29 * ===========================================================
30 *
31 * (C) Copyright 2000-2014, by Object Refinery Limited and Contributors.
32 *
33 * Project Info: http://www.jfree.org/jfreechart/index.html
34 *
35 * This library is free software; you can redistribute it and/or modify it
36 * under the terms of the GNU Lesser General Public License as published by
37 * the Free Software Foundation; either version 2.1 of the License, or
38 * (at your option) any later version.
39 *
40 * This library is distributed in the hope that it will be useful, but
41 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
42 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
43 * License for more details.
44 *
45 * You should have received a copy of the GNU Lesser General Public
46 * License along with this library; if not, write to the Free Software
47 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
48 * USA.
49 *
50 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.
51 * Other names may be trademarks of their respective owners.]
52 *
53 * -------------------------
54 * NumberTickUnitSource.java
55 * -------------------------
56 * (C) Copyright 2014, by Object Refinery Limited.
57 *
58 * Original Author: David Gilbert (for Object Refinery Limited);
59 * Contributor(s): -;
60 *
61 * Changes
62 * -------
63 * 18-Mar-2014 : Version 1 (DG);
64 *
65 */
66
67 import org.jfree.chart.axis.NumberTickUnit;
68 import org.jfree.chart.axis.TickUnit;
69 import org.jfree.chart.axis.TickUnitSource;
70
71 import java.io.Serializable;
72 import java.text.DecimalFormat;
73 import java.text.NumberFormat;
74
75 /**
76 * TickUnitSource for the frequency chart
77 *
78 * @author Kevin Morin (Code Lutin)
79 * @since 3.10
80 */
81 public class TuttiNumberTickUnitSource implements TickUnitSource, Serializable {
82
83 private boolean integers;
84
85 private int power = 0;
86
87 private int factor = 1;
88
89 /**
90 * Creates a new instance.
91 *
92 * @param integers show integers only.
93 */
94 public TuttiNumberTickUnitSource(boolean integers) {
95
96 this.integers = integers;
97 this.power = 0;
98 this.factor = 1;
99 }
100
101 @Override
102 public TickUnit getLargerTickUnit(TickUnit unit) {
103 TickUnit t = getCeilingTickUnit(unit);
104 if (t.equals(unit)) {
105 next();
106 t = new NumberTickUnit(getTickSize(), getTickLabelFormat(),
107 getMinorTickCount());
108 }
109 return t;
110 }
111
112 @Override
113 public TickUnit getCeilingTickUnit(TickUnit unit) {
114 return getCeilingTickUnit(unit.getSize());
115 }
116
117 @Override
118 public TickUnit getCeilingTickUnit(double size) {
119 if (Double.isInfinite(size)) {
120 throw new IllegalArgumentException("Must be finite.");
121 }
122 this.power = (int) Math.ceil(Math.log10(size));
123 if (this.integers) {
124 power = Math.max(this.power, 0);
125 }
126 this.factor = 1;
127 boolean done = false;
128 // step down in size until the current size is too small or there are
129 // no more units
130 while (!done) {
131 done = !previous();
132 if (getTickSize() < size) {
133 next();
134 done = true;
135 }
136 }
137 return new NumberTickUnit(getTickSize(), getTickLabelFormat(),
138 getMinorTickCount());
139 }
140
141 private boolean next() {
142 if (factor == 1) {
143 factor = 5;
144 return true;
145 }
146 if (factor == 5) {
147 if (power == 300) {
148 return false;
149 }
150 power++;
151 factor = 1;
152 return true;
153 }
154 throw new IllegalStateException("We should never get here.");
155 }
156
157 private boolean previous() {
158 if (factor == 1) {
159 if (this.integers && power == 0 || power == -1) {
160 return false;
161 }
162 factor = 5;
163 power--;
164 return true;
165 }
166 if (factor == 5) {
167 factor = 1;
168 return true;
169 }
170 throw new IllegalStateException("We should never get here.");
171 }
172
173 private double getTickSize() {
174 return this.factor * Math.pow(10.0, this.power);
175 }
176
177 private DecimalFormat dfNeg4 = new DecimalFormat("0.0000");
178
179 private DecimalFormat dfNeg3 = new DecimalFormat("0.000");
180
181 private DecimalFormat dfNeg2 = new DecimalFormat("0.00");
182
183 private DecimalFormat dfNeg1 = new DecimalFormat("0.0");
184
185 private DecimalFormat df0 = new DecimalFormat("#,##0");
186
187 private DecimalFormat df = new DecimalFormat("#.######E0");
188
189 private NumberFormat getTickLabelFormat() {
190 if (power == -4) {
191 return dfNeg4;
192 }
193 if (power == -3) {
194 return dfNeg3;
195 }
196 if (power == -2) {
197 return dfNeg2;
198 }
199 if (power == -1) {
200 return dfNeg1;
201 }
202 if (power >= 0 && power <= 6) {
203 return df0;
204 }
205 return df;
206 }
207
208 private int getMinorTickCount() {
209 return (int) (getTickSize() * (integers ? 1 : 2));
210 }
211
212 @Override
213 public boolean equals(Object obj) {
214 if (obj == this) {
215 return true;
216 }
217 if (!(obj instanceof TuttiNumberTickUnitSource)) {
218 return false;
219 }
220 TuttiNumberTickUnitSource that = (TuttiNumberTickUnitSource) obj;
221 if (this.integers != that.integers) {
222 return false;
223 }
224 if (this.power != that.power) {
225 return false;
226 }
227 if (this.factor != that.factor) {
228 return false;
229 }
230 return true;
231 }
232 }
233