使用 Protovis 的交互式面积图

发布于 2024-10-13 20:30:39 字数 1089 浏览 8 评论 0原文

对于 Protovis 新手来说,这是一个相当艰巨的项目,但也许你可以帮我把它分成易于理解的部分?

我想构建的是一个“交互式面积图”,如下所示: https://i.sstatic.net/ 7bs9W.png

首先,是数据...... 我在 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 
....       ...   .   .    .     .

对于每个省份和年份,我希望能够绘制面积图:

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

然后我想添加 2 种类型的交互性:

  1. 选择省份
  2. 时间滑块

一起,选择复选框和时间滑块确定在任何给定时间哪些区域可见。 例如,如果选择 A 省且年份为 1984 年,则仅显示该区域。如果现在拖动时间滑块,则会显示 A 省的相应年份。如果选中另一个省,则当时间滑块移动时,这些区域会重叠,并且两个区域都会重新绘制。

Protovis 问题:

  1. 如何设置此应用程序的数据格式(省、年、x、y)?
  2. 如何实现复选框与区域的绑定?
  3. 如何实现时间滑块?在 Protovis 中还是像带有侦听器的外部组件一样触发图形的重新渲染?

This is quite a daunting project to a Protovis newcomer, but maybe you could help me split it into digestible chunks?

What I would like to build is an "interactive Area chart", as sketched here: https://i.sstatic.net/7bs9W.png

First of all, it's the data ...
I have data for 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(d.x)) 
    .height(function(d) y(d.y)) 
    .fillStyle("rgb(21,173,210)") 
    .anchor("top").add(pv.Line) 
    .lineWidth(3); 

Then I would like to add 2 types of interactivity:

  1. Selection of Province
  2. Time slider

Together, the selection checkboxes and the time slider determine which areas are visible at any given time.
If, for example, Province A is selected and the year is 1984, only that area is displayed. If the time slider is now dragged, the corresponding years are now displayed for Province A. If another Province is checked, the areas are overlayed and both areas are redrawn when the time slider moves.

Protovis questions:

  1. How do I format the data (province, year, x, y) for this application?
  2. How do I achieve the binding of checkboxes to area?
  3. How do I implement the time slider? Within Protovis or like an external component with listeners that trigger re-rendering of the graph?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

岁月蹉跎了容颜 2024-10-20 20:31:01

我认为您正在尝试制作这对图表:

http://mbostock.github.io/protovis/ex/zoom.html< /a>


I think that you are trying to make that pair of charts:

http://mbostock.github.io/protovis/ex/zoom.html

手心的温暖 2024-10-20 20:30:47

格式化数据:第一步是使用一些外部工具将其转换为 JSON(我真的很喜欢 Google为此进行优化,尽管如果这就是您所需要的,那么它是一个相当大的工具 - 尝试 Mr. Data Converter 是一个快速而肮脏的选择)。这些工具可能会为您提供 JSON 对象形式的数据,如下所示:

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

一旦您获得了 JSON 形式的数据,您就会希望将其调整为适合您的可视化的形式。您将需要向每个 pv.Area 传递一个值数组 - 从您的描述来看,您似乎想要 [10, 100, 1000, 10000] 值。 Protovis 有很多用于操作数据的工具 - 请参阅 pv.Nest 运算符< /a>.有很多方法可以解决这个问题 - 我可能会这样做:

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']];
    });

它给你一个像这样的对象:

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

这为你设置了界面元素。将选中的省份和当前年份的数组保留在全局变量中:

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

并设置您的区域来引用这些变量:

// 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

现在使用其他一些库 - 我偏爱 jQuery,使用用于滑块的 jQuery UI - 来创建界面元素。每个元素的 onchange 函数只需要设置相应的全局变量并调用 vis.render() (假设您的根面板名为 vis)。这应该非常简单 - 请参阅此处使用 jQuery UI 制作的 Protovis 示例与您的想法非常相似的时间滑块。

Formatting data: The first step is to get it into JSON, using some external tool (I really like Google Refine for this, though it's a pretty big tool if this is all you need it for - try Mr. Data Converter for a quick and dirty option). These tools will probably give you data as a JSON object, like this:

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

Once you have the data available as JSON, you'll want to get it into shape for your vis. You're going to want to pass each pv.Area an array of values - from your description it looks like you want the [10, 100, 1000, 10000] values. Protovis has a lot of tools for manipulating data - see the pv.Nest operator. There are lots of ways you might approach this - I might 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 you up for the interface elements. Keep the array of checked Provinces and the current year in global variables:

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

and set up your area to reference those 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 some other library - I'm partial to jQuery, with jQuery UI for the slider - to create your interface elements. The onchange function for each element just needs to set the corresponding global variable and call vis.render() (assuming your root panel is called vis). This should be pretty simple - see here for a Protovis example using jQuery UI to make a time slider very similar to what you have in mind.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文