d3.js节点没有正确退出 [英] d3.js nodes are not exiting properly

查看:208
本文介绍了d3.js节点没有正确退出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以这里。我花了相当多的时间在这一个 - 而且真的很累 - 所以希望一些愚蠢的事情没有让我失望。

so here goes. I've spent quite some time on this one - and am really tired - so hopefully something silly hasn't eluded me.

我正在使用一个数据集创建一些线条在图表中。之后,使用图例我想隐藏线条同时也改变数据集 - 所以改变不透明度不会削减它。

I am using a dataset to create a few lines in a chart. After that, using a legend I want to hide lines while also changing the dataset - so changing opacity won't cut it.

我按照在数据集中的每个对象添加一个键的路径,并将其设置为false,以便能够过滤隐藏的对象。但是,它无法正常工作,因为我无法正确退出()行。完全删除行并再次绑定数据集可以完成工作,但会将行颜色映射到图例项。

I followed the path of adding a key enabled on each object in my dataset and set it to false in order to be able to filter objects to hide. However, It doesn't work as expected since I cannot exit() the lines properly. Removing the lines completely and binding the dataset again gets the job done but messes with the mapping of the line colors to the legend items.

问题出在 redraw()函数。

希望有人能够整理这个噩梦!

Hopefully someone is able to sort out this nightmare!

https://jsfiddle.net/2en21Lqh/2/

我已经创建了一个小提琴

I have created a fiddle

推荐答案

这是您的代码重构了以下修复:

