实时exit()。remove()离开数据对象出口上的节点

时间:2019-04-29 19:44:04

标签: javascript d3.js

我正在使用d3js相对于当前时间从右向左移动圆点。这是我用来过滤当前时间数据的代码。

window.onload = function() {

  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 % 100 === 0) {
      var point = {
        x: globalX,
        y: ((Math.random() * 200 + 50) >> 0)
      };
      data.push(point);
    }
    count++;
    globalX = new Date().getTime();
    var timer = new Date().getTime();
    var symbol = d3.symbol().size([100]),
      color = d3.schemeCategory10;
    data = data.filter(function(d) {
      return d.x > globalX - 10000;
    });
    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();
    // Shift the chart left
    x.domain([timer - 10000, timer]);
    axisX.transition()
      .duration(10)
      .call(xAxis);
    g.attr('transform', null)
      .transition()
      .duration(10)
      .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;
  fill: #d35400;
  font-size: 12px;
}

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

.circle {
  stroke: #e74c3c;
  stroke-width: 3px;
  fill: #FFF;
}
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.js"></script>
<link rel="stylesheet" type="text/css" href="http://bost.ocks.org/mike/style.css?20120427">
<svg id="chart"></svg>

最初的10秒钟后,您会开始看到圆点停留在视图的右侧,而第一个圆点离开了视图。

1 个答案:

答案 0 :(得分:1)

window.onload = function() {

  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 % 100 === 0) {
      var point = {
        x: globalX,
        y: ((Math.random() * 200 + 50) >> 0)
      };
      data.push(point);
    }
    count++;
    globalX = new Date().getTime();
    var timer = new Date().getTime();
    var symbol = d3.symbol().size([100]),
      color = d3.schemeCategory10;
    data = data.filter(function(d) {
      return d.x > globalX - 10000;
    });
    var circles = g.selectAll('path').data(data);
    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.transition()
      .duration(10)
      .call(xAxis);
    g.attr('transform', null)
      .transition()
      .duration(10)
      .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;
  fill: #d35400;
  font-size: 12px;
}

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

.circle {
  stroke: #e74c3c;
  stroke-width: 3px;
  fill: #FFF;
}
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.js"></script>
<link rel="stylesheet" type="text/css" href="http://bost.ocks.org/mike/style.css?20120427">
<svg id="chart"></svg>

您的圈子选择应包含数据绑定。没有初始选择中的数据,d3无法知道退出时要删除的点。

data = data.filter(function(d) {
      return d.x > globalX - 10000;
  });
  var circles = g.selectAll('path').data(data);
  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();