36532cd32f85904306cd87f490032f23cc17ab45
[dygraphs.git] / Util.js
1 /**
2 * @fileoverview Utility functions for Dygraphs.
3 *
4 * @author konigsberg@google.com (Robert Konigsberg)
5 */
6
7 import * as utils from '../../src/dygraph-utils';
8
9 var Util = {};
10
11 /**
12 * Get the y-labels for a given axis.
13 *
14 * You can specify a parent if more than one graph is in the document.
15 */
16 Util.getYLabels = function(axis_num, parent) {
17 axis_num = axis_num || "";
18 parent = parent || document;
19 var y_labels = parent.getElementsByClassName("dygraph-axis-label-y" + axis_num);
20 var ary = [];
21 for (var i = 0; i < y_labels.length; i++) {
22 ary.push(y_labels[i].innerHTML.replace(/&#160;|&nbsp;/g, ' '));
23 }
24 return ary;
25 };
26
27 /**
28 * Get the x-labels for a given axis.
29 *
30 * You can specify a parent if more than one graph is in the document.
31 */
32 Util.getXLabels = function(parent) {
33 parent = parent || document;
34 var x_labels = parent.getElementsByClassName("dygraph-axis-label-x");
35 var ary = [];
36 for (var i = 0; i < x_labels.length; i++) {
37 ary.push(x_labels[i].innerHTML.replace(/&#160;|&nbsp;/g, ' '));
38 }
39 return ary;
40 };
41
42 /**
43 * Returns all text in tags w/ a given css class, sorted.
44 * You can specify a parent if more than one graph is on the document.
45 */
46 Util.getClassTexts = function(css_class, parent) {
47 parent = parent || document;
48 var texts = [];
49 var els = parent.getElementsByClassName(css_class);
50 for (var i = 0; i < els.length; i++) {
51 texts[i] = els[i].textContent;
52 }
53 texts.sort();
54 return texts;
55 };
56
57 // Convert &nbsp; to a normal space
58 Util.nbspToSpace = function(str) {
59 var re = new RegExp(String.fromCharCode(160), 'g');
60 return str.replace(re, ' ');
61 };
62
63 Util.getLegend = function(parent) {
64 parent = parent || document;
65 var legend = parent.getElementsByClassName("dygraph-legend")[0];
66 return Util.nbspToSpace(legend.textContent);
67 };
68
69 /**
70 * Assert that all elements have a certain style property.
71 */
72 Util.assertStyleOfChildren = function(selector, property, expectedValue) {
73 assert.isTrue(selector.length > 0);
74 for (var idx = 0; idx < selector.length; idx++) {
75 var child = selector[idx];
76 assert.equal(expectedValue, window.getComputedStyle(child)[property]);
77 }
78 };
79
80
81 /**
82 * Takes in an array of strings and returns an array of floats.
83 */
84 Util.makeNumbers = function(ary) {
85 var ret = [];
86 for (var i = 0; i < ary.length; i++) {
87 ret.push(parseFloat(ary[i]));
88 }
89 return ret;
90 };
91
92
93 /**
94 * Sample a pixel from the canvas.
95 * Returns an [r, g, b, a] tuple where each values is in [0, 255].
96 * This is _very_ slow! If you want to sample many pixels, use PixelSampler.
97 */
98 Util.samplePixel = function(canvas, x, y) {
99 var ctx = canvas.getContext("2d"); // bypasses Proxy if applied.
100
101 var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
102
103 var scale = utils.getContextPixelRatio(ctx);
104
105 var i = 4 * (x * scale + imageData.width * y * scale);
106 var d = imageData.data;
107 return [d[i], d[i+1], d[i+2], d[i+3]];
108 };
109
110 /**
111 * Overrides the browser's built-in XMLHttpRequest with a mock.
112 * Usage:
113 *
114 * var mockXhr = Util.overrideXMLHttpRequest(your_data);
115 * ... call code that does an XHR ...
116 * mockXhr.respond(); // restores default behavior.
117 * ... do your assertions ...
118 */
119 Util.overrideXMLHttpRequest = function(data) {
120 var originalXMLHttpRequest = XMLHttpRequest;
121
122 var requests = [];
123 var FakeXMLHttpRequest = function () {
124 requests.push(this);
125 };
126 FakeXMLHttpRequest.prototype.open = function () {};
127 FakeXMLHttpRequest.prototype.send = function () {
128 this.readyState = 4;
129 this.status = 200;
130 this.responseText = data;
131 };
132 FakeXMLHttpRequest.restore = function() {
133 window.XMLHttpRequest = originalXMLHttpRequest;
134 };
135 FakeXMLHttpRequest.respond = function() {
136 for (var i = 0; i < requests.length; i++) {
137 requests[i].onreadystatechange();
138 }
139 FakeXMLHttpRequest.restore();
140 };
141 window.XMLHttpRequest = FakeXMLHttpRequest;
142 return FakeXMLHttpRequest;
143 };
144
145 /**
146 * Format a date as 2000/01/23
147 * @param {number} dateMillis Millis since epoch.
148 * @return {string} The date formatted as YYYY-MM-DD.
149 */
150 Util.formatDate = function(dateMillis) {
151 return utils.dateString_(dateMillis).slice(0, 10); // 10 == "YYYY/MM/DD".length
152 };
153
154 /**
155 * Capture console.{log,warn,error} statements into obj.
156 * obj will look like {log:[], warn:[], error:[]}
157 * This returns a function which will restore the original console.
158 */
159 Util.captureConsole = function(obj) {
160 obj.log = [];
161 obj.warn = [];
162 obj.error = [];
163 var orig = [console.log, console.warn, console.error];
164 console.log = function(text) { obj.log.push(text); };
165 console.warn = function(text) { obj.warn.push(text); };
166 console.error = function(text) { obj.error.push(text); };
167
168 return function() {
169 console.log = orig[0];
170 console.warn = orig[1];
171 console.error = orig[2];
172 };
173 };
174
175 export default Util;