D3更新,输入,退出模式

时间:2018-10-13 01:04:11

标签: d3.js

我是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>

当我运行代码并单击不同的过滤器按钮时。我注意到,每次选择不同的按钮时,都会运行enter选择。据我了解,当数据多于DOM元素时,应执行enter选择。除了一种情况(“刷新”按钮),在所有情况下,DOM中只有一个rect,因此更新选择不适用吗?

例如,单击“猫!”使输入选择符合预期。然后点击“狗!”触发进入和退出选择。由于新过滤的数据只有一个基准并且只有一个矩形,因此我希望触发更新选择。我想念什么?

1 个答案:

答案 0 :(得分:1)

这里有两个问题。

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

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

此处的匿名功能不是必需的,并且会导致异常行为。当我将数据绑定更改为此时...

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

一切正常。

@ rioV8谢谢您的帮助。