如何将数据绑定到相应的D3.js地图元素?

时间:2016-03-10 01:53:07

标签: javascript d3.js svg topojson

我的介绍性问题是:

将数据绑定到D3.js地图的最佳方法是什么?

我提出了三种可能性:

1。根据数据应用一个类,然后将样式应用于类。

.attr("class", function(d) { return quantize(rateById.get(d.id)); })

此选项似乎是最受欢迎的(请参阅choropleth块),但它实际上并不绑定数据。因此,D3的意图似乎有点不诚实。它还意味着不能简单地为工具提示引用绑定数据,例如。

2。将topo.json要素集合数据与其余数据合并。

我们可以将所有数据放在一个变量中(可能使用forEach)。结果可能类似于:

var mergeData = [{
                    area: "NW",
                    mean: 45,
                    features: {...}
                }, {
                    area: "NE",
                    mean: 23,
                    features: {...}
                }, {
                    area: "SW",
                    mean: 87,
                    features: {...}
                }, {
                    area: "SE",
                    mean: 56,
                    features: {...}
                }];

然后我们可以将mergeData绑定到路径元素,通过将“d”属性指向d.features生成地图,并使用d.mean设置样式。这允许每个路径元素包含我们将需要的所有必要数据。但是,将它们组合在一起似乎很麻烦。

3。用所需数据替换要素集合数据。

绘制地图形状后,不需要要素集合数据。它可以被替换。为什么不简单地将我们需要的数据绑定到这些路径(生成地图形状之后),以便它始终可用于样式,工具提示等?我们只需要一个关键功能来将新数据与正确的地图形状相匹配。更新选择将负责更换。

d3.selectAll(".area").data(data, function(d) {
                            return d.id;
                        })
                        .style("fill", function(d) {
                            return colorScale(d.mean);
                        });

这似乎运作良好,干净整洁。需要注意的是数据的结构,特征集必须相同。在两组数据上评估相同的键功能。因此,如果我们的数据是嵌套的,我们无法访问d.values.id,因为要素集中没有对应的values - 它只是d.id。直观地说,我希望关键功能像filter一样工作,这样我们就可以在每个数据集中指定id的位置,如下所示:

return d.id === d.values.id;

没有办法实现这一点,是吗?

解决方法是将嵌套数据重构为第三个展平的数据变量,使其不再嵌套。那样d.id可以用在关键功能中。但这再一次看起来很麻烦。

哪种方式最好?或者还有另一个吗?

我还在学习D3,所以请随时纠正我的任何假设或直接编辑我的问题。

1 个答案:

答案 0 :(得分:1)

我刚刚发现的选项#3的解决方案实际上非常简单。在创建嵌套数据之后,可以立即迭代它,并且可以在第一级插入所需的数据。

data.map(function(d) { d.id = d.values.id; });

这样,它可以在完全相同的结构中使用关键功能。 values中的所有汇总仍可供以后使用。