使用 d3js 从画笔缩放恢复到原始图形

Revert back to original graph from brush zoom using d3js

我正在使用 d3js 制作一个简单的图表来合并实时数据。在我下面的代码中,我使用模拟数据来呈现图形,因此我可以使用不同的功能来操作图形。我正在使用画笔缩放功能,并且该功能正在运行,但我无法使用外部重置按钮将图形恢复到原始状态。当我按下重置按钮时,会呈现原始图形,但也会显示缩放部分。请帮忙,因为我是 d3js 的新手。

var heartData = [{
  time: 0,
  pulse: 50
},{
  time: 1,
  pulse: 100
},{
  time: 2,
  pulse: 0
},{
  time: 3,
  pulse: -100
},{
  time: 4,
  pulse: -25
},{
  time: 5,
  pulse: 25
},{
  time: 6,
  pulse: 0
},{
  time: 7,
  pulse: 100
},{
  time: 8,
  pulse: -50
},{
  time: 9,
  pulse: 25
},{
  time: 10,
  pulse: -25
}];

var w = 600;
var h = 400;

var svg = d3.select('svg').attr("width", w).attr('height', h);

var x = d3.scale.linear()
  .domain([0, 10])
  .range([0, w]);

var y = d3.scale.linear()
  .domain([-150, 150])
  .range([0, h]);

var line = d3.svg.line()
    .x(function(d) { return x(d.time); })
    .y(function(d) { return y(d.pulse); });

svg.append("path")
      .attr("class", "line")
      .style('stroke', 'black')
      .style('stroke-width', '1')
      .style('fill', 'none')
      .datum(heartData)
      .attr("d", line);



// Draw transparent rectangle and zoom on mouseup
var brush = d3.svg.brush()
    .x(x)
    .y(y)
    .on("brushend", function() {
      console.log('brush', brush.extent());
      var extent = brush.extent();
      y.domain([extent[0][1], extent[1][1]]);
      x.domain([extent[0][0], extent[1][0]]);
      svg.select('.line').attr("d", line);
      brush.clear();
      svg.select('.brush').call(brush);
    });

svg.append("g")
  .attr('class','brush')
  .call(brush)
  .selectAll("rect")
  .style('fill-opacity', 0.5)
  .style('fill', 'red');

//Reset to original graph from Zoomed view

function reset (x, y, line){
  x = d3.scale.linear()
  .domain([0, 10])
  .range([0, w]);

  y = d3.scale.linear()
    .domain([-150, 150])
    .range([0, h]);

  line = d3.svg.line()
      .x(function(d) { return x(d.time); })
      .y(function(d) { return y(d.pulse); });

  svg.append("path")
        .attr("class", "line")
        .style('stroke', 'black')
        .style('stroke-width', '1')
        .style('fill', 'none')
        .datum(heartData)
        .attr("d", line);
  }

var d3Brush = this.brush;

function clearBrush(g){
  d3.selectAll("g.brush").call(this.brush.clear());
}


$(document).on('click','#resetbtn', function(e){


    e.preventDefault();

     reset();
     clearBrush();
});

您的重置功能正在重新初始化并重新绘制整个图表。您不需要做所有这些;您只需要 "unzoom" 然后重新画线:

function reset() {

  x.domain([0, 10]); // reset x domain

  y.domain([-150, 150]);  // reset y domain

  d3.select('.line')
    .attr("d", line); // redraw line
}

这是完整的工作代码:

<!DOCTYPE html>
<html>

  <head>
    <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
  </head>

  <body>
    <button id="resetbtn">Reset</button>
    <svg width="500" height="500"></svg>
    <script>
    var heartData = [{
      time: 0,
      pulse: 50
    }, {
      time: 1,
      pulse: 100
    }, {
      time: 2,
      pulse: 0
    }, {
      time: 3,
      pulse: -100
    }, {
      time: 4,
      pulse: -25
    }, {
      time: 5,
      pulse: 25
    }, {
      time: 6,
      pulse: 0
    }, {
      time: 7,
      pulse: 100
    }, {
      time: 8,
      pulse: -50
    }, {
      time: 9,
      pulse: 25
    }, {
      time: 10,
      pulse: -25
    }];

    var w = 600;
    var h = 400;

    var svg = d3.select('svg').attr("width", w).attr('height', h);

    var x = d3.scale.linear()
      .domain([0, 10])
      .range([0, w]);

    var y = d3.scale.linear()
      .domain([-150, 150])
      .range([0, h]);

    var line = d3.svg.line()
      .x(function(d) {
        return x(d.time);
      })
      .y(function(d) {
        return y(d.pulse);
      });

    svg.append("path")
      .attr("class", "line")
      .style('stroke', 'black')
      .style('stroke-width', '1')
      .style('fill', 'none')
      .datum(heartData)
      .attr("d", line);

    // Draw transparent rectangle and zoom on mouseup
    var brush = d3.svg.brush()
      .x(x)
      .y(y)
      .on("brushend", function() {
        console.log('brush', brush.extent());
        var extent = brush.extent();
        y.domain([extent[0][1], extent[1][1]]);
        x.domain([extent[0][0], extent[1][0]]);
        svg.select('.line').attr("d", line);
        brush.clear();
        svg.select('.brush').call(brush);
      });

    svg.append("g")
      .attr('class', 'brush')
      .call(brush)
      .selectAll("rect")
      .style('fill-opacity', 0.5)
      .style('fill', 'red');

    //Reset to original graph from Zoomed view

    function reset() {
      x.domain([0, 10]);

      y.domain([-150, 150]);

      d3.select('.line')
        .attr("d", line);
    }

    var d3Brush = this.brush;

    function clearBrush(g) {
      d3.selectAll("g.brush").call(this.brush.clear());
    }


    d3.select('#resetbtn').on('click', function(e) {


      d3.event.preventDefault();

      reset();
      clearBrush();
    });
  
  </script>
  </body>

</html>