1 | (function (global, factory) {
|
2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
3 | typeof define === 'function' && define.amd ? define(factory) :
|
4 | (global = global || self, global.controls = factory());
|
5 | }(this, (function () { 'use strict';
|
6 |
|
7 | var xhtml = "http://www.w3.org/1999/xhtml";
|
8 |
|
9 | var namespaces = {
|
10 | svg: "http://www.w3.org/2000/svg",
|
11 | xhtml: xhtml,
|
12 | xlink: "http://www.w3.org/1999/xlink",
|
13 | xml: "http://www.w3.org/XML/1998/namespace",
|
14 | xmlns: "http://www.w3.org/2000/xmlns/"
|
15 | };
|
16 |
|
17 | function namespace(name) {
|
18 | var prefix = name += "", i = prefix.indexOf(":");
|
19 | if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
|
20 | return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name;
|
21 | }
|
22 |
|
23 | function creatorInherit(name) {
|
24 | return function() {
|
25 | var document = this.ownerDocument,
|
26 | uri = this.namespaceURI;
|
27 | return uri === xhtml && document.documentElement.namespaceURI === xhtml
|
28 | ? document.createElement(name)
|
29 | : document.createElementNS(uri, name);
|
30 | };
|
31 | }
|
32 |
|
33 | function creatorFixed(fullname) {
|
34 | return function() {
|
35 | return this.ownerDocument.createElementNS(fullname.space, fullname.local);
|
36 | };
|
37 | }
|
38 |
|
39 | function creator(name) {
|
40 | var fullname = namespace(name);
|
41 | return (fullname.local
|
42 | ? creatorFixed
|
43 | : creatorInherit)(fullname);
|
44 | }
|
45 |
|
46 | function none() {}
|
47 |
|
48 | function selector(selector) {
|
49 | return selector == null ? none : function() {
|
50 | return this.querySelector(selector);
|
51 | };
|
52 | }
|
53 |
|
54 | function selection_select(select) {
|
55 | if (typeof select !== "function") select = selector(select);
|
56 |
|
57 | for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
|
58 | for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
|
59 | if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
|
60 | if ("__data__" in node) subnode.__data__ = node.__data__;
|
61 | subgroup[i] = subnode;
|
62 | }
|
63 | }
|
64 | }
|
65 |
|
66 | return new Selection(subgroups, this._parents);
|
67 | }
|
68 |
|
69 | function empty() {
|
70 | return [];
|
71 | }
|
72 |
|
73 | function selectorAll(selector) {
|
74 | return selector == null ? empty : function() {
|
75 | return this.querySelectorAll(selector);
|
76 | };
|
77 | }
|
78 |
|
79 | function selection_selectAll(select) {
|
80 | if (typeof select !== "function") select = selectorAll(select);
|
81 |
|
82 | for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
|
83 | for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
|
84 | if (node = group[i]) {
|
85 | subgroups.push(select.call(node, node.__data__, i, group));
|
86 | parents.push(node);
|
87 | }
|
88 | }
|
89 | }
|
90 |
|
91 | return new Selection(subgroups, parents);
|
92 | }
|
93 |
|
94 | function matcher(selector) {
|
95 | return function() {
|
96 | return this.matches(selector);
|
97 | };
|
98 | }
|
99 |
|
100 | function selection_filter(match) {
|
101 | if (typeof match !== "function") match = matcher(match);
|
102 |
|
103 | for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
|
104 | for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
|
105 | if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
|
106 | subgroup.push(node);
|
107 | }
|
108 | }
|
109 | }
|
110 |
|
111 | return new Selection(subgroups, this._parents);
|
112 | }
|
113 |
|
114 | function sparse(update) {
|
115 | return new Array(update.length);
|
116 | }
|
117 |
|
118 | function selection_enter() {
|
119 | return new Selection(this._enter || this._groups.map(sparse), this._parents);
|
120 | }
|
121 |
|
122 | function EnterNode(parent, datum) {
|
123 | this.ownerDocument = parent.ownerDocument;
|
124 | this.namespaceURI = parent.namespaceURI;
|
125 | this._next = null;
|
126 | this._parent = parent;
|
127 | this.__data__ = datum;
|
128 | }
|
129 |
|
130 | EnterNode.prototype = {
|
131 | constructor: EnterNode,
|
132 | appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
|
133 | insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },
|
134 | querySelector: function(selector) { return this._parent.querySelector(selector); },
|
135 | querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }
|
136 | };
|
137 |
|
138 | function constant(x) {
|
139 | return function() {
|
140 | return x;
|
141 | };
|
142 | }
|
143 |
|
144 | var keyPrefix = "$";
|
145 |
|
146 | function bindIndex(parent, group, enter, update, exit, data) {
|
147 | var i = 0,
|
148 | node,
|
149 | groupLength = group.length,
|
150 | dataLength = data.length;
|
151 |
|
152 |
|
153 |
|
154 |
|
155 | for (; i < dataLength; ++i) {
|
156 | if (node = group[i]) {
|
157 | node.__data__ = data[i];
|
158 | update[i] = node;
|
159 | } else {
|
160 | enter[i] = new EnterNode(parent, data[i]);
|
161 | }
|
162 | }
|
163 |
|
164 |
|
165 | for (; i < groupLength; ++i) {
|
166 | if (node = group[i]) {
|
167 | exit[i] = node;
|
168 | }
|
169 | }
|
170 | }
|
171 |
|
172 | function bindKey(parent, group, enter, update, exit, data, key) {
|
173 | var i,
|
174 | node,
|
175 | nodeByKeyValue = {},
|
176 | groupLength = group.length,
|
177 | dataLength = data.length,
|
178 | keyValues = new Array(groupLength),
|
179 | keyValue;
|
180 |
|
181 |
|
182 |
|
183 | for (i = 0; i < groupLength; ++i) {
|
184 | if (node = group[i]) {
|
185 | keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);
|
186 | if (keyValue in nodeByKeyValue) {
|
187 | exit[i] = node;
|
188 | } else {
|
189 | nodeByKeyValue[keyValue] = node;
|
190 | }
|
191 | }
|
192 | }
|
193 |
|
194 |
|
195 |
|
196 |
|
197 | for (i = 0; i < dataLength; ++i) {
|
198 | keyValue = keyPrefix + key.call(parent, data[i], i, data);
|
199 | if (node = nodeByKeyValue[keyValue]) {
|
200 | update[i] = node;
|
201 | node.__data__ = data[i];
|
202 | nodeByKeyValue[keyValue] = null;
|
203 | } else {
|
204 | enter[i] = new EnterNode(parent, data[i]);
|
205 | }
|
206 | }
|
207 |
|
208 |
|
209 | for (i = 0; i < groupLength; ++i) {
|
210 | if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {
|
211 | exit[i] = node;
|
212 | }
|
213 | }
|
214 | }
|
215 |
|
216 | function selection_data(value, key) {
|
217 | if (!value) {
|
218 | data = new Array(this.size()), j = -1;
|
219 | this.each(function(d) { data[++j] = d; });
|
220 | return data;
|
221 | }
|
222 |
|
223 | var bind = key ? bindKey : bindIndex,
|
224 | parents = this._parents,
|
225 | groups = this._groups;
|
226 |
|
227 | if (typeof value !== "function") value = constant(value);
|
228 |
|
229 | for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
|
230 | var parent = parents[j],
|
231 | group = groups[j],
|
232 | groupLength = group.length,
|
233 | data = value.call(parent, parent && parent.__data__, j, parents),
|
234 | dataLength = data.length,
|
235 | enterGroup = enter[j] = new Array(dataLength),
|
236 | updateGroup = update[j] = new Array(dataLength),
|
237 | exitGroup = exit[j] = new Array(groupLength);
|
238 |
|
239 | bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
|
240 |
|
241 |
|
242 |
|
243 |
|
244 | for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
|
245 | if (previous = enterGroup[i0]) {
|
246 | if (i0 >= i1) i1 = i0 + 1;
|
247 | while (!(next = updateGroup[i1]) && ++i1 < dataLength);
|
248 | previous._next = next || null;
|
249 | }
|
250 | }
|
251 | }
|
252 |
|
253 | update = new Selection(update, parents);
|
254 | update._enter = enter;
|
255 | update._exit = exit;
|
256 | return update;
|
257 | }
|
258 |
|
259 | function selection_exit() {
|
260 | return new Selection(this._exit || this._groups.map(sparse), this._parents);
|
261 | }
|
262 |
|
263 | function selection_join(onenter, onupdate, onexit) {
|
264 | var enter = this.enter(), update = this, exit = this.exit();
|
265 | enter = typeof onenter === "function" ? onenter(enter) : enter.append(onenter + "");
|
266 | if (onupdate != null) update = onupdate(update);
|
267 | if (onexit == null) exit.remove(); else onexit(exit);
|
268 | return enter && update ? enter.merge(update).order() : update;
|
269 | }
|
270 |
|
271 | function selection_merge(selection) {
|
272 |
|
273 | for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
|
274 | for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
|
275 | if (node = group0[i] || group1[i]) {
|
276 | merge[i] = node;
|
277 | }
|
278 | }
|
279 | }
|
280 |
|
281 | for (; j < m0; ++j) {
|
282 | merges[j] = groups0[j];
|
283 | }
|
284 |
|
285 | return new Selection(merges, this._parents);
|
286 | }
|
287 |
|
288 | function selection_order() {
|
289 |
|
290 | for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {
|
291 | for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
|
292 | if (node = group[i]) {
|
293 | if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode.insertBefore(node, next);
|
294 | next = node;
|
295 | }
|
296 | }
|
297 | }
|
298 |
|
299 | return this;
|
300 | }
|
301 |
|
302 | function selection_sort(compare) {
|
303 | if (!compare) compare = ascending;
|
304 |
|
305 | function compareNode(a, b) {
|
306 | return a && b ? compare(a.__data__, b.__data__) : !a - !b;
|
307 | }
|
308 |
|
309 | for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
|
310 | for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
|
311 | if (node = group[i]) {
|
312 | sortgroup[i] = node;
|
313 | }
|
314 | }
|
315 | sortgroup.sort(compareNode);
|
316 | }
|
317 |
|
318 | return new Selection(sortgroups, this._parents).order();
|
319 | }
|
320 |
|
321 | function ascending(a, b) {
|
322 | return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
|
323 | }
|
324 |
|
325 | function selection_call() {
|
326 | var callback = arguments[0];
|
327 | arguments[0] = this;
|
328 | callback.apply(null, arguments);
|
329 | return this;
|
330 | }
|
331 |
|
332 | function selection_nodes() {
|
333 | var nodes = new Array(this.size()), i = -1;
|
334 | this.each(function() { nodes[++i] = this; });
|
335 | return nodes;
|
336 | }
|
337 |
|
338 | function selection_node() {
|
339 |
|
340 | for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
|
341 | for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
|
342 | var node = group[i];
|
343 | if (node) return node;
|
344 | }
|
345 | }
|
346 |
|
347 | return null;
|
348 | }
|
349 |
|
350 | function selection_size() {
|
351 | var size = 0;
|
352 | this.each(function() { ++size; });
|
353 | return size;
|
354 | }
|
355 |
|
356 | function selection_empty() {
|
357 | return !this.node();
|
358 | }
|
359 |
|
360 | function selection_each(callback) {
|
361 |
|
362 | for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
|
363 | for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
|
364 | if (node = group[i]) callback.call(node, node.__data__, i, group);
|
365 | }
|
366 | }
|
367 |
|
368 | return this;
|
369 | }
|
370 |
|
371 | function attrRemove(name) {
|
372 | return function() {
|
373 | this.removeAttribute(name);
|
374 | };
|
375 | }
|
376 |
|
377 | function attrRemoveNS(fullname) {
|
378 | return function() {
|
379 | this.removeAttributeNS(fullname.space, fullname.local);
|
380 | };
|
381 | }
|
382 |
|
383 | function attrConstant(name, value) {
|
384 | return function() {
|
385 | this.setAttribute(name, value);
|
386 | };
|
387 | }
|
388 |
|
389 | function attrConstantNS(fullname, value) {
|
390 | return function() {
|
391 | this.setAttributeNS(fullname.space, fullname.local, value);
|
392 | };
|
393 | }
|
394 |
|
395 | function attrFunction(name, value) {
|
396 | return function() {
|
397 | var v = value.apply(this, arguments);
|
398 | if (v == null) this.removeAttribute(name);
|
399 | else this.setAttribute(name, v);
|
400 | };
|
401 | }
|
402 |
|
403 | function attrFunctionNS(fullname, value) {
|
404 | return function() {
|
405 | var v = value.apply(this, arguments);
|
406 | if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
|
407 | else this.setAttributeNS(fullname.space, fullname.local, v);
|
408 | };
|
409 | }
|
410 |
|
411 | function selection_attr(name, value) {
|
412 | var fullname = namespace(name);
|
413 |
|
414 | if (arguments.length < 2) {
|
415 | var node = this.node();
|
416 | return fullname.local
|
417 | ? node.getAttributeNS(fullname.space, fullname.local)
|
418 | : node.getAttribute(fullname);
|
419 | }
|
420 |
|
421 | return this.each((value == null
|
422 | ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
|
423 | ? (fullname.local ? attrFunctionNS : attrFunction)
|
424 | : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
|
425 | }
|
426 |
|
427 | function defaultView(node) {
|
428 | return (node.ownerDocument && node.ownerDocument.defaultView)
|
429 | || (node.document && node)
|
430 | || node.defaultView;
|
431 | }
|
432 |
|
433 | function styleRemove(name) {
|
434 | return function() {
|
435 | this.style.removeProperty(name);
|
436 | };
|
437 | }
|
438 |
|
439 | function styleConstant(name, value, priority) {
|
440 | return function() {
|
441 | this.style.setProperty(name, value, priority);
|
442 | };
|
443 | }
|
444 |
|
445 | function styleFunction(name, value, priority) {
|
446 | return function() {
|
447 | var v = value.apply(this, arguments);
|
448 | if (v == null) this.style.removeProperty(name);
|
449 | else this.style.setProperty(name, v, priority);
|
450 | };
|
451 | }
|
452 |
|
453 | function selection_style(name, value, priority) {
|
454 | return arguments.length > 1
|
455 | ? this.each((value == null
|
456 | ? styleRemove : typeof value === "function"
|
457 | ? styleFunction
|
458 | : styleConstant)(name, value, priority == null ? "" : priority))
|
459 | : styleValue(this.node(), name);
|
460 | }
|
461 |
|
462 | function styleValue(node, name) {
|
463 | return node.style.getPropertyValue(name)
|
464 | || defaultView(node).getComputedStyle(node, null).getPropertyValue(name);
|
465 | }
|
466 |
|
467 | function propertyRemove(name) {
|
468 | return function() {
|
469 | delete this[name];
|
470 | };
|
471 | }
|
472 |
|
473 | function propertyConstant(name, value) {
|
474 | return function() {
|
475 | this[name] = value;
|
476 | };
|
477 | }
|
478 |
|
479 | function propertyFunction(name, value) {
|
480 | return function() {
|
481 | var v = value.apply(this, arguments);
|
482 | if (v == null) delete this[name];
|
483 | else this[name] = v;
|
484 | };
|
485 | }
|
486 |
|
487 | function selection_property(name, value) {
|
488 | return arguments.length > 1
|
489 | ? this.each((value == null
|
490 | ? propertyRemove : typeof value === "function"
|
491 | ? propertyFunction
|
492 | : propertyConstant)(name, value))
|
493 | : this.node()[name];
|
494 | }
|
495 |
|
496 | function classArray(string) {
|
497 | return string.trim().split(/^|\s+/);
|
498 | }
|
499 |
|
500 | function classList(node) {
|
501 | return node.classList || new ClassList(node);
|
502 | }
|
503 |
|
504 | function ClassList(node) {
|
505 | this._node = node;
|
506 | this._names = classArray(node.getAttribute("class") || "");
|
507 | }
|
508 |
|
509 | ClassList.prototype = {
|
510 | add: function(name) {
|
511 | var i = this._names.indexOf(name);
|
512 | if (i < 0) {
|
513 | this._names.push(name);
|
514 | this._node.setAttribute("class", this._names.join(" "));
|
515 | }
|
516 | },
|
517 | remove: function(name) {
|
518 | var i = this._names.indexOf(name);
|
519 | if (i >= 0) {
|
520 | this._names.splice(i, 1);
|
521 | this._node.setAttribute("class", this._names.join(" "));
|
522 | }
|
523 | },
|
524 | contains: function(name) {
|
525 | return this._names.indexOf(name) >= 0;
|
526 | }
|
527 | };
|
528 |
|
529 | function classedAdd(node, names) {
|
530 | var list = classList(node), i = -1, n = names.length;
|
531 | while (++i < n) list.add(names[i]);
|
532 | }
|
533 |
|
534 | function classedRemove(node, names) {
|
535 | var list = classList(node), i = -1, n = names.length;
|
536 | while (++i < n) list.remove(names[i]);
|
537 | }
|
538 |
|
539 | function classedTrue(names) {
|
540 | return function() {
|
541 | classedAdd(this, names);
|
542 | };
|
543 | }
|
544 |
|
545 | function classedFalse(names) {
|
546 | return function() {
|
547 | classedRemove(this, names);
|
548 | };
|
549 | }
|
550 |
|
551 | function classedFunction(names, value) {
|
552 | return function() {
|
553 | (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
|
554 | };
|
555 | }
|
556 |
|
557 | function selection_classed(name, value) {
|
558 | var names = classArray(name + "");
|
559 |
|
560 | if (arguments.length < 2) {
|
561 | var list = classList(this.node()), i = -1, n = names.length;
|
562 | while (++i < n) if (!list.contains(names[i])) return false;
|
563 | return true;
|
564 | }
|
565 |
|
566 | return this.each((typeof value === "function"
|
567 | ? classedFunction : value
|
568 | ? classedTrue
|
569 | : classedFalse)(names, value));
|
570 | }
|
571 |
|
572 | function textRemove() {
|
573 | this.textContent = "";
|
574 | }
|
575 |
|
576 | function textConstant(value) {
|
577 | return function() {
|
578 | this.textContent = value;
|
579 | };
|
580 | }
|
581 |
|
582 | function textFunction(value) {
|
583 | return function() {
|
584 | var v = value.apply(this, arguments);
|
585 | this.textContent = v == null ? "" : v;
|
586 | };
|
587 | }
|
588 |
|
589 | function selection_text(value) {
|
590 | return arguments.length
|
591 | ? this.each(value == null
|
592 | ? textRemove : (typeof value === "function"
|
593 | ? textFunction
|
594 | : textConstant)(value))
|
595 | : this.node().textContent;
|
596 | }
|
597 |
|
598 | function htmlRemove() {
|
599 | this.innerHTML = "";
|
600 | }
|
601 |
|
602 | function htmlConstant(value) {
|
603 | return function() {
|
604 | this.innerHTML = value;
|
605 | };
|
606 | }
|
607 |
|
608 | function htmlFunction(value) {
|
609 | return function() {
|
610 | var v = value.apply(this, arguments);
|
611 | this.innerHTML = v == null ? "" : v;
|
612 | };
|
613 | }
|
614 |
|
615 | function selection_html(value) {
|
616 | return arguments.length
|
617 | ? this.each(value == null
|
618 | ? htmlRemove : (typeof value === "function"
|
619 | ? htmlFunction
|
620 | : htmlConstant)(value))
|
621 | : this.node().innerHTML;
|
622 | }
|
623 |
|
624 | function raise() {
|
625 | if (this.nextSibling) this.parentNode.appendChild(this);
|
626 | }
|
627 |
|
628 | function selection_raise() {
|
629 | return this.each(raise);
|
630 | }
|
631 |
|
632 | function lower() {
|
633 | if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
|
634 | }
|
635 |
|
636 | function selection_lower() {
|
637 | return this.each(lower);
|
638 | }
|
639 |
|
640 | function selection_append(name) {
|
641 | var create = typeof name === "function" ? name : creator(name);
|
642 | return this.select(function() {
|
643 | return this.appendChild(create.apply(this, arguments));
|
644 | });
|
645 | }
|
646 |
|
647 | function constantNull() {
|
648 | return null;
|
649 | }
|
650 |
|
651 | function selection_insert(name, before) {
|
652 | var create = typeof name === "function" ? name : creator(name),
|
653 | select = before == null ? constantNull : typeof before === "function" ? before : selector(before);
|
654 | return this.select(function() {
|
655 | return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
|
656 | });
|
657 | }
|
658 |
|
659 | function remove() {
|
660 | var parent = this.parentNode;
|
661 | if (parent) parent.removeChild(this);
|
662 | }
|
663 |
|
664 | function selection_remove() {
|
665 | return this.each(remove);
|
666 | }
|
667 |
|
668 | function selection_cloneShallow() {
|
669 | return this.parentNode.insertBefore(this.cloneNode(false), this.nextSibling);
|
670 | }
|
671 |
|
672 | function selection_cloneDeep() {
|
673 | return this.parentNode.insertBefore(this.cloneNode(true), this.nextSibling);
|
674 | }
|
675 |
|
676 | function selection_clone(deep) {
|
677 | return this.select(deep ? selection_cloneDeep : selection_cloneShallow);
|
678 | }
|
679 |
|
680 | function selection_datum(value) {
|
681 | return arguments.length
|
682 | ? this.property("__data__", value)
|
683 | : this.node().__data__;
|
684 | }
|
685 |
|
686 | var filterEvents = {};
|
687 |
|
688 | var event$1 = null;
|
689 |
|
690 | if (typeof document !== "undefined") {
|
691 | var element = document.documentElement;
|
692 | if (!("onmouseenter" in element)) {
|
693 | filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"};
|
694 | }
|
695 | }
|
696 |
|
697 | function filterContextListener(listener, index, group) {
|
698 | listener = contextListener(listener, index, group);
|
699 | return function(event) {
|
700 | var related = event.relatedTarget;
|
701 | if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {
|
702 | listener.call(this, event);
|
703 | }
|
704 | };
|
705 | }
|
706 |
|
707 | function contextListener(listener, index, group) {
|
708 | return function(event1) {
|
709 | var event0 = event$1;
|
710 | event$1 = event1;
|
711 | try {
|
712 | listener.call(this, this.__data__, index, group);
|
713 | } finally {
|
714 | event$1 = event0;
|
715 | }
|
716 | };
|
717 | }
|
718 |
|
719 | function parseTypenames(typenames) {
|
720 | return typenames.trim().split(/^|\s+/).map(function(t) {
|
721 | var name = "", i = t.indexOf(".");
|
722 | if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
|
723 | return {type: t, name: name};
|
724 | });
|
725 | }
|
726 |
|
727 | function onRemove(typename) {
|
728 | return function() {
|
729 | var on = this.__on;
|
730 | if (!on) return;
|
731 | for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
|
732 | if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
|
733 | this.removeEventListener(o.type, o.listener, o.capture);
|
734 | } else {
|
735 | on[++i] = o;
|
736 | }
|
737 | }
|
738 | if (++i) on.length = i;
|
739 | else delete this.__on;
|
740 | };
|
741 | }
|
742 |
|
743 | function onAdd(typename, value, capture) {
|
744 | var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener;
|
745 | return function(d, i, group) {
|
746 | var on = this.__on, o, listener = wrap(value, i, group);
|
747 | if (on) for (var j = 0, m = on.length; j < m; ++j) {
|
748 | if ((o = on[j]).type === typename.type && o.name === typename.name) {
|
749 | this.removeEventListener(o.type, o.listener, o.capture);
|
750 | this.addEventListener(o.type, o.listener = listener, o.capture = capture);
|
751 | o.value = value;
|
752 | return;
|
753 | }
|
754 | }
|
755 | this.addEventListener(typename.type, listener, capture);
|
756 | o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture};
|
757 | if (!on) this.__on = [o];
|
758 | else on.push(o);
|
759 | };
|
760 | }
|
761 |
|
762 | function selection_on(typename, value, capture) {
|
763 | var typenames = parseTypenames(typename + ""), i, n = typenames.length, t;
|
764 |
|
765 | if (arguments.length < 2) {
|
766 | var on = this.node().__on;
|
767 | if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
|
768 | for (i = 0, o = on[j]; i < n; ++i) {
|
769 | if ((t = typenames[i]).type === o.type && t.name === o.name) {
|
770 | return o.value;
|
771 | }
|
772 | }
|
773 | }
|
774 | return;
|
775 | }
|
776 |
|
777 | on = value ? onAdd : onRemove;
|
778 | if (capture == null) capture = false;
|
779 | for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture));
|
780 | return this;
|
781 | }
|
782 |
|
783 | function dispatchEvent(node, type, params) {
|
784 | var window = defaultView(node),
|
785 | event = window.CustomEvent;
|
786 |
|
787 | if (typeof event === "function") {
|
788 | event = new event(type, params);
|
789 | } else {
|
790 | event = window.document.createEvent("Event");
|
791 | if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
|
792 | else event.initEvent(type, false, false);
|
793 | }
|
794 |
|
795 | node.dispatchEvent(event);
|
796 | }
|
797 |
|
798 | function dispatchConstant(type, params) {
|
799 | return function() {
|
800 | return dispatchEvent(this, type, params);
|
801 | };
|
802 | }
|
803 |
|
804 | function dispatchFunction(type, params) {
|
805 | return function() {
|
806 | return dispatchEvent(this, type, params.apply(this, arguments));
|
807 | };
|
808 | }
|
809 |
|
810 | function selection_dispatch(type, params) {
|
811 | return this.each((typeof params === "function"
|
812 | ? dispatchFunction
|
813 | : dispatchConstant)(type, params));
|
814 | }
|
815 |
|
816 | var root = [null];
|
817 |
|
818 | function Selection(groups, parents) {
|
819 | this._groups = groups;
|
820 | this._parents = parents;
|
821 | }
|
822 |
|
823 | function selection() {
|
824 | return new Selection([[document.documentElement]], root);
|
825 | }
|
826 |
|
827 | Selection.prototype = selection.prototype = {
|
828 | constructor: Selection,
|
829 | select: selection_select,
|
830 | selectAll: selection_selectAll,
|
831 | filter: selection_filter,
|
832 | data: selection_data,
|
833 | enter: selection_enter,
|
834 | exit: selection_exit,
|
835 | join: selection_join,
|
836 | merge: selection_merge,
|
837 | order: selection_order,
|
838 | sort: selection_sort,
|
839 | call: selection_call,
|
840 | nodes: selection_nodes,
|
841 | node: selection_node,
|
842 | size: selection_size,
|
843 | empty: selection_empty,
|
844 | each: selection_each,
|
845 | attr: selection_attr,
|
846 | style: selection_style,
|
847 | property: selection_property,
|
848 | classed: selection_classed,
|
849 | text: selection_text,
|
850 | html: selection_html,
|
851 | raise: selection_raise,
|
852 | lower: selection_lower,
|
853 | append: selection_append,
|
854 | insert: selection_insert,
|
855 | remove: selection_remove,
|
856 | clone: selection_clone,
|
857 | datum: selection_datum,
|
858 | on: selection_on,
|
859 | dispatch: selection_dispatch
|
860 | };
|
861 |
|
862 | function select(selector) {
|
863 | return typeof selector === "string"
|
864 | ? new Selection([[document.querySelector(selector)]], [document.documentElement])
|
865 | : new Selection([[selector]], root);
|
866 | }
|
867 |
|
868 | function sourceEvent() {
|
869 | var current = event$1, source;
|
870 | while (source = current.sourceEvent) current = source;
|
871 | return current;
|
872 | }
|
873 |
|
874 | function point(node, event) {
|
875 | var svg = node.ownerSVGElement || node;
|
876 |
|
877 | if (svg.createSVGPoint) {
|
878 | var point = svg.createSVGPoint();
|
879 | point.x = event.clientX, point.y = event.clientY;
|
880 | point = point.matrixTransform(node.getScreenCTM().inverse());
|
881 | return [point.x, point.y];
|
882 | }
|
883 |
|
884 | var rect = node.getBoundingClientRect();
|
885 | return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
|
886 | }
|
887 |
|
888 | function d3_mouse(node) {
|
889 | var event = sourceEvent();
|
890 | if (event.changedTouches) event = event.changedTouches[0];
|
891 | return point(node, event);
|
892 | }
|
893 |
|
894 | function getDefaultParser() {
|
895 | return parseFloat;
|
896 | }
|
897 |
|
898 | function getDefaultFormatter() {
|
899 | return function(x) { return x.toString(); };
|
900 | }
|
901 |
|
902 | var t0 = new Date,
|
903 | t1 = new Date;
|
904 |
|
905 | function newInterval(floori, offseti, count, field) {
|
906 |
|
907 | function interval(date) {
|
908 | return floori(date = new Date(+date)), date;
|
909 | }
|
910 |
|
911 | interval.floor = interval;
|
912 |
|
913 | interval.ceil = function(date) {
|
914 | return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;
|
915 | };
|
916 |
|
917 | interval.round = function(date) {
|
918 | var d0 = interval(date),
|
919 | d1 = interval.ceil(date);
|
920 | return date - d0 < d1 - date ? d0 : d1;
|
921 | };
|
922 |
|
923 | interval.offset = function(date, step) {
|
924 | return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;
|
925 | };
|
926 |
|
927 | interval.range = function(start, stop, step) {
|
928 | var range = [], previous;
|
929 | start = interval.ceil(start);
|
930 | step = step == null ? 1 : Math.floor(step);
|
931 | if (!(start < stop) || !(step > 0)) return range;
|
932 | do range.push(previous = new Date(+start)), offseti(start, step), floori(start);
|
933 | while (previous < start && start < stop);
|
934 | return range;
|
935 | };
|
936 |
|
937 | interval.filter = function(test) {
|
938 | return newInterval(function(date) {
|
939 | if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);
|
940 | }, function(date, step) {
|
941 | if (date >= date) {
|
942 | if (step < 0) while (++step <= 0) {
|
943 | while (offseti(date, -1), !test(date)) {}
|
944 | } else while (--step >= 0) {
|
945 | while (offseti(date, +1), !test(date)) {}
|
946 | }
|
947 | }
|
948 | });
|
949 | };
|
950 |
|
951 | if (count) {
|
952 | interval.count = function(start, end) {
|
953 | t0.setTime(+start), t1.setTime(+end);
|
954 | floori(t0), floori(t1);
|
955 | return Math.floor(count(t0, t1));
|
956 | };
|
957 |
|
958 | interval.every = function(step) {
|
959 | step = Math.floor(step);
|
960 | return !isFinite(step) || !(step > 0) ? null
|
961 | : !(step > 1) ? interval
|
962 | : interval.filter(field
|
963 | ? function(d) { return field(d) % step === 0; }
|
964 | : function(d) { return interval.count(0, d) % step === 0; });
|
965 | };
|
966 | }
|
967 |
|
968 | return interval;
|
969 | }
|
970 |
|
971 | var millisecond = newInterval(function() {
|
972 |
|
973 | }, function(date, step) {
|
974 | date.setTime(+date + step);
|
975 | }, function(start, end) {
|
976 | return end - start;
|
977 | });
|
978 |
|
979 |
|
980 | millisecond.every = function(k) {
|
981 | k = Math.floor(k);
|
982 | if (!isFinite(k) || !(k > 0)) return null;
|
983 | if (!(k > 1)) return millisecond;
|
984 | return newInterval(function(date) {
|
985 | date.setTime(Math.floor(date / k) * k);
|
986 | }, function(date, step) {
|
987 | date.setTime(+date + step * k);
|
988 | }, function(start, end) {
|
989 | return (end - start) / k;
|
990 | });
|
991 | };
|
992 |
|
993 | var durationSecond = 1e3;
|
994 | var durationMinute = 6e4;
|
995 | var durationHour = 36e5;
|
996 | var durationDay = 864e5;
|
997 | var durationWeek = 6048e5;
|
998 |
|
999 | var second = newInterval(function(date) {
|
1000 | date.setTime(date - date.getMilliseconds());
|
1001 | }, function(date, step) {
|
1002 | date.setTime(+date + step * durationSecond);
|
1003 | }, function(start, end) {
|
1004 | return (end - start) / durationSecond;
|
1005 | }, function(date) {
|
1006 | return date.getUTCSeconds();
|
1007 | });
|
1008 |
|
1009 | var minute = newInterval(function(date) {
|
1010 | date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond);
|
1011 | }, function(date, step) {
|
1012 | date.setTime(+date + step * durationMinute);
|
1013 | }, function(start, end) {
|
1014 | return (end - start) / durationMinute;
|
1015 | }, function(date) {
|
1016 | return date.getMinutes();
|
1017 | });
|
1018 |
|
1019 | var hour = newInterval(function(date) {
|
1020 | date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond - date.getMinutes() * durationMinute);
|
1021 | }, function(date, step) {
|
1022 | date.setTime(+date + step * durationHour);
|
1023 | }, function(start, end) {
|
1024 | return (end - start) / durationHour;
|
1025 | }, function(date) {
|
1026 | return date.getHours();
|
1027 | });
|
1028 |
|
1029 | var day = newInterval(function(date) {
|
1030 | date.setHours(0, 0, 0, 0);
|
1031 | }, function(date, step) {
|
1032 | date.setDate(date.getDate() + step);
|
1033 | }, function(start, end) {
|
1034 | return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay;
|
1035 | }, function(date) {
|
1036 | return date.getDate() - 1;
|
1037 | });
|
1038 |
|
1039 | function weekday(i) {
|
1040 | return newInterval(function(date) {
|
1041 | date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
|
1042 | date.setHours(0, 0, 0, 0);
|
1043 | }, function(date, step) {
|
1044 | date.setDate(date.getDate() + step * 7);
|
1045 | }, function(start, end) {
|
1046 | return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;
|
1047 | });
|
1048 | }
|
1049 |
|
1050 | var sunday = weekday(0);
|
1051 | var monday = weekday(1);
|
1052 | var tuesday = weekday(2);
|
1053 | var wednesday = weekday(3);
|
1054 | var thursday = weekday(4);
|
1055 | var friday = weekday(5);
|
1056 | var saturday = weekday(6);
|
1057 |
|
1058 | var month = newInterval(function(date) {
|
1059 | date.setDate(1);
|
1060 | date.setHours(0, 0, 0, 0);
|
1061 | }, function(date, step) {
|
1062 | date.setMonth(date.getMonth() + step);
|
1063 | }, function(start, end) {
|
1064 | return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
|
1065 | }, function(date) {
|
1066 | return date.getMonth();
|
1067 | });
|
1068 |
|
1069 | var year = newInterval(function(date) {
|
1070 | date.setMonth(0, 1);
|
1071 | date.setHours(0, 0, 0, 0);
|
1072 | }, function(date, step) {
|
1073 | date.setFullYear(date.getFullYear() + step);
|
1074 | }, function(start, end) {
|
1075 | return end.getFullYear() - start.getFullYear();
|
1076 | }, function(date) {
|
1077 | return date.getFullYear();
|
1078 | });
|
1079 |
|
1080 |
|
1081 | year.every = function(k) {
|
1082 | return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
|
1083 | date.setFullYear(Math.floor(date.getFullYear() / k) * k);
|
1084 | date.setMonth(0, 1);
|
1085 | date.setHours(0, 0, 0, 0);
|
1086 | }, function(date, step) {
|
1087 | date.setFullYear(date.getFullYear() + step * k);
|
1088 | });
|
1089 | };
|
1090 |
|
1091 | var utcMinute = newInterval(function(date) {
|
1092 | date.setUTCSeconds(0, 0);
|
1093 | }, function(date, step) {
|
1094 | date.setTime(+date + step * durationMinute);
|
1095 | }, function(start, end) {
|
1096 | return (end - start) / durationMinute;
|
1097 | }, function(date) {
|
1098 | return date.getUTCMinutes();
|
1099 | });
|
1100 |
|
1101 | var utcHour = newInterval(function(date) {
|
1102 | date.setUTCMinutes(0, 0, 0);
|
1103 | }, function(date, step) {
|
1104 | date.setTime(+date + step * durationHour);
|
1105 | }, function(start, end) {
|
1106 | return (end - start) / durationHour;
|
1107 | }, function(date) {
|
1108 | return date.getUTCHours();
|
1109 | });
|
1110 |
|
1111 | var utcDay = newInterval(function(date) {
|
1112 | date.setUTCHours(0, 0, 0, 0);
|
1113 | }, function(date, step) {
|
1114 | date.setUTCDate(date.getUTCDate() + step);
|
1115 | }, function(start, end) {
|
1116 | return (end - start) / durationDay;
|
1117 | }, function(date) {
|
1118 | return date.getUTCDate() - 1;
|
1119 | });
|
1120 |
|
1121 | function utcWeekday(i) {
|
1122 | return newInterval(function(date) {
|
1123 | date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
|
1124 | date.setUTCHours(0, 0, 0, 0);
|
1125 | }, function(date, step) {
|
1126 | date.setUTCDate(date.getUTCDate() + step * 7);
|
1127 | }, function(start, end) {
|
1128 | return (end - start) / durationWeek;
|
1129 | });
|
1130 | }
|
1131 |
|
1132 | var utcSunday = utcWeekday(0);
|
1133 | var utcMonday = utcWeekday(1);
|
1134 | var utcTuesday = utcWeekday(2);
|
1135 | var utcWednesday = utcWeekday(3);
|
1136 | var utcThursday = utcWeekday(4);
|
1137 | var utcFriday = utcWeekday(5);
|
1138 | var utcSaturday = utcWeekday(6);
|
1139 |
|
1140 | var utcMonth = newInterval(function(date) {
|
1141 | date.setUTCDate(1);
|
1142 | date.setUTCHours(0, 0, 0, 0);
|
1143 | }, function(date, step) {
|
1144 | date.setUTCMonth(date.getUTCMonth() + step);
|
1145 | }, function(start, end) {
|
1146 | return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
|
1147 | }, function(date) {
|
1148 | return date.getUTCMonth();
|
1149 | });
|
1150 |
|
1151 | var utcYear = newInterval(function(date) {
|
1152 | date.setUTCMonth(0, 1);
|
1153 | date.setUTCHours(0, 0, 0, 0);
|
1154 | }, function(date, step) {
|
1155 | date.setUTCFullYear(date.getUTCFullYear() + step);
|
1156 | }, function(start, end) {
|
1157 | return end.getUTCFullYear() - start.getUTCFullYear();
|
1158 | }, function(date) {
|
1159 | return date.getUTCFullYear();
|
1160 | });
|
1161 |
|
1162 |
|
1163 | utcYear.every = function(k) {
|
1164 | return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
|
1165 | date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);
|
1166 | date.setUTCMonth(0, 1);
|
1167 | date.setUTCHours(0, 0, 0, 0);
|
1168 | }, function(date, step) {
|
1169 | date.setUTCFullYear(date.getUTCFullYear() + step * k);
|
1170 | });
|
1171 | };
|
1172 |
|
1173 | function localDate(d) {
|
1174 | if (0 <= d.y && d.y < 100) {
|
1175 | var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
|
1176 | date.setFullYear(d.y);
|
1177 | return date;
|
1178 | }
|
1179 | return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
|
1180 | }
|
1181 |
|
1182 | function utcDate(d) {
|
1183 | if (0 <= d.y && d.y < 100) {
|
1184 | var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
|
1185 | date.setUTCFullYear(d.y);
|
1186 | return date;
|
1187 | }
|
1188 | return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
|
1189 | }
|
1190 |
|
1191 | function newDate(y, m, d) {
|
1192 | return {y: y, m: m, d: d, H: 0, M: 0, S: 0, L: 0};
|
1193 | }
|
1194 |
|
1195 | function formatLocale(locale) {
|
1196 | var locale_dateTime = locale.dateTime,
|
1197 | locale_date = locale.date,
|
1198 | locale_time = locale.time,
|
1199 | locale_periods = locale.periods,
|
1200 | locale_weekdays = locale.days,
|
1201 | locale_shortWeekdays = locale.shortDays,
|
1202 | locale_months = locale.months,
|
1203 | locale_shortMonths = locale.shortMonths;
|
1204 |
|
1205 | var periodRe = formatRe(locale_periods),
|
1206 | periodLookup = formatLookup(locale_periods),
|
1207 | weekdayRe = formatRe(locale_weekdays),
|
1208 | weekdayLookup = formatLookup(locale_weekdays),
|
1209 | shortWeekdayRe = formatRe(locale_shortWeekdays),
|
1210 | shortWeekdayLookup = formatLookup(locale_shortWeekdays),
|
1211 | monthRe = formatRe(locale_months),
|
1212 | monthLookup = formatLookup(locale_months),
|
1213 | shortMonthRe = formatRe(locale_shortMonths),
|
1214 | shortMonthLookup = formatLookup(locale_shortMonths);
|
1215 |
|
1216 | var formats = {
|
1217 | "a": formatShortWeekday,
|
1218 | "A": formatWeekday,
|
1219 | "b": formatShortMonth,
|
1220 | "B": formatMonth,
|
1221 | "c": null,
|
1222 | "d": formatDayOfMonth,
|
1223 | "e": formatDayOfMonth,
|
1224 | "f": formatMicroseconds,
|
1225 | "H": formatHour24,
|
1226 | "I": formatHour12,
|
1227 | "j": formatDayOfYear,
|
1228 | "L": formatMilliseconds,
|
1229 | "m": formatMonthNumber,
|
1230 | "M": formatMinutes,
|
1231 | "p": formatPeriod,
|
1232 | "q": formatQuarter,
|
1233 | "Q": formatUnixTimestamp,
|
1234 | "s": formatUnixTimestampSeconds,
|
1235 | "S": formatSeconds,
|
1236 | "u": formatWeekdayNumberMonday,
|
1237 | "U": formatWeekNumberSunday,
|
1238 | "V": formatWeekNumberISO,
|
1239 | "w": formatWeekdayNumberSunday,
|
1240 | "W": formatWeekNumberMonday,
|
1241 | "x": null,
|
1242 | "X": null,
|
1243 | "y": formatYear,
|
1244 | "Y": formatFullYear,
|
1245 | "Z": formatZone,
|
1246 | "%": formatLiteralPercent
|
1247 | };
|
1248 |
|
1249 | var utcFormats = {
|
1250 | "a": formatUTCShortWeekday,
|
1251 | "A": formatUTCWeekday,
|
1252 | "b": formatUTCShortMonth,
|
1253 | "B": formatUTCMonth,
|
1254 | "c": null,
|
1255 | "d": formatUTCDayOfMonth,
|
1256 | "e": formatUTCDayOfMonth,
|
1257 | "f": formatUTCMicroseconds,
|
1258 | "H": formatUTCHour24,
|
1259 | "I": formatUTCHour12,
|
1260 | "j": formatUTCDayOfYear,
|
1261 | "L": formatUTCMilliseconds,
|
1262 | "m": formatUTCMonthNumber,
|
1263 | "M": formatUTCMinutes,
|
1264 | "p": formatUTCPeriod,
|
1265 | "q": formatUTCQuarter,
|
1266 | "Q": formatUnixTimestamp,
|
1267 | "s": formatUnixTimestampSeconds,
|
1268 | "S": formatUTCSeconds,
|
1269 | "u": formatUTCWeekdayNumberMonday,
|
1270 | "U": formatUTCWeekNumberSunday,
|
1271 | "V": formatUTCWeekNumberISO,
|
1272 | "w": formatUTCWeekdayNumberSunday,
|
1273 | "W": formatUTCWeekNumberMonday,
|
1274 | "x": null,
|
1275 | "X": null,
|
1276 | "y": formatUTCYear,
|
1277 | "Y": formatUTCFullYear,
|
1278 | "Z": formatUTCZone,
|
1279 | "%": formatLiteralPercent
|
1280 | };
|
1281 |
|
1282 | var parses = {
|
1283 | "a": parseShortWeekday,
|
1284 | "A": parseWeekday,
|
1285 | "b": parseShortMonth,
|
1286 | "B": parseMonth,
|
1287 | "c": parseLocaleDateTime,
|
1288 | "d": parseDayOfMonth,
|
1289 | "e": parseDayOfMonth,
|
1290 | "f": parseMicroseconds,
|
1291 | "H": parseHour24,
|
1292 | "I": parseHour24,
|
1293 | "j": parseDayOfYear,
|
1294 | "L": parseMilliseconds,
|
1295 | "m": parseMonthNumber,
|
1296 | "M": parseMinutes,
|
1297 | "p": parsePeriod,
|
1298 | "q": parseQuarter,
|
1299 | "Q": parseUnixTimestamp,
|
1300 | "s": parseUnixTimestampSeconds,
|
1301 | "S": parseSeconds,
|
1302 | "u": parseWeekdayNumberMonday,
|
1303 | "U": parseWeekNumberSunday,
|
1304 | "V": parseWeekNumberISO,
|
1305 | "w": parseWeekdayNumberSunday,
|
1306 | "W": parseWeekNumberMonday,
|
1307 | "x": parseLocaleDate,
|
1308 | "X": parseLocaleTime,
|
1309 | "y": parseYear,
|
1310 | "Y": parseFullYear,
|
1311 | "Z": parseZone,
|
1312 | "%": parseLiteralPercent
|
1313 | };
|
1314 |
|
1315 |
|
1316 | formats.x = newFormat(locale_date, formats);
|
1317 | formats.X = newFormat(locale_time, formats);
|
1318 | formats.c = newFormat(locale_dateTime, formats);
|
1319 | utcFormats.x = newFormat(locale_date, utcFormats);
|
1320 | utcFormats.X = newFormat(locale_time, utcFormats);
|
1321 | utcFormats.c = newFormat(locale_dateTime, utcFormats);
|
1322 |
|
1323 | function newFormat(specifier, formats) {
|
1324 | return function(date) {
|
1325 | var string = [],
|
1326 | i = -1,
|
1327 | j = 0,
|
1328 | n = specifier.length,
|
1329 | c,
|
1330 | pad,
|
1331 | format;
|
1332 |
|
1333 | if (!(date instanceof Date)) date = new Date(+date);
|
1334 |
|
1335 | while (++i < n) {
|
1336 | if (specifier.charCodeAt(i) === 37) {
|
1337 | string.push(specifier.slice(j, i));
|
1338 | if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);
|
1339 | else pad = c === "e" ? " " : "0";
|
1340 | if (format = formats[c]) c = format(date, pad);
|
1341 | string.push(c);
|
1342 | j = i + 1;
|
1343 | }
|
1344 | }
|
1345 |
|
1346 | string.push(specifier.slice(j, i));
|
1347 | return string.join("");
|
1348 | };
|
1349 | }
|
1350 |
|
1351 | function newParse(specifier, Z) {
|
1352 | return function(string) {
|
1353 | var d = newDate(1900, undefined, 1),
|
1354 | i = parseSpecifier(d, specifier, string += "", 0),
|
1355 | week, day$1;
|
1356 | if (i != string.length) return null;
|
1357 |
|
1358 |
|
1359 | if ("Q" in d) return new Date(d.Q);
|
1360 | if ("s" in d) return new Date(d.s * 1000 + ("L" in d ? d.L : 0));
|
1361 |
|
1362 |
|
1363 | if (Z && !("Z" in d)) d.Z = 0;
|
1364 |
|
1365 |
|
1366 | if ("p" in d) d.H = d.H % 12 + d.p * 12;
|
1367 |
|
1368 |
|
1369 | if (d.m === undefined) d.m = "q" in d ? d.q : 0;
|
1370 |
|
1371 |
|
1372 | if ("V" in d) {
|
1373 | if (d.V < 1 || d.V > 53) return null;
|
1374 | if (!("w" in d)) d.w = 1;
|
1375 | if ("Z" in d) {
|
1376 | week = utcDate(newDate(d.y, 0, 1)), day$1 = week.getUTCDay();
|
1377 | week = day$1 > 4 || day$1 === 0 ? utcMonday.ceil(week) : utcMonday(week);
|
1378 | week = utcDay.offset(week, (d.V - 1) * 7);
|
1379 | d.y = week.getUTCFullYear();
|
1380 | d.m = week.getUTCMonth();
|
1381 | d.d = week.getUTCDate() + (d.w + 6) % 7;
|
1382 | } else {
|
1383 | week = localDate(newDate(d.y, 0, 1)), day$1 = week.getDay();
|
1384 | week = day$1 > 4 || day$1 === 0 ? monday.ceil(week) : monday(week);
|
1385 | week = day.offset(week, (d.V - 1) * 7);
|
1386 | d.y = week.getFullYear();
|
1387 | d.m = week.getMonth();
|
1388 | d.d = week.getDate() + (d.w + 6) % 7;
|
1389 | }
|
1390 | } else if ("W" in d || "U" in d) {
|
1391 | if (!("w" in d)) d.w = "u" in d ? d.u % 7 : "W" in d ? 1 : 0;
|
1392 | day$1 = "Z" in d ? utcDate(newDate(d.y, 0, 1)).getUTCDay() : localDate(newDate(d.y, 0, 1)).getDay();
|
1393 | d.m = 0;
|
1394 | d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day$1 + 5) % 7 : d.w + d.U * 7 - (day$1 + 6) % 7;
|
1395 | }
|
1396 |
|
1397 |
|
1398 |
|
1399 | if ("Z" in d) {
|
1400 | d.H += d.Z / 100 | 0;
|
1401 | d.M += d.Z % 100;
|
1402 | return utcDate(d);
|
1403 | }
|
1404 |
|
1405 |
|
1406 | return localDate(d);
|
1407 | };
|
1408 | }
|
1409 |
|
1410 | function parseSpecifier(d, specifier, string, j) {
|
1411 | var i = 0,
|
1412 | n = specifier.length,
|
1413 | m = string.length,
|
1414 | c,
|
1415 | parse;
|
1416 |
|
1417 | while (i < n) {
|
1418 | if (j >= m) return -1;
|
1419 | c = specifier.charCodeAt(i++);
|
1420 | if (c === 37) {
|
1421 | c = specifier.charAt(i++);
|
1422 | parse = parses[c in pads ? specifier.charAt(i++) : c];
|
1423 | if (!parse || ((j = parse(d, string, j)) < 0)) return -1;
|
1424 | } else if (c != string.charCodeAt(j++)) {
|
1425 | return -1;
|
1426 | }
|
1427 | }
|
1428 |
|
1429 | return j;
|
1430 | }
|
1431 |
|
1432 | function parsePeriod(d, string, i) {
|
1433 | var n = periodRe.exec(string.slice(i));
|
1434 | return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;
|
1435 | }
|
1436 |
|
1437 | function parseShortWeekday(d, string, i) {
|
1438 | var n = shortWeekdayRe.exec(string.slice(i));
|
1439 | return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
|
1440 | }
|
1441 |
|
1442 | function parseWeekday(d, string, i) {
|
1443 | var n = weekdayRe.exec(string.slice(i));
|
1444 | return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
|
1445 | }
|
1446 |
|
1447 | function parseShortMonth(d, string, i) {
|
1448 | var n = shortMonthRe.exec(string.slice(i));
|
1449 | return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
|
1450 | }
|
1451 |
|
1452 | function parseMonth(d, string, i) {
|
1453 | var n = monthRe.exec(string.slice(i));
|
1454 | return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
|
1455 | }
|
1456 |
|
1457 | function parseLocaleDateTime(d, string, i) {
|
1458 | return parseSpecifier(d, locale_dateTime, string, i);
|
1459 | }
|
1460 |
|
1461 | function parseLocaleDate(d, string, i) {
|
1462 | return parseSpecifier(d, locale_date, string, i);
|
1463 | }
|
1464 |
|
1465 | function parseLocaleTime(d, string, i) {
|
1466 | return parseSpecifier(d, locale_time, string, i);
|
1467 | }
|
1468 |
|
1469 | function formatShortWeekday(d) {
|
1470 | return locale_shortWeekdays[d.getDay()];
|
1471 | }
|
1472 |
|
1473 | function formatWeekday(d) {
|
1474 | return locale_weekdays[d.getDay()];
|
1475 | }
|
1476 |
|
1477 | function formatShortMonth(d) {
|
1478 | return locale_shortMonths[d.getMonth()];
|
1479 | }
|
1480 |
|
1481 | function formatMonth(d) {
|
1482 | return locale_months[d.getMonth()];
|
1483 | }
|
1484 |
|
1485 | function formatPeriod(d) {
|
1486 | return locale_periods[+(d.getHours() >= 12)];
|
1487 | }
|
1488 |
|
1489 | function formatQuarter(d) {
|
1490 | return 1 + ~~(d.getMonth() / 3);
|
1491 | }
|
1492 |
|
1493 | function formatUTCShortWeekday(d) {
|
1494 | return locale_shortWeekdays[d.getUTCDay()];
|
1495 | }
|
1496 |
|
1497 | function formatUTCWeekday(d) {
|
1498 | return locale_weekdays[d.getUTCDay()];
|
1499 | }
|
1500 |
|
1501 | function formatUTCShortMonth(d) {
|
1502 | return locale_shortMonths[d.getUTCMonth()];
|
1503 | }
|
1504 |
|
1505 | function formatUTCMonth(d) {
|
1506 | return locale_months[d.getUTCMonth()];
|
1507 | }
|
1508 |
|
1509 | function formatUTCPeriod(d) {
|
1510 | return locale_periods[+(d.getUTCHours() >= 12)];
|
1511 | }
|
1512 |
|
1513 | function formatUTCQuarter(d) {
|
1514 | return 1 + ~~(d.getUTCMonth() / 3);
|
1515 | }
|
1516 |
|
1517 | return {
|
1518 | format: function(specifier) {
|
1519 | var f = newFormat(specifier += "", formats);
|
1520 | f.toString = function() { return specifier; };
|
1521 | return f;
|
1522 | },
|
1523 | parse: function(specifier) {
|
1524 | var p = newParse(specifier += "", false);
|
1525 | p.toString = function() { return specifier; };
|
1526 | return p;
|
1527 | },
|
1528 | utcFormat: function(specifier) {
|
1529 | var f = newFormat(specifier += "", utcFormats);
|
1530 | f.toString = function() { return specifier; };
|
1531 | return f;
|
1532 | },
|
1533 | utcParse: function(specifier) {
|
1534 | var p = newParse(specifier += "", true);
|
1535 | p.toString = function() { return specifier; };
|
1536 | return p;
|
1537 | }
|
1538 | };
|
1539 | }
|
1540 |
|
1541 | var pads = {"-": "", "_": " ", "0": "0"},
|
1542 | numberRe = /^\s*\d+/,
|
1543 | percentRe = /^%/,
|
1544 | requoteRe = /[\\^$*+?|[\]().{}]/g;
|
1545 |
|
1546 | function pad(value, fill, width) {
|
1547 | var sign = value < 0 ? "-" : "",
|
1548 | string = (sign ? -value : value) + "",
|
1549 | length = string.length;
|
1550 | return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
|
1551 | }
|
1552 |
|
1553 | function requote(s) {
|
1554 | return s.replace(requoteRe, "\\$&");
|
1555 | }
|
1556 |
|
1557 | function formatRe(names) {
|
1558 | return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
|
1559 | }
|
1560 |
|
1561 | function formatLookup(names) {
|
1562 | var map = {}, i = -1, n = names.length;
|
1563 | while (++i < n) map[names[i].toLowerCase()] = i;
|
1564 | return map;
|
1565 | }
|
1566 |
|
1567 | function parseWeekdayNumberSunday(d, string, i) {
|
1568 | var n = numberRe.exec(string.slice(i, i + 1));
|
1569 | return n ? (d.w = +n[0], i + n[0].length) : -1;
|
1570 | }
|
1571 |
|
1572 | function parseWeekdayNumberMonday(d, string, i) {
|
1573 | var n = numberRe.exec(string.slice(i, i + 1));
|
1574 | return n ? (d.u = +n[0], i + n[0].length) : -1;
|
1575 | }
|
1576 |
|
1577 | function parseWeekNumberSunday(d, string, i) {
|
1578 | var n = numberRe.exec(string.slice(i, i + 2));
|
1579 | return n ? (d.U = +n[0], i + n[0].length) : -1;
|
1580 | }
|
1581 |
|
1582 | function parseWeekNumberISO(d, string, i) {
|
1583 | var n = numberRe.exec(string.slice(i, i + 2));
|
1584 | return n ? (d.V = +n[0], i + n[0].length) : -1;
|
1585 | }
|
1586 |
|
1587 | function parseWeekNumberMonday(d, string, i) {
|
1588 | var n = numberRe.exec(string.slice(i, i + 2));
|
1589 | return n ? (d.W = +n[0], i + n[0].length) : -1;
|
1590 | }
|
1591 |
|
1592 | function parseFullYear(d, string, i) {
|
1593 | var n = numberRe.exec(string.slice(i, i + 4));
|
1594 | return n ? (d.y = +n[0], i + n[0].length) : -1;
|
1595 | }
|
1596 |
|
1597 | function parseYear(d, string, i) {
|
1598 | var n = numberRe.exec(string.slice(i, i + 2));
|
1599 | return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;
|
1600 | }
|
1601 |
|
1602 | function parseZone(d, string, i) {
|
1603 | var n = /^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(string.slice(i, i + 6));
|
1604 | return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1;
|
1605 | }
|
1606 |
|
1607 | function parseQuarter(d, string, i) {
|
1608 | var n = numberRe.exec(string.slice(i, i + 1));
|
1609 | return n ? (d.q = n[0] * 3 - 3, i + n[0].length) : -1;
|
1610 | }
|
1611 |
|
1612 | function parseMonthNumber(d, string, i) {
|
1613 | var n = numberRe.exec(string.slice(i, i + 2));
|
1614 | return n ? (d.m = n[0] - 1, i + n[0].length) : -1;
|
1615 | }
|
1616 |
|
1617 | function parseDayOfMonth(d, string, i) {
|
1618 | var n = numberRe.exec(string.slice(i, i + 2));
|
1619 | return n ? (d.d = +n[0], i + n[0].length) : -1;
|
1620 | }
|
1621 |
|
1622 | function parseDayOfYear(d, string, i) {
|
1623 | var n = numberRe.exec(string.slice(i, i + 3));
|
1624 | return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;
|
1625 | }
|
1626 |
|
1627 | function parseHour24(d, string, i) {
|
1628 | var n = numberRe.exec(string.slice(i, i + 2));
|
1629 | return n ? (d.H = +n[0], i + n[0].length) : -1;
|
1630 | }
|
1631 |
|
1632 | function parseMinutes(d, string, i) {
|
1633 | var n = numberRe.exec(string.slice(i, i + 2));
|
1634 | return n ? (d.M = +n[0], i + n[0].length) : -1;
|
1635 | }
|
1636 |
|
1637 | function parseSeconds(d, string, i) {
|
1638 | var n = numberRe.exec(string.slice(i, i + 2));
|
1639 | return n ? (d.S = +n[0], i + n[0].length) : -1;
|
1640 | }
|
1641 |
|
1642 | function parseMilliseconds(d, string, i) {
|
1643 | var n = numberRe.exec(string.slice(i, i + 3));
|
1644 | return n ? (d.L = +n[0], i + n[0].length) : -1;
|
1645 | }
|
1646 |
|
1647 | function parseMicroseconds(d, string, i) {
|
1648 | var n = numberRe.exec(string.slice(i, i + 6));
|
1649 | return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1;
|
1650 | }
|
1651 |
|
1652 | function parseLiteralPercent(d, string, i) {
|
1653 | var n = percentRe.exec(string.slice(i, i + 1));
|
1654 | return n ? i + n[0].length : -1;
|
1655 | }
|
1656 |
|
1657 | function parseUnixTimestamp(d, string, i) {
|
1658 | var n = numberRe.exec(string.slice(i));
|
1659 | return n ? (d.Q = +n[0], i + n[0].length) : -1;
|
1660 | }
|
1661 |
|
1662 | function parseUnixTimestampSeconds(d, string, i) {
|
1663 | var n = numberRe.exec(string.slice(i));
|
1664 | return n ? (d.s = +n[0], i + n[0].length) : -1;
|
1665 | }
|
1666 |
|
1667 | function formatDayOfMonth(d, p) {
|
1668 | return pad(d.getDate(), p, 2);
|
1669 | }
|
1670 |
|
1671 | function formatHour24(d, p) {
|
1672 | return pad(d.getHours(), p, 2);
|
1673 | }
|
1674 |
|
1675 | function formatHour12(d, p) {
|
1676 | return pad(d.getHours() % 12 || 12, p, 2);
|
1677 | }
|
1678 |
|
1679 | function formatDayOfYear(d, p) {
|
1680 | return pad(1 + day.count(year(d), d), p, 3);
|
1681 | }
|
1682 |
|
1683 | function formatMilliseconds(d, p) {
|
1684 | return pad(d.getMilliseconds(), p, 3);
|
1685 | }
|
1686 |
|
1687 | function formatMicroseconds(d, p) {
|
1688 | return formatMilliseconds(d, p) + "000";
|
1689 | }
|
1690 |
|
1691 | function formatMonthNumber(d, p) {
|
1692 | return pad(d.getMonth() + 1, p, 2);
|
1693 | }
|
1694 |
|
1695 | function formatMinutes(d, p) {
|
1696 | return pad(d.getMinutes(), p, 2);
|
1697 | }
|
1698 |
|
1699 | function formatSeconds(d, p) {
|
1700 | return pad(d.getSeconds(), p, 2);
|
1701 | }
|
1702 |
|
1703 | function formatWeekdayNumberMonday(d) {
|
1704 | var day = d.getDay();
|
1705 | return day === 0 ? 7 : day;
|
1706 | }
|
1707 |
|
1708 | function formatWeekNumberSunday(d, p) {
|
1709 | return pad(sunday.count(year(d) - 1, d), p, 2);
|
1710 | }
|
1711 |
|
1712 | function formatWeekNumberISO(d, p) {
|
1713 | var day = d.getDay();
|
1714 | d = (day >= 4 || day === 0) ? thursday(d) : thursday.ceil(d);
|
1715 | return pad(thursday.count(year(d), d) + (year(d).getDay() === 4), p, 2);
|
1716 | }
|
1717 |
|
1718 | function formatWeekdayNumberSunday(d) {
|
1719 | return d.getDay();
|
1720 | }
|
1721 |
|
1722 | function formatWeekNumberMonday(d, p) {
|
1723 | return pad(monday.count(year(d) - 1, d), p, 2);
|
1724 | }
|
1725 |
|
1726 | function formatYear(d, p) {
|
1727 | return pad(d.getFullYear() % 100, p, 2);
|
1728 | }
|
1729 |
|
1730 | function formatFullYear(d, p) {
|
1731 | return pad(d.getFullYear() % 10000, p, 4);
|
1732 | }
|
1733 |
|
1734 | function formatZone(d) {
|
1735 | var z = d.getTimezoneOffset();
|
1736 | return (z > 0 ? "-" : (z *= -1, "+"))
|
1737 | + pad(z / 60 | 0, "0", 2)
|
1738 | + pad(z % 60, "0", 2);
|
1739 | }
|
1740 |
|
1741 | function formatUTCDayOfMonth(d, p) {
|
1742 | return pad(d.getUTCDate(), p, 2);
|
1743 | }
|
1744 |
|
1745 | function formatUTCHour24(d, p) {
|
1746 | return pad(d.getUTCHours(), p, 2);
|
1747 | }
|
1748 |
|
1749 | function formatUTCHour12(d, p) {
|
1750 | return pad(d.getUTCHours() % 12 || 12, p, 2);
|
1751 | }
|
1752 |
|
1753 | function formatUTCDayOfYear(d, p) {
|
1754 | return pad(1 + utcDay.count(utcYear(d), d), p, 3);
|
1755 | }
|
1756 |
|
1757 | function formatUTCMilliseconds(d, p) {
|
1758 | return pad(d.getUTCMilliseconds(), p, 3);
|
1759 | }
|
1760 |
|
1761 | function formatUTCMicroseconds(d, p) {
|
1762 | return formatUTCMilliseconds(d, p) + "000";
|
1763 | }
|
1764 |
|
1765 | function formatUTCMonthNumber(d, p) {
|
1766 | return pad(d.getUTCMonth() + 1, p, 2);
|
1767 | }
|
1768 |
|
1769 | function formatUTCMinutes(d, p) {
|
1770 | return pad(d.getUTCMinutes(), p, 2);
|
1771 | }
|
1772 |
|
1773 | function formatUTCSeconds(d, p) {
|
1774 | return pad(d.getUTCSeconds(), p, 2);
|
1775 | }
|
1776 |
|
1777 | function formatUTCWeekdayNumberMonday(d) {
|
1778 | var dow = d.getUTCDay();
|
1779 | return dow === 0 ? 7 : dow;
|
1780 | }
|
1781 |
|
1782 | function formatUTCWeekNumberSunday(d, p) {
|
1783 | return pad(utcSunday.count(utcYear(d) - 1, d), p, 2);
|
1784 | }
|
1785 |
|
1786 | function formatUTCWeekNumberISO(d, p) {
|
1787 | var day = d.getUTCDay();
|
1788 | d = (day >= 4 || day === 0) ? utcThursday(d) : utcThursday.ceil(d);
|
1789 | return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2);
|
1790 | }
|
1791 |
|
1792 | function formatUTCWeekdayNumberSunday(d) {
|
1793 | return d.getUTCDay();
|
1794 | }
|
1795 |
|
1796 | function formatUTCWeekNumberMonday(d, p) {
|
1797 | return pad(utcMonday.count(utcYear(d) - 1, d), p, 2);
|
1798 | }
|
1799 |
|
1800 | function formatUTCYear(d, p) {
|
1801 | return pad(d.getUTCFullYear() % 100, p, 2);
|
1802 | }
|
1803 |
|
1804 | function formatUTCFullYear(d, p) {
|
1805 | return pad(d.getUTCFullYear() % 10000, p, 4);
|
1806 | }
|
1807 |
|
1808 | function formatUTCZone() {
|
1809 | return "+0000";
|
1810 | }
|
1811 |
|
1812 | function formatLiteralPercent() {
|
1813 | return "%";
|
1814 | }
|
1815 |
|
1816 | function formatUnixTimestamp(d) {
|
1817 | return +d;
|
1818 | }
|
1819 |
|
1820 | function formatUnixTimestampSeconds(d) {
|
1821 | return Math.floor(+d / 1000);
|
1822 | }
|
1823 |
|
1824 | var locale;
|
1825 | var timeFormat;
|
1826 | var timeParse;
|
1827 | var utcFormat;
|
1828 | var utcParse;
|
1829 |
|
1830 | defaultLocale({
|
1831 | dateTime: "%x, %X",
|
1832 | date: "%-m/%-d/%Y",
|
1833 | time: "%-I:%M:%S %p",
|
1834 | periods: ["AM", "PM"],
|
1835 | days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
|
1836 | shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
1837 | months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
1838 | shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
|
1839 | });
|
1840 |
|
1841 | function defaultLocale(definition) {
|
1842 | locale = formatLocale(definition);
|
1843 | timeFormat = locale.format;
|
1844 | timeParse = locale.parse;
|
1845 | utcFormat = locale.utcFormat;
|
1846 | utcParse = locale.utcParse;
|
1847 | return locale;
|
1848 | }
|
1849 |
|
1850 | var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ";
|
1851 |
|
1852 | function formatIsoNative(date) {
|
1853 | return date.toISOString();
|
1854 | }
|
1855 |
|
1856 | var formatIso = Date.prototype.toISOString
|
1857 | ? formatIsoNative
|
1858 | : utcFormat(isoSpecifier);
|
1859 |
|
1860 | function parseIsoNative(string) {
|
1861 | var date = new Date(string);
|
1862 | return isNaN(date) ? null : date;
|
1863 | }
|
1864 |
|
1865 | var parseIso = +new Date("2000-01-01T00:00:00.000Z")
|
1866 | ? parseIsoNative
|
1867 | : utcParse(isoSpecifier);
|
1868 |
|
1869 | function normalizeLetters(str) {
|
1870 | return str.toLowerCase();
|
1871 | }
|
1872 |
|
1873 | function ascending$1(a, b) {
|
1874 | return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
|
1875 | }
|
1876 |
|
1877 | |
1878 |
|
1879 |
|
1880 |
|
1881 |
|
1882 | function sortArray(uarr, state, numericParser, numericFormatter) {
|
1883 | var is_numeric = state.sort === "numeric";
|
1884 | var is_temporal = state.sort === "temporal";
|
1885 | var parser = normalizeLetters;
|
1886 | if (is_numeric) parser = numericParser;
|
1887 | else if (is_temporal) parser = timeParse(state.sort_temporal_format);
|
1888 |
|
1889 | var sarr = uarr.map(function(d, i) {
|
1890 | var parsed_value = parser(d);
|
1891 | return {
|
1892 | value: d,
|
1893 | options_index: i,
|
1894 | parsed: parsed_value,
|
1895 | display: is_numeric && !isNaN(parsed_value) ? numericFormatter(parsed_value) : d
|
1896 | };
|
1897 | });
|
1898 |
|
1899 | if (state.sort == "unsorted") return sarr;
|
1900 | return sarr.sort(function(a, b) { return ascending$1(a.parsed, b.parsed); });
|
1901 | }
|
1902 |
|
1903 | function Stylesheet() {
|
1904 | this.declarations = [];
|
1905 | return this;
|
1906 | }
|
1907 |
|
1908 | Stylesheet.prototype.select = function(selector) {
|
1909 | if (!selector) return this;
|
1910 | var declaration = new Declaration(selector, this);
|
1911 | declaration.parent = this;
|
1912 | this.addDeclaration(declaration);
|
1913 |
|
1914 | return declaration;
|
1915 | };
|
1916 |
|
1917 | Stylesheet.prototype.addDeclaration = function(declaration) {
|
1918 | this.declarations.push(declaration);
|
1919 | return this;
|
1920 | };
|
1921 |
|
1922 | Stylesheet.prototype.print = function() {
|
1923 | var text = "";
|
1924 | this.declarations.forEach(function(declaration) {
|
1925 | text += declaration.selector + " {\n";
|
1926 | declaration.styles.forEach(function(style) {
|
1927 | text += "\t" + style[0] + ": " + style[1] + ";\n";
|
1928 | });
|
1929 | text += "}\n\n";
|
1930 | });
|
1931 | return text;
|
1932 | };
|
1933 |
|
1934 | Stylesheet.prototype.clear = function() {
|
1935 | this.declarations = [];
|
1936 | return this;
|
1937 | };
|
1938 |
|
1939 | function Declaration(selector) {
|
1940 | this.selector = selector;
|
1941 | this.styles = [];
|
1942 | return this;
|
1943 | }
|
1944 |
|
1945 | Declaration.prototype.style = function(property, _value) {
|
1946 | var value = typeof value_ == "function" ? _value() : _value;
|
1947 | if (value !== "" && value !== null && value !== undefined) this.styles.push([property, value]);
|
1948 | return this;
|
1949 | };
|
1950 |
|
1951 | Declaration.prototype.select = function(selector) {
|
1952 | return this.parent.select(this.selector + " " + selector);
|
1953 | };
|
1954 |
|
1955 | function createCssString() {
|
1956 | var s = new Stylesheet();
|
1957 |
|
1958 | s.select(".fl-controls-container")
|
1959 | .style("display", "inline-block")
|
1960 | .style("line-height", "0");
|
1961 |
|
1962 | s.select(".fl-controls-container, .fl-controls-container *")
|
1963 | .style("box-sizing", "border-box");
|
1964 |
|
1965 | s.select(".slider-holder")
|
1966 | .style("margin-bottom", "20px");
|
1967 |
|
1968 | s.select(".fl-controls-slider, .slider-play")
|
1969 | .style("pointer-events", "all")
|
1970 | .style("display", "inline-block")
|
1971 | .style("vertical-align", "middle");
|
1972 |
|
1973 | s.select(".slider-play svg")
|
1974 | .style("height", "100%")
|
1975 | .style("width", "100%")
|
1976 | .style("cursor", " pointer", "");
|
1977 |
|
1978 | s.select(".slider-play:hover")
|
1979 | .style("opacity", "0.6");
|
1980 |
|
1981 | s.select(".fl-control-slider")
|
1982 | .style("width", "100%")
|
1983 | .style("bottom", "0");
|
1984 |
|
1985 | s.select(".fl-control")
|
1986 | .style("position", "relative");
|
1987 |
|
1988 | s.select(".fl-control.hidden")
|
1989 | .style("display", "none");
|
1990 |
|
1991 | s.select(".fl-control .button")
|
1992 | .style("display", "inline-block")
|
1993 | .style("background", "#eee")
|
1994 | .style("padding", "0.5em")
|
1995 | .style("margin-right", "0.25em")
|
1996 | .style("margin-bottom", "0.25em")
|
1997 | .style("line-height", "1em");
|
1998 |
|
1999 | s.select(".fl-control.grouped:not(.hidden)")
|
2000 | .style("display", "table")
|
2001 | .style("table-layout", "fixed")
|
2002 | .select(".button")
|
2003 | .style("display", "table-cell")
|
2004 | .style("margin", "0")
|
2005 | .style("text-align", "center");
|
2006 |
|
2007 | s.select(".fl-control .button.selected")
|
2008 | .style("background", "#ddd");
|
2009 |
|
2010 | s.select(".fl-control-dropdown")
|
2011 | .style("line-height", "1em")
|
2012 | .select(".list")
|
2013 | .style("display", "none")
|
2014 | .style("position", "absolute")
|
2015 | .style("background-color", "white")
|
2016 | .style("z-index", "100")
|
2017 | .style("border", "1px solid #eee")
|
2018 | .select(".list-item")
|
2019 | .style("cursor", "pointer")
|
2020 | .style("padding", "0.5rem");
|
2021 |
|
2022 | s.select(".fl-control-dropdown.open .list")
|
2023 | .style("display", "block");
|
2024 |
|
2025 | s.select(".fl-control-dropdown .main")
|
2026 | .style("position", "relative");
|
2027 |
|
2028 | s.select(".fl-control-dropdown .symbol")
|
2029 | .style("float", "right")
|
2030 | .select("div")
|
2031 | .style("border-top-color", "#333333");
|
2032 |
|
2033 | return s.print();
|
2034 | }
|
2035 |
|
2036 | var css_injected = false;
|
2037 |
|
2038 | function injectCSS() {
|
2039 | if (css_injected || typeof document === "undefined") return;
|
2040 |
|
2041 | var css_string = createCssString();
|
2042 |
|
2043 | var head = document.head || document.getElementsByTagName("head")[0];
|
2044 | var style = document.createElement("style");
|
2045 | style.type = "text/css";
|
2046 | style.className = "flourish-controls";
|
2047 | head.appendChild(style);
|
2048 | if (style.styleSheet) {
|
2049 | style.styleSheet.cssText = css_string;
|
2050 | }
|
2051 | else {
|
2052 | style.appendChild(document.createTextNode(css_string));
|
2053 | }
|
2054 | css_injected = true;
|
2055 | }
|
2056 |
|
2057 | var getTextWidth = (function() {
|
2058 | var context = document.createElement("canvas").getContext("2d");
|
2059 | return function(text, font) {
|
2060 | context.font = font || "10px sans-serif";
|
2061 | var metrics = context.measureText(text);
|
2062 | return metrics.width;
|
2063 | };
|
2064 | })();
|
2065 |
|
2066 | var remToPx;
|
2067 |
|
2068 | function getRemToPx() {
|
2069 | var font_size = parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
|
2070 | remToPx = function (rem) { return rem * font_size; };
|
2071 | }
|
2072 |
|
2073 | var MIN_HEIGHT = 90;
|
2074 | function createDropdown(control_obj, state, container) {
|
2075 | var dropdown_obj = {};
|
2076 | var bounding_container = document.body;
|
2077 |
|
2078 |
|
2079 | var dropdown = select(container).append("div").attr("class", "fl-control fl-control-dropdown");
|
2080 | var dropdown_node = dropdown.node();
|
2081 | var dropdown_main = dropdown.append("div").attr("class", "main");
|
2082 | var dropdown_current = dropdown_main.append("span").attr("class", "current");
|
2083 | dropdown_main.append("span").attr("class", "symbol").style("width", "10px")
|
2084 | .append("div")
|
2085 | .style("border-left", "5px solid transparent")
|
2086 | .style("border-right", "5px solid transparent")
|
2087 | .style("border-bottom", "5px solid transparent")
|
2088 | .style("border-top-style", "solid")
|
2089 | .style("border-top-width", "5px")
|
2090 | .style("top", "50%")
|
2091 | .style("position", "absolute")
|
2092 | .style("margin-top", "-2.5px");
|
2093 | var dropdown_list = dropdown.append("div").attr("class", "list");
|
2094 |
|
2095 | var showDropdownList = function() {
|
2096 | dropdown.classed("open", true);
|
2097 | dropdown_list.style("top", "100%");
|
2098 | dropdown_list.style("bottom", null);
|
2099 | dropdown_list.style("display", null);
|
2100 | dropdown_list.style("overflow", "auto");
|
2101 | var bounding_bb = bounding_container.getBoundingClientRect();
|
2102 | var list_bb = dropdown_list.node().getBoundingClientRect();
|
2103 | var overspill = list_bb.bottom - bounding_bb.bottom;
|
2104 | if (overspill > 0) {
|
2105 | var new_height = bounding_bb.bottom - list_bb.top - 30;
|
2106 | if (new_height > MIN_HEIGHT) dropdown_list.style("max-height", new_height + "px");
|
2107 | else dropdown_list
|
2108 | .style("top", "auto")
|
2109 | .style("bottom", "100%");
|
2110 | }
|
2111 | if (list_bb.right > window.innerWidth) {
|
2112 | dropdown_list.style("right", 0);
|
2113 | }
|
2114 | };
|
2115 |
|
2116 | var hideDropdownList = function() {
|
2117 | dropdown.classed("open", false);
|
2118 | dropdown_list.style("right", null);
|
2119 | dropdown_list.style("max-height", null);
|
2120 | dropdown_list.style("display", "none");
|
2121 | };
|
2122 |
|
2123 | var toggleDropdownList = function() {
|
2124 | if (dropdown.classed("open")) hideDropdownList();
|
2125 | else showDropdownList();
|
2126 | };
|
2127 |
|
2128 | dropdown_main.on("click", function() { toggleDropdownList(); });
|
2129 |
|
2130 | var clickHandler = function() {
|
2131 | if (!dropdown.classed("open")) return;
|
2132 | var el = event.target;
|
2133 | var parent = el.parentElement;
|
2134 | while (parent) {
|
2135 | if (el === dropdown_node) return;
|
2136 | el = parent;
|
2137 | parent = el.parentElement;
|
2138 | }
|
2139 | hideDropdownList();
|
2140 | };
|
2141 |
|
2142 | var showControl = function(longest_text_width) {
|
2143 | var dropdown_width = "100%";
|
2144 | if (state.dropdown_width_mode == "auto") {
|
2145 | dropdown_width = Math.min(longest_text_width + 40, remToPx(20)) + "px";
|
2146 | }
|
2147 | else if (state.dropdown_width_mode == "fixed") {
|
2148 | dropdown_width = remToPx(state.dropdown_width_fixed) + "px";
|
2149 | }
|
2150 | container.style.width = state.dropdown_width_mode == "full" ? dropdown_width : "";
|
2151 | dropdown.style("width", dropdown_width).style("display", state.dropdown_width_mode !== "full" ? "inline-table" : null);
|
2152 | dropdown.select(".main").style("width", dropdown_width);
|
2153 | };
|
2154 |
|
2155 | var hideControl = function() {
|
2156 | hideDropdownList();
|
2157 | dropdown.style("display", "none");
|
2158 | };
|
2159 |
|
2160 |
|
2161 | dropdown_obj.appendedToDOM = function(_bounding_container) {
|
2162 | if (_bounding_container) bounding_container = _bounding_container;
|
2163 | document.querySelector("body").addEventListener("click", clickHandler, false);
|
2164 | return dropdown_obj;
|
2165 | };
|
2166 |
|
2167 |
|
2168 | dropdown_obj.removedFromDOM = function() {
|
2169 | document.querySelector("body").removeEventListener("click", clickHandler);
|
2170 | return dropdown_obj;
|
2171 | };
|
2172 |
|
2173 | dropdown_obj.show = showControl;
|
2174 | dropdown_obj.hide = hideControl;
|
2175 |
|
2176 |
|
2177 | dropdown_obj.update = function(sorted_options) {
|
2178 | dropdown_list.text("");
|
2179 | var dropdown_font_size = window.getComputedStyle(dropdown.node()).fontSize;
|
2180 | if (!control_obj.n_options || state.control_type !== "dropdown") {
|
2181 | hideControl();
|
2182 | return dropdown_obj;
|
2183 | }
|
2184 |
|
2185 | var longest_text = "";
|
2186 | dropdown_list.text("")
|
2187 | .selectAll(".list-item")
|
2188 | .data(sorted_options)
|
2189 | .enter()
|
2190 | .append("div")
|
2191 | .attr("class", "list-item")
|
2192 | .text(function(d) {
|
2193 | if (d.display.length > longest_text.length) longest_text = d.display;
|
2194 | return d.display;
|
2195 | })
|
2196 | .on("click", function(d) {
|
2197 | hideDropdownList();
|
2198 | var i = d.options_index;
|
2199 | if (i === control_obj.index()) return;
|
2200 | control_obj.index(i);
|
2201 | dropdown_current.text(d.display).attr("title", d.display);
|
2202 | control_obj.trigger("change");
|
2203 | });
|
2204 | var longest_text_width = getTextWidth(longest_text, dropdown_font_size + " sans-serif");
|
2205 | var sorted_index = control_obj.getSortedIndex();
|
2206 | var value = sorted_options[sorted_index].display;
|
2207 | dropdown_current.text(value).attr("title", value);
|
2208 |
|
2209 | showControl(longest_text_width);
|
2210 |
|
2211 | return dropdown_obj;
|
2212 | };
|
2213 |
|
2214 |
|
2215 | return dropdown_obj;
|
2216 | }
|
2217 |
|
2218 | function createButtons(control_obj, state, container) {
|
2219 | var button_obj = {};
|
2220 | var button_container = select(container).append("div").attr("class", "fl-control fl-control-buttons");
|
2221 |
|
2222 | var showControl = function() {
|
2223 | button_container.classed("hidden", false);
|
2224 | };
|
2225 |
|
2226 | var hideControl = function() {
|
2227 | button_container.classed("hidden", true);
|
2228 | };
|
2229 |
|
2230 | button_obj.show = showControl;
|
2231 | button_obj.hide = hideControl;
|
2232 |
|
2233 | button_obj.update = function(sorted_options) {
|
2234 | button_container.text("");
|
2235 | if (!control_obj.n_options || state.control_type !== "buttons") {
|
2236 | hideControl();
|
2237 | return button_obj;
|
2238 | }
|
2239 |
|
2240 | var index = control_obj.index();
|
2241 |
|
2242 | button_container.classed("grouped", state.button_group);
|
2243 | button_container.classed("fixed-width", state.button_group_width_mode == "fixed" || state.button_group_width_mode == "full");
|
2244 | button_container.style("width", state.button_group && state.button_group_width_mode == "fixed" ? remToPx(state.button_group_width_fixed) + "px" : state.button_group_width_mode == "full" ? "100%" : null);
|
2245 |
|
2246 | var buttons = button_container.selectAll(".button")
|
2247 | .data(sorted_options)
|
2248 | .enter()
|
2249 | .append("div");
|
2250 |
|
2251 | buttons.attr("class", "button")
|
2252 | .style("cursor", "pointer")
|
2253 | .classed("selected", function(d) { return d.options_index === index; })
|
2254 | .on("click", function(d) {
|
2255 | var i = d.options_index;
|
2256 | if (i === control_obj.index()) return;
|
2257 | control_obj.index(i);
|
2258 | buttons.classed("selected", function(d) { return d.options_index === i; });
|
2259 | control_obj.trigger("change");
|
2260 | })
|
2261 | .append("span")
|
2262 | .text(function(d) { return d.display; });
|
2263 |
|
2264 | showControl();
|
2265 | };
|
2266 |
|
2267 | return button_obj;
|
2268 | }
|
2269 |
|
2270 | var slice = Array.prototype.slice;
|
2271 |
|
2272 | function identity(x) {
|
2273 | return x;
|
2274 | }
|
2275 |
|
2276 | var top = 1,
|
2277 | right = 2,
|
2278 | bottom = 3,
|
2279 | left = 4,
|
2280 | epsilon = 1e-6;
|
2281 |
|
2282 | function translateX(x) {
|
2283 | return "translate(" + (x + 0.5) + ",0)";
|
2284 | }
|
2285 |
|
2286 | function translateY(y) {
|
2287 | return "translate(0," + (y + 0.5) + ")";
|
2288 | }
|
2289 |
|
2290 | function number(scale) {
|
2291 | return function(d) {
|
2292 | return +scale(d);
|
2293 | };
|
2294 | }
|
2295 |
|
2296 | function center(scale) {
|
2297 | var offset = Math.max(0, scale.bandwidth() - 1) / 2;
|
2298 | if (scale.round()) offset = Math.round(offset);
|
2299 | return function(d) {
|
2300 | return +scale(d) + offset;
|
2301 | };
|
2302 | }
|
2303 |
|
2304 | function entering() {
|
2305 | return !this.__axis;
|
2306 | }
|
2307 |
|
2308 | function axis(orient, scale) {
|
2309 | var tickArguments = [],
|
2310 | tickValues = null,
|
2311 | tickFormat = null,
|
2312 | tickSizeInner = 6,
|
2313 | tickSizeOuter = 6,
|
2314 | tickPadding = 3,
|
2315 | k = orient === top || orient === left ? -1 : 1,
|
2316 | x = orient === left || orient === right ? "x" : "y",
|
2317 | transform = orient === top || orient === bottom ? translateX : translateY;
|
2318 |
|
2319 | function axis(context) {
|
2320 | var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,
|
2321 | format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity) : tickFormat,
|
2322 | spacing = Math.max(tickSizeInner, 0) + tickPadding,
|
2323 | range = scale.range(),
|
2324 | range0 = +range[0] + 0.5,
|
2325 | range1 = +range[range.length - 1] + 0.5,
|
2326 | position = (scale.bandwidth ? center : number)(scale.copy()),
|
2327 | selection = context.selection ? context.selection() : context,
|
2328 | path = selection.selectAll(".domain").data([null]),
|
2329 | tick = selection.selectAll(".tick").data(values, scale).order(),
|
2330 | tickExit = tick.exit(),
|
2331 | tickEnter = tick.enter().append("g").attr("class", "tick"),
|
2332 | line = tick.select("line"),
|
2333 | text = tick.select("text");
|
2334 |
|
2335 | path = path.merge(path.enter().insert("path", ".tick")
|
2336 | .attr("class", "domain")
|
2337 | .attr("stroke", "currentColor"));
|
2338 |
|
2339 | tick = tick.merge(tickEnter);
|
2340 |
|
2341 | line = line.merge(tickEnter.append("line")
|
2342 | .attr("stroke", "currentColor")
|
2343 | .attr(x + "2", k * tickSizeInner));
|
2344 |
|
2345 | text = text.merge(tickEnter.append("text")
|
2346 | .attr("fill", "currentColor")
|
2347 | .attr(x, k * spacing)
|
2348 | .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em"));
|
2349 |
|
2350 | if (context !== selection) {
|
2351 | path = path.transition(context);
|
2352 | tick = tick.transition(context);
|
2353 | line = line.transition(context);
|
2354 | text = text.transition(context);
|
2355 |
|
2356 | tickExit = tickExit.transition(context)
|
2357 | .attr("opacity", epsilon)
|
2358 | .attr("transform", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute("transform"); });
|
2359 |
|
2360 | tickEnter
|
2361 | .attr("opacity", epsilon)
|
2362 | .attr("transform", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); });
|
2363 | }
|
2364 |
|
2365 | tickExit.remove();
|
2366 |
|
2367 | path
|
2368 | .attr("d", orient === left || orient == right
|
2369 | ? (tickSizeOuter ? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter : "M0.5," + range0 + "V" + range1)
|
2370 | : (tickSizeOuter ? "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter : "M" + range0 + ",0.5H" + range1));
|
2371 |
|
2372 | tick
|
2373 | .attr("opacity", 1)
|
2374 | .attr("transform", function(d) { return transform(position(d)); });
|
2375 |
|
2376 | line
|
2377 | .attr(x + "2", k * tickSizeInner);
|
2378 |
|
2379 | text
|
2380 | .attr(x, k * spacing)
|
2381 | .text(format);
|
2382 |
|
2383 | selection.filter(entering)
|
2384 | .attr("fill", "none")
|
2385 | .attr("font-size", 10)
|
2386 | .attr("font-family", "sans-serif")
|
2387 | .attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle");
|
2388 |
|
2389 | selection
|
2390 | .each(function() { this.__axis = position; });
|
2391 | }
|
2392 |
|
2393 | axis.scale = function(_) {
|
2394 | return arguments.length ? (scale = _, axis) : scale;
|
2395 | };
|
2396 |
|
2397 | axis.ticks = function() {
|
2398 | return tickArguments = slice.call(arguments), axis;
|
2399 | };
|
2400 |
|
2401 | axis.tickArguments = function(_) {
|
2402 | return arguments.length ? (tickArguments = _ == null ? [] : slice.call(_), axis) : tickArguments.slice();
|
2403 | };
|
2404 |
|
2405 | axis.tickValues = function(_) {
|
2406 | return arguments.length ? (tickValues = _ == null ? null : slice.call(_), axis) : tickValues && tickValues.slice();
|
2407 | };
|
2408 |
|
2409 | axis.tickFormat = function(_) {
|
2410 | return arguments.length ? (tickFormat = _, axis) : tickFormat;
|
2411 | };
|
2412 |
|
2413 | axis.tickSize = function(_) {
|
2414 | return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;
|
2415 | };
|
2416 |
|
2417 | axis.tickSizeInner = function(_) {
|
2418 | return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;
|
2419 | };
|
2420 |
|
2421 | axis.tickSizeOuter = function(_) {
|
2422 | return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;
|
2423 | };
|
2424 |
|
2425 | axis.tickPadding = function(_) {
|
2426 | return arguments.length ? (tickPadding = +_, axis) : tickPadding;
|
2427 | };
|
2428 |
|
2429 | return axis;
|
2430 | }
|
2431 |
|
2432 | function axisBottom(scale) {
|
2433 | return axis(bottom, scale);
|
2434 | }
|
2435 |
|
2436 | function ascending$2(a, b) {
|
2437 | return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
|
2438 | }
|
2439 |
|
2440 | function bisector(compare) {
|
2441 | if (compare.length === 1) compare = ascendingComparator(compare);
|
2442 | return {
|
2443 | left: function(a, x, lo, hi) {
|
2444 | if (lo == null) lo = 0;
|
2445 | if (hi == null) hi = a.length;
|
2446 | while (lo < hi) {
|
2447 | var mid = lo + hi >>> 1;
|
2448 | if (compare(a[mid], x) < 0) lo = mid + 1;
|
2449 | else hi = mid;
|
2450 | }
|
2451 | return lo;
|
2452 | },
|
2453 | right: function(a, x, lo, hi) {
|
2454 | if (lo == null) lo = 0;
|
2455 | if (hi == null) hi = a.length;
|
2456 | while (lo < hi) {
|
2457 | var mid = lo + hi >>> 1;
|
2458 | if (compare(a[mid], x) > 0) hi = mid;
|
2459 | else lo = mid + 1;
|
2460 | }
|
2461 | return lo;
|
2462 | }
|
2463 | };
|
2464 | }
|
2465 |
|
2466 | function ascendingComparator(f) {
|
2467 | return function(d, x) {
|
2468 | return ascending$2(f(d), x);
|
2469 | };
|
2470 | }
|
2471 |
|
2472 | var ascendingBisect = bisector(ascending$2);
|
2473 | var bisectRight = ascendingBisect.right;
|
2474 |
|
2475 | var e10 = Math.sqrt(50),
|
2476 | e5 = Math.sqrt(10),
|
2477 | e2 = Math.sqrt(2);
|
2478 |
|
2479 | function ticks(start, stop, count) {
|
2480 | var reverse,
|
2481 | i = -1,
|
2482 | n,
|
2483 | ticks,
|
2484 | step;
|
2485 |
|
2486 | stop = +stop, start = +start, count = +count;
|
2487 | if (start === stop && count > 0) return [start];
|
2488 | if (reverse = stop < start) n = start, start = stop, stop = n;
|
2489 | if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];
|
2490 |
|
2491 | if (step > 0) {
|
2492 | start = Math.ceil(start / step);
|
2493 | stop = Math.floor(stop / step);
|
2494 | ticks = new Array(n = Math.ceil(stop - start + 1));
|
2495 | while (++i < n) ticks[i] = (start + i) * step;
|
2496 | } else {
|
2497 | start = Math.floor(start * step);
|
2498 | stop = Math.ceil(stop * step);
|
2499 | ticks = new Array(n = Math.ceil(start - stop + 1));
|
2500 | while (++i < n) ticks[i] = (start - i) / step;
|
2501 | }
|
2502 |
|
2503 | if (reverse) ticks.reverse();
|
2504 |
|
2505 | return ticks;
|
2506 | }
|
2507 |
|
2508 | function tickIncrement(start, stop, count) {
|
2509 | var step = (stop - start) / Math.max(0, count),
|
2510 | power = Math.floor(Math.log(step) / Math.LN10),
|
2511 | error = step / Math.pow(10, power);
|
2512 | return power >= 0
|
2513 | ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)
|
2514 | : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);
|
2515 | }
|
2516 |
|
2517 | function tickStep(start, stop, count) {
|
2518 | var step0 = Math.abs(stop - start) / Math.max(0, count),
|
2519 | step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),
|
2520 | error = step0 / step1;
|
2521 | if (error >= e10) step1 *= 10;
|
2522 | else if (error >= e5) step1 *= 5;
|
2523 | else if (error >= e2) step1 *= 2;
|
2524 | return stop < start ? -step1 : step1;
|
2525 | }
|
2526 |
|
2527 | function define(constructor, factory, prototype) {
|
2528 | constructor.prototype = factory.prototype = prototype;
|
2529 | prototype.constructor = constructor;
|
2530 | }
|
2531 |
|
2532 | function extend(parent, definition) {
|
2533 | var prototype = Object.create(parent.prototype);
|
2534 | for (var key in definition) prototype[key] = definition[key];
|
2535 | return prototype;
|
2536 | }
|
2537 |
|
2538 | function Color() {}
|
2539 |
|
2540 | var darker = 0.7;
|
2541 | var brighter = 1 / darker;
|
2542 |
|
2543 | var reI = "\\s*([+-]?\\d+)\\s*",
|
2544 | reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*",
|
2545 | reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*",
|
2546 | reHex3 = /^#([0-9a-f]{3})$/,
|
2547 | reHex6 = /^#([0-9a-f]{6})$/,
|
2548 | reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"),
|
2549 | reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"),
|
2550 | reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"),
|
2551 | reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"),
|
2552 | reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"),
|
2553 | reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$");
|
2554 |
|
2555 | var named = {
|
2556 | aliceblue: 0xf0f8ff,
|
2557 | antiquewhite: 0xfaebd7,
|
2558 | aqua: 0x00ffff,
|
2559 | aquamarine: 0x7fffd4,
|
2560 | azure: 0xf0ffff,
|
2561 | beige: 0xf5f5dc,
|
2562 | bisque: 0xffe4c4,
|
2563 | black: 0x000000,
|
2564 | blanchedalmond: 0xffebcd,
|
2565 | blue: 0x0000ff,
|
2566 | blueviolet: 0x8a2be2,
|
2567 | brown: 0xa52a2a,
|
2568 | burlywood: 0xdeb887,
|
2569 | cadetblue: 0x5f9ea0,
|
2570 | chartreuse: 0x7fff00,
|
2571 | chocolate: 0xd2691e,
|
2572 | coral: 0xff7f50,
|
2573 | cornflowerblue: 0x6495ed,
|
2574 | cornsilk: 0xfff8dc,
|
2575 | crimson: 0xdc143c,
|
2576 | cyan: 0x00ffff,
|
2577 | darkblue: 0x00008b,
|
2578 | darkcyan: 0x008b8b,
|
2579 | darkgoldenrod: 0xb8860b,
|
2580 | darkgray: 0xa9a9a9,
|
2581 | darkgreen: 0x006400,
|
2582 | darkgrey: 0xa9a9a9,
|
2583 | darkkhaki: 0xbdb76b,
|
2584 | darkmagenta: 0x8b008b,
|
2585 | darkolivegreen: 0x556b2f,
|
2586 | darkorange: 0xff8c00,
|
2587 | darkorchid: 0x9932cc,
|
2588 | darkred: 0x8b0000,
|
2589 | darksalmon: 0xe9967a,
|
2590 | darkseagreen: 0x8fbc8f,
|
2591 | darkslateblue: 0x483d8b,
|
2592 | darkslategray: 0x2f4f4f,
|
2593 | darkslategrey: 0x2f4f4f,
|
2594 | darkturquoise: 0x00ced1,
|
2595 | darkviolet: 0x9400d3,
|
2596 | deeppink: 0xff1493,
|
2597 | deepskyblue: 0x00bfff,
|
2598 | dimgray: 0x696969,
|
2599 | dimgrey: 0x696969,
|
2600 | dodgerblue: 0x1e90ff,
|
2601 | firebrick: 0xb22222,
|
2602 | floralwhite: 0xfffaf0,
|
2603 | forestgreen: 0x228b22,
|
2604 | fuchsia: 0xff00ff,
|
2605 | gainsboro: 0xdcdcdc,
|
2606 | ghostwhite: 0xf8f8ff,
|
2607 | gold: 0xffd700,
|
2608 | goldenrod: 0xdaa520,
|
2609 | gray: 0x808080,
|
2610 | green: 0x008000,
|
2611 | greenyellow: 0xadff2f,
|
2612 | grey: 0x808080,
|
2613 | honeydew: 0xf0fff0,
|
2614 | hotpink: 0xff69b4,
|
2615 | indianred: 0xcd5c5c,
|
2616 | indigo: 0x4b0082,
|
2617 | ivory: 0xfffff0,
|
2618 | khaki: 0xf0e68c,
|
2619 | lavender: 0xe6e6fa,
|
2620 | lavenderblush: 0xfff0f5,
|
2621 | lawngreen: 0x7cfc00,
|
2622 | lemonchiffon: 0xfffacd,
|
2623 | lightblue: 0xadd8e6,
|
2624 | lightcoral: 0xf08080,
|
2625 | lightcyan: 0xe0ffff,
|
2626 | lightgoldenrodyellow: 0xfafad2,
|
2627 | lightgray: 0xd3d3d3,
|
2628 | lightgreen: 0x90ee90,
|
2629 | lightgrey: 0xd3d3d3,
|
2630 | lightpink: 0xffb6c1,
|
2631 | lightsalmon: 0xffa07a,
|
2632 | lightseagreen: 0x20b2aa,
|
2633 | lightskyblue: 0x87cefa,
|
2634 | lightslategray: 0x778899,
|
2635 | lightslategrey: 0x778899,
|
2636 | lightsteelblue: 0xb0c4de,
|
2637 | lightyellow: 0xffffe0,
|
2638 | lime: 0x00ff00,
|
2639 | limegreen: 0x32cd32,
|
2640 | linen: 0xfaf0e6,
|
2641 | magenta: 0xff00ff,
|
2642 | maroon: 0x800000,
|
2643 | mediumaquamarine: 0x66cdaa,
|
2644 | mediumblue: 0x0000cd,
|
2645 | mediumorchid: 0xba55d3,
|
2646 | mediumpurple: 0x9370db,
|
2647 | mediumseagreen: 0x3cb371,
|
2648 | mediumslateblue: 0x7b68ee,
|
2649 | mediumspringgreen: 0x00fa9a,
|
2650 | mediumturquoise: 0x48d1cc,
|
2651 | mediumvioletred: 0xc71585,
|
2652 | midnightblue: 0x191970,
|
2653 | mintcream: 0xf5fffa,
|
2654 | mistyrose: 0xffe4e1,
|
2655 | moccasin: 0xffe4b5,
|
2656 | navajowhite: 0xffdead,
|
2657 | navy: 0x000080,
|
2658 | oldlace: 0xfdf5e6,
|
2659 | olive: 0x808000,
|
2660 | olivedrab: 0x6b8e23,
|
2661 | orange: 0xffa500,
|
2662 | orangered: 0xff4500,
|
2663 | orchid: 0xda70d6,
|
2664 | palegoldenrod: 0xeee8aa,
|
2665 | palegreen: 0x98fb98,
|
2666 | paleturquoise: 0xafeeee,
|
2667 | palevioletred: 0xdb7093,
|
2668 | papayawhip: 0xffefd5,
|
2669 | peachpuff: 0xffdab9,
|
2670 | peru: 0xcd853f,
|
2671 | pink: 0xffc0cb,
|
2672 | plum: 0xdda0dd,
|
2673 | powderblue: 0xb0e0e6,
|
2674 | purple: 0x800080,
|
2675 | rebeccapurple: 0x663399,
|
2676 | red: 0xff0000,
|
2677 | rosybrown: 0xbc8f8f,
|
2678 | royalblue: 0x4169e1,
|
2679 | saddlebrown: 0x8b4513,
|
2680 | salmon: 0xfa8072,
|
2681 | sandybrown: 0xf4a460,
|
2682 | seagreen: 0x2e8b57,
|
2683 | seashell: 0xfff5ee,
|
2684 | sienna: 0xa0522d,
|
2685 | silver: 0xc0c0c0,
|
2686 | skyblue: 0x87ceeb,
|
2687 | slateblue: 0x6a5acd,
|
2688 | slategray: 0x708090,
|
2689 | slategrey: 0x708090,
|
2690 | snow: 0xfffafa,
|
2691 | springgreen: 0x00ff7f,
|
2692 | steelblue: 0x4682b4,
|
2693 | tan: 0xd2b48c,
|
2694 | teal: 0x008080,
|
2695 | thistle: 0xd8bfd8,
|
2696 | tomato: 0xff6347,
|
2697 | turquoise: 0x40e0d0,
|
2698 | violet: 0xee82ee,
|
2699 | wheat: 0xf5deb3,
|
2700 | white: 0xffffff,
|
2701 | whitesmoke: 0xf5f5f5,
|
2702 | yellow: 0xffff00,
|
2703 | yellowgreen: 0x9acd32
|
2704 | };
|
2705 |
|
2706 | define(Color, color, {
|
2707 | displayable: function() {
|
2708 | return this.rgb().displayable();
|
2709 | },
|
2710 | hex: function() {
|
2711 | return this.rgb().hex();
|
2712 | },
|
2713 | toString: function() {
|
2714 | return this.rgb() + "";
|
2715 | }
|
2716 | });
|
2717 |
|
2718 | function color(format) {
|
2719 | var m;
|
2720 | format = (format + "").trim().toLowerCase();
|
2721 | return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1))
|
2722 | : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16))
|
2723 | : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1)
|
2724 | : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1)
|
2725 | : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4])
|
2726 | : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4])
|
2727 | : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1)
|
2728 | : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4])
|
2729 | : named.hasOwnProperty(format) ? rgbn(named[format])
|
2730 | : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0)
|
2731 | : null;
|
2732 | }
|
2733 |
|
2734 | function rgbn(n) {
|
2735 | return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
|
2736 | }
|
2737 |
|
2738 | function rgba(r, g, b, a) {
|
2739 | if (a <= 0) r = g = b = NaN;
|
2740 | return new Rgb(r, g, b, a);
|
2741 | }
|
2742 |
|
2743 | function rgbConvert(o) {
|
2744 | if (!(o instanceof Color)) o = color(o);
|
2745 | if (!o) return new Rgb;
|
2746 | o = o.rgb();
|
2747 | return new Rgb(o.r, o.g, o.b, o.opacity);
|
2748 | }
|
2749 |
|
2750 | function rgb(r, g, b, opacity) {
|
2751 | return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
|
2752 | }
|
2753 |
|
2754 | function Rgb(r, g, b, opacity) {
|
2755 | this.r = +r;
|
2756 | this.g = +g;
|
2757 | this.b = +b;
|
2758 | this.opacity = +opacity;
|
2759 | }
|
2760 |
|
2761 | define(Rgb, rgb, extend(Color, {
|
2762 | brighter: function(k) {
|
2763 | k = k == null ? brighter : Math.pow(brighter, k);
|
2764 | return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
|
2765 | },
|
2766 | darker: function(k) {
|
2767 | k = k == null ? darker : Math.pow(darker, k);
|
2768 | return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
|
2769 | },
|
2770 | rgb: function() {
|
2771 | return this;
|
2772 | },
|
2773 | displayable: function() {
|
2774 | return (0 <= this.r && this.r <= 255)
|
2775 | && (0 <= this.g && this.g <= 255)
|
2776 | && (0 <= this.b && this.b <= 255)
|
2777 | && (0 <= this.opacity && this.opacity <= 1);
|
2778 | },
|
2779 | hex: function() {
|
2780 | return "#" + hex(this.r) + hex(this.g) + hex(this.b);
|
2781 | },
|
2782 | toString: function() {
|
2783 | var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
|
2784 | return (a === 1 ? "rgb(" : "rgba(")
|
2785 | + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
|
2786 | + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
|
2787 | + Math.max(0, Math.min(255, Math.round(this.b) || 0))
|
2788 | + (a === 1 ? ")" : ", " + a + ")");
|
2789 | }
|
2790 | }));
|
2791 |
|
2792 | function hex(value) {
|
2793 | value = Math.max(0, Math.min(255, Math.round(value) || 0));
|
2794 | return (value < 16 ? "0" : "") + value.toString(16);
|
2795 | }
|
2796 |
|
2797 | function hsla(h, s, l, a) {
|
2798 | if (a <= 0) h = s = l = NaN;
|
2799 | else if (l <= 0 || l >= 1) h = s = NaN;
|
2800 | else if (s <= 0) h = NaN;
|
2801 | return new Hsl(h, s, l, a);
|
2802 | }
|
2803 |
|
2804 | function hslConvert(o) {
|
2805 | if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
|
2806 | if (!(o instanceof Color)) o = color(o);
|
2807 | if (!o) return new Hsl;
|
2808 | if (o instanceof Hsl) return o;
|
2809 | o = o.rgb();
|
2810 | var r = o.r / 255,
|
2811 | g = o.g / 255,
|
2812 | b = o.b / 255,
|
2813 | min = Math.min(r, g, b),
|
2814 | max = Math.max(r, g, b),
|
2815 | h = NaN,
|
2816 | s = max - min,
|
2817 | l = (max + min) / 2;
|
2818 | if (s) {
|
2819 | if (r === max) h = (g - b) / s + (g < b) * 6;
|
2820 | else if (g === max) h = (b - r) / s + 2;
|
2821 | else h = (r - g) / s + 4;
|
2822 | s /= l < 0.5 ? max + min : 2 - max - min;
|
2823 | h *= 60;
|
2824 | } else {
|
2825 | s = l > 0 && l < 1 ? 0 : h;
|
2826 | }
|
2827 | return new Hsl(h, s, l, o.opacity);
|
2828 | }
|
2829 |
|
2830 | function hsl(h, s, l, opacity) {
|
2831 | return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
|
2832 | }
|
2833 |
|
2834 | function Hsl(h, s, l, opacity) {
|
2835 | this.h = +h;
|
2836 | this.s = +s;
|
2837 | this.l = +l;
|
2838 | this.opacity = +opacity;
|
2839 | }
|
2840 |
|
2841 | define(Hsl, hsl, extend(Color, {
|
2842 | brighter: function(k) {
|
2843 | k = k == null ? brighter : Math.pow(brighter, k);
|
2844 | return new Hsl(this.h, this.s, this.l * k, this.opacity);
|
2845 | },
|
2846 | darker: function(k) {
|
2847 | k = k == null ? darker : Math.pow(darker, k);
|
2848 | return new Hsl(this.h, this.s, this.l * k, this.opacity);
|
2849 | },
|
2850 | rgb: function() {
|
2851 | var h = this.h % 360 + (this.h < 0) * 360,
|
2852 | s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
|
2853 | l = this.l,
|
2854 | m2 = l + (l < 0.5 ? l : 1 - l) * s,
|
2855 | m1 = 2 * l - m2;
|
2856 | return new Rgb(
|
2857 | hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),
|
2858 | hsl2rgb(h, m1, m2),
|
2859 | hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
|
2860 | this.opacity
|
2861 | );
|
2862 | },
|
2863 | displayable: function() {
|
2864 | return (0 <= this.s && this.s <= 1 || isNaN(this.s))
|
2865 | && (0 <= this.l && this.l <= 1)
|
2866 | && (0 <= this.opacity && this.opacity <= 1);
|
2867 | }
|
2868 | }));
|
2869 |
|
2870 |
|
2871 | function hsl2rgb(h, m1, m2) {
|
2872 | return (h < 60 ? m1 + (m2 - m1) * h / 60
|
2873 | : h < 180 ? m2
|
2874 | : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60
|
2875 | : m1) * 255;
|
2876 | }
|
2877 |
|
2878 | var deg2rad = Math.PI / 180;
|
2879 | var rad2deg = 180 / Math.PI;
|
2880 |
|
2881 |
|
2882 | var K = 18,
|
2883 | Xn = 0.96422,
|
2884 | Yn = 1,
|
2885 | Zn = 0.82521,
|
2886 | t0$1 = 4 / 29,
|
2887 | t1$1 = 6 / 29,
|
2888 | t2 = 3 * t1$1 * t1$1,
|
2889 | t3 = t1$1 * t1$1 * t1$1;
|
2890 |
|
2891 | function labConvert(o) {
|
2892 | if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);
|
2893 | if (o instanceof Hcl) {
|
2894 | if (isNaN(o.h)) return new Lab(o.l, 0, 0, o.opacity);
|
2895 | var h = o.h * deg2rad;
|
2896 | return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);
|
2897 | }
|
2898 | if (!(o instanceof Rgb)) o = rgbConvert(o);
|
2899 | var r = rgb2lrgb(o.r),
|
2900 | g = rgb2lrgb(o.g),
|
2901 | b = rgb2lrgb(o.b),
|
2902 | y = xyz2lab((0.2225045 * r + 0.7168786 * g + 0.0606169 * b) / Yn), x, z;
|
2903 | if (r === g && g === b) x = z = y; else {
|
2904 | x = xyz2lab((0.4360747 * r + 0.3850649 * g + 0.1430804 * b) / Xn);
|
2905 | z = xyz2lab((0.0139322 * r + 0.0971045 * g + 0.7141733 * b) / Zn);
|
2906 | }
|
2907 | return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);
|
2908 | }
|
2909 |
|
2910 | function lab(l, a, b, opacity) {
|
2911 | return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);
|
2912 | }
|
2913 |
|
2914 | function Lab(l, a, b, opacity) {
|
2915 | this.l = +l;
|
2916 | this.a = +a;
|
2917 | this.b = +b;
|
2918 | this.opacity = +opacity;
|
2919 | }
|
2920 |
|
2921 | define(Lab, lab, extend(Color, {
|
2922 | brighter: function(k) {
|
2923 | return new Lab(this.l + K * (k == null ? 1 : k), this.a, this.b, this.opacity);
|
2924 | },
|
2925 | darker: function(k) {
|
2926 | return new Lab(this.l - K * (k == null ? 1 : k), this.a, this.b, this.opacity);
|
2927 | },
|
2928 | rgb: function() {
|
2929 | var y = (this.l + 16) / 116,
|
2930 | x = isNaN(this.a) ? y : y + this.a / 500,
|
2931 | z = isNaN(this.b) ? y : y - this.b / 200;
|
2932 | x = Xn * lab2xyz(x);
|
2933 | y = Yn * lab2xyz(y);
|
2934 | z = Zn * lab2xyz(z);
|
2935 | return new Rgb(
|
2936 | lrgb2rgb( 3.1338561 * x - 1.6168667 * y - 0.4906146 * z),
|
2937 | lrgb2rgb(-0.9787684 * x + 1.9161415 * y + 0.0334540 * z),
|
2938 | lrgb2rgb( 0.0719453 * x - 0.2289914 * y + 1.4052427 * z),
|
2939 | this.opacity
|
2940 | );
|
2941 | }
|
2942 | }));
|
2943 |
|
2944 | function xyz2lab(t) {
|
2945 | return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0$1;
|
2946 | }
|
2947 |
|
2948 | function lab2xyz(t) {
|
2949 | return t > t1$1 ? t * t * t : t2 * (t - t0$1);
|
2950 | }
|
2951 |
|
2952 | function lrgb2rgb(x) {
|
2953 | return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);
|
2954 | }
|
2955 |
|
2956 | function rgb2lrgb(x) {
|
2957 | return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
|
2958 | }
|
2959 |
|
2960 | function hclConvert(o) {
|
2961 | if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);
|
2962 | if (!(o instanceof Lab)) o = labConvert(o);
|
2963 | if (o.a === 0 && o.b === 0) return new Hcl(NaN, 0, o.l, o.opacity);
|
2964 | var h = Math.atan2(o.b, o.a) * rad2deg;
|
2965 | return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);
|
2966 | }
|
2967 |
|
2968 | function hcl(h, c, l, opacity) {
|
2969 | return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);
|
2970 | }
|
2971 |
|
2972 | function Hcl(h, c, l, opacity) {
|
2973 | this.h = +h;
|
2974 | this.c = +c;
|
2975 | this.l = +l;
|
2976 | this.opacity = +opacity;
|
2977 | }
|
2978 |
|
2979 | define(Hcl, hcl, extend(Color, {
|
2980 | brighter: function(k) {
|
2981 | return new Hcl(this.h, this.c, this.l + K * (k == null ? 1 : k), this.opacity);
|
2982 | },
|
2983 | darker: function(k) {
|
2984 | return new Hcl(this.h, this.c, this.l - K * (k == null ? 1 : k), this.opacity);
|
2985 | },
|
2986 | rgb: function() {
|
2987 | return labConvert(this).rgb();
|
2988 | }
|
2989 | }));
|
2990 |
|
2991 | var A = -0.14861,
|
2992 | B = +1.78277,
|
2993 | C = -0.29227,
|
2994 | D = -0.90649,
|
2995 | E = +1.97294,
|
2996 | ED = E * D,
|
2997 | EB = E * B,
|
2998 | BC_DA = B * C - D * A;
|
2999 |
|
3000 | function cubehelixConvert(o) {
|
3001 | if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);
|
3002 | if (!(o instanceof Rgb)) o = rgbConvert(o);
|
3003 | var r = o.r / 255,
|
3004 | g = o.g / 255,
|
3005 | b = o.b / 255,
|
3006 | l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),
|
3007 | bl = b - l,
|
3008 | k = (E * (g - l) - C * bl) / D,
|
3009 | s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)),
|
3010 | h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;
|
3011 | return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);
|
3012 | }
|
3013 |
|
3014 | function cubehelix(h, s, l, opacity) {
|
3015 | return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);
|
3016 | }
|
3017 |
|
3018 | function Cubehelix(h, s, l, opacity) {
|
3019 | this.h = +h;
|
3020 | this.s = +s;
|
3021 | this.l = +l;
|
3022 | this.opacity = +opacity;
|
3023 | }
|
3024 |
|
3025 | define(Cubehelix, cubehelix, extend(Color, {
|
3026 | brighter: function(k) {
|
3027 | k = k == null ? brighter : Math.pow(brighter, k);
|
3028 | return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
|
3029 | },
|
3030 | darker: function(k) {
|
3031 | k = k == null ? darker : Math.pow(darker, k);
|
3032 | return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
|
3033 | },
|
3034 | rgb: function() {
|
3035 | var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,
|
3036 | l = +this.l,
|
3037 | a = isNaN(this.s) ? 0 : this.s * l * (1 - l),
|
3038 | cosh = Math.cos(h),
|
3039 | sinh = Math.sin(h);
|
3040 | return new Rgb(
|
3041 | 255 * (l + a * (A * cosh + B * sinh)),
|
3042 | 255 * (l + a * (C * cosh + D * sinh)),
|
3043 | 255 * (l + a * (E * cosh)),
|
3044 | this.opacity
|
3045 | );
|
3046 | }
|
3047 | }));
|
3048 |
|
3049 | function constant$1(x) {
|
3050 | return function() {
|
3051 | return x;
|
3052 | };
|
3053 | }
|
3054 |
|
3055 | function linear(a, d) {
|
3056 | return function(t) {
|
3057 | return a + t * d;
|
3058 | };
|
3059 | }
|
3060 |
|
3061 | function exponential(a, b, y) {
|
3062 | return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
|
3063 | return Math.pow(a + t * b, y);
|
3064 | };
|
3065 | }
|
3066 |
|
3067 | function gamma(y) {
|
3068 | return (y = +y) === 1 ? nogamma : function(a, b) {
|
3069 | return b - a ? exponential(a, b, y) : constant$1(isNaN(a) ? b : a);
|
3070 | };
|
3071 | }
|
3072 |
|
3073 | function nogamma(a, b) {
|
3074 | var d = b - a;
|
3075 | return d ? linear(a, d) : constant$1(isNaN(a) ? b : a);
|
3076 | }
|
3077 |
|
3078 | var rgb$1 = (function rgbGamma(y) {
|
3079 | var color = gamma(y);
|
3080 |
|
3081 | function rgb$1(start, end) {
|
3082 | var r = color((start = rgb(start)).r, (end = rgb(end)).r),
|
3083 | g = color(start.g, end.g),
|
3084 | b = color(start.b, end.b),
|
3085 | opacity = nogamma(start.opacity, end.opacity);
|
3086 | return function(t) {
|
3087 | start.r = r(t);
|
3088 | start.g = g(t);
|
3089 | start.b = b(t);
|
3090 | start.opacity = opacity(t);
|
3091 | return start + "";
|
3092 | };
|
3093 | }
|
3094 |
|
3095 | rgb$1.gamma = rgbGamma;
|
3096 |
|
3097 | return rgb$1;
|
3098 | })(1);
|
3099 |
|
3100 | function array(a, b) {
|
3101 | var nb = b ? b.length : 0,
|
3102 | na = a ? Math.min(nb, a.length) : 0,
|
3103 | x = new Array(na),
|
3104 | c = new Array(nb),
|
3105 | i;
|
3106 |
|
3107 | for (i = 0; i < na; ++i) x[i] = interpolateValue(a[i], b[i]);
|
3108 | for (; i < nb; ++i) c[i] = b[i];
|
3109 |
|
3110 | return function(t) {
|
3111 | for (i = 0; i < na; ++i) c[i] = x[i](t);
|
3112 | return c;
|
3113 | };
|
3114 | }
|
3115 |
|
3116 | function date(a, b) {
|
3117 | var d = new Date;
|
3118 | return a = +a, b -= a, function(t) {
|
3119 | return d.setTime(a + b * t), d;
|
3120 | };
|
3121 | }
|
3122 |
|
3123 | function reinterpolate(a, b) {
|
3124 | return a = +a, b -= a, function(t) {
|
3125 | return a + b * t;
|
3126 | };
|
3127 | }
|
3128 |
|
3129 | function object(a, b) {
|
3130 | var i = {},
|
3131 | c = {},
|
3132 | k;
|
3133 |
|
3134 | if (a === null || typeof a !== "object") a = {};
|
3135 | if (b === null || typeof b !== "object") b = {};
|
3136 |
|
3137 | for (k in b) {
|
3138 | if (k in a) {
|
3139 | i[k] = interpolateValue(a[k], b[k]);
|
3140 | } else {
|
3141 | c[k] = b[k];
|
3142 | }
|
3143 | }
|
3144 |
|
3145 | return function(t) {
|
3146 | for (k in i) c[k] = i[k](t);
|
3147 | return c;
|
3148 | };
|
3149 | }
|
3150 |
|
3151 | var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,
|
3152 | reB = new RegExp(reA.source, "g");
|
3153 |
|
3154 | function zero(b) {
|
3155 | return function() {
|
3156 | return b;
|
3157 | };
|
3158 | }
|
3159 |
|
3160 | function one(b) {
|
3161 | return function(t) {
|
3162 | return b(t) + "";
|
3163 | };
|
3164 | }
|
3165 |
|
3166 | function string(a, b) {
|
3167 | var bi = reA.lastIndex = reB.lastIndex = 0,
|
3168 | am,
|
3169 | bm,
|
3170 | bs,
|
3171 | i = -1,
|
3172 | s = [],
|
3173 | q = [];
|
3174 |
|
3175 |
|
3176 | a = a + "", b = b + "";
|
3177 |
|
3178 |
|
3179 | while ((am = reA.exec(a))
|
3180 | && (bm = reB.exec(b))) {
|
3181 | if ((bs = bm.index) > bi) {
|
3182 | bs = b.slice(bi, bs);
|
3183 | if (s[i]) s[i] += bs;
|
3184 | else s[++i] = bs;
|
3185 | }
|
3186 | if ((am = am[0]) === (bm = bm[0])) {
|
3187 | if (s[i]) s[i] += bm;
|
3188 | else s[++i] = bm;
|
3189 | } else {
|
3190 | s[++i] = null;
|
3191 | q.push({i: i, x: reinterpolate(am, bm)});
|
3192 | }
|
3193 | bi = reB.lastIndex;
|
3194 | }
|
3195 |
|
3196 |
|
3197 | if (bi < b.length) {
|
3198 | bs = b.slice(bi);
|
3199 | if (s[i]) s[i] += bs;
|
3200 | else s[++i] = bs;
|
3201 | }
|
3202 |
|
3203 |
|
3204 |
|
3205 | return s.length < 2 ? (q[0]
|
3206 | ? one(q[0].x)
|
3207 | : zero(b))
|
3208 | : (b = q.length, function(t) {
|
3209 | for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
|
3210 | return s.join("");
|
3211 | });
|
3212 | }
|
3213 |
|
3214 | function interpolateValue(a, b) {
|
3215 | var t = typeof b, c;
|
3216 | return b == null || t === "boolean" ? constant$1(b)
|
3217 | : (t === "number" ? reinterpolate
|
3218 | : t === "string" ? ((c = color(b)) ? (b = c, rgb$1) : string)
|
3219 | : b instanceof color ? rgb$1
|
3220 | : b instanceof Date ? date
|
3221 | : Array.isArray(b) ? array
|
3222 | : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object
|
3223 | : reinterpolate)(a, b);
|
3224 | }
|
3225 |
|
3226 | function interpolateRound(a, b) {
|
3227 | return a = +a, b -= a, function(t) {
|
3228 | return Math.round(a + b * t);
|
3229 | };
|
3230 | }
|
3231 |
|
3232 | var array$1 = Array.prototype;
|
3233 |
|
3234 | var map = array$1.map;
|
3235 | var slice$1 = array$1.slice;
|
3236 |
|
3237 | function constant$2(x) {
|
3238 | return function() {
|
3239 | return x;
|
3240 | };
|
3241 | }
|
3242 |
|
3243 | function number$1(x) {
|
3244 | return +x;
|
3245 | }
|
3246 |
|
3247 | var unit = [0, 1];
|
3248 |
|
3249 | function deinterpolateLinear(a, b) {
|
3250 | return (b -= (a = +a))
|
3251 | ? function(x) { return (x - a) / b; }
|
3252 | : constant$2(b);
|
3253 | }
|
3254 |
|
3255 | function deinterpolateClamp(deinterpolate) {
|
3256 | return function(a, b) {
|
3257 | var d = deinterpolate(a = +a, b = +b);
|
3258 | return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); };
|
3259 | };
|
3260 | }
|
3261 |
|
3262 | function reinterpolateClamp(reinterpolate) {
|
3263 | return function(a, b) {
|
3264 | var r = reinterpolate(a = +a, b = +b);
|
3265 | return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); };
|
3266 | };
|
3267 | }
|
3268 |
|
3269 | function bimap(domain, range, deinterpolate, reinterpolate) {
|
3270 | var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];
|
3271 | if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0);
|
3272 | else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1);
|
3273 | return function(x) { return r0(d0(x)); };
|
3274 | }
|
3275 |
|
3276 | function polymap(domain, range, deinterpolate, reinterpolate) {
|
3277 | var j = Math.min(domain.length, range.length) - 1,
|
3278 | d = new Array(j),
|
3279 | r = new Array(j),
|
3280 | i = -1;
|
3281 |
|
3282 |
|
3283 | if (domain[j] < domain[0]) {
|
3284 | domain = domain.slice().reverse();
|
3285 | range = range.slice().reverse();
|
3286 | }
|
3287 |
|
3288 | while (++i < j) {
|
3289 | d[i] = deinterpolate(domain[i], domain[i + 1]);
|
3290 | r[i] = reinterpolate(range[i], range[i + 1]);
|
3291 | }
|
3292 |
|
3293 | return function(x) {
|
3294 | var i = bisectRight(domain, x, 1, j) - 1;
|
3295 | return r[i](d[i](x));
|
3296 | };
|
3297 | }
|
3298 |
|
3299 | function copy(source, target) {
|
3300 | return target
|
3301 | .domain(source.domain())
|
3302 | .range(source.range())
|
3303 | .interpolate(source.interpolate())
|
3304 | .clamp(source.clamp());
|
3305 | }
|
3306 |
|
3307 |
|
3308 |
|
3309 | function continuous(deinterpolate, reinterpolate) {
|
3310 | var domain = unit,
|
3311 | range = unit,
|
3312 | interpolate = interpolateValue,
|
3313 | clamp = false,
|
3314 | piecewise,
|
3315 | output,
|
3316 | input;
|
3317 |
|
3318 | function rescale() {
|
3319 | piecewise = Math.min(domain.length, range.length) > 2 ? polymap : bimap;
|
3320 | output = input = null;
|
3321 | return scale;
|
3322 | }
|
3323 |
|
3324 | function scale(x) {
|
3325 | return (output || (output = piecewise(domain, range, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate)))(+x);
|
3326 | }
|
3327 |
|
3328 | scale.invert = function(y) {
|
3329 | return (input || (input = piecewise(range, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y);
|
3330 | };
|
3331 |
|
3332 | scale.domain = function(_) {
|
3333 | return arguments.length ? (domain = map.call(_, number$1), rescale()) : domain.slice();
|
3334 | };
|
3335 |
|
3336 | scale.range = function(_) {
|
3337 | return arguments.length ? (range = slice$1.call(_), rescale()) : range.slice();
|
3338 | };
|
3339 |
|
3340 | scale.rangeRound = function(_) {
|
3341 | return range = slice$1.call(_), interpolate = interpolateRound, rescale();
|
3342 | };
|
3343 |
|
3344 | scale.clamp = function(_) {
|
3345 | return arguments.length ? (clamp = !!_, rescale()) : clamp;
|
3346 | };
|
3347 |
|
3348 | scale.interpolate = function(_) {
|
3349 | return arguments.length ? (interpolate = _, rescale()) : interpolate;
|
3350 | };
|
3351 |
|
3352 | return rescale();
|
3353 | }
|
3354 |
|
3355 |
|
3356 |
|
3357 |
|
3358 | function formatDecimal(x, p) {
|
3359 | if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null;
|
3360 | var i, coefficient = x.slice(0, i);
|
3361 |
|
3362 |
|
3363 |
|
3364 | return [
|
3365 | coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
|
3366 | +x.slice(i + 1)
|
3367 | ];
|
3368 | }
|
3369 |
|
3370 | function exponent(x) {
|
3371 | return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;
|
3372 | }
|
3373 |
|
3374 | function formatGroup(grouping, thousands) {
|
3375 | return function(value, width) {
|
3376 | var i = value.length,
|
3377 | t = [],
|
3378 | j = 0,
|
3379 | g = grouping[0],
|
3380 | length = 0;
|
3381 |
|
3382 | while (i > 0 && g > 0) {
|
3383 | if (length + g + 1 > width) g = Math.max(1, width - length);
|
3384 | t.push(value.substring(i -= g, i + g));
|
3385 | if ((length += g + 1) > width) break;
|
3386 | g = grouping[j = (j + 1) % grouping.length];
|
3387 | }
|
3388 |
|
3389 | return t.reverse().join(thousands);
|
3390 | };
|
3391 | }
|
3392 |
|
3393 | function formatNumerals(numerals) {
|
3394 | return function(value) {
|
3395 | return value.replace(/[0-9]/g, function(i) {
|
3396 | return numerals[+i];
|
3397 | });
|
3398 | };
|
3399 | }
|
3400 |
|
3401 |
|
3402 | var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;
|
3403 |
|
3404 | function formatSpecifier(specifier) {
|
3405 | return new FormatSpecifier(specifier);
|
3406 | }
|
3407 |
|
3408 | formatSpecifier.prototype = FormatSpecifier.prototype;
|
3409 |
|
3410 | function FormatSpecifier(specifier) {
|
3411 | if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
|
3412 | var match;
|
3413 | this.fill = match[1] || " ";
|
3414 | this.align = match[2] || ">";
|
3415 | this.sign = match[3] || "-";
|
3416 | this.symbol = match[4] || "";
|
3417 | this.zero = !!match[5];
|
3418 | this.width = match[6] && +match[6];
|
3419 | this.comma = !!match[7];
|
3420 | this.precision = match[8] && +match[8].slice(1);
|
3421 | this.trim = !!match[9];
|
3422 | this.type = match[10] || "";
|
3423 | }
|
3424 |
|
3425 | FormatSpecifier.prototype.toString = function() {
|
3426 | return this.fill
|
3427 | + this.align
|
3428 | + this.sign
|
3429 | + this.symbol
|
3430 | + (this.zero ? "0" : "")
|
3431 | + (this.width == null ? "" : Math.max(1, this.width | 0))
|
3432 | + (this.comma ? "," : "")
|
3433 | + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0))
|
3434 | + (this.trim ? "~" : "")
|
3435 | + this.type;
|
3436 | };
|
3437 |
|
3438 |
|
3439 | function formatTrim(s) {
|
3440 | out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) {
|
3441 | switch (s[i]) {
|
3442 | case ".": i0 = i1 = i; break;
|
3443 | case "0": if (i0 === 0) i0 = i; i1 = i; break;
|
3444 | default: if (i0 > 0) { if (!+s[i]) break out; i0 = 0; } break;
|
3445 | }
|
3446 | }
|
3447 | return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;
|
3448 | }
|
3449 |
|
3450 | var prefixExponent;
|
3451 |
|
3452 | function formatPrefixAuto(x, p) {
|
3453 | var d = formatDecimal(x, p);
|
3454 | if (!d) return x + "";
|
3455 | var coefficient = d[0],
|
3456 | exponent = d[1],
|
3457 | i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
|
3458 | n = coefficient.length;
|
3459 | return i === n ? coefficient
|
3460 | : i > n ? coefficient + new Array(i - n + 1).join("0")
|
3461 | : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i)
|
3462 | : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0];
|
3463 | }
|
3464 |
|
3465 | function formatRounded(x, p) {
|
3466 | var d = formatDecimal(x, p);
|
3467 | if (!d) return x + "";
|
3468 | var coefficient = d[0],
|
3469 | exponent = d[1];
|
3470 | return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient
|
3471 | : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1)
|
3472 | : coefficient + new Array(exponent - coefficient.length + 2).join("0");
|
3473 | }
|
3474 |
|
3475 | var formatTypes = {
|
3476 | "%": function(x, p) { return (x * 100).toFixed(p); },
|
3477 | "b": function(x) { return Math.round(x).toString(2); },
|
3478 | "c": function(x) { return x + ""; },
|
3479 | "d": function(x) { return Math.round(x).toString(10); },
|
3480 | "e": function(x, p) { return x.toExponential(p); },
|
3481 | "f": function(x, p) { return x.toFixed(p); },
|
3482 | "g": function(x, p) { return x.toPrecision(p); },
|
3483 | "o": function(x) { return Math.round(x).toString(8); },
|
3484 | "p": function(x, p) { return formatRounded(x * 100, p); },
|
3485 | "r": formatRounded,
|
3486 | "s": formatPrefixAuto,
|
3487 | "X": function(x) { return Math.round(x).toString(16).toUpperCase(); },
|
3488 | "x": function(x) { return Math.round(x).toString(16); }
|
3489 | };
|
3490 |
|
3491 | function identity$1(x) {
|
3492 | return x;
|
3493 | }
|
3494 |
|
3495 | var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];
|
3496 |
|
3497 | function formatLocale$1(locale) {
|
3498 | var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$1,
|
3499 | currency = locale.currency,
|
3500 | decimal = locale.decimal,
|
3501 | numerals = locale.numerals ? formatNumerals(locale.numerals) : identity$1,
|
3502 | percent = locale.percent || "%";
|
3503 |
|
3504 | function newFormat(specifier) {
|
3505 | specifier = formatSpecifier(specifier);
|
3506 |
|
3507 | var fill = specifier.fill,
|
3508 | align = specifier.align,
|
3509 | sign = specifier.sign,
|
3510 | symbol = specifier.symbol,
|
3511 | zero = specifier.zero,
|
3512 | width = specifier.width,
|
3513 | comma = specifier.comma,
|
3514 | precision = specifier.precision,
|
3515 | trim = specifier.trim,
|
3516 | type = specifier.type;
|
3517 |
|
3518 |
|
3519 | if (type === "n") comma = true, type = "g";
|
3520 |
|
3521 |
|
3522 | else if (!formatTypes[type]) precision == null && (precision = 12), trim = true, type = "g";
|
3523 |
|
3524 |
|
3525 | if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "=";
|
3526 |
|
3527 |
|
3528 |
|
3529 | var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
|
3530 | suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? percent : "";
|
3531 |
|
3532 |
|
3533 |
|
3534 |
|
3535 | var formatType = formatTypes[type],
|
3536 | maybeSuffix = /[defgprs%]/.test(type);
|
3537 |
|
3538 |
|
3539 |
|
3540 |
|
3541 |
|
3542 | precision = precision == null ? 6
|
3543 | : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))
|
3544 | : Math.max(0, Math.min(20, precision));
|
3545 |
|
3546 | function format(value) {
|
3547 | var valuePrefix = prefix,
|
3548 | valueSuffix = suffix,
|
3549 | i, n, c;
|
3550 |
|
3551 | if (type === "c") {
|
3552 | valueSuffix = formatType(value) + valueSuffix;
|
3553 | value = "";
|
3554 | } else {
|
3555 | value = +value;
|
3556 |
|
3557 |
|
3558 | var valueNegative = value < 0;
|
3559 | value = formatType(Math.abs(value), precision);
|
3560 |
|
3561 |
|
3562 | if (trim) value = formatTrim(value);
|
3563 |
|
3564 |
|
3565 | if (valueNegative && +value === 0) valueNegative = false;
|
3566 |
|
3567 |
|
3568 | valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
|
3569 | valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : "");
|
3570 |
|
3571 |
|
3572 |
|
3573 | if (maybeSuffix) {
|
3574 | i = -1, n = value.length;
|
3575 | while (++i < n) {
|
3576 | if (c = value.charCodeAt(i), 48 > c || c > 57) {
|
3577 | valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
|
3578 | value = value.slice(0, i);
|
3579 | break;
|
3580 | }
|
3581 | }
|
3582 | }
|
3583 | }
|
3584 |
|
3585 |
|
3586 | if (comma && !zero) value = group(value, Infinity);
|
3587 |
|
3588 |
|
3589 | var length = valuePrefix.length + value.length + valueSuffix.length,
|
3590 | padding = length < width ? new Array(width - length + 1).join(fill) : "";
|
3591 |
|
3592 |
|
3593 | if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
|
3594 |
|
3595 |
|
3596 | switch (align) {
|
3597 | case "<": value = valuePrefix + value + valueSuffix + padding; break;
|
3598 | case "=": value = valuePrefix + padding + value + valueSuffix; break;
|
3599 | case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;
|
3600 | default: value = padding + valuePrefix + value + valueSuffix; break;
|
3601 | }
|
3602 |
|
3603 | return numerals(value);
|
3604 | }
|
3605 |
|
3606 | format.toString = function() {
|
3607 | return specifier + "";
|
3608 | };
|
3609 |
|
3610 | return format;
|
3611 | }
|
3612 |
|
3613 | function formatPrefix(specifier, value) {
|
3614 | var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
|
3615 | e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,
|
3616 | k = Math.pow(10, -e),
|
3617 | prefix = prefixes[8 + e / 3];
|
3618 | return function(value) {
|
3619 | return f(k * value) + prefix;
|
3620 | };
|
3621 | }
|
3622 |
|
3623 | return {
|
3624 | format: newFormat,
|
3625 | formatPrefix: formatPrefix
|
3626 | };
|
3627 | }
|
3628 |
|
3629 | var locale$1;
|
3630 | var format;
|
3631 | var formatPrefix;
|
3632 |
|
3633 | defaultLocale$1({
|
3634 | decimal: ".",
|
3635 | thousands: ",",
|
3636 | grouping: [3],
|
3637 | currency: ["$", ""]
|
3638 | });
|
3639 |
|
3640 | function defaultLocale$1(definition) {
|
3641 | locale$1 = formatLocale$1(definition);
|
3642 | format = locale$1.format;
|
3643 | formatPrefix = locale$1.formatPrefix;
|
3644 | return locale$1;
|
3645 | }
|
3646 |
|
3647 | function precisionFixed(step) {
|
3648 | return Math.max(0, -exponent(Math.abs(step)));
|
3649 | }
|
3650 |
|
3651 | function precisionPrefix(step, value) {
|
3652 | return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step)));
|
3653 | }
|
3654 |
|
3655 | function precisionRound(step, max) {
|
3656 | step = Math.abs(step), max = Math.abs(max) - step;
|
3657 | return Math.max(0, exponent(max) - exponent(step)) + 1;
|
3658 | }
|
3659 |
|
3660 | function tickFormat(domain, count, specifier) {
|
3661 | var start = domain[0],
|
3662 | stop = domain[domain.length - 1],
|
3663 | step = tickStep(start, stop, count == null ? 10 : count),
|
3664 | precision;
|
3665 | specifier = formatSpecifier(specifier == null ? ",f" : specifier);
|
3666 | switch (specifier.type) {
|
3667 | case "s": {
|
3668 | var value = Math.max(Math.abs(start), Math.abs(stop));
|
3669 | if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
|
3670 | return formatPrefix(specifier, value);
|
3671 | }
|
3672 | case "":
|
3673 | case "e":
|
3674 | case "g":
|
3675 | case "p":
|
3676 | case "r": {
|
3677 | if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
|
3678 | break;
|
3679 | }
|
3680 | case "f":
|
3681 | case "%": {
|
3682 | if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
|
3683 | break;
|
3684 | }
|
3685 | }
|
3686 | return format(specifier);
|
3687 | }
|
3688 |
|
3689 | function linearish(scale) {
|
3690 | var domain = scale.domain;
|
3691 |
|
3692 | scale.ticks = function(count) {
|
3693 | var d = domain();
|
3694 | return ticks(d[0], d[d.length - 1], count == null ? 10 : count);
|
3695 | };
|
3696 |
|
3697 | scale.tickFormat = function(count, specifier) {
|
3698 | return tickFormat(domain(), count, specifier);
|
3699 | };
|
3700 |
|
3701 | scale.nice = function(count) {
|
3702 | if (count == null) count = 10;
|
3703 |
|
3704 | var d = domain(),
|
3705 | i0 = 0,
|
3706 | i1 = d.length - 1,
|
3707 | start = d[i0],
|
3708 | stop = d[i1],
|
3709 | step;
|
3710 |
|
3711 | if (stop < start) {
|
3712 | step = start, start = stop, stop = step;
|
3713 | step = i0, i0 = i1, i1 = step;
|
3714 | }
|
3715 |
|
3716 | step = tickIncrement(start, stop, count);
|
3717 |
|
3718 | if (step > 0) {
|
3719 | start = Math.floor(start / step) * step;
|
3720 | stop = Math.ceil(stop / step) * step;
|
3721 | step = tickIncrement(start, stop, count);
|
3722 | } else if (step < 0) {
|
3723 | start = Math.ceil(start * step) / step;
|
3724 | stop = Math.floor(stop * step) / step;
|
3725 | step = tickIncrement(start, stop, count);
|
3726 | }
|
3727 |
|
3728 | if (step > 0) {
|
3729 | d[i0] = Math.floor(start / step) * step;
|
3730 | d[i1] = Math.ceil(stop / step) * step;
|
3731 | domain(d);
|
3732 | } else if (step < 0) {
|
3733 | d[i0] = Math.ceil(start * step) / step;
|
3734 | d[i1] = Math.floor(stop * step) / step;
|
3735 | domain(d);
|
3736 | }
|
3737 |
|
3738 | return scale;
|
3739 | };
|
3740 |
|
3741 | return scale;
|
3742 | }
|
3743 |
|
3744 | function linear$1() {
|
3745 | var scale = continuous(deinterpolateLinear, reinterpolate);
|
3746 |
|
3747 | scale.copy = function() {
|
3748 | return copy(scale, linear$1());
|
3749 | };
|
3750 |
|
3751 | return linearish(scale);
|
3752 | }
|
3753 |
|
3754 | var VERSION = "1.3.2";
|
3755 |
|
3756 | function Slider(selector) {
|
3757 | this.container = select(selector);
|
3758 |
|
3759 | this._width = null;
|
3760 | this._height = null;
|
3761 |
|
3762 | this._handleRadius = 15;
|
3763 | this._channelHeight = 5;
|
3764 | this._channelRadius = null;
|
3765 |
|
3766 | this._handleFill = "black";
|
3767 | this._channelFill = "#eee";
|
3768 |
|
3769 | this._margin = { top: null, left: null, right: null };
|
3770 |
|
3771 | this._domain = [0, 1];
|
3772 | this._value = null;
|
3773 | this._snap = false;
|
3774 |
|
3775 | this._scale = null;
|
3776 | this._axis = false;
|
3777 | this._ticks = null;
|
3778 | this._tickFormat = null;
|
3779 | this._tickSize = null;
|
3780 |
|
3781 | this._label = null;
|
3782 | this._labelSize = 18;
|
3783 |
|
3784 | this._startLabel = null;
|
3785 | this._startLabelBelow = false;
|
3786 |
|
3787 | this._endLabel = null;
|
3788 | this._endLabelBelow = false;
|
3789 |
|
3790 | this._startEndLabelSize = 16;
|
3791 |
|
3792 | this.handlers = { "change": [] };
|
3793 | }
|
3794 |
|
3795 |
|
3796 | function accessor(k) {
|
3797 | if (k.length > 0 && k.charAt(0) == "_") {
|
3798 | Slider.prototype[k.substr(1)] = function(v) {
|
3799 | if (typeof v == "undefined") return this[k];
|
3800 | this[k] = v;
|
3801 | return this;
|
3802 | };
|
3803 | }
|
3804 | }
|
3805 | var s = new Slider();
|
3806 | for (var k in s) {
|
3807 | accessor(k);
|
3808 | }
|
3809 |
|
3810 |
|
3811 | Slider.prototype.margin = function Slider_margin(options) {
|
3812 | if (!options) return this._margin;
|
3813 | for (k in options) {
|
3814 | if (k in this._margin) this._margin[k] = options[k];
|
3815 | else throw "Slider.margin: unrecognised option " + k;
|
3816 | }
|
3817 | return this;
|
3818 | };
|
3819 |
|
3820 |
|
3821 | Slider.prototype.on = function Slider_on(event, handler) {
|
3822 | if (!(event in this.handlers)) throw "Slider.on: No such event: " + event;
|
3823 | this.handlers[event].push(handler);
|
3824 | return this;
|
3825 | };
|
3826 |
|
3827 |
|
3828 | Slider.prototype.fire = function Slider_fire(event, d) {
|
3829 | if (!(event in this.handlers)) throw "Slider.fire: No such event: " + event;
|
3830 | var handlers = this.handlers[event];
|
3831 | for (var i = 0; i < handlers.length; i++) {
|
3832 | handlers[i].call(this, d);
|
3833 | }
|
3834 | return this;
|
3835 | };
|
3836 |
|
3837 |
|
3838 | function closestValue(sorted_list, value, a, b) {
|
3839 | if (typeof a === "undefined") a = 0;
|
3840 | if (typeof b === "undefined") b = sorted_list.length;
|
3841 |
|
3842 | if (b-a == 0) return value;
|
3843 | if (b-a == 1) return sorted_list[a];
|
3844 | if (b-a == 2) {
|
3845 | var d1 = Math.abs(sorted_list[a] - value),
|
3846 | d2 = Math.abs(sorted_list[a+1] - value);
|
3847 | if (d1 <= d2) return sorted_list[a];
|
3848 | else return sorted_list[a+1];
|
3849 | }
|
3850 |
|
3851 | var mid = a + Math.floor((b-a) / 2),
|
3852 | mid_v = sorted_list[mid],
|
3853 | pre = mid - 1,
|
3854 | pre_v = sorted_list[pre];
|
3855 | if (pre_v <= value && value <= mid_v) {
|
3856 | return (Math.abs(pre_v - value) <= Math.abs(mid_v - value)) ? pre_v : mid_v;
|
3857 | }
|
3858 | if (mid_v <= value) return closestValue(sorted_list, value, mid, b);
|
3859 | else return closestValue(sorted_list, value, a, mid);
|
3860 | }
|
3861 |
|
3862 | function snapTo(specification, value) {
|
3863 | if (typeof specification == "boolean") {
|
3864 | return specification ? Math.round(value) : value;
|
3865 | }
|
3866 |
|
3867 | return closestValue(specification, value);
|
3868 | }
|
3869 |
|
3870 |
|
3871 | Slider.prototype.draw = function Slider_draw() {
|
3872 | var that = this;
|
3873 |
|
3874 | var cw = this._width,
|
3875 | ch = this._height;
|
3876 |
|
3877 | var container_node = this.container.node();
|
3878 |
|
3879 |
|
3880 |
|
3881 | if (!cw) {
|
3882 | var r = container_node.getBoundingClientRect();
|
3883 |
|
3884 |
|
3885 | if (!r || r.width == 0) return this;
|
3886 |
|
3887 | cw = r.width;
|
3888 | ch = r.height;
|
3889 | }
|
3890 |
|
3891 | var channel_r = this._channelRadius == null ? this._channelHeight/2 : this._channelRadius,
|
3892 | left_margin = (this._margin.left == null ? Math.max(this._handleRadius, channel_r) : this._margin.left),
|
3893 | right_margin = (this._margin.right == null ? Math.max(this._handleRadius, channel_r) : this._margin.right),
|
3894 | top_margin = this._margin.top == null ? Math.max(this._handleRadius, this._channelHeight/2) : this._margin.top,
|
3895 | w = cw - left_margin - right_margin,
|
3896 | channel_w = w + 2*channel_r,
|
3897 | label_h = this._labelSize * 1.5;
|
3898 |
|
3899 | if (this._label != null && this._margin.top == null) top_margin += label_h;
|
3900 |
|
3901 | var slider;
|
3902 | if (container_node.namespaceURI == "http://www.w3.org/2000/svg") {
|
3903 | slider = this.container;
|
3904 | }
|
3905 | else {
|
3906 | slider = this.container.selectAll("svg").data([{ width: cw, height: ch }]);
|
3907 | slider.exit().remove();
|
3908 | slider = slider.enter().append("svg").merge(slider);
|
3909 | slider.attr("width", function(d) { return d.width; })
|
3910 | .attr("height", function(d) { return d.height; });
|
3911 | }
|
3912 |
|
3913 | var g = slider.selectAll("g.slider-container").data([{left: left_margin, top: top_margin, id: this._id}]);
|
3914 | g.exit().remove();
|
3915 | g = g.enter().append("g").attr("class", "slider-container").merge(g);
|
3916 | g.attr("transform", function(d) {
|
3917 | return "translate(" + d.left + "," + d.top + ")";
|
3918 | })
|
3919 | .attr("id", function(d) { return d.id; });
|
3920 |
|
3921 | this.scale = (this._scale ? this._scale() : linear$1()).domain(this._domain).range([0, w]);
|
3922 |
|
3923 | if (this._value == null || this._value < this._domain[0]) this._value = this._domain[0];
|
3924 | else if (this._value > this._domain[1]) this._value = this._domain[1];
|
3925 |
|
3926 | if (this._snap) this._value = snapTo(this._snap, this._value);
|
3927 |
|
3928 | var axes_data = [];
|
3929 | if (this._axis) {
|
3930 | var axis;
|
3931 | if (typeof this._axis != "boolean") {
|
3932 | axis = this._axis(this.scale);
|
3933 | }
|
3934 | else {
|
3935 | axis = axisBottom().scale(this.scale).tickPadding(6);
|
3936 | }
|
3937 |
|
3938 | if (this._ticks) axis.ticks(this._ticks);
|
3939 | if (this._tickFormat) axis.tickFormat(this._tickFormat);
|
3940 | if (this._tickSize) axis.tickSize(this._tickSize);
|
3941 | else axis.tickSize(Math.max(5, this._handleRadius - this._channelHeight - 2));
|
3942 | axes_data.push(axis);
|
3943 | }
|
3944 |
|
3945 | var axes = g.selectAll(".slider-axis");
|
3946 | var axes_enter = axes.data(axes_data).enter();
|
3947 | axes_enter.append("g").attr("class", "slider-axis")
|
3948 | .attr("transform", "translate(" + 0 + "," + this._channelHeight/2 + ")")
|
3949 | .each(function(axis) { axis(select(this)); });
|
3950 | axes_enter.select(".domain").attr("fill", "none");
|
3951 | axes_enter.selectAll(".tick line").attr("stroke", "black");
|
3952 | axes_enter.exit().remove();
|
3953 |
|
3954 | var channel, handle;
|
3955 | channel = g.selectAll(".slider-channel")
|
3956 | .data([{ width: channel_w, height: this._channelHeight, channel_r: channel_r }]);
|
3957 | channel.exit().remove();
|
3958 |
|
3959 | channel = channel.enter().append("rect").attr("class", "slider-channel")
|
3960 | .attr("cursor", "pointer")
|
3961 | .on("click", function() {
|
3962 | var slider_x = Math.max(0, Math.min(w, d3_mouse(this)[0]));
|
3963 | that._value = that.scale.invert(slider_x);
|
3964 | if (that._snap) that._value = snapTo(that._snap, that._value);
|
3965 | handle.attr("cx", that.scale(that._value));
|
3966 | that.fire("change", that._value);
|
3967 | })
|
3968 | .merge(channel);
|
3969 |
|
3970 | channel.attr("width", function(d) { return d.width; })
|
3971 | .attr("fill", this._channelFill)
|
3972 | .attr("height", function(d) { return d.height; })
|
3973 | .attr("y", function(d) { return -d.height/2; })
|
3974 | .attr("x", function(d) { return -d.channel_r; })
|
3975 | .attr("rx", function(d) { return d.channel_r; });
|
3976 |
|
3977 | var drag_dx_origin, drag_x_origin;
|
3978 | function handleMousedown(event) {
|
3979 | document.addEventListener("mouseup", handleMouseup, false);
|
3980 | document.addEventListener("mousemove", handleMousemove, false);
|
3981 | drag_dx_origin = event.clientX;
|
3982 | drag_x_origin = that.scale(that._value);
|
3983 | }
|
3984 |
|
3985 | function handleMouseup() {
|
3986 | document.removeEventListener("mouseup", handleMouseup, false);
|
3987 | document.removeEventListener("mousemove", handleMousemove, false);
|
3988 | }
|
3989 |
|
3990 | function handleMousemove(event) {
|
3991 | drag(event.clientX - drag_dx_origin);
|
3992 | }
|
3993 |
|
3994 | function handleTouchstart(event) {
|
3995 | if (event.touches.length != 1) return;
|
3996 | document.addEventListener("touchend", handleTouchend, false);
|
3997 | document.addEventListener("touchmove", handleTouchmove, false);
|
3998 | drag_dx_origin = event.touches[0].clientX;
|
3999 | drag_x_origin = that.scale(that._value);
|
4000 | }
|
4001 |
|
4002 | function handleTouchend() {
|
4003 | document.removeEventListener("touchend", handleTouchend, false);
|
4004 | document.removeEventListener("touchmove", handleTouchmove, false);
|
4005 | }
|
4006 |
|
4007 | function handleTouchmove(event) {
|
4008 | if (event.touches.length != 1) return;
|
4009 | drag(event.touches[0].clientX - drag_dx_origin);
|
4010 | }
|
4011 |
|
4012 | function drag(dx) {
|
4013 | var new_x = drag_x_origin + dx;
|
4014 | var slider_x = Math.max(0, Math.min(w, new_x));
|
4015 | var new_value = that.scale.invert(slider_x);
|
4016 | if (that._snap) new_value = snapTo(that._snap, new_value);
|
4017 | handle.attr("cx", that.scale(new_value));
|
4018 | if (new_value != that._value) {
|
4019 | that._value = new_value;
|
4020 | that.fire("change", that._value);
|
4021 | }
|
4022 | }
|
4023 |
|
4024 | handle = g.selectAll(".slider-handle").data([{ v: this._value, x: this.scale(this._value) }]);
|
4025 | handle = handle.enter().append("circle").attr("class", "slider-handle")
|
4026 | .attr("cursor", "col-resize")
|
4027 | .merge(handle);
|
4028 |
|
4029 | handle.attr("cx", function(d) { return d.x; })
|
4030 | .attr("r", this._handleRadius)
|
4031 | .attr("fill", this._handleFill)
|
4032 | .on("mousedown", function() {
|
4033 | event$1.preventDefault();
|
4034 | handleMousedown(event$1);
|
4035 | })
|
4036 | .on("touchstart", function() {
|
4037 | event$1.preventDefault();
|
4038 | handleTouchstart(event$1);
|
4039 | });
|
4040 |
|
4041 | var label_data = [];
|
4042 | if (this._label) {
|
4043 | label_data.push({
|
4044 | label: this._label, x: w/2, y: -label_h, font_size: this._labelSize
|
4045 | });
|
4046 | }
|
4047 | var label = g.selectAll(".slider-label").data(label_data);
|
4048 | label.exit().remove();
|
4049 | label = label.enter()
|
4050 | .append("text").attr("class", "slider-label")
|
4051 | .attr("text-anchor", "middle")
|
4052 | .attr("cursor", "default")
|
4053 | .merge(label);
|
4054 |
|
4055 | label
|
4056 | .text(function(d) { return d.label; })
|
4057 | .attr("x", function(d) { return d.x; })
|
4058 | .attr("y", function(d) { return d.y; })
|
4059 | .attr("font-size", this._labelSize);
|
4060 |
|
4061 | var end_label_data = [];
|
4062 | if (this._startLabel) {
|
4063 | end_label_data.push({
|
4064 | label: this._startLabel,
|
4065 | x: this._startLabelBelow ? 0 : -(channel_r + 5 + Math.max(0, this._handleRadius - channel_r)),
|
4066 | y: this._startLabelBelow ? (channel_r + 15) : this._startEndLabelSize/1.75 - channel_r/2,
|
4067 | anchor: this._startLabelBelow ? "middle" : "end",
|
4068 | font_size: this._startEndLabelSize
|
4069 | });
|
4070 | }
|
4071 | if (this._endLabel) {
|
4072 | end_label_data.push({
|
4073 | label: this._endLabel,
|
4074 | x: this._endLabelBelow ? w : w + (channel_r + Math.max(0, this._handleRadius - channel_r) + 5),
|
4075 | y: this._startLabelBelow ? (channel_r + 15) : this._startEndLabelSize/1.75 - channel_r/2,
|
4076 | anchor: this._endLabelBelow ? "middle" : "start",
|
4077 | font_size: this._startEndLabelSize
|
4078 | });
|
4079 | }
|
4080 |
|
4081 | var end_labels = g.selectAll(".slider-end-labels").data(end_label_data);
|
4082 | end_labels.exit().remove();
|
4083 | end_labels = end_labels.enter().append("text").attr("class", "slider-end-labels")
|
4084 | .attr("pointer-events", "none")
|
4085 | .merge(end_labels);
|
4086 | end_labels
|
4087 | .text(function(d) { return d.label; })
|
4088 | .attr("font-size", function(d) { return d.font_size; })
|
4089 | .attr("x", function(d) { return d.x; })
|
4090 | .attr("y", function(d) { return d.y; })
|
4091 | .attr("text-anchor", function(d) { return d.anchor; });
|
4092 |
|
4093 | return this;
|
4094 | };
|
4095 |
|
4096 | Slider.prototype.update = Slider.prototype.draw;
|
4097 |
|
4098 | function Flourish_slider(selector) {
|
4099 | return new Slider(selector);
|
4100 | }
|
4101 | Flourish_slider.version = VERSION;
|
4102 |
|
4103 | function createPlayButton(colour) {
|
4104 | var start_string = '<svg width="25px" height="30px" viewBox="0 0 25 30"> <polygon fill="';
|
4105 | var end_string = '" stroke="none" points="25 15 0 30 0 0"></polygon> </svg>';
|
4106 | return start_string + colour + end_string;
|
4107 | }
|
4108 |
|
4109 | function createPauseButton(colour) {
|
4110 | var start_string = '<svg width="26px" height="30px" viewBox="0 0 26 30"> <g stroke="none" stroke-width="1" fill="';
|
4111 | var end_string = '"><rect x="2" y="2" width="9" height="26"></rect> <rect x="15" y="2" width="9" height="26"></rect> </g> </svg>';
|
4112 | return start_string + colour + end_string;
|
4113 | }
|
4114 |
|
4115 | function createSlider(control_obj, state, container) {
|
4116 | var slider_obj = {};
|
4117 | var slider_holder = select(container).append("div").attr("class", "fl-control fl-control-slider animatable");
|
4118 | var slider_play_button = slider_holder.append("div").attr("class", "slider-play");
|
4119 | var slider_div = slider_holder.append("div").attr("class", "fl-controls-slider");
|
4120 |
|
4121 | var play_string, pause_string, handle_color;
|
4122 | var sorted_options, timesteps, slider_label, is_playing;
|
4123 | var timer_id = null;
|
4124 |
|
4125 | var clearTimer = function() {
|
4126 | clearTimeout(timer_id);
|
4127 | timer_id = null;
|
4128 | };
|
4129 |
|
4130 | var sliderChangeFunction = function(i) {
|
4131 | var d = sorted_options[i];
|
4132 | if (d.options_index === control_obj.index()) return;
|
4133 | control_obj.index(d.options_index);
|
4134 | control_obj.trigger("change");
|
4135 | };
|
4136 |
|
4137 | var slider = Flourish_slider(slider_div.node())
|
4138 | .snap(true)
|
4139 | .on("change", function(i) {
|
4140 | var is_playing = timer_id !== null;
|
4141 | if (is_playing) clearTimer();
|
4142 | sliderChangeFunction(i);
|
4143 | if (is_playing) setNextTick();
|
4144 | });
|
4145 |
|
4146 |
|
4147 | var stopSliderPlayer = function() {
|
4148 | clearTimer();
|
4149 | slider_holder.classed("playing", false);
|
4150 | slider_play_button.html(play_string);
|
4151 | control_obj._isPlaying_(false);
|
4152 | is_playing = false;
|
4153 | };
|
4154 |
|
4155 |
|
4156 | var setNextTick = function() {
|
4157 | var current_index = control_obj.getSortedIndex();
|
4158 | var current_delay = timesteps[current_index];
|
4159 | var final_index = control_obj.n_options - 1;
|
4160 | var next_index = current_index < final_index ? current_index + 1 : 0;
|
4161 |
|
4162 | timer_id = setTimeout(function() {
|
4163 | sliderChangeFunction(next_index);
|
4164 | if (state.slider_loop || next_index < final_index) setNextTick();
|
4165 | else stopSliderPlayer();
|
4166 | }, current_delay);
|
4167 | };
|
4168 |
|
4169 |
|
4170 | var startSliderPlayer = function() {
|
4171 | slider_holder.classed("playing", true);
|
4172 | slider_play_button.html(pause_string);
|
4173 | setNextTick();
|
4174 | control_obj._isPlaying_(true);
|
4175 | is_playing = true;
|
4176 | };
|
4177 |
|
4178 |
|
4179 | slider_play_button.on("click", function() {
|
4180 | if (timer_id === null) startSliderPlayer();
|
4181 | else stopSliderPlayer();
|
4182 | });
|
4183 |
|
4184 |
|
4185 | var setWidths = function() {
|
4186 | var handle_radius = Math.round(remToPx(state.slider_handle_height) / 2);
|
4187 | slider_holder.style("width", Math.round(remToPx(state.slider_width)) + "px");
|
4188 | slider_play_button
|
4189 | .style("height", handle_radius * 2 + "px")
|
4190 | .style("width", handle_radius * 2 + "px")
|
4191 | .style("display", state.slider_play_button ? null : "none");
|
4192 | var holder_width = slider_holder.node().getBoundingClientRect().width;
|
4193 | var button_width = slider_play_button.node().getBoundingClientRect().width;
|
4194 | slider_div
|
4195 | .style("width", Math.max((holder_width - button_width), 1) + "px")
|
4196 | .style("height", handle_radius * 2 + "px");
|
4197 |
|
4198 | slider
|
4199 | .handleRadius(handle_radius)
|
4200 | .margin({
|
4201 | left: handle_radius + 5,
|
4202 | right: handle_radius + remToPx(state.slider_margin),
|
4203 | top: handle_radius
|
4204 | });
|
4205 | };
|
4206 |
|
4207 |
|
4208 | var setHandles = function() {
|
4209 | if (state.slider_play_button) {
|
4210 | slider_holder.classed("animatable", true);
|
4211 | }
|
4212 | else {
|
4213 | stopSliderPlayer();
|
4214 | slider_holder.classed("animatable", false);
|
4215 | }
|
4216 | if (handle_color !== state.slider_handle_color) {
|
4217 | slider.update();
|
4218 | handle_color = state.slider_handle_color || "currentColor";
|
4219 | slider_holder.select(".slider-handle").style("fill", handle_color);
|
4220 | play_string = createPlayButton(handle_color);
|
4221 | pause_string = createPauseButton(handle_color);
|
4222 | slider_play_button.html(timer_id ? pause_string : play_string);
|
4223 | }
|
4224 | };
|
4225 |
|
4226 |
|
4227 | var showControl = function() {
|
4228 | slider_holder.style("display", "inline-block");
|
4229 | setWidths();
|
4230 | setHandles();
|
4231 | return slider_obj;
|
4232 | };
|
4233 |
|
4234 | var hideControl = function() {
|
4235 | stopSliderPlayer();
|
4236 | slider_holder.style("display", "none");
|
4237 | return slider_obj;
|
4238 | };
|
4239 |
|
4240 | slider_obj.show = showControl;
|
4241 | slider_obj.hide = hideControl;
|
4242 |
|
4243 |
|
4244 | slider_obj.update = function(_sorted_options) {
|
4245 | sorted_options = _sorted_options;
|
4246 | if (!control_obj.n_options || state.control_type !== "slider") {
|
4247 | hideControl();
|
4248 | return slider_obj;
|
4249 | }
|
4250 |
|
4251 | showControl();
|
4252 |
|
4253 | var n_options = control_obj.n_options;
|
4254 | var loop = state.slider_loop;
|
4255 |
|
4256 | timesteps = sorted_options.map(function(d, i) {
|
4257 | var dur_in_seconds = state.slider_step_time + (loop && i === (n_options -1) ? state.slider_restart_pause : 0);
|
4258 | return dur_in_seconds * 1000;
|
4259 | });
|
4260 |
|
4261 | var sorted_index = control_obj.getSortedIndex();
|
4262 | var d = sorted_options[sorted_index];
|
4263 |
|
4264 | slider.domain([0, n_options - 1])
|
4265 | .value(sorted_index)
|
4266 | .endLabel(d.display)
|
4267 | .channelHeight(Math.round(remToPx(state.slider_track_height)))
|
4268 | .channelFill(state.slider_background_color)
|
4269 | .update();
|
4270 |
|
4271 | slider.container.select("svg").attr("fill", "currentColor");
|
4272 |
|
4273 | slider_label = slider_label || slider_div.select("text.slider-end-labels");
|
4274 | slider_label
|
4275 | .style("fill", state.slider_font_color)
|
4276 | .attr("y", "0")
|
4277 | .attr("dy", "0.25em");
|
4278 |
|
4279 |
|
4280 | if (control_obj._isPlaying_() && !is_playing) startSliderPlayer();
|
4281 | else if (!control_obj._isPlaying_() && is_playing) stopSliderPlayer();
|
4282 |
|
4283 | return slider_obj;
|
4284 | };
|
4285 |
|
4286 |
|
4287 | return slider_obj;
|
4288 | }
|
4289 |
|
4290 | var DEFAULTS = Object.freeze({
|
4291 | control_type: "dropdown",
|
4292 |
|
4293 |
|
4294 | dropdown_width_mode: "auto",
|
4295 | dropdown_width_fixed: 20,
|
4296 |
|
4297 |
|
4298 | button_group: true,
|
4299 | button_group_width_mode: "fixed",
|
4300 | button_group_width_fixed: 20,
|
4301 |
|
4302 |
|
4303 | slider_width: 15,
|
4304 | slider_handle_color: null,
|
4305 | slider_font_color: null,
|
4306 | slider_background_color: "#dddddd",
|
4307 |
|
4308 | slider_handle_height: 1,
|
4309 | slider_track_height: 0.2,
|
4310 | slider_margin: 4.5,
|
4311 |
|
4312 | slider_play_button: true,
|
4313 | slider_step_time: 2,
|
4314 | slider_loop: true,
|
4315 | slider_restart_pause: 0,
|
4316 |
|
4317 |
|
4318 | sort: "unsorted",
|
4319 | sort_temporal_format: "%Y",
|
4320 |
|
4321 | _index_: null,
|
4322 | _is_playing_: false
|
4323 | });
|
4324 |
|
4325 |
|
4326 | function init(state, getParser, getFormatter) {
|
4327 | var control_obj = {};
|
4328 | getParser = getParser || getDefaultParser;
|
4329 | getFormatter = getFormatter || getDefaultFormatter;
|
4330 | var options = [];
|
4331 | var sorted_options = [];
|
4332 | var changeHandlers = [];
|
4333 | var container = document.createElement("div");
|
4334 | container.setAttribute("class", "fl-controls-container");
|
4335 | var dropdown_obj = createDropdown(control_obj, state, container);
|
4336 | var buttons_obj = createButtons(control_obj, state, container);
|
4337 | var slider_obj = createSlider(control_obj, state, container);
|
4338 |
|
4339 | for (var key in DEFAULTS) {
|
4340 | if (state[key] === undefined) state[key] = DEFAULTS[key];
|
4341 | }
|
4342 |
|
4343 | var current_index = state._index_;
|
4344 |
|
4345 | var checkValidIndex = function(i) {
|
4346 | return options.length && i >= 0 && i < options.length;
|
4347 | };
|
4348 |
|
4349 | var updateControls = function(sorted_options) {
|
4350 | container.style.display = (sorted_options.length > 1) ? null : "none";
|
4351 | container.style.width = "";
|
4352 | slider_obj.update(sorted_options);
|
4353 | dropdown_obj.update(sorted_options);
|
4354 | buttons_obj.update(sorted_options);
|
4355 | };
|
4356 |
|
4357 | control_obj.appendTo = function(parent_container, bounding_container) {
|
4358 | injectCSS();
|
4359 | select(parent_container).node().appendChild(container);
|
4360 | dropdown_obj.appendedToDOM(bounding_container);
|
4361 | return control_obj;
|
4362 | };
|
4363 |
|
4364 | var callOnChangeCallbacks = function() {
|
4365 | var index = indexFunction();
|
4366 | var value = options[index];
|
4367 | changeHandlers.forEach(function(func) {
|
4368 | func(value, index);
|
4369 | });
|
4370 | return control_obj;
|
4371 | };
|
4372 |
|
4373 | control_obj.remove = function() {
|
4374 | if (container.parentElement) container.parentElement.removeChild(container);
|
4375 | dropdown_obj.removedFromDOM();
|
4376 |
|
4377 | return control_obj;
|
4378 | };
|
4379 |
|
4380 | control_obj.options = function(arr) {
|
4381 | if (arr === undefined) return options.slice();
|
4382 | if (!Array.isArray(arr)) return control_obj;
|
4383 | options = arr.slice();
|
4384 | var n = options.length;
|
4385 | var i = indexFunction();
|
4386 | if (!n) indexFunction(null);
|
4387 | else if (i === null || i >= n) indexFunction(0);
|
4388 | return control_obj;
|
4389 | };
|
4390 |
|
4391 | Object.defineProperty(control_obj, "n_options", { get: function() { return options.length; } });
|
4392 |
|
4393 |
|
4394 | var indexFunction = function(i) {
|
4395 | if (i === undefined) {
|
4396 | if (!state._is_playing_) current_index = state._index_;
|
4397 | return current_index;
|
4398 | }
|
4399 | if (i === null || checkValidIndex(i)) {
|
4400 | current_index = i;
|
4401 | if (!state._is_playing_) state._index_ = current_index;
|
4402 | }
|
4403 | else console.warn("Invalid index, ignoring update call");
|
4404 | return control_obj;
|
4405 | };
|
4406 | control_obj.index = indexFunction;
|
4407 |
|
4408 | control_obj.getSortedIndex = function() {
|
4409 | var options_index = indexFunction();
|
4410 | if (state.sort == "unsorted") return options_index;
|
4411 | var sorted_index;
|
4412 | sorted_options.some(function(d, i) {
|
4413 | if (d.options_index === options_index) {
|
4414 | sorted_index = i;
|
4415 | return true;
|
4416 | }
|
4417 | });
|
4418 | return sorted_index;
|
4419 | };
|
4420 |
|
4421 | control_obj.value = function(value) {
|
4422 | if (value === undefined) return options[indexFunction()];
|
4423 | var index = options.indexOf(value);
|
4424 | if (index !== -1) indexFunction(index);
|
4425 | return control_obj;
|
4426 | };
|
4427 |
|
4428 | control_obj.on = function(event, callback) {
|
4429 | if (event === "change") changeHandlers.push(callback.bind(control_obj));
|
4430 | return control_obj;
|
4431 | };
|
4432 |
|
4433 | control_obj.update = function() {
|
4434 | getRemToPx();
|
4435 | sorted_options = sortArray(options, state, getParser(), getFormatter());
|
4436 | updateControls(sorted_options);
|
4437 | return control_obj;
|
4438 | };
|
4439 |
|
4440 | control_obj.trigger = function(event) {
|
4441 | if (event === "change") callOnChangeCallbacks();
|
4442 | return control_obj;
|
4443 | };
|
4444 |
|
4445 | var isPlaying = function(is_playing) {
|
4446 | if (is_playing === undefined) return state._is_playing_;
|
4447 | state._is_playing_ = !!is_playing;
|
4448 | if (!is_playing) indexFunction(current_index);
|
4449 | };
|
4450 |
|
4451 | control_obj._isPlaying_ = isPlaying;
|
4452 |
|
4453 | return control_obj;
|
4454 | }
|
4455 |
|
4456 | return init;
|
4457 |
|
4458 | })));
|