代码之家  ›  专栏  ›  技术社区  ›  Matthias Herrmann timelfelt

为转换的每个帧运行自定义计算

  •  1
  • Matthias Herrmann timelfelt  · 技术社区  · 6 年前

    作为 d3.treemap()

    svg 元素有嵌套 groups rect text tspan 这样地:

    <g><rect></rect><text><tspan>Text here</tspan></text></g>
    

    treemap

    const calculateCenterOfTextInRectangle = (tspanNode) => {
    const rectangleNode = tspanNode.parentElement.previousSibling.previousSibling; // tspan is in text element and 2 nodes above is the rectangle
    const centerX = (rectangleNode.getAttribute('width') / 2) - (tspanNode.getComputedTextLength() / 2);
    const centerY = (rectangleNode.getAttribute('height') / 2) + (19 / 2); // 19 is the font-size in pixel
    return {centerX: centerX,
        centerY: centerY}; };
    

    如果 height width 矩形的大小不变。但是用户可以选择不同的选项来更改矩形的大小并触发此操作 d3.transition()

    treemap(root.sum(sum)); // new values
    cell.transition()
        .duration(750)
        .attr('transform', (d) => 'translate(' + d.x0 + ',' + d.y0 + ')')
        .selectAll('rect')
        .attr('width', (d) => d.x1 - d.x0)
        .attr('height', (d) => d.y1 - d.y0);
    

    setInterval(
            () => {
                cell.selectAll('tspan')
                    .attr('x', function() { return calculateCenterOfTextInRectangle(this).centerX; }) // center x and y. Not using Es6 function because of this context which is the tspan element.
                    .attr('y', function() { return calculateCenterOfTextInRectangle(this).centerY; });
            },
            0.1
        );
    

    问题是,当使用 setInterval transition

    1 回复  |  直到 6 年前
        1
  •  2
  •   Gerardo Furtado    6 年前

    calculateCenterOfTextInRectangle

    var svg = d3.select("svg");
    var g = svg.append("g");
    var rect = g.append("rect")
      .attr("stroke", "black")
      .attr("fill", "white")
      .attr("x", 0)
      .attr("y", 0)
      .attr("width", 50)
      .attr("height", 150);
    
    var text = g.append("text")
      .text("foo")
      .attr("x", function() {
        return calculateCenterOfTextInRectangle(this).centerX
      })
      .attr("y", function() {
        return calculateCenterOfTextInRectangle(this).centerY
      });
    
    var gTransition = g.transition()
      .duration(5000);
    
    gTransition.select("rect")
      .attr("width", 150)
      .attr("height", 40);
    
    gTransition.select("text")
      .attr("x", function() {
        console.log(calculateCenterOfTextInRectangle(this).centerX)
        return calculateCenterOfTextInRectangle(this).centerX
      })
      .attr("y", function() {
        console.log(calculateCenterOfTextInRectangle(this).centerY)
        return calculateCenterOfTextInRectangle(this).centerY
      })
    
    function calculateCenterOfTextInRectangle(tspanNode) {
      const rectangleNode = tspanNode.previousSibling;
      const centerX = (rectangleNode.getAttribute('width') / 2) - (tspanNode.getComputedTextLength() / 2);
      const centerY = (rectangleNode.getAttribute('height') / 2) + (19 / 2); // 19 is the font-size in pixel
      return {
        centerX: centerX,
        centerY: centerY
      };
    };
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <svg></svg>

    x y

    tween

    transition.select("text")
        .tween("positioning", function() {
            var self = this;
            var rectangleNode = this.previousSibling;
            return function() {
                d3.select(self)
                    .attr("x", (rectangleNode.getAttribute('width') / 2) - (self.getComputedTextLength() / 2))
                    .attr("y", (rectangleNode.getAttribute('height') / 2) + (19 / 2))
            }
        })
    

    var svg = d3.select("svg");
    var g = svg.append("g");
    var rect = g.append("rect")
      .attr("stroke", "black")
      .attr("fill", "white")
      .attr("x", 0)
      .attr("y", 0)
      .attr("width", 50)
      .attr("height", 150);
    var text = g.append("text")
      .attr("x", function() {
        return calculateCenterOfTextInRectangle(this).centerX
      })
      .attr("y", function() {
        return calculateCenterOfTextInRectangle(this).centerY
      })
      .text("foo");
    
    var gTransition = g.transition()
      .duration(5000);
    
    gTransition.select("rect")
      .attr("width", 150)
      .attr("height", 40);
    
    gTransition.select("text")
      .tween("positioning", function() {
        var self = this;
        var rectangleNode = this.previousSibling;
        return function() {
          d3.select(self)
            .attr("x", (rectangleNode.getAttribute('width') / 2) - (self.getComputedTextLength() / 2))
            .attr("y", (rectangleNode.getAttribute('height') / 2) + (19 / 2))
        }
      })
    
    function calculateCenterOfTextInRectangle(tspanNode) {
      const rectangleNode = tspanNode.previousSibling;
      const centerX = (rectangleNode.getAttribute('width') / 2) - (tspanNode.getComputedTextLength() / 2);
      const centerY = (rectangleNode.getAttribute('height') / 2) + (19 / 2); // 19 is the font-size in pixel
      return {
        centerX: centerX,
        centerY: centerY
      };
    };
    <script src=“https://d3 js.org/d3.v5.min.js”></script>