D3.js exit()似乎没有得到更新的信息 [英] D3.js exit() not seeming to get updated information

查看:175
本文介绍了D3.js exit()似乎没有得到更新的信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Django视图将tablib CSV提供给D3.js.然而,我发现,无论如何或在哪里我使用exit(),它不返回任何东西 - 因此,我不能删除旧的,不需要的元素,一切只是叠加在彼此之上。

I've got a Django View feeding a tablib CSV to D3.js. However, I'm finding that no matter how or where I use exit(), it isn't returning anything- and thusly, I cannot remove the old, unneeded elements, and everything just overlays on top of each other.

任何想法?我根据基本的Stacked Bar Chart示例很难编写代码。

Any ideas? I based my code pretty hard off of 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>


推荐答案

在上面的例子中,没有定义类。任何后续 d3.selectAll(。name)将返回一个空选择,所有数据元素将显示在 .enter c $ c>方法。

In your example above it seems that the entered nodes have no defined class. Any subsequent d3.selectAll(".name") will return an empty selection and all data elements will show up under .enter() method.

每次输入节点时,您都​​可以尝试分配相应的类名:

You might want to try assigning the corresponding classname every time entering nodes are appended:

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

您还可以考虑使用 .data()的第二个参数为每个数据点定义唯一标识符(键)确保在每次更新时退出正确的元素,如果顺序不同。
https://github.com/mbostock/d3/wiki/Selections #wiki-data

You might also want to consider using the second argument of .data() to define a unique identifier (key) for each datapoint, ensuring that correct elements are exited on each update, if the order is different. https://github.com/mbostock/d3/wiki/Selections#wiki-data

在您的代码中,name属性可能用作键:

In your code "name" property could probably be used as a key:

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

最后我注意到你正在追加轴在更新函数内。这意味着一组新的轴将被附加在每个更新之上的前一个。您可能希望将它们移动到顶层。

Finally I notice that you are appending the axes inside the update function. This means a new set of axes will be appended on every update on top of the previous ones. You might want to move those out to the top level.

这篇关于D3.js exit()似乎没有得到更新的信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