-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsvi.js
More file actions
795 lines (666 loc) · 25.4 KB
/
svi.js
File metadata and controls
795 lines (666 loc) · 25.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
//This code does these following things
//draws map, add layer of counties
//color counties by overall svi
//recalculate overall svi each time checklist to left is clicked to check and uncheck
//color map with new sums
//sort list with new sums
//////////////////////////////////////////////////////////
//TODO
//style popup with more info - rank and also individual categories
//do observations - make case studies
//SECTION 1
//Setup variables, may still need some cleaning to get rid of unused ones
console.log(window.innerWidth)
d3.select("#map").style("min-width",window.innerWidth+"px").style("margin-left",(window.innerWidth/2-390)*-1+"px")
d3.select("#measures").style("margin-left",(window.innerWidth/2-420)*-1+"px")
var map;
var thememap;
var pub = {
all:null,
min:999,
max:0, //
startState:"NY",
stateAllocations:null,
currentState:"NY"
}
var colors = ["#00A9CE","#fff","#FB7139"]
var minMaxDictionary = {}
var measures = ["EPL_POV","EPL_PCI","EPL_UNEMP","EPL_NOHSDP","EPL_AGE17","EPL_AGE65","EPL_DISABL","EPL_SNGPNT", "EPL_LIMENG","EPL_MINRTY","EPL_CROWD","EPL_GROUPQ","EPL_MOBILE", "EPL_MUNIT","EPL_NOVEH"]
pub["activeThemes"]=measures
var groups = {
THEME1:["EPL_POV","EPL_PCI","EPL_UNEMP","EPL_NOHSDP"],
THEME2:["EPL_AGE17","EPL_AGE65","EPL_DISABL","EPL_SNGPNT"],
THEME3:["EPL_LIMENG","EPL_MINRTY"],
THEME4:["EPL_GROUPQ","EPL_NOVEH","EPL_CROWD","EPL_MUNIT","EPL_MOBILE"]
}
var measureGroups = ["SPL_THEME1","SPL_THEME2","SPL_THEME3","SPL_THEME4"]
var toggleDictionary = {}
var tally = 0
//each theme's display name
var themeGroupDisplayText = {
THEME1:"Socioeconomic Status",
THEME2:"Household Composition & Disability",
THEME3:"Minority Status & Language",
THEME4:"Housing Type & Transportation"
}
var themeDisplayText = {
"EPL_POV":"% of population<span class=\"highlight\"> below poverty</span>",
"EPL_PCI":"$<span class=\"highlight\"> Per capita income</span>",
"EPL_UNEMP":"% of population<span class=\"highlight\"> unemployed</span>",
"EPL_NOHSDP":"% of population<span class=\"highlight\"> with no high school diploma</span>",
"EPL_AGE17":"% of population<span class=\"highlight\"> under 18</span>",
"EPL_AGE65":"% of population<span class=\"highlight\"> over 64</span>",
"EPL_DISABL":"% of population<span class=\"highlight\"> with a disability</span>",
"EPL_SNGPNT":"% of<span class=\"highlight\"> single parent households</span>",
"EPL_LIMENG":"% of population who speak <span class=\"highlight\">limited english</span>",
"EPL_MINRTY":"% of population who are<span class=\"highlight\"> minorities</span>",
"EPL_CROWD":"% of households with <span class=\"highlight\">more people than rooms</span>",
"EPL_GROUPQ":"% of population in <span class=\"highlight\">group quarters</span>",
"EPL_MOBILE":"% of housing are <span class=\"highlight\">mobile homes</span>",
"EPL_MUNIT":"% of housing in <span class=\"highlight\">structures with 10+ units</span>",
"EPL_NOVEH":"% of households with <span class=\"highlight\">no vehicle available</span>"
}
var themeDisplayTextShort = {
"EPL_POV":"below poverty",
"EPL_PCI":"Per capita income",
"EPL_UNEMP":"unemployment",
"EPL_NOHSDP":"no high school diploma",
"EPL_AGE17":"under 18",
"EPL_AGE65":"over 64",
"EPL_DISABL":"disability",
"EPL_SNGPNT":"single parent households",
"EPL_LIMENG":"limited english",
"EPL_MINRTY":"minorities",
"EPL_CROWD":"more people than rooms",
"EPL_GROUPQ":"group quarters",
"EPL_MOBILE":"mobile homes",
"EPL_MUNIT":"structures with 10+ units",
"EPL_NOVEH":"no vehicle available"
}
var measuresLabels = {
TOTPOP:"Total Persons",
HH:"Households",
HU:"Housing Units",
AGE17:"under 18",
AGE65:"over 64",
DISABL:"with a disability",
LIMENG:"who speak limited English",
CROWD:"with more people than rooms",
GROUPQ:"in group quarters",
MINRTY:"who are Minorities",
MOBILE:"that are Mobile homes",
MUNIT:"in structures with 10+ units",
NOHSDP:"with no high school diploma",
NOVEH:"with no vehicle available",
PCI:"Per capita income",
POV:"below poverty",
SNGPNT:"have a single parent w/children under 18",
UNEMP:"unemployed"
}
var themeDisplayTextFull = {
"EPL_POV":"Persons below poverty",
"EPL_PCI":"Per capita income",
"EPL_UNEMP":"Civilian (age 16+) unemployed",
"EPL_NOHSDP":"Persons with no high school diploma (age25+)",
"EPL_AGE17":"Persons aged 17 and younger",
"EPL_AGE65":"Persons aged 65 and older",
"EPL_DISABL":"Civilian noninstitutionalized population with a disability",
"EPL_SNGPNT":"Single parent households with children under 18",
"EPL_LIMENG":"of persons (age 5+) who speak English \"less than well\"",
"EPL_MINRTY":"minority (all persons except white, non - Hispanic)",
"EPL_CROWD":"households with more people than rooms",
"EPL_GROUPQ":"Persons in group quarters",
"EPL_MOBILE":"mobile homes",
"EPL_MUNIT":"housing in structures with 10 or more units",
"EPL_NOVEH":"households with no vehicle available"
}
//colors for the lefthand checklist
var themeColors = {
THEME1:"#aaaaaa",
THEME2:"#3d85a4",
THEME3:"#4bacdd",
THEME4:"#658994"
}
var width = 250;
var data = [
{"color":colors[0],"value":0},
{"color":colors[0],"value":width/5},
{"color":"rgba(255,255,255,.2)","value":width/2},
{"color":colors[2],"value":width/5*4},
{"color":colors[2],"value":width}
];
var extent = d3.extent(data, d => d.value);
var padding = 5;
var innerWidth = width - (padding * 2);
var barHeight = 5;
var height = 25;
//this is the color scale for list on the right, it should match the map
var colorScale = d3.scaleLinear()
.range(colors)
.domain([0,measures.length/2,measures.length])
var svg = d3.select("#key")
.append("svg").attr("width", width).attr("height", height)//.attr("id", "footerKey");
var g = svg.append("g");
svg.append("text")
.text("High SVI")
.attr("x",250)
.attr("y",15)
.attr("text-anchor","end")
.style("font-size","10px")
.style("fill",colors[2])
.style("background-color","white")
.style("letter-spacing","1px")
svg.append("text")
.text("Low SVI")
.attr("x",0).attr("y",15)
.style("font-size","10px")
.style("fill",colors[0])
.style("font-weight","bold")
.style("letter-spacing","1px")
var defs = svg.append("defs");
var linearGradient = defs.append("linearGradient").attr("id", "Gradient");
linearGradient.selectAll("stop")
.data(data)
.enter().append("stop")
.attr("offset", d => ((d.value - extent[0]) / (extent[1] - extent[0]) * 100) + "%")
.attr("stop-color", d => d.color);
g.append("rect")
.attr("width", 250)
.attr("height", barHeight)
.style("fill", "url(#Gradient)");
//END SECTION 1 ////////////////////////////////////////////////////////
//SECTION 2
//2 datasets/loading
// var counties = d3.json("NYCensusTract.geojson")
var tractsFile = d3.json("nyc.geojson")
// var svi = d3.csv("SVINewYork2018_CensusTract.csv")
// Promise.all([counties,svi])
Promise.all([tractsFile])
.then(function(data){
ready(data[0])
})
//END SECTION 2 ////////////////////////////////////////////////////////
//SECTION 3
//main function after loading data - everything stems from the ready function right now
function ready(tracts){
//initial formatting of data
// var dataByFIPS = turnToDictFIPS(svi)
var tallied = combineGeojson(tracts)
pub.all = tallied//counties//combinedGeojson
// console.log(counties)
//console.log(combinedGeojson)
//draw the map
var map = drawMap(tracts,"map")
var sorted = rankCounties()
//drawTheme(sorted)
drawBars(sorted)
drawBoroughs(sorted)
drawClickableThemeMap(tracts)
// drawList (sorted);
//once everything is loaded, color the map
map.once("idle",function(){ colorByPriority(map)})
//set everything on the check list to true to start - all things are on and included in overall svi
for(var n in measures){toggleDictionary[measures[n]]=true}
d3.select("#activeThemesText").html("Showing the sum of all "+pub.activeThemes.length+" variables.")
//sort according to current state and draw the list of counties on the right accordingly
//for the leftside - draw each of the themes and the metrics under the themes
for(var g in groups){//for each theme, add title
var themeName = g
var themeContent = groups[g]
d3.select("#measures")
.append("div")
.attr("id",themeName)
.html(themeGroupDisplayText[themeName])
.style("font-size","18px")
.style("font-style","italic")
.style('padding',"6px")
.style('padding-top',"20px")
for(var t in themeContent){//for each metric under theme, add the name of the metric
var item = d3.select("#measures").append("div").attr("id",themeContent[t])
.style("cursor","pointer")
.style("margin-left","10px")
item.append("div").attr("class","checkbox").attr("id","checkbox_"+themeContent[t])
.style("display","inline-block")
item.append("div").attr("class","check").attr("id","check_"+themeContent[t])
.style("display","inline-block")
item.append("div")
.attr("id",themeContent[t])
.style("display","inline-block")
.attr("class","measureLable")
.attr("theme",themeName)
.html(themeDisplayText[themeContent[t]])
.style("cursor","pointer")
item.on("mouseover",function(){d3.select(this).style("background-color","gold")})
item.on("mouseout",function(){d3.select(this).style("background-color","#fff")})
item.on("click",function(){
var id = d3.select(this).attr("id")
//console.log(id)
var themeGroup = d3.select(this).attr("theme")
//whenever a metric is clicked, check if it is on or off currently, and toggle to opposite
if(toggleDictionary[id]==false){
// d3.select(this).style("background-color","#fff")//themeColors[themeGroup])
d3.select(this).style("color","#000000")
d3.select("#checkbox_"+id).style("border","#000000 1px solid")
d3.select("#"+id).select(".highlight").style("color","#000000")
toggleDictionary[id]=true
d3.select("#check_"+id).style("visibility","visible")
}else{
d3.select(this).style("color","#aaa")
toggleDictionary[id]=false
d3.select("#check_"+id).style("visibility","hidden")
d3.select("#"+id).select(".highlight").style("color","#aaaaaa")
d3.select("#checkbox_"+id).style("border","#aaaaaa 1px solid")
}
//recalculate the overal SVI accordingly
//sort and update the list on the right of ranked counties
//recolor the map
calculateTally(toggleDictionary)
// updateList(rankCounties())
drawList(rankCounties())
colorByPriority(map)
})
}
}
}
//END SECTION 3 ////////////////////////////////////////////////////////
//SECTION 4
//these are all the functions that are called, see comments below for what each does
//these 3 functions below draws the ranked/sorted list to the right and updates it when something changes
function drawList(data){
//console.log(Object.keys(data))
data = data.filter(function(nullnum){
return nullnum.tally !="-999" &&nullnum.tally!=0}) //filter out tally with -999
var highs = data.slice(0,10)//
var lows = data.slice(-10)
d3.selectAll(".rankItem").remove()
console.log(highs)
console.log(lows)
// d3.select("#rankings svg").remove()
for(var i in highs){
d3.select("#high")
.append("div")
.attr("id",highs[i].county)
.attr("class","rankItem")
.attr("cursor","pointer")
.html(//highs[i].order+". "
highs[i].countyName.replace("Census ","")
.replace(", New York County"," Manhattan")
.replace(", Richmond County"," Staten Island")
.replace(", Kings County"," Brooklyn")
.replace("County","")
.replace(", New York","")
+" <strong>"+Math.round(highs[i].tally*100)/100+"</strong>"
)
.attr("cursor","pointer")
.style("margin-left","10px")
.on("mouseover",function(){
var id = d3.select(this).attr("id")
map.setFilter("hoverOutline",["==","FIPS",parseInt(id)])
})
.on("click",function(){
var id = d3.select(this).attr("id")
map.setFilter("hoverOutline",["==","FIPS",parseInt(id)])
var centroid = centroids[id]
map.flyTo({
center: centroid,
zoom:14
});
})
}
for(var i in lows){
d3.select("#low")
.append("div")
.attr("class","rankItem")
.attr("id",lows[i].county)
.html(//lows[i].order+". "
lows[i].countyName.replace("Census ","")
.replace(", New York County"," Manhattan")
.replace(", Richmond County"," Staten Island")
.replace(", Kings County"," Brooklyn")
.replace("County","")
.replace(", New York","")
+" <strong>"+Math.round(lows[i].tally*100)/100+"</strong>"
)
.attr("cursor","pointer")
.on("mouseover",function(){
var id = d3.select(this).attr("id")
map.setFilter("hoverOutline",["==","FIPS",parseInt(id)])
})
.style("margin-left","10px")
.on("click",function(){
var id = d3.select(this).attr("id")
map.setFilter("hoverOutline",["==","FIPS",parseInt(id)])
var centroid = centroids[id]
map.flyTo({
center: centroid,
zoom:14
});
})
}
// var svg = d3.select("#rankings").append("svg").attr("width",200).attr("height",data.length*12+12)
// svg.selectAll(".ranked")
// .data(data)
// .enter()
// .append("text")
// .attr("class","ranked")
// .attr("id",function(d){return "_"+d.county})
// .attr("county",function(d){return d.county})
// .attr("x",function(d,i){return 20})
// //.attr("y",function(d,i){return parseInt(d.order)*12})
// .attr("y",function(d,i){return parseInt(data.indexOf(d))/2})
// //.text(function(d,i){return (parseInt(d.order)+1)+". Tract "+d.county.toString().slice(-6)+", "+d.countyName+" "+ Math.round(d.tally*10000)/10000})
// .text(function(d,i){return (parseInt(d.order)+1)+". "+d.countyName.slice(7,-16)+" "+ Math.round(d.tally*10000)/10000})
// .attr("transform","translate(0,20)")
// .attr("fill",function(d){
// return colorScale(d.tally)
// })
}
function updateList(data){
var svg = d3.select("#rankings svg").data(data)//.append("svg").attr("width",200).attr("height",data.length*12)
d3.selectAll(".ranked")//.remove()
.data(data)
.each(function(d,i){
var c = d3.select(this).attr("county")
d3.selectAll("#_"+d.county)
.transition()
.duration(1000)
.delay(i*20)
.attr("y",parseInt(data.indexOf(d))*12)
// .attr("y",parseInt(d.order)*12)
.attr("transform","translate(0,20)")
.text(function(d){
return (i+1)+". "+d.county+" "+Math.round(d.tally*10000)/10000
})
})
}
//ranks all counties by svi?
function rankCounties(){
var countiesInState =[]
for(var c in pub.all.features){
var state = pub.all.features[c].properties["ST_ABBR"]
if(state== pub.currentState){
var countyName = pub.all.features[c].properties.LOCATION
var county = pub.all.features[c].properties.FIPS//.replace(countyFIPS,"")
var tally = pub.all.features[c].properties.tally
countiesInState.push({county:county,tally:tally,countyName:countyName,data:pub.all.features[c].properties})
}
}
var sorted = countiesInState.sort(function(a,b){
return parseFloat(b.tally)-parseFloat(a.tally)
})
for(var s in sorted){
sorted[s]["order"]=s
}
//console.log(sorted)
return sorted
}
//this takes active themes and tallys the svi according to what is active
function calculateTally(toggleDictionary){
pub["activeThemes"]=[]
var activeThemesText = ""
var index=0
for(var t in toggleDictionary){
if(toggleDictionary[t]==true){
pub["activeThemes"].push(t)
if(index!=0){
activeThemesText+=" + "+t
}else{
activeThemesText+=t
}
index+=1
}
}
if(pub.activeThemes.length==measures.length){
d3.select("#activeThemesText").html("Showing the sum of all "+pub.activeThemes.length+" variables.")
}else{
d3.select("#activeThemesText").html("Showing the sum of "+pub.activeThemes.length+" variables.")
}
for(var i in pub.all.features){
var tally = 0
for(var t in toggleDictionary){
if(toggleDictionary[t]==true){
tally+=parseFloat(pub.all.features[i].properties[t])
}
}
pub.all.features[i].properties["tally"]=parseFloat(tally)
}
}
//this formats the datasets and combins them for use - needs to be adjusted for new data, definitedly need to be improved\
//converts svi to a Dictionary with FIPS as the key
function turnToDictFIPS(data){
var fipsDict = {}
for(var i in data){
// console.log(data[i])
var county = data[i].COUNTY
//need to change from FIPS to
var fips = data[i]["FIPS"]
//grab last 6 characters
if(fips){
fips = fips.substring(fips.length - 6)
fipsDict[fips]=data[i]
}
}
return fipsDict
}
//combine svi (i.e. all) with counties
function combineGeojson(counties){
//console.log(counties)
//get column names from first object
var propertyKeys = Object.keys(counties.features[0].properties)
// var propertyKeys = Object.keys(all[0])
for(var p in propertyKeys){
var pkey = propertyKeys[p]
minMaxDictionary[pkey]={max:0,min:99999}
}
var excludeKeys = ["ST_ABBR","STATE","ST","AREA_SQMI","COUNTY","LOCATION"]
for(var c in counties.features){
var countyFIPS = counties.features[c].properties.STCNTY
var tractFIPS = counties.features[c].properties.FIPS.replace(countyFIPS,"")
var data = counties.features[c].properties//all[tractFIPS]
counties.features[c]["id"]=tractFIPS
//var population = counties.features[c].properties.totalPopulation
//for now PR is undefined
if(data!=undefined){
var keys = Object.keys(data)
for(var k in keys){
var key = keys[k]
var value = data[key]
if(value!=-999 && value!=999 && excludeKeys.indexOf(key)==-1){
value = parseFloat(value)
if(value>minMaxDictionary[key].max){
minMaxDictionary[key].max=value
}
if(value<minMaxDictionary[key].min){
minMaxDictionary[key].min=value
}
}
if(value==-999 || value==999){
value = 0
}
if(isNaN(value)==false){
value = parseFloat(value)
}
counties.features[c].properties[key]=value
}
counties.features[c].properties["tally"]=parseFloat(data["SPL_THEMES"])
}
}
//console.log(counties)
return counties
}
//this draws the map, adds counties, and adds the pop up to the map
function drawMap(data,divName){//,outline){
// console.log(data);
//makes new map in the #map div
d3.select("#map")
.style("width",window.innerWidth+"px")
.style("height",window.innerHeight+"px")
mapboxgl.accessToken = "pk.eyJ1IjoiYzRzci1nc2FwcCIsImEiOiJja2J0ajRtNzMwOHBnMnNvNnM3Ymw5MnJzIn0.fsTNczOFZG8Ik3EtO9LdNQ"
var maxBounds = [
[-74.635258, 40.45], // Southwest coordinates
[-73.289334, 40.98] // Northeast coordinates
];
map = new mapboxgl.Map({
container: divName,
// style:"mapbox://styles/c4sr-gsapp/ckpwtdzjv4ty617llc8vp12gu",
style:"mapbox://styles/c4sr-gsapp/ckytx8oxk000e14rh745xntyo",
// maxZoom:15,
zoom: 12,
center:[-73.905,40.739],
preserveDrawingBuffer: true,
minZoom:1,
maxBounds: maxBounds
// bearing: 28
});
var hoverCountyID = null;
// add a layer called counties from the geojson and
map.on("load",function(){
const scale = new mapboxgl.ScaleControl({
maxWidth: 80,
unit: 'imperial'
});
map.addControl(scale);
map.addControl(new mapboxgl.NavigationControl(),'bottom-right');
map.dragRotate.disable();
map.addSource("counties",{
"type":"geojson",
"data":data
})
// JIA: This is where I tried to add another hover outline layer
map.addLayer({
'id': 'hoverOutline',
'type': 'line',
'source': 'counties',
'layout': {},
'paint': {
'line-color': '#000000',
'line-width': 1
}
})
map.addLayer({
'id': 'counties',
'type': 'fill',
'source': 'counties',
'paint': {
'fill-outline-color':"white",
'fill-color': "#fff",
'fill-opacity':.8
},
"filter": ["!=", "E_TOTPOP", 0] // filter out no population
},"hoverOutline")
//map.setFilter("counties",["==","stateAbbr","NY"])
map.setFilter("hoverOutline",["==","FIPS",""])
});
//detects mouse on counties layer inorder to get data for where mouse is
map.on("click","counties",function(e){
var fips = e.features[0]["properties"].FIPS
map.setFilter(hoverOUtline,["==","FIPS",fips])
var centroid = centroids[fips]
map.flyTo({
center: centroid,
zoom:13
});
})
map.on("mouseleave","counties",function(){
map.setFilter("hoverOutline",["==","FIPS",""])
})
map.on('mousemove', 'counties', function(e) {
var feature = e.features[0]
// console.log(feature)
map.getCanvas().style.cursor = 'pointer';
if(feature["properties"].FIPS!=undefined){
// console.log(feature["properties"])
map.setFilter("hoverOutline",["==","FIPS",feature["properties"].FIPS])
//this section just sets the x and y of the popup
var x = event.clientX+20;
var y = event.clientY+20;
var w = window.innerWidth;
var h = window.innerHeight;
if(x+200>w){
x = x-280
}
if(y+200>h){
y= h-220
}else if(y-200<150){
y = 150
}
d3.select("#mapPopup").style("visibility","visible")
.style("left",x+"px")
.style("top",y+"px")
var variableColorScale = d3.scaleLinear().domain([0,.5,1]).range(colors)
var variableText = ""
for(var a in pub.activeThemes){
var key = pub.activeThemes[a]
var value = feature["properties"][key]
var color = variableColorScale(value)
var displayKey =themeDisplayTextShort[key]
if(value>.8){
variableText+="<span style=\"color:"+color+"\"><strong>HIGH "+displayKey+":</strong>"+value+"</span><br>"
}else if(value<.2){
variableText+="<span style=\"color:"+color+"\"><strong>LOW "+displayKey+":</strong>"+value+"</span><br>"
}
}
//this section sets the text content of the popup
var locationName = feature["properties"]["LOCATION"].replace("New York County","Manhattan")
.replace(", New York","").replace("Census","")
//var countyName = feature["properties"]["COUNTY"]+" County, "+feature["properties"]["ST_ABBR"]
var population = feature["properties"]["E_TOTPOP"]
var displayString = "<b>"+locationName+"</b><br>" //+ "<br> Population: "+population+"<br>"
var activeTally = 0
var activeCount = 0
for(var t in toggleDictionary){
if(toggleDictionary[t]==true){
activeTally+=feature.properties[t]
activeCount+=1
}
}
if(Math.round(activeTally*10000)/10000==0){
displayString+="Not enough data for selected variables."
d3.select("#mapPopup").html(displayString+"<br"+variableText)
}else{
displayString+="Overall SVI: "
+Math.round(activeTally*10000)/10000
+" out of "+ activeCount
d3.select("#mapPopup").html(displayString+"<br>"+variableText)
}
}
//when mouseleaves, popup is hidden
map.on("mouseleave",'counties',function(){
d3.select("#mapPopup").style("visibility","hidden")
})
});
return map
}
//this is called when map is idle after first loading and then everytime the tally is changed
function colorByPriority(map){
//console.log(pub.all)
console.log(pub.activeThemes)
map.getSource('counties').setData(pub.all);
// map.setPaintProperty("counties", 'fill-opacity',1)
var matchString = {
property: "tally",
stops: [
[0,"#aaa"],
[.000001, colors[0]],
[pub.activeThemes.length*.2, colors[0]],
[pub.activeThemes.length/2,colors[1]],
[pub.activeThemes.length*.8, colors[2]],
[pub.activeThemes.length, colors[2]]
]
}
var opacitySteps = {
property: "tally",
stops: [
[0,1],
[.000001, 1],
[pub.activeThemes.length*.2, .9],
[pub.activeThemes.length/2, 0],
[pub.activeThemes.length*.8, .9],
[pub.activeThemes.length, 1]
]
}
map.setPaintProperty("counties", 'fill-opacity', opacitySteps)
map.setPaintProperty("counties", 'fill-color', matchString)
d3.select("#coverage").style("display","block")
}
//ENZ ////////////////////////////////////////////////////////