我有一个Django View将Tablib CSV提供给D3.js.但是,我发现无论我使用exit()的方式和位置,它都没有返回任何东西 - 因此,我无法删除旧的,不需要的元素,而且所有内容都叠加在彼此之上。
有什么想法吗?我基于the basic Stacked Bar Chart example非常难以使用我的代码。
<div id="id_d3_canvas" class="d3_canvas_space">
</div>
<div>
<form id="id_date_form">
<input id="id_date_small" name="date1" type="text" value="03-01-2012">
<input id="id_date_large" name="date2" type="text" value="{% now 'n-j-Y' %}">
<select name="our_people" multiple>
{% for person in object_list %}
<option value="{{ person.name }}" selected>{{ person.name }}</option>
{% endfor %}
</select>
</form>
<button id="id_test_data_gather" class="btn btn-primary update_d3_csv">Update</button>
</div>
<script src="{{ STATIC_URL }}cms/js/d3.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 900 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.rangeRound([height, 0]);
var color = d3.scale.ordinal()
.range(["#98abc5", "#ff8c00"]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
var svg = d3.select(".d3_canvas_space").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var date_info = $("#id_date_form").serialize(),
initial_csv_url = "{% url blahblah %}?" + date_info;
function updateMultiData(multi_csv_url) {
d3.csv(multi_csv_url, function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Name"; }));
data.forEach(function(d) {
var y0 = 0;
d.tasks = color.domain().map(function(category) { return {category: category, y0: y0, y1: y0 += +d[category]};});
d.total_tasks = d.tasks[d.tasks.length - 1].y1;
});
data.sort(function(a, b) { return b.total - a.total; });
x.domain(data.map(function(d) { return d.Name; }));
y.domain([0, d3.max(data, function(d) { return d.total_tasks; })]);
svg.selectAll(".name").data(data).exit().remove()
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Tasks");
var person_name = svg.selectAll(".name")
.data(data)
.enter().append("g")
.attr("transform", function(d) { return "translate(" + x(d.Name) + ",0)"; });
person_name.selectAll("rect")
.data(function(d) { return d.tasks; })
.enter().append("rect")
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.category); });
console.log(svg.selectAll(".name").data(data).exit());
var legend = svg.selectAll(".legend")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35m")
.style("text-anchor", "end")
.text(function(d) { return d; });
});
};
updateMultiData(initial_csv_url);
$(document).on("click", "button.update_d3_csv", function(e){
e.preventDefault();
var new_info = $("#id_date_form").serialize(),
new_multi_csv_url = "{% url blahblah %}?" + new_info;
updateMultiData(new_multi_csv_url);
console.log(new_multi_csv_url);
});
</script>
答案 0 :(得分:2)
在上面的示例中,似乎输入的节点没有已定义的类。任何后续d3.selectAll(".name")
都会返回一个空的选择,所有数据元素都会显示在.enter()
方法下。
每次输入节点时,您可能想尝试分配相应的类名:
.enter().append("g").classed("name",true)
您可能还需要考虑使用.data()
的第二个参数为每个数据点定义唯一标识符(键),以确保在每次更新时退出正确的元素(如果顺序不同)。
https://github.com/mbostock/d3/wiki/Selections#wiki-data
在您的代码中,“name”属性可能用作密钥:
var person_name = svg.selectAll(".name")
.data(data,function(d) { return d.name; })
最后我注意到你将轴附加到更新功能中。这意味着一组新的轴将附加在之前的每个更新上。您可能希望将它们移到顶层。