Add user controls for data slicing and dicing
Now comes the fun part. All that extra effort we put into making our components aware of filtering, and it all comes down to this: User controls.
Here’s what we’re building:
It’s a set of filters for users to slice and dice our visualization. The shortened dataset gives you 2 years, 12 job titles, and 50 US states. You’ll get 5 years and many more job titles with the full dataset.
We’re using the architecture we discussed earlier to make it work. Clicking buttons updates a filter function and communicates it all the way up to the App component. App then uses it to update this.state.filteredSalaries, which triggers a re-render and updates our dataviz.
We’re building in 4 steps, top to bottom:
- Update
App.jswith filtering and a<Controls>render - Build a
Controlscomponent, which builds the filter based on inputs - Build a
ControlRowcomponent, which handles a row of buttons - Build a
Togglecomponent, which is a button
We’ll go through the files linearly. That makes them easier for me to explain and easier for you to understand, but that also means there’s going to be a long period where all you’re seeing is an error like this:
If you want to see what’s up during this process, just remove an import or two and maybe a thing from render. For instance, it’s complaining about ControlRow in this screenshot. Remove the ControlRow import on top and delete <ControlRow ... /> from render. The error goes away, and you see what you’re doing.
Step 1: Update App.js
All right, you know the drill. Add imports, tweak some things, add to render. We have to import Controls, set up filtering, update the map’s zoom prop, and render a white rectangle and Controls.
The white rectangle makes it so the zoomed-in map doesn’t cover up the histogram. I’ll explain when we get there.
We import the Controls component and add a default salariesFilter function to this.state. The updateDataFilter method passes the filter function and filteredBy dictionary from arguments to App state. We’ll use it as a callback in Controls.
The rest of filtering setup happens in the render method.
We add a .filter call to filteredSalaries, which uses our salariesFilter method to throw out anything that doesn’t fit. Then we set up zoom if a US state was selected.
We built the CountyMap component to focus on a given US state. Finding the centroid of a polygon, re-centering the map, and increasing the sizing factor. It creates a nice zoom effect.
And here’s the downside of this approach. SVG doesn’t know about element boundaries. It just renders stuff.
See, it goes under the histogram. Let’s fix that and add the Controls render while we’re at it.