plotly.js 2.15.1 → 2.16.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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * plotly.js (mapbox) v2.15.1
2
+ * plotly.js (mapbox) v2.16.0
3
3
  * Copyright 2012-2022, Plotly, Inc.
4
4
  * All rights reserved.
5
5
  * Licensed under the MIT license
@@ -120428,6 +120428,21 @@ var attrs = module.exports = overrideAll({
120428
120428
  dflt: 0,
120429
120429
  },
120430
120430
 
120431
+ bounds: {
120432
+ west: {
120433
+ valType: 'number',
120434
+ },
120435
+ east: {
120436
+ valType: 'number',
120437
+ },
120438
+ south: {
120439
+ valType: 'number',
120440
+ },
120441
+ north: {
120442
+ valType: 'number',
120443
+ }
120444
+ },
120445
+
120431
120446
  layers: templatedArray('layer', {
120432
120447
  visible: {
120433
120448
  valType: 'boolean',
@@ -120573,6 +120588,19 @@ function handleDefaults(containerIn, containerOut, coerce, opts) {
120573
120588
  coerce('bearing');
120574
120589
  coerce('pitch');
120575
120590
 
120591
+ var west = coerce('bounds.west');
120592
+ var east = coerce('bounds.east');
120593
+ var south = coerce('bounds.south');
120594
+ var north = coerce('bounds.north');
120595
+ if(
120596
+ west === undefined ||
120597
+ east === undefined ||
120598
+ south === undefined ||
120599
+ north === undefined
120600
+ ) {
120601
+ delete containerOut.bounds;
120602
+ }
120603
+
120576
120604
  handleArrayContainerDefaults(containerIn, containerOut, {
120577
120605
  name: 'layers',
120578
120606
  handleItemDefaults: handleLayerDefaults
@@ -120738,6 +120766,9 @@ proto.createMap = function(calcData, fullLayout, resolve, reject) {
120738
120766
  // store access token associated with this map
120739
120767
  self.accessToken = opts.accesstoken;
120740
120768
 
120769
+ var bounds = opts.bounds;
120770
+ var maxBounds = bounds ? [[bounds.west, bounds.south], [bounds.east, bounds.north]] : null;
120771
+
120741
120772
  // create the map!
120742
120773
  var map = self.map = new mapboxgl.Map({
120743
120774
  container: self.div,
@@ -120747,6 +120778,7 @@ proto.createMap = function(calcData, fullLayout, resolve, reject) {
120747
120778
  zoom: opts.zoom,
120748
120779
  bearing: opts.bearing,
120749
120780
  pitch: opts.pitch,
120781
+ maxBounds: maxBounds,
120750
120782
 
120751
120783
  interactive: !self.isStatic,
120752
120784
  preserveDrawingBuffer: self.isStatic,
@@ -130732,6 +130764,7 @@ var colorScaleAttrs = _dereq_('../../components/colorscale/attributes');
130732
130764
 
130733
130765
  var extendFlat = _dereq_('../../lib/extend').extendFlat;
130734
130766
  var overrideAll = _dereq_('../../plot_api/edit_types').overrideAll;
130767
+ var mapboxLayoutAtributes = _dereq_('../../plots/mapbox/layout_attributes');
130735
130768
 
130736
130769
  var lineAttrs = scatterGeoAttrs.line;
130737
130770
  var markerAttrs = scatterGeoAttrs.marker;
@@ -130740,6 +130773,33 @@ module.exports = overrideAll({
130740
130773
  lon: scatterGeoAttrs.lon,
130741
130774
  lat: scatterGeoAttrs.lat,
130742
130775
 
130776
+ cluster: {
130777
+ enabled: {
130778
+ valType: 'boolean',
130779
+ },
130780
+ maxzoom: extendFlat({}, mapboxLayoutAtributes.layers.maxzoom, {
130781
+ }),
130782
+ step: {
130783
+ valType: 'number',
130784
+ arrayOk: true,
130785
+ dflt: -1,
130786
+ min: -1,
130787
+ },
130788
+ size: {
130789
+ valType: 'number',
130790
+ arrayOk: true,
130791
+ dflt: 20,
130792
+ min: 0,
130793
+ },
130794
+ color: {
130795
+ valType: 'color',
130796
+ arrayOk: true,
130797
+ },
130798
+ opacity: extendFlat({}, markerAttrs.opacity, {
130799
+ dflt: 1
130800
+ })
130801
+ },
130802
+
130743
130803
  // locations
130744
130804
  // locationmode
130745
130805
 
@@ -130842,11 +130902,12 @@ module.exports = function convert(gd, calcTrace) {
130842
130902
  var hasText = subTypes.hasText(trace);
130843
130903
  var hasCircles = (hasMarkers && trace.marker.symbol === 'circle');
130844
130904
  var hasSymbols = (hasMarkers && trace.marker.symbol !== 'circle');
130905
+ var hasCluster = trace.cluster && trace.cluster.enabled;
130845
130906
 
130846
- var fill = initContainer();
130847
- var line = initContainer();
130848
- var circle = initContainer();
130849
- var symbol = initContainer();
130907
+ var fill = initContainer('fill');
130908
+ var line = initContainer('line');
130909
+ var circle = initContainer('circle');
130910
+ var symbol = initContainer('symbol');
130850
130911
 
130851
130912
  var opts = {
130852
130913
  fill: fill,
@@ -130890,6 +130951,29 @@ module.exports = function convert(gd, calcTrace) {
130890
130951
  var circleOpts = makeCircleOpts(calcTrace);
130891
130952
  circle.geojson = circleOpts.geojson;
130892
130953
  circle.layout.visibility = 'visible';
130954
+ if(hasCluster) {
130955
+ circle.filter = ['!', ['has', 'point_count']];
130956
+ opts.cluster = {
130957
+ type: 'circle',
130958
+ filter: ['has', 'point_count'],
130959
+ layout: {visibility: 'visible'},
130960
+ paint: {
130961
+ 'circle-color': arrayifyAttribute(trace.cluster.color, trace.cluster.step),
130962
+ 'circle-radius': arrayifyAttribute(trace.cluster.size, trace.cluster.step),
130963
+ 'circle-opacity': arrayifyAttribute(trace.cluster.opacity, trace.cluster.step),
130964
+ },
130965
+ };
130966
+ opts.clusterCount = {
130967
+ type: 'symbol',
130968
+ filter: ['has', 'point_count'],
130969
+ paint: {},
130970
+ layout: {
130971
+ 'text-field': '{point_count_abbreviated}',
130972
+ 'text-font': ['Open Sans Regular', 'Arial Unicode MS Regular'],
130973
+ 'text-size': 12
130974
+ }
130975
+ };
130976
+ }
130893
130977
 
130894
130978
  Lib.extendFlat(circle.paint, {
130895
130979
  'circle-color': circleOpts.mcc,
@@ -130898,6 +130982,10 @@ module.exports = function convert(gd, calcTrace) {
130898
130982
  });
130899
130983
  }
130900
130984
 
130985
+ if(hasCircles && hasCluster) {
130986
+ circle.filter = ['!', ['has', 'point_count']];
130987
+ }
130988
+
130901
130989
  if(hasSymbols || hasText) {
130902
130990
  symbol.geojson = makeSymbolGeoJSON(calcTrace, gd);
130903
130991
 
@@ -130958,10 +131046,12 @@ module.exports = function convert(gd, calcTrace) {
130958
131046
  return opts;
130959
131047
  };
130960
131048
 
130961
- function initContainer() {
131049
+ function initContainer(type) {
130962
131050
  return {
131051
+ type: type,
130963
131052
  geojson: geoJsonUtils.makeBlank(),
130964
131053
  layout: { visibility: 'none' },
131054
+ filter: null,
130965
131055
  paint: {}
130966
131056
  };
130967
131057
  }
@@ -131016,7 +131106,8 @@ function makeCircleOpts(calcTrace) {
131016
131106
 
131017
131107
  features.push({
131018
131108
  type: 'Feature',
131019
- geometry: {type: 'Point', coordinates: lonlat},
131109
+ id: i + 1,
131110
+ geometry: { type: 'Point', coordinates: lonlat },
131020
131111
  properties: props
131021
131112
  });
131022
131113
  }
@@ -131140,6 +131231,20 @@ function isBADNUM(lonlat) {
131140
131231
  return lonlat[0] === BADNUM;
131141
131232
  }
131142
131233
 
131234
+ function arrayifyAttribute(values, step) {
131235
+ var newAttribute;
131236
+ if(Lib.isArrayOrTypedArray(values) && Lib.isArrayOrTypedArray(step)) {
131237
+ newAttribute = ['step', ['get', 'point_count'], values[0]];
131238
+
131239
+ for(var idx = 1; idx < values.length; idx++) {
131240
+ newAttribute.push(step[idx - 1], values[idx]);
131241
+ }
131242
+ } else {
131243
+ newAttribute = values;
131244
+ }
131245
+ return newAttribute;
131246
+ }
131247
+
131143
131248
  },{"../../components/colorscale":127,"../../components/drawing":137,"../../components/fx/helpers":151,"../../constants/numerical":236,"../../lib":258,"../../lib/geojson_utils":254,"../../lib/svg_text_utils":281,"../../plots/mapbox/convert_text_opts":339,"../scatter/make_bubble_size_func":397,"../scatter/subtypes":405,"fast-isnumeric":28}],412:[function(_dereq_,module,exports){
131144
131249
  'use strict';
131145
131250
 
@@ -131157,6 +131262,10 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
131157
131262
  return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);
131158
131263
  }
131159
131264
 
131265
+ function coerce2(attr, dflt) {
131266
+ return Lib.coerce2(traceIn, traceOut, attributes, attr, dflt);
131267
+ }
131268
+
131160
131269
  var len = handleLonLatDefaults(traceIn, traceOut, coerce);
131161
131270
  if(!len) {
131162
131271
  traceOut.visible = false;
@@ -131189,6 +131298,21 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
131189
131298
  }
131190
131299
  }
131191
131300
 
131301
+ var clusterMaxzoom = coerce2('cluster.maxzoom');
131302
+ var clusterStep = coerce2('cluster.step');
131303
+ var clusterColor = coerce2('cluster.color', (traceOut.marker && traceOut.marker.color) || defaultColor);
131304
+ var clusterSize = coerce2('cluster.size');
131305
+ var clusterOpacity = coerce2('cluster.opacity');
131306
+
131307
+ var clusterEnabledDflt =
131308
+ clusterMaxzoom !== false ||
131309
+ clusterStep !== false ||
131310
+ clusterColor !== false ||
131311
+ clusterSize !== false ||
131312
+ clusterOpacity !== false;
131313
+
131314
+ coerce('cluster.enabled', clusterEnabledDflt);
131315
+
131192
131316
  if(subTypes.hasText(traceOut)) {
131193
131317
  handleTextDefaults(traceIn, traceOut, layout, coerce, {noSelect: true});
131194
131318
  }
@@ -131247,6 +131371,7 @@ var Lib = _dereq_('../../lib');
131247
131371
  var getTraceColor = _dereq_('../scatter/get_trace_color');
131248
131372
  var fillText = Lib.fillText;
131249
131373
  var BADNUM = _dereq_('../../constants/numerical').BADNUM;
131374
+ var LAYER_PREFIX = _dereq_('../../plots/mapbox/constants').traceLayerPrefix;
131250
131375
 
131251
131376
  function hoverPoints(pointData, xval, yval) {
131252
131377
  var cd = pointData.cd;
@@ -131254,6 +131379,14 @@ function hoverPoints(pointData, xval, yval) {
131254
131379
  var xa = pointData.xa;
131255
131380
  var ya = pointData.ya;
131256
131381
  var subplot = pointData.subplot;
131382
+ var clusteredPointsIds = [];
131383
+ var layer = LAYER_PREFIX + trace.uid + '-circle';
131384
+ var hasCluster = trace.cluster && trace.cluster.enabled;
131385
+
131386
+ if(hasCluster) {
131387
+ var elems = subplot.map.queryRenderedFeatures(null, {layers: [layer]});
131388
+ clusteredPointsIds = elems.map(function(elem) {return elem.id;});
131389
+ }
131257
131390
 
131258
131391
  // compute winding number about [-180, 180] globe
131259
131392
  var winding = (xval >= 0) ?
@@ -131267,6 +131400,7 @@ function hoverPoints(pointData, xval, yval) {
131267
131400
  function distFn(d) {
131268
131401
  var lonlat = d.lonlat;
131269
131402
  if(lonlat[0] === BADNUM) return Infinity;
131403
+ if(hasCluster && clusteredPointsIds.indexOf(d.i + 1) === -1) return Infinity;
131270
131404
 
131271
131405
  var lon = Lib.modHalf(lonlat[0], 360);
131272
131406
  var lat = lonlat[1];
@@ -131347,7 +131481,7 @@ module.exports = {
131347
131481
  getExtraText: getExtraText
131348
131482
  };
131349
131483
 
131350
- },{"../../components/fx":155,"../../constants/numerical":236,"../../lib":258,"../scatter/get_trace_color":390}],416:[function(_dereq_,module,exports){
131484
+ },{"../../components/fx":155,"../../constants/numerical":236,"../../lib":258,"../../plots/mapbox/constants":338,"../scatter/get_trace_color":390}],416:[function(_dereq_,module,exports){
131351
131485
  'use strict';
131352
131486
 
131353
131487
  module.exports = {
@@ -131379,27 +131513,36 @@ module.exports = {
131379
131513
  },{"../../plots/mapbox":340,"../scatter/marker_colorbar":398,"../scattergeo/calc":409,"./attributes":410,"./defaults":412,"./event_data":413,"./format_labels":414,"./hover":415,"./plot":417,"./select":418}],417:[function(_dereq_,module,exports){
131380
131514
  'use strict';
131381
131515
 
131516
+ var Lib = _dereq_('../../lib');
131382
131517
  var convert = _dereq_('./convert');
131383
131518
  var LAYER_PREFIX = _dereq_('../../plots/mapbox/constants').traceLayerPrefix;
131384
- var ORDER = ['fill', 'line', 'circle', 'symbol'];
131519
+ var ORDER = {
131520
+ cluster: ['cluster', 'clusterCount', 'circle'],
131521
+ nonCluster: ['fill', 'line', 'circle', 'symbol'],
131522
+ };
131385
131523
 
131386
- function ScatterMapbox(subplot, uid) {
131524
+ function ScatterMapbox(subplot, uid, clusterEnabled) {
131387
131525
  this.type = 'scattermapbox';
131388
131526
  this.subplot = subplot;
131389
131527
  this.uid = uid;
131528
+ this.clusterEnabled = clusterEnabled;
131390
131529
 
131391
131530
  this.sourceIds = {
131392
131531
  fill: 'source-' + uid + '-fill',
131393
131532
  line: 'source-' + uid + '-line',
131394
131533
  circle: 'source-' + uid + '-circle',
131395
- symbol: 'source-' + uid + '-symbol'
131534
+ symbol: 'source-' + uid + '-symbol',
131535
+ cluster: 'source-' + uid + '-circle',
131536
+ clusterCount: 'source-' + uid + '-circle',
131396
131537
  };
131397
131538
 
131398
131539
  this.layerIds = {
131399
131540
  fill: LAYER_PREFIX + uid + '-fill',
131400
131541
  line: LAYER_PREFIX + uid + '-line',
131401
131542
  circle: LAYER_PREFIX + uid + '-circle',
131402
- symbol: LAYER_PREFIX + uid + '-symbol'
131543
+ symbol: LAYER_PREFIX + uid + '-symbol',
131544
+ cluster: LAYER_PREFIX + uid + '-cluster',
131545
+ clusterCount: LAYER_PREFIX + uid + '-cluster-count',
131403
131546
  };
131404
131547
 
131405
131548
  // We could merge the 'fill' source with the 'line' source and
@@ -131413,11 +131556,20 @@ function ScatterMapbox(subplot, uid) {
131413
131556
 
131414
131557
  var proto = ScatterMapbox.prototype;
131415
131558
 
131416
- proto.addSource = function(k, opts) {
131417
- this.subplot.map.addSource(this.sourceIds[k], {
131559
+ proto.addSource = function(k, opts, cluster) {
131560
+ var sourceOpts = {
131418
131561
  type: 'geojson',
131419
- data: opts.geojson
131420
- });
131562
+ data: opts.geojson,
131563
+ };
131564
+
131565
+ if(cluster && cluster.enabled) {
131566
+ Lib.extendFlat(sourceOpts, {
131567
+ cluster: true,
131568
+ clusterMaxZoom: cluster.maxzoom,
131569
+ });
131570
+ }
131571
+
131572
+ this.subplot.map.addSource(this.sourceIds[k], sourceOpts);
131421
131573
  };
131422
131574
 
131423
131575
  proto.setSourceData = function(k, opts) {
@@ -131427,56 +131579,79 @@ proto.setSourceData = function(k, opts) {
131427
131579
  };
131428
131580
 
131429
131581
  proto.addLayer = function(k, opts, below) {
131430
- this.subplot.addLayer({
131431
- type: k,
131582
+ var source = {
131583
+ type: opts.type,
131432
131584
  id: this.layerIds[k],
131433
131585
  source: this.sourceIds[k],
131434
131586
  layout: opts.layout,
131435
- paint: opts.paint
131436
- }, below);
131587
+ paint: opts.paint,
131588
+ };
131589
+ if(opts.filter) {
131590
+ source.filter = opts.filter;
131591
+ }
131592
+ this.subplot.addLayer(source, below);
131437
131593
  };
131438
131594
 
131439
131595
  proto.update = function update(calcTrace) {
131596
+ var trace = calcTrace[0].trace;
131440
131597
  var subplot = this.subplot;
131441
131598
  var map = subplot.map;
131442
131599
  var optsAll = convert(subplot.gd, calcTrace);
131443
131600
  var below = subplot.belowLookup['trace-' + this.uid];
131444
131601
  var i, k, opts;
131602
+ var hasCluster = !!(trace.cluster && trace.cluster.enabled);
131603
+ var hadCluster = !!this.clusterEnabled;
131445
131604
 
131446
131605
  if(below !== this.below) {
131447
- for(i = ORDER.length - 1; i >= 0; i--) {
131448
- k = ORDER[i];
131606
+ var order = ORDER.nonCluster;
131607
+
131608
+ for(i = order.length - 1; i >= 0; i--) {
131609
+ k = order[i];
131449
131610
  map.removeLayer(this.layerIds[k]);
131450
131611
  }
131451
- for(i = 0; i < ORDER.length; i++) {
131452
- k = ORDER[i];
131612
+ for(i = 0; i < order.length; i++) {
131613
+ k = order[i];
131453
131614
  opts = optsAll[k];
131454
131615
  this.addLayer(k, opts, below);
131455
131616
  }
131456
131617
  this.below = below;
131457
- }
131458
-
131459
- for(i = 0; i < ORDER.length; i++) {
131460
- k = ORDER[i];
131461
- opts = optsAll[k];
131462
-
131463
- subplot.setOptions(this.layerIds[k], 'setLayoutProperty', opts.layout);
131464
-
131465
- if(opts.layout.visibility === 'visible') {
131466
- this.setSourceData(k, opts);
131467
- subplot.setOptions(this.layerIds[k], 'setPaintProperty', opts.paint);
131618
+ } else if(hasCluster && !hadCluster) {
131619
+ for(i = ORDER.nonCluster.length - 1; i >= 0; i--) {
131620
+ k = ORDER.nonCluster[i];
131621
+ map.removeLayer(this.layerIds[k]);
131622
+ map.removeSource(this.sourceIds[k]);
131623
+ }
131624
+ this.addSource('circle', optsAll.circle, trace.cluster);
131625
+ for(i = 0; i < ORDER.cluster.length; i++) {
131626
+ k = ORDER.cluster[i];
131627
+ opts = optsAll[k];
131628
+ this.addLayer(k, opts, below);
131629
+ }
131630
+ this.clusterEnabled = hasCluster;
131631
+ } else if(!hasCluster && hadCluster) {
131632
+ for(i = 0; i < ORDER.cluster.length; i++) {
131633
+ k = ORDER.cluster[i];
131634
+ map.removeLayer(this.layerIds[k]);
131635
+ }
131636
+ map.removeSource(this.sourceIds.circle);
131637
+ for(i = 0; i < ORDER.nonCluster.length; i++) {
131638
+ k = ORDER.nonCluster[i];
131639
+ opts = optsAll[k];
131640
+ this.addSource(k, opts, trace.cluster);
131641
+ this.addLayer(k, opts, below);
131468
131642
  }
131643
+ this.clusterEnabled = hasCluster;
131469
131644
  }
131470
131645
 
131471
- // link ref for quick update during selections
131646
+ // link ref for quick update during selections
131472
131647
  calcTrace[0].trace._glTrace = this;
131473
131648
  };
131474
131649
 
131475
131650
  proto.dispose = function dispose() {
131476
131651
  var map = this.subplot.map;
131477
-
131478
- for(var i = ORDER.length - 1; i >= 0; i--) {
131479
- var k = ORDER[i];
131652
+ var order = this.clusterEnabled ? ORDER.cluster : ORDER.nonCluster;
131653
+ for(var i = order.length - 1; i >= 0; i--) {
131654
+ var k = order[i];
131480
131655
  map.removeLayer(this.layerIds[k]);
131481
131656
  map.removeSource(this.sourceIds[k]);
131482
131657
  }
@@ -131484,15 +131659,31 @@ proto.dispose = function dispose() {
131484
131659
 
131485
131660
  module.exports = function createScatterMapbox(subplot, calcTrace) {
131486
131661
  var trace = calcTrace[0].trace;
131487
- var scatterMapbox = new ScatterMapbox(subplot, trace.uid);
131662
+ var hasCluster = trace.cluster && trace.cluster.enabled;
131663
+ var scatterMapbox = new ScatterMapbox(
131664
+ subplot,
131665
+ trace.uid,
131666
+ hasCluster
131667
+ );
131668
+
131488
131669
  var optsAll = convert(subplot.gd, calcTrace);
131489
131670
  var below = scatterMapbox.below = subplot.belowLookup['trace-' + trace.uid];
131671
+ var i, k, opts;
131490
131672
 
131491
- for(var i = 0; i < ORDER.length; i++) {
131492
- var k = ORDER[i];
131493
- var opts = optsAll[k];
131494
- scatterMapbox.addSource(k, opts);
131495
- scatterMapbox.addLayer(k, opts, below);
131673
+ if(hasCluster) {
131674
+ scatterMapbox.addSource('circle', optsAll.circle, trace.cluster);
131675
+ for(i = 0; i < ORDER.cluster.length; i++) {
131676
+ k = ORDER.cluster[i];
131677
+ opts = optsAll[k];
131678
+ scatterMapbox.addLayer(k, opts, below);
131679
+ }
131680
+ } else {
131681
+ for(i = 0; i < ORDER.nonCluster.length; i++) {
131682
+ k = ORDER.nonCluster[i];
131683
+ opts = optsAll[k];
131684
+ scatterMapbox.addSource(k, opts, trace.cluster);
131685
+ scatterMapbox.addLayer(k, opts, below);
131686
+ }
131496
131687
  }
131497
131688
 
131498
131689
  // link ref for quick update during selections
@@ -131501,7 +131692,7 @@ module.exports = function createScatterMapbox(subplot, calcTrace) {
131501
131692
  return scatterMapbox;
131502
131693
  };
131503
131694
 
131504
- },{"../../plots/mapbox/constants":338,"./convert":411}],418:[function(_dereq_,module,exports){
131695
+ },{"../../lib":258,"../../plots/mapbox/constants":338,"./convert":411}],418:[function(_dereq_,module,exports){
131505
131696
  'use strict';
131506
131697
 
131507
131698
  var Lib = _dereq_('../../lib');
@@ -132616,7 +132807,7 @@ function getSortFunc(opts, d2c) {
132616
132807
  'use strict';
132617
132808
 
132618
132809
  // package version injected by `npm run preprocess`
132619
- exports.version = '2.15.1';
132810
+ exports.version = '2.16.0';
132620
132811
 
132621
132812
  },{}]},{},[9])(9)
132622
132813
  });