@@ -181,40 +181,52 @@ export default class WorldMap {
181
181
createCircles ( data ) {
182
182
console . log ( 'createCircles: begin' ) ;
183
183
const circles : any [ ] = [ ] ;
184
+ const circles_by_key = { } ;
184
185
data . forEach ( dataPoint => {
185
186
// Todo: Review: Is a "locationName" really required
186
- // just for displaying a circle on a map?
187
+ // just for displaying a circle on a map?
187
188
if ( ! dataPoint . locationName ) {
188
189
return ;
189
190
}
190
- circles . push ( this . createCircle ( dataPoint ) ) ;
191
+ let circle ;
192
+
193
+ // Create circle.
194
+ if ( circles_by_key [ dataPoint . key ] == undefined ) {
195
+ circle = this . createCircle ( dataPoint ) ;
196
+ circles_by_key [ dataPoint . key ] = circle ;
197
+
198
+ // Amend popup content if circle has been created already.
199
+ } else {
200
+ circle = circles_by_key [ dataPoint . key ] ;
201
+ this . extendPopupContent ( circle , dataPoint ) ;
202
+ }
203
+ circles . push ( circle ) ;
191
204
} ) ;
192
205
this . circlesLayer = this . addCircles ( circles ) ;
193
206
this . circles = circles ;
194
207
console . log ( 'createCircles: end' ) ;
195
208
}
196
209
197
210
updateCircles ( data ) {
211
+ const circles_by_key = { } ;
198
212
data . forEach ( dataPoint => {
213
+ // Todo: Review: Is a "locationName" really required
214
+ // just for displaying a circle on a map?
199
215
if ( ! dataPoint . locationName ) {
200
216
return ;
201
217
}
202
218
203
- const circle = _ . find ( this . circles , cir => {
204
- return cir . options . location === dataPoint . key ;
205
- } ) ;
219
+ // Update circle.
220
+ if ( circles_by_key [ dataPoint . key ] == undefined ) {
221
+ const circle = this . updateCircle ( dataPoint ) ;
222
+ if ( circle ) {
223
+ circles_by_key [ dataPoint . key ] = circle ;
224
+ }
206
225
207
- if ( circle ) {
208
- circle . setRadius ( this . calcCircleSize ( dataPoint . value || 0 ) ) ;
209
- circle . setStyle ( {
210
- color : this . getColor ( dataPoint . value ) ,
211
- fillColor : this . getColor ( dataPoint . value ) ,
212
- fillOpacity : 0.5 ,
213
- location : dataPoint . key ,
214
- } ) ;
215
- circle . unbindPopup ( ) ;
216
- this . createClickthrough ( circle , dataPoint ) ;
217
- this . createPopup ( circle , dataPoint . locationName , dataPoint . valueRounded ) ;
226
+ // Amend popup content if circle has been updated already.
227
+ } else {
228
+ const circle = circles_by_key [ dataPoint . key ] ;
229
+ this . extendPopupContent ( circle , dataPoint ) ;
218
230
}
219
231
} ) ;
220
232
}
@@ -231,10 +243,38 @@ export default class WorldMap {
231
243
} ) ;
232
244
233
245
this . createClickthrough ( circle , dataPoint ) ;
234
- this . createPopup ( circle , dataPoint . locationName , dataPoint . valueRounded ) ;
246
+ const content = this . getPopupContent ( dataPoint . locationName , dataPoint . valueRounded ) ;
247
+ this . createPopup ( circle , content ) ;
235
248
return circle ;
236
249
}
237
250
251
+ updateCircle ( dataPoint ) {
252
+ // Find back circle object by data point key.
253
+ const circle = _ . find ( this . circles , cir => {
254
+ return cir . options . location === dataPoint . key ;
255
+ } ) ;
256
+
257
+ if ( circle ) {
258
+ circle . setRadius ( this . calcCircleSize ( dataPoint . value || 0 ) ) ;
259
+ circle . setStyle ( {
260
+ color : this . getColor ( dataPoint . value ) ,
261
+ fillColor : this . getColor ( dataPoint . value ) ,
262
+ fillOpacity : 0.5 ,
263
+ location : dataPoint . key ,
264
+ } ) ;
265
+
266
+ // Re-create popup.
267
+ circle . unbindPopup ( ) ;
268
+ const content = this . getPopupContent ( dataPoint . locationName , dataPoint . valueRounded ) ;
269
+ this . createPopup ( circle , content ) ;
270
+
271
+ // Re-create clickthrough-link.
272
+ this . createClickthrough ( circle , dataPoint ) ;
273
+
274
+ return circle ;
275
+ }
276
+ }
277
+
238
278
calcCircleSize ( dataPointValue ) {
239
279
const circleMinSize = parseInt ( this . ctrl . settings . circleMinSize , 10 ) || 1 ;
240
280
const circleMaxSize = parseInt ( this . ctrl . settings . circleMaxSize , 10 ) || 10 ;
@@ -294,14 +334,7 @@ export default class WorldMap {
294
334
}
295
335
}
296
336
297
- createPopup ( circle , locationName , value ) {
298
- let unit ;
299
- if ( _ . isNaN ( value ) ) {
300
- value = 'n/a' ;
301
- } else {
302
- unit = value && value === 1 ? this . ctrl . settings . unitSingular : this . ctrl . settings . unitPlural ;
303
- }
304
- const label = `${ locationName } : ${ value } ${ unit || '' } ` . trim ( ) ;
337
+ createPopup ( circle , label ) {
305
338
circle . bindPopup ( label , {
306
339
offset : ( window as any ) . L . point ( 0 , - 2 ) ,
307
340
className : 'worldmap-popup' ,
@@ -323,6 +356,24 @@ export default class WorldMap {
323
356
}
324
357
}
325
358
359
+ extendPopupContent ( circle , dataPoint ) {
360
+ const popup = circle . getPopup ( ) ;
361
+ let popupContent = popup . _content ;
362
+ popupContent += `\n${ this . getPopupContent ( dataPoint . locationName , dataPoint . valueRounded ) } ` ;
363
+ circle . setPopupContent ( popupContent ) ;
364
+ }
365
+
366
+ getPopupContent ( locationName , value ) {
367
+ let unit ;
368
+ if ( _ . isNaN ( value ) ) {
369
+ value = 'n/a' ;
370
+ } else {
371
+ unit = value && value === 1 ? this . ctrl . settings . unitSingular : this . ctrl . settings . unitPlural ;
372
+ }
373
+ const label = `${ locationName } : ${ value } ${ unit || '' } ` . trim ( ) ;
374
+ return label ;
375
+ }
376
+
326
377
getColor ( value ) {
327
378
for ( let index = this . ctrl . data . thresholds . length ; index > 0 ; index -= 1 ) {
328
379
if ( value >= this . ctrl . data . thresholds [ index - 1 ] ) {
@@ -337,7 +388,6 @@ export default class WorldMap {
337
388
}
338
389
339
390
panToMapCenter ( options ?: any ) {
340
-
341
391
console . log ( 'panToMapCenter' ) ;
342
392
343
393
// Get a bunch of metadata from settings and data which
0 commit comments