This project has retired. For details please refer to its
Attic page.
Chart xref
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.chukwa.hicc;
20
21
22 import java.util.ArrayList;
23 import java.util.Map;
24 import java.util.TreeMap;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map.Entry;
28 import java.text.SimpleDateFormat;
29 import javax.servlet.http.HttpServletRequest;
30 import javax.swing.text.html.HTMLDocument.Iterator;
31
32 import org.apache.hadoop.chukwa.util.XssFilter;
33 import org.json.JSONArray;
34
35 @SuppressWarnings("unused")
36 public class Chart {
37 private String id;
38 private String title;
39 private String graphType;
40 private ArrayList<TreeMap<String, TreeMap<String, Double>>> dataset;
41 private ArrayList<String> chartType;
42 private ArrayList<String> restData;
43 private boolean xLabelOn;
44 private boolean yLabelOn;
45 private boolean yRightLabelOn;
46 private int width;
47 private int height;
48 private List<String> xLabelRange;
49 private HashMap<String, Long> xLabelRangeHash;
50 private HttpServletRequest request = null;
51 private boolean legend;
52 private String xLabel = "";
53 private String yLabel = "";
54 private String yRightLabel = "";
55 private int datasetCounter = 0;
56 private double max = 0;
57 private double min = 0;
58 private int seriesCounter = 0;
59 private List<String> rightList;
60 private boolean userDefinedMax = false;
61 private boolean userDefinedMin = false;
62 private boolean displayPercentage = false;
63 private String[] seriesOrder = null;
64 private XssFilter xf = null;
65
66 public Chart(HttpServletRequest request) {
67 xf = new XssFilter(request);
68 if (request != null && xf.getParameter("boxId") != null) {
69 this.id = xf.getParameter("boxId");
70 } else {
71 this.id = "0";
72 }
73 this.title = "Untitled Chart";
74 this.graphType = "image";
75 this.xLabelOn = true;
76 this.yLabelOn = true;
77 this.width = 400;
78 this.height = 200;
79 this.request = request;
80 this.legend = true;
81 this.max = 0;
82 this.datasetCounter = 0;
83 this.seriesCounter = 0;
84 this.rightList = new ArrayList<String>();
85 this.userDefinedMax = false;
86 this.userDefinedMin = false;
87 this.displayPercentage = false;
88 this.seriesOrder = null;
89 }
90
91 public void setYMax(double max) {
92 this.max = max;
93 this.userDefinedMax = true;
94 }
95
96 public void setYMin(double min) {
97 this.min = min;
98 this.userDefinedMin = true;
99 }
100
101 public void setDisplayPercentage(boolean percentage) {
102 this.displayPercentage = percentage;
103 }
104
105 public void setSize(int width, int height) {
106 this.width = width;
107 this.height = height;
108 }
109
110 public void setGraphType(String graphType) {
111 if (graphType != null) {
112 this.graphType = graphType;
113 }
114 }
115
116 public void setTitle(String title) {
117 this.title = title;
118 }
119
120 public void setId(String id) {
121 this.id = id;
122 }
123
124 public void setDataSet(String chartType,
125 TreeMap<String, TreeMap<String, Double>> data) {
126 if (this.dataset == null) {
127 this.dataset = new ArrayList<TreeMap<String, TreeMap<String, Double>>>();
128 this.chartType = new ArrayList<String>();
129 }
130 this.dataset.add(data);
131 this.chartType.add(chartType);
132 }
133
134 public void setDataSet(String chartType, String series, String data) {
135 if (this.dataset == null) {
136 this.restData = new ArrayList<String>();
137 this.dataset = new ArrayList<TreeMap<String, TreeMap<String, Double>>>();
138 this.chartType = new ArrayList<String>();
139 }
140 this.chartType.add(chartType);
141 this.restData.add(data);
142 TreeMap<String, TreeMap<String, Double>> tree = new TreeMap<String, TreeMap<String, Double>>();
143 tree.put(series, new TreeMap<String, Double>());
144 this.dataset.add(tree);
145 }
146
147 public void setSeriesOrder(String[] metrics) {
148 this.seriesOrder = (String[]) metrics.clone();
149 }
150
151 public void setXAxisLabels(boolean toggle) {
152 xLabelOn = toggle;
153 }
154
155 public void setYAxisLabels(boolean toggle) {
156 yLabelOn = toggle;
157 }
158
159 public void setYAxisRightLabels(boolean toggle) {
160 yRightLabelOn = toggle;
161 }
162
163 public void setXAxisLabel(String label) {
164 xLabel = label;
165 }
166
167 public void setYAxisLabel(String label) {
168 yLabel = label;
169 }
170
171 public void setYAxisRightLabel(String label) {
172 yRightLabel = label;
173 }
174
175 public void setXLabelsRange(List<String> range) {
176 xLabelRange = range;
177 xLabelRangeHash = new HashMap<String, Long>();
178 long value = 0;
179 for (String label : range) {
180 xLabelRangeHash.put(label, value);
181 value++;
182 }
183 }
184
185 public void setLegend(boolean toggle) {
186 legend = toggle;
187 }
188
189 public String plot() {
190 StringBuilder output = new StringBuilder();
191 if (dataset == null && restData == null) {
192 output.append("No Data available.");
193 return output.toString();
194 }
195 String dateFormat = "%H:%M";
196 if (xLabel.intern() == "Time".intern()) {
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217 }
218 StringBuilder xAxisOptions = new StringBuilder();
219 if (xLabel.intern() == "Time".intern()) {
220
221
222
223
224
225 xAxisOptions.append("mode: \"time\"");
226 } else {
227 xAxisOptions
228 .append("tickFormatter: function (val, axis) { if(val!=0) { return xLabels[Math.round(val)]; } else { return \" \"; }; }, ticks: 5");
229 }
230 if (request != null && xf.getParameter("format") == null) {
231 output
232 .append("<html><link href=\"/hicc/css/default.css\" rel=\"stylesheet\" type=\"text/css\">\n");
233 output
234 .append("<html><link href=\"/hicc/css/iframe.css\" rel=\"stylesheet\" type=\"text/css\">\n");
235 output
236 .append("<html><link href=\"/hicc/css/flexigrid/flexigrid.css\" rel=\"stylesheet\" type=\"text/css\">\n");
237 output
238 .append("<body><script type=\"text/javascript\" src=\"/hicc/js/jquery-1.2.6.min.js\"></script>\n");
239 output
240 .append("<script type=\"text/javascript\" src=\"/hicc/js/jquery.flot.pack.js\"></script>\n");
241 output
242 .append("<script type=\"text/javascript\" src=\"/hicc/js/flexigrid.pack.js\"></script>\n");
243 output
244 .append("<script type=\"text/javascript\" src=\"/hicc/js/excanvas.pack.js\"></script>\n");
245 output
246 .append("<script type=\"text/javascript\" src=\"/hicc/js/base64.js\"></script>\n");
247 output
248 .append("<script type=\"text/javascript\" src=\"/hicc/js/canvas2image.js\"></script>\n");
249 output.append("<div id=\"placeholderTitle\"><center>" + title
250 + "</center></div>\n");
251 output.append("<div id=\"placeholder\" style=\"width:" + this.width
252 + "px;height:" + this.height + "px;\"></div>\n");
253 output.append("<center><div id=\"placeholderLegend\" style=\"display:"+(legend?"block":"none")+";\"></div></center>\n");
254 output.append("<center><div id=\"statisLegend\" style=\"display:"+(legend?"block":"none")+";\"></div></center>\n");
255 output.append("<center><div id=\"statisLegend\" style=\"display:"+(legend?"block":"none")+";\"></div></center>\n");
256 output.append("<input type=\"hidden\" id=\"boxId\" value=\"iframe"
257 + this.id + "\">\n");
258 output
259 .append("<script type=\"text/javascript\" src=\"/hicc/js/flot.extend.js\">\n");
260 output.append("</script>\n");
261 output.append("<script type=\"text/javascript\">\n");
262 output.append("var chartTitle=\"<center>" + title + "</center>\";\n");
263 output.append("var height=" + this.height + ";\n");
264 output.append("var xLabels=new Array();\n");
265 output.append("var cw = document.body.clientWidth-70;\n");
266 output.append("var ch = document.body.clientHeight-50;\n");
267 output
268 .append("document.getElementById('placeholder').style.width=cw+'px';\n");
269 output
270 .append("document.getElementById('placeholder').style.height=ch+'px';\n");
271 }
272 output.append("_options={\n");
273 output.append(" points: { show: false },\n");
274 output.append(" xaxis: { " + xAxisOptions + " },\n");
275 output.append(" selection: { mode: \"xy\" },\n");
276 output.append(" grid: {\n");
277 output.append(" clickable: true,\n");
278 output.append(" hoverable: true,\n");
279 output.append(" tickColor: \"#C0C0C0\",\n");
280 output.append(" borderWidth: 0,\n");
281 output.append(" backgroundColor:\"#F9F9F9\"\n");
282 output.append(" },\n");
283 output.append(" legend: { show: " + this.legend
284 + ", noColumns: 3, container: $(\"#placeholderLegend\") },\n");
285 output.append(" yaxis: { ");
286 boolean stack = false;
287 for (String type : this.chartType) {
288 if (type.startsWith("stack")) {
289 stack = true;
290 }
291 }
292 if (stack) {
293 output.append("mode: \"stack\", ");
294 }
295 if (displayPercentage) {
296 output
297 .append("tickFormatter: function(val, axis) { return val.toFixed(axis.tickDecimals) + \" %\"; }");
298 } else {
299 output.append("tickFormatter: function(val, axis) { ");
300 output
301 .append("if (val >= 1000000000000000) return (val / 1000000000000000).toFixed(2) + \"x10<sup>15</sup>\";");
302 output
303 .append("else if (val >= 100000000000000) return (val / 100000000000000).toFixed(2) + \"x10<sup>14</sup>\";");
304 output
305 .append("else if (val >= 10000000000000) return (val / 10000000000000).toFixed(2) + \"x10<sup>13</sup>\";");
306 output
307 .append("else if (val >= 1000000000000) return (val / 1000000000000).toFixed(2) + \"x10<sup>12</sup>\";");
308 output
309 .append("else if (val >= 100000000000) return (val / 100000000000).toFixed(2) + \"x10<sup>11</sup>\";");
310 output
311 .append("else if (val >= 10000000000) return (val / 10000000000).toFixed(2) + \"x10<sup>10</sup>\";");
312 output
313 .append("else if (val >= 1000000000) return (val / 1000000000).toFixed(2) + \"x10<sup>9</sup>\";");
314 output
315 .append("else if (val >= 100000000) return (val / 100000000).toFixed(2) + \"x10<sup>8</sup>\";");
316 output
317 .append("else if (val >= 10000000) return (val / 10000000).toFixed(2) + \"x10<sup>7</sup>\";");
318 output
319 .append("else if (val >= 1000000) return (val / 1000000).toFixed(2) + \"x10<sup>6</sup>\";");
320 output
321 .append("else if (val >= 100000) return (val / 100000).toFixed(2) + \"x10<sup>5</sup>\";");
322 output
323 .append("else if (val >= 10000) return (val / 10000).toFixed(2) + \"x10<sup>4</sup>\";");
324 output
325 .append("else if (val >= 2000) return (val / 1000).toFixed(2) + \"x10<sup>3</sup>\";");
326 output.append("else return val.toFixed(2) + \"\"; }");
327 }
328 if (userDefinedMin) {
329 output.append(", min:");
330 output.append(this.min);
331 }
332 if (userDefinedMax) {
333 output.append(", max:");
334 output.append(this.max);
335 }
336 output.append("}\n");
337 output.append(" };\n");
338 if (!xLabel.equals("Time")) {
339 output.append("xLabels = [\"");
340 for (int i = 0; i < xLabelRange.size(); i++) {
341 if (i > 0) {
342 output.append("\",\"");
343 }
344 output.append(xLabelRange.get(i));
345 }
346 output.append("\"];\n");
347 }
348 output.append("_series=[\n");
349 ColorPicker cp = new ColorPicker();
350 int i = 0;
351 if(this.dataset!=null) {
352 for (TreeMap<String, TreeMap<String, Double>> dataMap : this.dataset) {
353 String[] keyNames;
354 if (this.seriesOrder != null) {
355 keyNames = this.seriesOrder;
356 } else {
357 keyNames = dataMap.keySet().toArray(
358 new String[dataMap.size()]);
359 }
360 int counter = 0;
361 if (i != 0 && !this.userDefinedMax) {
362 this.max = 0;
363 }
364 for (String seriesName : keyNames) {
365 int counter2 = 0;
366 if ((counter != 0) || (i != 0)) {
367 output.append(",");
368 }
369 String param = "fill: false, lineWidth: 1";
370 String type = "lines";
371 if (this.chartType.get(i).intern() == "stack-area".intern()
372 || this.chartType.get(i).intern() == "area".intern()) {
373 param = "fill: true, lineWidth: 0";
374 }
375 if (this.chartType.get(i).intern() == "bar".intern()) {
376 type = "bars";
377 param = "stepByStep: true, lineWidth: 0";
378 }
379 if (this.chartType.get(i).intern() == "point".intern()) {
380 type = "points";
381 param = "fill: false";
382 }
383 output.append(" {");
384 output.append(type);
385 output.append(": { show: true, ");
386 output.append(param);
387 output.append(" }, color: \"");
388 output.append(cp.getNext());
389 output.append("\", label: \"");
390 output.append(seriesName);
391 output.append("\", ");
392 String showYAxis = "false";
393 String shortRow = "false";
394 if (counter == 0 || i > 0) {
395 showYAxis = "true";
396 shortRow = "false";
397 }
398 output.append(" row: { show: ");
399 output.append(showYAxis);
400 output.append(",shortRow:");
401 output.append(shortRow);
402 output.append(", showYAxis:");
403 output.append(showYAxis);
404 output.append("}, data:[");
405 TreeMap<String, Double> data = dataMap.get(seriesName);
406 if(data!=null) {
407 java.util.Iterator<Entry<String, Double>> iter = data.entrySet().iterator();
408 while (iter.hasNext()) {
409 Map.Entry<String, Double> entry = (Map.Entry<String, Double>) iter.next();
410 int rangeLabel = 0;
411 if (counter2 != 0) {
412 output.append(",");
413 }
414 if (xLabel.equals("Time")) {
415 if (Double.isNaN(entry.getValue())) {
416 output.append("[");
417 output.append(entry.getKey());
418 output.append(",NULL]");
419 } else {
420 output.append("[");
421 output.append(entry.getKey());
422 output.append(",");
423 output.append(entry.getValue());
424 output.append("]");
425 }
426 } else {
427 long value = xLabelRangeHash.get(entry.getKey());
428 if (Double.isNaN(entry.getValue())) {
429 output.append("[");
430 output.append(value);
431 output.append(",NULL]");
432 } else {
433 output.append("[");
434 output.append(value);
435 output.append(",");
436 output.append(entry.getValue());
437 output.append("]");
438 }
439 rangeLabel++;
440 }
441 counter2++;
442 }
443 }
444 output.append("], min:0");
445 if (this.userDefinedMax) {
446 output.append(", max:");
447 output.append(this.max);
448 }
449 output.append("}");
450 counter++;
451 }
452 i++;
453 }
454 }
455 output.append(" ];\n");
456 if(this.restData!=null) {
457 JSONArray arr = new JSONArray();
458 for(String url : restData) {
459 arr.put(url);
460 }
461 output.append("var _rest = ");
462 output.append(arr.toString());
463 output.append(";");
464 }
465 if (request != null && xf.getParameter("format") == null) {
466 output.append("$(document).ready(function() { \n");
467 if(this.restData!=null) {
468 output.append(" loadData();\n");
469 } else {
470 output.append(" wholePeriod();\n");
471 }
472 output.append(" $(window).resize(function() { wholePeriod(); });\n");
473 output.append("});\n");
474 output.append("</script>\n");
475 output.append("<input type=\"button\" value=\"Export\" onclick=\"javascript:saveReport();\">\n");
476 output.append("</body></html>\n");
477 } else {
478 output.append("chartTitle=\"<center>" + this.title + "</center>\";");
479 output.append("height=" + this.height + ";");
480 }
481 return output.toString();
482 }
483 }