Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b30b8fb

Browse files
committed
improve scattermapbox convert step:
- add support for arrayOk 'marker.color' and 'marker.size' - add make 'lines' render as 'MultiLineString' GeoJSON
1 parent 41840cb commit b30b8fb

File tree

2 files changed

+152
-37
lines changed

2 files changed

+152
-37
lines changed

src/traces/scattermapbox/convert.js

Lines changed: 149 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,31 @@ var isNumeric = require('fast-isnumeric');
1313

1414
var Lib = require('../../lib');
1515
var subTypes = require('../scatter/subtypes');
16+
var makeBubbleSizeFn = require('../scatter/make_bubble_size_func');
17+
var hasColorscale = require('../../components/colorscale/has_colorscale');
18+
var makeColorScaleFn = require('../../components/colorscale/make_scale_function');
19+
20+
var COLOR_PROP = 'circle-color';
21+
var SIZE_PROP = 'circle-size';
1622

1723

1824
module.exports = function convert(trace) {
1925
var isVisible = (trace.visible === true),
2026
hasLines = subTypes.hasLines(trace),
2127
hasMarkers = subTypes.hasMarkers(trace);
2228

23-
var coordinates = (isVisible) ? calcCoords(trace) : [];
29+
var geojsonLines = makeBlankGeoJSON(),
30+
layoutLines = { visibility: 'none' },
31+
paintLines = {};
2432

25-
var geojsonLines = makeGeoJson('LineString', coordinates);
26-
var layoutLines = {
27-
visibility: (isVisible && hasLines) ? 'visible' : 'none'
28-
};
29-
var paintLines = {};
33+
var geojsonMarkers = makeBlankGeoJSON(),
34+
layoutMarkers = { visibility: 'none' },
35+
paintMarkers = {};
36+
37+
if(isVisible && hasLines) {
38+
geojsonLines = makeLineGeoJSON(trace);
39+
layoutLines.visibility = 'visible';
3040

31-
if(hasLines) {
3241
var line = trace.line;
3342

3443
Lib.extendFlat(paintLines, {
@@ -41,23 +50,19 @@ module.exports = function convert(trace) {
4150
// line-dasharray and line-pattern
4251
}
4352

44-
var geojsonMarkers = makeGeoJson('MultiPoint', coordinates);
45-
var layoutMarkers = {
46-
visibility: (isVisible && hasMarkers) ? 'visible' : 'none'
47-
};
48-
var paintMarkers = {};
53+
if(isVisible && hasMarkers) {
54+
var hash = {};
55+
hash[COLOR_PROP] = {};
56+
hash[SIZE_PROP] = {};
4957

50-
if(hasMarkers) {
51-
var marker = trace.marker;
58+
geojsonMarkers = makeMarkerGeoJSON(trace, hash);
59+
layoutMarkers.visibility = 'visible';
5260

5361
Lib.extendFlat(paintMarkers, {
54-
'circle-radius': marker.size / 2,
55-
'circle-color': marker.color,
56-
'circle-opacity': trace.opacity * marker.opacity
62+
'circle-opacity': trace.opacity * trace.marker.opacity,
63+
'circle-color': calcMarkerColor(trace, hash),
64+
'circle-radius': calcMarkerSize(trace, hash)
5765
});
58-
59-
// could probably translate arrayOk properties into
60-
// multiple layers by making paintMarkers a array!
6166
}
6267

6368
return {
@@ -71,6 +76,130 @@ module.exports = function convert(trace) {
7176
};
7277
};
7378

79+
function makeBlankGeoJSON() {
80+
return {
81+
type: 'Point',
82+
coordinates: []
83+
};
84+
}
85+
86+
function makeLineGeoJSON(trace) {
87+
return {
88+
type: 'MultiLineString',
89+
coordinates: [calcCoords(trace)]
90+
};
91+
}
92+
93+
// N.B. `hash` is mutated here
94+
function makeMarkerGeoJSON(trace, hash) {
95+
var marker = trace.marker,
96+
len = trace.lon.length,
97+
hasColorArray = Array.isArray(marker.color),
98+
hasSizeArray = Array.isArray(marker.size);
99+
100+
// translate vals in trace arrayOk containers
101+
// into a val-to-index hash object
102+
function translate(props, key, cont, index) {
103+
var value = cont[index];
104+
105+
if(!hash[key][value]) hash[key][value] = index;
106+
107+
props[key] = hash[key][value];
108+
}
109+
110+
var features = [];
111+
112+
for(var i = 0; i < len; i++) {
113+
var lon = trace.lon[i],
114+
lat = trace.lat[i];
115+
116+
var props = {};
117+
if(hasColorArray) translate(props, COLOR_PROP, marker.color, i);
118+
if(hasSizeArray) translate(props, SIZE_PROP, marker.size, i);
119+
120+
if(isNumeric(lon) && isNumeric(lat)) {
121+
features.push({
122+
type: 'Feature',
123+
geometry: {
124+
type: 'Point',
125+
coordinates: [+lon, +lat]
126+
},
127+
properties: props
128+
});
129+
}
130+
}
131+
132+
return {
133+
type: 'FeatureCollection',
134+
features: features
135+
};
136+
}
137+
138+
function calcMarkerColor(trace, hash) {
139+
var marker = trace.marker;
140+
var out;
141+
142+
if(Array.isArray(marker.color)) {
143+
var colorFn = hasColorscale(trace, 'marker') ?
144+
makeColorScaleFn(marker.colorscale, marker.cmin, marker.cmax) :
145+
Lib.identity;
146+
147+
var vals = Object.keys(hash[COLOR_PROP]),
148+
stops = [];
149+
150+
for(var i = 0; i < vals.length; i++) {
151+
var val = vals[i];
152+
153+
stops.push([ hash[COLOR_PROP][val], colorFn(val) ]);
154+
}
155+
156+
out = {
157+
property: SIZE_PROP,
158+
stops: stops
159+
};
160+
161+
}
162+
else {
163+
out = marker.color;
164+
}
165+
166+
return out;
167+
}
168+
169+
function calcMarkerSize(trace, hash) {
170+
var marker = trace.marker;
171+
var out;
172+
173+
if(Array.isArray(marker.size)) {
174+
var sizeFn = makeBubbleSizeFn(trace);
175+
176+
var vals = Object.keys(hash[SIZE_PROP]),
177+
stops = [];
178+
179+
for(var i = 0; i < vals.length; i++) {
180+
var val = vals[i];
181+
182+
stops.push([ hash[SIZE_PROP][val], sizeFn(val) ]);
183+
}
184+
185+
// stops indices must be sorted
186+
stops.sort(function(a, b) {
187+
return a[0] - b[0];
188+
});
189+
190+
out = {
191+
property: SIZE_PROP,
192+
stops: stops
193+
};
194+
}
195+
else {
196+
out = marker.size / 2;
197+
}
198+
199+
return out;
200+
}
201+
202+
74203
function calcCoords(trace) {
75204
var len = trace.lon.length;
76205
var coordinates = [];
@@ -86,16 +215,3 @@ function calcCoords(trace) {
86215

87216
return coordinates;
88217
}
89-
90-
function makeGeoJson(geometryType, coordinates) {
91-
return {
92-
type: 'FeatureCollection',
93-
features: [{
94-
type: 'Feature',
95-
geometry: {
96-
type: geometryType,
97-
coordinates: coordinates
98-
}
99-
}]
100-
};
101-
}

src/traces/scattermapbox/index.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ var ScatterMapbox = {};
1616
// - Different line dashes
1717
// - no `locations` support
1818
// - no 'text' mode support
19-
// - arrayOk properties would require multi layers per source
20-
// - support for marker.line ???
21-
ScatterMapbox.attributes = require('../scattergeo/attributes');
22-
ScatterMapbox.supplyDefaults = require('../scattergeo/defaults');
19+
// - limited arrayOk
20+
// - support for marker.line (could do it using two concentric circles)
21+
2322
ScatterMapbox.attributes = require('./attributes');
2423
ScatterMapbox.supplyDefaults = require('./defaults');
2524
ScatterMapbox.colorbar = require('../scatter/colorbar');

0 commit comments

Comments
 (0)