/cdn.vox-cdn.com/uploads/chorus_image/image/55043939/aca_dashboard.0.jpg)
Growing uncertainty around the future of health care in the US has insurance providers scrambling. A number of them have decided to stop offering their products on the health insurance exchanges (HIX) — marketplaces where Obamacare compliant insurance plans are sold.
More and more providers are joining the ones who have already exited, leaving many who depend on these exchanges with little or no choice in insurance options.
Vox’s Sarah Kliff and Sarah Frostenson have been tracking and reporting on the evolving insurance coverage landscape. But at the pace things are changing, there is a need for a solution that would make it easy for reporters to keep abreast with these rapid changes.
With this challenge in mind, the Storytelling Studio collaborated with Vox to create an internal tool for managing HIX data and generating coverage maps from it.
Prioritize aggressively to define the product
Building a tool to manage a complex dataset such as health care coverage comes with the risk of “scope-creep” — attempting to build too much into one tool.
To avoid losing sight of the main objectives, we came together to first list all the things the tool should and could do. We then aggressively prioritized, cut and refined items in the list to come up with a compact set of features to include in the first version of tool.
The tool was to be built as a dashboard that can act as a place for reporters to look up current coverage status, as well as generate maps at both the national and state levels. Another feature that made the cut was generating maps simulating providers leaving a county or state.
Once the list of features was finalized, we had to figure out the best way to build it.
A tech spec in progress... pic.twitter.com/tedKMSMPyp
— Kavya Sukumar (@kavyaSukumar) April 12, 2017
This would have been an easy candidate for a simple CRUD dashboard with Rails or Django. But like most newsrooms, we lean toward building static sites whenever possible. Building something outside the Studio’s general workflow and infrastructure often end up being maintenance overheads.
In addition to the data management and mapping features, the dashboard also needed to have a robust authentication system because it allows users to change data permanently.
After evaluating a lot of different approaches, we decided to build it like our other apps — a static page built with Middleman and hosted on Chorus, Vox Media’s media stack. For dynamic data we used Kinto, an open source JSON storage service from Mozilla.
We used our existing servers, workflow and tools. This approach also came with an added advantage of being able to plug into Chorus authentication.
The tool had enough moving parts to warrant two developers. While I focused on the data management aspect of the dashboard, Casey Miller built mapping and image generation.
Simplify the data management
One of the reasons we built this tool is because there is no one place where HIX data can be reliably scraped. The data is often hand curated from various sources. This tool does not remove the need for curation. It merely makes it easier by giving the users an interface to update and view the data.
But we still needed a base data source to begin with, which came from the Robert Wood Johnson Foundation (RWJF). RWJF sent us an Excel file detailing the current coverage status by county.
With a combination of rake tasks and shell scripts, the data was parsed and uploaded to our Kinto instance.
On the client, a common data adapter script fetched data asynchronously from Kinto and made it available to both the maps and the data management page via callbacks.
:no_upscale()/cdn.vox-cdn.com/uploads/chorus_asset/file/8601815/Screen_Shot_2017_05_30_at_1.35.26_PM.png)
Export dataset as static maps
Once I set up the backend, Casey began working on the map generation UI for the tool. The tool needed to be able to create both maps of the United States and individual states. It also needed the ability to display either the most up-to-date provider count data or provider count data based on a hypothetical scenario that could then be exported as an image for use in stories. While the user would set the hypothetical provider info in the app’s provider view, the map view needed some sort of UI to allow the user to create these different subsets of maps.
Since this is a relatively simple tool with only a few options, Casey decided to place the UI elements in a sidebar to the right of the map. This also happens to coincidentally follow the same format that we set up for creating projects in Autotune, Vox Media’s open-source centralized suite of tools for creating charts, graphs and other story elements.
When finished filling out the information in the sidebar, the user can hit “Submit” to update the map on the left. Once the user is happy with the map they’ve generated, they can click “Save image” to download a png of the map to their local machine.
The save image functionality relies on a version of pancakejs, “A mini-library for easily flattening SVG and Canvas elements into images on the fly,” that was ever so slightly tweaked to allow for the saving of retina images (rather than the lower resolution images it was exporting by default).
Refactor and optimize
At nearly 5MB, HIX data is a heavy payload to download in its entirety on each reload of the dashboard. We needed a way to manipulate data locally and share it between mapping page and the data editing page.
There was a definitely a case to be made for caching data locally across sessions.
LocalStorage was quickly ruled out as an option. With multiple versions of the data we needed to store, and with future plans for extending the tool to handle historical data, we would easily exceed the 10MB cap on localStorage.
We decided to use IndexedDB instead. IndexedDB has some set up overhead but, in the end, it turned out to be exactly what we needed.
Data fetch from Kinto is asynchronous. Unlike localStorage APIs, indexedDB APIs are also largely asynchronous.
It was only a matter of time before the code descended into async hell. At one point, there were seven levels of nesting of functions with eight different potential places for callback. Code readability hit rock bottom. Debugging got harder and harder. Something had to give.
:no_upscale()/cdn.vox-cdn.com/uploads/chorus_asset/file/8601409/Screen_Shot_2017_05_30_at_12.45.03_PM.png)
All callbacks were replaced with JavaScript Promises. Code started looking much better and less error-prone.
:no_upscale()/cdn.vox-cdn.com/uploads/chorus_asset/file/8601417/Screen_Shot_2017_05_30_at_12.43.03_PM.png)
Release the tool
The tool is now available to Vox reporters.
Since we started developing the tool, Alabama has already seen some changes in coverage. Depending on how the story and data evolves, we may add more features, such as comparing historical data and combining it with other datasets.
Keep an eye out for health care coverage maps as the insurance coverage changes in reaction to the market and policies. And if you want to keep up with the latest twists and turns of the health care debate, sign up for VoxCare — Vox’s afternoon briefing on the health care news that matters the most.