代码之家  ›  专栏  ›  技术社区  ›  ttmt

更新模式,退出并删除

  •  -1
  • ttmt  · 技术社区  · 6 年前

    我有一个堆垛机 here . 我尝试使用D3更新模式创建一个简单的示例。单击更新按钮从数据中随机选择并更新图形。这种情况正在发生,但它将新图形放在当前图形的顶部,而不是删除当前图形。

    exit() remove() 但显然不正确。

    2 回复  |  直到 6 年前
        1
  •  2
  •   ksav    6 年前

    我认为您最大的问题是在每次更新时都要创建新的scales&axes,而您应该通过scales各自的域将更新的数据输入scales,然后在每个轴上再次调用它们。

    .enter .update . 因此,您还必须定位那些先前存在的条(否则条会彼此重叠)。

    <!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>
    </head>
    
    <body>
      <div class="chart-container"></div>
      <button id="btn">Update</button>
      <script>
        var originalData = [{
            "date": "Jan",
            "value": 1507
          },
          {
            "date": "Feb",
            "value": 1600
          },
          {
            "date": "Mar",
            "value": 1281
          },
          {
            "date": "Apr",
            "value": 1898
          },
          {
            "date": "May",
            "value": 1749
          },
          {
            "date": "June",
            "value": 1270
          },
          {
            "date": "July",
            "value": 1712
          },
          {
            "date": "Aug",
            "value": 1270
          },
          {
            "date": "Sept",
            "value": 1257
          },
          {
            "date": "Oct",
            "value": 1257
          },
          {
            "date": "Nov",
            "value": 1277
          },
          {
            "date": "Dec",
            "value": 1057
          }
        ];
    
        ///////////////////////////// Update function
    
        function randomizeData(data) {
          var rand = Math.floor(Math.random() * data.length) + 2
          var newData = data.slice(0, rand);
          update(newData)
          console.log(newData)
        }
    
        ///////////////////////////// Create SVG
    
        var w = 400;
        var h = 250;
    
        var margin = {
          top: 20,
          bottom: 40,
          left: 40,
          right: 20
        }
    
        var width = w - margin.left - margin.right
        var height = h - margin.top - margin.bottom
    
        var svg = d3.select(".chart-container").append("svg")
          .attr("id", "svg")
          .attr("width", w)
          .attr("height", h)
    
        var chart = svg.append('g')
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
        var x = d3.scaleBand()
          .range([0, width])
          .padding(0.1)
    
    
        var y = d3.scaleLinear()
          .rangeRound([height, 0])
    
    
        var xAxis = chart.append('g')
        var yAxis = chart.append('g')
    
        ///////////////////////////////// Update function
    
        function update(graphData) {
    
          // Recalc domains based on new data
          x.domain(graphData.map(function(d) {
            return d.date
          }));
    
          y.domain([0, d3.max(graphData, function(d) {
            return d.value;
          })]);
    
          // Redraw axes based on new data
          xAxis.call(d3.axisBottom(x)).attr("transform", "translate(0," + height + ")")
          yAxis.call(d3.axisLeft(y))
    
          var u = chart.selectAll(".bar")
            .data(graphData);
    
          // Enter
          u.enter()
            .append("rect")
            .classed('bar', true)
            .attr('x', function(d) {
              return x(d.date)
            })
            .attr("width", x.bandwidth())
            .attr("y", function(d, i) {
              return y(d.value);
            })
            .attr("height", function(d, i) {
              return height - y(d.value);
            });
    
          // Update
          u.attr('x', function(d) {
              return x(d.date)
            })
            .attr("width", x.bandwidth())
            .attr("y", function(d, i) {
              return y(d.value);
            })
            .attr("height", function(d, i) {
              return height - y(d.value);
            });
    
          // Exit
          u.exit()
            .remove();
        }
    
        randomizeData(originalData);
    
        var button = document.getElementById('btn');
        button.addEventListener('click', () => randomizeData(originalData));
      </script>
    </body>
    
    </html>

    stackblitz fork

        2
  •  1
  •   Chandu    6 年前

    只需删除的X,Y比例和轴的更新功能和使用 remove() exit() 更新内部。

    ///////////////////////////// Update function
    
    function doUpdate(gdata){
        var rand = Math.floor(Math.random()*data.length)+2
        var newData = data.slice(0, rand);
         update(newData)
    }
    
    ///////////////////////////// Create SVG
    
    var w = 400;
    var h = 250;
    
    var margin = {
      top: 20,
      bottom: 40,
      left: 40,
      right: 20
    }
    
    var width = w - margin.left - margin.right
    var height = h - margin.top - margin.bottom
    
    var svg = d3.select(".chart-container").append("svg")
      .attr("id", "svg")
      .attr("width", w)
      .attr("height", h)
    
    var chart = svg.append('g')
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
    var x = d3.scaleBand()
      .range([0, width])
      .padding(0.1)
      .domain(data.map(function(d) { 
        return d.date
      }));
    
      var y = d3.scaleLinear()
        .rangeRound([height, 0])
        .domain([0, d3.max(data, function(d) { 
          return d.value; 
        })]);
    
    var xAxis = chart.append('g')
        .classed('x-axis', true)
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(x))
    
      var yAxis = chart.append('g')
        .classed('y-axis', true)
        .call(d3.axisLeft(y))   
    
    ///////////////////////////////// Update function
    
    function update(graphData){
      console.log(graphData,graphData.length)
      var u = chart.selectAll(".bar")
        .remove()
        .exit()
        .data(graphData);
    
        u.enter()
         .append("rect")
         .classed('bar', true)
         .attr('x', function(d){
          return x(d.date)
        })
        .attr("width", x.bandwidth())
        .attr("y", function (d, i) {
          return y(d.value);
        })
        .attr("height", function(d,i){
          return height - y(d.value);
        });
    
    
    
    }    
    var button = document.getElementById('btn');
    button.addEventListener('click', doUpdate);
    doUpdate(data);