当退出视图时,exit().remove()不会删除节点 [英] exit().remove() doesn't remove node when it goes out of view

查看:109
本文介绍了当退出视图时,exit().remove()不会删除节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用d3js相对于当前时间从右向左移动圆点.我有几个问题: 1. .exit().remove()不起作用.节点一旦离开视图,就不会被删除. 2.圈子的过渡有点跳跃

I'm using d3js to move circular dots from right to left with respect to current time. I have a couple of issues: 1. .exit().remove() don't work. Node doesn't get removed once it goes out of the view. 2. Transition of circles are a bit jumpy

var circles = g.selectAll('path')
  circles.data(data)
    .enter()
    .append('path')
    .attr("d", symbol.type(d3.symbolCircle))
    .merge(circles)
    .attr("transform", (d) => "translate(" + x(d.x) + "," + y(d.y) + ")");   
  circles.exit().remove();

您可以在此处查看我的完整代码: http://jsfiddle.net/hsdhott/3tdhuLgm/

You can see my full code here: http://jsfiddle.net/hsdhott/3tdhuLgm/

推荐答案

除了您的enter-exit-update模式不正确之外(请检查下面的代码段),这里最大的问题是数据:

Besides your enter-exit-update pattern not being correct (please check the snippet bellow), the big problem here is the data:

selection.exit()方法不会神奇地选择—通常用于以后使用remove()—基于任意条件的元素,例如退出视图" .它仅基于数据.问题是您的数据永远不会停止增长:

selection.exit() method won't magically select — normally for using remove() later — an element based on any arbitrary criterion, such as "getting out of the view". It's based on the data only. And the problem is that your data never stops increasing:

if (count % 10 === 0) {
    var point = {
        x: globalX,
        y: ((Math.random() * 200 + 50) >> 0)
    };
    data.push(point);
}  

因此,在这种情况下,一种非常快速的解决方案是根据您的x域删除数据点:

So, a very quick solution in this case is removing the data points based on your x domain:

data = data.filter(function(d) {
    return d.x > globalX - 10000;
});

这只是一个建议,请使用所需的逻辑从数据数组中删除对象.但是,无论使用哪种逻辑,都必须删除它们.

This is just a suggestion, use the logic you want for removing the objects from the data array. However, regardless the logic you use, you have to remove them.

关于跳跃式过渡,问题在于您正在使用selection.transitionsetInterval.那行不通,选择其中之一.

Regarding the jumpy transition, the problem is that you're using selection.transition and setInterval. That won't work, chose one of them.

这是您更新的代码:

var data = [];
var width = 500;
var height = 350;
var globalX = new Date().getTime();
/* var globalX = 0; */
var duration = 250;
var step = 10;
var count = 0;
var chart = d3.select('#chart')
  .attr('width', width + 50)
  .attr('height', height + 50);
var x = d3.scaleTime()
  .domain([globalX, (globalX - 10000)])
  .range([0, width]);
var y = d3.scaleLinear()
  .domain([0, 300])
  .range([300, 0]);
// -----------------------------------
// Draw the axis
var xAxis = d3.axisBottom()
  .scale(x)
  .ticks(10)
  .tickFormat(formatter);
var axisX = chart.append('g')
  .attr('class', 'x axis')
  .attr('transform', 'translate(0, 300)')
  .call(xAxis);
// Append the holder for line chart and circles
var g = chart.append('g');

function formatter(time) {
  if ((time.getSeconds() % 5) != 0) {
    return "";
  }
  return d3.timeFormat('%H:%M:%S')(time);
}

function createData() {
  // Generate new data
  var point = {
    x: globalX,
    y: ((Math.random() * 200 + 50) >> 0)
  };
  data.push(point);
}

function callInterval() {
  count++;
  if (count % 3 === 0) createData();
}
// Main loop
function tick() {
  // Generate new data
  if (count % 10 === 0) {
    var point = {
      x: globalX,
      y: ((Math.random() * 200 + 50) >> 0)
    };
    data.push(point);
  }
  data = data.filter(function(d) {
    return d.x > globalX - 10000;
  });
  count++;
  globalX = new Date().getTime();
  var timer = new Date().getTime();
  var symbol = d3.symbol().size([100]),
    color = d3.schemeCategory10;
  var circles = g.selectAll('path')
    .data(data);
  circles = circles.enter()
    .append('path')
    .attr("d", symbol.type(d3.symbolCircle))
    .merge(circles)
    .attr("transform", (d) => "translate(" + x(d.x) + "," + y(d.y) + ")");
  circles.exit().remove();
  // Shift the chart left
  x.domain([timer - 10000, timer]);
  axisX.call(xAxis);
  g.attr('transform', null)
    .attr('transform', 'translate(' + x(globalX - 10000) + ')');
  // Remote old data (max 50 points)
  if (data.length && (data[data.length - 1].x < (globalX - 10000))) data.shift();
}
tick();
setInterval(tick, 10);

.axis {
  font-family: sans-serif;
  font-size: 12px;
}

.line {
  fill: none;
  stroke: #f1c40f;
  stroke-width: 3px;
}

.circle {
  stroke: #e74c3c;
  stroke-width: 3px;
  fill: #FFF;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<svg id="chart"></svg>

这篇关于当退出视图时,exit().remove()不会删除节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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