@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,833 @@
1
+ function _array_like_to_array(arr, len) {
2
+ if (len == null || len > arr.length) len = arr.length;
3
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
4
+ return arr2;
5
+ }
6
+ function _array_with_holes(arr) {
7
+ if (Array.isArray(arr)) return arr;
8
+ }
9
+ function _assert_this_initialized(self) {
10
+ if (self === void 0) {
11
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
12
+ }
13
+ return self;
14
+ }
15
+ function _call_super(_this, derived, args) {
16
+ derived = _get_prototype_of(derived);
17
+ return _possible_constructor_return(_this, _is_native_reflect_construct() ? Reflect.construct(derived, args || [], _get_prototype_of(_this).constructor) : derived.apply(_this, args));
18
+ }
19
+ function _class_call_check(instance, Constructor) {
20
+ if (!(instance instanceof Constructor)) {
21
+ throw new TypeError("Cannot call a class as a function");
22
+ }
23
+ }
24
+ function _defineProperties(target, props) {
25
+ for(var i = 0; i < props.length; i++){
26
+ var descriptor = props[i];
27
+ descriptor.enumerable = descriptor.enumerable || false;
28
+ descriptor.configurable = true;
29
+ if ("value" in descriptor) descriptor.writable = true;
30
+ Object.defineProperty(target, descriptor.key, descriptor);
31
+ }
32
+ }
33
+ function _create_class(Constructor, protoProps, staticProps) {
34
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
35
+ if (staticProps) _defineProperties(Constructor, staticProps);
36
+ return Constructor;
37
+ }
38
+ function _get(target, property, receiver) {
39
+ if (typeof Reflect !== "undefined" && Reflect.get) {
40
+ _get = Reflect.get;
41
+ } else {
42
+ _get = function get(target, property, receiver) {
43
+ var base = _super_prop_base(target, property);
44
+ if (!base) return;
45
+ var desc = Object.getOwnPropertyDescriptor(base, property);
46
+ if (desc.get) {
47
+ return desc.get.call(receiver || target);
48
+ }
49
+ return desc.value;
50
+ };
51
+ }
52
+ return _get(target, property, receiver || target);
53
+ }
54
+ function _get_prototype_of(o) {
55
+ _get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o) {
56
+ return o.__proto__ || Object.getPrototypeOf(o);
57
+ };
58
+ return _get_prototype_of(o);
59
+ }
60
+ function _inherits(subClass, superClass) {
61
+ if (typeof superClass !== "function" && superClass !== null) {
62
+ throw new TypeError("Super expression must either be null or a function");
63
+ }
64
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
65
+ constructor: {
66
+ value: subClass,
67
+ writable: true,
68
+ configurable: true
69
+ }
70
+ });
71
+ if (superClass) _set_prototype_of(subClass, superClass);
72
+ }
73
+ function _instanceof(left, right) {
74
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
75
+ return !!right[Symbol.hasInstance](left);
76
+ } else {
77
+ return left instanceof right;
78
+ }
79
+ }
80
+ function _iterable_to_array_limit(arr, i) {
81
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
82
+ if (_i == null) return;
83
+ var _arr = [];
84
+ var _n = true;
85
+ var _d = false;
86
+ var _s, _e;
87
+ try {
88
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
89
+ _arr.push(_s.value);
90
+ if (i && _arr.length === i) break;
91
+ }
92
+ } catch (err) {
93
+ _d = true;
94
+ _e = err;
95
+ } finally{
96
+ try {
97
+ if (!_n && _i["return"] != null) _i["return"]();
98
+ } finally{
99
+ if (_d) throw _e;
100
+ }
101
+ }
102
+ return _arr;
103
+ }
104
+ function _non_iterable_rest() {
105
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
106
+ }
107
+ function _possible_constructor_return(self, call) {
108
+ if (call && (_type_of(call) === "object" || typeof call === "function")) {
109
+ return call;
110
+ }
111
+ return _assert_this_initialized(self);
112
+ }
113
+ function _set_prototype_of(o, p) {
114
+ _set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o, p) {
115
+ o.__proto__ = p;
116
+ return o;
117
+ };
118
+ return _set_prototype_of(o, p);
119
+ }
120
+ function _sliced_to_array(arr, i) {
121
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
122
+ }
123
+ function _super_prop_base(object, property) {
124
+ while(!Object.prototype.hasOwnProperty.call(object, property)){
125
+ object = _get_prototype_of(object);
126
+ if (object === null) break;
127
+ }
128
+ return object;
129
+ }
130
+ function _type_of(obj) {
131
+ "@swc/helpers - typeof";
132
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
133
+ }
134
+ function _unsupported_iterable_to_array(o, minLen) {
135
+ if (!o) return;
136
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
137
+ var n = Object.prototype.toString.call(o).slice(8, -1);
138
+ if (n === "Object" && o.constructor) n = o.constructor.name;
139
+ if (n === "Map" || n === "Set") return Array.from(n);
140
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
141
+ }
142
+ function _is_native_reflect_construct() {
143
+ try {
144
+ var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
145
+ } catch (_) {}
146
+ return (_is_native_reflect_construct = function() {
147
+ return !!result;
148
+ })();
149
+ }
150
+ import { extent, max, quantile } from "d3-array";
151
+ import { color } from "d3-color";
152
+ import { zoomTransform } from "d3-zoom";
153
+ import * as d3GeoCore from "d3-geo";
154
+ import * as d3GeoProjection from "d3-geo-projection";
155
+ import * as d3CompositeProjections from "d3-composite-projections";
156
+ var d3Geo = Object.assign({}, d3GeoCore, d3GeoProjection, d3CompositeProjections);
157
+ import * as scales from "d3-scale";
158
+ import { tile } from "d3-tile";
159
+ import { feature } from "topojson-client";
160
+ import { load } from "@d3plus/data";
161
+ import { assign, parseSides } from "@d3plus/dom";
162
+ import { pointDistance } from "@d3plus/math";
163
+ import { Circle, Path } from "../shapes/index.js";
164
+ import { accessor, configPrep, constant } from "../utils/index.js";
165
+ import Viz from "./Viz";
166
+ import attributions from "./helpers/tileAttributions.js";
167
+ /**
168
+ * @name findAttribution
169
+ * @param {String} url
170
+ * @private
171
+ */ function findAttribution(url) {
172
+ var a = attributions.find(function(d) {
173
+ return d.matches.some(function(m) {
174
+ return url.includes(m);
175
+ });
176
+ });
177
+ return a ? a.text : false;
178
+ }
179
+ /**
180
+ @name topo2feature
181
+ @desc Converts a specific topojson object key into a feature ready for projection.
182
+ @param {Object} *topo* A valid topojson json object.
183
+ @param {String} [*key*] The topojson object key to be used. If undefined, the first key available will be used.
184
+ @private
185
+ */ function topo2feature(topo, key) {
186
+ var k = key && topo.objects[key] ? key : Object.keys(topo.objects)[0];
187
+ return feature(topo, k);
188
+ }
189
+ var Geomap = /*#__PURE__*/ function(Viz) {
190
+ "use strict";
191
+ _inherits(Geomap, Viz);
192
+ function Geomap() {
193
+ _class_call_check(this, Geomap);
194
+ var _this;
195
+ _this = _call_super(this, Geomap);
196
+ _this._fitObject = false;
197
+ _this._noDataMessage = false;
198
+ _this._ocean = "#d4dadc";
199
+ _this._point = accessor("point");
200
+ _this._pointSize = constant(1);
201
+ _this._pointSizeMax = 10;
202
+ _this._pointSizeMin = 5;
203
+ _this._pointSizeScale = "linear";
204
+ _this._projection = d3Geo.geoMercator();
205
+ _this._projectionPadding = parseSides(20);
206
+ _this._shape = constant("Circle");
207
+ _this._shapeConfig = assign(_this._shapeConfig, {
208
+ ariaLabel: function(d, i) {
209
+ return "".concat(_this._drawLabel(d, i), ", ").concat(_this._pointSize(d, i));
210
+ },
211
+ hoverOpacity: 1,
212
+ Path: {
213
+ ariaLabel: function(d, i) {
214
+ var validColorScale = _this._colorScale ? ", ".concat(_this._colorScale(d, i)) : "";
215
+ return "".concat(_this._drawLabel(d, i)).concat(validColorScale, ".");
216
+ },
217
+ fill: function(d, i) {
218
+ if (_this._colorScale && !_this._coordData.features.includes(d)) {
219
+ var c = _this._colorScale(d);
220
+ if (c !== undefined && c !== null) {
221
+ if (_this._colorScaleClass._colorScale) {
222
+ return _this._colorScaleClass._colorScale(c);
223
+ } else {
224
+ var color = _this._colorScaleClass.color();
225
+ if (_instanceof(color, Array)) color = color[color.length - 1];
226
+ return color;
227
+ }
228
+ }
229
+ }
230
+ return _this._topojsonFill(d, i);
231
+ },
232
+ on: {
233
+ "mouseenter": function(d, i, x, event) {
234
+ return !_this._coordData.features.includes(d) ? _this._on.mouseenter.bind(_this)(d, i, x, event) : null;
235
+ },
236
+ "mousemove.shape": function(d, i, x, event) {
237
+ return !_this._coordData.features.includes(d) ? _this._on["mousemove.shape"].bind(_this)(d, i, x, event) : null;
238
+ },
239
+ "mouseleave": function(d, i, x, event) {
240
+ return !_this._coordData.features.includes(d) ? _this._on.mouseleave.bind(_this)(d, i, x, event) : null;
241
+ }
242
+ },
243
+ stroke: function(d, i) {
244
+ var c = typeof _this._shapeConfig.Path.fill === "function" ? _this._shapeConfig.Path.fill(d, i) : _this._shapeConfig.Path.fill;
245
+ return color(c).darker();
246
+ },
247
+ strokeWidth: 1
248
+ }
249
+ });
250
+ _this._tiles = true;
251
+ _this._tileGen = tile();
252
+ _this.tileUrl("https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}@2x.png");
253
+ _this._topojson = false;
254
+ _this._topojsonFill = constant("#f5f5f3");
255
+ _this._topojsonFilter = function(d) {
256
+ return ![
257
+ "010"
258
+ ].includes(d.id);
259
+ };
260
+ _this._topojsonId = accessor("id");
261
+ _this._zoom = true;
262
+ _this._zoomSet = false;
263
+ return _this;
264
+ }
265
+ _create_class(Geomap, [
266
+ {
267
+ /**
268
+ Renders map tiles based on the current zoom level.
269
+ @private
270
+ */ key: "_renderTiles",
271
+ value: function _renderTiles() {
272
+ var _this = this;
273
+ var transform = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : zoomTransform(this._container.node()), duration = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0;
274
+ var tileData = [];
275
+ if (this._tiles) {
276
+ tileData = this._tileGen.extent(this._zoomBehavior.translateExtent()).scale(this._projection.scale() * (2 * Math.PI) * transform.k).translate(transform.apply(this._projection.translate()))();
277
+ this._tileGroup.transition().duration(duration).attr("transform", transform);
278
+ }
279
+ var images = this._tileGroup.selectAll("image.d3plus-geomap-tile").data(tileData, function(param) {
280
+ var _param = _sliced_to_array(param, 3), x = _param[0], y = _param[1], z = _param[2];
281
+ return "".concat(x, "-").concat(y, "-").concat(z);
282
+ });
283
+ images.exit().transition().duration(duration).attr("opacity", 0).remove();
284
+ var scale = tileData.scale / transform.k;
285
+ var tileEnter = images.enter().append("image").attr("class", "d3plus-geomap-tile");
286
+ tileEnter.attr("opacity", 0).transition().duration(duration).attr("opacity", 1);
287
+ images.merge(tileEnter).attr("width", scale).attr("height", scale).attr("xlink:href", function(param) {
288
+ var _param = _sliced_to_array(param, 3), x = _param[0], y = _param[1], z = _param[2];
289
+ return _this._tileUrl.replace("{s}", [
290
+ "a",
291
+ "b",
292
+ "c"
293
+ ][Math.random() * 3 | 0]).replace("{z}", z).replace("{x}", x).replace("{y}", y);
294
+ }).attr("x", function(param) {
295
+ var _param = _sliced_to_array(param, 1), x = _param[0];
296
+ return x * scale + tileData.translate[0] * scale - transform.x / transform.k;
297
+ }).attr("y", function(param) {
298
+ var _param = _sliced_to_array(param, 2), y = _param[1];
299
+ return y * scale + tileData.translate[1] * scale - transform.y / transform.k;
300
+ });
301
+ }
302
+ },
303
+ {
304
+ /**
305
+ Extends the draw behavior of the abstract Viz class.
306
+ @private
307
+ */ key: "_draw",
308
+ value: function _draw(callback) {
309
+ var _this = this;
310
+ _get(_get_prototype_of(Geomap.prototype), "_draw", this).call(this, callback);
311
+ var height = this._height - this._margin.top - this._margin.bottom, width = this._width - this._margin.left - this._margin.right;
312
+ this._container = this._select.selectAll("svg.d3plus-geomap").data([
313
+ 0
314
+ ]);
315
+ this._container = this._container.enter().append("svg").attr("class", "d3plus-geomap").attr("opacity", 0).attr("width", width).attr("height", height).attr("x", this._margin.left).attr("y", this._margin.top).style("background-color", this._ocean || "transparent").merge(this._container);
316
+ this._container.transition(this._transition).attr("opacity", 1).attr("width", width).attr("height", height).attr("x", this._margin.left).attr("y", this._margin.top);
317
+ var ocean = this._container.selectAll("rect.d3plus-geomap-ocean").data([
318
+ 0
319
+ ]);
320
+ ocean.enter().append("rect").attr("class", "d3plus-geomap-ocean").merge(ocean).attr("width", width).attr("height", height).attr("fill", this._ocean || "transparent");
321
+ this._tileGroup = this._container.selectAll("g.d3plus-geomap-tileGroup").data([
322
+ 0
323
+ ]);
324
+ this._tileGroup = this._tileGroup.enter().append("g").attr("class", "d3plus-geomap-tileGroup").merge(this._tileGroup);
325
+ this._zoomGroup = this._container.selectAll("g.d3plus-geomap-zoomGroup").data([
326
+ 0
327
+ ]);
328
+ this._zoomGroup = this._zoomGroup.enter().append("g").attr("class", "d3plus-geomap-zoomGroup").merge(this._zoomGroup);
329
+ var pathGroup = this._zoomGroup.selectAll("g.d3plus-geomap-paths").data([
330
+ 0
331
+ ]);
332
+ pathGroup = pathGroup.enter().append("g").attr("class", "d3plus-geomap-paths").merge(pathGroup);
333
+ var coordData = this._coordData = this._topojson ? topo2feature(this._topojson, this._topojsonKey) : {
334
+ type: "FeatureCollection",
335
+ features: []
336
+ };
337
+ if (this._topojsonFilter) coordData.features = coordData.features.filter(this._topojsonFilter);
338
+ var path = this._path = d3Geo.geoPath().projection(this._projection);
339
+ var pointData = this._filteredData.filter(function(d, i) {
340
+ return _instanceof(_this._point(d, i), Array);
341
+ });
342
+ var pathData = this._filteredData.filter(function(d, i) {
343
+ return !_instanceof(_this._point(d, i), Array);
344
+ }).reduce(function(obj, d) {
345
+ obj[_this._id(d)] = d;
346
+ return obj;
347
+ }, {});
348
+ var topoData = coordData.features.reduce(function(arr, feature) {
349
+ var id = _this._topojsonId(feature);
350
+ arr.push({
351
+ __d3plus__: true,
352
+ data: pathData[id],
353
+ feature: feature,
354
+ id: id
355
+ });
356
+ return arr;
357
+ }, []);
358
+ var r = scales["scale".concat(this._pointSizeScale.charAt(0).toUpperCase()).concat(this._pointSizeScale.slice(1))]().domain(extent(pointData, function(d, i) {
359
+ return _this._pointSize(d, i);
360
+ })).range([
361
+ this._pointSizeMin,
362
+ this._pointSizeMax
363
+ ]);
364
+ if (!this._zoomSet) {
365
+ var fitData = this._fitObject ? topo2feature(this._fitObject, this._fitKey) : coordData;
366
+ this._extentBounds = {
367
+ type: "FeatureCollection",
368
+ features: this._fitFilter ? fitData.features.filter(this._fitFilter) : fitData.features.slice()
369
+ };
370
+ this._extentBounds.features = this._extentBounds.features.reduce(function(arr, d) {
371
+ if (d.geometry) {
372
+ var reduced = {
373
+ type: d.type,
374
+ id: d.id,
375
+ geometry: {
376
+ coordinates: d.geometry.coordinates,
377
+ type: d.geometry.type
378
+ }
379
+ };
380
+ if (d.geometry.type === "MultiPolygon" && d.geometry.coordinates.length > 1) {
381
+ var areas = [], distances = [];
382
+ d.geometry.coordinates.forEach(function(c) {
383
+ reduced.geometry.coordinates = [
384
+ c
385
+ ];
386
+ areas.push(path.area(reduced));
387
+ });
388
+ reduced.geometry.coordinates = [
389
+ d.geometry.coordinates[areas.indexOf(max(areas))]
390
+ ];
391
+ var center = path.centroid(reduced);
392
+ d.geometry.coordinates.forEach(function(c) {
393
+ reduced.geometry.coordinates = [
394
+ c
395
+ ];
396
+ distances.push(pointDistance(path.centroid(reduced), center));
397
+ });
398
+ var distCutoff = quantile(areas.reduce(function(arr, dist, i) {
399
+ if (dist) arr.push(areas[i] / dist);
400
+ return arr;
401
+ }, []), 0.9);
402
+ reduced.geometry.coordinates = d.geometry.coordinates.filter(function(c, i) {
403
+ var dist = distances[i];
404
+ return dist === 0 || areas[i] / dist >= distCutoff;
405
+ });
406
+ }
407
+ arr.push(reduced);
408
+ }
409
+ return arr;
410
+ }, []);
411
+ if (!this._extentBounds.features.length && pointData.length) {
412
+ var bounds = [
413
+ [
414
+ undefined,
415
+ undefined
416
+ ],
417
+ [
418
+ undefined,
419
+ undefined
420
+ ]
421
+ ];
422
+ pointData.forEach(function(d, i) {
423
+ var point = _this._projection(_this._point(d, i));
424
+ if (bounds[0][0] === void 0 || point[0] < bounds[0][0]) bounds[0][0] = point[0];
425
+ if (bounds[1][0] === void 0 || point[0] > bounds[1][0]) bounds[1][0] = point[0];
426
+ if (bounds[0][1] === void 0 || point[1] < bounds[0][1]) bounds[0][1] = point[1];
427
+ if (bounds[1][1] === void 0 || point[1] > bounds[1][1]) bounds[1][1] = point[1];
428
+ });
429
+ this._extentBounds = {
430
+ type: "FeatureCollection",
431
+ features: [
432
+ {
433
+ type: "Feature",
434
+ geometry: {
435
+ type: "MultiPoint",
436
+ coordinates: bounds.map(function(b) {
437
+ return _this._projection.invert(b);
438
+ })
439
+ }
440
+ }
441
+ ]
442
+ };
443
+ var maxSize = max(pointData, function(d, i) {
444
+ return r(_this._pointSize(d, i));
445
+ });
446
+ this._projectionPadding.top += maxSize;
447
+ this._projectionPadding.right += maxSize;
448
+ this._projectionPadding.bottom += maxSize;
449
+ this._projectionPadding.left += maxSize;
450
+ }
451
+ this._zoomBehavior.extent([
452
+ [
453
+ 0,
454
+ 0
455
+ ],
456
+ [
457
+ width,
458
+ height
459
+ ]
460
+ ]).scaleExtent([
461
+ 1,
462
+ this._zoomMax
463
+ ]).translateExtent([
464
+ [
465
+ 0,
466
+ 0
467
+ ],
468
+ [
469
+ width,
470
+ height
471
+ ]
472
+ ]);
473
+ this._zoomSet = true;
474
+ }
475
+ this._projection = this._projection.fitExtent(this._extentBounds.features.length ? [
476
+ [
477
+ this._projectionPadding.left,
478
+ this._projectionPadding.top
479
+ ],
480
+ [
481
+ width - this._projectionPadding.right,
482
+ height - this._projectionPadding.bottom
483
+ ]
484
+ ] : [
485
+ [
486
+ 0,
487
+ 0
488
+ ],
489
+ [
490
+ width,
491
+ height
492
+ ]
493
+ ], this._extentBounds.features.length ? this._extentBounds : {
494
+ type: "Sphere"
495
+ });
496
+ this._shapes.push(new Path().data(topoData).d(function(d) {
497
+ return path(d.feature);
498
+ }).select(pathGroup.node()).x(0).y(0).config(configPrep.bind(this)(this._shapeConfig, "shape", "Path")).render());
499
+ var pointGroup = this._zoomGroup.selectAll("g.d3plus-geomap-pins").data([
500
+ 0
501
+ ]);
502
+ pointGroup = pointGroup.enter().append("g").attr("class", "d3plus-geomap-pins").merge(pointGroup);
503
+ var circles = new Circle().config(configPrep.bind(this)(this._shapeConfig, "shape", "Circle")).data(pointData).r(function(d, i) {
504
+ return r(_this._pointSize(d, i));
505
+ }).select(pointGroup.node()).sort(function(a, b) {
506
+ return _this._pointSize(b) - _this._pointSize(a);
507
+ }).x(function(d, i) {
508
+ return _this._projection(_this._point(d, i))[0];
509
+ }).y(function(d, i) {
510
+ return _this._projection(_this._point(d, i))[1];
511
+ });
512
+ var events = Object.keys(this._on);
513
+ var classEvents = events.filter(function(e) {
514
+ return e.includes(".Circle");
515
+ }), globalEvents = events.filter(function(e) {
516
+ return !e.includes(".");
517
+ }), shapeEvents = events.filter(function(e) {
518
+ return e.includes(".shape");
519
+ });
520
+ for(var e = 0; e < globalEvents.length; e++)circles.on(globalEvents[e], this._on[globalEvents[e]]);
521
+ for(var e1 = 0; e1 < shapeEvents.length; e1++)circles.on(shapeEvents[e1], this._on[shapeEvents[e1]]);
522
+ for(var e2 = 0; e2 < classEvents.length; e2++)circles.on(classEvents[e2], this._on[classEvents[e2]]);
523
+ this._shapes.push(circles.render());
524
+ return this;
525
+ }
526
+ },
527
+ {
528
+ /**
529
+ @memberof Geomap
530
+ @desc Topojson files sometimes include small geographies that negatively impact how the library determines the default zoom level (for example, a small island or territory far off the coast that is barely visible to the eye). The fitFilter method can be used to remove specific geographies from the logic used to determine the zooming.
531
+
532
+ The *value* passed can be a single id to remove, an array of ids, or a filter function. Take a look at the [Choropleth Example](http://d3plus.org/examples/d3plus-geomap/getting-started/) to see it in action.
533
+ @param {Number|String|Array|Function} [*value*]
534
+ @chainable
535
+ */ key: "fitFilter",
536
+ value: function fitFilter(_) {
537
+ if (arguments.length) {
538
+ this._zoomSet = false;
539
+ if (typeof _ === "function") return this._fitFilter = _, this;
540
+ if (!_instanceof(_, Array)) _ = [
541
+ _
542
+ ];
543
+ return this._fitFilter = function(d) {
544
+ return _.includes(d.id);
545
+ }, this;
546
+ }
547
+ return this._fitFilter;
548
+ }
549
+ },
550
+ {
551
+ /**
552
+ @memberof Geomap
553
+ @desc If the topojson being used to determine the zoom fit (either the main [topojson](#Geomap.topojson) object or the [fitObject](#Geomap.fitObject)) contains multiple geographical sets (for example, a file containing state and county boundaries), use this method to indentify which set to use for the zoom fit.
554
+
555
+ If not specified, the first key in the *Array* returned from using `Object.keys` on the topojson will be used.
556
+ @param {String} *value*
557
+ @chainable
558
+ */ key: "fitKey",
559
+ value: function fitKey(_) {
560
+ if (arguments.length) {
561
+ this._fitKey = _;
562
+ this._zoomSet = false;
563
+ return this;
564
+ }
565
+ return this._fitKey;
566
+ }
567
+ },
568
+ {
569
+ /**
570
+ @memberof Geomap
571
+ @desc The topojson to be used for the initial projection [fit extent](https://github.com/d3/d3-geo#projection_fitExtent). The value passed should either be a valid Topojson *Object* or a *String* representing a filepath or URL to be loaded.
572
+
573
+ 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 needs to return the final Topojson *Object*.
574
+ @param {Object|String} *data* = `undefined`
575
+ @param {Function} [*formatter*]
576
+ @chainable
577
+ */ key: "fitObject",
578
+ value: function fitObject(_, f) {
579
+ if (arguments.length) {
580
+ if (typeof _ === "string") {
581
+ var prev = this._queue.find(function(q) {
582
+ return q[3] === "fitObject";
583
+ });
584
+ var d = [
585
+ load.bind(this),
586
+ _,
587
+ f,
588
+ "fitObject"
589
+ ];
590
+ if (prev) this._queue[this._queue.indexOf(prev)] = d;
591
+ else this._queue.push(d);
592
+ } else {
593
+ this._fitObject = _;
594
+ }
595
+ this._zoomSet = false;
596
+ return this;
597
+ }
598
+ return this._fitObject;
599
+ }
600
+ },
601
+ {
602
+ /**
603
+ @memberof Geomap
604
+ @desc The color visible behind any shapes drawn on the map projection. By default, a color value matching the color used in the map tiles is used to help mask the loading time needed to render the tiles. Any value CSS color value may be used, including hexidecimal, rgb, rgba, and color strings like `"blue"` and `"transparent"`.
605
+ @param {String} [*value* = "#d4dadc"]
606
+ @chainable
607
+ */ key: "ocean",
608
+ value: function ocean(_) {
609
+ return arguments.length ? (this._ocean = _, this) : this._ocean;
610
+ }
611
+ },
612
+ {
613
+ /**
614
+ @memberof Geomap
615
+ @desc The accessor to be used when detecting coordinate points in the objects passed to the [data](https://d3plus.org/docs/#Viz.data) method. Values are expected to be in the format `[longitude, latitude]`, which is in-line with d3's expected coordinate mapping.
616
+ @param {Function|Array} [*value*]
617
+ @chainable
618
+ */ key: "point",
619
+ value: function point(_) {
620
+ return arguments.length ? (this._point = typeof _ === "function" ? _ : constant(_), this) : this._point;
621
+ }
622
+ },
623
+ {
624
+ /**
625
+ @memberof Geomap
626
+ @desc The accessor or static value to be used for sizing coordinate points.
627
+ @param {Function|Number} [*value*]
628
+ @chainable
629
+ */ key: "pointSize",
630
+ value: function pointSize(_) {
631
+ return arguments.length ? (this._pointSize = typeof _ === "function" ? _ : constant(_), this) : this._pointSize;
632
+ }
633
+ },
634
+ {
635
+ /**
636
+ @memberof Geomap
637
+ @desc The maximum pixel radius used in the scale for sizing coordinate points.
638
+ @param {Number} [*value* = 10]
639
+ @chainable
640
+ */ key: "pointSizeMax",
641
+ value: function pointSizeMax(_) {
642
+ return arguments.length ? (this._pointSizeMax = _, this) : this._pointSizeMax;
643
+ }
644
+ },
645
+ {
646
+ /**
647
+ @memberof Geomap
648
+ @desc The minimum pixel radius used in the scale for sizing coordinate points.
649
+ @param {Number} [*value* = 5]
650
+ @chainable
651
+ */ key: "pointSizeMin",
652
+ value: function pointSizeMin(_) {
653
+ return arguments.length ? (this._pointSizeMin = _, this) : this._pointSizeMin;
654
+ }
655
+ },
656
+ {
657
+ /**
658
+ @memberof Geomap
659
+ @desc Sets the map projection used when displaying topojson and coordinate points. All of the projections exported from [d3-geo](https://github.com/d3/d3-geo#projections), [d3-geo-projection](https://github.com/d3/d3-geo-projection#api-reference), and [d3-composite-projections](http://geoexamples.com/d3-composite-projections/) are accepted, whether as the string name (ie. "geoMercator") or the generator function itself. Map tiles are only usable when the projection is set to Mercator (which is also the default value).
660
+ @param {Function|String} *projection* = "geoMercator"
661
+ @chainable
662
+ */ key: "projection",
663
+ value: function projection(_) {
664
+ if (arguments.length && _ !== "geoMercator") this.tiles(false);
665
+ return arguments.length ? (this._projection = typeof _ === "string" ? d3Geo[_] ? d3Geo[_]() : d3Geo.geoMercator() : _, this) : this._projection;
666
+ }
667
+ },
668
+ {
669
+ /**
670
+ @memberof Geomap
671
+ @desc The outer padding between the edge of the visualization and the shapes drawn. The value passed can be either a single number to be used on all sides, or a CSS string pattern (ie. `"20px 0 10px"`).
672
+ @param {Number|String} [*value* = 20]
673
+ @chainable
674
+ */ key: "projectionPadding",
675
+ value: function projectionPadding(_) {
676
+ return arguments.length ? (this._projectionPadding = parseSides(_), this) : this._projectionPadding;
677
+ }
678
+ },
679
+ {
680
+ /**
681
+ @memberof Geomap
682
+ @desc An array that corresponds to the value passed to the projection's [rotate](https://github.com/d3/d3-geo#projection_rotate) function. Use this method to shift the centerpoint of a map.
683
+ @param {Array} [*value* = [0, 0]]
684
+ @chainable
685
+ */ key: "projectionRotate",
686
+ value: function projectionRotate(_) {
687
+ if (arguments.length) {
688
+ this._projection.rotate(_);
689
+ this.tiles(false);
690
+ this._zoomSet = false;
691
+ return this;
692
+ } else {
693
+ return this._projectionRotate;
694
+ }
695
+ }
696
+ },
697
+ {
698
+ /**
699
+ @memberof Geomap
700
+ @desc Toggles the visibility of the map tiles.
701
+ @param {Boolean} [*value* = true]
702
+ @chainable
703
+ */ key: "tiles",
704
+ value: function tiles(_) {
705
+ if (arguments.length) {
706
+ this._tiles = _;
707
+ var attribution = findAttribution(this._tileUrl);
708
+ if (_ && this._attribution === "") this._attribution = attribution;
709
+ else if (!_ && this._attribution === attribution) this._attribution = "";
710
+ return this;
711
+ }
712
+ return this._tiles;
713
+ }
714
+ },
715
+ {
716
+ /**
717
+ @memberof Geomap
718
+ @desc By default, d3plus uses the `light_all` style provided by [CARTO](https://carto.com/location-data-services/basemaps/) for it's map tiles. The [tileUrl](https://d3plus.org/docs/#Geomap.tileUrl) method changes the base URL used for fetching the tiles, as long as the string passed contains `{x}`, `{y}`, and `{z}` variables enclosed in curly brackets for the zoom logic to load the correct tiles.
719
+ @param {String} [url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png"]
720
+ @chainable
721
+ */ key: "tileUrl",
722
+ value: function tileUrl(_) {
723
+ if (arguments.length) {
724
+ this._tileUrl = _;
725
+ if (this._tiles) this._attribution = findAttribution(_);
726
+ if (this._tileGroup) this._renderTiles.bind(this)();
727
+ return this;
728
+ }
729
+ return this._tileUrl;
730
+ }
731
+ },
732
+ {
733
+ /**
734
+ @memberof Geomap
735
+ @desc The topojson to be used for drawing geographical paths. The value passed should either be a valid Topojson *Object* or a *String* representing a filepath or URL to be loaded.
736
+
737
+ 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 Topojson *Obejct*.
738
+ @param {Object|String} *data* = []
739
+ @param {Function} [*formatter*]
740
+ @chainable
741
+ */ key: "topojson",
742
+ value: function topojson(_, f) {
743
+ if (arguments.length) {
744
+ if (typeof _ === "string") {
745
+ var prev = this._queue.find(function(q) {
746
+ return q[3] === "topojson";
747
+ });
748
+ var d = [
749
+ load.bind(this),
750
+ _,
751
+ f,
752
+ "topojson"
753
+ ];
754
+ if (prev) this._queue[this._queue.indexOf(prev)] = d;
755
+ else this._queue.push(d);
756
+ } else {
757
+ this._topojson = _;
758
+ }
759
+ this._zoomSet = false;
760
+ return this;
761
+ }
762
+ return this._topojson;
763
+ }
764
+ },
765
+ {
766
+ /**
767
+ @memberof Geomap
768
+ @desc The function is used to set default color of the map.
769
+ @param {String|Function} *value* = string
770
+ @chainable
771
+ */ key: "topojsonFill",
772
+ value: function topojsonFill(_) {
773
+ return arguments.length ? (this._topojsonFill = typeof _ === "function" ? _ : constant(_), this, this) : this._topojsonFill;
774
+ }
775
+ },
776
+ {
777
+ /**
778
+ @memberof Geomap
779
+ @desc If the [topojson](#Geomap.topojson) being used contains boundaries that should not be shown, this method can be used to filter them out of the final output. The *value* passed can be a single id to remove, an array of ids, or a filter function.
780
+ @param {Number|String|Array|Function} [*value*]
781
+ @chainable
782
+ */ key: "topojsonFilter",
783
+ value: function topojsonFilter(_) {
784
+ if (arguments.length) {
785
+ this._zoomSet = false;
786
+ if (typeof _ === "function") return this._topojsonFilter = _, this;
787
+ if (!_instanceof(_, Array)) _ = [
788
+ _
789
+ ];
790
+ return this._topojsonFilter = function(d) {
791
+ return _.includes(d.id);
792
+ }, this;
793
+ }
794
+ return this._topojsonFilter;
795
+ }
796
+ },
797
+ {
798
+ /**
799
+ @memberof Geomap
800
+ @desc If the [topojson](#Geomap.topojson) contains multiple geographical sets (for example, a file containing state and county boundaries), use this method to indentify which set to use.
801
+
802
+ If not specified, the first key in the *Array* returned from using `Object.keys` on the topojson will be used.
803
+ @param {String} *value*
804
+ @chainable
805
+ */ key: "topojsonKey",
806
+ value: function topojsonKey(_) {
807
+ if (arguments.length) {
808
+ this._topojsonKey = _;
809
+ this._zoomSet = false;
810
+ return this;
811
+ }
812
+ return this._topojsonKey;
813
+ }
814
+ },
815
+ {
816
+ /**
817
+ @memberof Geomap
818
+ @desc The accessor used to map each topojson geometry to it's corresponding [data](https://d3plus.org/docs/#Viz.data) point.
819
+ @param {String|Function} *value* = "id"
820
+ @chainable
821
+ */ key: "topojsonId",
822
+ value: function topojsonId(_) {
823
+ return arguments.length ? (this._topojsonId = typeof _ === "function" ? _ : accessor(_), this, this) : this._topojsonId;
824
+ }
825
+ }
826
+ ]);
827
+ return Geomap;
828
+ }(Viz);
829
+ /**
830
+ @class Geomap
831
+ @extends Viz
832
+ @desc Creates a geographical map with zooming, panning, image tiles, and the ability to layer choropleth paths and coordinate points. See [this example](https://d3plus.org/examples/d3plus-geomap/getting-started/) for help getting started.
833
+ */ export { Geomap as default };