County boundaries (TopoJSON)
Source: GeoData@Wisconsin – “Counties (TIGER/Line), WI 2019” URL: https://geodata.wisc.edu/catalog/604F7A0B-1715-43B8-835E-4032851481AD Description: This dataset contains county-level administrative boundaries for the state of Wisconsin, derived from the 2019 TIGER/Line files.
Forestry dataset (CSV)
Source: Wisconsin DNR Open Data Portal URL: https://data-wi-dnr.opendata.arcgis.com Description: Contains county-level forest acreage, total acreage, and derived forest percentage values.
1. Converted the Wisconsin county shapefile into TopoJSON for use in ObservableHQ.
2. Loaded the CSV and computed a normalized variable: forest_pct = forest_acres total_acres
3. Ensured the GEOID field in both datasets matched (converted CSV GEOID to string).
4. Joined the CSV attributes to the TopoJSON features using GEOID as the unique identifier.
5. Cleaned column names and removed unused fields.
TIGER/Line boundaries usually are more generalized and will likely not perfectly align with high‑resolution datasets.
Forest acreage estimates may include classification error.
There is a temporal mismatch that I discovered because County boundaries (2019) and forestry data (2023/2024) are from different years.
Counties with very small total acreage may show exaggerated forest percentages as a result of normalization bias.
There was 1 county that was missing data or [null].
Q1. A choropleth map requires a single shared ID field (in my case GEOID) that exists in both the TopoJSON file and the csv file. In order to achieve this step of joining these files together, I read the csv and convert it to a table where each row has an associated GEOID field, and forest percentage. Then, I need to turn this table into a lookup structure where the key becomes the GEOID and the value becomes the entire row of data. Using mapshaper, I converted the GeoJSON file into TopoJSON and assign each county polygon to its own 'properties.GEOID'. This process allows the geometry (shape) to be joined to the attribute (forest percentage). Therefore, once this step is complete, for each county polygon, I am able to use GEOID to retrieve the associated row from the csv.
Q2. Using the color scale, I need to translate the numeric values I currently have, into a color. I decided on a range of values, with 3 natural breaks because it captured my data the best without simplifying or overcomplicating it visually. I chose a green color scheme because it is associated with vegetation and my map displays vegetation percentage (total) across Wisconsin counties. I used colorbrewer.org to determine this scheme (light green=low forest; dark green=high forest density). The color scale takes the numbers (rang of values) I had decided on and returns a specific color from that data set which will be displayed on my choropleth map. To summarize, each county's forest percent will be fed into the color scale I chose, which will then return the color as the polygon's "fill". After this is completed, it will allow the viewer to visually compare forest cover across each county.
Q6. SVG stands for Scalable Vector Graphics and is a vector-based way of drawing shapes. To further explain this, essentially shapes will be defined mathematically rather than as pixels which allows the sharpness to be increased. In this choropleth map, it works as a canvas tool where each county is drawn as a SVG path that represents its boundary geometry. In the upper JavaScript code, it displays the control I have over these paths: fill color, stroke color, stroke width, etc.). I can then attach these attributes and styles directly to each county to convey the purpose of my map.
Q3. In order to determine polygon border style, it is important to note that borders are separate from the fill. Meaning, strong color sets the outline color for each county, and stroke width acts differently by controlling how thick that outline will appear on the map. Having more thin borders allows for counties to be distinguished from each other without being overpowered by the other colors. I chose white because I felt like it captured this difference/concision the best.
Q4. To create a legend, I input the color scale and title of my map into the legend helper which then draws up a small graphic to mirror the color scale and add tick marks/labels. This then lets the viewer/map reader interpret what light green vs. dark green values will mean. In this case, my legend appears as a gradient bar from light to dark labeled with low to high numeric values of forest percentage.
Q5. In order for values to appear when hovering over each polygon, attaching mouse events to each county polygon has to be implemented. This can be then seen when the mouse moves over a county, it will identify the code and feature by using the county's GEOID and looking up the corresponding csv row. After this step, it can display a small box that will show information on the county name and forest percentage, which can be extremely helpful when exact data is displayed/present but doesn't clutter up the map with labels everywhere.