Created
February 9, 2024 18:44
-
-
Save PBI-DataVizzle/87968e821d1823cf34427ce9a7e197f4 to your computer and use it in GitHub Desktop.
vega-dubois-map
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"$schema": "https://vega.github.io/schema/vega/v5.json", | |
"description": "Entry for challenge 01 in the 2024 DVS Du Bois Visualization Contest.", | |
"usermeta": { | |
"developedBy": "Madison Giammaria", | |
"LinkedIn": "https://www.linkedin.com/in/madison-giammaria-58463b33", | |
"email": "[email protected]" | |
}, | |
"title": { | |
"text": "NEGRO POPULATION OF GEORGIA BY COUNTIES.", | |
"orient": "top", | |
"anchor": "middle", | |
"font": {"signal": "font"}, | |
"fontSize": 14, | |
"offset": -70, | |
"zindex": 99 | |
}, | |
"width": 400, | |
"padding": 5, | |
"signals": [ | |
{ | |
"name": "extent1870", | |
"description": "projection extent for the 1870 map", | |
"init": "[[0, -20], [width/2, height/2-20]]" | |
}, | |
{ | |
"name": "extent1880", | |
"description": "projection extent for the 1880 map", | |
"init": "[[width/2, height/2-20], [width, height-20]]" | |
}, | |
{ | |
"name": "font", | |
"description": "font to be used throught the chart", | |
"value": "sans-serif" | |
}, | |
{ | |
"name": "mapfontSize", | |
"description": "font size to be used for the map titles", | |
"value": 12 | |
}, | |
{ | |
"name": "mapfontWeight", | |
"description": "font weight to be used for the map titles", | |
"value": 500 | |
}, | |
{ | |
"name": "legendSymbolRadius", | |
"description": "radius for the legend circles", | |
"value": 10 | |
}, | |
{ | |
"name": "legendFontSize", | |
"description": "font size for the legend labels", | |
"value": 10 | |
}, | |
{ | |
"name": "legendFontWeight", | |
"description": "font weight for the legend labels", | |
"value": 100 | |
}, | |
{ | |
"name": "legendFontOpacity", | |
"description": "legend font opacity for the legend labels", | |
"value": 0.5 | |
}, | |
{ | |
"name": "countyMouseover", | |
"description": "capture county datums on mouseover to be used to adjust the strokeWidth on the maps", | |
"on": [ | |
{ | |
"events": { | |
"type": "mouseover", | |
"marknames": ["map_1870", "map_1880"] | |
}, | |
"update": "datum" | |
}, | |
{ | |
"events": {"type": "mouseout", "marknames": ["map_1870", "map_1880"]}, | |
"update": "null" | |
} | |
] | |
}, | |
{ | |
"name": "focusedCounty", | |
"description": "capture the datum of the clicked county", | |
"value": null, | |
"on": [ | |
{ | |
"events": {"type": "click"}, | |
"marknames": ["map_1870", "map_1880"], | |
"update": "isValid(focusedCounty) && focusedCounty['county'] === datum['county'] ? null : datum" | |
}, | |
{ | |
"events": {"type": "click"}, | |
"update": "isValid(datum) && isValid(datum['county']) ? focusedCounty : null" | |
} | |
] | |
}, | |
{ | |
"name": "focusedLegendItem", | |
"description": "capture the datum of the clicked legend item", | |
"value": null, | |
"on": [ | |
{ | |
"events": {"type": "click"}, | |
"update": "isValid(focusedLegendItem) && isValid(group()) && isValid(group()['datum']) && focusedLegendItem['populationDescription'] === group()['datum']['populationDescription'] ? null : group()['datum']" | |
}, | |
{ | |
"events": {"type": "click"}, | |
"update": "isValid(group()) && isValid(group()['datum']) && isValid(group()['datum']['populationDescription']) ? focusedLegendItem : null" | |
} | |
] | |
}, | |
{ | |
"name": "height", | |
"description": "dynamically adjust the height based on the width", | |
"init": "1.3*width" | |
}, | |
{ | |
"name": "infoIconPath", | |
"value": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-208a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" | |
} | |
], | |
"projections": [ | |
{ | |
"name": "projection1870", | |
"type": "mercator", | |
"fit": {"signal": "data('map')"}, | |
"extent": {"signal": "extent1870"} | |
}, | |
{ | |
"name": "projection1880", | |
"type": "mercator", | |
"fit": {"signal": "data('map')"}, | |
"extent": {"signal": "extent1880"} | |
} | |
], | |
"marks": [ | |
{ | |
"name": "background_img", | |
"description": "background image to make the visual look like the original plate", | |
"type": "image", | |
"encode": { | |
"enter": { | |
"url": { | |
"value": "https://raw.githubusercontent.com/Giammaria/Du-Bois-DVS-challenge/main/2024/challenge-01/_artifacts/background.jpg" | |
}, | |
"x": {"value": -40}, | |
"y": {"value": -80}, | |
"aspect": {"value": true}, | |
"width": {"signal": "width*1.2"} | |
} | |
} | |
}, | |
{ | |
"name": "info_icon", | |
"description": "an icon that displays more information about the visual on hover", | |
"type": "symbol", | |
"encode": { | |
"enter": { | |
"shape": {"signal": "infoIconPath"}, | |
"size": {"value": 0.0045}, | |
"x": {"signal": "width+5"}, | |
"y": {"signal": "-100"}, | |
"fill": {"value": "#666"}, | |
"cursor": {"value": "pointer"}, | |
"tooltip": { | |
"signal": "{title: 'Interaction Instructions', 'County Hover:': 'Hover over a county on one of the maps to see additional details.', 'County Select:': 'Click a county to quickly compare across maps.', 'Legend Select:': 'Click a legend item to filter all counties to a specific population range', 'Clear Selections:': 'Click on the paper background to clear selections.'}" | |
} | |
} | |
} | |
}, | |
{ | |
"name": "title_1870", | |
"description": "title over the 1870 map", | |
"type": "text", | |
"interactive": false, | |
"encode": { | |
"enter": { | |
"text": {"value": "1870"}, | |
"fontSize": {"signal": "mapfontSize"}, | |
"fontWeight": {"signal": "mapfontWeight"}, | |
"font": {"signal": "font"}, | |
"align": {"value": "center"}, | |
"baseline": {"value": "bottom"}, | |
"x": {"signal": "extent1870[0][0]+(extent1870[1][0])*0.25"}, | |
"dy": {"signal": "-5"} | |
} | |
} | |
}, | |
{ | |
"name": "map_1870", | |
"description": "map of the 1870 Georgia counties", | |
"type": "shape", | |
"from": {"data": "map"}, | |
"encode": { | |
"update": { | |
"fill": {"field": "hex1870"}, | |
"fillOpacity": { | |
"signal": "isValid(focusedLegendItem) ? datum['populationDescription1870'] === focusedLegendItem['populationDescription'] ? 1 : 0 : !isValid(focusedCounty) ? 1 : focusedCounty['county'] === datum['county'] ? 1 : 0" | |
}, | |
"stroke": {"value": "#000"}, | |
"strokeWidth": { | |
"signal": "isValid(countyMouseover) && countyMouseover['county'] === datum['county'] ? 3 : 0.5" | |
}, | |
"tooltip": {"signal": "datum['tooltip']"}, | |
"cursor": {"value": "pointer"} | |
} | |
}, | |
"transform": [{"type": "geoshape", "projection": "projection1870"}] | |
}, | |
{ | |
"name": "legend1_group", | |
"description": "group for the legend symbols and labels that appear at the top right of the visual", | |
"type": "group", | |
"from": {"data": "legend1"}, | |
"encode": { | |
"enter": { | |
"x": {"signal": "extent1870[1][1]*0.875"}, | |
"y": {"scale": "legend1Y", "field": "sort", "band": 0.5} | |
} | |
}, | |
"marks": [ | |
{ | |
"name": "legend_circles", | |
"type": "arc", | |
"encode": { | |
"enter": { | |
"startAngle": {"value": 0}, | |
"endAngle": {"signal": "2*PI"}, | |
"outerRadius": {"signal": "legendSymbolRadius"}, | |
"fill": {"signal": "parent['hex']"}, | |
"cursor": {"value": "pointer"} | |
}, | |
"update": { | |
"opacity": { | |
"signal": "isValid(focusedLegendItem) ? focusedLegendItem['populationDescription'] === parent['populationDescription'] ? 1 : 0.1 : 1" | |
} | |
} | |
} | |
}, | |
{ | |
"name": "legend_text", | |
"type": "text", | |
"encode": { | |
"enter": { | |
"text": {"signal": "parent['populationDescription']"}, | |
"align": {"value": "left"}, | |
"baseline": {"value": "middle"}, | |
"dx": {"signal": "2*legendSymbolRadius"}, | |
"fontSize": {"signal": "legendFontSize"}, | |
"font": {"signal": "font"}, | |
"fontWeight": {"signal": "legendFontWeight"}, | |
"opacity": {"signal": "legendFontOpacity"}, | |
"cursor": {"value": "pointer"} | |
}, | |
"update": { | |
"opacity": { | |
"signal": "isValid(focusedLegendItem) ? focusedLegendItem['populationDescription'] === parent['populationDescription'] ? legendFontOpacity : 0.1 : legendFontOpacity" | |
} | |
} | |
} | |
} | |
] | |
}, | |
{ | |
"name": "title_1880", | |
"description": "title over the 1880 map", | |
"type": "text", | |
"interactive": false, | |
"encode": { | |
"enter": { | |
"text": {"value": "1880"}, | |
"fontSize": {"signal": "mapfontSize"}, | |
"fontWeight": {"signal": "mapfontWeight"}, | |
"font": {"signal": "font"}, | |
"align": {"value": "center"}, | |
"baseline": {"value": "bottom"}, | |
"x": {"signal": "extent1880[0][0]+(extent1880[1][0])*0.125"}, | |
"y": {"signal": "extent1880[0][1]"}, | |
"dy": {"signal": "15"} | |
} | |
} | |
}, | |
{ | |
"name": "map_1880", | |
"description": "map of the 1880 Georgia counties", | |
"type": "shape", | |
"from": {"data": "map"}, | |
"encode": { | |
"update": { | |
"fill": {"field": "hex1880"}, | |
"fillOpacity": { | |
"signal": "isValid(focusedLegendItem) ? datum['populationDescription1880'] === focusedLegendItem['populationDescription'] ? 1 : 0 : !isValid(focusedCounty) ? 1 : focusedCounty['county'] === datum['county'] ? 1 : 0" | |
}, | |
"stroke": {"value": "#000"}, | |
"strokeWidth": { | |
"signal": "isValid(countyMouseover) && countyMouseover['county'] === datum['county'] ? 3 : 0.5" | |
}, | |
"tooltip": {"signal": "datum['tooltip']"}, | |
"cursor": {"value": "pointer"} | |
} | |
}, | |
"transform": [{"type": "geoshape", "projection": "projection1880"}] | |
}, | |
{ | |
"name": "legend2_group", | |
"description": "group for the legend symbols and labels that appear at the by right of the visual", | |
"type": "group", | |
"from": {"data": "legend2"}, | |
"encode": { | |
"enter": { | |
"x": {"signal": "extent1880[0][0]*0.15"}, | |
"y": {"scale": "legend2Y", "field": "sort", "band": 0.5} | |
} | |
}, | |
"marks": [ | |
{ | |
"name": "legend_circles", | |
"type": "arc", | |
"encode": { | |
"enter": { | |
"startAngle": {"value": 0}, | |
"endAngle": {"signal": "2*PI"}, | |
"outerRadius": {"signal": "legendSymbolRadius"}, | |
"fill": {"signal": "parent['hex']"}, | |
"cursor": {"value": "pointer"} | |
}, | |
"update": { | |
"opacity": { | |
"signal": "isValid(focusedLegendItem) ? focusedLegendItem['populationDescription'] === parent['populationDescription'] ? 1 : 0.1 : 1" | |
} | |
} | |
} | |
}, | |
{ | |
"name": "legend_text", | |
"type": "text", | |
"encode": { | |
"enter": { | |
"text": {"signal": "parent['populationDescription']"}, | |
"align": {"value": "left"}, | |
"baseline": {"value": "middle"}, | |
"dx": {"signal": "2*legendSymbolRadius"}, | |
"fontSize": {"signal": "legendFontSize"}, | |
"font": {"signal": "font"}, | |
"fontWeight": {"signal": "legendFontWeight"}, | |
"opacity": {"signal": "legendFontOpacity"}, | |
"cursor": {"value": "pointer"} | |
}, | |
"update": { | |
"opacity": { | |
"signal": "isValid(focusedLegendItem) ? focusedLegendItem['populationDescription'] === parent['populationDescription'] ? legendFontOpacity : 0.1 : legendFontOpacity" | |
} | |
} | |
} | |
} | |
] | |
}, | |
{ | |
"type": "group", | |
"name": "footer_group", | |
"description": "The group of marks located at the bottom of the canvas that provide additional information about the visual", | |
"marks": [ | |
{ | |
"name": "footer_prefix_text", | |
"description": "The labels for each footer item", | |
"type": "text", | |
"from": {"data": "footer"}, | |
"interactive": false, | |
"encode": { | |
"update": { | |
"opacity": {"value": 1}, | |
"fill": {"signal": "'#888'"}, | |
"font": {"signal": "font"}, | |
"fontWeight": {"value": 100}, | |
"fontSize": {"value": 10}, | |
"baseline": {"value": "middle"}, | |
"x": {"signal": "0"}, | |
"y": {"signal": "scale('yScaleFooter', datum['id'])"}, | |
"text": {"signal": "datum['text'][0]"} | |
} | |
} | |
}, | |
{ | |
"name": "footer_href_text", | |
"description": "The hyperlinks for each footer item", | |
"type": "text", | |
"from": {"data": "footer"}, | |
"encode": { | |
"update": { | |
"opacity": {"value": 0.65}, | |
"fill": {"signal": "'#333'"}, | |
"font": {"signal": "font"}, | |
"fontWeight": {"value": 600}, | |
"fontSize": {"value": 10}, | |
"baseline": {"value": "middle"}, | |
"x": { | |
"signal": "data('footer_prefix_text')[0]['bounds']['x2']+5" | |
}, | |
"y": {"signal": "scale('yScaleFooter', datum['id'])"}, | |
"text": {"signal": "datum['text'][1]"}, | |
"href": {"field": "href"}, | |
"cursor": {"value": "pointer"}, | |
"tooltip": {"field": "href"} | |
}, | |
"hover": {"opacity": {"value": 1}} | |
} | |
} | |
] | |
} | |
], | |
"scales": [ | |
{ | |
"name": "legend1Y", | |
"type": "band", | |
"domain": {"data": "legend1", "field": "sort"}, | |
"range": [ | |
{"signal": "extent1870[1][1] * 0.04"}, | |
{"signal": "extent1870[1][1] * 0.5"} | |
] | |
}, | |
{ | |
"name": "legend2Y", | |
"type": "band", | |
"domain": {"data": "legend2", "field": "sort"}, | |
"range": [ | |
{"signal": "extent1880[0][1]*1.1"}, | |
{"signal": "extent1880[0][1]*1.85"} | |
] | |
}, | |
{ | |
"name": "yScaleFooter", | |
"type": "band", | |
"domain": {"data": "footer", "field": "id"}, | |
"range": [ | |
{"signal": "height+20"}, | |
{"signal": "height+30+length(data('footer'))*11"} | |
] | |
} | |
], | |
"data": [ | |
{ | |
"name": "colorLookup", | |
"values": [ | |
{ | |
"populationLookup": "20000 - 30000", | |
"populationDescription": "BETWEEN 20,000 AND 30,000", | |
"hex": "#312B64", | |
"sort": 0 | |
}, | |
{ | |
"populationLookup": "15000 - 20000", | |
"populationDescription": "15,000 TO 20,000", | |
"hex": "#5D3A26", | |
"sort": 1 | |
}, | |
{ | |
"populationLookup": "10000 - 15000", | |
"populationDescription": "10,000 TO 15,000", | |
"hex": "#BF9C83", | |
"sort": 2 | |
}, | |
{ | |
"populationLookup": "5000 - 10000", | |
"populationDescription": "5,000 TO 10,000", | |
"hex": "#D22A49", | |
"sort": 3 | |
}, | |
{ | |
"populationLookup": "2500 - 5000", | |
"populationDescription": "2,500 TO 5,000", | |
"hex": "#DB918D", | |
"sort": 4 | |
}, | |
{ | |
"populationLookup": "1000 - 2500", | |
"populationDescription": "1,000 TO 2,000", | |
"hex": "#EAB45C", | |
"sort": 5 | |
}, | |
{ | |
"populationLookup": "> 1000", | |
"populationDescription": "UNDER 1,000", | |
"hex": "#5C6D5F", | |
"sort": 6 | |
} | |
] | |
}, | |
{ | |
"name": "legend1", | |
"source": "colorLookup", | |
"transform": [{"type": "filter", "expr": "datum['sort'] <= 2"}] | |
}, | |
{ | |
"name": "legend2", | |
"source": "colorLookup", | |
"transform": [{"type": "filter", "expr": "datum['sort'] > 2"}] | |
}, | |
{ | |
"name": "1870", | |
"format": {"type": "csv"}, | |
"url": "https://raw.githubusercontent.com/Giammaria/Du-Bois-DVS-challenge/main/2024/challenge-01/data/data-1870.csv", | |
"transform": [ | |
{ | |
"type": "lookup", | |
"key": "populationLookup", | |
"from": "colorLookup", | |
"fields": ["Population"], | |
"values": ["populationDescription", "hex", "sort"] | |
} | |
] | |
}, | |
{ | |
"name": "1880", | |
"format": {"type": "csv"}, | |
"url": "https://raw.githubusercontent.com/Giammaria/Du-Bois-DVS-challenge/main/2024/challenge-01/data/data-1880.csv", | |
"transform": [ | |
{ | |
"type": "lookup", | |
"key": "populationLookup", | |
"from": "colorLookup", | |
"fields": ["Population"], | |
"values": ["populationDescription", "hex", "sort"] | |
} | |
] | |
}, | |
{ | |
"name": "footer", | |
"values": [ | |
{ | |
"id": 1, | |
"text": [ | |
"Data Source:", | |
"github.com/ajstarks/dubois-data-portraits/" | |
], | |
"href": "https://github.com/ajstarks/dubois-data-portraits/tree/master/challenge/2024/challenge01" | |
}, | |
{ | |
"id": 2, | |
"text": ["Original:", "Negro Population of Georgia by County"], | |
"href": "https://github.com/Giammaria/Du-Bois-DVS-challenge/blob/main/2024/challenge-01/_artifacts/original-plate-06.jpg" | |
}, | |
{ | |
"id": 3, | |
"text": ["Challenge:", "2024 Du Bois Visualization Challenge"], | |
"href": "https://www.datavisualizationsociety.org/news/2024/2/2/advance-your-data-viz-skills-with-the-weekly-2024-du-bois-visualization-challenge" | |
}, | |
{ | |
"id": 4, | |
"text": ["Emulated By:", "Madison Giammaria"], | |
"href": "https://www.linkedin.com/in/madison-giammaria-58463b33" | |
} | |
] | |
}, | |
{ | |
"name": "map", | |
"format": {"type": "topojson", "feature": "counties"}, | |
"url": "https://raw.githubusercontent.com/Giammaria/Du-Bois-DVS-challenge/main/2024/challenge-01/data/counties-topojson.json", | |
"transform": [ | |
{ | |
"type": "formula", | |
"expr": "datum['properties']['county']", | |
"as": "county" | |
}, | |
{ | |
"type": "formula", | |
"expr": "replace(datum['county'], /[^a-zA-Z]+/, '')", | |
"as": "county" | |
}, | |
{ | |
"type": "lookup", | |
"key": "County", | |
"from": "1870", | |
"fields": ["county"], | |
"values": ["populationDescription", "hex", "sort"], | |
"as": ["populationDescription1870", "hex1870", "sort1870"] | |
}, | |
{ | |
"type": "lookup", | |
"key": "County", | |
"from": "1880", | |
"fields": ["county"], | |
"values": ["populationDescription", "hex", "sort"], | |
"as": ["populationDescription1880", "hex1880", "sort1880"] | |
}, | |
{ | |
"type": "formula", | |
"expr": "datum['sort1870'] === datum['sort1880'] ? 'No Change' : datum['sort1870'] > datum['sort1880'] ? 'Increase ⭡' : 'Decrease ⭣'", | |
"as": "Change" | |
}, | |
{ | |
"type": "formula", | |
"expr": "{title: 'Georgia Negro Population - ' + datum['Change'], 'County:': datum['county'], '1870 Population:': lower(datum['populationDescription1870']), '1880 Population:': lower(datum['populationDescription1880'])}", | |
"as": "tooltip" | |
} | |
] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment