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

d3不向绑定的矩形显示初始数据

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

    render() 调用,它应首先显示绑定到此数据的矩形。但我没有看到任何矩形。

    然后,如果单击这些矩形中的任何一个,则函数 removeElement 调用,它从数组中删除该矩形的数据,然后调用 render() 并使用新数据执行。

    如果在任何地方单击svg,则会向数据中添加一个新的数据元素,并再次调用render,它会根据新数据再次显示矩形。

    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>
      /*.active {
        stroke: #000;
        stroke-width: 2px;
      }*/
    
      svg {
        border: 1px solid black;
      }
    </style>
    <svg width="800" height="300"></svg>
    <script src="//d3js.org/d3.v4.min.js"></script>
    <script>
      var margin = {
          top: 20,
          right: 20,
          bottom: 20,
          left: 20
        },
        width = 840 - margin.left - margin.right,
        height = 640 - margin.top - margin.bottom;
    
      var svg = d3.select("svg");
    
      var data = [{
        x: 100
      }, {
        x: 300
      }, {
        x: 400
      }, {
        x: 600
      }];
    
      var ind = 0;
      var groove = svg.append("g")
        .attr("class", "groove_group");
    
      groove.append("rect")
        .attr("x", 0)
        .attr("y", 150)
        .attr("rx", 2)
        .attr("ry", 2)
        .attr("height", 6)
        .attr("width", width)
        .style("fill", "grey");
    
      groove.append("rect")
        .attr("x", 2)
        .attr("y", 152)
        .attr("rx", 2)
        .attr("ry", 2)
        .attr("height", 2)
        .attr("width", 796)
        .style("fill", "black");
    
      render();
    
      function render() {
        // create group
        var group = svg.selectAll(null)
          .data(data, function(d) {
            return d.x
          });
    
        group.exit().remove();
    
        group.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, i) {
            if (i == 0) { // first element
              return ((data[i].x / 2));
            } else {
              return (data[i].x - (data[i].x - data[i - 1].x) / 2);
            }
          })
          .attr("y", 100)
          .attr("text-anchor", "middle")
          .style("fill", "black")
          .attr('id', function(d, i) {
            return 'text_' + i;
          })
          .text(function(d, i) {
            if (i == 0) { // first set
              return i + ": " + (data[i].x) + "m";
            } else {
              return i + ": " + ((data[i].x - data[i - 1].x)) + "m";
            }
          });
        
      }
      svg.on("click", function() {
        var coords = d3.mouse(this);
    
        getPosition(ind, coords[0]);
    
        render();
    
      });
    
      function dragstarted(d) {
        d3.select(this).raise().classed("active", true);
      }
    
      function dragged(d, i) {
        if (i == 0) {
          d3.select("#text_" + i)
            .attr("x", d.x = (d3.event.x / 2))
            .text(function(d) {
              return i + " " + d3.event.x
            });
          d3.select("#text_" + (i + 1))
            .attr("x", d.x = d3.event.x + ((data[i + 1].x - d3.event.x) / 2))
            .text(function(d) {
              return (i + 1) + " " + (data[i + 1].x - d3.event.x) + "m"
            });
          d3.select(this).select("rect")
            .attr("x", d.x = d3.event.x);
        } else if (i == data.length - 1) {
          d3.select("#text_" + i)
            .attr("x", d.x = (d3.event.x - data[i - 1].x) / 2 + data[i - 1].x)
            .text(function(d) {
              return i + ": " + (d3.event.x - data[i - 1].x) + "m"
            });
          d3.select("#text_" + (i + 1))
            .attr("x", d.x = d3.event.x + (width - d3.event.x) / 2)
            .text(function(d) {
              return (i + 1) + ": " + (width - d3.event.x) + "m"
            });
          d3.select(this).select("rect")
            .attr("x", d.x = d3.event.x);
        } else {
          d3.select("#text_" + i)
            .attr("x", d.x = d3.event.x - ((d3.event.x - data[i - 1].x) / 2))
            .text(function(d) {
              return i + ": " + (d3.event.x - data[i - 1].x) + "m"
            });
          d3.select("#text_" + (i + 1))
            .attr("x", d.x = d3.event.x + ((data[i + 1].x - d3.event.x) / 2))
            .text(function(d) {
              return (i + 1) + ": " + (data[i + 1].x - d3.event.x) + "m"
            });
          d3.select(this).select("rect")
            .attr("x", d.x = d3.event.x);
        }
      }
    
      function dragended(d) {
        d3.select(this)
          .classed("active", false);
      }
    
      function removeElement(d, i) {
        d3.event.stopPropagation();
       
        data = data.filter(function(e) {
          return e != d;
        });
        d3.select(this)
          .remove();
    
        render();
       
      }
    
      function getPosition(ind, coords) {
        if (coords[0] > data[ind].x) {
          getPosition(++ind);
        } else {
          data.splice(1, 0, {
            x: coords
          });
        }
      }
    </script>

    任何帮助都将不胜感激,

    1 回复  |  直到 8 年前
        1
  •  1
  •   Gerardo Furtado    8 年前

    如果你看 group

    var group = svg.selectAll(null)
        .data(data, function(d) {
            return d.x
        });
    

    ... 您将看到它只是一个“更新”选择。有 SVG <g> 元素添加到此处。因此,这。。。

    group.append("rect")
        //etc...
    

    没有效果。

    解决方案 :使用 merge() 功能或正确的输入选择:

    var groupEnter = group.enter()
        .append("g")
        .attr("class", "group");
    
    groupEnter.append("rect")
        //etc...
    

    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>
      /*.active {
        stroke: #000;
        stroke-width: 2px;
      }*/
    
      svg {
        border: 1px solid black;
      }
    </style>
    <svg width="800" height="300"></svg>
    <script src="//d3js.org/d3.v4.min.js"></script>
    <script>
      var margin = {
          top: 20,
          right: 20,
          bottom: 20,
          left: 20
        },
        width = 840 - margin.left - margin.right,
        height = 640 - margin.top - margin.bottom;
    
      var svg = d3.select("svg");
    
      var data = [{
        x: 100
      }, {
        x: 300
      }, {
        x: 400
      }, {
        x: 600
      }];
    
      var ind = 0;
      var groove = svg.append("g")
        .attr("class", "groove_group");
    
      groove.append("rect")
        .attr("x", 0)
        .attr("y", 150)
        .attr("rx", 2)
        .attr("ry", 2)
        .attr("height", 6)
        .attr("width", width)
        .style("fill", "grey");
    
      groove.append("rect")
        .attr("x", 2)
        .attr("y", 152)
        .attr("rx", 2)
        .attr("ry", 2)
        .attr("height", 2)
        .attr("width", 796)
        .style("fill", "black");
    
      render();
    
      function render() {
        // create group
        var group = svg.selectAll(null)
          .data(data, function(d) {
            return d.x
          });
    
        group.exit().remove();
    
        var groupEnter = group.enter().append("g")
          .attr("class", "group");
          
        groupEnter.call(d3.drag()
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended))
          .on("click", removeElement);
    
        groupEnter.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");
    
        groupEnter.append("text")
          .attr("x", function(d, i) {
            if (i == 0) { // first element
              return ((data[i].x / 2));
            } else {
              return (data[i].x - (data[i].x - data[i - 1].x) / 2);
            }
          })
          .attr("y", 100)
          .attr("text-anchor", "middle")
          .style("fill", "black")
          .attr('id', function(d, i) {
            return 'text_' + i;
          })
          .text(function(d, i) {
            if (i == 0) { // first set
              return i + ": " + (data[i].x) + "m";
            } else {
              return i + ": " + ((data[i].x - data[i - 1].x)) + "m";
            }
          });
        
      }
      svg.on("click", function() {
        var coords = d3.mouse(this);
    
        getPosition(ind, coords[0]);
    
        render();
    
      });
    
      function dragstarted(d) {
        d3.select(this).raise().classed("active", true);
      }
    
      function dragged(d, i) {
        if (i == 0) {
          d3.select("#text_" + i)
            .attr("x", d.x = (d3.event.x / 2))
            .text(function(d) {
              return i + " " + d3.event.x
            });
          d3.select("#text_" + (i + 1))
            .attr("x", d.x = d3.event.x + ((data[i + 1].x - d3.event.x) / 2))
            .text(function(d) {
              return (i + 1) + " " + (data[i + 1].x - d3.event.x) + "m"
            });
          d3.select(this).select("rect")
            .attr("x", d.x = d3.event.x);
        } else if (i == data.length - 1) {
          d3.select("#text_" + i)
            .attr("x", d.x = (d3.event.x - data[i - 1].x) / 2 + data[i - 1].x)
            .text(function(d) {
              return i + ": " + (d3.event.x - data[i - 1].x) + "m"
            });
          d3.select("#text_" + (i + 1))
            .attr("x", d.x = d3.event.x + (width - d3.event.x) / 2)
            .text(function(d) {
              return (i + 1) + ": " + (width - d3.event.x) + "m"
            });
          d3.select(this).select("rect")
            .attr("x", d.x = d3.event.x);
        } else {
          d3.select("#text_" + i)
            .attr("x", d.x = d3.event.x - ((d3.event.x - data[i - 1].x) / 2))
            .text(function(d) {
              return i + ": " + (d3.event.x - data[i - 1].x) + "m"
            });
          d3.select("#text_" + (i + 1))
            .attr("x", d.x = d3.event.x + ((data[i + 1].x - d3.event.x) / 2))
            .text(function(d) {
              return (i + 1) + ": " + (data[i + 1].x - d3.event.x) + "m"
            });
          d3.select(this).select("rect")
            .attr("x", d.x = d3.event.x);
        }
      }
    
      function dragended(d) {
        d3.select(this)
          .classed("active", false);
      }
    
      function removeElement(d, i) {
        d3.event.stopPropagation();
       
        data = data.filter(function(e) {
          return e != d;
        });
        d3.select(this)
          .remove();
    
        render();
       
      }
    
      function getPosition(ind, coords) {
        if (coords[0] > data[ind].x) {
          getPosition(++ind);
        } else {
          data.splice(1, 0, {
            x: coords
          });
        }
      }
    </script>

    PS:你的代码仍然有很多问题(我可以在这里预见未来的问题)。。。这个答案很有说服力 只有 关于“回车”选择的主要问题。

    推荐文章