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