Here's your code refactored with the following fixes:


  1. 简化初始绘制并重画为单一功能。

  2. 正确处理输入,更新,退出

  3. 引入键功能
  4. a>修复数据绑定(保持数据唯一)
  5. 使用 d.key 代替索引(to修复

  6. 修正了一些一般的代码质量问题(缺少var关键字,筛选选择而不是数据等)

  1. Condensed initial draw and redraw into single function.
  2. Properly handled enter, update, exit pattern in this single function.
  3. Introduced key function to fix data binding (keep it unique to the data).
  4. Use d.key for colors instead of index (to fix the wandering colors).
  5. Fixed some general code quality issues (missing var keywords, filtering on selection instead of data, etc...)

我没有使用透明度切换行,尽管这样也可以。

I did not "toggle" the lines using opacity, although that would work as well.

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
  <script data-require="jquery@3.0.0" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
  <style>
    .line-chart {
      width: 800px;
      height: 200px;
    }
    
    .d3-axis {
      font-family: 'Arial', sans-serif;
      font-size: 10px;
    }
    
    .d3-line {
      fill: none;
      stroke-width: 2px;
    }
    
    .d3-axis path {
      fill: none;
      stroke: #e6e6e6;
      shape-rendering: crispEdges;
      opacity: 0; // remove axes
    }
    
    .d3-axis line {
      fill: none;
      stroke: #eee;
      shape-rendering: crispEdges;
    }
    
    ul li {
      display: inline-block;
      margin-left: 10px;
    }
    
    .color-square {
      display: block;
      float: left;
      margin-right: 3px;
      width: 20px;
      height: 20px;
      border: 1px solid #000;
    }
  </style>
</head>

<body>
  <div class="line-chart"></div>
  <ul class="legend"></ul>
  <script>
    var data = [{
      "name": "line1",
      "date": "2016-10-07T23:59:07Z",
      "value": 67
    }, {
      "name": "line1",
      "date": "2016-10-15T11:35:32Z",
      "value": 57
    }, {
      "name": "line1",
      "date": "2017-02-09T07:13:41Z",
      "value": 11
    }, {
      "name": "line1",
      "date": "2016-11-16T21:18:03Z",
      "value": 12
    }, {
      "name": "line1",
      "date": "2016-05-01T03:08:22Z",
      "value": 71
    }, {
      "name": "line1",
      "date": "2016-10-01T08:15:08Z",
      "value": 64
    }, {
      "name": "line1",
      "date": "2016-07-27T09:58:43Z",
      "value": 25
    }, {
      "name": "line1",
      "date": "2016-04-15T12:20:35Z",
      "value": 15
    }, {
      "name": "line1",
      "date": "2016-11-01T11:51:14Z",
      "value": 69
    }, {
      "name": "line1",
      "date": "2016-10-05T23:27:50Z",
      "value": 12
    }, {
      "name": "line1",
      "date": "2016-11-11T21:53:45Z",
      "value": 87
    }, {
      "name": "line1",
      "date": "2017-01-22T17:22:10Z",
      "value": 10
    }, {
      "name": "line1",
      "date": "2016-07-18T23:33:03Z",
      "value": 27
    }, {
      "name": "line1",
      "date": "2017-01-04T14:35:53Z",
      "value": 6
    }, {
      "name": "line1",
      "date": "2016-11-10T07:17:06Z",
      "value": 91
    }, {
      "name": "line1",
      "date": "2016-04-18T00:40:18Z",
      "value": 56
    }, {
      "name": "line1",
      "date": "2016-06-23T11:27:18Z",
      "value": 22
    }, {
      "name": "line1",
      "date": "2016-08-10T12:53:00Z",
      "value": 18
    }, {
      "name": "line1",
      "date": "2016-09-02T17:24:51Z",
      "value": 89
    }, {
      "name": "line1",
      "date": "2016-06-08T03:09:20Z",
      "value": 27
    }, {
      "name": "line1",
      "date": "2016-10-30T17:54:30Z",
      "value": 38
    }, {
      "name": "line1",
      "date": "2017-01-22T01:56:44Z",
      "value": 99
    }, {
      "name": "line1",
      "date": "2016-06-02T19:58:44Z",
      "value": 48
    }, {
      "name": "line1",
      "date": "2016-07-12T01:04:56Z",
      "value": 68
    }, {
      "name": "line1",
      "date": "2016-09-23T07:30:45Z",
      "value": 11
    }, {
      "name": "line1",
      "date": "2016-11-08T05:18:12Z",
      "value": 29
    }, {
      "name": "line1",
      "date": "2017-01-24T03:46:43Z",
      "value": 19
    }, {
      "name": "line2",
      "date": "2016-04-17T06:36:39Z",
      "value": 44
    }, {
      "name": "line2",
      "date": "2016-03-27T17:40:29Z",
      "value": 29
    }, {
      "name": "line2",
      "date": "2016-09-13T02:11:44Z",
      "value": 55
    }, {
      "name": "line2",
      "date": "2016-12-24T10:47:49Z",
      "value": 54
    }, {
      "name": "line2",
      "date": "2016-11-12T21:17:27Z",
      "value": 74
    }, {
      "name": "line2",
      "date": "2016-07-17T10:18:03Z",
      "value": 55
    }, {
      "name": "line2",
      "date": "2016-10-15T10:46:42Z",
      "value": 24
    }, {
      "name": "line2",
      "date": "2016-08-25T12:10:23Z",
      "value": 63
    }, {
      "name": "line2",
      "date": "2017-01-22T18:08:27Z",
      "value": 88
    }, {
      "name": "line2",
      "date": "2016-05-04T09:47:14Z",
      "value": 44
    }, {
      "name": "line2",
      "date": "2016-10-19T18:45:20Z",
      "value": 74
    }, {
      "name": "line2",
      "date": "2017-01-16T19:03:01Z",
      "value": 46
    }, {
      "name": "line2",
      "date": "2017-01-03T18:05:28Z",
      "value": 32
    }, {
      "name": "line2",
      "date": "2016-09-22T14:32:07Z",
      "value": 93
    }, {
      "name": "line2",
      "date": "2016-08-26T16:07:09Z",
      "value": 22
    }, {
      "name": "line2",
      "date": "2016-08-12T07:03:45Z",
      "value": 52
    }, {
      "name": "line2",
      "date": "2016-10-09T11:12:56Z",
      "value": 52
    }, {
      "name": "line2",
      "date": "2016-10-11T00:13:01Z",
      "value": 39
    }, {
      "name": "line2",
      "date": "2016-10-23T16:35:20Z",
      "value": 58
    }, {
      "name": "line2",
      "date": "2016-07-06T05:18:24Z",
      "value": 95
    }, {
      "name": "line2",
      "date": "2017-02-03T08:49:39Z",
      "value": 51
    }, {
      "name": "line2",
      "date": "2016-07-21T00:03:27Z",
      "value": 100
    }, {
      "name": "line2",
      "date": "2016-08-27T07:23:05Z",
      "value": 71
    }, {
      "name": "line3",
      "date": "2016-11-11T21:53:45Z",
      "value": 87
    }, {
      "name": "line3",
      "date": "2017-01-22T17:22:10Z",
      "value": 220
    }, {
      "name": "line3",
      "date": "2016-07-18T23:33:03Z",
      "value": 24
    }, {
      "name": "line3",
      "date": "2017-01-04T14:35:53Z",
      "value": 65
    }, {
      "name": "line3",
      "date": "2016-11-10T07:17:06Z",
      "value": 9
    }, {
      "name": "line3",
      "date": "2016-04-18T00:40:18Z",
      "value": 54
    }, {
      "name": "line3",
      "date": "2016-06-23T11:27:18Z",
      "value": 72
    }, {
      "name": "line3",
      "date": "2016-08-10T12:53:00Z",
      "value": 88
    }, {
      "name": "line3",
      "date": "2016-09-02T17:24:51Z",
      "value": 89
    }, {
      "name": "line3",
      "date": "2016-06-08T03:09:20Z",
      "value": 27
    }, {
      "name": "line3",
      "date": "2016-10-30T17:54:30Z",
      "value": 38
    }, {
      "name": "line3",
      "date": "2017-01-22T01:56:44Z",
      "value": 99
    }, {
      "name": "line3",
      "date": "2016-06-02T19:58:44Z",
      "value": 48
    }, {
      "name": "line3",
      "date": "2016-07-12T01:04:56Z",
      "value": 68
    }, {
      "name": "line3",
      "date": "2016-09-23T07:30:45Z",
      "value": 51
    }, {
      "name": "line3",
      "date": "2016-11-08T05:18:12Z",
      "value": 49
    }, {
      "name": "line3",
      "date": "2017-01-24T03:46:43Z",
      "value": 89
    }, {
      "name": "line3",
      "date": "2016-04-17T06:36:39Z",
      "value": 54
    }, {
      "name": "line3",
      "date": "2016-03-27T17:40:29Z",
      "value": 27
    }, {
      "name": "line3",
      "date": "2016-09-13T02:11:44Z",
      "value": 58
    }, {
      "name": "line3",
      "date": "2016-12-24T10:47:49Z",
      "value": 24
    }, {
      "name": "line3",
      "date": "2016-11-12T21:17:27Z",
      "value": 54
    }, {
      "name": "line3",
      "date": "2016-07-17T10:18:03Z",
      "value": 55
    }, {
      "name": "line3",
      "date": "2016-10-15T10:46:42Z",
      "value": 24
    }, {
      "name": "line3",
      "date": "2016-08-25T12:10:23Z",
      "value": 63
    }]

    margin = {
      top: 20,
      right: 20,
      bottom: 20,
      left: 30
    };

    var containerwidth = $('.line-chart').width(),
        containerheight = $('.line-chart').height();


    var width = containerwidth - margin.left - margin.right,
       height = containerheight - margin.top - margin.bottom;

    var parseTime = d3.timeParse("%Y-%m-%dT%H:%M:%SZ")

    data.forEach(function(d) {
      d.date = parseTime(d.date);
      d.value = +d.value;
    });

    function sortByDateAscending(a, b) {
      return a.date - b.date;
    }
    dataset = data.sort(sortByDateAscending);

    var dataGroup = d3.nest()
      .key(function(d) {
        return d.name;
      })
      .entries(data);

    dataGroup.forEach(function(d) {
      d.enabled = true;
    });
    
    var svg = d3.select('.line-chart')
      .append('svg')
      .attr('width', containerwidth)
      .attr('height', containerheight)
      .append('g')
      .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

    var x = d3.scaleTime().range([0, width]),
        y = d3.scaleLinear().range([height, 0]);

    var colorScale = d3.scaleOrdinal(d3.schemeCategory10);

    var xAxis = d3.axisBottom(x).ticks(20).tickSizeInner(2).tickSizeOuter(0);
    var yAxis = d3.axisLeft(y).ticks(5).tickSizeInner(-width).tickSizeOuter(0);
    var xAxisGroup = svg.append('g').attr('class', 'x d3-axis').attr('transform', 'translate(0,' + height + ')');
    var yAxisGroup = svg.append('g').attr('class', 'y d3-axis').attr('transform', 'translate(0,0)');

    var line = d3.line()
      .x(function(d) {
        return x(d.date);
      }).y(function(d) {
        return y(d.value);
      });

    var legendItem = d3.select(".legend")
      .selectAll("li")
      .data(dataGroup)
      .enter()
      .append("li")
      .on('click', function(d) {
        d.enabled = !d.enabled;
        redraw();
      });

    legendItem
      .append("span")
      .attr("class", "color-square")
      .style("background", function(d, i) {
        return colorScale(d.key);
      });

    legendItem
      .append("span")
      .text(function(d) {
        return (d.values[0].name)
      });

    redraw();

    function redraw() {

      var fData = dataGroup.filter(function(d) {
        return d.enabled;
      });
      
      y.domain([
        d3.min(fData, function(c) {
          return d3.min(c.values, function(d) {
            return d.value;
          });
        }),
        d3.max(fData, function(c) {
          return d3.max(c.values, function(d) {
            return d.value;
          });
        })
      ]);
      
      x.domain([
        d3.min(fData, function(c) {
          return d3.min(c.values, function(d) {
            return d.date;
          });
        }),
        d3.max(fData, function(c) {
          return d3.max(c.values, function(d) {
            return d.date;
          });
        })
      ]);
      
      xAxisGroup.call(xAxis);
      yAxisGroup.call(yAxis);

      // update selection
      lines = svg.selectAll(".d3-group")
        .data(fData, function(d) {
          return d.key
        });

      // exit the whole group
      lines
        .exit().remove();

      // enter selection
      linesEnter = lines
        .enter()
        .append("g")
        .attr("class", "d3-group");
        
      // add path on enter
      linesEnter.append("path")
        .attr("class", "d3-line");
        
      // add text on enter
      linesEnter.append("text")
        .attr("class", "my-label")
        .attr("x", function(d,i){
          return i * 100;
        })
        .attr("y", 10);
        
      // update + enter
      lines = lines.merge(linesEnter);
      
      // adjust label
      lines.select(".my-label")
        .text(function(d,i){
          return "hi Mom " + d.key;
        });

      // adjust path
      lines.select(".d3-line")
        .attr('d', function(d) {
          return line(d.values);
        })
        .style("stroke", function(d, i) {
          return colorScale(d.key);
        });

    }
  </script>
</body>

</html>

这篇关于d3.js节点没有正确退出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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