首页 > 解决方案 > D3 更新、进入、退出模式

问题描述

我是 D3 的新手,但是一直在练习它。我遇到了更新、进入和退出模式的问题。这是我一直在测试的一些代码。

function myFunction(myData){
    let width = 10;
    let height = 10;

    console.log('Update: ',m.selectAll('rect')
    .data(myData, d => d.Value).size());

    d3.select('g').selectAll('rect')
        .data(myData, d=> d.Value)
        .attr('width', d => d.Value);

    console.log('Enter: ' + m.selectAll('rect')
        .data(myData, d => d.Value)
        .enter()
        .size()
    );
    d3.select('g').selectAll('rect')
        .data(myData, d => d.Value)
        .enter()
            .append('rect')
                .attr('width',function(d){return d.Value;})
                .attr('height', height)
                .attr('y', (d,i) => i * 50);
    console.log('Exit: ' + d3.select('g').selectAll('rect')
        .data(myData, d => d.Value)
            .exit().size());

    d3.select('g').selectAll('rect')
        .data(myData, d => d.Value)
            .exit().remove();
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>My Chart</title>
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <script src="superChart.js"></script>
</head>
<body>
    <div style="padding: 10px;">
    <button onclick="myFunction(myData)">Refresh!</button>
    <button onclick="myFunction(myData.filter(d => d.Title == 'Cat'))">Cat!</button>
    <button onclick="myFunction(myData.filter(d => d.Title == 'Dog'))">Dog!</button>
    <button onclick="myFunction(myData.filter(d => d.Title == 'Rat'))">Rat!</button>
    <button onclick="myFunction(myData.filter(d => d.Title == 'Bat'))">Bat!</button>
    <button onclick="myFunction(myData.filter(d => d.Title == 'Gnat'))">Gnat!</button>
    <button onclick="myFunction(myData.filter(d => d.Title == 'Mat'))">Mat!</button>
</div>
<div class="visual"></div>


    <script>
        var myData = [
            {Title:'Cat',Value:56},
            {Title:'Dog',Value:78},
            {Title:'Rat',Value:45},
            {Title:'Bat',Value:30},
            {Title:'Gnat',Value:19},
            {Title:'Mat',Value:37}

        ]
        var m = d3.select('.visual')
        .append('svg')
            .attr('width','700')
            .attr('height','400')
            .append('g');
        
    </script>
</body>
</html>

当我运行代码并单击不同的过滤器按钮时。我注意到每次选择不同的按钮时都会运行输入选择。据我了解,当数据多于 DOM 元素时,输入选择应该运行。除了一种情况(刷新按钮)之外,DOM 中只有一个矩形,所以不应该应用更新选择吗?

例如,单击“猫!” 导致按预期输入选择。然后点击“狗!” 触发进入和退出选择。由于新过滤的数据只有一个数据并且只有一个矩形,我希望会触发更新选择。我错过了什么?

标签: d3.js

解决方案


这里有两个问题。

  1. 感谢 rioV8 指出我不应该多次绑定数据,因为它会影响后续的数据绑定。
  2. 我绑定数据的方式。例如,下面是我绑定数据的方式。

d3.select('g').selectAll('rect') .data(myData, d => d.Value);

这里的匿名函数不是必需的,并且会导致奇怪的行为。当我将数据绑定更改为此...

d3.select('g').selectAll('rect')
    .data(myData);

一切都按预期工作。

@rioV8 感谢您的帮助。


推荐阅读