在d3.js中有关更新,输入,退出数据和选择的问题

时间:2019-04-22 08:48:58

标签: d3.js

我正在做一个视觉项目,使用d3展示1900-2018年的自然灾害。我想添加一个互动动作,让人们可以选择显示的第一年和去年。
最初,我按以下方式创建图片:

d3.csv("output.csv", rowConventer, function (data) {
            dataset = data;
            var xScale = d3.scaleBand()
                .domain(d3.range(dataset.length))
                .range([padding, width - padding])
                .paddingInner(0.05);
            var yScale = d3.scaleLinear()
                .domain([0, 
                    d3.max(dataset, function (d) {
                        return d.AllNaturalDisasters;
                    })])
                .range([height - padding, padding])
                .nice();

            stack = d3.stack().keys(["Drought", "Earthquake", "ExtremeTemperature", "ExtremeWeather", "Flood", "Impact", "Landslide", "MassMovementDry", "VolcanicActivity", "Wildfire"]);
            series = stack(dataset);
            gr = svg.append("g");
            groups = gr.selectAll("g")
            .data(series)
            .enter()
            .append("g")
            .style("fill", function(d, i) {
                return colors(i);
            })
            .attr("class", "groups");
            rects = groups.selectAll("rect")
                .data(function(d) { return d; })
                .enter()
                .append("rect")
                .attr("x", function(d, i) {
                    return xScale(i);
                })
                .attr("y", function(d) {
                    return yScale(d[1]);
                })
                .attr("height", function(d) {
                    return yScale(d[0]) - yScale(d[1]);
                })
                .attr("width", xScale.bandwidth())
                .append("title")
                .text(function (d) {
                    var rect = this.parentNode;// the rectangle, parent of the title
                    var g = rect.parentNode;// the g, parent of the rect.
                    return d.data.Year + ", " + d3.select(g).datum().key + "," + (d[1]-d[0]);
                });
           d3.select("button")
               .on("click", choosePeriod);

我简化了一些代码以使我的问题变得简单。在最后一行,我添加了一个事件侦听器以实现上述功能。更新功能为choosePeriod。现在如下:

    function choosePeriod() {
        firstYear = parseInt(document.getElementById("FirstYear").value);
        lastYear = parseInt(document.getElementById("LastYear").value);
        d3.csv("output.csv", rowConventer, function (newdata) {
            dataset = newdata;
            series=stack(dataset);
            groups.data(series);
            groups.selectAll("rect")
                .data(function (d) {
                    return d;
                })
                .enter()
                .append("rect")
                .attr("x", function(d, i) {
                    return xScales(i);
                })
                .attr("y", function(d) {
                    return yScales(d[1]);
                })
                .attr("height", function(d) {
                    return yScales(d[0]) - yScales(d[1]);
                })
                .attr("width", xScales.bandwidth())
                .append("title")
                .text(function (d) {
                    var rect = this.parentNode;// the rectangle, parent of the title
                    var g = rect.parentNode;// the g, parent of the rect.
                    return d.data.Year + ", " + d3.select(g).datum().key + "," + (d[1]-d[0]);
                });
            groups.selectAll("rect")
                    .data(function (d) {
                        return d;
                    })
                    .exit()
                    .remove();

        })
    }

通过rowConventer实现数据集的更改,这在这个问题中并不重要。现在,功能choosePeriod并未按预期运行! enter以及exitupdate都无法正常工作!整个画面一团糟!例如,我想要的是,如果我输入了firstYear=1900lastYear=2000,则图片应以1900-2000的周期进行更新以显示。如何实现?

我不熟悉整个结构的安排,我的意思是,在某个地方使用d3.select()class而不是id的{​​{1}}吧?

1 个答案:

答案 0 :(得分:0)

看起来您已经处理了回车和退出选择。您唯一缺少的是更新选择,它将处理已经存在的矩形,不需要添加或删除。为此,请复制您的更新模式,但只需删除enter()。append()位,例如:

groups.selectAll("rect")
                .data(function (d) {
                    return d;
                })
                .attr("x", function(d, i) {
                    return xScales(i);
                })
                .attr("y", function(d) {
                    return yScales(d[1]);
                })
                .attr("height", function(d) {
                    return yScales(d[0]) - yScales(d[1]);
                })
                .attr("width", xScales.bandwidth())
                .append("title")
                .text(function (d) {
                    var rect = this.parentNode;// the rectangle, parent of the title
                    var g = rect.parentNode;// the g, parent of the rect.
                    return d.data.Year + ", " + d3.select(g).datum().key + "," + (d[1]-d[0]);
                })