@@ -13,22 +13,31 @@ var isNumeric = require('fast-isnumeric');
13
13
14
14
var Lib = require ( '../../lib' ) ;
15
15
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' ;
16
22
17
23
18
24
module . exports = function convert ( trace ) {
19
25
var isVisible = ( trace . visible === true ) ,
20
26
hasLines = subTypes . hasLines ( trace ) ,
21
27
hasMarkers = subTypes . hasMarkers ( trace ) ;
22
28
23
- var coordinates = ( isVisible ) ? calcCoords ( trace ) : [ ] ;
29
+ var geojsonLines = makeBlankGeoJSON ( ) ,
30
+ layoutLines = { visibility : 'none' } ,
31
+ paintLines = { } ;
24
32
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' ;
30
40
31
- if ( hasLines ) {
32
41
var line = trace . line ;
33
42
34
43
Lib . extendFlat ( paintLines , {
@@ -41,23 +50,19 @@ module.exports = function convert(trace) {
41
50
// line-dasharray and line-pattern
42
51
}
43
52
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 ] = { } ;
49
57
50
- if ( hasMarkers ) {
51
- var marker = trace . marker ;
58
+ geojsonMarkers = makeMarkerGeoJSON ( trace , hash ) ;
59
+ layoutMarkers . visibility = 'visible' ;
52
60
53
61
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 )
57
65
} ) ;
58
-
59
- // could probably translate arrayOk properties into
60
- // multiple layers by making paintMarkers a array!
61
66
}
62
67
63
68
return {
@@ -71,6 +76,130 @@ module.exports = function convert(trace) {
71
76
} ;
72
77
} ;
73
78
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
+
74
203
function calcCoords ( trace ) {
75
204
var len = trace . lon . length ;
76
205
var coordinates = [ ] ;
@@ -86,16 +215,3 @@ function calcCoords(trace) {
86
215
87
216
return coordinates ;
88
217
}
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
- }
0 commit comments