Initial OpenECOMP policy/engine commit
[policy/engine.git] / ecomp-sdk-app / src / main / webapp / static / fusion / raptor / dy3 / js / plugins / annotations.js
1 /**
2  * @license
3  * Copyright 2012 Dan Vanderkam (danvdk@gmail.com)
4  * MIT-licensed (http://opensource.org/licenses/MIT)
5  */
6
7 /*global Dygraph:false */
8
9 Dygraph.Plugins.Annotations = (function() {
10
11 "use strict";
12
13 /**
14 Current bits of jankiness:
15 - Uses dygraph.layout_ to get the parsed annotations.
16 - Uses dygraph.plotter_.area
17
18 It would be nice if the plugin didn't require so much special support inside
19 the core dygraphs classes, but annotations involve quite a bit of parsing and
20 layout.
21
22 TODO(danvk): cache DOM elements.
23
24 */
25
26 var annotations = function() {
27   this.annotations_ = [];
28 };
29
30 annotations.prototype.toString = function() {
31   return "Annotations Plugin";
32 };
33
34 annotations.prototype.activate = function(g) {
35   return {
36     clearChart: this.clearChart,
37     didDrawChart: this.didDrawChart
38   };
39 };
40
41 annotations.prototype.detachLabels = function() {
42   for (var i = 0; i < this.annotations_.length; i++) {
43     var a = this.annotations_[i];
44     if (a.parentNode) a.parentNode.removeChild(a);
45     this.annotations_[i] = null;
46   }
47   this.annotations_ = [];
48 };
49
50 annotations.prototype.clearChart = function(e) {
51   this.detachLabels();
52 };
53
54 annotations.prototype.didDrawChart = function(e) {
55   var g = e.dygraph;
56
57   // Early out in the (common) case of zero annotations.
58   var points = g.layout_.annotated_points;
59   if (!points || points.length === 0) return;
60
61   var containerDiv = e.canvas.parentNode;
62   var annotationStyle = {
63     "position": "absolute",
64     "fontSize": g.getOption('axisLabelFontSize') + "px",
65     "zIndex": 10,
66     "overflow": "hidden"
67   };
68
69   var bindEvt = function(eventName, classEventName, pt) {
70     return function(annotation_event) {
71       var a = pt.annotation;
72       if (a.hasOwnProperty(eventName)) {
73         a[eventName](a, pt, g, annotation_event);
74       } else if (g.getOption(classEventName)) {
75         g.getOption(classEventName)(a, pt, g, annotation_event );
76       }
77     };
78   };
79
80   // Add the annotations one-by-one.
81   var area = e.dygraph.plotter_.area;
82
83   // x-coord to sum of previous annotation's heights (used for stacking).
84   var xToUsedHeight = {};
85
86   for (var i = 0; i < points.length; i++) {
87     var p = points[i];
88     if (p.canvasx < area.x || p.canvasx > area.x + area.w ||
89         p.canvasy < area.y || p.canvasy > area.y + area.h) {
90       continue;
91     }
92
93     var a = p.annotation;
94     var tick_height = 6;
95     if (a.hasOwnProperty("tickHeight")) {
96       tick_height = a.tickHeight;
97     }
98
99     var div = document.createElement("div");
100     for (var name in annotationStyle) {
101       if (annotationStyle.hasOwnProperty(name)) {
102         div.style[name] = annotationStyle[name];
103       }
104     }
105     if (!a.hasOwnProperty('icon')) {
106       div.className = "dygraphDefaultAnnotation";
107     }
108     if (a.hasOwnProperty('cssClass')) {
109       div.className += " " + a.cssClass;
110     }
111
112     var width = a.hasOwnProperty('width') ? a.width : 16;
113     var height = a.hasOwnProperty('height') ? a.height : 16;
114     if (a.hasOwnProperty('icon')) {
115       var img = document.createElement("img");
116       img.src = a.icon;
117       img.width = width;
118       img.height = height;
119       div.appendChild(img);
120     } else if (p.annotation.hasOwnProperty('shortText')) {
121       div.appendChild(document.createTextNode(p.annotation.shortText));
122     }
123     var left = p.canvasx - width / 2;
124     div.style.left = left + "px";
125     var divTop = 0;
126     if (a.attachAtBottom) {
127       var y = (area.y + area.h - height - tick_height);
128       if (xToUsedHeight[left]) {
129         y -= xToUsedHeight[left];
130       } else {
131         xToUsedHeight[left] = 0;
132       }
133       xToUsedHeight[left] += (tick_height + height);
134       divTop = y;
135     } else {
136       divTop = p.canvasy - height - tick_height;
137     }
138     div.style.top = divTop + "px";
139     div.style.width = width + "px";
140     div.style.height = height + "px";
141     div.title = p.annotation.text;
142     div.style.color = g.colorsMap_[p.name];
143     div.style.borderColor = g.colorsMap_[p.name];
144     a.div = div;
145
146     g.addAndTrackEvent(div, 'click',
147         bindEvt('clickHandler', 'annotationClickHandler', p, this));
148     g.addAndTrackEvent(div, 'mouseover',
149         bindEvt('mouseOverHandler', 'annotationMouseOverHandler', p, this));
150     g.addAndTrackEvent(div, 'mouseout',
151         bindEvt('mouseOutHandler', 'annotationMouseOutHandler', p, this));
152     g.addAndTrackEvent(div, 'dblclick',
153         bindEvt('dblClickHandler', 'annotationDblClickHandler', p, this));
154
155     containerDiv.appendChild(div);
156     this.annotations_.push(div);
157
158     var ctx = e.drawingContext;
159     ctx.save();
160     ctx.strokeStyle = g.colorsMap_[p.name];
161     ctx.beginPath();
162     if (!a.attachAtBottom) {
163       ctx.moveTo(p.canvasx, p.canvasy);
164       ctx.lineTo(p.canvasx, p.canvasy - 2 - tick_height);
165     } else {
166       var y = divTop + height;
167       ctx.moveTo(p.canvasx, y);
168       ctx.lineTo(p.canvasx, y + tick_height);
169     }
170     ctx.closePath();
171     ctx.stroke();
172     ctx.restore();
173   }
174 };
175
176 annotations.prototype.destroy = function() {
177   this.detachLabels();
178 };
179
180 return annotations;
181
182 })();