Initial OpenECOMP policy/engine commit
[policy/engine.git] / ecomp-sdk-app / src / main / webapp / static / fusion / raptor / dy3 / js / plugins / chart-labels.js
1 /**
2  * @license
3  * Copyright 2012 Dan Vanderkam (danvdk@gmail.com)
4  * MIT-licensed (http://opensource.org/licenses/MIT)
5  */
6 /*global Dygraph:false */
7
8 Dygraph.Plugins.ChartLabels = (function() {
9
10 "use strict";
11
12 // TODO(danvk): move chart label options out of dygraphs and into the plugin.
13 // TODO(danvk): only tear down & rebuild the DIVs when it's necessary.
14
15 var chart_labels = function() {
16   this.title_div_ = null;
17   this.xlabel_div_ = null;
18   this.ylabel_div_ = null;
19   this.y2label_div_ = null;
20 };
21
22 chart_labels.prototype.toString = function() {
23   return "ChartLabels Plugin";
24 };
25
26 chart_labels.prototype.activate = function(g) {
27   return {
28     layout: this.layout,
29     // clearChart: this.clearChart,
30     didDrawChart: this.didDrawChart
31   };
32 };
33
34 // QUESTION: should there be a plugin-utils.js?
35 var createDivInRect = function(r) {
36   var div = document.createElement('div');
37   div.style.position = 'absolute';
38   div.style.left = r.x + 'px';
39   div.style.top = r.y + 'px';
40   div.style.width = r.w + 'px';
41   div.style.height = r.h + 'px';
42   return div;
43 };
44
45 // Detach and null out any existing nodes.
46 chart_labels.prototype.detachLabels_ = function() {
47   var els = [ this.title_div_,
48               this.xlabel_div_,
49               this.ylabel_div_,
50               this.y2label_div_ ];
51   for (var i = 0; i < els.length; i++) {
52     var el = els[i];
53     if (!el) continue;
54     if (el.parentNode) el.parentNode.removeChild(el);
55   }
56
57   this.title_div_ = null;
58   this.xlabel_div_ = null;
59   this.ylabel_div_ = null;
60   this.y2label_div_ = null;
61 };
62
63 var createRotatedDiv = function(g, box, axis, classes, html) {
64   // TODO(danvk): is this outer div actually necessary?
65   var div = document.createElement("div");
66   div.style.position = 'absolute';
67   if (axis == 1) {
68     // NOTE: this is cheating. Should be positioned relative to the box.
69     div.style.left = '0px';
70   } else {
71     div.style.left = box.x + 'px';
72   }
73   div.style.top = box.y + 'px';
74   div.style.width = box.w + 'px';
75   div.style.height = box.h + 'px';
76   div.style.fontSize = (g.getOption('yLabelWidth') - 2) + 'px';
77
78   var inner_div = document.createElement("div");
79   inner_div.style.position = 'absolute';
80   inner_div.style.width = box.h + 'px';
81   inner_div.style.height = box.w + 'px';
82   inner_div.style.top = (box.h / 2 - box.w / 2) + 'px';
83   inner_div.style.left = (box.w / 2 - box.h / 2) + 'px';
84   inner_div.style.textAlign = 'center';
85
86   // CSS rotation is an HTML5 feature which is not standardized. Hence every
87   // browser has its own name for the CSS style.
88   var val = 'rotate(' + (axis == 1 ? '-' : '') + '90deg)';
89   inner_div.style.transform = val;        // HTML5
90   inner_div.style.WebkitTransform = val;  // Safari/Chrome
91   inner_div.style.MozTransform = val;     // Firefox
92   inner_div.style.OTransform = val;       // Opera
93   inner_div.style.msTransform = val;      // IE9
94
95   if (typeof(document.documentMode) !== 'undefined' &&
96       document.documentMode < 9) {
97     // We're dealing w/ an old version of IE, so we have to rotate the text
98     // using a BasicImage transform. This uses a different origin of rotation
99     // than HTML5 rotation (top left of div vs. its center).
100     inner_div.style.filter =
101         'progid:DXImageTransform.Microsoft.BasicImage(rotation=' +
102         (axis == 1 ? '3' : '1') + ')';
103     inner_div.style.left = '0px';
104     inner_div.style.top = '0px';
105   }
106
107   var class_div = document.createElement("div");
108   class_div.className = classes;
109   class_div.innerHTML = html;
110
111   inner_div.appendChild(class_div);
112   div.appendChild(inner_div);
113   return div;
114 };
115
116 chart_labels.prototype.layout = function(e) {
117   this.detachLabels_();
118
119   var g = e.dygraph;
120   var div = e.chart_div;
121   if (g.getOption('title')) {
122     // QUESTION: should this return an absolutely-positioned div instead?
123     var title_rect = e.reserveSpaceTop(g.getOption('titleHeight'));
124     this.title_div_ = createDivInRect(title_rect);
125     this.title_div_.style.textAlign = 'center';
126     this.title_div_.style.fontSize = (g.getOption('titleHeight') - 8) + 'px';
127     this.title_div_.style.fontWeight = 'bold';
128     this.title_div_.style.zIndex = 10;
129
130     var class_div = document.createElement("div");
131     class_div.className = 'dygraph-label dygraph-title';
132     class_div.innerHTML = g.getOption('title');
133     this.title_div_.appendChild(class_div);
134     div.appendChild(this.title_div_);
135   }
136
137   if (g.getOption('xlabel')) {
138     var x_rect = e.reserveSpaceBottom(g.getOption('xLabelHeight'));
139     this.xlabel_div_ = createDivInRect(x_rect);
140     this.xlabel_div_.style.textAlign = 'center';
141     this.xlabel_div_.style.fontSize = (g.getOption('xLabelHeight') - 2) + 'px';
142
143     var class_div = document.createElement("div");
144     class_div.className = 'dygraph-label dygraph-xlabel';
145     class_div.innerHTML = g.getOption('xlabel');
146     this.xlabel_div_.appendChild(class_div);
147     div.appendChild(this.xlabel_div_);
148   }
149
150   if (g.getOption('ylabel')) {
151     // It would make sense to shift the chart here to make room for the y-axis
152     // label, but the default yAxisLabelWidth is large enough that this results
153     // in overly-padded charts. The y-axis label should fit fine. If it
154     // doesn't, the yAxisLabelWidth option can be increased.
155     var y_rect = e.reserveSpaceLeft(0);
156
157     this.ylabel_div_ = createRotatedDiv(
158         g, y_rect,
159         1,  // primary (left) y-axis
160         'dygraph-label dygraph-ylabel',
161         g.getOption('ylabel'));
162     div.appendChild(this.ylabel_div_);
163   }
164
165   if (g.getOption('y2label') && g.numAxes() == 2) {
166     // same logic applies here as for ylabel.
167     var y2_rect = e.reserveSpaceRight(0);
168     this.y2label_div_ = createRotatedDiv(
169         g, y2_rect,
170         2,  // secondary (right) y-axis
171         'dygraph-label dygraph-y2label',
172         g.getOption('y2label'));
173     div.appendChild(this.y2label_div_);
174   }
175 };
176
177 chart_labels.prototype.didDrawChart = function(e) {
178   var g = e.dygraph;
179   if (this.title_div_) {
180     this.title_div_.children[0].innerHTML = g.getOption('title');
181   }
182   if (this.xlabel_div_) {
183     this.xlabel_div_.children[0].innerHTML = g.getOption('xlabel');
184   }
185   if (this.ylabel_div_) {
186     this.ylabel_div_.children[0].children[0].innerHTML = g.getOption('ylabel');
187   }
188   if (this.y2label_div_) {
189     this.y2label_div_.children[0].children[0].innerHTML = g.getOption('y2label');
190   }
191 };
192
193 chart_labels.prototype.clearChart = function() {
194 };
195
196 chart_labels.prototype.destroy = function() {
197   this.detachLabels_();
198 };
199
200
201 return chart_labels;
202 })();