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

D3不正确的阻力行为

  •  2
  • ofey  · 技术社区  · 8 年前

    这是我上一个问题的后续部分 d3 rect in one group interfering with rect in another group

    1. 拖动行为不正确。当单击第二个矩形拖动它时,它会跳到第三个矩形所在的位置。

    我知道我应该每个问题只有一个问题,但这些都是相关的,我怀疑他们会一起解决。

    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>
      /*.active {
        stroke: #000;
        stroke-width: 2px;
      }*/
    </style>
    <svg width="960" height="500"></svg>
    <script src="//d3js.org/d3.v4.min.js"></script>
    <script>
      var margin = {
          top: 20,
          right: 20,
          bottom: 20,
          left: 20
        },
        width = 600 - margin.left - margin.right,
        height = 600 - margin.top - margin.bottom;
    
      var svg = d3.select("svg");
    
      var data = [{
        x: 200
      }, {
        x: 300
      }, {
        x: 400
      }];
    
      var groove = svg.append("g")
        .attr("class", "groove_group");
    
      groove.append("rect")
        .attr("x", 100)
        .attr("y", 150)
        .attr("rx", 2)
        .attr("ry", 2)
        .attr("height", 6)
        .attr("width", 800)
        .style("fill", "grey");
    
      groove.append("rect")
        .attr("x", 102)
        .attr("y", 152)
        .attr("rx", 2)
        .attr("ry", 2)
        .attr("height", 2)
        .attr("width", 796)
        .style("fill", "black");
    
      // create group
      var group = svg.selectAll(null)
        .data(data)
        .enter().append("g")
        .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended))
        .on("click", removeElement);
    
      group.append("rect")
        .attr("x", function(d) {
          return d.x;
        })
        .attr("y", 100)
        .attr("height", 100)
        .attr("width", 15)
        .style("fill", "lightblue")
        .attr('id', function(d, i) {
          return 'handle_' + i;
        })
        .attr("rx", 6)
        .attr("ry", 6)
        .attr("stroke-width", 2)
        .attr("stroke", "black");
    
      group.append("text")
        .attr("x", function(d) {
          return d.x
        })
        .attr("y", 100)
        .attr("text-anchor", "start")
        .style("fill", "black")
        .text(function(d) {
          return "x:" + d.x
        });
    
      // create group
      var group = svg.selectAll("g")
        .data(data)
        .enter().append("g")
        .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended))
        .on("click", removeElement);
    
      group.append("rect")
        .attr("x", function(d) {
          return d.x;
        })
        .attr("y", 200)
        .attr("height", 100)
        .attr("width", 15)
        .style("fill", "lightblue")
        .attr('id', function(d, i) {
          return 'handle_' + i;
        })
        .attr("rx", 6)
        .attr("ry", 6)
        .attr("stroke-width", 2)
        .attr("stroke", "black");
    
      group.append("text")
        .attr("x", function(d) {
          return d.x
        })
        .attr("y", 200)
        .attr("text-anchor", "start")
        .style("fill", "black")
        .text(function(d) {
          return "x:" + d.x
        });
    
      svg.on("click", function() {
        var coords = d3.mouse(this);
    
        var newData = {
          x: d3.event.x,
        }
        data.push(newData);
    
        group.selectAll("rect")
          .data(data)
          .enter()
          .append("rect")
          .attr("x", function(d) {
            return d.x;
          })
          .attr("y", 200)
          .attr("height", 100)
          .attr("width", 15)
          .style("fill", "steelblue")
          .attr('id', function(d, i) {
            return 'rect_' + i;
          })
          .attr("rx", 6)
          .attr("ry", 6)
          .attr("stroke-width", 2)
          .attr("stroke", "black");
      });
    
    
      function dragstarted(d) {
        d3.select(this).raise().classed("active", true);
      }
    
      function dragged(d) {
        d3.select(this).select("text")
          .attr("x", d.x = d3.event.x);
        d3.select(this).select("rect")
          .attr("x", d.x = d3.event.x);
      }
    
      function dragended(d) {
        d3.select(this)
          .classed("active", false);
      }
    
      function removeElement(d) {
        d3.event.stopPropagation();
        data = data.filter(function(e) {
          return e != d;
        });
        d3.select(this)
          .remove();
      }
    </script>
    2 回复  |  直到 8 年前
        1
  •  1
  •   Gerardo Furtado    8 年前

    以下是对您的问题的解释:

    1. var groups var组
    2. 在附加新矩形的函数中,使用选择矩形的更新选择。但是,输入选择会附加组( <g> )元素,而不是矩形。

    看看重构函数,它将数据绑定到新创建的组,并将矩形附加到该组:

    var newGroup = svg.selectAll(".group")
        .data(data, function(d) {
            return d.x
        })
        .enter()
        .append("g")
        //etc...
    
    newGroup.append("rect")
        //etc...
    

    此外,在数据绑定中使用键选择,这样您就可以确切地知道要拖动的矩形是什么:

    .data(data, function(d){return d.x})
    

    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>
      /*.active {
        stroke: #000;
        stroke-width: 2px;
      }*/
    </style>
    <svg width="960" height="500"></svg>
    <script src="//d3js.org/d3.v4.min.js"></script>
    <script>
      var margin = {
          top: 20,
          right: 20,
          bottom: 20,
          left: 20
        },
        width = 600 - margin.left - margin.right,
        height = 600 - margin.top - margin.bottom;
    
      var svg = d3.select("svg");
    
      var data = [{
        x: 200
      }, {
        x: 300
      }, {
        x: 400
      }];
    
      var groove = svg.append("g")
        .attr("class", "groove_group");
    
      groove.append("rect")
        .attr("x", 100)
        .attr("y", 150)
        .attr("rx", 2)
        .attr("ry", 2)
        .attr("height", 6)
        .attr("width", 800)
        .style("fill", "grey");
    
      groove.append("rect")
        .attr("x", 102)
        .attr("y", 152)
        .attr("rx", 2)
        .attr("ry", 2)
        .attr("height", 2)
        .attr("width", 796)
        .style("fill", "black");
    
      // create group
      var group = svg.selectAll(null)
        .data(data, function(d){return d.x})
        .enter().append("g")
        .attr("class", "group")
        .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended))
        .on("click", removeElement);
    
      group.append("rect")
        .attr("x", function(d) {
          return d.x;
        })
        .attr("y", 100)
        .attr("height", 100)
        .attr("width", 15)
        .style("fill", "lightblue")
        .attr('id', function(d, i) {
          return 'handle_' + i;
        })
        .attr("rx", 6)
        .attr("ry", 6)
        .attr("stroke-width", 2)
        .attr("stroke", "black");
    
      group.append("text")
        .attr("x", function(d) {
          return d.x
        })
        .attr("y", 100)
        .attr("text-anchor", "start")
        .style("fill", "black")
        .text(function(d) {
          return "x:" + d.x
        });
    
      svg.on("click", function() {
        var coords = d3.mouse(this);
    
        var newData = {
          x: coords[0],
        }
        
        data.push(newData);
    
        var newGroup = svg.selectAll(".group")
          .data(data, function(d){return d.x})
          .enter()
          .append("g")
          .attr("class", "group")
              .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended))
        .on("click", removeElement);
          
          newGroup.append("rect")
          .attr("x", function(d) {
            return d.x;
          })
          .attr("y", 200)
          .attr("height", 100)
          .attr("width", 15)
          .style("fill", "steelblue")
          .attr('id', function(d, i) {
            return 'rect_' + i;
          })
          .attr("rx", 6)
          .attr("ry", 6)
          .attr("stroke-width", 2)
          .attr("stroke", "black");
      });
    
    
      function dragstarted(d) {
        d3.select(this).raise().classed("active", true);
      }
    
      function dragged(d) {
        d3.select(this).select("text")
          .attr("x", d.x = d3.event.x);
        d3.select(this).select("rect")
          .attr("x", d.x = d3.event.x);
      }
    
      function dragended(d) {
        d3.select(this)
          .classed("active", false);
      }
    
      function removeElement(d) {
        d3.event.stopPropagation();
        data = data.filter(function(e) {
          return e != d;
        });
        d3.select(this)
          .remove();
      }
    </script>
        2
  •  1
  •   Mikhail Shabrikov    8 年前

    var margin = {
          top: 20,
          right: 20,
          bottom: 20,
          left: 20
        },
        width = 600 - margin.left - margin.right,
        height = 600 - margin.top - margin.bottom;
    
      var svg = d3.select("svg");
    
      var data = [{
        x: 200
      }, {
        x: 300
      }, {
        x: 400
      }];
    
      var groove = svg.append("g")
        .attr("class", "groove_group");
    
      groove.append("rect")
        .attr("x", 100)
        .attr("y", 150)
        .attr("rx", 2)
        .attr("ry", 2)
        .attr("height", 6)
        .attr("width", 800)
        .style("fill", "grey");
    
      groove.append("rect")
        .attr("x", 102)
        .attr("y", 152)
        .attr("rx", 2)
        .attr("ry", 2)
        .attr("height", 2)
        .attr("width", 796)
        .style("fill", "black");
    
      // create group
      var group = svg.selectAll(null)
        .data(data)
        .enter().append("g")
        .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended))
        .on("click", removeElement);
    
      group.append("rect")
        .attr("x", function(d) {
          return d.x;
        })
        .attr("y", 100)
        .attr("height", 100)
        .attr("width", 15)
        .style("fill", "lightblue")
        .attr('id', function(d, i) {
          return 'handle_' + i;
        })
        .attr("rx", 6)
        .attr("ry", 6)
        .attr("stroke-width", 2)
        .attr("stroke", "black");
    
      group.append("text")
        .attr("x", function(d) {
          return d.x
        })
        .attr("y", 100)
        .attr("text-anchor", "start")
        .style("fill", "black")
        .text(function(d) {
          return "x:" + d.x
        });
    
      svg.on("click", function() {
        var coords = d3.mouse(this);
    
        var newData = {
          x: d3.event.x,
        }
        data.push(newData);
    
        group.selectAll("rect")
          .data(data)
    			.exit()
    			.enter()
          .append("rect")
          .attr("x", function(d) {
            return d.x;
          })
          .attr("y", 200)
          .attr("height", 100)
          .attr("width", 15)
          .style("fill", "steelblue")
          .attr('id', function(d, i) {
            return 'rect_' + i;
          })
          .attr("rx", 6)
          .attr("ry", 6)
          .attr("stroke-width", 2)
          .attr("stroke", "black");
      });
    
    
      function dragstarted(d) {
        d3.select(this).raise().classed("active", true);
      }
    
      function dragged(d) {
        d3.select(this).select("text")
          .attr("x", d.x = d3.event.x);
        d3.select(this).select("rect")
          .attr("x", d.x = d3.event.x);
      }
    
      function dragended(d) {
        d3.select(this)
          .classed("active", false);
      }
    
      function removeElement(d) {
        d3.event.stopPropagation();
        data = data.filter(function(e) {
          return e != d;
        });
        d3.select(this)
          .remove();
      }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.min.js"></script>
    <svg width="960" height="500"></svg>