Introduction
Every now and then, you might come across the need to present your user with data that can be sliced by multiple criteria. Say, for instance, you are so lucky as to write an app that follows the departures and the introduction of new characters in 'Game of Thrones/Song of ice and fire'. Your data might be sliced by house, by character gender, by geographic location, show season, book volume, etc.
This control will give your user what they need.
Have fun (just drag and drop stuff, you will get the hang of it):
Using the Code
Just include the JavaScript and its dependencies (D3.js and require.js) in your page. Call the setup function and you are good to go (or just have a look at the site code). Read on for a description of the variable the setup function expects.
Series
This is the data displayed. For each one of these, your user would see a bar in each group of the chart. For our example, these are the number of characters killed off and the number of characters introduced.
Segment
This is the way you 'slice and dice' your data (the dimensions). In our case, this includes the Gender, Location, House, etc. These can be used as the categories for the X axis or as filters that limit the scope of the displayed data (the breadcrumbs). The filtering is performed by dragging a specific bars group onto a segment or vice versa. The user may also swap the X axis segment for another segment, in which case the total of the data is not expected to change but it would be distributed by the new segmentation.
Segments may be arranged in a hierarchy, such as the Chapters are child elements of the Seasons and the Continent, Region, Location hierarchy.
Data Callback
Each time the user interacts with the data, the callback you provide is invoked to retrieve additional data. You might want to go to the server from your callback or you might want to send all the data at once and provide it as needed (see Mock data). The callback takes in the following data:
Requested Segment
The X axis segment of the new data.
Filters
If the user had narrowed the field of the data they wish to be presented, you get the filtering in the request. These filters map to the breadcrumbs on the top of the chart.
The callback is expected to return the data in a format the holds a collection of Segment Values each containing the data that should be plotted to the X axis and a collection of values, one for each series displayed.
Here is an example of what is what (formatted as JSON but this is not the actual stracture of the data. Check out the code for that):
{Segment : House
SegmentValue : Stark
SeriesValues:[ {Killed : 42},{Introduced : 2}]
}
Mock Data
To do my own testing and to show off this stuff, I created a few classes to provide trials data:
Generated Data (Easy)
You provide the Segment and Series descriptions and the segment values. The class generates random data for you. Check out the TrialsGameOfThronesDataGenerator
class.
Generated Data & Segment Values (Super Easy)
You provide the Segment and Series descriptions. The class generates segment values and data for you (say if you have a 'House' segment, it creates 'House 1', 'House 2', etc.)
There should probably be a provider that takes real data, segmented in full, and does the job... maybe I will get to it if there is popular demand, or you can do it on github and send a pull request.
Customizing the Look
Everything is CSSable. Series and Segment descriptions include the CSS class name.
Touch (not so) Ready
The design was done with touch in mind, there are no tooltips and everything is done by simply dragging. Alas, there seems to be a problem in identifying drop targets with touch (there is no unified support for 'mouse over' JavaScript event). I might get to fixing that in the future.
Points of Interest
Check out the github project.
D3
The control is based on D3 library by Mike Bostock. If you haven't yet, go to the gallery and check out what you can do with this awesome stuff.
Typescript
The code is written in Typescript (and transpiled to JavaScript). Typescript is the way to write and maintain complex client side stuff without losing your mind. If you are not familiar with it, you might want to check their site.
Note that the code can be consumed by any JavaScript, so it is great for you even if you don't like that new thing.
Typescript requires a little setup. The project was built with both Visual Studio and the new light Visual Studio Code, so you have all you need to get going with those two. I think it is also ready for other IDEs. Let me know if you encounter a problem.
History
- 29/10/2015: Initial release