Interactive area diagram using Protovis

This is a pretty complicated project for protovit beginners, but maybe you could help me break it into digestible pieces?

What I would like to build is an β€œinteractive area diagram,” as described here: http://i.stack.imgur.com/7bs9W.png

First of all, this is the data ... I have data for the provinces in Excel:

  Province Year 10 100 1000 10000 
 A 1970 2 4 6 3 
 A 1971 3 6 8 5 
 B 1970 6 9 12 6 
 B 1971 4 8 11 8 
 .... ....  .  .  .

For each province and year, I would like to be able to draw an area chart:

vis.add(pv.Area) .data(data.ProvinceA[1970]) .bottom(1) .interpolate("basis") .left(function(d) x(dx)) .height(function(d) y(dy)) .fillStyle("rgb(21,173,210)") .anchor("top").add(pv.Line) .lineWidth(3); 

Then I would like to add 2 types of interactivity:

  • Province Choice
  • Time slider

Together, the selection flags and the time slider determine which areas are visible at any given time. If, for example, province A is selected, and in 1984, only this area is displayed. If the time slider is now being dragged, the corresponding years are displayed for province A. If another province is checked, the regions overlap and both regions redraw when the time slider is moved.

Questions of protovism:

  • How do I format data (province, year, x, y) for this application?
  • How to achieve the binding of flags to the area?
  • How to implement a time slider? As part of Protovis or as an external component with listeners that cause re-rendering of the schedule?
+4
source share
2 answers

Data formatting. The first step is to get it in JSON using some external tool (I really like Google Refine for this, although it's a pretty big tool, if that's all you need for this - try Mr. Data Converter for a quick and dirty option). These tools are likely to provide you with data as a JSON object, for example:

 `[{"Province":"A", "Year":"1970", "10":2, "100":4, "1000":6, "10000":3}, ...]` 

Once you have the data available as JSON, you want to get it in the form for your view. You will want to pass each pv.Area an array of values ​​- from your description, it seems to you that you want the values ​​[10, 100, 1000, 10000]. The protoviz has many tools for managing data - see the pv.Nest operator . There are many ways you could approach: I could do this:

 data = pv.nest(data) .key(function(x) {return x.Province}) .key(function(x) {return x.Year}) .rollup(function(v) { return [v[0]['10'], v[0]['100'], v[0]['1000'], v[0]['10000']]; }); 

which gives you an object like:

 { A: { 1970: [2,4,6,3] // ... }, // ... } 

This sets up for interface elements. Store an array of checked provinces and the current year in global variables:

 var currentProvinces = ['A', 'B', ...]; var currentYear = 1970; 

and set up your scope to reference these variables:

 // a containing panel to help with layout and data var panel = vis.add(pv.Panel) .data(function() currentProvinces); // making this a function allows it to // be re-evaluated later // the area itself var area = panel.add(pv.Area) .data(function(province) data[province][currentYear]); // plus more area settings as needed 

Now use a different library - I'm partly related to jQuery, with the jQuery UI for the slider - to create interface elements. The onchange function for each element simply needs to set the corresponding global variable and call vis.render() (if your root panel is called vis ). It should be pretty simple - see here for a Protovis example using the jQuery user interface to make the time slider look very much like what you mean.

+6
source

I think you are trying to make this pair of diagrams:

http://mbostock.imtqy.com/protovis/ex/zoom.html

0
source

Source: https://habr.com/ru/post/1336668/


All Articles