@d3plus/core 3.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +6219 -0
  2. package/es/index.js +4 -0
  3. package/es/src/charts/AreaPlot.js +86 -0
  4. package/es/src/charts/BarChart.js +93 -0
  5. package/es/src/charts/BoxWhisker.js +97 -0
  6. package/es/src/charts/BumpChart.js +148 -0
  7. package/es/src/charts/Donut.js +84 -0
  8. package/es/src/charts/Geomap.js +833 -0
  9. package/es/src/charts/LinePlot.js +84 -0
  10. package/es/src/charts/Matrix.js +358 -0
  11. package/es/src/charts/Network.js +787 -0
  12. package/es/src/charts/Pack.js +318 -0
  13. package/es/src/charts/Pie.js +242 -0
  14. package/es/src/charts/Plot.js +2212 -0
  15. package/es/src/charts/Priestley.js +312 -0
  16. package/es/src/charts/Radar.js +365 -0
  17. package/es/src/charts/RadialMatrix.js +393 -0
  18. package/es/src/charts/Rings.js +777 -0
  19. package/es/src/charts/Sankey.js +413 -0
  20. package/es/src/charts/StackedArea.js +80 -0
  21. package/es/src/charts/Tree.js +312 -0
  22. package/es/src/charts/Treemap.js +406 -0
  23. package/es/src/charts/Viz.js +2017 -0
  24. package/es/src/charts/drawSteps/drawAttribution.js +14 -0
  25. package/es/src/charts/drawSteps/drawBack.js +23 -0
  26. package/es/src/charts/drawSteps/drawColorScale.js +69 -0
  27. package/es/src/charts/drawSteps/drawLegend.js +120 -0
  28. package/es/src/charts/drawSteps/drawSubtitle.js +31 -0
  29. package/es/src/charts/drawSteps/drawTimeline.js +80 -0
  30. package/es/src/charts/drawSteps/drawTitle.js +31 -0
  31. package/es/src/charts/drawSteps/drawTotal.js +32 -0
  32. package/es/src/charts/drawSteps/zoomControls.js +254 -0
  33. package/es/src/charts/events/click.legend.js +76 -0
  34. package/es/src/charts/events/click.shape.js +26 -0
  35. package/es/src/charts/events/mouseenter.js +31 -0
  36. package/es/src/charts/events/mouseleave.js +21 -0
  37. package/es/src/charts/events/mousemove.legend.js +64 -0
  38. package/es/src/charts/events/mousemove.shape.js +42 -0
  39. package/es/src/charts/events/touchstart.body.js +7 -0
  40. package/es/src/charts/helpers/matrixData.js +104 -0
  41. package/es/src/charts/helpers/tileAttributions.js +34 -0
  42. package/es/src/charts/index.js +21 -0
  43. package/es/src/charts/plotBuffers/Bar.js +65 -0
  44. package/es/src/charts/plotBuffers/Box.js +60 -0
  45. package/es/src/charts/plotBuffers/Circle.js +39 -0
  46. package/es/src/charts/plotBuffers/Line.js +30 -0
  47. package/es/src/charts/plotBuffers/Rect.js +40 -0
  48. package/es/src/charts/plotBuffers/discreteBuffer.js +24 -0
  49. package/es/src/charts/plotBuffers/numericBuffer.js +111 -0
  50. package/es/src/components/Axis.js +1567 -0
  51. package/es/src/components/AxisBottom.js +77 -0
  52. package/es/src/components/AxisLeft.js +77 -0
  53. package/es/src/components/AxisRight.js +77 -0
  54. package/es/src/components/AxisTop.js +77 -0
  55. package/es/src/components/ColorScale.js +958 -0
  56. package/es/src/components/Legend.js +673 -0
  57. package/es/src/components/Message.js +95 -0
  58. package/es/src/components/TextBox.js +752 -0
  59. package/es/src/components/Timeline.js +760 -0
  60. package/es/src/components/Tooltip.js +726 -0
  61. package/es/src/components/index.js +11 -0
  62. package/es/src/shapes/Area.js +361 -0
  63. package/es/src/shapes/Bar.js +342 -0
  64. package/es/src/shapes/Box.js +482 -0
  65. package/es/src/shapes/Circle.js +201 -0
  66. package/es/src/shapes/Image.js +255 -0
  67. package/es/src/shapes/Line.js +289 -0
  68. package/es/src/shapes/Path.js +186 -0
  69. package/es/src/shapes/Rect.js +215 -0
  70. package/es/src/shapes/Shape.js +1156 -0
  71. package/es/src/shapes/Whisker.js +330 -0
  72. package/es/src/shapes/index.js +10 -0
  73. package/es/src/utils/BaseClass.js +204 -0
  74. package/es/src/utils/RESET.js +4 -0
  75. package/es/src/utils/accessor.js +19 -0
  76. package/es/src/utils/configPrep.js +76 -0
  77. package/es/src/utils/constant.js +15 -0
  78. package/es/src/utils/getProp.js +9 -0
  79. package/es/src/utils/index.js +7 -0
  80. package/es/src/utils/uuid.js +13 -0
  81. package/package.json +68 -0
  82. package/umd/d3plus-core.full.js +56459 -0
  83. package/umd/d3plus-core.full.js.map +1 -0
  84. package/umd/d3plus-core.full.min.js +7241 -0
  85. package/umd/d3plus-core.js +14422 -0
  86. package/umd/d3plus-core.js.map +1 -0
  87. package/umd/d3plus-core.min.js +4564 -0
