1 /* ============================================================
2 * JRobin : Pure java implementation of RRDTool's functionality
3 * ============================================================
4 *
5 * Project Info: http://www.jrobin.org
6 * Project Lead: Sasa Markovic (saxon@jrobin.org)
7 *
8 * Developers: Sasa Markovic (saxon@jrobin.org)
9 *
10 *
11 * (C) Copyright 2003-2005, by Sasa Markovic.
12 *
13 * This library is free software; you can redistribute it and/or modify it under the terms
14 * of the GNU Lesser General Public License as published by the Free Software Foundation;
15 * either version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 * See the GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public License along with this
22 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
23 * Boston, MA 02111-1307, USA.
24 */
25 package org.jrobin.graph;
26
27 class ValueScaler {
28 static final String UNIT_UNKNOWN = "?";
29 static final String UNIT_SYMBOLS[] = {
30 "a", "f", "p", "n", "u", "m", " ", "k", "M", "G", "T", "P", "E"
31 };
32 static final int SYMB_CENTER = 6;
33
34 private final double base;
35 private double magfact = -1; // nothing scaled before, rescale
36 private String unit;
37
38 ValueScaler(double base) {
39 this.base = base;
40 }
41
42 Scaled scale(double value, boolean mustRescale) {
43 Scaled scaled;
44 if (mustRescale) {
45 scaled = rescale(value);
46 }
47 else if (magfact >= 0) {
48 // already scaled, need not rescale
49 scaled = new Scaled(value / magfact, unit);
50 }
51 else {
52 // scaling not requested, but never scaled before - must rescale anyway
53 scaled = rescale(value);
54 // if zero, scale again on the next try
55 if (scaled.value == 0.0 || Double.isNaN(scaled.value)) {
56 magfact = -1.0;
57 }
58 }
59 return scaled;
60 }
61
62 private Scaled rescale(double value) {
63 int sindex;
64 if (value == 0.0 || Double.isNaN(value)) {
65 sindex = 0;
66 magfact = 1.0;
67 }
68 else {
69 sindex = (int) (Math.floor(Math.log(Math.abs(value)) / Math.log(base)));
70 magfact = Math.pow(base, sindex);
71 }
72 if (sindex <= SYMB_CENTER && sindex >= -SYMB_CENTER) {
73 unit = UNIT_SYMBOLS[sindex + SYMB_CENTER];
74 }
75 else {
76 unit = UNIT_UNKNOWN;
77 }
78 return new Scaled(value / magfact, unit);
79 }
80
81 static class Scaled {
82 double value;
83 String unit;
84
85 public Scaled(double value, String unit) {
86 this.value = value;
87 this.unit = unit;
88 }
89
90 void dump() {
91 System.out.println("[" + value + unit + "]");
92 }
93 }
94 }
95