Step 12: Dropdown to select map key

In this step, we are going to create a dropdown to select the key after which the map is colored.

Function for the coloring

Until now, the map is colored when the CSV inside the GeoJSON is loaded. We want to be able to change the colors without having to reload the CSV data (and the GeoJSON) because the data is already available.

So far, the data of the CSV is only available within the function which loads the file. We need to be able to access this data from outside of this function so we declare a new variable in which we store the data once it is available.

map.js - variable to store the data
 7
 8
 9
10
11
12
// ...

// We define a variable to later hold the data of the CSV.
var mapData;

// ...

In the function where we load the CSV, we store the data to the new variable.

map.js - store the data
70
71
72
73
74
75
76
77
78
79
80
81
82
  // ...

  // Read the data for the cartogram
  d3.csv('data/areastatistics.csv', function(data) {

    // We store the data object in the variable which is accessible from
    // outside of this function.
    mapData = data;

    // This maps the data of the CSV so it can be easily accessed by
    // the ID of the municipality, for example: dataById[2196]

    // ...

Now we can use the map data to upate the colors any time we want. We can therefore define a function which will do exactly that. The coloring is already done in the CSV function and we can take a lot of it to create our function, namely setting the domain of the quantize scale (as this depends on which data key we are looking at) and the setting the class of the feature paths.

map.js - function to update map colors
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// ...

/**
 * Update the colors of the features on the map. Each feature is given a
 * CSS class based on its value.
 */
function updateMapColors() {
  // Set the domain of the values (the minimum and maximum values of
  // all values of the current key) to the quantize scale.
  quantize.domain([
    d3.min(mapData, function(d) { return getValueOfData(d); }),
    d3.max(mapData, function(d) { return getValueOfData(d); })
  ]);
  // Update the class (determining the color) of the features.
  mapFeatures.selectAll('path')
    .attr('class', function(f) {
      // Use the quantized value for the class
      return quantize(getValueOfData(dataById[getIdOfFeature(f)]));
    });
}

// ...

Since setting the domain of the quantize scale and setting the class of the feature paths is now handled by a separate function, we can remove this part from the CSV file and instead call the function we just created. This prevents duplication of code.

map.js - call updateMapColors from within CSV
 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
  // ...

  // Read the data for the cartogram
  d3.csv('data/areastatistics.csv', function(data) {

    // We store the data object in the variable which is accessible from
    // outside of this function.
    mapData = data;

    // This maps the data of the CSV so it can be easily accessed by
    // the ID of the municipality, for example: dataById[2196]
    dataById = d3.nest()
      .key(function(d) { return d.id; })
      .rollup(function(d) { return d[0]; })
      .map(data);

    // We add the features to the <g> element created before.
    // D3 wants us to select the (non-existing) path objects first ...
    mapFeatures.selectAll('path')
        // ... and then enter the data. For each feature, a <path>
        // element is added.
        .data(features.features)
      .enter().append('path')
        // As "d" attribute, we set the path of the feature.
        .attr('d', path)
        // When the mouse moves over a feature, show the tooltip.
        .on('mousemove', showTooltip)
        // When the mouse moves out of a feature, hide the tooltip.
        .on('mouseout', hideTooltip)
        // When a feature is clicked, show the details of it.
        .on('click', showDetails);

    // Call the function to update the map colors.
    updateMapColors();

  });

  // ...

Action to change the key

Now we need to trigger an update of the map colors when an option of the dropdown is selected.

map.js - trigger action to change map colors
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// ...

// Listen to changes of the dropdown to select the key to visualize on
// the map.
d3.select('#select-key').on('change', function(a) {
  // Change the current key and call the function to update the colors.
  currentKey = d3.select(this).property('value');
  updateMapColors();
});

// ...

And finally we can update the instructions as this is a new action the user than perform.

index.html - update instructions
27
28
29
30
31
32
33
34
      <!-- ... -->
        <h5>Instructions</h5>
        <ul>
          <li>Change the key using the dropdown above the map.</li>
          <li>Select a municipality to show the details.</li>
          <li>Scroll in the map to zoom in and out.</li>
        </ul>
      <!-- ... -->

Next

Proceed to Step 13: Declare sources and show instructions again.

Code