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