mpld3 0.5.3 → 0.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2079 @@
1
+ if (!d3) {
2
+ var d3 = require("d3");
3
+ }
4
+
5
+ var mpld3 = {
6
+ _mpld3IsLoaded: true,
7
+ figures: [],
8
+ plugin_map: {}
9
+ };
10
+
11
+ mpld3.version = "0.5.7";
12
+
13
+ mpld3.register_plugin = function(name, obj) {
14
+ mpld3.plugin_map[name] = obj;
15
+ };
16
+
17
+ mpld3.remove_figure = function(figid) {
18
+ var element = document.getElementById(figid);
19
+ if (element !== null) {
20
+ element.innerHTML = "";
21
+ }
22
+ for (var i = 0; i < mpld3.figures.length; i++) {
23
+ var fig = mpld3.figures[i];
24
+ if (fig.figid === figid) {
25
+ mpld3.figures.splice(i, 1);
26
+ }
27
+ }
28
+ return true;
29
+ };
30
+
31
+ mpld3.draw_figure = function(figid, spec, process, clearElem) {
32
+ var element = document.getElementById(figid);
33
+ clearElem = typeof clearElem !== "undefined" ? clearElem : false;
34
+ if (clearElem) {
35
+ mpld3.remove_figure(figid);
36
+ }
37
+ if (element === null) {
38
+ throw figid + " is not a valid id";
39
+ }
40
+ var fig = new mpld3.Figure(figid, spec);
41
+ if (process) {
42
+ process(fig, element);
43
+ }
44
+ mpld3.figures.push(fig);
45
+ fig.draw();
46
+ return fig;
47
+ };
48
+
49
+ mpld3.cloneObj = mpld3_cloneObj;
50
+
51
+ function mpld3_cloneObj(oldObj) {
52
+ var newObj = {};
53
+ for (var key in oldObj) {
54
+ newObj[key] = oldObj[key];
55
+ }
56
+ return newObj;
57
+ }
58
+
59
+ mpld3.boundsToTransform = function(fig, bounds) {
60
+ var width = fig.width;
61
+ var height = fig.height;
62
+ var dx = bounds[1][0] - bounds[0][0];
63
+ var dy = bounds[1][1] - bounds[0][1];
64
+ var x = (bounds[0][0] + bounds[1][0]) / 2;
65
+ var y = (bounds[0][1] + bounds[1][1]) / 2;
66
+ var scale = Math.max(1, Math.min(8, .9 / Math.max(dx / width, dy / height)));
67
+ var translate = [ width / 2 - scale * x, height / 2 - scale * y ];
68
+ return {
69
+ translate: translate,
70
+ scale: scale
71
+ };
72
+ };
73
+
74
+ mpld3.getTransformation = function(transform) {
75
+ var g = document.createElementNS("http://www.w3.org/2000/svg", "g");
76
+ g.setAttributeNS(null, "transform", transform);
77
+ var matrix = g.transform.baseVal.consolidate().matrix;
78
+ var a = matrix.a, b = matrix.b, c = matrix.c, d = matrix.d, e = matrix.e, f = matrix.f;
79
+ var scaleX, scaleY, skewX;
80
+ if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
81
+ if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
82
+ if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
83
+ if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
84
+ var transformObj = {
85
+ translateX: e,
86
+ translateY: f,
87
+ rotate: Math.atan2(b, a) * 180 / Math.PI,
88
+ skewX: Math.atan(skewX) * 180 / Math.PI,
89
+ scaleX: scaleX,
90
+ scaleY: scaleY
91
+ };
92
+ var transformStr = "" + "translate(" + transformObj.translateX + "," + transformObj.translateY + ")" + "rotate(" + transformObj.rotate + ")" + "skewX(" + transformObj.skewX + ")" + "scale(" + transformObj.scaleX + "," + transformObj.scaleY + ")";
93
+ return transformStr;
94
+ };
95
+
96
+ mpld3.merge_objects = function(_) {
97
+ var output = {};
98
+ var obj;
99
+ for (var i = 0; i < arguments.length; i++) {
100
+ obj = arguments[i];
101
+ for (var attr in obj) {
102
+ output[attr] = obj[attr];
103
+ }
104
+ }
105
+ return output;
106
+ };
107
+
108
+ mpld3.generate_id = function(N, chars) {
109
+ console.warn("mpld3.generate_id is deprecated. " + "Use mpld3.generateId instead.");
110
+ return mpld3_generateId(N, chars);
111
+ };
112
+
113
+ mpld3.generateId = mpld3_generateId;
114
+
115
+ function mpld3_generateId(N, chars) {
116
+ N = typeof N !== "undefined" ? N : 10;
117
+ chars = typeof chars !== "undefined" ? chars : "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
118
+ var id = chars.charAt(Math.round(Math.random() * (chars.length - 11)));
119
+ for (var i = 1; i < N; i++) id += chars.charAt(Math.round(Math.random() * (chars.length - 1)));
120
+ return id;
121
+ }
122
+
123
+ mpld3.get_element = function(id, fig) {
124
+ var figs_to_search, ax, el;
125
+ if (typeof fig === "undefined") {
126
+ figs_to_search = mpld3.figures;
127
+ } else if (typeof fig.length === "undefined") {
128
+ figs_to_search = [ fig ];
129
+ } else {
130
+ figs_to_search = fig;
131
+ }
132
+ for (var i = 0; i < figs_to_search.length; i++) {
133
+ fig = figs_to_search[i];
134
+ if (fig.props.id === id) {
135
+ return fig;
136
+ }
137
+ for (var j = 0; j < fig.axes.length; j++) {
138
+ ax = fig.axes[j];
139
+ if (ax.props.id === id) {
140
+ return ax;
141
+ }
142
+ for (var k = 0; k < ax.elements.length; k++) {
143
+ el = ax.elements[k];
144
+ if (el.props.id === id) {
145
+ return el;
146
+ }
147
+ }
148
+ }
149
+ }
150
+ return null;
151
+ };
152
+
153
+ mpld3.insert_css = function(selector, attributes) {
154
+ var head = document.head || document.getElementsByTagName("head")[0];
155
+ var style = document.createElement("style");
156
+ var css = selector + " {";
157
+ for (var prop in attributes) {
158
+ css += prop + ":" + attributes[prop] + "; ";
159
+ }
160
+ css += "}";
161
+ style.type = "text/css";
162
+ if (style.styleSheet) {
163
+ style.styleSheet.cssText = css;
164
+ } else {
165
+ style.appendChild(document.createTextNode(css));
166
+ }
167
+ head.appendChild(style);
168
+ };
169
+
170
+ mpld3.process_props = function(obj, properties, defaults, required) {
171
+ console.warn("mpld3.process_props is deprecated. " + "Plot elements should derive from mpld3.PlotElement");
172
+ Element.prototype = Object.create(mpld3_PlotElement.prototype);
173
+ Element.prototype.constructor = Element;
174
+ Element.prototype.requiredProps = required;
175
+ Element.prototype.defaultProps = defaults;
176
+ function Element(props) {
177
+ mpld3_PlotElement.call(this, null, props);
178
+ }
179
+ var el = new Element(properties);
180
+ return el.props;
181
+ };
182
+
183
+ mpld3.interpolateDates = mpld3_interpolateDates;
184
+
185
+ function mpld3_interpolateDates(a, b) {
186
+ var interp = d3.interpolate([ a[0].valueOf(), a[1].valueOf() ], [ b[0].valueOf(), b[1].valueOf() ]);
187
+ return function(t) {
188
+ var i = interp(t);
189
+ return [ new Date(i[0]), new Date(i[1]) ];
190
+ };
191
+ }
192
+
193
+ function isUndefined(x) {
194
+ return typeof x === "undefined";
195
+ }
196
+
197
+ function isUndefinedOrNull(x) {
198
+ return x == null || isUndefined(x);
199
+ }
200
+
201
+ function getMod(L, i) {
202
+ return L.length > 0 ? L[i % L.length] : null;
203
+ }
204
+
205
+ mpld3.path = function() {
206
+ return mpld3_path();
207
+ };
208
+
209
+ function mpld3_path(_) {
210
+ var x = function(d, i) {
211
+ return d[0];
212
+ };
213
+ var y = function(d, i) {
214
+ return d[1];
215
+ };
216
+ var defined = function(d, i) {
217
+ return true;
218
+ };
219
+ var n_vertices = {
220
+ M: 1,
221
+ m: 1,
222
+ L: 1,
223
+ l: 1,
224
+ Q: 2,
225
+ q: 2,
226
+ T: 1,
227
+ t: 1,
228
+ S: 2,
229
+ s: 2,
230
+ C: 3,
231
+ c: 3,
232
+ Z: 0,
233
+ z: 0
234
+ };
235
+ function path(vertices, pathcodes) {
236
+ var functor = function(x) {
237
+ if (typeof x == "function") {
238
+ return x;
239
+ }
240
+ return function() {
241
+ return x;
242
+ };
243
+ };
244
+ var fx = functor(x), fy = functor(y);
245
+ var points = [], segments = [], i_v = 0, i_c = -1, halt = 0, nullpath = false;
246
+ if (!pathcodes) {
247
+ pathcodes = [ "M" ];
248
+ for (var i = 1; i < vertices.length; i++) pathcodes.push("L");
249
+ }
250
+ while (++i_c < pathcodes.length) {
251
+ halt = i_v + n_vertices[pathcodes[i_c]];
252
+ points = [];
253
+ while (i_v < halt) {
254
+ if (defined.call(this, vertices[i_v], i_v)) {
255
+ points.push(fx.call(this, vertices[i_v], i_v), fy.call(this, vertices[i_v], i_v));
256
+ i_v++;
257
+ } else {
258
+ points = null;
259
+ i_v = halt;
260
+ }
261
+ }
262
+ if (!points) {
263
+ nullpath = true;
264
+ } else if (nullpath && points.length > 0) {
265
+ segments.push("M", points[0], points[1]);
266
+ nullpath = false;
267
+ } else {
268
+ segments.push(pathcodes[i_c]);
269
+ segments = segments.concat(points);
270
+ }
271
+ }
272
+ if (i_v != vertices.length) console.warn("Warning: not all vertices used in Path");
273
+ return segments.join(" ");
274
+ }
275
+ path.x = function(_) {
276
+ if (!arguments.length) return x;
277
+ x = _;
278
+ return path;
279
+ };
280
+ path.y = function(_) {
281
+ if (!arguments.length) return y;
282
+ y = _;
283
+ return path;
284
+ };
285
+ path.defined = function(_) {
286
+ if (!arguments.length) return defined;
287
+ defined = _;
288
+ return path;
289
+ };
290
+ path.call = path;
291
+ return path;
292
+ }
293
+
294
+ mpld3.multiscale = mpld3_multiscale;
295
+
296
+ function mpld3_multiscale(_) {
297
+ var args = Array.prototype.slice.call(arguments, 0);
298
+ var N = args.length;
299
+ function scale(x) {
300
+ args.forEach(function(mapping) {
301
+ x = mapping(x);
302
+ });
303
+ return x;
304
+ }
305
+ scale.domain = function(x) {
306
+ if (!arguments.length) return args[0].domain();
307
+ args[0].domain(x);
308
+ return scale;
309
+ };
310
+ scale.range = function(x) {
311
+ if (!arguments.length) return args[N - 1].range();
312
+ args[N - 1].range(x);
313
+ return scale;
314
+ };
315
+ scale.step = function(i) {
316
+ return args[i];
317
+ };
318
+ return scale;
319
+ }
320
+
321
+ mpld3.icons = {
322
+ reset: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI\nWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIcACMoD/OzIwAAAJhJREFUOMtjYKAx4KDUgNsMDAx7\nyNV8i4GB4T8U76VEM8mGYNNMtCH4NBM0hBjNMIwSsMzQ0MamcDkDA8NmQi6xggpUoikwQbIkHk2u\nE0rLI7vCBknBSyxeRDZAE6qHgQkq+ZeBgYERSfFPAoHNDNUDN4BswIRmKgxwEasP2dlsDAwMYlA/\n/mVgYHiBpkkGKscIDaPfVMmuAGnOTaGsXF0MAAAAAElFTkSuQmCC\n",
323
+ move: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI\nWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIcACQMfLHBNQAAANZJREFUOMud07FKA0EQBuAviaKB\nlFr7COJrpAyYRlKn8hECEkFEn8ROCCm0sBMRYgh5EgVFtEhsRjiO27vkBoZd/vn5d3b+XcrjFI9q\nxgXWkc8pUjOB93GMd3zgB9d1unjDSxmhWSHQqOJki+MtOuv/b3ZifUqctIrMxwhHuG1gim4Ma5kR\nWuEkXFgU4B0MW1Ho4TeyjX3s4TDq3zn8ALvZ7q5wX9DqLOHCDA95cFBAnOO1AL/ZdNopgY3fQcqF\nyriMe37hM9w521ZkkvlMo7o/8g7nZYQ/QDctp1nTCf0AAAAASUVORK5CYII=\n",
324
+ zoom: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI\nWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gMPDiIRPL/2oQAAANBJREFUOMvF0b9KgzEcheHHVnCT\nKoI4uXbtLXgB3oJDJxevw1VwkoJ/NjepQ2/BrZRCx0ILFURQKV2kyOeSQpAmn7WDB0Lg955zEhLy\n2scdXlBggits+4WOQqjAJ3qYR7NGLrwXGU9+sGbEtlIF18FwmuBngZ+nCt6CIacC3Rx8LSl4xzgF\nn0tusBn4UyVhuA/7ZYIv5g+pE3ail25hN/qdmzCfpsJVjKKCZesDBwtzrAqGOMQj6vhCDRsY4ALH\nmOVObltR/xeG/jph6OD2r+Fv5lZBWEhMx58AAAAASUVORK5CYII=\n",
325
+ brush: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI\nWXMAAEQkAABEJAFAZ8RUAAAAB3RJTUUH3gMCEiQKB9YaAgAAAWtJREFUOMuN0r1qVVEQhuFn700k\nnfEvBq0iNiIiOKXgH4KCaBeIhWARK/EibLwFCwVLjyAWaQzRGG9grC3URkHUBKKgRuWohWvL5pjj\nyTSLxcz7rZlZHyMiItqzFxGTEVF18/UoODNFxDIO4x12dkXqTcBPsCUzD+AK3ndFqhHwEsYz82gn\nN4dbmMRK9R/4KY7jAvbiWmYeHBT5Z4QCP8J1rGAeN3GvU3Mbl/Gq3qCDcxjLzOV+v78fq/iFIxFx\nPyJ2lNJpfBy2g59YzMyzEbEVLzGBJjOriLiBq5gaJrCIU3hcRCbwAtuwjm/Yg/V6I9NgDA1OR8RC\nZq6Vcd7iUwtn5h8fdMBdETGPE+Xe4ExELDRNs4bX2NfCUHe+7UExyfkCP8MhzOA7PuAkvrbwXyNF\nxF3MDqxiqlhXC7SPdaOKiN14g0u4g3H0MvOiTUSNY3iemb0ywmfMdfYyUmAJ2yPiBx6Wr/oy2Oqw\n+A1SupBzAOuE/AAAAABJRU5ErkJggg==\n"
326
+ };
327
+
328
+ mpld3.Grid = mpld3_Grid;
329
+
330
+ mpld3_Grid.prototype = Object.create(mpld3_PlotElement.prototype);
331
+
332
+ mpld3_Grid.prototype.constructor = mpld3_Grid;
333
+
334
+ mpld3_Grid.prototype.requiredProps = [ "xy" ];
335
+
336
+ mpld3_Grid.prototype.defaultProps = {
337
+ color: "gray",
338
+ dasharray: "2,2",
339
+ alpha: "0.5",
340
+ nticks: 10,
341
+ gridOn: true,
342
+ tickvalues: null,
343
+ zorder: 0
344
+ };
345
+
346
+ function mpld3_Grid(ax, prop) {
347
+ mpld3_PlotElement.call(this, ax, prop);
348
+ this.cssclass = "mpld3-" + this.props.xy + "grid";
349
+ if (this.props.xy == "x") {
350
+ this.transform = "translate(0," + this.ax.height + ")";
351
+ this.position = "bottom";
352
+ this.scale = this.ax.xdom;
353
+ this.tickSize = -this.ax.height;
354
+ } else if (this.props.xy == "y") {
355
+ this.transform = "translate(0,0)";
356
+ this.position = "left";
357
+ this.scale = this.ax.ydom;
358
+ this.tickSize = -this.ax.width;
359
+ } else {
360
+ throw "unrecognized grid xy specifier: should be 'x' or 'y'";
361
+ }
362
+ }
363
+
364
+ mpld3_Grid.prototype.draw = function() {
365
+ var scaleMethod = {
366
+ left: "axisLeft",
367
+ right: "axisRight",
368
+ top: "axisTop",
369
+ bottom: "axisBottom"
370
+ }[this.position];
371
+ this.grid = d3[scaleMethod](this.scale).ticks(this.props.nticks).tickValues(this.props.tickvalues).tickSize(this.tickSize, 0, 0).tickFormat("");
372
+ this.elem = this.ax.axes.append("g").attr("class", this.cssclass).attr("transform", this.transform).call(this.grid);
373
+ mpld3.insert_css("div#" + this.ax.fig.figid + " ." + this.cssclass + " .tick", {
374
+ stroke: this.props.color,
375
+ "stroke-dasharray": this.props.dasharray,
376
+ "stroke-opacity": this.props.alpha
377
+ });
378
+ mpld3.insert_css("div#" + this.ax.fig.figid + " ." + this.cssclass + " path", {
379
+ "stroke-width": 0
380
+ });
381
+ mpld3.insert_css("div#" + this.ax.fig.figid + " ." + this.cssclass + " .domain", {
382
+ "pointer-events": "none"
383
+ });
384
+ };
385
+
386
+ mpld3_Grid.prototype.zoomed = function(transform) {
387
+ if (transform) {
388
+ if (this.props.xy == "x") {
389
+ this.elem.call(this.grid.scale(transform.rescaleX(this.scale)));
390
+ } else {
391
+ this.elem.call(this.grid.scale(transform.rescaleY(this.scale)));
392
+ }
393
+ } else {
394
+ this.elem.call(this.grid);
395
+ }
396
+ };
397
+
398
+ mpld3.Axis = mpld3_Axis;
399
+
400
+ mpld3_Axis.prototype = Object.create(mpld3_PlotElement.prototype);
401
+
402
+ mpld3_Axis.prototype.constructor = mpld3_Axis;
403
+
404
+ mpld3_Axis.prototype.requiredProps = [ "position" ];
405
+
406
+ mpld3_Axis.prototype.defaultProps = {
407
+ nticks: 10,
408
+ tickvalues: null,
409
+ tickformat: null,
410
+ filtered_tickvalues: null,
411
+ filtered_tickformat: null,
412
+ tickformat_formatter: null,
413
+ fontsize: "11px",
414
+ fontcolor: "black",
415
+ axiscolor: "black",
416
+ scale: "linear",
417
+ grid: {},
418
+ zorder: 0,
419
+ visible: true
420
+ };
421
+
422
+ function mpld3_Axis(ax, props) {
423
+ mpld3_PlotElement.call(this, ax, props);
424
+ var trans = {
425
+ bottom: [ 0, this.ax.height ],
426
+ top: [ 0, 0 ],
427
+ left: [ 0, 0 ],
428
+ right: [ this.ax.width, 0 ]
429
+ };
430
+ var xy = {
431
+ bottom: "x",
432
+ top: "x",
433
+ left: "y",
434
+ right: "y"
435
+ };
436
+ this.ax = ax;
437
+ this.transform = "translate(" + trans[this.props.position] + ")";
438
+ this.props.xy = xy[this.props.position];
439
+ this.cssclass = "mpld3-" + this.props.xy + "axis";
440
+ this.scale = this.ax[this.props.xy + "dom"];
441
+ this.tickNr = null;
442
+ this.tickFormat = null;
443
+ }
444
+
445
+ mpld3_Axis.prototype.getGrid = function() {
446
+ var gridprop = {
447
+ nticks: this.props.nticks,
448
+ zorder: this.props.zorder,
449
+ tickvalues: null,
450
+ xy: this.props.xy
451
+ };
452
+ if (this.props.grid) {
453
+ for (var key in this.props.grid) {
454
+ gridprop[key] = this.props.grid[key];
455
+ }
456
+ }
457
+ return new mpld3_Grid(this.ax, gridprop);
458
+ };
459
+
460
+ mpld3_Axis.prototype.wrapTicks = function() {
461
+ function wrap(text, width, lineHeight) {
462
+ lineHeight = lineHeight || 1.2;
463
+ text.each(function() {
464
+ var text = d3.select(this);
465
+ var bbox = text.node().getBBox();
466
+ var textHeight = bbox.height;
467
+ var words = text.text().split(/\s+/).reverse();
468
+ var word;
469
+ var line = [];
470
+ var lineNumber = 0;
471
+ var y = text.attr("y");
472
+ var dy = textHeight;
473
+ var tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy);
474
+ while (word = words.pop()) {
475
+ line.push(word);
476
+ tspan.text(line.join(" "));
477
+ if (tspan.node().getComputedTextLength() > width) {
478
+ line.pop();
479
+ tspan.text(line.join(" "));
480
+ line = [ word ];
481
+ tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * (textHeight * lineHeight) + dy).text(word);
482
+ }
483
+ }
484
+ });
485
+ }
486
+ var TEXT_WIDTH = 80;
487
+ if (this.props.xy == "x") {
488
+ this.elem.selectAll("text").call(wrap, TEXT_WIDTH);
489
+ }
490
+ };
491
+
492
+ mpld3_Axis.prototype.draw = function() {
493
+ var scale = this.props.xy === "x" ? this.parent.props.xscale : this.parent.props.yscale;
494
+ if (scale === "date" && this.props.tickvalues) {
495
+ var domain = this.props.xy === "x" ? this.parent.x.domain() : this.parent.y.domain();
496
+ var range = this.props.xy === "x" ? this.parent.xdom.domain() : this.parent.ydom.domain();
497
+ var ordinal_to_js_date = d3.scaleLinear().domain(domain).range(range);
498
+ this.props.tickvalues = this.props.tickvalues.map(function(value) {
499
+ return new Date(ordinal_to_js_date(value));
500
+ });
501
+ }
502
+ var scaleMethod = {
503
+ left: "axisLeft",
504
+ right: "axisRight",
505
+ top: "axisTop",
506
+ bottom: "axisBottom"
507
+ }[this.props.position];
508
+ this.axis = d3[scaleMethod](this.scale);
509
+ var that = this;
510
+ this.filter_ticks(this.axis.scale().domain());
511
+ if (this.props.tickformat_formatter == "index") {
512
+ this.axis = this.axis.tickFormat(function(d, i) {
513
+ return that.props.filtered_tickformat[d];
514
+ });
515
+ } else if (this.props.tickformat_formatter == "percent") {
516
+ this.axis = this.axis.tickFormat(function(d, i) {
517
+ var value = d / that.props.tickformat.xmax * 100;
518
+ var decimals = that.props.tickformat.decimals || 0;
519
+ var formatted_string = d3.format("." + decimals + "f")(value);
520
+ return formatted_string + that.props.tickformat.symbol;
521
+ });
522
+ } else if (this.props.tickformat_formatter == "str_method") {
523
+ this.axis = this.axis.tickFormat(function(d, i) {
524
+ var formatted_string = d3.format(that.props.tickformat.format_string)(d);
525
+ return that.props.tickformat.prefix + formatted_string + that.props.tickformat.suffix;
526
+ });
527
+ } else if (this.props.tickformat_formatter == "fixed") {
528
+ this.axis = this.axis.tickFormat(function(d, i) {
529
+ return that.props.filtered_tickformat[i];
530
+ });
531
+ } else if (this.tickFormat) {
532
+ this.axis = this.axis.tickFormat(this.tickFormat);
533
+ }
534
+ if (this.tickNr) {
535
+ this.axis = this.axis.ticks(this.tickNr);
536
+ }
537
+ this.axis = this.axis.tickValues(this.props.filtered_tickvalues);
538
+ this.elem = this.ax.baseaxes.append("g").attr("transform", this.transform).attr("class", this.cssclass).call(this.axis);
539
+ this.wrapTicks();
540
+ mpld3.insert_css("div#" + this.ax.fig.figid + " ." + this.cssclass + " line, " + " ." + this.cssclass + " path", {
541
+ "shape-rendering": "crispEdges",
542
+ stroke: this.props.axiscolor,
543
+ fill: "none"
544
+ });
545
+ mpld3.insert_css("div#" + this.ax.fig.figid + " ." + this.cssclass + " text", {
546
+ "font-family": "sans-serif",
547
+ "font-size": this.props.fontsize + "px",
548
+ fill: this.props.fontcolor,
549
+ stroke: "none"
550
+ });
551
+ };
552
+
553
+ mpld3_Axis.prototype.zoomed = function(transform) {
554
+ this.filter_ticks(this.axis.scale().domain());
555
+ this.axis = this.axis.tickValues(this.props.filtered_tickvalues);
556
+ if (transform) {
557
+ if (this.props.xy == "x") {
558
+ this.elem.call(this.axis.scale(transform.rescaleX(this.scale)));
559
+ } else {
560
+ this.elem.call(this.axis.scale(transform.rescaleY(this.scale)));
561
+ }
562
+ this.wrapTicks();
563
+ } else {
564
+ this.elem.call(this.axis);
565
+ }
566
+ };
567
+
568
+ mpld3_Axis.prototype.setTicks = function(nr, format) {
569
+ this.tickNr = nr;
570
+ this.tickFormat = format;
571
+ };
572
+
573
+ mpld3_Axis.prototype.filter_ticks = function(domain) {
574
+ if (this.props.tickvalues) {
575
+ const that = this;
576
+ const filteredTickIndices = this.props.tickvalues.map(function(d, i) {
577
+ return i;
578
+ }).filter(function(d, i) {
579
+ const v = that.props.tickvalues[d];
580
+ return v >= domain[0] && v <= domain[1];
581
+ });
582
+ this.props.filtered_tickvalues = this.props.tickvalues.filter(function(d, i) {
583
+ return filteredTickIndices.includes(i);
584
+ });
585
+ if (this.props.tickformat) {
586
+ this.props.filtered_tickformat = this.props.tickformat.filter(function(d, i) {
587
+ return filteredTickIndices.includes(i);
588
+ });
589
+ } else {
590
+ this.props.filtered_tickformat = this.props.tickformat;
591
+ }
592
+ } else {
593
+ this.props.filtered_tickvalues = this.props.tickvalues;
594
+ this.props.filtered_tickformat = this.props.tickformat;
595
+ }
596
+ };
597
+
598
+ mpld3.Coordinates = mpld3_Coordinates;
599
+
600
+ function mpld3_Coordinates(trans, ax) {
601
+ this.trans = trans;
602
+ if (typeof ax === "undefined") {
603
+ this.ax = null;
604
+ this.fig = null;
605
+ if (this.trans !== "display") throw "ax must be defined if transform != 'display'";
606
+ } else {
607
+ this.ax = ax;
608
+ this.fig = ax.fig;
609
+ }
610
+ this.zoomable = this.trans === "data";
611
+ this.x = this["x_" + this.trans];
612
+ this.y = this["y_" + this.trans];
613
+ if (typeof this.x === "undefined" || typeof this.y === "undefined") throw "unrecognized coordinate code: " + this.trans;
614
+ }
615
+
616
+ mpld3_Coordinates.prototype.xy = function(d, ix, iy) {
617
+ ix = typeof ix === "undefined" ? 0 : ix;
618
+ iy = typeof iy === "undefined" ? 1 : iy;
619
+ return [ this.x(d[ix]), this.y(d[iy]) ];
620
+ };
621
+
622
+ mpld3_Coordinates.prototype.x_data = function(x) {
623
+ return this.ax.x(x);
624
+ };
625
+
626
+ mpld3_Coordinates.prototype.y_data = function(y) {
627
+ return this.ax.y(y);
628
+ };
629
+
630
+ mpld3_Coordinates.prototype.x_display = function(x) {
631
+ return x;
632
+ };
633
+
634
+ mpld3_Coordinates.prototype.y_display = function(y) {
635
+ return y;
636
+ };
637
+
638
+ mpld3_Coordinates.prototype.x_axes = function(x) {
639
+ return x * this.ax.width;
640
+ };
641
+
642
+ mpld3_Coordinates.prototype.y_axes = function(y) {
643
+ return this.ax.height * (1 - y);
644
+ };
645
+
646
+ mpld3_Coordinates.prototype.x_figure = function(x) {
647
+ return x * this.fig.width - this.ax.position[0];
648
+ };
649
+
650
+ mpld3_Coordinates.prototype.y_figure = function(y) {
651
+ return (1 - y) * this.fig.height - this.ax.position[1];
652
+ };
653
+
654
+ mpld3.Path = mpld3_Path;
655
+
656
+ mpld3_Path.prototype = Object.create(mpld3_PlotElement.prototype);
657
+
658
+ mpld3_Path.prototype.constructor = mpld3_Path;
659
+
660
+ mpld3_Path.prototype.requiredProps = [ "data" ];
661
+
662
+ mpld3_Path.prototype.defaultProps = {
663
+ xindex: 0,
664
+ yindex: 1,
665
+ coordinates: "data",
666
+ facecolor: "green",
667
+ edgecolor: "black",
668
+ edgewidth: 1,
669
+ dasharray: "none",
670
+ pathcodes: null,
671
+ offset: null,
672
+ offsetcoordinates: "data",
673
+ alpha: 1,
674
+ drawstyle: "none",
675
+ zorder: 1
676
+ };
677
+
678
+ function mpld3_Path(ax, props) {
679
+ mpld3_PlotElement.call(this, ax, props);
680
+ this.data = ax.fig.get_data(this.props.data);
681
+ this.pathcodes = this.props.pathcodes;
682
+ this.pathcoords = new mpld3_Coordinates(this.props.coordinates, this.ax);
683
+ this.offsetcoords = new mpld3_Coordinates(this.props.offsetcoordinates, this.ax);
684
+ this.datafunc = mpld3_path();
685
+ }
686
+
687
+ mpld3_Path.prototype.finiteFilter = function(d, i) {
688
+ return isFinite(this.pathcoords.x(d[this.props.xindex])) && isFinite(this.pathcoords.y(d[this.props.yindex]));
689
+ };
690
+
691
+ mpld3_Path.prototype.draw = function() {
692
+ this.datafunc.defined(this.finiteFilter.bind(this)).x(function(d) {
693
+ return this.pathcoords.x(d[this.props.xindex]);
694
+ }.bind(this)).y(function(d) {
695
+ return this.pathcoords.y(d[this.props.yindex]);
696
+ }.bind(this));
697
+ if (this.pathcoords.zoomable) {
698
+ this.path = this.ax.paths.append("svg:path");
699
+ } else {
700
+ this.path = this.ax.staticPaths.append("svg:path");
701
+ }
702
+ this.path = this.path.attr("d", this.datafunc(this.data, this.pathcodes)).attr("class", "mpld3-path").style("stroke", this.props.edgecolor).style("stroke-width", this.props.edgewidth).style("stroke-dasharray", this.props.dasharray).style("stroke-opacity", this.props.alpha).style("fill", this.props.facecolor).style("fill-opacity", this.props.alpha).attr("vector-effect", "non-scaling-stroke");
703
+ if (this.props.offset !== null) {
704
+ var offset = this.offsetcoords.xy(this.props.offset);
705
+ this.path.attr("transform", "translate(" + offset + ")");
706
+ }
707
+ };
708
+
709
+ mpld3_Path.prototype.elements = function(d) {
710
+ return this.path;
711
+ };
712
+
713
+ mpld3.PathCollection = mpld3_PathCollection;
714
+
715
+ mpld3_PathCollection.prototype = Object.create(mpld3_PlotElement.prototype);
716
+
717
+ mpld3_PathCollection.prototype.constructor = mpld3_PathCollection;
718
+
719
+ mpld3_PathCollection.prototype.requiredProps = [ "paths", "offsets" ];
720
+
721
+ mpld3_PathCollection.prototype.defaultProps = {
722
+ xindex: 0,
723
+ yindex: 1,
724
+ pathtransforms: [],
725
+ pathcoordinates: "display",
726
+ offsetcoordinates: "data",
727
+ offsetorder: "before",
728
+ edgecolors: [ "#000000" ],
729
+ drawstyle: "none",
730
+ edgewidths: [ 1 ],
731
+ facecolors: [ "#0000FF" ],
732
+ alphas: [ 1 ],
733
+ zorder: 2
734
+ };
735
+
736
+ function mpld3_PathCollection(ax, props) {
737
+ mpld3_PlotElement.call(this, ax, props);
738
+ if (this.props.facecolors == null || this.props.facecolors.length == 0) {
739
+ this.props.facecolors = [ "none" ];
740
+ }
741
+ if (this.props.edgecolors == null || this.props.edgecolors.length == 0) {
742
+ this.props.edgecolors = [ "none" ];
743
+ }
744
+ var offsets = this.ax.fig.get_data(this.props.offsets);
745
+ if (offsets === null || offsets.length === 0) offsets = [ null ];
746
+ var N = Math.max(this.props.paths.length, offsets.length);
747
+ if (offsets.length === N) {
748
+ this.offsets = offsets;
749
+ } else {
750
+ this.offsets = [];
751
+ for (var i = 0; i < N; i++) this.offsets.push(getMod(offsets, i));
752
+ }
753
+ this.pathcoords = new mpld3_Coordinates(this.props.pathcoordinates, this.ax);
754
+ this.offsetcoords = new mpld3_Coordinates(this.props.offsetcoordinates, this.ax);
755
+ }
756
+
757
+ mpld3_PathCollection.prototype.transformFunc = function(d, i) {
758
+ var t = this.props.pathtransforms;
759
+ var transform = t.length == 0 ? "" : mpld3.getTransformation("matrix(" + getMod(t, i) + ")").toString();
760
+ var offset = d === null || typeof d === "undefined" ? "translate(0, 0)" : "translate(" + this.offsetcoords.xy(d, this.props.xindex, this.props.yindex) + ")";
761
+ return this.props.offsetorder === "after" ? transform + offset : offset + transform;
762
+ };
763
+
764
+ mpld3_PathCollection.prototype.pathFunc = function(d, i) {
765
+ return mpld3_path().x(function(d) {
766
+ return this.pathcoords.x(d[0]);
767
+ }.bind(this)).y(function(d) {
768
+ return this.pathcoords.y(d[1]);
769
+ }.bind(this)).apply(this, getMod(this.props.paths, i));
770
+ };
771
+
772
+ mpld3_PathCollection.prototype.styleFunc = function(d, i) {
773
+ var styles = {
774
+ stroke: getMod(this.props.edgecolors, i),
775
+ "stroke-width": getMod(this.props.edgewidths, i),
776
+ "stroke-opacity": getMod(this.props.alphas, i),
777
+ fill: getMod(this.props.facecolors, i),
778
+ "fill-opacity": getMod(this.props.alphas, i)
779
+ };
780
+ var ret = "";
781
+ for (var key in styles) {
782
+ ret += key + ":" + styles[key] + ";";
783
+ }
784
+ return ret;
785
+ };
786
+
787
+ mpld3_PathCollection.prototype.allFinite = function(d) {
788
+ if (d instanceof Array) {
789
+ return d.length == d.filter(isFinite).length;
790
+ } else {
791
+ return true;
792
+ }
793
+ };
794
+
795
+ mpld3_PathCollection.prototype.draw = function() {
796
+ if (this.offsetcoords.zoomable || this.pathcoords.zoomable) {
797
+ this.group = this.ax.paths.append("svg:g");
798
+ } else {
799
+ this.group = this.ax.staticPaths.append("svg:g");
800
+ }
801
+ this.pathsobj = this.group.selectAll("paths").data(this.offsets.filter(this.allFinite)).enter().append("svg:path").attr("d", this.pathFunc.bind(this)).attr("class", "mpld3-path").attr("transform", this.transformFunc.bind(this)).attr("style", this.styleFunc.bind(this)).attr("vector-effect", "non-scaling-stroke");
802
+ };
803
+
804
+ mpld3_PathCollection.prototype.elements = function(d) {
805
+ return this.group.selectAll("path");
806
+ };
807
+
808
+ mpld3.Line = mpld3_Line;
809
+
810
+ mpld3_Line.prototype = Object.create(mpld3_Path.prototype);
811
+
812
+ mpld3_Line.prototype.constructor = mpld3_Line;
813
+
814
+ mpld3_Line.prototype.requiredProps = [ "data" ];
815
+
816
+ mpld3_Line.prototype.defaultProps = {
817
+ xindex: 0,
818
+ yindex: 1,
819
+ coordinates: "data",
820
+ color: "salmon",
821
+ linewidth: 2,
822
+ dasharray: "none",
823
+ alpha: 1,
824
+ zorder: 2,
825
+ drawstyle: "none"
826
+ };
827
+
828
+ function mpld3_Line(ax, props) {
829
+ mpld3_PlotElement.call(this, ax, props);
830
+ var pathProps = this.props;
831
+ pathProps.facecolor = "none";
832
+ pathProps.edgecolor = pathProps.color;
833
+ delete pathProps.color;
834
+ pathProps.edgewidth = pathProps.linewidth;
835
+ delete pathProps.linewidth;
836
+ const drawstyle = pathProps.drawstyle;
837
+ delete pathProps.drawstyle;
838
+ this.defaultProps = mpld3_Path.prototype.defaultProps;
839
+ mpld3_Path.call(this, ax, pathProps);
840
+ switch (drawstyle) {
841
+ case "steps":
842
+ case "steps-pre":
843
+ this.datafunc = d3.line().curve(d3.curveStepBefore);
844
+ break;
845
+
846
+ case "steps-post":
847
+ this.datafunc = d3.line().curve(d3.curveStepAfter);
848
+ break;
849
+
850
+ case "steps-mid":
851
+ this.datafunc = d3.line().curve(d3.curveStep);
852
+ break;
853
+
854
+ default:
855
+ this.datafunc = d3.line().curve(d3.curveLinear);
856
+ }
857
+ }
858
+
859
+ mpld3.Markers = mpld3_Markers;
860
+
861
+ mpld3_Markers.prototype = Object.create(mpld3_PathCollection.prototype);
862
+
863
+ mpld3_Markers.prototype.constructor = mpld3_Markers;
864
+
865
+ mpld3_Markers.prototype.requiredProps = [ "data" ];
866
+
867
+ mpld3_Markers.prototype.defaultProps = {
868
+ xindex: 0,
869
+ yindex: 1,
870
+ coordinates: "data",
871
+ facecolor: "salmon",
872
+ edgecolor: "black",
873
+ edgewidth: 1,
874
+ alpha: 1,
875
+ markersize: 6,
876
+ markername: "circle",
877
+ drawstyle: "none",
878
+ markerpath: null,
879
+ zorder: 3
880
+ };
881
+
882
+ function mpld3_Markers(ax, props) {
883
+ mpld3_PlotElement.call(this, ax, props);
884
+ if (this.props.markerpath !== null) {
885
+ this.marker = this.props.markerpath[0].length == 0 ? null : mpld3.path().call(this.props.markerpath[0], this.props.markerpath[1]);
886
+ } else {
887
+ this.marker = this.props.markername === null ? null : d3.symbol(this.props.markername).size(Math.pow(this.props.markersize, 2))();
888
+ }
889
+ var PCprops = {
890
+ paths: [ this.props.markerpath ],
891
+ offsets: ax.fig.parse_offsets(ax.fig.get_data(this.props.data, true)),
892
+ xindex: this.props.xindex,
893
+ yindex: this.props.yindex,
894
+ offsetcoordinates: this.props.coordinates,
895
+ edgecolors: [ this.props.edgecolor ],
896
+ edgewidths: [ this.props.edgewidth ],
897
+ facecolors: [ this.props.facecolor ],
898
+ alphas: [ this.props.alpha ],
899
+ zorder: this.props.zorder,
900
+ id: this.props.id
901
+ };
902
+ this.requiredProps = mpld3_PathCollection.prototype.requiredProps;
903
+ this.defaultProps = mpld3_PathCollection.prototype.defaultProps;
904
+ mpld3_PathCollection.call(this, ax, PCprops);
905
+ }
906
+
907
+ mpld3_Markers.prototype.pathFunc = function(d, i) {
908
+ return this.marker;
909
+ };
910
+
911
+ mpld3.Image = mpld3_Image;
912
+
913
+ mpld3_Image.prototype = Object.create(mpld3_PlotElement.prototype);
914
+
915
+ mpld3_Image.prototype.constructor = mpld3_Image;
916
+
917
+ mpld3_Image.prototype.requiredProps = [ "data", "extent" ];
918
+
919
+ mpld3_Image.prototype.defaultProps = {
920
+ alpha: 1,
921
+ coordinates: "data",
922
+ drawstyle: "none",
923
+ zorder: 1
924
+ };
925
+
926
+ function mpld3_Image(ax, props) {
927
+ mpld3_PlotElement.call(this, ax, props);
928
+ this.coords = new mpld3_Coordinates(this.props.coordinates, this.ax);
929
+ }
930
+
931
+ mpld3_Image.prototype.draw = function() {
932
+ this.image = this.ax.paths.append("svg:image");
933
+ this.image = this.image.attr("class", "mpld3-image").attr("xlink:href", "data:image/png;base64," + this.props.data).style("opacity", this.props.alpha).attr("preserveAspectRatio", "none");
934
+ this.updateDimensions();
935
+ };
936
+
937
+ mpld3_Image.prototype.elements = function(d) {
938
+ return d3.select(this.image);
939
+ };
940
+
941
+ mpld3_Image.prototype.updateDimensions = function() {
942
+ var extent = this.props.extent;
943
+ this.image.attr("x", this.coords.x(extent[0])).attr("y", this.coords.y(extent[3])).attr("width", this.coords.x(extent[1]) - this.coords.x(extent[0])).attr("height", this.coords.y(extent[2]) - this.coords.y(extent[3]));
944
+ };
945
+
946
+ mpld3.Text = mpld3_Text;
947
+
948
+ mpld3_Text.prototype = Object.create(mpld3_PlotElement.prototype);
949
+
950
+ mpld3_Text.prototype.constructor = mpld3_Text;
951
+
952
+ mpld3_Text.prototype.requiredProps = [ "text", "position" ];
953
+
954
+ mpld3_Text.prototype.defaultProps = {
955
+ coordinates: "data",
956
+ h_anchor: "start",
957
+ v_baseline: "auto",
958
+ rotation: 0,
959
+ fontsize: 11,
960
+ drawstyle: "none",
961
+ color: "black",
962
+ alpha: 1,
963
+ zorder: 3
964
+ };
965
+
966
+ function mpld3_Text(ax, props) {
967
+ mpld3_PlotElement.call(this, ax, props);
968
+ this.text = this.props.text;
969
+ this.position = this.props.position;
970
+ this.coords = new mpld3_Coordinates(this.props.coordinates, this.ax);
971
+ }
972
+
973
+ mpld3_Text.prototype.draw = function() {
974
+ if (this.props.coordinates == "data") {
975
+ if (this.coords.zoomable) {
976
+ this.obj = this.ax.paths.append("text");
977
+ } else {
978
+ this.obj = this.ax.staticPaths.append("text");
979
+ }
980
+ } else {
981
+ this.obj = this.ax.baseaxes.append("text");
982
+ }
983
+ this.obj.attr("class", "mpld3-text").text(this.text).style("text-anchor", this.props.h_anchor).style("dominant-baseline", this.props.v_baseline).style("font-size", this.props.fontsize).style("fill", this.props.color).style("opacity", this.props.alpha);
984
+ this.applyTransform();
985
+ };
986
+
987
+ mpld3_Text.prototype.elements = function(d) {
988
+ return d3.select(this.obj);
989
+ };
990
+
991
+ mpld3_Text.prototype.applyTransform = function() {
992
+ var pos = this.coords.xy(this.position);
993
+ this.obj.attr("x", pos[0]).attr("y", pos[1]);
994
+ if (this.props.rotation) this.obj.attr("transform", "rotate(" + this.props.rotation + "," + pos + ")");
995
+ };
996
+
997
+ mpld3.Axes = mpld3_Axes;
998
+
999
+ mpld3_Axes.prototype = Object.create(mpld3_PlotElement.prototype);
1000
+
1001
+ mpld3_Axes.prototype.constructor = mpld3_Axes;
1002
+
1003
+ mpld3_Axes.prototype.requiredProps = [ "xlim", "ylim" ];
1004
+
1005
+ mpld3_Axes.prototype.defaultProps = {
1006
+ bbox: [ .1, .1, .8, .8 ],
1007
+ axesbg: "#FFFFFF",
1008
+ axesbgalpha: 1,
1009
+ gridOn: false,
1010
+ xdomain: null,
1011
+ ydomain: null,
1012
+ xscale: "linear",
1013
+ yscale: "linear",
1014
+ zoomable: true,
1015
+ axes: [ {
1016
+ position: "left"
1017
+ }, {
1018
+ position: "bottom"
1019
+ } ],
1020
+ lines: [],
1021
+ paths: [],
1022
+ markers: [],
1023
+ texts: [],
1024
+ collections: [],
1025
+ sharex: [],
1026
+ sharey: [],
1027
+ images: []
1028
+ };
1029
+
1030
+ function mpld3_Axes(fig, props) {
1031
+ mpld3_PlotElement.call(this, fig, props);
1032
+ this.axnum = this.fig.axes.length;
1033
+ this.axid = this.fig.figid + "_ax" + (this.axnum + 1);
1034
+ this.clipid = this.axid + "_clip";
1035
+ this.props.xdomain = this.props.xdomain || this.props.xlim;
1036
+ this.props.ydomain = this.props.ydomain || this.props.ylim;
1037
+ this.sharex = [];
1038
+ this.sharey = [];
1039
+ this.elements = [];
1040
+ this.axisList = [];
1041
+ var bbox = this.props.bbox;
1042
+ this.position = [ bbox[0] * this.fig.width, (1 - bbox[1] - bbox[3]) * this.fig.height ];
1043
+ this.width = bbox[2] * this.fig.width;
1044
+ this.height = bbox[3] * this.fig.height;
1045
+ this.isZoomEnabled = null;
1046
+ this.zoom = null;
1047
+ this.lastTransform = d3.zoomIdentity;
1048
+ this.isBoxzoomEnabled = null;
1049
+ this.isLinkedBrushEnabled = null;
1050
+ this.isCurrentLinkedBrushTarget = false;
1051
+ this.brushG = null;
1052
+ function buildDate(d) {
1053
+ return new Date(d[0], d[1], d[2], d[3], d[4], d[5]);
1054
+ }
1055
+ function setDomain(scale, domain) {
1056
+ return scale !== "date" ? domain : [ buildDate(domain[0]), buildDate(domain[1]) ];
1057
+ }
1058
+ this.props.xdomain = setDomain(this.props.xscale, this.props.xdomain);
1059
+ this.props.ydomain = setDomain(this.props.yscale, this.props.ydomain);
1060
+ function build_scale(scale, domain, range) {
1061
+ var dom = scale === "date" ? d3.scaleTime() : scale === "log" ? d3.scaleLog() : d3.scaleLinear();
1062
+ return dom.domain(domain).range(range);
1063
+ }
1064
+ this.x = this.xdom = build_scale(this.props.xscale, this.props.xdomain, [ 0, this.width ]);
1065
+ this.y = this.ydom = build_scale(this.props.yscale, this.props.ydomain, [ this.height, 0 ]);
1066
+ if (this.props.xscale === "date") {
1067
+ this.x = mpld3.multiscale(d3.scaleLinear().domain(this.props.xlim).range(this.props.xdomain.map(Number)), this.xdom);
1068
+ }
1069
+ if (this.props.yscale === "date") {
1070
+ this.y = mpld3.multiscale(d3.scaleLinear().domain(this.props.ylim).range(this.props.ydomain.map(Number)), this.ydom);
1071
+ }
1072
+ var axes = this.props.axes;
1073
+ for (var i = 0; i < axes.length; i++) {
1074
+ var axis = new mpld3.Axis(this, axes[i]);
1075
+ this.axisList.push(axis);
1076
+ this.elements.push(axis);
1077
+ if (this.props.gridOn || axis.props.grid.gridOn) {
1078
+ this.elements.push(axis.getGrid());
1079
+ }
1080
+ }
1081
+ var paths = this.props.paths;
1082
+ for (var i = 0; i < paths.length; i++) {
1083
+ this.elements.push(new mpld3.Path(this, paths[i]));
1084
+ }
1085
+ var lines = this.props.lines;
1086
+ for (var i = 0; i < lines.length; i++) {
1087
+ this.elements.push(new mpld3.Line(this, lines[i]));
1088
+ }
1089
+ var markers = this.props.markers;
1090
+ for (var i = 0; i < markers.length; i++) {
1091
+ this.elements.push(new mpld3.Markers(this, markers[i]));
1092
+ }
1093
+ var texts = this.props.texts;
1094
+ for (var i = 0; i < texts.length; i++) {
1095
+ this.elements.push(new mpld3.Text(this, texts[i]));
1096
+ }
1097
+ var collections = this.props.collections;
1098
+ for (var i = 0; i < collections.length; i++) {
1099
+ this.elements.push(new mpld3.PathCollection(this, collections[i]));
1100
+ }
1101
+ var images = this.props.images;
1102
+ for (var i = 0; i < images.length; i++) {
1103
+ this.elements.push(new mpld3.Image(this, images[i]));
1104
+ }
1105
+ this.elements.sort(function(a, b) {
1106
+ return a.props.zorder - b.props.zorder;
1107
+ });
1108
+ }
1109
+
1110
+ mpld3_Axes.prototype.draw = function() {
1111
+ for (var i = 0; i < this.props.sharex.length; i++) {
1112
+ this.sharex.push(mpld3.get_element(this.props.sharex[i]));
1113
+ }
1114
+ for (var i = 0; i < this.props.sharey.length; i++) {
1115
+ this.sharey.push(mpld3.get_element(this.props.sharey[i]));
1116
+ }
1117
+ this.baseaxes = this.fig.canvas.append("g").attr("transform", "translate(" + this.position[0] + "," + this.position[1] + ")").attr("width", this.width).attr("height", this.height).attr("class", "mpld3-baseaxes");
1118
+ this.axes = this.baseaxes.append("g").attr("class", "mpld3-axes").style("pointer-events", "visiblefill");
1119
+ this.clip = this.axes.append("svg:clipPath").attr("id", this.clipid).append("svg:rect").attr("x", 0).attr("y", 0).attr("width", this.width).attr("height", this.height);
1120
+ this.axesbg = this.axes.append("svg:rect").attr("width", this.width).attr("height", this.height).attr("class", "mpld3-axesbg").style("fill", this.props.axesbg).style("fill-opacity", this.props.axesbgalpha);
1121
+ this.pathsContainer = this.axes.append("g").attr("clip-path", "url(#" + this.clipid + ")").attr("x", 0).attr("y", 0).attr("width", this.width).attr("height", this.height).attr("class", "mpld3-paths-container");
1122
+ this.paths = this.pathsContainer.append("g").attr("class", "mpld3-paths");
1123
+ this.staticPaths = this.axes.append("g").attr("class", "mpld3-staticpaths");
1124
+ this.brush = d3.brush().extent([ [ 0, 0 ], [ this.fig.width, this.fig.height ] ]).on("start", this.brushStart.bind(this)).on("brush", this.brushMove.bind(this)).on("end", this.brushEnd.bind(this)).on("start.nokey", function() {
1125
+ d3.select(window).on("keydown.brush keyup.brush", null);
1126
+ });
1127
+ for (var i = 0; i < this.elements.length; i++) {
1128
+ this.elements[i].draw();
1129
+ }
1130
+ };
1131
+
1132
+ mpld3_Axes.prototype.bindZoom = function() {
1133
+ if (!this.zoom) {
1134
+ this.zoom = d3.zoom();
1135
+ this.zoom.on("zoom", this.zoomed.bind(this));
1136
+ this.axes.call(this.zoom);
1137
+ }
1138
+ };
1139
+
1140
+ mpld3_Axes.prototype.unbindZoom = function() {
1141
+ if (this.zoom) {
1142
+ this.zoom.on("zoom", null);
1143
+ this.axes.on(".zoom", null);
1144
+ this.zoom = null;
1145
+ }
1146
+ };
1147
+
1148
+ mpld3_Axes.prototype.bindBrush = function() {
1149
+ if (!this.brushG) {
1150
+ this.brushG = this.axes.append("g").attr("class", "mpld3-brush").call(this.brush);
1151
+ }
1152
+ };
1153
+
1154
+ mpld3_Axes.prototype.unbindBrush = function() {
1155
+ if (this.brushG) {
1156
+ this.brushG.remove();
1157
+ this.brushG.on(".brush", null);
1158
+ this.brushG = null;
1159
+ }
1160
+ };
1161
+
1162
+ mpld3_Axes.prototype.reset = function() {
1163
+ if (this.zoom) {
1164
+ this.doZoom(false, d3.zoomIdentity, 750);
1165
+ } else {
1166
+ this.bindZoom();
1167
+ this.doZoom(false, d3.zoomIdentity, 750, function() {
1168
+ if (this.isSomeTypeOfZoomEnabled) {
1169
+ return;
1170
+ }
1171
+ this.unbindZoom();
1172
+ }.bind(this));
1173
+ }
1174
+ };
1175
+
1176
+ mpld3_Axes.prototype.enableOrDisableBrushing = function() {
1177
+ if (this.isBoxzoomEnabled || this.isLinkedBrushEnabled) {
1178
+ this.bindBrush();
1179
+ } else {
1180
+ this.unbindBrush();
1181
+ }
1182
+ };
1183
+
1184
+ mpld3_Axes.prototype.isSomeTypeOfZoomEnabled = function() {
1185
+ return this.isZoomEnabled || this.isBoxzoomEnabled;
1186
+ };
1187
+
1188
+ mpld3_Axes.prototype.enableOrDisableZooming = function() {
1189
+ if (this.isSomeTypeOfZoomEnabled()) {
1190
+ this.bindZoom();
1191
+ } else {
1192
+ this.unbindZoom();
1193
+ }
1194
+ };
1195
+
1196
+ mpld3_Axes.prototype.enableLinkedBrush = function() {
1197
+ this.isLinkedBrushEnabled = true;
1198
+ this.enableOrDisableBrushing();
1199
+ };
1200
+
1201
+ mpld3_Axes.prototype.disableLinkedBrush = function() {
1202
+ this.isLinkedBrushEnabled = false;
1203
+ this.enableOrDisableBrushing();
1204
+ };
1205
+
1206
+ mpld3_Axes.prototype.enableBoxzoom = function() {
1207
+ this.isBoxzoomEnabled = true;
1208
+ this.enableOrDisableBrushing();
1209
+ this.enableOrDisableZooming();
1210
+ };
1211
+
1212
+ mpld3_Axes.prototype.disableBoxzoom = function() {
1213
+ this.isBoxzoomEnabled = false;
1214
+ this.enableOrDisableBrushing();
1215
+ this.enableOrDisableZooming();
1216
+ };
1217
+
1218
+ mpld3_Axes.prototype.enableZoom = function() {
1219
+ this.isZoomEnabled = true;
1220
+ this.enableOrDisableZooming();
1221
+ this.axes.style("cursor", "move");
1222
+ };
1223
+
1224
+ mpld3_Axes.prototype.disableZoom = function() {
1225
+ this.isZoomEnabled = false;
1226
+ this.enableOrDisableZooming();
1227
+ this.axes.style("cursor", null);
1228
+ };
1229
+
1230
+ mpld3_Axes.prototype.doZoom = function(propagate, transform, duration, onTransitionEnd) {
1231
+ if (!this.props.zoomable || !this.zoom) {
1232
+ return;
1233
+ }
1234
+ if (duration) {
1235
+ var transition = this.axes.transition().duration(duration).call(this.zoom.transform, transform);
1236
+ if (onTransitionEnd) {
1237
+ transition.on("end", onTransitionEnd);
1238
+ }
1239
+ } else {
1240
+ this.axes.call(this.zoom.transform, transform);
1241
+ }
1242
+ if (propagate) {
1243
+ this.lastTransform = transform;
1244
+ this.sharex.forEach(function(sharedAxes) {
1245
+ sharedAxes.doZoom(false, transform, duration);
1246
+ });
1247
+ this.sharey.forEach(function(sharedAxes) {
1248
+ sharedAxes.doZoom(false, transform, duration);
1249
+ });
1250
+ } else {
1251
+ this.lastTransform = transform;
1252
+ }
1253
+ };
1254
+
1255
+ mpld3_Axes.prototype.zoomed = function() {
1256
+ var isProgrammatic = d3.event.sourceEvent && d3.event.sourceEvent.type != "zoom";
1257
+ if (isProgrammatic) {
1258
+ this.doZoom(true, d3.event.transform, false);
1259
+ } else {
1260
+ var transform = d3.event.transform;
1261
+ this.paths.attr("transform", transform);
1262
+ this.elements.forEach(function(element) {
1263
+ if (element.zoomed) {
1264
+ element.zoomed(transform);
1265
+ }
1266
+ }.bind(this));
1267
+ }
1268
+ };
1269
+
1270
+ mpld3_Axes.prototype.resetBrush = function() {
1271
+ this.brushG.call(this.brush.move, null);
1272
+ };
1273
+
1274
+ mpld3_Axes.prototype.doBoxzoom = function(selection) {
1275
+ if (!selection || !this.brushG) {
1276
+ return;
1277
+ }
1278
+ var sel = selection.map(this.lastTransform.invert, this.lastTransform);
1279
+ var dx = sel[1][0] - sel[0][0];
1280
+ var dy = sel[1][1] - sel[0][1];
1281
+ var cx = (sel[0][0] + sel[1][0]) / 2;
1282
+ var cy = (sel[0][1] + sel[1][1]) / 2;
1283
+ var scale = dx > dy ? this.width / dx : this.height / dy;
1284
+ var transX = this.width / 2 - scale * cx;
1285
+ var transY = this.height / 2 - scale * cy;
1286
+ var transform = d3.zoomIdentity.translate(transX, transY).scale(scale);
1287
+ this.doZoom(true, transform, 750);
1288
+ this.resetBrush();
1289
+ };
1290
+
1291
+ mpld3_Axes.prototype.brushStart = function() {
1292
+ if (this.isLinkedBrushEnabled) {
1293
+ this.isCurrentLinkedBrushTarget = d3.event.sourceEvent.constructor.name == "MouseEvent";
1294
+ if (this.isCurrentLinkedBrushTarget) {
1295
+ this.fig.resetBrushForOtherAxes(this.axid);
1296
+ }
1297
+ }
1298
+ };
1299
+
1300
+ mpld3_Axes.prototype.brushMove = function() {
1301
+ var selection = d3.event.selection;
1302
+ if (this.isLinkedBrushEnabled) {
1303
+ this.fig.updateLinkedBrush(selection);
1304
+ }
1305
+ };
1306
+
1307
+ mpld3_Axes.prototype.brushEnd = function() {
1308
+ var selection = d3.event.selection;
1309
+ if (this.isBoxzoomEnabled) {
1310
+ this.doBoxzoom(selection);
1311
+ }
1312
+ if (this.isLinkedBrushEnabled) {
1313
+ if (!selection) {
1314
+ this.fig.endLinkedBrush();
1315
+ }
1316
+ this.isCurrentLinkedBrushTarget = false;
1317
+ }
1318
+ };
1319
+
1320
+ mpld3_Axes.prototype.setTicks = function(xy, nr, format) {
1321
+ this.axisList.forEach(function(axis) {
1322
+ if (axis.props.xy == xy) {
1323
+ axis.setTicks(nr, format);
1324
+ }
1325
+ });
1326
+ };
1327
+
1328
+ mpld3.Toolbar = mpld3_Toolbar;
1329
+
1330
+ mpld3_Toolbar.prototype = Object.create(mpld3_PlotElement.prototype);
1331
+
1332
+ mpld3_Toolbar.prototype.constructor = mpld3_Toolbar;
1333
+
1334
+ mpld3_Toolbar.prototype.defaultProps = {
1335
+ buttons: [ "reset", "move" ]
1336
+ };
1337
+
1338
+ function mpld3_Toolbar(fig, props) {
1339
+ mpld3_PlotElement.call(this, fig, props);
1340
+ this.buttons = [];
1341
+ this.props.buttons.forEach(this.addButton.bind(this));
1342
+ }
1343
+
1344
+ mpld3_Toolbar.prototype.addButton = function(button) {
1345
+ this.buttons.push(new button(this));
1346
+ };
1347
+
1348
+ mpld3_Toolbar.prototype.draw = function() {
1349
+ mpld3.insert_css("div#" + this.fig.figid + " .mpld3-toolbar image", {
1350
+ cursor: "pointer",
1351
+ opacity: .2,
1352
+ display: "inline-block",
1353
+ margin: "0px"
1354
+ });
1355
+ mpld3.insert_css("div#" + this.fig.figid + " .mpld3-toolbar image.active", {
1356
+ opacity: .4
1357
+ });
1358
+ mpld3.insert_css("div#" + this.fig.figid + " .mpld3-toolbar image.pressed", {
1359
+ opacity: .6
1360
+ });
1361
+ function showButtons() {
1362
+ this.buttonsobj.transition(750).attr("y", 0);
1363
+ }
1364
+ function hideButtons() {
1365
+ this.buttonsobj.transition(750).delay(250).attr("y", 16);
1366
+ }
1367
+ this.fig.canvas.on("mouseenter", showButtons.bind(this)).on("mouseleave", hideButtons.bind(this)).on("touchenter", showButtons.bind(this)).on("touchstart", showButtons.bind(this));
1368
+ this.toolbar = this.fig.canvas.append("svg:svg").attr("width", 16 * this.buttons.length).attr("height", 16).attr("x", 2).attr("y", this.fig.height - 16 - 2).attr("class", "mpld3-toolbar");
1369
+ this.buttonsobj = this.toolbar.append("svg:g").selectAll("buttons").data(this.buttons).enter().append("svg:image").attr("class", function(d) {
1370
+ return d.cssclass;
1371
+ }).attr("xlink:href", function(d) {
1372
+ return d.icon();
1373
+ }).attr("width", 16).attr("height", 16).attr("x", function(d, i) {
1374
+ return i * 16;
1375
+ }).attr("y", 16).on("click", function(d) {
1376
+ d.click();
1377
+ }).on("mouseenter", function() {
1378
+ d3.select(this).classed("active", true);
1379
+ }).on("mouseleave", function() {
1380
+ d3.select(this).classed("active", false);
1381
+ });
1382
+ for (var i = 0; i < this.buttons.length; i++) this.buttons[i].onDraw();
1383
+ };
1384
+
1385
+ mpld3_Toolbar.prototype.deactivate_all = function() {
1386
+ this.buttons.forEach(function(b) {
1387
+ b.deactivate();
1388
+ });
1389
+ };
1390
+
1391
+ mpld3_Toolbar.prototype.deactivate_by_action = function(actions) {
1392
+ function filt(e) {
1393
+ return actions.indexOf(e) !== -1;
1394
+ }
1395
+ if (actions.length > 0) {
1396
+ this.buttons.forEach(function(button) {
1397
+ if (button.actions.filter(filt).length > 0) button.deactivate();
1398
+ });
1399
+ }
1400
+ };
1401
+
1402
+ mpld3.Button = mpld3_Button;
1403
+
1404
+ mpld3_Button.prototype = Object.create(mpld3_PlotElement.prototype);
1405
+
1406
+ mpld3_Button.prototype.constructor = mpld3_Button;
1407
+
1408
+ function mpld3_Button(toolbar, key) {
1409
+ mpld3_PlotElement.call(this, toolbar);
1410
+ this.toolbar = toolbar;
1411
+ this.fig = this.toolbar.fig;
1412
+ this.cssclass = "mpld3-" + key + "button";
1413
+ this.active = false;
1414
+ }
1415
+
1416
+ mpld3_Button.prototype.setState = function(state) {
1417
+ state ? this.activate() : this.deactivate();
1418
+ };
1419
+
1420
+ mpld3_Button.prototype.click = function() {
1421
+ this.active ? this.deactivate() : this.activate();
1422
+ };
1423
+
1424
+ mpld3_Button.prototype.activate = function() {
1425
+ this.toolbar.deactivate_by_action(this.actions);
1426
+ this.onActivate();
1427
+ this.active = true;
1428
+ this.toolbar.toolbar.select("." + this.cssclass).classed("pressed", true);
1429
+ if (!this.sticky) {
1430
+ this.deactivate();
1431
+ }
1432
+ };
1433
+
1434
+ mpld3_Button.prototype.deactivate = function() {
1435
+ this.onDeactivate();
1436
+ this.active = false;
1437
+ this.toolbar.toolbar.select("." + this.cssclass).classed("pressed", false);
1438
+ };
1439
+
1440
+ mpld3_Button.prototype.sticky = false;
1441
+
1442
+ mpld3_Button.prototype.actions = [];
1443
+
1444
+ mpld3_Button.prototype.icon = function() {
1445
+ return "";
1446
+ };
1447
+
1448
+ mpld3_Button.prototype.onActivate = function() {};
1449
+
1450
+ mpld3_Button.prototype.onDeactivate = function() {};
1451
+
1452
+ mpld3_Button.prototype.onDraw = function() {};
1453
+
1454
+ mpld3.ButtonFactory = function(members) {
1455
+ if (typeof members.buttonID !== "string") {
1456
+ throw "ButtonFactory: buttonID must be present and be a string";
1457
+ }
1458
+ function B(toolbar) {
1459
+ mpld3_Button.call(this, toolbar, this.buttonID);
1460
+ }
1461
+ B.prototype = Object.create(mpld3_Button.prototype);
1462
+ B.prototype.constructor = B;
1463
+ for (var key in members) {
1464
+ B.prototype[key] = members[key];
1465
+ }
1466
+ return B;
1467
+ };
1468
+
1469
+ mpld3.Plugin = mpld3_Plugin;
1470
+
1471
+ mpld3_Plugin.prototype = Object.create(mpld3_PlotElement.prototype);
1472
+
1473
+ mpld3_Plugin.prototype.constructor = mpld3_Plugin;
1474
+
1475
+ mpld3_Plugin.prototype.requiredProps = [];
1476
+
1477
+ mpld3_Plugin.prototype.defaultProps = {};
1478
+
1479
+ function mpld3_Plugin(fig, props) {
1480
+ mpld3_PlotElement.call(this, fig, props);
1481
+ }
1482
+
1483
+ mpld3_Plugin.prototype.draw = function() {};
1484
+
1485
+ mpld3.ResetPlugin = mpld3_ResetPlugin;
1486
+
1487
+ mpld3.register_plugin("reset", mpld3_ResetPlugin);
1488
+
1489
+ mpld3_ResetPlugin.prototype = Object.create(mpld3_Plugin.prototype);
1490
+
1491
+ mpld3_ResetPlugin.prototype.constructor = mpld3_ResetPlugin;
1492
+
1493
+ mpld3_ResetPlugin.prototype.requiredProps = [];
1494
+
1495
+ mpld3_ResetPlugin.prototype.defaultProps = {};
1496
+
1497
+ function mpld3_ResetPlugin(fig, props) {
1498
+ mpld3_Plugin.call(this, fig, props);
1499
+ var ResetButton = mpld3.ButtonFactory({
1500
+ buttonID: "reset",
1501
+ sticky: false,
1502
+ onActivate: function() {
1503
+ this.toolbar.fig.reset();
1504
+ },
1505
+ icon: function() {
1506
+ return mpld3.icons["reset"];
1507
+ }
1508
+ });
1509
+ this.fig.buttons.push(ResetButton);
1510
+ }
1511
+
1512
+ mpld3.ZoomPlugin = mpld3_ZoomPlugin;
1513
+
1514
+ mpld3.register_plugin("zoom", mpld3_ZoomPlugin);
1515
+
1516
+ mpld3_ZoomPlugin.prototype = Object.create(mpld3_Plugin.prototype);
1517
+
1518
+ mpld3_ZoomPlugin.prototype.constructor = mpld3_ZoomPlugin;
1519
+
1520
+ mpld3_ZoomPlugin.prototype.requiredProps = [];
1521
+
1522
+ mpld3_ZoomPlugin.prototype.defaultProps = {
1523
+ button: true,
1524
+ enabled: null
1525
+ };
1526
+
1527
+ function mpld3_ZoomPlugin(fig, props) {
1528
+ mpld3_Plugin.call(this, fig, props);
1529
+ if (this.props.enabled === null) {
1530
+ this.props.enabled = !this.props.button;
1531
+ }
1532
+ var enabled = this.props.enabled;
1533
+ if (this.props.button) {
1534
+ var ZoomButton = mpld3.ButtonFactory({
1535
+ buttonID: "zoom",
1536
+ sticky: true,
1537
+ actions: [ "scroll", "drag" ],
1538
+ onActivate: this.activate.bind(this),
1539
+ onDeactivate: this.deactivate.bind(this),
1540
+ onDraw: function() {
1541
+ this.setState(enabled);
1542
+ },
1543
+ icon: function() {
1544
+ return mpld3.icons["move"];
1545
+ }
1546
+ });
1547
+ this.fig.buttons.push(ZoomButton);
1548
+ }
1549
+ }
1550
+
1551
+ mpld3_ZoomPlugin.prototype.activate = function() {
1552
+ this.fig.enableZoom();
1553
+ };
1554
+
1555
+ mpld3_ZoomPlugin.prototype.deactivate = function() {
1556
+ this.fig.disableZoom();
1557
+ };
1558
+
1559
+ mpld3_ZoomPlugin.prototype.draw = function() {
1560
+ if (this.props.enabled) {
1561
+ this.activate();
1562
+ } else {
1563
+ this.deactivate();
1564
+ }
1565
+ };
1566
+
1567
+ mpld3.BoxZoomPlugin = mpld3_BoxZoomPlugin;
1568
+
1569
+ mpld3.register_plugin("boxzoom", mpld3_BoxZoomPlugin);
1570
+
1571
+ mpld3_BoxZoomPlugin.prototype = Object.create(mpld3_Plugin.prototype);
1572
+
1573
+ mpld3_BoxZoomPlugin.prototype.constructor = mpld3_BoxZoomPlugin;
1574
+
1575
+ mpld3_BoxZoomPlugin.prototype.requiredProps = [];
1576
+
1577
+ mpld3_BoxZoomPlugin.prototype.defaultProps = {
1578
+ button: true,
1579
+ enabled: null
1580
+ };
1581
+
1582
+ function mpld3_BoxZoomPlugin(fig, props) {
1583
+ mpld3_Plugin.call(this, fig, props);
1584
+ if (this.props.enabled === null) {
1585
+ this.props.enabled = !this.props.button;
1586
+ }
1587
+ var enabled = this.props.enabled;
1588
+ if (this.props.button) {
1589
+ var BoxZoomButton = mpld3.ButtonFactory({
1590
+ buttonID: "boxzoom",
1591
+ sticky: true,
1592
+ actions: [ "drag" ],
1593
+ onActivate: this.activate.bind(this),
1594
+ onDeactivate: this.deactivate.bind(this),
1595
+ onDraw: function() {
1596
+ this.setState(enabled);
1597
+ },
1598
+ icon: function() {
1599
+ return mpld3.icons["zoom"];
1600
+ }
1601
+ });
1602
+ this.fig.buttons.push(BoxZoomButton);
1603
+ }
1604
+ this.extentClass = "boxzoombrush";
1605
+ }
1606
+
1607
+ mpld3_BoxZoomPlugin.prototype.activate = function() {
1608
+ this.fig.enableBoxzoom();
1609
+ };
1610
+
1611
+ mpld3_BoxZoomPlugin.prototype.deactivate = function() {
1612
+ this.fig.disableBoxzoom();
1613
+ };
1614
+
1615
+ mpld3_BoxZoomPlugin.prototype.draw = function() {
1616
+ if (this.props.enabled) {
1617
+ this.activate();
1618
+ } else {
1619
+ this.deactivate();
1620
+ }
1621
+ };
1622
+
1623
+ mpld3.TooltipPlugin = mpld3_TooltipPlugin;
1624
+
1625
+ mpld3.register_plugin("tooltip", mpld3_TooltipPlugin);
1626
+
1627
+ mpld3_TooltipPlugin.prototype = Object.create(mpld3_Plugin.prototype);
1628
+
1629
+ mpld3_TooltipPlugin.prototype.constructor = mpld3_TooltipPlugin;
1630
+
1631
+ mpld3_TooltipPlugin.prototype.requiredProps = [ "id" ];
1632
+
1633
+ mpld3_TooltipPlugin.prototype.defaultProps = {
1634
+ labels: null,
1635
+ hoffset: 0,
1636
+ voffset: 10,
1637
+ location: "mouse"
1638
+ };
1639
+
1640
+ function mpld3_TooltipPlugin(fig, props) {
1641
+ mpld3_Plugin.call(this, fig, props);
1642
+ }
1643
+
1644
+ mpld3_TooltipPlugin.prototype.draw = function() {
1645
+ var obj = mpld3.get_element(this.props.id, this.fig);
1646
+ var labels = this.props.labels;
1647
+ var loc = this.props.location;
1648
+ this.tooltip = this.fig.canvas.append("text").attr("class", "mpld3-tooltip-text").attr("x", 0).attr("y", 0).text("").style("visibility", "hidden");
1649
+ if (loc == "bottom left" || loc == "top left") {
1650
+ this.x = obj.ax.position[0] + 5 + this.props.hoffset;
1651
+ this.tooltip.style("text-anchor", "beginning");
1652
+ } else if (loc == "bottom right" || loc == "top right") {
1653
+ this.x = obj.ax.position[0] + obj.ax.width - 5 + this.props.hoffset;
1654
+ this.tooltip.style("text-anchor", "end");
1655
+ } else {
1656
+ this.tooltip.style("text-anchor", "middle");
1657
+ }
1658
+ if (loc == "bottom left" || loc == "bottom right") {
1659
+ this.y = obj.ax.position[1] + obj.ax.height - 5 + this.props.voffset;
1660
+ } else if (loc == "top left" || loc == "top right") {
1661
+ this.y = obj.ax.position[1] + 5 + this.props.voffset;
1662
+ }
1663
+ function mouseover(d, i) {
1664
+ this.tooltip.style("visibility", "visible").text(labels === null ? "(" + d + ")" : getMod(labels, i));
1665
+ }
1666
+ function mousemove(d, i) {
1667
+ if (loc === "mouse") {
1668
+ var pos = d3.mouse(this.fig.canvas.node());
1669
+ this.x = pos[0] + this.props.hoffset;
1670
+ this.y = pos[1] - this.props.voffset;
1671
+ }
1672
+ this.tooltip.attr("x", this.x).attr("y", this.y);
1673
+ }
1674
+ function mouseout(d, i) {
1675
+ this.tooltip.style("visibility", "hidden");
1676
+ }
1677
+ obj.elements().on("mouseover", mouseover.bind(this)).on("mousemove", mousemove.bind(this)).on("mouseout", mouseout.bind(this));
1678
+ };
1679
+
1680
+ mpld3.LinkedBrushPlugin = mpld3_LinkedBrushPlugin;
1681
+
1682
+ mpld3.register_plugin("linkedbrush", mpld3_LinkedBrushPlugin);
1683
+
1684
+ mpld3_LinkedBrushPlugin.prototype = Object.create(mpld3.Plugin.prototype);
1685
+
1686
+ mpld3_LinkedBrushPlugin.prototype.constructor = mpld3_LinkedBrushPlugin;
1687
+
1688
+ mpld3_LinkedBrushPlugin.prototype.requiredProps = [ "id" ];
1689
+
1690
+ mpld3_LinkedBrushPlugin.prototype.defaultProps = {
1691
+ button: true,
1692
+ enabled: null
1693
+ };
1694
+
1695
+ function mpld3_LinkedBrushPlugin(fig, props) {
1696
+ mpld3.Plugin.call(this, fig, props);
1697
+ if (this.props.enabled === null) {
1698
+ this.props.enabled = !this.props.button;
1699
+ }
1700
+ var enabled = this.props.enabled;
1701
+ if (this.props.button) {
1702
+ var BrushButton = mpld3.ButtonFactory({
1703
+ buttonID: "linkedbrush",
1704
+ sticky: true,
1705
+ actions: [ "drag" ],
1706
+ onActivate: this.activate.bind(this),
1707
+ onDeactivate: this.deactivate.bind(this),
1708
+ onDraw: function() {
1709
+ this.setState(enabled);
1710
+ },
1711
+ icon: function() {
1712
+ return mpld3.icons["brush"];
1713
+ }
1714
+ });
1715
+ this.fig.buttons.push(BrushButton);
1716
+ }
1717
+ this.pathCollectionsByAxes = [];
1718
+ this.objectsByAxes = [];
1719
+ this.allObjects = [];
1720
+ this.extentClass = "linkedbrush";
1721
+ this.dataKey = "offsets";
1722
+ this.objectClass = null;
1723
+ }
1724
+
1725
+ mpld3_LinkedBrushPlugin.prototype.activate = function() {
1726
+ this.fig.enableLinkedBrush();
1727
+ };
1728
+
1729
+ mpld3_LinkedBrushPlugin.prototype.deactivate = function() {
1730
+ this.fig.disableLinkedBrush();
1731
+ };
1732
+
1733
+ mpld3_LinkedBrushPlugin.prototype.isPathInSelection = function(path, ix, iy, sel) {
1734
+ var result = sel[0][0] < path[ix] && sel[1][0] > path[ix] && sel[0][1] < path[iy] && sel[1][1] > path[iy];
1735
+ return result;
1736
+ };
1737
+
1738
+ mpld3_LinkedBrushPlugin.prototype.invertSelection = function(sel, axes) {
1739
+ var xs = [ axes.x.invert(sel[0][0]), axes.x.invert(sel[1][0]) ];
1740
+ var ys = [ axes.y.invert(sel[1][1]), axes.y.invert(sel[0][1]) ];
1741
+ return [ [ Math.min.apply(Math, xs), Math.min.apply(Math, ys) ], [ Math.max.apply(Math, xs), Math.max.apply(Math, ys) ] ];
1742
+ };
1743
+
1744
+ mpld3_LinkedBrushPlugin.prototype.update = function(selection) {
1745
+ if (!selection) {
1746
+ return;
1747
+ }
1748
+ this.pathCollectionsByAxes.forEach(function(axesColls, axesIndex) {
1749
+ var pathCollection = axesColls[0];
1750
+ var objects = this.objectsByAxes[axesIndex];
1751
+ var invertedSelection = this.invertSelection(selection, this.fig.axes[axesIndex]);
1752
+ var ix = pathCollection.props.xindex;
1753
+ var iy = pathCollection.props.yindex;
1754
+ objects.selectAll("path").classed("mpld3-hidden", function(path, idx) {
1755
+ return !this.isPathInSelection(path, ix, iy, invertedSelection);
1756
+ }.bind(this));
1757
+ }.bind(this));
1758
+ };
1759
+
1760
+ mpld3_LinkedBrushPlugin.prototype.end = function() {
1761
+ this.allObjects.selectAll("path").classed("mpld3-hidden", false);
1762
+ };
1763
+
1764
+ mpld3_LinkedBrushPlugin.prototype.draw = function() {
1765
+ mpld3.insert_css("#" + this.fig.figid + " path.mpld3-hidden", {
1766
+ stroke: "#ccc !important",
1767
+ fill: "#ccc !important"
1768
+ });
1769
+ var pathCollection = mpld3.get_element(this.props.id);
1770
+ if (!pathCollection) {
1771
+ throw new Error("[LinkedBrush] Could not find path collection");
1772
+ }
1773
+ if (!("offsets" in pathCollection.props)) {
1774
+ throw new Error("[LinkedBrush] Figure is not a scatter plot.");
1775
+ }
1776
+ this.objectClass = "mpld3-brushtarget-" + pathCollection.props[this.dataKey];
1777
+ this.pathCollectionsByAxes = this.fig.axes.map(function(axes) {
1778
+ return axes.elements.map(function(el) {
1779
+ if (el.props[this.dataKey] == pathCollection.props[this.dataKey]) {
1780
+ el.group.classed(this.objectClass, true);
1781
+ return el;
1782
+ }
1783
+ }.bind(this)).filter(function(d) {
1784
+ return d;
1785
+ });
1786
+ }.bind(this));
1787
+ this.objectsByAxes = this.fig.axes.map(function(axes) {
1788
+ return axes.axes.selectAll("." + this.objectClass);
1789
+ }.bind(this));
1790
+ this.allObjects = this.fig.canvas.selectAll("." + this.objectClass);
1791
+ };
1792
+
1793
+ mpld3.register_plugin("mouseposition", MousePositionPlugin);
1794
+
1795
+ MousePositionPlugin.prototype = Object.create(mpld3.Plugin.prototype);
1796
+
1797
+ MousePositionPlugin.prototype.constructor = MousePositionPlugin;
1798
+
1799
+ MousePositionPlugin.prototype.requiredProps = [];
1800
+
1801
+ MousePositionPlugin.prototype.defaultProps = {
1802
+ fontsize: 12,
1803
+ fmt: ".3g"
1804
+ };
1805
+
1806
+ function MousePositionPlugin(fig, props) {
1807
+ mpld3.Plugin.call(this, fig, props);
1808
+ }
1809
+
1810
+ MousePositionPlugin.prototype.draw = function() {
1811
+ var fig = this.fig;
1812
+ var fmt = d3.format(this.props.fmt);
1813
+ var coords = fig.canvas.append("text").attr("class", "mpld3-coordinates").style("text-anchor", "end").style("font-size", this.props.fontsize).attr("x", this.fig.width - 5).attr("y", this.fig.height - 5);
1814
+ for (var i = 0; i < this.fig.axes.length; i++) {
1815
+ var update_coords = function() {
1816
+ var ax = fig.axes[i];
1817
+ return function() {
1818
+ var pos = d3.mouse(this), x = ax.x.invert(pos[0]), y = ax.y.invert(pos[1]);
1819
+ coords.text("(" + fmt(x) + ", " + fmt(y) + ")");
1820
+ };
1821
+ }();
1822
+ fig.axes[i].baseaxes.on("mousemove", update_coords).on("mouseout", function() {
1823
+ coords.text("");
1824
+ });
1825
+ }
1826
+ };
1827
+
1828
+ mpld3.Figure = mpld3_Figure;
1829
+
1830
+ mpld3_Figure.prototype = Object.create(mpld3_PlotElement.prototype);
1831
+
1832
+ mpld3_Figure.prototype.constructor = mpld3_Figure;
1833
+
1834
+ mpld3_Figure.prototype.requiredProps = [ "width", "height" ];
1835
+
1836
+ mpld3_Figure.prototype.defaultProps = {
1837
+ data: {},
1838
+ axes: [],
1839
+ plugins: [ {
1840
+ type: "reset"
1841
+ }, {
1842
+ type: "zoom"
1843
+ }, {
1844
+ type: "boxzoom"
1845
+ } ]
1846
+ };
1847
+
1848
+ function mpld3_Figure(figid, props) {
1849
+ mpld3_PlotElement.call(this, null, props);
1850
+ this.figid = figid;
1851
+ this.width = this.props.width;
1852
+ this.height = this.props.height;
1853
+ this.data = this.props.data;
1854
+ this.buttons = [];
1855
+ this.root = d3.select("#" + figid).append("div").style("position", "relative");
1856
+ this.axes = [];
1857
+ for (var i = 0; i < this.props.axes.length; i++) this.axes.push(new mpld3_Axes(this, this.props.axes[i]));
1858
+ this.plugins = [];
1859
+ this.pluginsByType = {};
1860
+ this.props.plugins.forEach(function(plugin) {
1861
+ this.addPlugin(plugin);
1862
+ }.bind(this));
1863
+ this.toolbar = new mpld3.Toolbar(this, {
1864
+ buttons: this.buttons
1865
+ });
1866
+ }
1867
+
1868
+ mpld3_Figure.prototype.addPlugin = function(pluginInfo) {
1869
+ if (!pluginInfo.type) {
1870
+ return console.warn("unspecified plugin type. Skipping this");
1871
+ }
1872
+ var plugin;
1873
+ if (pluginInfo.type in mpld3.plugin_map) {
1874
+ plugin = mpld3.plugin_map[pluginInfo.type];
1875
+ } else {
1876
+ return console.warn("Skipping unrecognized plugin: " + plugin);
1877
+ }
1878
+ if (pluginInfo.clear_toolbar || pluginInfo.buttons) {
1879
+ console.warn("DEPRECATION WARNING: " + "You are using pluginInfo.clear_toolbar or pluginInfo, which " + "have been deprecated. Please see the build-in plugins for the new " + "method to add buttons, otherwise contact the mpld3 maintainers.");
1880
+ }
1881
+ var pluginInfoNoType = mpld3_cloneObj(pluginInfo);
1882
+ delete pluginInfoNoType.type;
1883
+ var pluginInstance = new plugin(this, pluginInfoNoType);
1884
+ this.plugins.push(pluginInstance);
1885
+ this.pluginsByType[pluginInfo.type] = pluginInstance;
1886
+ };
1887
+
1888
+ mpld3_Figure.prototype.draw = function() {
1889
+ mpld3.insert_css("div#" + this.figid, {
1890
+ "font-family": "Helvetica, sans-serif"
1891
+ });
1892
+ this.canvas = this.root.append("svg:svg").attr("class", "mpld3-figure").attr("width", this.width).attr("height", this.height);
1893
+ for (var i = 0; i < this.axes.length; i++) {
1894
+ this.axes[i].draw();
1895
+ }
1896
+ this.disableZoom();
1897
+ for (var i = 0; i < this.plugins.length; i++) {
1898
+ this.plugins[i].draw();
1899
+ }
1900
+ this.toolbar.draw();
1901
+ };
1902
+
1903
+ mpld3_Figure.prototype.resetBrushForOtherAxes = function(currentAxid) {
1904
+ this.axes.forEach(function(axes) {
1905
+ if (axes.axid != currentAxid) {
1906
+ axes.resetBrush();
1907
+ }
1908
+ });
1909
+ };
1910
+
1911
+ mpld3_Figure.prototype.updateLinkedBrush = function(selection) {
1912
+ if (!this.pluginsByType.linkedbrush) {
1913
+ return;
1914
+ }
1915
+ this.pluginsByType.linkedbrush.update(selection);
1916
+ };
1917
+
1918
+ mpld3_Figure.prototype.endLinkedBrush = function() {
1919
+ if (!this.pluginsByType.linkedbrush) {
1920
+ return;
1921
+ }
1922
+ this.pluginsByType.linkedbrush.end();
1923
+ };
1924
+
1925
+ mpld3_Figure.prototype.reset = function(duration) {
1926
+ this.axes.forEach(function(axes) {
1927
+ axes.reset();
1928
+ });
1929
+ };
1930
+
1931
+ mpld3_Figure.prototype.enableLinkedBrush = function() {
1932
+ this.axes.forEach(function(axes) {
1933
+ axes.enableLinkedBrush();
1934
+ });
1935
+ };
1936
+
1937
+ mpld3_Figure.prototype.disableLinkedBrush = function() {
1938
+ this.axes.forEach(function(axes) {
1939
+ axes.disableLinkedBrush();
1940
+ });
1941
+ };
1942
+
1943
+ mpld3_Figure.prototype.enableBoxzoom = function() {
1944
+ this.axes.forEach(function(axes) {
1945
+ axes.enableBoxzoom();
1946
+ });
1947
+ };
1948
+
1949
+ mpld3_Figure.prototype.disableBoxzoom = function() {
1950
+ this.axes.forEach(function(axes) {
1951
+ axes.disableBoxzoom();
1952
+ });
1953
+ };
1954
+
1955
+ mpld3_Figure.prototype.enableZoom = function() {
1956
+ this.axes.forEach(function(axes) {
1957
+ axes.enableZoom();
1958
+ });
1959
+ };
1960
+
1961
+ mpld3_Figure.prototype.disableZoom = function() {
1962
+ this.axes.forEach(function(axes) {
1963
+ axes.disableZoom();
1964
+ });
1965
+ };
1966
+
1967
+ mpld3_Figure.prototype.toggleZoom = function() {
1968
+ if (this.isZoomEnabled) {
1969
+ this.disableZoom();
1970
+ } else {
1971
+ this.enableZoom();
1972
+ }
1973
+ };
1974
+
1975
+ mpld3_Figure.prototype.setTicks = function(xy, nr, format) {
1976
+ this.axes.forEach(function(axes) {
1977
+ axes.setTicks(xy, nr, format);
1978
+ });
1979
+ };
1980
+
1981
+ mpld3_Figure.prototype.setXTicks = function(nr, format) {
1982
+ this.setTicks("x", nr, format);
1983
+ };
1984
+
1985
+ mpld3_Figure.prototype.setYTicks = function(nr, format) {
1986
+ this.setTicks("y", nr, format);
1987
+ };
1988
+
1989
+ mpld3_Figure.prototype.removeNaN = function(data) {
1990
+ output = output.map(function(offsets) {
1991
+ return offsets.map(function(value) {
1992
+ if (typeof value == "number" && isNaN(value)) {
1993
+ return 0;
1994
+ } else {
1995
+ return value;
1996
+ }
1997
+ });
1998
+ });
1999
+ };
2000
+
2001
+ mpld3_Figure.prototype.parse_offsets = function(data) {
2002
+ return data.map(function(offsets) {
2003
+ return offsets.map(function(value) {
2004
+ if (typeof value == "number" && isNaN(value)) {
2005
+ return 0;
2006
+ } else {
2007
+ return value;
2008
+ }
2009
+ });
2010
+ });
2011
+ };
2012
+
2013
+ mpld3_Figure.prototype.get_data = function(data) {
2014
+ var output = data;
2015
+ if (data === null || typeof data === "undefined") {
2016
+ output = null;
2017
+ } else if (typeof data === "string") {
2018
+ output = this.data[data];
2019
+ }
2020
+ return output;
2021
+ };
2022
+
2023
+ mpld3.PlotElement = mpld3_PlotElement;
2024
+
2025
+ function mpld3_PlotElement(parent, props) {
2026
+ this.parent = isUndefinedOrNull(parent) ? null : parent;
2027
+ this.props = isUndefinedOrNull(props) ? {} : this.processProps(props);
2028
+ this.fig = parent instanceof mpld3_Figure ? parent : parent && "fig" in parent ? parent.fig : null;
2029
+ this.ax = parent instanceof mpld3_Axes ? parent : parent && "ax" in parent ? parent.ax : null;
2030
+ }
2031
+
2032
+ mpld3_PlotElement.prototype.requiredProps = [];
2033
+
2034
+ mpld3_PlotElement.prototype.defaultProps = {};
2035
+
2036
+ mpld3_PlotElement.prototype.processProps = function(props) {
2037
+ props = mpld3_cloneObj(props);
2038
+ var finalProps = {};
2039
+ var this_name = this.name();
2040
+ this.requiredProps.forEach(function(p) {
2041
+ if (!(p in props)) {
2042
+ throw "property '" + p + "' " + "must be specified for " + this_name;
2043
+ }
2044
+ finalProps[p] = props[p];
2045
+ delete props[p];
2046
+ });
2047
+ for (var p in this.defaultProps) {
2048
+ if (p in props) {
2049
+ finalProps[p] = props[p];
2050
+ delete props[p];
2051
+ } else {
2052
+ finalProps[p] = this.defaultProps[p];
2053
+ }
2054
+ }
2055
+ if ("id" in props) {
2056
+ finalProps.id = props.id;
2057
+ delete props.id;
2058
+ } else if (!("id" in finalProps)) {
2059
+ finalProps.id = mpld3.generateId();
2060
+ }
2061
+ for (var p in props) {
2062
+ console.warn("Unrecognized property '" + p + "' " + "for object " + this.name() + " (value = " + props[p] + ").");
2063
+ }
2064
+ return finalProps;
2065
+ };
2066
+
2067
+ mpld3_PlotElement.prototype.name = function() {
2068
+ var funcNameRegex = /function (.{1,})\(/;
2069
+ var results = funcNameRegex.exec(this.constructor.toString());
2070
+ return results && results.length > 1 ? results[1] : "";
2071
+ };
2072
+
2073
+ if (typeof module === "object" && module.exports) {
2074
+ module.exports = mpld3;
2075
+ } else {
2076
+ this.mpld3 = mpld3;
2077
+ }
2078
+
2079
+ console.log("Loaded mpld3 version " + mpld3.version);