如何使用d3过滤器和更新功能在数据选择之间切换 [英] How to use d3 filter and update function to toggle between data selections
问题描述
我试图通过根据房屋地址是否以街道",道路",道路"等结尾的价格创建条形图来掌握d3.
I'm trying to get to grips with d3 by creating a bar chart of house prices based on whether the property address ends with 'Street', 'Road', 'Way' etc.
但是,我也希望基于本地社区的数据列来更改数据视图.
However, I'd also like the view of the data to change based on a column of data for local neighbourhoods.
这是关于此主题的第二个查询.这是上一个查询-如何为d3图表提取名义标签
It's the second query on this topic. Here's the previous query - How to extract nominal labels for d3 chart
您可以在此处查看通过Pandas的to_json函数提取的数据结构: http://plnkr.co/edit/He3yPUfuE8k7hvIkupjS?p=preview
You can see the structure of the data extracted through Pandas' to_json function here: http://plnkr.co/edit/He3yPUfuE8k7hvIkupjS?p=preview
我使用过嵌套函数在本地区域上键入数据,但无法解决如何插入d3.filter方法将数据限制在选定区域的问题.
I've used a nest function to key the data on the the local areas, but can't work out how to plug in a d3.filter method to restrict the data to a selected area.
我有一个可以根据按键创建选择按钮的功能:
I've got a function which creates a select button based on the keys:
var options = dropDown.selectAll("option")
.data(nested_data)
.enter()
.append("option");
options.text(function (d) { return d.key; })
.attr("value", function (d) { return d.key; });
但是我无法解决的是如何将选择的值插入d3脚本的绘图部分.
But what I can't work out is how to plug the value from this selection into the plotting part of the d3 script.
d3.select("svg")
.selectAll("circle")
.data(nested_data)
.enter()
.append("circle")
d3.selectAll("circle")
.attr("cx", function(d) {
console.log(d["street_name"]);
return street_scale(d["street_name"]);
})
.attr("cy", function(d) {
return price_scale(d["value"]);
})
.attr("r", 5)
.attr("fill", "steelblue");
虽然我知道我需要一个更新功能来继续在用户选择之间更改图表,但我找不到适合我的示例.
And while I know I need an update function to continue to change the chart as users select between, I've not found an example that I can adapt.
预先感谢您的耐心-我对d3和Javascript noob还是陌生的.
Thank you in advance for your patience - I'm very new to d3 and a Javascript noob.
推荐答案
最后考虑一下您想要的数据结构.由于d3
喜欢对象的数组,并且您想按地区进行过滤,因此我在想一想:
Think about the data structure you want in the end. Since d3
likes arrays of objects and you want to filter by district, I'm picturing this:
var data = {
district1: [
{
street_split: 'a',
value: 1
},{
street_split: 'b',
value: 2
}
],
district2: [
{
street_split: 'a',
value: 1
},{
street_split: 'b',
value: 2
}
],
etc...
您的过滤器然后简单地变成:
Your filter then simply becomes:
data[someDistrict]
因此,我们如何获取这种格式的数据.我会在一个循环中完成所有操作,数据,范围,标签等...
So, how do we get your data in this format. I'd do everything in one loop, the data, the extents, the labels, etc...:
var orgData = {}, // our final data like above
street_labels = d3.set(), // set of streets
districts = d3.set(), // set of districts
minVal = 1e99, // min of values
maxVal = -1e99; //max of values
data.forEach(function(d){
d.value = +d.value; // convert to numeric
street_labels.add(d.street_split); // set of street_labels
districts.add(d.district); // set of districts
if (d.value < minVal) minVal = d.value; // new min?
if (d.value > maxVal) maxVal = d.value; //new max?
if (!orgData[d.district]){ // we want a associate array with keys of districts
orgData[d.district] = []; // and values that are arrays of object
}
orgData[d.district].push({ // those objects are street_split and value
street_split: d.street_split,
value: d.value
});
});
现在我们如何更新其他选择?那简直变成了:
Now how do we update on a different select? That simply becomes:
dropDown.on("change", function() {
d3.selectAll("circle")
.data(orgData[this.value]) // new data
.attr("cx", function(d) { // update attributes
return street_scale(d.street_split);
})
.attr("cy", function(d) {
return price_scale(d.value);
});
});
这是我的工作代码.
这篇关于如何使用d3过滤器和更新功能在数据选择之间切换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!