3 * Copyright 2012 Dan Vanderkam (danvdk@gmail.com)
4 * MIT-licensed (http://opensource.org/licenses/MIT)
7 /*global Dygraph:false */
12 Current bits of jankiness:
13 - Uses dygraph.layout_ to get the parsed annotations.
14 - Uses dygraph.plotter_.area
16 It would be nice if the plugin didn't require so much special support inside
17 the core dygraphs classes, but annotations involve quite a bit of parsing and
20 TODO(danvk): cache DOM elements.
23 var annotations
= function() {
24 this.annotations_
= [];
27 annotations
.prototype.toString
= function() {
28 return "Annotations Plugin";
31 annotations
.prototype.activate
= function(g
) {
33 clearChart
: this.clearChart
,
34 didDrawChart
: this.didDrawChart
38 annotations
.prototype.detachLabels
= function() {
39 for (var i
= 0; i
< this.annotations_
.length
; i
++) {
40 var a
= this.annotations_
[i
];
41 if (a
.parentNode
) a
.parentNode
.removeChild(a
);
42 this.annotations_
[i
] = null;
44 this.annotations_
= [];
47 annotations
.prototype.clearChart
= function(e
) {
51 annotations
.prototype.didDrawChart
= function(e
) {
54 // Early out in the (common) case of zero annotations.
55 var points
= g
.layout_
.annotated_points
;
56 if (!points
|| points
.length
=== 0) return;
58 var containerDiv
= e
.canvas
.parentNode
;
60 var bindEvt
= function(eventName
, classEventName
, pt
) {
61 return function(annotation_event
) {
62 var a
= pt
.annotation
;
63 if (a
.hasOwnProperty(eventName
)) {
64 a
[eventName
](a
, pt
, g
, annotation_event
);
65 } else if (g
.getOption(classEventName
)) {
66 g
.getOption(classEventName
)(a
, pt
, g
, annotation_event
);
71 // Add the annotations one-by-one.
72 var area
= e
.dygraph
.getArea();
74 // x-coord to sum of previous annotation's heights (used for stacking).
75 var xToUsedHeight
= {};
77 for (var i
= 0; i
< points
.length
; i
++) {
79 if (p
.canvasx
< area
.x
|| p
.canvasx
> area
.x
+ area
.w
||
80 p
.canvasy
< area
.y
|| p
.canvasy
> area
.y
+ area
.h
) {
86 if (a
.hasOwnProperty("tickHeight")) {
87 tick_height
= a
.tickHeight
;
90 // TODO: deprecate axisLabelFontSize in favor of CSS
91 var div
= document
.createElement("div");
92 div
.style
['fontSize'] = g
.getOption('axisLabelFontSize') + "px";
93 var className
= 'dygraph-annotation';
94 if (!a
.hasOwnProperty('icon')) {
95 // camelCase class names are deprecated.
96 className
+= ' dygraphDefaultAnnotation dygraph-default-annotation';
98 if (a
.hasOwnProperty('cssClass')) {
99 className
+= " " + a
.cssClass
;
101 div
.className
= className
;
103 var width
= a
.hasOwnProperty('width') ? a
.width
: 16;
104 var height
= a
.hasOwnProperty('height') ? a
.height
: 16;
105 if (a
.hasOwnProperty('icon')) {
106 var img
= document
.createElement("img");
110 div
.appendChild(img
);
111 } else if (p
.annotation
.hasOwnProperty('shortText')) {
112 div
.appendChild(document
.createTextNode(p
.annotation
.shortText
));
114 var left
= p
.canvasx
- width
/ 2;
115 div
.style
.left
= left
+ "px";
117 if (a
.attachAtBottom
) {
118 var y
= (area
.y
+ area
.h
- height
- tick_height
);
119 if (xToUsedHeight
[left
]) {
120 y
-= xToUsedHeight
[left
];
122 xToUsedHeight
[left
] = 0;
124 xToUsedHeight
[left
] += (tick_height
+ height
);
127 divTop
= p
.canvasy
- height
- tick_height
;
129 div
.style
.top
= divTop
+ "px";
130 div
.style
.width
= width
+ "px";
131 div
.style
.height
= height
+ "px";
132 div
.title
= p
.annotation
.text
;
133 div
.style
.color
= g
.colorsMap_
[p
.name
];
134 div
.style
.borderColor
= g
.colorsMap_
[p
.name
];
137 g
.addAndTrackEvent(div
, 'click',
138 bindEvt('clickHandler', 'annotationClickHandler', p
, this));
139 g
.addAndTrackEvent(div
, 'mouseover',
140 bindEvt('mouseOverHandler', 'annotationMouseOverHandler', p
, this));
141 g
.addAndTrackEvent(div
, 'mouseout',
142 bindEvt('mouseOutHandler', 'annotationMouseOutHandler', p
, this));
143 g
.addAndTrackEvent(div
, 'dblclick',
144 bindEvt('dblClickHandler', 'annotationDblClickHandler', p
, this));
146 containerDiv
.appendChild(div
);
147 this.annotations_
.push(div
);
149 var ctx
= e
.drawingContext
;
151 ctx
.strokeStyle
= a
.hasOwnProperty('tickColor') ? a
.tickColor
: g
.colorsMap_
[p
.name
];
152 ctx
.lineWidth
= a
.hasOwnProperty('tickWidth') ? a
.tickWidth
: g
.getOption('strokeWidth');
154 if (!a
.attachAtBottom
) {
155 ctx
.moveTo(p
.canvasx
, p
.canvasy
);
156 ctx
.lineTo(p
.canvasx
, p
.canvasy
- 2 - tick_height
);
158 var y
= divTop
+ height
;
159 ctx
.moveTo(p
.canvasx
, y
);
160 ctx
.lineTo(p
.canvasx
, y
+ tick_height
);
168 annotations
.prototype.destroy
= function() {
172 export default annotations
;