D3 - 根据数据键更新图表
D3 - Update chart based on data keys
我是 D3 的新手,我想在一些散点图上训练自己(基于 NYT 的散点图:Student debt。
我设法重新创建了一张这样的图表:Oklahoma Colleges。
现在,我的条目比俄克拉荷马州的图表多得多,所以我的图表可读性不是很好,我想根据一个按钮过滤数据,我可以 select 使用该按钮仅显示 "public" 所大学或 "private" 所大学。
我已经阅读了很多关于 ENTER-UPDATE-EXIT 方法的教程,但我在实际应用它时仍然遇到一些问题。
假设以下 JSON 文件:
[ {
"Id": 1,
"Name": "College A",
"Type": "Public" }, {
"Id": 2,
"Name": "College B",
"Type": "Private" }, {
"Id": 3,
"Name": "College C",
"Type": "Public" }, {
"Id": 4,
"Name": "College D",
"Type": "Public" }, {
"Id": 5,
"Name": "College E",
"Type": "Private" }, {
"Id": 6,
"Name": "College F",
"Type": "Private" }, ]
我想实现以下算法:
button.on("change"){
If value == "public" :
display data where data.type == "public"
Else
display data where data.type == "private"
}
我的第一个解决方案是每次使用新数据集按下按钮(并擦除之前的 SVG)时创建一个 SVG。但我认为有更好的方法来做到这一点:)
你能帮帮我吗?
谢谢!
编辑:跟随@sapote warrior 的回答-
这是我加载数据时所做的:
d3.json("data.json", function(data) {
//Coerce string to numbers
...
dataset = data;
...
//Add axis and legend
}
当我点击两个按钮之一时:
function update(input){
var data = [];
for(i in dataset) {
if(dataset[i]["Type"] == input)
data.push(dataset[i]);
}
test = data; //Global scope variable, to check if new data is here on the console
circles = svg.selectAll(".circle")
.data(data);
circles.exit().remove();
circles.enter().append("circle")
.attr("class","circle")
...
}
但这并不完美。第一次单击任何按钮时圆圈正确显示,然后当我单击第二个按钮时它们并没有全部消失,而且新数据似乎没有正确附加。
嗯,对进入-更新-退出过程的理解还有点问题^^
编辑:好的,问题解决了!我刚刚在实施进入-更新-退出方法时犯了一些错误。用减少的数据集来理解这个问题,现在我很清楚了:)
我想我也许能帮到你。假设您的圈子已经显示在 SVG 上,一种方法是在单击按钮时构建一个新的值数组,其类型为 "Public" 或 "Private"。像这样:
publicButton.on("click", function() {
newData = [];
for(i in existingDataArray) {
if(existingDataArray[i]["Type"] == "Public")
newData.push(existingDataArray[i]);
}
现在您可以将此新数据与您提到的 .data().enter().exit().remove()
方法一起使用,以将新数据附加到您的圈子对象。之后,您可以删除那些不在新数据中的圈子,并保留那些在新数据中的圈子。那些你保留的,你可以对他们做一些事情,比如更新他们的颜色,或者如果你愿意的话什么都不做。有点像这样:
var circles = svg.selectAll("circle").data(newData);
circles.exit().remove();
circles.enter().attr("fill", ...);
}
希望这对一些人有所帮助,如果您有任何问题,请告诉我。
我是 D3 的新手,我想在一些散点图上训练自己(基于 NYT 的散点图:Student debt。
我设法重新创建了一张这样的图表:Oklahoma Colleges。
现在,我的条目比俄克拉荷马州的图表多得多,所以我的图表可读性不是很好,我想根据一个按钮过滤数据,我可以 select 使用该按钮仅显示 "public" 所大学或 "private" 所大学。
我已经阅读了很多关于 ENTER-UPDATE-EXIT 方法的教程,但我在实际应用它时仍然遇到一些问题。
假设以下 JSON 文件:
[ { "Id": 1, "Name": "College A", "Type": "Public" }, { "Id": 2, "Name": "College B", "Type": "Private" }, { "Id": 3, "Name": "College C", "Type": "Public" }, { "Id": 4, "Name": "College D", "Type": "Public" }, { "Id": 5, "Name": "College E", "Type": "Private" }, { "Id": 6, "Name": "College F", "Type": "Private" }, ]
我想实现以下算法:
button.on("change"){
If value == "public" :
display data where data.type == "public"
Else
display data where data.type == "private"
}
我的第一个解决方案是每次使用新数据集按下按钮(并擦除之前的 SVG)时创建一个 SVG。但我认为有更好的方法来做到这一点:)
你能帮帮我吗? 谢谢!
编辑:跟随@sapote warrior 的回答-
这是我加载数据时所做的:
d3.json("data.json", function(data) {
//Coerce string to numbers
...
dataset = data;
...
//Add axis and legend
}
当我点击两个按钮之一时:
function update(input){
var data = [];
for(i in dataset) {
if(dataset[i]["Type"] == input)
data.push(dataset[i]);
}
test = data; //Global scope variable, to check if new data is here on the console
circles = svg.selectAll(".circle")
.data(data);
circles.exit().remove();
circles.enter().append("circle")
.attr("class","circle")
...
}
但这并不完美。第一次单击任何按钮时圆圈正确显示,然后当我单击第二个按钮时它们并没有全部消失,而且新数据似乎没有正确附加。
嗯,对进入-更新-退出过程的理解还有点问题^^
编辑:好的,问题解决了!我刚刚在实施进入-更新-退出方法时犯了一些错误。用减少的数据集来理解这个问题,现在我很清楚了:)
我想我也许能帮到你。假设您的圈子已经显示在 SVG 上,一种方法是在单击按钮时构建一个新的值数组,其类型为 "Public" 或 "Private"。像这样:
publicButton.on("click", function() {
newData = [];
for(i in existingDataArray) {
if(existingDataArray[i]["Type"] == "Public")
newData.push(existingDataArray[i]);
}
现在您可以将此新数据与您提到的 .data().enter().exit().remove()
方法一起使用,以将新数据附加到您的圈子对象。之后,您可以删除那些不在新数据中的圈子,并保留那些在新数据中的圈子。那些你保留的,你可以对他们做一些事情,比如更新他们的颜色,或者如果你愿意的话什么都不做。有点像这样:
var circles = svg.selectAll("circle").data(newData);
circles.exit().remove();
circles.enter().attr("fill", ...);
}
希望这对一些人有所帮助,如果您有任何问题,请告诉我。