|
1 /* |
|
2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Definitions for the class GraphUtils |
|
15 * |
|
16 */ |
|
17 package com.nokia.s60tools.analyzetool.internal.ui.util; |
|
18 import java.text.DecimalFormat; |
|
19 |
|
20 import org.eclipse.swt.SWT; |
|
21 import org.eclipse.swt.graphics.Font; |
|
22 import org.eclipse.swt.graphics.GC; |
|
23 import org.eclipse.swt.graphics.Image; |
|
24 import org.eclipse.swt.widgets.Display; |
|
25 |
|
26 /** |
|
27 * Utilities class for the graph |
|
28 * |
|
29 */ |
|
30 public final class GraphUtils { |
|
31 private static final String MILLISECONDS = "ms"; //$NON-NLS-1$ |
|
32 private static final String SECONDS = "s"; //$NON-NLS-1$ |
|
33 private static final String MINUTES = "m"; //$NON-NLS-1$ |
|
34 private static final String HOURS = "h"; //$NON-NLS-1$ |
|
35 private static final String DAYS = "d"; //$NON-NLS-1$ |
|
36 private static final String SPACE = " "; //$NON-NLS-1$ |
|
37 private static final int KILOBYTE = 1024; |
|
38 private static final int MEGABYTE = 1024*1024; |
|
39 private static final int GIGABYTE = 1024*1024*1024; |
|
40 private static final DecimalFormat MB_FORMAT = new DecimalFormat("#####.0"); |
|
41 private static final DecimalFormat BYTES_FORMAT = new DecimalFormat("#####.##"); |
|
42 |
|
43 |
|
44 //make constructor private so class doesn't get instantiated |
|
45 private GraphUtils(){ |
|
46 |
|
47 } |
|
48 |
|
49 /** |
|
50 * |
|
51 * @param aBytes |
|
52 * @return next rounded value in Bytes. |
|
53 */ |
|
54 public static int prettyMaxBytes(final int aBytes) { |
|
55 int bytes = aBytes; |
|
56 if (bytes <= KILOBYTE) |
|
57 bytes = 1024; |
|
58 else if (bytes <= 10 * KILOBYTE) |
|
59 bytes = 10 * KILOBYTE; |
|
60 else if (bytes <= 20 * KILOBYTE) |
|
61 bytes = 20 * KILOBYTE; |
|
62 else if (bytes <= 30 * KILOBYTE) |
|
63 bytes = 30 * KILOBYTE; |
|
64 else if (bytes <= 50 * KILOBYTE) |
|
65 bytes = 50 * KILOBYTE; |
|
66 else if (bytes <= 100 * KILOBYTE) |
|
67 bytes = 100 * KILOBYTE; |
|
68 else if (bytes <= 200 * KILOBYTE) |
|
69 bytes = 200 * KILOBYTE; |
|
70 else if (bytes <= 300 * KILOBYTE) |
|
71 bytes = 300 * KILOBYTE; |
|
72 else if (bytes <= 500 * KILOBYTE) |
|
73 bytes = 500 * KILOBYTE; |
|
74 else if (bytes <= MEGABYTE) |
|
75 bytes = MEGABYTE; |
|
76 else if (bytes <= 2 * MEGABYTE) |
|
77 bytes = 2 * MEGABYTE; |
|
78 else if (bytes <= 3 * MEGABYTE) |
|
79 bytes = 3 * MEGABYTE; |
|
80 else if (bytes <= 5 * MEGABYTE) |
|
81 bytes = 5 * MEGABYTE; |
|
82 else if (bytes <= 10 * MEGABYTE) |
|
83 bytes = 10 * MEGABYTE; |
|
84 else if (bytes <= 20 * MEGABYTE) |
|
85 bytes = 20 * MEGABYTE; |
|
86 else if (bytes <= 30 * MEGABYTE) |
|
87 bytes = 30 * MEGABYTE; |
|
88 else if (bytes <= 50 * MEGABYTE) |
|
89 bytes = 50 * MEGABYTE; |
|
90 else if (bytes <= 100 * MEGABYTE) |
|
91 bytes = 100 * MEGABYTE; |
|
92 else if (bytes <= 200 * MEGABYTE) |
|
93 bytes = 200 * MEGABYTE; |
|
94 else if (bytes <= 300 * MEGABYTE) |
|
95 bytes = 300 * MEGABYTE; |
|
96 else if (bytes <= 500 * MEGABYTE) |
|
97 bytes = 500 * MEGABYTE; |
|
98 else |
|
99 bytes = ((bytes + GIGABYTE - 1) / GIGABYTE) * GIGABYTE; |
|
100 |
|
101 return bytes; |
|
102 } |
|
103 /** |
|
104 * Draws the given String and an arrow on an image and returns it. |
|
105 * @param name The string to display |
|
106 * @return the newly created image |
|
107 */ |
|
108 public static Image getVerticalLabel(final String name) |
|
109 { |
|
110 final Image image = new Image(Display.getDefault(), 90, 14); |
|
111 final GC gc = new GC(image); |
|
112 final Font font = new Font(Display.getDefault(), Display.getDefault().getSystemFont().getFontData()[0].getName(), 9, SWT.BOLD); |
|
113 gc.setFont(font); |
|
114 gc.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); |
|
115 gc.fillRectangle(0, 0, 90, 15); |
|
116 gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); |
|
117 gc.drawText(name + " ->", 0, 0, true); |
|
118 font.dispose(); |
|
119 gc.dispose(); |
|
120 return image; |
|
121 } |
|
122 /** |
|
123 * Calculates the next larger or smaller scale. Used typically when zooming in / out. |
|
124 * @param scale the current scale |
|
125 * @param bigger flag to indicate whether to increase or decrease the scale |
|
126 * @return the new scale |
|
127 */ |
|
128 public static double nextScale(final double scale, final boolean bigger) |
|
129 { |
|
130 double logScale = Math.log10(scale); |
|
131 double floorLogScale = Math.floor(Math.log10(scale)); |
|
132 double mostSignificantDigit = Math.rint(Math.pow(10, (logScale - floorLogScale))); |
|
133 double powerOfTen = Math.pow(10, floorLogScale); |
|
134 |
|
135 if (bigger) { |
|
136 if (mostSignificantDigit < 2) { |
|
137 mostSignificantDigit = 2; |
|
138 } else if (mostSignificantDigit < 5) { |
|
139 mostSignificantDigit = 5; |
|
140 } else { |
|
141 mostSignificantDigit = 10; |
|
142 } |
|
143 } else { |
|
144 if (mostSignificantDigit > 5) { |
|
145 mostSignificantDigit = 5; |
|
146 } else if (mostSignificantDigit > 2) { |
|
147 mostSignificantDigit = 2; |
|
148 } else if (mostSignificantDigit > 1) { |
|
149 mostSignificantDigit = 1; |
|
150 } else { |
|
151 mostSignificantDigit = 0.5; |
|
152 } |
|
153 } |
|
154 |
|
155 double result = mostSignificantDigit * powerOfTen; |
|
156 |
|
157 if (result < 0.1) |
|
158 result = 0.1; |
|
159 |
|
160 return result; |
|
161 } |
|
162 /** |
|
163 * Returns the given amount of microseconds as user-friendly formatted string, |
|
164 * for example "3d 5h 20min 2d 3ms" |
|
165 * The returned string can be quite long. Use {@link #renderTime(double)} for |
|
166 * a short version |
|
167 * @param aTotalMicroSeconds the given amount of microseconds to convert |
|
168 * @return the formatted time string |
|
169 */ |
|
170 @SuppressWarnings("nls") |
|
171 public static String renderTime(final double aTotalMicroSeconds) { |
|
172 double totalMicroSeconds = aTotalMicroSeconds; |
|
173 long days, hours, minutes, seconds, ms; |
|
174 days= (long) (totalMicroSeconds / 86400000000L); |
|
175 totalMicroSeconds -= days * 86400000000L; |
|
176 hours = (long) (totalMicroSeconds / 3600000000L); |
|
177 totalMicroSeconds -= hours * 3600000000L; |
|
178 minutes = (long) totalMicroSeconds / 60000000; |
|
179 totalMicroSeconds -= minutes * 60000000; |
|
180 seconds = (long) totalMicroSeconds / 1000000; |
|
181 totalMicroSeconds -= seconds * 1000000; |
|
182 ms = (long)totalMicroSeconds / 1000; |
|
183 |
|
184 StringBuilder result= new StringBuilder(); |
|
185 if(days > 0) { |
|
186 result.append(days).append(DAYS); |
|
187 } |
|
188 if(hours > 0) { |
|
189 if (result.length() > 0){ |
|
190 result.append(SPACE); |
|
191 } |
|
192 result.append(hours).append(HOURS); |
|
193 } |
|
194 if(minutes > 0) { |
|
195 if (result.length() > 0){ |
|
196 result.append(SPACE); |
|
197 } |
|
198 result.append(minutes).append(MINUTES); |
|
199 } |
|
200 if(seconds > 0) { |
|
201 if (result.length() > 0){ |
|
202 result.append(SPACE); |
|
203 } |
|
204 result.append(seconds).append(SECONDS); |
|
205 } |
|
206 if (ms > 0){ |
|
207 if (result.length() > 0){ |
|
208 result.append(SPACE); |
|
209 } |
|
210 result.append(ms).append(MILLISECONDS); |
|
211 } |
|
212 |
|
213 if (result.length() == 0){ |
|
214 result.append(0).append(MILLISECONDS); |
|
215 } |
|
216 return result.toString(); |
|
217 } |
|
218 |
|
219 /** |
|
220 * Formats the given number of bytes into an easily readable format |
|
221 * @param bytes The number of bytes to format |
|
222 * @return String containing a formatted version of the input data |
|
223 */ |
|
224 public static String formatBytes(final double bytes) { |
|
225 String scaledY; |
|
226 |
|
227 if (bytes < 10000) { |
|
228 scaledY = BYTES_FORMAT.format((long)bytes) + " B"; |
|
229 } else if (bytes <= 500 * 1024) { |
|
230 scaledY = BYTES_FORMAT.format(bytes / 1024) + " KB"; |
|
231 } else { |
|
232 scaledY = MB_FORMAT.format(((float) bytes / (1024 * 1024))) + " MB"; |
|
233 } |
|
234 return scaledY; |
|
235 } |
|
236 |
|
237 /** |
|
238 * Formats given time value to String with units. The resulting String |
|
239 * is formatted quite short, e.g.: |
|
240 * <br>"30s" |
|
241 * <br>"1m 30s" |
|
242 * <br>"40m" |
|
243 * <br>"1h 30m" |
|
244 * @param aTime Time in microseconds |
|
245 * @return time String with units |
|
246 */ |
|
247 public static String getTimeStringWithUnits(final double aTime) { |
|
248 long time = (long) aTime / 1000; //convert from microseconds to milliseconds |
|
249 String formatted ; |
|
250 |
|
251 //If we have only less than 10 seconds, show seconds and milliseconds |
|
252 if(time < 6000){ |
|
253 //"s.S's'" |
|
254 int seconds = (int) time / 1000; |
|
255 long ms = time - (seconds * 1000); |
|
256 if (ms == 0 ){ |
|
257 formatted = String.format("%ds", seconds); |
|
258 } else { |
|
259 formatted = String.format("%ds%03d", seconds, ms); |
|
260 } |
|
261 } |
|
262 //If we have 10s or more, but less than 1min, show seconds |
|
263 else if(time < 60000){ |
|
264 //"s's'" |
|
265 formatted = String.format("%ds", (int) time / 1000); |
|
266 } |
|
267 //If we have more than one minute, but less than one 5min, showing the seconds as well |
|
268 else if(time >= 60000 && time < (60000*5)){ |
|
269 //"m'm' s's'" |
|
270 long minutes = (int) time / 60000; |
|
271 long seconds = (time - minutes * 60000) / 1000; |
|
272 if (seconds == 0 ){ |
|
273 formatted = String.format("%dm", minutes); |
|
274 } else { |
|
275 formatted = String.format("%dm %ds", minutes, seconds); |
|
276 } |
|
277 } |
|
278 //If we have more than five minute, but less than one hour, we show only minutes |
|
279 else if(time >= (60000*5) && time < (60*60*1000)){ |
|
280 //"m'm'" |
|
281 formatted = String.format("%dm", (int) time / 60000); |
|
282 } |
|
283 else{ |
|
284 //"H'h' m'm'" |
|
285 long hours = (time / 3600000); |
|
286 long minutes = (time - hours * 3600000) / 60000; |
|
287 |
|
288 if (minutes == 0){ |
|
289 formatted = String.format("%dh", hours); |
|
290 } else { |
|
291 formatted = String.format("%dh %dm", hours, minutes); |
|
292 } |
|
293 |
|
294 } |
|
295 return formatted; |
|
296 } |
|
297 } |