D3:数据集更新不会从DOM中删除元素

时间:2017-09-19 19:38:45

标签: javascript jquery d3.js

我有一个折线图,默认情况下我只需显示元素的子集,然后在下拉事件中显示不同的子集。

这是初始代码:

 varlines = svg.append("g")
    .attr('id', 'lines')
    .selectAll('g')
    .data(datum.filter(function(d) {
            return d.group == 'default'
        }),
        function(d) {
            return d.name
        }
    ).enter()
    .append("g")
    .attr("class", 'varline')
    .append("path")
    .attr("class", "line")
    .attr("id", function(d) {
        return 'line_' + d.name
    })
    .attr("d", function(d) {
        return line(d.datum);
    });

它工作正常。 现在,这是用于更新我的选择的代码:

$('.dropdown-menu a').click(function(d) {
    var g = this.text;
    dd.select("button").text(g) // switch header

    var newdata = datum.filter(function(d) {
        return d.group == g
    }); # datalines for selected group

    varlines.data(newdata, function(d) { return d.name })
        .enter()
        .merge(varlines)
        .append("g")
        .attr("class", 'varline')
        .attr("id", function(d) {
            return 'line_' + d.name
        })
        .append("path")
        .attr("class", "line")
        .attr("d", function(d) {
            return line(d.datum);
        });

    varlines.exit().remove()

它很奇怪。虽然它添加了东西并且没有复制dom元素,但它并没有删除旧元素。

此外,当我在任何步骤console.log(varlines);时,它只显示_groups数组中的两个初始元素,并且没有_enter_exit属性,即使有3行也是如此在svg。

我正在使用d3v4,jquery3.1.1.slim

2 个答案:

答案 0 :(得分:2)

如果您查看varlines,您会发现它只是输入选项:

varlines = svg.append("g")
    .attr('id', 'lines')
    .selectAll('g')
    .data(datum.filter(function(d) {
            return d.group == 'default'
        }),
        function(d) {
            return d.name
        }
    ).enter()
    .append("g")
    //etc...

当然,你不能在输入选择上调用exit()。因此,这个:

varlines.exit().remove()

......没用。

解决方案:通过破解它来使varlines成为“更新”选择(我在这里使用var,所以我们避免它是全局的):

var varlines = svg.append("g")
    .attr('id', 'lines')
    .selectAll('g')
    .data(datum.filter(function(d) {
            return d.group == 'default'
        }),
        function(d) {
            return d.name
        }
    );

varlines.enter()
    .append("g")
    //etc...

请注意以下事实:由于您使用的是D3 v4,因此必须使用merge(),否则将在代码首次运行时显示。或者,您可以只复制代码:

varlines = svg.append("g")
    .attr('id', 'lines')
    .selectAll('g')
    .data(datum.filter(function(d) {
            return d.group == 'default'
        }),
        function(d) {
            return d.name
        }
    )

varlines.enter()
    .append("g")
    //all the attributes here

varlines.//all the attributes here again

编辑:你的编辑中的问题很清楚:当你这样做时......

.attr("class", "line")

...你正在覆盖上一堂课。因此,它应该是:

.attr("class", "varline line")

以下是更新的plunker:https://plnkr.co/edit/43suZoDC37TOEfCBJOdT?p=preview

答案 1 :(得分:0)

以下是我的新代码,遵循Gerardo的建议以及Mike的教程:https://bl.ocks.org/EmbraceLife/efb531e68ce46c51cb1df2ca360348bb

function update(data) {

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


  // ENTER
  // Create new elements as needed.
  //
  // ENTER + UPDATE
  varlines.enter().append("g")
      .attr("class", 'varline')
      .attr("id", function(d) {
                    return 'line_' + d.name
                })
                .append("path")
                .attr("class", "line")
                .attr("d", function(d) {
                    return line(d.datum);
                })
                .style('stroke', function(d) {
                    return z(d.name)
                });
    // .merge(varlines); does not help if uncomment and move after .enter()

  // EXIT
  // Remove old elements as needed.
  varlines.exit().remove();
}

然后在初始代码(queue.await(...))中:

svg.append("g")
   .attr('id', 'lines');
var data = datum.filter(function(d){return (d.group == 
settings['groups_settings']['default_group']) && (d.tp == tp)});
update(data)

和下拉列表更改事件相同:

var newdata = datum.filter(function(d){return (d.group == g) && (d.tp == tp)});
update(newdata);

行为保持不变 - 正确显示第一批,但不删除任何更改的行(只是不断添加行)

on print .selectAll返回:

Selection {_groups: Array(1), _parents: Array(1), _enter: Array(1), _exit: Array(1)}
_enter:[Array(6)]_exit
:[Array(0)]_groups
:[Array(6)]
_parents:[svg]
__proto__:Object]

这是完整的代码: https://gist.github.com/Casyfill/78069927d2b95bf4856aa8048a4fa4be