@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,787 @@
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, mean, min, merge } from "d3-array";
105
+ import { nest } from "d3-collection";
106
+ import { forceLink, forceManyBody, forceSimulation } from "d3-force";
107
+ import { polygonHull } from "d3-polygon";
108
+ import * as scales from "d3-scale";
109
+ import { zoomTransform } from "d3-zoom";
110
+ import { assign, elem } from "@d3plus/dom";
111
+ import { addToQueue } from "@d3plus/data";
112
+ import * as shapes from "../shapes/index.js";
113
+ import { accessor, configPrep, constant } from "../utils/index.js";
114
+ import Viz from "./Viz";
115
+ /**
116
+ * Fetches the unique ID for a data point, whether it's defined by data or nodes.
117
+ * @private
118
+ */ function getNodeId(d, i) {
119
+ return "".concat(this._id(d, i) || this._nodeGroupBy[min([
120
+ this._drawDepth,
121
+ this._nodeGroupBy.length - 1
122
+ ])](d, i));
123
+ }
124
+ var Network = /*#__PURE__*/ function(Viz) {
125
+ "use strict";
126
+ _inherits(Network, Viz);
127
+ function Network() {
128
+ _class_call_check(this, Network);
129
+ var _this;
130
+ _this = _call_super(this, Network);
131
+ _this._links = [];
132
+ _this._linkSize = constant(1);
133
+ _this._linkSizeMin = 1;
134
+ _this._linkSizeScale = "sqrt";
135
+ _this._noDataMessage = false;
136
+ _this._nodeGroupBy = [
137
+ accessor("id")
138
+ ];
139
+ _this._nodes = [];
140
+ _this._on["click.shape"] = function(d, i, x, event) {
141
+ _this._tooltipClass.data([]).render();
142
+ if (_this._hover && _this._drawDepth >= _this._groupBy.length - 1) {
143
+ var id = getNodeId.bind(_this)(d, i);
144
+ if (_this._focus && _this._focus === id) {
145
+ _this.active(false);
146
+ _this._on.mouseenter.bind(_this)(d, i, x, event);
147
+ _this._focus = undefined;
148
+ _this._zoomToBounds(null);
149
+ } else {
150
+ _this.hover(false);
151
+ var links = _this._linkLookup[id], node = _this._nodeLookup[id];
152
+ var filterIds = [
153
+ id
154
+ ];
155
+ var xDomain = [
156
+ node.x - node.r,
157
+ node.x + node.r
158
+ ], yDomain = [
159
+ node.y - node.r,
160
+ node.y + node.r
161
+ ];
162
+ links.forEach(function(l) {
163
+ filterIds.push(l.id);
164
+ if (l.x - l.r < xDomain[0]) xDomain[0] = l.x - l.r;
165
+ if (l.x + l.r > xDomain[1]) xDomain[1] = l.x + l.r;
166
+ if (l.y - l.r < yDomain[0]) yDomain[0] = l.y - l.r;
167
+ if (l.y + l.r > yDomain[1]) yDomain[1] = l.y + l.r;
168
+ });
169
+ _this.active(function(h, x) {
170
+ if (h.source && h.target) return h.source.id === id || h.target.id === id;
171
+ else return filterIds.includes(getNodeId.bind(_this)(h, x));
172
+ });
173
+ _this._focus = id;
174
+ var t = zoomTransform(_this._container.node());
175
+ xDomain = xDomain.map(function(d) {
176
+ return d * t.k + t.x;
177
+ });
178
+ yDomain = yDomain.map(function(d) {
179
+ return d * t.k + t.y;
180
+ });
181
+ _this._zoomToBounds([
182
+ [
183
+ xDomain[0],
184
+ yDomain[0]
185
+ ],
186
+ [
187
+ xDomain[1],
188
+ yDomain[1]
189
+ ]
190
+ ]);
191
+ }
192
+ }
193
+ };
194
+ _this._on["click.legend"] = function(d, i, x, event) {
195
+ var ids = _this._id(d);
196
+ var id = _this._ids(d);
197
+ id = id[id.length - 1];
198
+ if (_this._hover && _this._drawDepth >= _this._groupBy.length - 1) {
199
+ if (_this._focus && _this._focus === ids) {
200
+ _this.active(false);
201
+ _this._focus = undefined;
202
+ _this._zoomToBounds(null);
203
+ } else {
204
+ _this.hover(false);
205
+ var nodes = ids.map(function(id) {
206
+ return _this._nodeLookup[id];
207
+ });
208
+ var filterIds = [
209
+ "".concat(id)
210
+ ];
211
+ var xDomain = [
212
+ nodes[0].x - nodes[0].r,
213
+ nodes[0].x + nodes[0].r
214
+ ], yDomain = [
215
+ nodes[0].y - nodes[0].r,
216
+ nodes[0].y + nodes[0].r
217
+ ];
218
+ nodes.forEach(function(l) {
219
+ filterIds.push(l.id);
220
+ if (l.x - l.r < xDomain[0]) xDomain[0] = l.x - l.r;
221
+ if (l.x + l.r > xDomain[1]) xDomain[1] = l.x + l.r;
222
+ if (l.y - l.r < yDomain[0]) yDomain[0] = l.y - l.r;
223
+ if (l.y + l.r > yDomain[1]) yDomain[1] = l.y + l.r;
224
+ });
225
+ _this.active(function(h, x) {
226
+ if (h.source && h.target) return filterIds.includes(h.source.id) && filterIds.includes(h.target.id);
227
+ else {
228
+ var myIds = _this._ids(h, x);
229
+ return filterIds.includes("".concat(myIds[myIds.length - 1]));
230
+ }
231
+ });
232
+ _this._focus = ids;
233
+ var t = zoomTransform(_this._container.node());
234
+ xDomain = xDomain.map(function(d) {
235
+ return d * t.k + t.x;
236
+ });
237
+ yDomain = yDomain.map(function(d) {
238
+ return d * t.k + t.y;
239
+ });
240
+ _this._zoomToBounds([
241
+ [
242
+ xDomain[0],
243
+ yDomain[0]
244
+ ],
245
+ [
246
+ xDomain[1],
247
+ yDomain[1]
248
+ ]
249
+ ]);
250
+ }
251
+ _this._on.mouseenter.bind(_this)(d, i, x, event);
252
+ _this._on["mousemove.legend"].bind(_this)(d, i, x, event);
253
+ }
254
+ };
255
+ _this._on.mouseenter = function() {};
256
+ _this._on["mouseleave.shape"] = function() {
257
+ _this.hover(false);
258
+ };
259
+ var defaultMouseMove = _this._on["mousemove.shape"];
260
+ _this._on["mousemove.shape"] = function(d, i, x, event) {
261
+ defaultMouseMove(d, i, x, event);
262
+ var id = getNodeId.bind(_this)(d, i), links = _this._linkLookup[id] || [], node = _this._nodeLookup[id];
263
+ var filterIds = [
264
+ id
265
+ ];
266
+ var xDomain = [
267
+ node.x - node.r,
268
+ node.x + node.r
269
+ ], yDomain = [
270
+ node.y - node.r,
271
+ node.y + node.r
272
+ ];
273
+ links.forEach(function(l) {
274
+ filterIds.push(l.id);
275
+ if (l.x - l.r < xDomain[0]) xDomain[0] = l.x - l.r;
276
+ if (l.x + l.r > xDomain[1]) xDomain[1] = l.x + l.r;
277
+ if (l.y - l.r < yDomain[0]) yDomain[0] = l.y - l.r;
278
+ if (l.y + l.r > yDomain[1]) yDomain[1] = l.y + l.r;
279
+ });
280
+ _this.hover(function(h, x) {
281
+ if (h.source && h.target) return h.source.id === id || h.target.id === id;
282
+ else return filterIds.includes("".concat(_this._ids(h, x)[_this._drawDepth]));
283
+ });
284
+ };
285
+ _this._sizeMin = 5;
286
+ _this._sizeScale = "sqrt";
287
+ _this._shape = constant("Circle");
288
+ _this._shapeConfig = assign(_this._shapeConfig, {
289
+ ariaLabel: function(d, i) {
290
+ var validSize = _this._size ? ", ".concat(_this._size(d, i)) : "";
291
+ return "".concat(_this._drawLabel(d, i)).concat(validSize, ".");
292
+ },
293
+ labelConfig: {
294
+ duration: 0,
295
+ fontMin: 1,
296
+ fontResize: true,
297
+ labelPadding: 0,
298
+ textAnchor: "middle",
299
+ verticalAlign: "middle"
300
+ },
301
+ Path: {
302
+ fill: "none",
303
+ label: false,
304
+ stroke: "#eee"
305
+ }
306
+ });
307
+ _this._x = accessor("x");
308
+ _this._y = accessor("y");
309
+ _this._zoom = true;
310
+ return _this;
311
+ }
312
+ _create_class(Network, [
313
+ {
314
+ /**
315
+ Extends the draw behavior of the abstract Viz class.
316
+ @private
317
+ */ key: "_draw",
318
+ value: function _draw(callback) {
319
+ var _this = this;
320
+ _get(_get_prototype_of(Network.prototype), "_draw", this).call(this, callback);
321
+ var duration = this._duration, height = this._height - this._margin.top - this._margin.bottom, transform = "translate(".concat(this._margin.left, ", ").concat(this._margin.top, ")"), width = this._width - this._margin.left - this._margin.right;
322
+ var data = this._filteredData.reduce(function(obj, d, i) {
323
+ obj[_this._id(d, i)] = d;
324
+ return obj;
325
+ }, {});
326
+ var nodes = this._nodes.reduce(function(obj, d, i) {
327
+ obj[getNodeId.bind(_this)(d, i)] = d;
328
+ return obj;
329
+ }, {});
330
+ nodes = Array.from(new Set(Object.keys(data).concat(Object.keys(nodes)))).map(function(id, i) {
331
+ var d = data[id], n = nodes[id];
332
+ if (n === undefined) return false;
333
+ return {
334
+ __d3plus__: true,
335
+ data: d || n,
336
+ i: i,
337
+ id: id,
338
+ fx: d !== undefined && !isNaN(_this._x(d)) ? _this._x(d) : _this._x(n),
339
+ fy: d !== undefined && !isNaN(_this._y(d)) ? _this._y(d) : _this._y(n),
340
+ node: n,
341
+ r: _this._size ? d !== undefined && _this._size(d) !== undefined ? _this._size(d) : _this._size(n) : _this._sizeMin,
342
+ shape: d !== undefined && _this._shape(d) !== undefined ? _this._shape(d) : _this._shape(n)
343
+ };
344
+ }).filter(function(n) {
345
+ return n;
346
+ });
347
+ var nodeLookup = this._nodeLookup = nodes.reduce(function(obj, d) {
348
+ obj[d.id] = d;
349
+ return obj;
350
+ }, {});
351
+ var nodeIndices = nodes.map(function(n) {
352
+ return n.node;
353
+ });
354
+ var links = this._links.map(function(l) {
355
+ var referenceType = _type_of(l.source);
356
+ return {
357
+ size: _this._linkSize(l),
358
+ source: referenceType === "number" ? nodes[nodeIndices.indexOf(_this._nodes[l.source])] : referenceType === "string" ? nodeLookup[l.source] : nodeLookup[l.source.id],
359
+ target: referenceType === "number" ? nodes[nodeIndices.indexOf(_this._nodes[l.target])] : referenceType === "string" ? nodeLookup[l.target] : nodeLookup[l.target.id]
360
+ };
361
+ });
362
+ this._linkLookup = links.reduce(function(obj, d) {
363
+ if (!obj[d.source.id]) obj[d.source.id] = [];
364
+ obj[d.source.id].push(d.target);
365
+ if (!obj[d.target.id]) obj[d.target.id] = [];
366
+ obj[d.target.id].push(d.source);
367
+ return obj;
368
+ }, {});
369
+ var missingCoords = nodes.some(function(n) {
370
+ return n.fx === undefined || n.fy === undefined;
371
+ });
372
+ if (missingCoords) {
373
+ var linkStrength = scales.scaleLinear().domain(extent(links, function(d) {
374
+ return d.size;
375
+ })).range([
376
+ 0.1,
377
+ 0.5
378
+ ]);
379
+ var simulation = forceSimulation().force("link", forceLink(links).id(function(d) {
380
+ return d.id;
381
+ }).distance(1).strength(function(d) {
382
+ return linkStrength(d.size);
383
+ }).iterations(4)).force("charge", forceManyBody().strength(-1)).stop();
384
+ var iterations = 100;
385
+ var alphaMin = 0.001;
386
+ var alphaDecay = 1 - Math.pow(alphaMin, 1 / iterations);
387
+ simulation.velocityDecay(0);
388
+ simulation.alphaMin(alphaMin);
389
+ simulation.alphaDecay(alphaDecay);
390
+ simulation.alphaDecay(0);
391
+ simulation.nodes(nodes);
392
+ simulation.tick(iterations).stop();
393
+ var nodePositions = nodes.map(function(n) {
394
+ return [
395
+ n.vx,
396
+ n.vy
397
+ ];
398
+ });
399
+ var angle = 0, cx = 0, cy = 0;
400
+ if (nodePositions.length === 2) {
401
+ angle = 100;
402
+ } else if (nodePositions.length > 2) {
403
+ var hull = polygonHull(nodePositions);
404
+ var rect = shapes.largestRect(hull, {
405
+ verbose: true
406
+ });
407
+ angle = rect.angle;
408
+ cx = rect.cx;
409
+ cy = rect.cy;
410
+ }
411
+ nodes.forEach(function(n) {
412
+ var p = shapes.pointRotate([
413
+ n.vx,
414
+ n.vy
415
+ ], -1 * (Math.PI / 180 * angle), [
416
+ cx,
417
+ cy
418
+ ]);
419
+ n.fx = p[0];
420
+ n.fy = p[1];
421
+ });
422
+ }
423
+ var xExtent = extent(nodes.map(function(n) {
424
+ return n.fx;
425
+ })), yExtent = extent(nodes.map(function(n) {
426
+ return n.fy;
427
+ }));
428
+ var x = scales.scaleLinear().domain(xExtent).range([
429
+ 0,
430
+ width
431
+ ]), y = scales.scaleLinear().domain(yExtent).range([
432
+ 0,
433
+ height
434
+ ]);
435
+ var nodeRatio = (xExtent[1] - xExtent[0]) / (yExtent[1] - yExtent[0]) || 1, screenRatio = width / height;
436
+ if (nodeRatio > screenRatio) {
437
+ var h = height * screenRatio / nodeRatio;
438
+ y.range([
439
+ (height - h) / 2,
440
+ height - (height - h) / 2
441
+ ]);
442
+ } else {
443
+ var w = width * nodeRatio / screenRatio;
444
+ x.range([
445
+ (width - w) / 2,
446
+ width - (width - w) / 2
447
+ ]);
448
+ }
449
+ nodes.forEach(function(n) {
450
+ n.x = x(n.fx);
451
+ n.y = y(n.fy);
452
+ });
453
+ var rExtent = extent(nodes.map(function(n) {
454
+ return n.r;
455
+ }));
456
+ var rMax = this._sizeMax || max([
457
+ 1,
458
+ min(merge(nodes.map(function(n1) {
459
+ return nodes.map(function(n2) {
460
+ return n1 === n2 ? null : shapes.pointDistance([
461
+ n1.x,
462
+ n1.y
463
+ ], [
464
+ n2.x,
465
+ n2.y
466
+ ]);
467
+ });
468
+ }))) / 2
469
+ ]);
470
+ var r = scales["scale".concat(this._sizeScale.charAt(0).toUpperCase()).concat(this._sizeScale.slice(1))]().domain(rExtent).range([
471
+ rExtent[0] === rExtent[1] ? rMax : min([
472
+ rMax / 2,
473
+ this._sizeMin
474
+ ]),
475
+ rMax
476
+ ]), xDomain = x.domain(), yDomain = y.domain();
477
+ var xOldSize = xDomain[1] - xDomain[0], yOldSize = yDomain[1] - yDomain[0];
478
+ nodes.forEach(function(n) {
479
+ var size = r(n.r);
480
+ if (xDomain[0] > x.invert(n.x - size)) xDomain[0] = x.invert(n.x - size);
481
+ if (xDomain[1] < x.invert(n.x + size)) xDomain[1] = x.invert(n.x + size);
482
+ if (yDomain[0] > y.invert(n.y - size)) yDomain[0] = y.invert(n.y - size);
483
+ if (yDomain[1] < y.invert(n.y + size)) yDomain[1] = y.invert(n.y + size);
484
+ });
485
+ var xNewSize = xDomain[1] - xDomain[0], yNewSize = yDomain[1] - yDomain[0];
486
+ rMax *= min([
487
+ xOldSize / xNewSize,
488
+ yOldSize / yNewSize
489
+ ]);
490
+ r.range([
491
+ rExtent[0] === rExtent[1] ? rMax : min([
492
+ rMax / 2,
493
+ this._sizeMin
494
+ ]),
495
+ rMax
496
+ ]);
497
+ x.domain(xDomain);
498
+ y.domain(yDomain);
499
+ var fallbackRadius = (nodeRatio > screenRatio ? width : height) / 2;
500
+ nodes.forEach(function(n) {
501
+ n.x = x(n.fx);
502
+ n.fx = n.x;
503
+ n.y = y(n.fy);
504
+ n.fy = n.y;
505
+ n.r = r(n.r) || fallbackRadius;
506
+ n.width = n.r * 2;
507
+ n.height = n.r * 2;
508
+ });
509
+ this._container = this._select.selectAll("svg.d3plus-network").data([
510
+ 0
511
+ ]);
512
+ this._container = this._container.enter().append("svg").attr("class", "d3plus-network").attr("opacity", 0).attr("width", width).attr("height", height).attr("x", this._margin.left).attr("y", this._margin.top).style("background-color", "transparent").merge(this._container);
513
+ this._container.transition().duration(duration).attr("opacity", 1).attr("width", width).attr("height", height).attr("x", this._margin.left).attr("y", this._margin.top);
514
+ var hitArea = this._container.selectAll("rect.d3plus-network-hitArea").data([
515
+ 0
516
+ ]);
517
+ hitArea.enter().append("rect").attr("class", "d3plus-network-hitArea").merge(hitArea).attr("width", width).attr("height", height).attr("fill", "transparent").on("click", function() {
518
+ if (_this._focus) {
519
+ _this.active(false);
520
+ _this._focus = undefined;
521
+ _this._zoomToBounds(null);
522
+ }
523
+ });
524
+ this._zoomGroup = this._container.selectAll("g.d3plus-network-zoomGroup").data([
525
+ 0
526
+ ]);
527
+ var parent = this._zoomGroup = this._zoomGroup.enter().append("g").attr("class", "d3plus-network-zoomGroup").merge(this._zoomGroup);
528
+ var strokeExtent = extent(links, function(d) {
529
+ return d.size;
530
+ });
531
+ if (strokeExtent[0] !== strokeExtent[1]) {
532
+ var strokeScale = scales["scale".concat(this._linkSizeScale.charAt(0).toUpperCase()).concat(this._linkSizeScale.slice(1))]().domain(strokeExtent).range([
533
+ this._linkSizeMin,
534
+ r.range()[0]
535
+ ]);
536
+ links.forEach(function(link) {
537
+ link.size = strokeScale(link.size);
538
+ });
539
+ }
540
+ var linkConfig = configPrep.bind(this)(this._shapeConfig, "edge", "Path");
541
+ delete linkConfig.on;
542
+ this._shapes.push(new shapes.Path().config(linkConfig).strokeWidth(function(d) {
543
+ return d.size;
544
+ }).activeStyle({
545
+ "stroke-width": function(d) {
546
+ return d.size;
547
+ }
548
+ }).d(function(d) {
549
+ return "M".concat(d.source.x, ",").concat(d.source.y, " ").concat(d.target.x, ",").concat(d.target.y);
550
+ }).data(links).select(elem("g.d3plus-network-links", {
551
+ parent: parent,
552
+ duration: duration,
553
+ enter: {
554
+ transform: transform
555
+ },
556
+ update: {
557
+ transform: transform
558
+ }
559
+ }).node()).render());
560
+ var shapeConfig = {
561
+ label: function(d) {
562
+ return nodes.length <= _this._dataCutoff || _this._hover && _this._hover(d) || _this._active && _this._active(d) ? _this._drawLabel(d.data || d.node, d.i) : false;
563
+ },
564
+ select: elem("g.d3plus-network-nodes", {
565
+ parent: parent,
566
+ duration: duration,
567
+ enter: {
568
+ transform: transform
569
+ },
570
+ update: {
571
+ transform: transform
572
+ }
573
+ }).node()
574
+ };
575
+ nest().key(function(d) {
576
+ return d.shape;
577
+ }).entries(nodes).forEach(function(d) {
578
+ _this._shapes.push(new shapes[d.key]().config(configPrep.bind(_this)(_this._shapeConfig, "shape", d.key)).config(shapeConfig).config(shapeConfig[d.key] || {}).data(d.values).render());
579
+ });
580
+ return this;
581
+ }
582
+ },
583
+ {
584
+ /**
585
+ @memberof Network
586
+ @desc If *value* is specified, sets the hover method to the specified function and returns the current class instance.
587
+ @param {Function} [*value*]
588
+ @chainable
589
+ */ key: "hover",
590
+ value: function hover(_) {
591
+ this._hover = _;
592
+ if (this._nodes.length < this._dataCutoff) {
593
+ this._shapes.forEach(function(s) {
594
+ return s.hover(_);
595
+ });
596
+ if (this._legend) this._legendClass.hover(_);
597
+ }
598
+ return this;
599
+ }
600
+ },
601
+ {
602
+ /**
603
+ @memberof Network
604
+ @desc A predefined *Array* of edges that connect each object passed to the [node](#Network.node) method. The `source` and `target` keys in each link need to map to the nodes in one of three ways:
605
+ 1. The index of the node in the nodes array (as in [this](http://d3plus.org/examples/d3plus-network/getting-started/) example).
606
+ 2. The actual node *Object* itself.
607
+ 3. A *String* value matching the `id` of the node.
608
+
609
+ The value passed should either be an *Array* of data or a *String* representing a filepath or URL to be loaded. An optional formatting function can be passed as a second argument to this method. This custom function will be passed the data that has been loaded, as long as there are no errors. This function should return the final links *Array*.
610
+ @param {Array|String} *links* = []
611
+ @param {Function} [*formatter*]
612
+ @chainable
613
+ */ key: "links",
614
+ value: function links(_, f) {
615
+ if (arguments.length) {
616
+ addToQueue.bind(this)(_, f, "links");
617
+ return this;
618
+ }
619
+ return this._links;
620
+ }
621
+ },
622
+ {
623
+ /**
624
+ @memberof Network
625
+ @desc Defines the thickness of the links connecting each node. The value provided can be either a pixel Number to be used for all links, or an accessor function that returns a specific data value to be used in an automatically calculated linear scale.
626
+ @param {Function|Name} [*value* = 1]
627
+ @chainable
628
+ */ key: "linkSize",
629
+ value: function linkSize(_) {
630
+ return arguments.length ? (this._linkSize = typeof _ === "function" ? _ : constant(_), this) : this._linkSize;
631
+ }
632
+ },
633
+ {
634
+ /**
635
+ @memberof Network
636
+ @desc Defines the minimum pixel stroke width used in link sizing.
637
+ @param {Number} [*value* = 2]
638
+ @chainable
639
+ */ key: "linkSizeMin",
640
+ value: function linkSizeMin(_) {
641
+ return arguments.length ? (this._linkSizeMin = _, this) : this._linkSizeMin;
642
+ }
643
+ },
644
+ {
645
+ /**
646
+ @memberof Network
647
+ @desc Sets the specific type of [continuous d3-scale](https://github.com/d3/d3-scale#continuous-scales) used when calculating the pixel size of links in the network.
648
+ @param {String} [*value* = "sqrt"]
649
+ @chainable
650
+ */ key: "linkSizeScale",
651
+ value: function linkSizeScale(_) {
652
+ return arguments.length ? (this._linkSizeScale = _, this) : this._linkSizeScale;
653
+ }
654
+ },
655
+ {
656
+ /**
657
+ @memberof Network
658
+ @desc If *value* is specified, sets the node group accessor(s) to the specified string, function, or array of values and returns the current class instance. This method overrides the default .groupBy() function from being used with the data passed to .nodes(). If *value* is not specified, returns the current node group accessor.
659
+ @param {String|Function|Array} [*value* = "id"]
660
+ @chainable
661
+ */ key: "nodeGroupBy",
662
+ value: function nodeGroupBy(_) {
663
+ var _this = this;
664
+ if (!arguments.length) return this._nodeGroupBy;
665
+ if (!_instanceof(_, Array)) _ = [
666
+ _
667
+ ];
668
+ return this._nodeGroupBy = _.map(function(k) {
669
+ if (typeof k === "function") return k;
670
+ else {
671
+ if (!_this._aggs[k]) {
672
+ _this._aggs[k] = function(a, c) {
673
+ var v = Array.from(new Set(a.map(c)));
674
+ return v.length === 1 ? v[0] : v;
675
+ };
676
+ }
677
+ return accessor(k);
678
+ }
679
+ }), this;
680
+ }
681
+ },
682
+ {
683
+ /**
684
+ @memberof Network
685
+ @desc The list of nodes to be used for drawing the network. The value passed should either be an *Array* of data or a *String* representing a filepath or URL to be loaded.
686
+
687
+ Additionally, a custom formatting function can be passed as a second argument to this method. This custom function will be passed the data that has been loaded, as long as there are no errors. This function should return the final node *Array*.
688
+ @param {Array|String} *nodes* = []
689
+ @param {Function} [*formatter*]
690
+ @chainable
691
+ */ key: "nodes",
692
+ value: function nodes(_, f) {
693
+ if (arguments.length) {
694
+ addToQueue.bind(this)(_, f, "nodes");
695
+ return this;
696
+ }
697
+ return this._nodes;
698
+ }
699
+ },
700
+ {
701
+ /**
702
+ @memberof Network
703
+ @desc If *value* is specified, sets the size accessor to the specified function or data key and returns the current class instance. If *value* is not specified, returns the current size accessor.
704
+ @param {Function|String} [*value*]
705
+ @chainable
706
+ */ key: "size",
707
+ value: function size(_) {
708
+ return arguments.length ? (this._size = typeof _ === "function" || !_ ? _ : accessor(_), this) : this._size;
709
+ }
710
+ },
711
+ {
712
+ /**
713
+ @memberof Network
714
+ @desc Defines the maximum pixel radius used in size scaling. By default, the maximum size is determined by half the distance of the two closest nodes.
715
+ @param {Number} [*value*]
716
+ @chainable
717
+ */ key: "sizeMax",
718
+ value: function sizeMax(_) {
719
+ return arguments.length ? (this._sizeMax = _, this) : this._sizeMax;
720
+ }
721
+ },
722
+ {
723
+ /**
724
+ @memberof Network
725
+ @desc Defines the minimum pixel radius used in size scaling.
726
+ @param {Number} [*value* = 5]
727
+ @chainable
728
+ */ key: "sizeMin",
729
+ value: function sizeMin(_) {
730
+ return arguments.length ? (this._sizeMin = _, this) : this._sizeMin;
731
+ }
732
+ },
733
+ {
734
+ /**
735
+ @memberof Network
736
+ @desc Sets the specific type of [continuous d3-scale](https://github.com/d3/d3-scale#continuous-scales) used when calculating the pixel size of nodes in the network.
737
+ @param {String} [*value* = "sqrt"]
738
+ @chainable
739
+ */ key: "sizeScale",
740
+ value: function sizeScale(_) {
741
+ return arguments.length ? (this._sizeScale = _, this) : this._sizeScale;
742
+ }
743
+ },
744
+ {
745
+ /**
746
+ @memberof Network
747
+ @desc If *value* is specified, sets the x accessor to the specified function or string matching a key in the data and returns the current class instance. The data passed to .data() takes priority over the .nodes() data array. If *value* is not specified, returns the current x accessor. By default, the x and y positions are determined dynamically based on default force layout properties.
748
+ @param {Function|String} [*value*]
749
+ @chainable
750
+ */ key: "x",
751
+ value: function x(_) {
752
+ if (arguments.length) {
753
+ if (typeof _ === "function") this._x = _;
754
+ else {
755
+ this._x = accessor(_);
756
+ if (!this._aggs[_]) this._aggs[_] = mean;
757
+ }
758
+ return this;
759
+ } else return this._x;
760
+ }
761
+ },
762
+ {
763
+ /**
764
+ @memberof Network
765
+ @desc If *value* is specified, sets the y accessor to the specified function or string matching a key in the data and returns the current class instance. The data passed to .data() takes priority over the .nodes() data array. If *value* is not specified, returns the current y accessor. By default, the x and y positions are determined dynamically based on default force layout properties.
766
+ @param {Function|String} [*value*]
767
+ @chainable
768
+ */ key: "y",
769
+ value: function y(_) {
770
+ if (arguments.length) {
771
+ if (typeof _ === "function") this._y = _;
772
+ else {
773
+ this._y = accessor(_);
774
+ if (!this._aggs[_]) this._aggs[_] = mean;
775
+ }
776
+ return this;
777
+ } else return this._y;
778
+ }
779
+ }
780
+ ]);
781
+ return Network;
782
+ }(Viz);
783
+ /**
784
+ @class Network
785
+ @extends Viz
786
+ @desc Creates a network visualization based on a defined set of nodes and edges. [Click here](http://d3plus.org/examples/d3plus-network/getting-started/) for help getting started using the Network class.
787
+ */ export { Network as default };