View Javadoc

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  import org.jrobin.core.Util;
28  
29  import java.awt.*;
30  
31  class ValueAxis implements RrdGraphConstants {
32  	private static final YLab[] ylab = {
33  		new YLab(0.1, 1, 2, 5, 10),
34  		new YLab(0.2, 1, 5, 10, 20),
35  		new YLab(0.5, 1, 2, 4, 10),
36  		new YLab(1.0, 1, 2, 5, 10),
37  		new YLab(2.0, 1, 5, 10, 20),
38  		new YLab(5.0, 1, 2, 4, 10),
39  		new YLab(10.0, 1, 2, 5, 10),
40  		new YLab(20.0, 1, 5, 10, 20),
41  		new YLab(50.0, 1, 2, 4, 10),
42  		new YLab(100.0, 1, 2, 5, 10),
43  		new YLab(200.0, 1, 5, 10, 20),
44  		new YLab(500.0, 1, 2, 4, 10),
45  		new YLab(1000.0, 1, 2, 5, 10),
46  		new YLab(2000.0, 1, 5, 10, 20),
47  		new YLab(5000.0, 1, 2, 4, 10),
48  		new YLab(10000.0, 1, 2, 5, 10),
49  		new YLab(20000.0, 1, 5, 10, 20),
50  		new YLab(50000.0, 1, 2, 4, 10),
51  		new YLab(100000.0, 1, 2, 5, 10),
52  		new YLab(0.0, 0, 0, 0, 0)
53  	};
54  
55  	private RrdGraph rrdGraph;
56  	private ImageParameters im;
57  	private ImageWorker worker;
58  	private RrdGraphDef gdef;
59  
60  	ValueAxis(RrdGraph rrdGraph) {
61  		this.rrdGraph = rrdGraph;
62  		this.im = rrdGraph.im;
63  		this.gdef = rrdGraph.gdef;
64  		this.worker = rrdGraph.worker;
65  	}
66  
67  	boolean draw() {
68  		Font font = gdef.smallFont;
69  		Paint gridColor = gdef.colors[COLOR_GRID];
70  		Paint mGridColor = gdef.colors[COLOR_MGRID];
71  		Paint fontColor = gdef.colors[COLOR_FONT];
72  		int fontHeight = (int) Math.ceil(rrdGraph.getSmallFontHeight());
73  		int labelOffset = (int) (worker.getFontAscent(font) / 2);
74  		int labfact = 2, gridind = -1;
75  		double range = im.maxval - im.minval;
76  		double scaledrange = range / im.magfact;
77  		double gridstep;
78  		if (Double.isNaN(scaledrange)) {
79  			return false;
80  		}
81  		int pixel = 1;
82  		String labfmt = null;
83  		if (Double.isNaN(im.ygridstep)) {
84  			if (gdef.altYGrid) {
85  				/* find the value with max number of digits. Get number of digits */
86  				int decimals = (int) Math.ceil(Math.log10(Math.max(Math.abs(im.maxval),
87  						Math.abs(im.minval))));
88  				if (decimals <= 0) /* everything is small. make place for zero */ {
89  					decimals = 1;
90  				}
91  				int fractionals = (int) Math.floor(Math.log10(range));
92  				if (fractionals < 0) /* small amplitude. */ {
93  					labfmt = Util.sprintf("%%%d.%df", decimals - fractionals + 1, -fractionals + 1);
94  				}
95  				else {
96  					labfmt = Util.sprintf("%%%d.1f", decimals + 1);
97  				}
98  				gridstep = Math.pow(10, fractionals);
99  				if (gridstep == 0) /* range is one -> 0.1 is reasonable scale */ {
100 					gridstep = 0.1;
101 				}
102 				/* should have at least 5 lines but no more then 15 */
103 				if (range / gridstep < 5) {
104 					gridstep /= 10;
105 				}
106 				if (range / gridstep > 15) {
107 					gridstep *= 10;
108 				}
109 				if (range / gridstep > 5) {
110 					labfact = 1;
111 					if (range / gridstep > 8) {
112 						labfact = 2;
113 					}
114 				}
115 				else {
116 					gridstep /= 5;
117 					labfact = 5;
118 				}
119 			}
120 			else {
121 				for (int i = 0; ylab[i].grid > 0; i++) {
122 					pixel = (int) (im.ysize / (scaledrange / ylab[i].grid));
123 					if (gridind == -1 && pixel > 5) {
124 						gridind = i;
125 						break;
126 					}
127 				}
128 				for (int i = 0; i < 4; i++) {
129 					if (pixel * ylab[gridind].lfac[i] >= 2 * fontHeight) {
130 						labfact = ylab[gridind].lfac[i];
131 						break;
132 					}
133 				}
134 				gridstep = ylab[gridind].grid * im.magfact;
135 			}
136 		}
137 		else {
138 			gridstep = im.ygridstep;
139 			labfact = im.ylabfact;
140 		}
141 		int x0 = im.xorigin, x1 = x0 + im.xsize;
142 		int sgrid = (int) (im.minval / gridstep - 1);
143 		int egrid = (int) (im.maxval / gridstep + 1);
144 		double scaledstep = gridstep / im.magfact;
145 		for (int i = sgrid; i <= egrid; i++) {
146 			int y = rrdGraph.mapper.ytr(gridstep * i);
147 			if (y >= im.yorigin - im.ysize && y <= im.yorigin) {
148 				if (i % labfact == 0) {
149 					String graph_label;
150 					if (i == 0 || im.symbol == ' ') {
151 						if (scaledstep < 1) {
152 							if (i != 0 && gdef.altYGrid) {
153 								graph_label = Util.sprintf(labfmt, scaledstep * i);
154 							}
155 							else {
156 								graph_label = Util.sprintf("%4.1f", scaledstep * i);
157 							}
158 						}
159 						else {
160 							graph_label = Util.sprintf("%4.0f", scaledstep * i);
161 						}
162 					}
163 					else {
164 						if (scaledstep < 1) {
165 							graph_label = Util.sprintf("%4.1f %c", scaledstep * i, im.symbol);
166 						}
167 						else {
168 							graph_label = Util.sprintf("%4.0f %c", scaledstep * i, im.symbol);
169 						}
170 					}
171 					int length = (int) (worker.getStringWidth(graph_label, font));
172 					worker.drawString(graph_label, x0 - length - PADDING_VLABEL, y + labelOffset, font, fontColor);
173 					worker.drawLine(x0 - 2, y, x0 + 2, y, mGridColor, TICK_STROKE);
174 					worker.drawLine(x1 - 2, y, x1 + 2, y, mGridColor, TICK_STROKE);
175 					worker.drawLine(x0, y, x1, y, mGridColor, GRID_STROKE);
176 				}
177 				else if (!(gdef.noMinorGrid)) {
178 					worker.drawLine(x0 - 1, y, x0 + 1, y, gridColor, TICK_STROKE);
179 					worker.drawLine(x1 - 1, y, x1 + 1, y, gridColor, TICK_STROKE);
180 					worker.drawLine(x0, y, x1, y, gridColor, GRID_STROKE);
181 				}
182 			}
183 		}
184 		return true;
185 	}
186 
187 	static class YLab {
188 		double grid;
189 		int[] lfac;
190 
191 		YLab(double grid, int lfac1, int lfac2, int lfac3, int lfac4) {
192 			this.grid = grid;
193 			lfac = new int[] {lfac1, lfac2, lfac3, lfac4};
194 		}
195 	}
196 }