3 * Copyright 2012 Dan Vanderkam (danvdk@gmail.com)
4 * MIT-licensed (http://opensource.org/licenses/MIT)
6 Dygraph
.Plugins
.ChartLabels
= (function() {
8 // TODO(danvk): move chart label options out of dygraphs and into the plugin.
10 var chart_labels
= function() {
11 this.title_div_
= null;
12 this.xlabel_div_
= null;
13 this.ylabel_div_
= null;
14 this.y2label_div_
= null;
17 chart_labels
.prototype.toString
= function() {
18 return "ChartLabels Plugin";
21 chart_labels
.prototype.activate
= function(g
) {
24 // clearChart: this.clearChart,
25 drawChart
: this.drawChart
29 // QUESTION: should there be a plugin-utils.js?
30 var createDivInRect
= function(r
) {
31 var div
= document
.createElement('div');
32 div
.style
.position
= 'absolute';
33 div
.style
.left
= r
.x
+ 'px';
34 div
.style
.top
= r
.y
+ 'px';
35 div
.style
.width
= r
.w
+ 'px';
36 div
.style
.height
= r
.h
+ 'px';
40 // Detach and null out any existing nodes.
41 chart_labels
.prototype.detachLabels_
= function() {
42 var els
= [ this.title_div_
,
46 for (var i
= 0; i
< els
.length
; i
++) {
49 if (el
.parentNode
) el
.parentNode
.removeChild(el
);
52 this.title_div_
= null;
53 this.xlabel_div_
= null;
54 this.ylabel_div_
= null;
55 this.y2label_div_
= null;
58 var createRotatedDiv
= function(g
, box
, axis
, classes
, html
) {
59 // TODO(danvk): is this outer div actually necessary?
60 div
= document
.createElement("div");
61 div
.style
.position
= 'absolute';
63 div
.style
.left
= box
.left
;
65 div
.style
.right
= box
.left
;
67 div
.style
.top
= box
.top
+ 'px';
68 div
.style
.width
= box
.width
+ 'px';
69 div
.style
.height
= box
.height
+ 'px';
70 div
.style
.fontSize
= (g
.getOption('yLabelWidth') - 2) + 'px';
72 var inner_div
= document
.createElement("div");
73 inner_div
.style
.position
= 'absolute';
74 inner_div
.style
.width
= box
.height
+ 'px';
75 inner_div
.style
.height
= box
.width
+ 'px';
76 inner_div
.style
.top
= (box
.height
/ 2 - box.width / 2) + 'px';
77 inner_div
.style
.left
= (box
.width
/ 2 - box.height / 2) + 'px';
78 inner_div
.style
.textAlign
= 'center';
80 // CSS rotation is an HTML5 feature which is not standardized. Hence every
81 // browser has its own name for the CSS style.
82 var val
= 'rotate(' + (axis
== 1 ? '-' : '') + '90deg)';
83 inner_div
.style
.transform
= val
; // HTML5
84 inner_div
.style
.WebkitTransform
= val
; // Safari/Chrome
85 inner_div
.style
.MozTransform
= val
; // Firefox
86 inner_div
.style
.OTransform
= val
; // Opera
87 inner_div
.style
.msTransform
= val
; // IE9
89 if (typeof(document
.documentMode
) !== 'undefined' &&
90 document
.documentMode
< 9) {
91 // We're dealing w/ an old version of IE
, so we have to rotate the text
92 // using a BasicImage transform. This uses a different origin of rotation
93 // than HTML5 rotation (top left of div vs. its center).
94 inner_div
.style
.filter
=
95 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' +
96 (axis
== 1 ? '3' : '1') + ')';
97 inner_div
.style
.left
= '0px';
98 inner_div
.style
.top
= '0px';
101 class_div
= document
.createElement("div");
102 class_div
.className
= classes
;
103 class_div
.innerHTML
= html
;
105 inner_div
.appendChild(class_div
);
106 div
.appendChild(inner_div
);
110 chart_labels
.prototype.layout
= function(e
) {
111 this.detachLabels_();
114 var div
= e
.chart_div
;
115 if (g
.getOption('title')) {
116 // QUESTION: should this return an absolutely-positioned div instead?
117 var title_rect
= e
.reserveSpaceTop(g
.getOption('titleHeight'));
118 this.title_div_
= createDivInRect(title_rect
);
119 this.title_div_
.className
= 'dygraph-label dygraph-title';
120 this.title_div_
.innerHTML
= g
.getOption('title');
121 this.title_div_
.style
.textAlign
= 'center';
122 this.title_div_
.style
.fontSize
= (g
.getOption('titleHeight') - 8) + 'px';
123 this.title_div_
.style
.fontWeight
= 'bold';
124 div
.appendChild(this.title_div_
);
127 if (g
.getOption('ylabel')) {
128 // It would make sense to shift the chart here to make room for the y-axis
129 // label, but the default yAxisLabelWidth is large enough that this results
130 // in overly-padded charts. The y-axis label should fit fine. If it
131 // doesn't, the yAxisLabelWidth option can be increased.
132 var y_rect
= e
.reserveSpaceLeft(0);
134 this.ylabel_div_
= createRotatedDiv(
136 1, // primary (left) y-axis
137 'dygraph-label dygraph-ylabel',
138 g
.getOption('ylabel'));
139 div
.appendChild(this.ylabel_div_
);
143 if (g.getOption('xlabel')) {
144 var x_rect = e.reserveSpaceBottom(g.getOption('xLabelHeight'));
147 if (g.getOption('y2label')) {
148 var y2_rect = e.reserveSpaceRight(0);
153 chart_labels
.prototype.drawChart
= function(e
) {
155 if (this.title_div_
) {
156 this.title_div_
.innerHTML
= g
.getOption('title');
158 if (this.ylabel_div_
) {
163 chart_labels
.prototype.clearChart
= function() {
166 chart_labels
.prototype.destroy
= function() {