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.
- package/CHANGELOG.md +8 -0
- package/README.md +3 -3
- package/dist/README.md +19 -19
- package/dist/plot-schema.json +92 -0
- package/dist/plotly-basic.js +2 -2
- package/dist/plotly-basic.min.js +2 -2
- package/dist/plotly-cartesian.js +2 -2
- package/dist/plotly-cartesian.min.js +2 -2
- package/dist/plotly-finance.js +2 -2
- package/dist/plotly-finance.min.js +2 -2
- package/dist/plotly-geo-assets.js +2 -2
- package/dist/plotly-geo.js +2 -2
- package/dist/plotly-geo.min.js +2 -2
- package/dist/plotly-gl2d.js +2 -2
- package/dist/plotly-gl2d.min.js +2 -2
- package/dist/plotly-gl3d.js +2 -2
- package/dist/plotly-gl3d.min.js +2 -2
- package/dist/plotly-mapbox.js +238 -47
- package/dist/plotly-mapbox.min.js +3 -3
- package/dist/plotly-strict.js +238 -47
- package/dist/plotly-strict.min.js +11 -11
- package/dist/plotly-with-meta.js +271 -47
- package/dist/plotly.js +238 -47
- package/dist/plotly.min.js +2 -2
- package/package.json +1 -1
- package/src/plots/mapbox/layout_attributes.js +31 -0
- package/src/plots/mapbox/layout_defaults.js +13 -0
- package/src/plots/mapbox/mapbox.js +4 -0
- package/src/traces/scattermapbox/attributes.js +45 -0
- package/src/traces/scattermapbox/convert.js +51 -6
- package/src/traces/scattermapbox/defaults.js +19 -0
- package/src/traces/scattermapbox/hover.js +10 -0
- package/src/traces/scattermapbox/plot.js +94 -37
- package/src/version.js +1 -1
package/package.json
CHANGED
|
@@ -95,6 +95,37 @@ var attrs = module.exports = overrideAll({
|
|
|
95
95
|
].join(' ')
|
|
96
96
|
},
|
|
97
97
|
|
|
98
|
+
bounds: {
|
|
99
|
+
west: {
|
|
100
|
+
valType: 'number',
|
|
101
|
+
description: [
|
|
102
|
+
'Sets the minimum longitude of the map (in degrees East)',
|
|
103
|
+
'if `east`, `south` and `north` are declared.'
|
|
104
|
+
].join(' ')
|
|
105
|
+
},
|
|
106
|
+
east: {
|
|
107
|
+
valType: 'number',
|
|
108
|
+
description: [
|
|
109
|
+
'Sets the maximum longitude of the map (in degrees East)',
|
|
110
|
+
'if `west`, `south` and `north` are declared.'
|
|
111
|
+
].join(' ')
|
|
112
|
+
},
|
|
113
|
+
south: {
|
|
114
|
+
valType: 'number',
|
|
115
|
+
description: [
|
|
116
|
+
'Sets the minimum latitude of the map (in degrees North)',
|
|
117
|
+
'if `east`, `west` and `north` are declared.'
|
|
118
|
+
].join(' ')
|
|
119
|
+
},
|
|
120
|
+
north: {
|
|
121
|
+
valType: 'number',
|
|
122
|
+
description: [
|
|
123
|
+
'Sets the maximum latitude of the map (in degrees North)',
|
|
124
|
+
'if `east`, `west` and `south` are declared.'
|
|
125
|
+
].join(' ')
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
|
|
98
129
|
layers: templatedArray('layer', {
|
|
99
130
|
visible: {
|
|
100
131
|
valType: 'boolean',
|
|
@@ -26,6 +26,19 @@ function handleDefaults(containerIn, containerOut, coerce, opts) {
|
|
|
26
26
|
coerce('bearing');
|
|
27
27
|
coerce('pitch');
|
|
28
28
|
|
|
29
|
+
var west = coerce('bounds.west');
|
|
30
|
+
var east = coerce('bounds.east');
|
|
31
|
+
var south = coerce('bounds.south');
|
|
32
|
+
var north = coerce('bounds.north');
|
|
33
|
+
if(
|
|
34
|
+
west === undefined ||
|
|
35
|
+
east === undefined ||
|
|
36
|
+
south === undefined ||
|
|
37
|
+
north === undefined
|
|
38
|
+
) {
|
|
39
|
+
delete containerOut.bounds;
|
|
40
|
+
}
|
|
41
|
+
|
|
29
42
|
handleArrayContainerDefaults(containerIn, containerOut, {
|
|
30
43
|
name: 'layers',
|
|
31
44
|
handleItemDefaults: handleLayerDefaults
|
|
@@ -91,6 +91,9 @@ proto.createMap = function(calcData, fullLayout, resolve, reject) {
|
|
|
91
91
|
// store access token associated with this map
|
|
92
92
|
self.accessToken = opts.accesstoken;
|
|
93
93
|
|
|
94
|
+
var bounds = opts.bounds;
|
|
95
|
+
var maxBounds = bounds ? [[bounds.west, bounds.south], [bounds.east, bounds.north]] : null;
|
|
96
|
+
|
|
94
97
|
// create the map!
|
|
95
98
|
var map = self.map = new mapboxgl.Map({
|
|
96
99
|
container: self.div,
|
|
@@ -100,6 +103,7 @@ proto.createMap = function(calcData, fullLayout, resolve, reject) {
|
|
|
100
103
|
zoom: opts.zoom,
|
|
101
104
|
bearing: opts.bearing,
|
|
102
105
|
pitch: opts.pitch,
|
|
106
|
+
maxBounds: maxBounds,
|
|
103
107
|
|
|
104
108
|
interactive: !self.isStatic,
|
|
105
109
|
preserveDrawingBuffer: self.isStatic,
|
|
@@ -10,6 +10,7 @@ var colorScaleAttrs = require('../../components/colorscale/attributes');
|
|
|
10
10
|
|
|
11
11
|
var extendFlat = require('../../lib/extend').extendFlat;
|
|
12
12
|
var overrideAll = require('../../plot_api/edit_types').overrideAll;
|
|
13
|
+
var mapboxLayoutAtributes = require('../../plots/mapbox/layout_attributes');
|
|
13
14
|
|
|
14
15
|
var lineAttrs = scatterGeoAttrs.line;
|
|
15
16
|
var markerAttrs = scatterGeoAttrs.marker;
|
|
@@ -18,6 +19,50 @@ module.exports = overrideAll({
|
|
|
18
19
|
lon: scatterGeoAttrs.lon,
|
|
19
20
|
lat: scatterGeoAttrs.lat,
|
|
20
21
|
|
|
22
|
+
cluster: {
|
|
23
|
+
enabled: {
|
|
24
|
+
valType: 'boolean',
|
|
25
|
+
description: 'Determines whether clustering is enabled or disabled.'
|
|
26
|
+
},
|
|
27
|
+
maxzoom: extendFlat({}, mapboxLayoutAtributes.layers.maxzoom, {
|
|
28
|
+
description: [
|
|
29
|
+
'Sets the maximum zoom level.',
|
|
30
|
+
'At zoom levels equal to or greater than this, points will never be clustered.'
|
|
31
|
+
].join(' ')
|
|
32
|
+
}),
|
|
33
|
+
step: {
|
|
34
|
+
valType: 'number',
|
|
35
|
+
arrayOk: true,
|
|
36
|
+
dflt: -1,
|
|
37
|
+
min: -1,
|
|
38
|
+
description: [
|
|
39
|
+
'Sets how many points it takes to create a cluster or advance to the next cluster step.',
|
|
40
|
+
'Use this in conjunction with arrays for `size` and / or `color`.',
|
|
41
|
+
'If an integer, steps start at multiples of this number.',
|
|
42
|
+
'If an array, each step extends from the given value until one less than the next value.'
|
|
43
|
+
].join(' ')
|
|
44
|
+
},
|
|
45
|
+
size: {
|
|
46
|
+
valType: 'number',
|
|
47
|
+
arrayOk: true,
|
|
48
|
+
dflt: 20,
|
|
49
|
+
min: 0,
|
|
50
|
+
description: [
|
|
51
|
+
'Sets the size for each cluster step.'
|
|
52
|
+
].join(' ')
|
|
53
|
+
},
|
|
54
|
+
color: {
|
|
55
|
+
valType: 'color',
|
|
56
|
+
arrayOk: true,
|
|
57
|
+
description: [
|
|
58
|
+
'Sets the color for each cluster step.'
|
|
59
|
+
].join(' ')
|
|
60
|
+
},
|
|
61
|
+
opacity: extendFlat({}, markerAttrs.opacity, {
|
|
62
|
+
dflt: 1
|
|
63
|
+
})
|
|
64
|
+
},
|
|
65
|
+
|
|
21
66
|
// locations
|
|
22
67
|
// locationmode
|
|
23
68
|
|
|
@@ -26,11 +26,12 @@ module.exports = function convert(gd, calcTrace) {
|
|
|
26
26
|
var hasText = subTypes.hasText(trace);
|
|
27
27
|
var hasCircles = (hasMarkers && trace.marker.symbol === 'circle');
|
|
28
28
|
var hasSymbols = (hasMarkers && trace.marker.symbol !== 'circle');
|
|
29
|
+
var hasCluster = trace.cluster && trace.cluster.enabled;
|
|
29
30
|
|
|
30
|
-
var fill = initContainer();
|
|
31
|
-
var line = initContainer();
|
|
32
|
-
var circle = initContainer();
|
|
33
|
-
var symbol = initContainer();
|
|
31
|
+
var fill = initContainer('fill');
|
|
32
|
+
var line = initContainer('line');
|
|
33
|
+
var circle = initContainer('circle');
|
|
34
|
+
var symbol = initContainer('symbol');
|
|
34
35
|
|
|
35
36
|
var opts = {
|
|
36
37
|
fill: fill,
|
|
@@ -74,6 +75,29 @@ module.exports = function convert(gd, calcTrace) {
|
|
|
74
75
|
var circleOpts = makeCircleOpts(calcTrace);
|
|
75
76
|
circle.geojson = circleOpts.geojson;
|
|
76
77
|
circle.layout.visibility = 'visible';
|
|
78
|
+
if(hasCluster) {
|
|
79
|
+
circle.filter = ['!', ['has', 'point_count']];
|
|
80
|
+
opts.cluster = {
|
|
81
|
+
type: 'circle',
|
|
82
|
+
filter: ['has', 'point_count'],
|
|
83
|
+
layout: {visibility: 'visible'},
|
|
84
|
+
paint: {
|
|
85
|
+
'circle-color': arrayifyAttribute(trace.cluster.color, trace.cluster.step),
|
|
86
|
+
'circle-radius': arrayifyAttribute(trace.cluster.size, trace.cluster.step),
|
|
87
|
+
'circle-opacity': arrayifyAttribute(trace.cluster.opacity, trace.cluster.step),
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
opts.clusterCount = {
|
|
91
|
+
type: 'symbol',
|
|
92
|
+
filter: ['has', 'point_count'],
|
|
93
|
+
paint: {},
|
|
94
|
+
layout: {
|
|
95
|
+
'text-field': '{point_count_abbreviated}',
|
|
96
|
+
'text-font': ['Open Sans Regular', 'Arial Unicode MS Regular'],
|
|
97
|
+
'text-size': 12
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
77
101
|
|
|
78
102
|
Lib.extendFlat(circle.paint, {
|
|
79
103
|
'circle-color': circleOpts.mcc,
|
|
@@ -82,6 +106,10 @@ module.exports = function convert(gd, calcTrace) {
|
|
|
82
106
|
});
|
|
83
107
|
}
|
|
84
108
|
|
|
109
|
+
if(hasCircles && hasCluster) {
|
|
110
|
+
circle.filter = ['!', ['has', 'point_count']];
|
|
111
|
+
}
|
|
112
|
+
|
|
85
113
|
if(hasSymbols || hasText) {
|
|
86
114
|
symbol.geojson = makeSymbolGeoJSON(calcTrace, gd);
|
|
87
115
|
|
|
@@ -142,10 +170,12 @@ module.exports = function convert(gd, calcTrace) {
|
|
|
142
170
|
return opts;
|
|
143
171
|
};
|
|
144
172
|
|
|
145
|
-
function initContainer() {
|
|
173
|
+
function initContainer(type) {
|
|
146
174
|
return {
|
|
175
|
+
type: type,
|
|
147
176
|
geojson: geoJsonUtils.makeBlank(),
|
|
148
177
|
layout: { visibility: 'none' },
|
|
178
|
+
filter: null,
|
|
149
179
|
paint: {}
|
|
150
180
|
};
|
|
151
181
|
}
|
|
@@ -200,7 +230,8 @@ function makeCircleOpts(calcTrace) {
|
|
|
200
230
|
|
|
201
231
|
features.push({
|
|
202
232
|
type: 'Feature',
|
|
203
|
-
|
|
233
|
+
id: i + 1,
|
|
234
|
+
geometry: { type: 'Point', coordinates: lonlat },
|
|
204
235
|
properties: props
|
|
205
236
|
});
|
|
206
237
|
}
|
|
@@ -323,3 +354,17 @@ function blankFillFunc() { return ''; }
|
|
|
323
354
|
function isBADNUM(lonlat) {
|
|
324
355
|
return lonlat[0] === BADNUM;
|
|
325
356
|
}
|
|
357
|
+
|
|
358
|
+
function arrayifyAttribute(values, step) {
|
|
359
|
+
var newAttribute;
|
|
360
|
+
if(Lib.isArrayOrTypedArray(values) && Lib.isArrayOrTypedArray(step)) {
|
|
361
|
+
newAttribute = ['step', ['get', 'point_count'], values[0]];
|
|
362
|
+
|
|
363
|
+
for(var idx = 1; idx < values.length; idx++) {
|
|
364
|
+
newAttribute.push(step[idx - 1], values[idx]);
|
|
365
|
+
}
|
|
366
|
+
} else {
|
|
367
|
+
newAttribute = values;
|
|
368
|
+
}
|
|
369
|
+
return newAttribute;
|
|
370
|
+
}
|
|
@@ -14,6 +14,10 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
|
|
|
14
14
|
return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
function coerce2(attr, dflt) {
|
|
18
|
+
return Lib.coerce2(traceIn, traceOut, attributes, attr, dflt);
|
|
19
|
+
}
|
|
20
|
+
|
|
17
21
|
var len = handleLonLatDefaults(traceIn, traceOut, coerce);
|
|
18
22
|
if(!len) {
|
|
19
23
|
traceOut.visible = false;
|
|
@@ -46,6 +50,21 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
|
|
|
46
50
|
}
|
|
47
51
|
}
|
|
48
52
|
|
|
53
|
+
var clusterMaxzoom = coerce2('cluster.maxzoom');
|
|
54
|
+
var clusterStep = coerce2('cluster.step');
|
|
55
|
+
var clusterColor = coerce2('cluster.color', (traceOut.marker && traceOut.marker.color) || defaultColor);
|
|
56
|
+
var clusterSize = coerce2('cluster.size');
|
|
57
|
+
var clusterOpacity = coerce2('cluster.opacity');
|
|
58
|
+
|
|
59
|
+
var clusterEnabledDflt =
|
|
60
|
+
clusterMaxzoom !== false ||
|
|
61
|
+
clusterStep !== false ||
|
|
62
|
+
clusterColor !== false ||
|
|
63
|
+
clusterSize !== false ||
|
|
64
|
+
clusterOpacity !== false;
|
|
65
|
+
|
|
66
|
+
coerce('cluster.enabled', clusterEnabledDflt);
|
|
67
|
+
|
|
49
68
|
if(subTypes.hasText(traceOut)) {
|
|
50
69
|
handleTextDefaults(traceIn, traceOut, layout, coerce, {noSelect: true});
|
|
51
70
|
}
|
|
@@ -5,6 +5,7 @@ var Lib = require('../../lib');
|
|
|
5
5
|
var getTraceColor = require('../scatter/get_trace_color');
|
|
6
6
|
var fillText = Lib.fillText;
|
|
7
7
|
var BADNUM = require('../../constants/numerical').BADNUM;
|
|
8
|
+
var LAYER_PREFIX = require('../../plots/mapbox/constants').traceLayerPrefix;
|
|
8
9
|
|
|
9
10
|
function hoverPoints(pointData, xval, yval) {
|
|
10
11
|
var cd = pointData.cd;
|
|
@@ -12,6 +13,14 @@ function hoverPoints(pointData, xval, yval) {
|
|
|
12
13
|
var xa = pointData.xa;
|
|
13
14
|
var ya = pointData.ya;
|
|
14
15
|
var subplot = pointData.subplot;
|
|
16
|
+
var clusteredPointsIds = [];
|
|
17
|
+
var layer = LAYER_PREFIX + trace.uid + '-circle';
|
|
18
|
+
var hasCluster = trace.cluster && trace.cluster.enabled;
|
|
19
|
+
|
|
20
|
+
if(hasCluster) {
|
|
21
|
+
var elems = subplot.map.queryRenderedFeatures(null, {layers: [layer]});
|
|
22
|
+
clusteredPointsIds = elems.map(function(elem) {return elem.id;});
|
|
23
|
+
}
|
|
15
24
|
|
|
16
25
|
// compute winding number about [-180, 180] globe
|
|
17
26
|
var winding = (xval >= 0) ?
|
|
@@ -25,6 +34,7 @@ function hoverPoints(pointData, xval, yval) {
|
|
|
25
34
|
function distFn(d) {
|
|
26
35
|
var lonlat = d.lonlat;
|
|
27
36
|
if(lonlat[0] === BADNUM) return Infinity;
|
|
37
|
+
if(hasCluster && clusteredPointsIds.indexOf(d.i + 1) === -1) return Infinity;
|
|
28
38
|
|
|
29
39
|
var lon = Lib.modHalf(lonlat[0], 360);
|
|
30
40
|
var lat = lonlat[1];
|
|
@@ -1,26 +1,35 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var Lib = require('../../lib');
|
|
3
4
|
var convert = require('./convert');
|
|
4
5
|
var LAYER_PREFIX = require('../../plots/mapbox/constants').traceLayerPrefix;
|
|
5
|
-
var ORDER =
|
|
6
|
+
var ORDER = {
|
|
7
|
+
cluster: ['cluster', 'clusterCount', 'circle'],
|
|
8
|
+
nonCluster: ['fill', 'line', 'circle', 'symbol'],
|
|
9
|
+
};
|
|
6
10
|
|
|
7
|
-
function ScatterMapbox(subplot, uid) {
|
|
11
|
+
function ScatterMapbox(subplot, uid, clusterEnabled) {
|
|
8
12
|
this.type = 'scattermapbox';
|
|
9
13
|
this.subplot = subplot;
|
|
10
14
|
this.uid = uid;
|
|
15
|
+
this.clusterEnabled = clusterEnabled;
|
|
11
16
|
|
|
12
17
|
this.sourceIds = {
|
|
13
18
|
fill: 'source-' + uid + '-fill',
|
|
14
19
|
line: 'source-' + uid + '-line',
|
|
15
20
|
circle: 'source-' + uid + '-circle',
|
|
16
|
-
symbol: 'source-' + uid + '-symbol'
|
|
21
|
+
symbol: 'source-' + uid + '-symbol',
|
|
22
|
+
cluster: 'source-' + uid + '-circle',
|
|
23
|
+
clusterCount: 'source-' + uid + '-circle',
|
|
17
24
|
};
|
|
18
25
|
|
|
19
26
|
this.layerIds = {
|
|
20
27
|
fill: LAYER_PREFIX + uid + '-fill',
|
|
21
28
|
line: LAYER_PREFIX + uid + '-line',
|
|
22
29
|
circle: LAYER_PREFIX + uid + '-circle',
|
|
23
|
-
symbol: LAYER_PREFIX + uid + '-symbol'
|
|
30
|
+
symbol: LAYER_PREFIX + uid + '-symbol',
|
|
31
|
+
cluster: LAYER_PREFIX + uid + '-cluster',
|
|
32
|
+
clusterCount: LAYER_PREFIX + uid + '-cluster-count',
|
|
24
33
|
};
|
|
25
34
|
|
|
26
35
|
// We could merge the 'fill' source with the 'line' source and
|
|
@@ -34,11 +43,20 @@ function ScatterMapbox(subplot, uid) {
|
|
|
34
43
|
|
|
35
44
|
var proto = ScatterMapbox.prototype;
|
|
36
45
|
|
|
37
|
-
proto.addSource = function(k, opts) {
|
|
38
|
-
|
|
46
|
+
proto.addSource = function(k, opts, cluster) {
|
|
47
|
+
var sourceOpts = {
|
|
39
48
|
type: 'geojson',
|
|
40
|
-
data: opts.geojson
|
|
41
|
-
}
|
|
49
|
+
data: opts.geojson,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
if(cluster && cluster.enabled) {
|
|
53
|
+
Lib.extendFlat(sourceOpts, {
|
|
54
|
+
cluster: true,
|
|
55
|
+
clusterMaxZoom: cluster.maxzoom,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
this.subplot.map.addSource(this.sourceIds[k], sourceOpts);
|
|
42
60
|
};
|
|
43
61
|
|
|
44
62
|
proto.setSourceData = function(k, opts) {
|
|
@@ -48,56 +66,79 @@ proto.setSourceData = function(k, opts) {
|
|
|
48
66
|
};
|
|
49
67
|
|
|
50
68
|
proto.addLayer = function(k, opts, below) {
|
|
51
|
-
|
|
52
|
-
type:
|
|
69
|
+
var source = {
|
|
70
|
+
type: opts.type,
|
|
53
71
|
id: this.layerIds[k],
|
|
54
72
|
source: this.sourceIds[k],
|
|
55
73
|
layout: opts.layout,
|
|
56
|
-
paint: opts.paint
|
|
57
|
-
}
|
|
74
|
+
paint: opts.paint,
|
|
75
|
+
};
|
|
76
|
+
if(opts.filter) {
|
|
77
|
+
source.filter = opts.filter;
|
|
78
|
+
}
|
|
79
|
+
this.subplot.addLayer(source, below);
|
|
58
80
|
};
|
|
59
81
|
|
|
60
82
|
proto.update = function update(calcTrace) {
|
|
83
|
+
var trace = calcTrace[0].trace;
|
|
61
84
|
var subplot = this.subplot;
|
|
62
85
|
var map = subplot.map;
|
|
63
86
|
var optsAll = convert(subplot.gd, calcTrace);
|
|
64
87
|
var below = subplot.belowLookup['trace-' + this.uid];
|
|
65
88
|
var i, k, opts;
|
|
89
|
+
var hasCluster = !!(trace.cluster && trace.cluster.enabled);
|
|
90
|
+
var hadCluster = !!this.clusterEnabled;
|
|
66
91
|
|
|
67
92
|
if(below !== this.below) {
|
|
68
|
-
|
|
69
|
-
|
|
93
|
+
var order = ORDER.nonCluster;
|
|
94
|
+
|
|
95
|
+
for(i = order.length - 1; i >= 0; i--) {
|
|
96
|
+
k = order[i];
|
|
70
97
|
map.removeLayer(this.layerIds[k]);
|
|
71
98
|
}
|
|
72
|
-
for(i = 0; i <
|
|
73
|
-
k =
|
|
99
|
+
for(i = 0; i < order.length; i++) {
|
|
100
|
+
k = order[i];
|
|
74
101
|
opts = optsAll[k];
|
|
75
102
|
this.addLayer(k, opts, below);
|
|
76
103
|
}
|
|
77
104
|
this.below = below;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
105
|
+
} else if(hasCluster && !hadCluster) {
|
|
106
|
+
for(i = ORDER.nonCluster.length - 1; i >= 0; i--) {
|
|
107
|
+
k = ORDER.nonCluster[i];
|
|
108
|
+
map.removeLayer(this.layerIds[k]);
|
|
109
|
+
map.removeSource(this.sourceIds[k]);
|
|
110
|
+
}
|
|
111
|
+
this.addSource('circle', optsAll.circle, trace.cluster);
|
|
112
|
+
for(i = 0; i < ORDER.cluster.length; i++) {
|
|
113
|
+
k = ORDER.cluster[i];
|
|
114
|
+
opts = optsAll[k];
|
|
115
|
+
this.addLayer(k, opts, below);
|
|
116
|
+
}
|
|
117
|
+
this.clusterEnabled = hasCluster;
|
|
118
|
+
} else if(!hasCluster && hadCluster) {
|
|
119
|
+
for(i = 0; i < ORDER.cluster.length; i++) {
|
|
120
|
+
k = ORDER.cluster[i];
|
|
121
|
+
map.removeLayer(this.layerIds[k]);
|
|
89
122
|
}
|
|
123
|
+
map.removeSource(this.sourceIds.circle);
|
|
124
|
+
for(i = 0; i < ORDER.nonCluster.length; i++) {
|
|
125
|
+
k = ORDER.nonCluster[i];
|
|
126
|
+
opts = optsAll[k];
|
|
127
|
+
this.addSource(k, opts, trace.cluster);
|
|
128
|
+
this.addLayer(k, opts, below);
|
|
129
|
+
}
|
|
130
|
+
this.clusterEnabled = hasCluster;
|
|
90
131
|
}
|
|
91
132
|
|
|
92
|
-
|
|
133
|
+
// link ref for quick update during selections
|
|
93
134
|
calcTrace[0].trace._glTrace = this;
|
|
94
135
|
};
|
|
95
136
|
|
|
96
137
|
proto.dispose = function dispose() {
|
|
97
138
|
var map = this.subplot.map;
|
|
98
|
-
|
|
99
|
-
for(var i =
|
|
100
|
-
var k =
|
|
139
|
+
var order = this.clusterEnabled ? ORDER.cluster : ORDER.nonCluster;
|
|
140
|
+
for(var i = order.length - 1; i >= 0; i--) {
|
|
141
|
+
var k = order[i];
|
|
101
142
|
map.removeLayer(this.layerIds[k]);
|
|
102
143
|
map.removeSource(this.sourceIds[k]);
|
|
103
144
|
}
|
|
@@ -105,15 +146,31 @@ proto.dispose = function dispose() {
|
|
|
105
146
|
|
|
106
147
|
module.exports = function createScatterMapbox(subplot, calcTrace) {
|
|
107
148
|
var trace = calcTrace[0].trace;
|
|
108
|
-
var
|
|
149
|
+
var hasCluster = trace.cluster && trace.cluster.enabled;
|
|
150
|
+
var scatterMapbox = new ScatterMapbox(
|
|
151
|
+
subplot,
|
|
152
|
+
trace.uid,
|
|
153
|
+
hasCluster
|
|
154
|
+
);
|
|
155
|
+
|
|
109
156
|
var optsAll = convert(subplot.gd, calcTrace);
|
|
110
157
|
var below = scatterMapbox.below = subplot.belowLookup['trace-' + trace.uid];
|
|
158
|
+
var i, k, opts;
|
|
111
159
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
160
|
+
if(hasCluster) {
|
|
161
|
+
scatterMapbox.addSource('circle', optsAll.circle, trace.cluster);
|
|
162
|
+
for(i = 0; i < ORDER.cluster.length; i++) {
|
|
163
|
+
k = ORDER.cluster[i];
|
|
164
|
+
opts = optsAll[k];
|
|
165
|
+
scatterMapbox.addLayer(k, opts, below);
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
for(i = 0; i < ORDER.nonCluster.length; i++) {
|
|
169
|
+
k = ORDER.nonCluster[i];
|
|
170
|
+
opts = optsAll[k];
|
|
171
|
+
scatterMapbox.addSource(k, opts, trace.cluster);
|
|
172
|
+
scatterMapbox.addLayer(k, opts, below);
|
|
173
|
+
}
|
|
117
174
|
}
|
|
118
175
|
|
|
119
176
|
// link ref for quick update during selections
|
package/src/version.js
CHANGED