Javascript D3.js exit()似乎无法获取更新信息

Javascript D3.js exit()似乎无法获取更新信息,javascript,d3.js,Javascript,D3.js,我有一个Django视图将tablib CSV提供给D3.js。然而,我发现,无论我如何或在何处使用exit(),它都不会返回任何内容——因此,我无法删除旧的、不需要的元素,所有内容都只是重叠在一起 有什么想法吗?我把我的代码建立得很好 {对象列表%中的人的百分比} {{person.name} {%endfor%} 更新 var margin={顶部:20,右侧:20,底部:30,左侧:40}, 宽度=900-边距。左侧-边距。右侧, 高度=500-margin.top-margin.bot

我有一个Django视图将tablib CSV提供给D3.js。然而,我发现,无论我如何或在何处使用exit(),它都不会返回任何内容——因此,我无法删除旧的、不需要的元素,所有内容都只是重叠在一起

有什么想法吗?我把我的代码建立得很好


{对象列表%中的人的百分比}
{{person.name}
{%endfor%}
更新
var margin={顶部:20,右侧:20,底部:30,左侧:40},
宽度=900-边距。左侧-边距。右侧,
高度=500-margin.top-margin.bottom;
var x=d3.scale.ordinal()
.rangeRoundBands([0,宽度],.1);
变量y=d3.scale.linear()
.rangeRound([高度,0]);
var color=d3.scale.ordinal()
.范围([“#98abc5”、“#ff8c00”]);
var xAxis=d3.svg.axis()
.比例(x)
.东方(“底部”);
var yAxis=d3.svg.axis()
.比例(y)
.东方(“左”)
.tick格式(d3格式(“.2s”);
var svg=d3。选择(“.d3\u画布\u空间”)。追加(“svg”)
.attr(“宽度”,宽度+边距。左侧+边距。右侧)
.attr(“高度”,高度+边距。顶部+边距。底部)
.附加(“g”)
.attr(“转换”、“平移”(+margin.left+)、“+margin.top+”);
var date_info=$(“#id_date_form”).serialize(),
初始_csv_url=“{%url blahblah%}?”+日期信息;
函数updateMultiData(multi_csv_url){
d3.csv(多个csv url、函数(错误、数据){
color.domain(d3.keys(数据[0]).filter(函数(键){returnkey!==“Name”});
data.forEach(函数(d){
var y0=0;
d、 tasks=color.domain().map(函数(类别){return{category:category,y0:y0,y1:y0+=+d[category]};});
d、 任务总数=d.tasks[d.tasks.length-1].y1;
});
sort(函数(a,b){返回b.total-a.total;});
x、 域(data.map(函数(d){返回d.Name;}));
y、 域([0,d3.max(数据,函数(d){返回d.total_tasks;})];
svg.selectAll(“.name”).data(data.exit().remove()
svg.append(“g”)
.attr(“类”、“x轴”)
.attr(“变换”、“平移(0)”、“高度+”)
.呼叫(xAxis);
svg.append(“g”)
.attr(“类”、“y轴”)
.呼叫(yAxis)
.append(“文本”)
.attr(“变换”、“旋转(-90)”)
.attr(“y”,6)
.attr(“dy”,“.71em”)
.style(“文本锚定”、“结束”)
.文本(“任务”);
var person\u name=svg.selectAll(“.name”)
.数据(数据)
.enter().append(“g”)
.attr(“transform”,函数(d){return”translate(“+x(d.Name)+”,0)”;});
人名。选择全部(“rect”)
.data(函数(d){返回d.tasks;})
.enter().append(“rect”)
.attr(“宽度”,x.rangeBand())
.attr(“y”,函数(d){返回y(d.y1);})
.attr(“高度”,函数(d){返回y(d.y0)-y(d.y1);})
.style(“fill”,函数(d){返回颜色(d.category);});
console.log(svg.selectAll(“.name”).data(data.exit());
var legend=svg.selectAll(“.legend”)
.data(color.domain().slice().reverse())
.enter().append(“g”)
.attr(“类”、“图例”)
.attr(“transform”,函数(d,i){return“translate(0,+i*20+”);});
图例。追加(“rect”)
.attr(“x”,宽度-18)
.attr(“宽度”,18)
.attr(“高度”,18)
.样式(“填充”,颜色);
图例。追加(“文本”)
.attr(“x”,宽度-24)
.attr(“y”,9)
.attr(“dy”,“.35m”)
.style(“文本锚定”、“结束”)
.text(函数(d){return d;});
});
};
updateMultiData(初始\u csv\u url);
$(文档)。在(“单击”,“按钮.更新”\u d3\u csv“,功能(e){
e、 预防默认值();
var new_info=$(“#id_date_form”).serialize(),
new_multi_csv_url=“{%url blahblah%}?”+new_info;
更新多数据(新的多csv url);
log(新的多个csv url);
});

在上面的示例中,输入的节点似乎没有定义的类。任何后续的
d3.selectAll(“.name”)
将返回一个空选择,所有数据元素将显示在
方法下

您可能希望在每次追加输入节点时尝试分配相应的类名:

.enter().append("g").classed("name",true)

您可能还想考虑使用<代码> .DATA()/代码>的第二个参数为每个数据池定义一个唯一的标识符(key),如果顺序不同,确保每个更新都有正确的元素退出。

在代码中,“name”属性可能用作键:

var person_name = svg.selectAll(".name")
            .data(data,function(d) { return d.name; })

最后,我注意到您正在更新函数中添加轴。这意味着每次更新都会在以前的轴的基础上附加一组新的轴。您可能希望将它们移到顶层。

您是否尝试过为
.data()
提供一个函数,告诉它如何比较元素?默认情况下,它按索引匹配元素,因此只要您从未给出较短的数组,则
.exit()
选择中将不会有任何内容。@Larskothoff您的意思是什么?当您将数组传递给
.data()
时,d3会尝试将数组中的元素与已经存在的数据进行匹配。默认情况下,它使用数组中的索引执行此操作。也就是说,新数组中的第一个元素将与您之前传入的第一个元素相匹配——不管实际的元素是什么。
.exit()
选择包含与任何现有元素都不匹配的元素,但如果您始终
var person_name = svg.selectAll(".name")
            .data(data,function(d) { return d.name; })