77
77
.q8-11 { fill : rgb (215 , 48 , 31 ); }
78
78
.q9-11 { fill : rgb (179 , 0 , 0 ); }
79
79
.q10-11 { fill : rgb (127 , 0 , 0 ); }
80
+
81
+ .legend {
82
+ font-size : 12px ;
83
+ }
84
+
80
85
</ style >
81
86
< script type ="text/javascript " src ="https://www.google.com/jsapi "> </ script >
82
87
< script src ="//d3js.org/d3.v3.min.js "> </ script >
@@ -176,14 +181,29 @@ <h3>GeoDa Release</h3>
176
181
177
182
178
183
< h3 > Live Update of GeoDa Users Across the Globe</ h3 >
179
- < p >
180
184
<!--<iframe width="100%" height="520" frameborder="0" src="https://lixun910.cartodb.com/viz/d1b90530-3fbd-11e6-93d2-0e3a376473ab/embed_map" allowfullscreen webkitallowfullscreen mozallowfullscreen oallowfullscreen msallowfullscreen></iframe>-->
181
- < div id ="geoda_map " style ="width: 50%; height: 500px;border: 0px solid red; "> </ div >
185
+ < a id ="map_selector " style ="float:left; "> 2D/3D</ a >
186
+ < p >
187
+ < div id ="geoda_map " style ="width: 50%; height: 500px;border: 0px solid red; "> </ div >
188
+ < div id ="geoda_map_2d " style ="width: 50%; height: 500px;border: 0px solid red; display: none; "> </ div >
182
189
</ p >
190
+ < br />
191
+ < script >
192
+ $ ( '#map_selector' ) . click ( function ( ) {
193
+ if ( $ ( '#geoda_map' ) . css ( "display" ) == "block" ) {
194
+ $ ( '#geoda_map' ) . css ( "display" , "none" ) ;
195
+ $ ( '#geoda_map_2d' ) . css ( "display" , "block" ) ;
196
+ } else {
197
+ $ ( '#geoda_map' ) . css ( "display" , "block" ) ;
198
+ $ ( '#geoda_map_2d' ) . css ( "display" , "none" ) ;
199
+ }
200
+ } ) ;
201
+ </ script >
183
202
< p >
184
203
< div id ="visualization " style ="width: 75%; height: 400px; "> </ div >
185
-
186
204
</ p >
205
+
206
+
187
207
< script type ="text/javascript ">
188
208
google . load ( 'visualization' , '1' , { packages : [ 'areachart' ] } ) ;
189
209
function drawVisualization ( ) {
@@ -223,12 +243,19 @@ <h3>Live Update of GeoDa Users Across the Globe</h3>
223
243
224
244
< script >
225
245
246
+ // 2d map
247
+ var projection_2d = d3 . geo . equirectangular ( ) . scale ( 150 ) ;
248
+ var path_2d = d3 . geo . path ( ) . projection ( projection_2d ) ;
249
+ var svg_2d = d3 . select ( "#geoda_map_2d" ) . append ( "svg" ) . attr ( "width" , 900 , ) . attr ( "height" , 500 ) ;
250
+ svg_2d . append ( "path" ) . datum ( { type : "Sphere" } ) . attr ( "class" , "water" ) . attr ( "d" , path_2d ) ;
251
+
252
+ // 3D map
226
253
var width = 600 ,
227
254
height = 500 ,
228
255
sens = 0.25 ,
229
256
focused ;
230
257
231
- var interrupt = false ;
258
+ var interrupt = false ;
232
259
var scales = { } ;
233
260
234
261
//Setting projection
@@ -239,8 +266,7 @@ <h3>Live Update of GeoDa Users Across the Globe</h3>
239
266
. translate ( [ width / 2 , height / 2 ] )
240
267
. clipAngle ( 90 ) ;
241
268
242
- var path = d3 . geo . path ( )
243
- . projection ( projection ) ;
269
+ var path = d3 . geo . path ( ) . projection ( projection ) ;
244
270
245
271
//SVG container
246
272
@@ -251,29 +277,27 @@ <h3>Live Update of GeoDa Users Across the Globe</h3>
251
277
//Adding water
252
278
253
279
svg . append ( "path" )
254
- . datum ( { type : "Sphere" } )
255
- . attr ( "class" , "water" )
256
- . attr ( "d" , path )
257
- //Drag event
258
- . call ( d3 . behavior . drag ( )
259
- . origin ( function ( ) {
260
- interrupt = true ;
261
- var r = projection . rotate ( ) ;
262
- return { x : r [ 0 ] / sens , y : - r [ 1 ] / sens } ;
263
- } )
264
- . on ( "drag" , function ( ) {
265
-
266
- var rotate = projection . rotate ( ) ;
267
- projection . rotate ( [ d3 . event . x * sens , - d3 . event . y * sens , rotate [ 2 ] ] ) ;
268
- svg . selectAll ( "path.land" ) . attr ( "d" , path ) ;
269
- svg . selectAll ( ".focused" ) . classed ( "focused" , focused = false ) ;
270
- } )
271
- ) ;
280
+ . datum ( { type : "Sphere" } )
281
+ . attr ( "class" , "water" )
282
+ . attr ( "d" , path )
283
+ //Drag event
284
+ . call ( d3 . behavior . drag ( )
285
+ . origin ( function ( ) {
286
+ interrupt = true ;
287
+ var r = projection . rotate ( ) ;
288
+ return { x : r [ 0 ] / sens , y : - r [ 1 ] / sens } ;
289
+ } )
290
+ . on ( "drag" , function ( ) {
291
+ var rotate = projection . rotate ( ) ;
292
+ projection . rotate ( [ d3 . event . x * sens , - d3 . event . y * sens , rotate [ 2 ] ] ) ;
293
+ svg . selectAll ( "path.land" ) . attr ( "d" , path ) ;
294
+ svg . selectAll ( ".focused" ) . classed ( "focused" , focused = false ) ;
295
+ } )
296
+ ) ;
272
297
273
298
274
299
var countryTooltip = d3 . select ( "body" ) . append ( "div" ) . attr ( "class" , "countryTooltip" ) ;
275
300
276
-
277
301
queue ( )
278
302
. defer ( d3 . json , "./data/world-110m.json" )
279
303
. defer ( d3 . tsv , "./data/world-110m-country-names.tsv" )
@@ -320,7 +344,35 @@ <h3>Live Update of GeoDa Users Across the Globe</h3>
320
344
. domain ( [ 0 , sum_down ] )
321
345
. range ( d3 . range ( 11 ) . map ( function ( i ) { return "q" + i + "-11" ; } ) ) ;
322
346
323
-
347
+ // Drawing 2d globe
348
+ var world_2d = svg_2d . selectAll ( "path.land" )
349
+ . data ( countries )
350
+ . enter ( ) . append ( "path" )
351
+ . attr ( "class" , function ( d ) {
352
+ var down = 0 ;
353
+ if ( d . id in downloadById ) {
354
+ down = downloadById [ d . id ] ;
355
+ }
356
+ var clr = scales [ "jenks9" ] ( down ) ;
357
+ if ( clr == undefined ) {
358
+ console . log ( d . id ) ;
359
+ }
360
+ return "land " + clr ;
361
+ } )
362
+ . attr ( "d" , path_2d )
363
+ . on ( "mouseover" , function ( d ) {
364
+ countryTooltip . text ( function ( ) {
365
+ var cnt = 0 ;
366
+ if ( d . id in downloadById ) {
367
+ cnt = downloadById [ d . id ] ;
368
+ }
369
+ return countryById [ d . id ] + ": " + cnt ;
370
+ } )
371
+ . style ( "left" , ( d3 . event . pageX + 7 ) + "px" )
372
+ . style ( "top" , ( d3 . event . pageY - 15 ) + "px" )
373
+ . style ( "display" , "block" )
374
+ . style ( "opacity" , 1 ) ;
375
+ } ) ;
324
376
325
377
//Drawing countries on the globe
326
378
var world = svg . selectAll ( "path.land" )
@@ -382,14 +434,62 @@ <h3>Live Update of GeoDa Users Across the Globe</h3>
382
434
383
435
d3 . timer ( function ( ) {
384
436
if ( interrupt == false ) {
385
- var dt = Date . now ( ) - t0 ;
386
- projection . rotate ( [ velocity [ 0 ] * dt + origin [ 0 ] , velocity [ 1 ] * dt + origin [ 1 ] ] ) ;
387
- svg . selectAll ( "path.land" ) . attr ( "d" , path ) ;
437
+ var dt = Date . now ( ) - t0 ;
438
+ projection . rotate ( [ velocity [ 0 ] * dt + origin [ 0 ] , velocity [ 1 ] * dt + origin [ 1 ] ] ) ;
439
+ svg . selectAll ( "path.land" ) . attr ( "d" , path ) ;
388
440
svg . selectAll ( ".focused" ) . classed ( "focused" , focused = false ) ;
389
441
}
390
-
391
442
} ) ;
392
443
444
+ //Adding legend for our Choropleth
445
+ var legend_cat = ss . jenks ( down_data , 10 ) ;
446
+
447
+ var legend = svg . selectAll ( "g.legend" )
448
+ . data ( legend_cat )
449
+ . enter ( ) . append ( "g" )
450
+ . attr ( "class" , "legend" ) ;
451
+
452
+ var ls_w = 20 , ls_h = 20 ;
453
+
454
+ legend . append ( "rect" )
455
+ . attr ( "x" , 20 )
456
+ . attr ( "y" , function ( d , i ) { return height - ( i * ls_h ) - 2 * ls_h ; } )
457
+ . attr ( "width" , ls_w )
458
+ . attr ( "height" , ls_h )
459
+ . attr ( "class" , function ( d , i ) { return "q" + i + "-11" ; } )
460
+ //.style("fill", function(d, i) { return color(d); })
461
+ . style ( "opacity" , 0.8 ) ;
462
+
463
+ legend . append ( "text" )
464
+ . attr ( "x" , 50 )
465
+ . attr ( "y" , function ( d , i ) { return height - ( ( i + 1 ) * ls_h ) - ls_h - 4 ; } )
466
+ . text ( function ( d , i ) {
467
+ return down_cat [ i ] ;
468
+ } ) ;
469
+
470
+ legend = svg_2d . selectAll ( "g.legend" )
471
+ . data ( legend_cat )
472
+ . enter ( ) . append ( "g" )
473
+ . attr ( "class" , "legend" ) ;
474
+
475
+ var ls_w = 20 , ls_h = 20 ;
476
+
477
+ legend . append ( "rect" )
478
+ . attr ( "x" , 20 )
479
+ . attr ( "y" , function ( d , i ) { return height - ( i * ls_h ) - 2 * ls_h ; } )
480
+ . attr ( "width" , ls_w )
481
+ . attr ( "height" , ls_h )
482
+ . attr ( "class" , function ( d , i ) { return "q" + i + "-11" ; } )
483
+ //.style("fill", function(d, i) { return color(d); })
484
+ . style ( "opacity" , 0.8 ) ;
485
+
486
+ legend . append ( "text" )
487
+ . attr ( "x" , 50 )
488
+ . attr ( "y" , function ( d , i ) { return height - ( ( i + 1 ) * ls_h ) - ls_h - 4 ; } )
489
+ . text ( function ( d , i ) {
490
+ return down_cat [ i ] ;
491
+ } ) ;
492
+
393
493
} ;
394
494
</ script >
395
495
0 commit comments