@@ -0,0 +1,760 @@
1
+ function _assert_this_initialized(self) {
2
+ if (self === void 0) {
3
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
4
+ }
5
+ return self;
6
+ }
7
+ function _call_super(_this, derived, args) {
8
+ derived = _get_prototype_of(derived);
9
+ return _possible_constructor_return(_this, _is_native_reflect_construct() ? Reflect.construct(derived, args || [], _get_prototype_of(_this).constructor) : derived.apply(_this, args));
10
+ }
11
+ function _class_call_check(instance, Constructor) {
12
+ if (!(instance instanceof Constructor)) {
13
+ throw new TypeError("Cannot call a class as a function");
14
+ }
15
+ }
16
+ function _defineProperties(target, props) {
17
+ for(var i = 0; i < props.length; i++){
18
+ var descriptor = props[i];
19
+ descriptor.enumerable = descriptor.enumerable || false;
20
+ descriptor.configurable = true;
21
+ if ("value" in descriptor) descriptor.writable = true;
22
+ Object.defineProperty(target, descriptor.key, descriptor);
23
+ }
24
+ }
25
+ function _create_class(Constructor, protoProps, staticProps) {
26
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
27
+ if (staticProps) _defineProperties(Constructor, staticProps);
28
+ return Constructor;
29
+ }
30
+ function _get(target, property, receiver) {
31
+ if (typeof Reflect !== "undefined" && Reflect.get) {
32
+ _get = Reflect.get;
33
+ } else {
34
+ _get = function get(target, property, receiver) {
35
+ var base = _super_prop_base(target, property);
36
+ if (!base) return;
37
+ var desc = Object.getOwnPropertyDescriptor(base, property);
38
+ if (desc.get) {
39
+ return desc.get.call(receiver || target);
40
+ }
41
+ return desc.value;
42
+ };
43
+ }
44
+ return _get(target, property, receiver || target);
45
+ }
46
+ function _get_prototype_of(o) {
47
+ _get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o) {
48
+ return o.__proto__ || Object.getPrototypeOf(o);
49
+ };
50
+ return _get_prototype_of(o);
51
+ }
52
+ function _inherits(subClass, superClass) {
53
+ if (typeof superClass !== "function" && superClass !== null) {
54
+ throw new TypeError("Super expression must either be null or a function");
55
+ }
56
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
57
+ constructor: {
58
+ value: subClass,
59
+ writable: true,
60
+ configurable: true
61
+ }
62
+ });
63
+ if (superClass) _set_prototype_of(subClass, superClass);
64
+ }
65
+ function _instanceof(left, right) {
66
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
67
+ return !!right[Symbol.hasInstance](left);
68
+ } else {
69
+ return left instanceof right;
70
+ }
71
+ }
72
+ function _possible_constructor_return(self, call) {
73
+ if (call && (_type_of(call) === "object" || typeof call === "function")) {
74
+ return call;
75
+ }
76
+ return _assert_this_initialized(self);
77
+ }
78
+ function _set_prototype_of(o, p) {
79
+ _set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o, p) {
80
+ o.__proto__ = p;
81
+ return o;
82
+ };
83
+ return _set_prototype_of(o, p);
84
+ }
85
+ function _super_prop_base(object, property) {
86
+ while(!Object.prototype.hasOwnProperty.call(object, property)){
87
+ object = _get_prototype_of(object);
88
+ if (object === null) break;
89
+ }
90
+ return object;
91
+ }
92
+ function _type_of(obj) {
93
+ "@swc/helpers - typeof";
94
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
95
+ }
96
+ function _is_native_reflect_construct() {
97
+ try {
98
+ var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
99
+ } catch (_) {}
100
+ return (_is_native_reflect_construct = function() {
101
+ return !!result;
102
+ })();
103
+ }
104
+ import { extent, max, min } from "d3-array";
105
+ import { brushX } from "d3-brush";
106
+ import { scaleTime } from "d3-scale";
107
+ import { pointers } from "d3-selection";
108
+ import { colorDefaults } from "@d3plus/color";
109
+ import { assign, attrize, date, elem, textWidth } from "@d3plus/dom";
110
+ import { formatDate } from "@d3plus/format";
111
+ import { locale } from "@d3plus/locales";
112
+ import { closest } from "@d3plus/math";
113
+ import { textWrap } from "@d3plus/text";
114
+ import { Axis, TextBox } from "../components/index.js";
115
+ import { constant } from "../utils/index.js";
116
+ var colorMid = "#bbb";
117
+ var Timeline = /*#__PURE__*/ function(Axis) {
118
+ "use strict";
119
+ _inherits(Timeline, Axis);
120
+ function Timeline() {
121
+ _class_call_check(this, Timeline);
122
+ var _this;
123
+ _this = _call_super(this, Timeline);
124
+ _this._barConfig = assign({}, _this._barConfig, {
125
+ stroke: function() {
126
+ return _this._buttonBehaviorCurrent === "buttons" ? "transparent" : colorMid;
127
+ },
128
+ "stroke-width": function() {
129
+ return _this._buttonBehaviorCurrent === "buttons" ? 0 : 1;
130
+ }
131
+ });
132
+ _this._brushing = true;
133
+ _this._brushFilter = function(event) {
134
+ return !event.button && event.detail < 2;
135
+ };
136
+ _this._brushMin = constant(1);
137
+ _this._buttonAlign = "middle";
138
+ _this._buttonBehavior = "auto";
139
+ _this._buttonPadding = 10;
140
+ _this._buttonHeight = 24;
141
+ _this._domain = [
142
+ 2001,
143
+ 2010
144
+ ];
145
+ _this._gridSize = 0;
146
+ _this._handleConfig = {
147
+ fill: colorDefaults.light,
148
+ stroke: "#228be6",
149
+ "stroke-width": 2,
150
+ rx: 2,
151
+ ry: 2
152
+ };
153
+ _this._handleSize = 6;
154
+ _this._height = 100;
155
+ _this._labelOffset = false;
156
+ _this._on = {};
157
+ _this.orient("bottom");
158
+ _this._playButton = true;
159
+ _this._playButtonClass = new TextBox().on("click", function() {
160
+ // if playing, pause
161
+ if (_this._playTimer) {
162
+ clearInterval(_this._playTimer);
163
+ _this._playTimer = false;
164
+ _this._playButtonClass.render();
165
+ } else {
166
+ var firstTime = true;
167
+ var nextYear = function() {
168
+ var selection = _this._selection || [
169
+ _this._domain[_this._domain.length - 1]
170
+ ];
171
+ if (!_instanceof(selection, Array)) selection = [
172
+ selection
173
+ ];
174
+ selection = selection.map(date).map(Number);
175
+ if (selection.length === 1) selection.push(selection[0]);
176
+ var ticks = _this._ticks.map(Number);
177
+ var firstIndex = ticks.indexOf(selection[0]);
178
+ var lastIndex = ticks.indexOf(selection[selection.length - 1]);
179
+ if (lastIndex === ticks.length - 1) {
180
+ if (!firstTime) {
181
+ clearInterval(_this._playTimer);
182
+ _this._playTimer = false;
183
+ _this._playButtonClass.render();
184
+ } else {
185
+ _this.selection([
186
+ _this._ticks[0],
187
+ _this._ticks[lastIndex - firstIndex]
188
+ ]).render();
189
+ }
190
+ } else {
191
+ if (lastIndex + 1 === ticks.length - 1) {
192
+ clearInterval(_this._playTimer);
193
+ _this._playTimer = false;
194
+ }
195
+ _this.selection([
196
+ _this._ticks[firstIndex + 1],
197
+ _this._ticks[lastIndex + 1]
198
+ ]).render();
199
+ }
200
+ firstTime = false;
201
+ };
202
+ _this._playTimer = setInterval(nextYear, _this._playButtonInterval);
203
+ nextYear();
204
+ }
205
+ }).on("mousemove", function() {
206
+ return _this._playButtonClass.select().style("cursor", "pointer");
207
+ });
208
+ _this._playButtonConfig = {
209
+ fontColor: colorDefaults.dark,
210
+ fontSize: 15,
211
+ text: function() {
212
+ return _this._playTimer ? "&#x23f8;&#xFE0E;" : "⏵";
213
+ },
214
+ textAnchor: "middle",
215
+ verticalAlign: "middle"
216
+ };
217
+ _this._playButtonInterval = 1000;
218
+ _this._selectionConfig = {
219
+ "fill": "#228be6",
220
+ "fill-opacity": function() {
221
+ return _this._buttonBehaviorCurrent === "buttons" ? 0.3 : 1;
222
+ },
223
+ "stroke-width": 0
224
+ };
225
+ _this._shape = "Rect";
226
+ _this._shapeConfig = assign({}, _this._shapeConfig, {
227
+ labelBounds: function(d) {
228
+ return _this._buttonBehaviorCurrent === "buttons" ? {
229
+ x: d.labelBounds.x,
230
+ y: -_this._buttonHeight / 2 + 1,
231
+ width: d.labelBounds.width,
232
+ height: _this._buttonHeight
233
+ } : d.labelBounds;
234
+ },
235
+ labelConfig: {
236
+ fontColor: colorDefaults.dark,
237
+ fontSize: function() {
238
+ return 12;
239
+ },
240
+ verticalAlign: function() {
241
+ return _this._buttonBehaviorCurrent === "buttons" ? "middle" : "top";
242
+ }
243
+ },
244
+ fill: function() {
245
+ return _this._buttonBehaviorCurrent === "buttons" ? "#fff" : colorMid;
246
+ },
247
+ stroke: function() {
248
+ return _this._buttonBehaviorCurrent === "buttons" ? colorMid : "transparent";
249
+ },
250
+ height: function(d) {
251
+ return _this._buttonBehaviorCurrent === "buttons" ? _this._buttonHeight : d.tick ? _this._handleSize : 0;
252
+ },
253
+ width: function(d) {
254
+ return _this._buttonBehaviorCurrent === "buttons" ? _this._ticksWidth / _this._availableTicks.length : d.tick ? _this._domain.map(Number).includes(d.id) ? 2 : 1 : 0;
255
+ },
256
+ y: function(d) {
257
+ return _this._buttonBehaviorCurrent === "buttons" ? _this._align === "middle" ? _this._height / 2 : _this._align === "start" ? _this._margin.top + _this._buttonHeight / 2 : _this._height - _this._buttonHeight / 2 - _this._margin.bottom : d.y;
258
+ },
259
+ rx: function(d) {
260
+ return _this._buttonBehaviorCurrent === "buttons" ? 0 : _this._domain.map(Number).includes(d.id) ? 1 : 0;
261
+ },
262
+ ry: function(d) {
263
+ return _this._buttonBehaviorCurrent === "buttons" ? 0 : _this._domain.map(Number).includes(d.id) ? 1 : 0;
264
+ }
265
+ });
266
+ _this._snapping = true;
267
+ return _this;
268
+ }
269
+ _create_class(Timeline, [
270
+ {
271
+ /**
272
+ @memberof Timeline
273
+ @desc Triggered on brush "brush".
274
+ @private
275
+ */ key: "_brushBrush",
276
+ value: function _brushBrush(event) {
277
+ if (event.sourceEvent && event.sourceEvent.offsetX && event.selection !== null && (!this._brushing || this._snapping)) {
278
+ clearInterval(this._playTimer);
279
+ this._playTimer = false;
280
+ this._playButtonClass.render();
281
+ var domain = this._updateDomain(event);
282
+ this._brushGroup.call(this._brush.move, this._updateBrushLimit(domain));
283
+ }
284
+ this._brushStyle();
285
+ if (this._on.brush) this._on.brush(this._selection);
286
+ }
287
+ },
288
+ {
289
+ /**
290
+ @memberof Timeline
291
+ @desc Triggered on brush "end".
292
+ @private
293
+ */ key: "_brushEnd",
294
+ value: function _brushEnd(event) {
295
+ if (!event.sourceEvent) return; // Only transition after input.
296
+ var domain = this._updateDomain(event);
297
+ this._brushStyle();
298
+ if (this._brushing || !this._snapping) this._brushGroup.transition(this._transition).call(this._brush.move, this._updateBrushLimit(domain));
299
+ if (this._on.end) this._on.end(this._selection);
300
+ }
301
+ },
302
+ {
303
+ /**
304
+ @memberof Timeline
305
+ @desc Triggered on brush "start".
306
+ @private
307
+ */ key: "_brushStart",
308
+ value: function _brushStart(event) {
309
+ if (event.sourceEvent !== null && (!this._brushing || this._snapping)) {
310
+ clearInterval(this._playTimer);
311
+ this._playTimer = false;
312
+ this._playButtonClass.render();
313
+ var domain = this._updateDomain(event);
314
+ this._brushGroup.call(this._brush.move, this._updateBrushLimit(domain));
315
+ }
316
+ this._brushStyle();
317
+ if (this._on.start) this._on.start(event);
318
+ }
319
+ },
320
+ {
321
+ /**
322
+ @memberof Timeline
323
+ @desc Overrides the default brush styles.
324
+ @private
325
+ */ key: "_brushStyle",
326
+ value: function _brushStyle() {
327
+ var _this = this;
328
+ var height = this._position.height;
329
+ var timelineHeight = this._shape === "Circle" ? typeof this._shapeConfig.r === "function" ? this._shapeConfig.r({
330
+ tick: true
331
+ }) * 2 : this._shapeConfig.r : this._shape === "Rect" ? typeof this._shapeConfig[height] === "function" ? this._shapeConfig[height]({
332
+ tick: true
333
+ }) : this._shapeConfig[height] : this._tickSize;
334
+ var brushSelection = this._brushGroup.selectAll(".selection").call(attrize, this._selectionConfig).attr("transform", "translate(0,-1)").attr("height", timelineHeight + 2);
335
+ var brushHandle = this._brushGroup.selectAll(".handle").call(attrize, this._handleConfig).attr("display", this._hiddenHandles ? "none" : "block").attr("transform", function(d) {
336
+ return _this._buttonBehaviorCurrent === "buttons" ? "translate(".concat(d.type === "w" ? -_this._handleSize / 2 : 0, ",-1)") : "";
337
+ }).attr("height", this._buttonBehaviorCurrent === "buttons" ? this._buttonHeight + 2 : timelineHeight + this._handleSize);
338
+ this._brushGroup.selectAll(".overlay").attr("x", this._paddingLeft).attr("cursor", "pointer").attr("transform", "translate(0,".concat(this._buttonBehaviorCurrent === "buttons" ? this._buttonHeight / 2 : -this._handleSize, ")")).attr("width", this._buttonBehaviorCurrent === "buttons" ? this._ticksWidth : this._width).attr("height", this._buttonBehaviorCurrent === "buttons" ? this._buttonHeight : this._handleSize * 2);
339
+ if (this._buttonBehaviorCurrent === "buttons") {
340
+ var yTransform = this._align === "middle" ? this._height / 2 - this._buttonHeight / 2 : this._align === "start" ? this._margin.top : this._height - this._buttonHeight - this._margin.bottom;
341
+ brushHandle.attr("y", yTransform);
342
+ brushSelection.attr("y", yTransform);
343
+ }
344
+ }
345
+ },
346
+ {
347
+ /**
348
+ @memberof Timeline
349
+ @desc Updates domain of the timeline used in brush functions.
350
+ @private
351
+ */ key: "_updateDomain",
352
+ value: function _updateDomain(event) {
353
+ var x = pointers(event, this._select.node());
354
+ var domain = event.selection && this._brushing || !x.length ? event.selection : [
355
+ x[0][0],
356
+ x[0][0]
357
+ ];
358
+ if (this._buttonBehaviorCurrent === "ticks") domain = domain.map(this._d3Scale.invert);
359
+ domain = domain.map(Number);
360
+ if (event.type === "brush" && this._brushing && this._buttonBehaviorCurrent === "buttons") {
361
+ var diffs = event.selection.map(function(d) {
362
+ return Math.abs(d - event.sourceEvent.offsetX);
363
+ });
364
+ domain = diffs[1] <= diffs[0] ? [
365
+ event.selection[0],
366
+ event.sourceEvent.offsetX
367
+ ].sort(function(a, b) {
368
+ return a - b;
369
+ }) : [
370
+ event.sourceEvent.offsetX,
371
+ event.selection[1]
372
+ ].sort(function(a, b) {
373
+ return a - b;
374
+ });
375
+ }
376
+ var ticks = this._buttonBehaviorCurrent === "ticks" ? this._availableTicks.map(Number) : this._d3Scale.range();
377
+ if (this._buttonBehaviorCurrent === "ticks") {
378
+ // find closest min and max ticks from data
379
+ // and their indices in the ticks Array
380
+ var minDomain = date(closest(domain[0], ticks));
381
+ var minIndex = ticks.indexOf(+minDomain);
382
+ var maxDomain = date(closest(domain[1], ticks));
383
+ var maxIndex = ticks.indexOf(+maxDomain);
384
+ // using the indices, determine if the 2 ends of the brush
385
+ // are too close to each other. "ticksApart" always needs to
386
+ // be less than the current current brushMin minus 1. For
387
+ // example, a brushMin of "2" means that the min and max domain
388
+ // values need to be "1" space apart from eachother.
389
+ var ticksApart = Math.abs(maxIndex - minIndex);
390
+ var minTicksAllowed = this._brushMin() - 1;
391
+ // if the min and max are not far enough apart to satisfy
392
+ // brushMin, then forcibly extend the domain.
393
+ if (ticksApart < minTicksAllowed) {
394
+ // push the maxDomain out as far as possible to account for brushMin
395
+ maxIndex = min([
396
+ ticks.length - 1,
397
+ maxIndex + (minTicksAllowed - ticksApart)
398
+ ]);
399
+ maxDomain = ticks[maxIndex];
400
+ ticksApart = Math.abs(maxIndex - minIndex);
401
+ // if the domain is still not far enough apart, extent the minDomain
402
+ // as far as possible to allow for brushMin
403
+ if (ticksApart < minTicksAllowed) {
404
+ minIndex = max([
405
+ 0,
406
+ minIndex - (minTicksAllowed - ticksApart)
407
+ ]);
408
+ minDomain = ticks[minIndex];
409
+ }
410
+ }
411
+ domain[0] = minDomain;
412
+ domain[1] = maxDomain;
413
+ } else {
414
+ domain[0] = closest(domain[0], ticks);
415
+ domain[1] = closest(domain[1], ticks);
416
+ }
417
+ // if the brush event has finished, update the current "selection" value
418
+ var single = +domain[0] === +domain[1];
419
+ if (event.type === "brush" || event.type === "end") {
420
+ this._selection = this._buttonBehaviorCurrent === "ticks" ? single ? domain[0] : domain : single ? date(this._availableTicks[ticks.indexOf(domain[0])]) : [
421
+ date(this._availableTicks[ticks.indexOf(domain[0])]),
422
+ date(this._availableTicks[ticks.indexOf(domain[1])])
423
+ ];
424
+ }
425
+ return domain;
426
+ }
427
+ },
428
+ {
429
+ /**
430
+ @memberof Timeline
431
+ @desc Updates limits of the brush.
432
+ @private
433
+ */ key: "_updateBrushLimit",
434
+ value: function _updateBrushLimit(domain) {
435
+ var selection = this._buttonBehaviorCurrent === "ticks" ? domain.map(date).map(this._d3Scale) : domain;
436
+ if (selection[0] === selection[1]) {
437
+ selection[0] -= 0.1;
438
+ selection[1] += 0.1;
439
+ }
440
+ if (this._buttonBehaviorCurrent === "buttons") {
441
+ var handleSize = this._hiddenHandles ? 0 : this._handleSize;
442
+ var buttonWidth = 0.5 * (this._ticksWidth / this._availableTicks.length - handleSize);
443
+ selection[0] -= buttonWidth;
444
+ selection[1] += buttonWidth;
445
+ }
446
+ return selection;
447
+ }
448
+ },
449
+ {
450
+ /**
451
+ @memberof Timeline
452
+ @desc Draws the timeline.
453
+ @param {Function} [*callback* = undefined]
454
+ @chainable
455
+ */ key: "render",
456
+ value: function render(callback) {
457
+ var _this = this;
458
+ var _this__position = this._position, height = _this__position.height, y = _this__position.y;
459
+ if (this._ticks) this._ticks = this._ticks.map(date);
460
+ if (this._data) this._data = this._data.map(date);
461
+ var ticks = this._ticks ? this._ticks : this._domain.map(date);
462
+ if (!this._ticks) {
463
+ var d3Scale = scaleTime().domain(ticks).range([
464
+ 0,
465
+ this._width
466
+ ]);
467
+ ticks = d3Scale.ticks();
468
+ }
469
+ var timeLocale = this._timeLocale || locale[this._locale] || locale["en-US"];
470
+ if (this._userFormat === undefined) this._userFormat = this._tickFormat || false;
471
+ var tickFormat = this._tickFormat = this._userFormat ? this._userFormat : function(d) {
472
+ return formatDate(d, ticks).replace(/^Q/g, timeLocale.quarter);
473
+ };
474
+ // Measures size of ticks
475
+ this._ticksWidth = this._width;
476
+ if ([
477
+ "auto",
478
+ "buttons"
479
+ ].includes(this._buttonBehavior)) {
480
+ var maxLabel = 0;
481
+ ticks.forEach(function(d, i) {
482
+ var _this__shapeConfig_labelConfig = _this._shapeConfig.labelConfig, fontFamily = _this__shapeConfig_labelConfig.fontFamily, fontSize = _this__shapeConfig_labelConfig.fontSize;
483
+ var f = typeof fontFamily === "function" ? fontFamily(d, i) : fontFamily, s = typeof fontSize === "function" ? fontSize(d, i) : fontSize;
484
+ var wrap = textWrap().fontFamily(f).fontSize(s).lineHeight(_this._shapeConfig.lineHeight ? _this._shapeConfig.lineHeight(d, i) : undefined);
485
+ var res = wrap(tickFormat(d));
486
+ var width = res.lines.length ? Math.ceil(max(res.lines.map(function(line) {
487
+ return textWidth(line, {
488
+ "font-family": f,
489
+ "font-size": s
490
+ });
491
+ }))) + s / 4 : 0;
492
+ if (width % 2) width++;
493
+ if (maxLabel < width) maxLabel = width + 2 * _this._buttonPadding;
494
+ });
495
+ this._ticksWidth = maxLabel * ticks.length;
496
+ }
497
+ var playButtonWidth = this._playButton ? this._buttonHeight : 0;
498
+ var space = this._width - playButtonWidth;
499
+ this._buttonBehaviorCurrent = this._buttonBehavior === "auto" ? this._ticksWidth < space ? "buttons" : "ticks" : this._buttonBehavior;
500
+ var hiddenHandles = this._hiddenHandles = this._buttonBehaviorCurrent === "buttons" && !this._brushing;
501
+ if (this._buttonBehaviorCurrent === "buttons") {
502
+ this._scale = "ordinal";
503
+ var domain = scaleTime().domain(this._domain.map(date)).ticks().map(Number);
504
+ this._domain = this._ticks ? this._ticks : Array.from(Array(domain[domain.length - 1] - domain[0] + 1), function(_, x) {
505
+ return domain[0] + x;
506
+ }).map(date);
507
+ this._ticks = this._domain;
508
+ var buttonMargin = 0.5 * this._ticksWidth / this._ticks.length;
509
+ var emptySpace = this._width - this._ticksWidth - playButtonWidth;
510
+ this._paddingLeft = this._buttonAlign === "middle" ? emptySpace / 2 + playButtonWidth : this._buttonAlign === "end" ? emptySpace + playButtonWidth : playButtonWidth;
511
+ this._range = [
512
+ this._paddingLeft + buttonMargin,
513
+ this._paddingLeft + this._ticksWidth - buttonMargin
514
+ ];
515
+ } else {
516
+ this._scale = "time";
517
+ this._domain = extent(ticks);
518
+ this._range = [
519
+ playButtonWidth ? playButtonWidth * 1.5 : undefined,
520
+ undefined
521
+ ];
522
+ this._paddingLeft = playButtonWidth;
523
+ }
524
+ _get(_get_prototype_of(Timeline.prototype), "render", this).call(this, callback);
525
+ var offset = this._outerBounds[y], range = this._d3Scale.range();
526
+ var brush = this._brush = brushX().extent([
527
+ [
528
+ range[0],
529
+ offset
530
+ ],
531
+ [
532
+ range[range.length - 1],
533
+ offset + this._outerBounds[height]
534
+ ]
535
+ ]).filter(this._brushFilter).handleSize(hiddenHandles ? 0 : this._handleSize).on("start", this._brushStart.bind(this)).on("brush", this._brushBrush.bind(this)).on("end", this._brushEnd.bind(this));
536
+ // data Array to be used when detecting the default value
537
+ var defaultData = this._buttonBehaviorCurrent === "ticks" ? this._availableTicks : range;
538
+ // the default selection, if needed
539
+ var defaultSelection = [
540
+ this._brushMin() > defaultData.length ? defaultData[0] : defaultData[defaultData.length - this._brushMin()],
541
+ defaultData[defaultData.length - 1]
542
+ ];
543
+ // the current selection, considering user input, defaults, and data
544
+ var selection = this._selection === void 0 ? defaultSelection : _instanceof(this._selection, Array) ? this._buttonBehaviorCurrent === "buttons" ? this._selection.map(date).map(function(d) {
545
+ return range[_this._ticks.map(Number).indexOf(+d)];
546
+ }) : this._selection.map(date) : this._buttonBehaviorCurrent === "buttons" ? [
547
+ range[this._ticks.map(Number).indexOf(+this._selection)]
548
+ ] : [
549
+ this._selection
550
+ ];
551
+ if (selection.length === 1) selection.push(selection[0]);
552
+ this._updateBrushLimit(selection);
553
+ this._brushGroup = elem("g.brushGroup", {
554
+ parent: this._group
555
+ });
556
+ this._brushGroup.call(brush).transition(this._transition).call(brush.move, this._buttonBehaviorCurrent === "ticks" ? this._updateBrushLimit(selection) : selection);
557
+ this._outerBounds.y -= this._handleSize / 2;
558
+ this._outerBounds.height += this._handleSize / 2;
559
+ var playButtonGroup = elem("g.d3plus-Timeline-play", {
560
+ parent: this._group
561
+ });
562
+ this._playButtonClass.data(this._playButton ? [
563
+ {
564
+ x: this._paddingLeft - playButtonWidth,
565
+ y: this._buttonBehaviorCurrent === "buttons" ? this._align === "middle" ? this._height / 2 - this._buttonHeight / 2 : this._align === "start" ? this._margin.top : this._height - this._buttonHeight - this._margin.bottom : this._outerBounds.y,
566
+ width: playButtonWidth,
567
+ height: playButtonWidth
568
+ }
569
+ ] : []).select(playButtonGroup.node()).config(this._playButtonConfig).render();
570
+ return this;
571
+ }
572
+ },
573
+ {
574
+ /**
575
+ @memberof Timeline
576
+ @desc If *value* is specified, sets the button padding and returns the current class instance. If *value* is not specified, returns the current button padding.
577
+ @param {Number} [*value* = 10]
578
+ @chainable
579
+ */ key: "buttonPadding",
580
+ value: function buttonPadding(_) {
581
+ return arguments.length ? (this._buttonPadding = _, this) : this._buttonPadding;
582
+ }
583
+ },
584
+ {
585
+ /**
586
+ @memberof Timeline
587
+ @desc If *value* is specified, toggles the brushing value and returns the current class instance. If *value* is not specified, returns the current brushing value.
588
+ @param {Boolean} [*value* = true]
589
+ @chainable
590
+ */ key: "brushing",
591
+ value: function brushing(_) {
592
+ return arguments.length ? (this._brushing = _, this) : this._brushing;
593
+ }
594
+ },
595
+ {
596
+ /**
597
+ @memberof Timeline
598
+ @desc If *value* is specified, sets the brush event filter and returns the current class instance. If *value* is not specified, returns the current brush event filter.
599
+ @param {Function} [*value*]
600
+ @chainable
601
+ @example
602
+ function() {
603
+ return !event.button && event.detail < 2;
604
+ }
605
+ */ key: "brushFilter",
606
+ value: function brushFilter(_) {
607
+ return arguments.length ? (this._brushFilter = _, this) : this._brushFilter;
608
+ }
609
+ },
610
+ {
611
+ /**
612
+ @memberof Timeline
613
+ @desc Sets the minimum number of "ticks" to allow to be highlighted when using "ticks" buttonBehavior. Helpful when using x/y plots where you don't want the user to select less than 2 time periods. Value passed can either be a static Number, or a function that is expected to return a Number.
614
+ @param {Number|Function} [*value* = 1]
615
+ @chainable
616
+ */ key: "brushMin",
617
+ value: function brushMin(_) {
618
+ return arguments.length ? (this._brushMin = typeof _ === "function" ? _ : constant(_), this) : this._brushMin;
619
+ }
620
+ },
621
+ {
622
+ /**
623
+ @memberof Timeline
624
+ @desc If *value* is specified, toggles the horizontal alignment of the button timeline. Accepted values are `"start"`, `"middle"` and `"end"`. If *value* is not specified, returns the current button value.
625
+ @param {String} [*value* = "middle"]
626
+ @chainable
627
+ */ key: "buttonAlign",
628
+ value: function buttonAlign(_) {
629
+ return arguments.length ? (this._buttonAlign = _, this) : this._buttonAlign;
630
+ }
631
+ },
632
+ {
633
+ /**
634
+ @memberof Timeline
635
+ @desc If *value* is specified, toggles the style of the timeline. Accepted values are `"auto"`, `"buttons"` and `"ticks"`. If *value* is not specified, returns the current button value.
636
+ @param {String} [*value* = "auto"]
637
+ @chainable
638
+ */ key: "buttonBehavior",
639
+ value: function buttonBehavior(_) {
640
+ return arguments.length ? (this._buttonBehavior = _, this) : this._buttonBehavior;
641
+ }
642
+ },
643
+ {
644
+ /**
645
+ @memberof Timeline
646
+ @desc If *value* is specified, sets the button height and returns the current class instance. If *value* is not specified, returns the current button height.
647
+ @param {Number} [*value* = 30]
648
+ @chainable
649
+ */ key: "buttonHeight",
650
+ value: function buttonHeight(_) {
651
+ return arguments.length ? (this._buttonHeight = _, this) : this._buttonHeight;
652
+ }
653
+ },
654
+ {
655
+ /**
656
+ @memberof Timeline
657
+ @desc If *value* is specified, sets the handle style and returns the current class instance. If *value* is not specified, returns the current handle style.
658
+ @param {Object} [*value*]
659
+ @chainable
660
+ */ key: "handleConfig",
661
+ value: function handleConfig(_) {
662
+ return arguments.length ? (this._handleConfig = assign(this._handleConfig, _), this) : this._handleConfig;
663
+ }
664
+ },
665
+ {
666
+ /**
667
+ @memberof Timeline
668
+ @desc If *value* is specified, sets the handle size and returns the current class instance. If *value* is not specified, returns the current handle size.
669
+ @param {Number} [*value* = 6]
670
+ @chainable
671
+ */ key: "handleSize",
672
+ value: function handleSize(_) {
673
+ return arguments.length ? (this._handleSize = _, this) : this._handleSize;
674
+ }
675
+ },
676
+ {
677
+ /**
678
+ @memberof Timeline
679
+ @desc Adds or removes a *listener* for the specified brush event *typename*. If a *listener* is not specified, returns the currently-assigned listener for the specified event *typename*. Mirrors the core [d3-brush](https://github.com/d3/d3-brush#brush_on) behavior.
680
+ @param {String|Object} [*typename*]
681
+ @param {Function} [*listener*]
682
+ @chainable
683
+ */ key: "on",
684
+ value: function on(_, f) {
685
+ return arguments.length === 2 ? (this._on[_] = f, this) : arguments.length ? typeof _ === "string" ? this._on[_] : (this._on = assign({}, this._on, _), this) : this._on;
686
+ }
687
+ },
688
+ {
689
+ /**
690
+ @memberof Timeline
691
+ @desc Determines the visibility of the play button to the left the of timeline, which will cycle through the available periods at a rate defined by the playButtonInterval method.
692
+ @param {Boolean} [*value* = true]
693
+ @chainable
694
+ */ key: "playButton",
695
+ value: function playButton(_) {
696
+ return arguments.length ? (this._playButton = _, this) : this._playButton;
697
+ }
698
+ },
699
+ {
700
+ /**
701
+ @memberof Timeline
702
+ @desc The config Object for the Rect class used to create the playButton.
703
+ @param {Object} [*value*]
704
+ @chainable
705
+ */ key: "playButtonConfig",
706
+ value: function playButtonConfig(_) {
707
+ return arguments.length ? (this._playButtonConfig = assign(this._playButtonConfig, _), this) : this._playButtonConfig;
708
+ }
709
+ },
710
+ {
711
+ /**
712
+ @memberof Timeline
713
+ @desc The value, in milliseconds, to use when cycling through the available time periods when the user clicks the playButton.
714
+ @param {Number} [*value* = 1000]
715
+ @chainable
716
+ */ key: "playButtonInterval",
717
+ value: function playButtonInterval(_) {
718
+ return arguments.length ? (this._playButtonInterval = _, this) : this._playButtonInterval;
719
+ }
720
+ },
721
+ {
722
+ /**
723
+ @memberof Timeline
724
+ @desc If *value* is specified, sets the selection style and returns the current class instance. If *value* is not specified, returns the current selection style.
725
+ @param {Object} [*value*]
726
+ @chainable
727
+ */ key: "selectionConfig",
728
+ value: function selectionConfig(_) {
729
+ return arguments.length ? (this._selectionConfig = assign(this._selectionConfig, _), this) : this._selectionConfig;
730
+ }
731
+ },
732
+ {
733
+ /**
734
+ @memberof Timeline
735
+ @desc If *value* is specified, sets the selection and returns the current class instance. If *value* is not specified, returns the current selection. Defaults to the most recent year in the timeline.
736
+ @param {Array|Date|Number|String} [*value*]
737
+ @chainable
738
+ */ key: "selection",
739
+ value: function selection(_) {
740
+ return arguments.length ? (this._selection = _, this) : this._selection;
741
+ }
742
+ },
743
+ {
744
+ /**
745
+ @memberof Timeline
746
+ @desc If *value* is specified, toggles the snapping value and returns the current class instance. If *value* is not specified, returns the current snapping value.
747
+ @param {Boolean} [*value* = true]
748
+ @chainable
749
+ */ key: "snapping",
750
+ value: function snapping(_) {
751
+ return arguments.length ? (this._snapping = _, this) : this._snapping;
752
+ }
753
+ }
754
+ ]);
755
+ return Timeline;
756
+ }(Axis);
757
+ /**
758
+ @class Timeline
759
+ @extends Axis
760
+ */ export { Timeline as default };