关于缩放的D3图形问题

D3 graph questions about zoom

我正在旧 angularjs 应用程序上设置冰柱图。我决定尝试 d3 图表并做一些测试...... 所以基本上有两个问题,针对两个不同的代码:

问题一: 最初我用这个例子:https://bl.ocks.org/lorenzopub/c4a226f9c29a20dd0cc152e212a70c9a

我意识到当您放大图表的某些区域时,returns“属性宽度:负值无效。(”-2428.9156626506024")”,即使它进行了缩放不显示文本。 知道为什么会这样吗?

问题二: 后来我尝试制作自己的结构,使用与前面示例相同的 json。主要区别在于我创建了一个 "g" 并在其中放置了 "rec" 和 "foreignObject",以使其在结构方面更有条理。下面的代码

我将以下代码放在 angularjs 指令中。

我正在使用 d3 的 V4 "//d3js.org/d3.v4.min.js"


      var totalSize = 0;
      var width = 960, height = 500;
      var x = d3.scaleLinear().range([0, width]);
      var y = d3.scaleLinear().range([0, height]);
      var color = d3.scaleOrdinal(d3.schemeCategory20c);
      var partition = d3.partition()
        .size([width, height])
        .padding(0)
        .round(true);
      var svg = d3.select("#pleaseWork") //.append("svg")
        .attr("width", width)
        .attr("height", height);
      var groups = svg.selectAll("g");

      d3.json("graphs/dataD3.json", function (error, root) {
        //d3.json("graphs/newData.json", function (error, root) {
        if (error) throw error;
        root = d3.hierarchy(d3.entries(root)[0], function (d) {
            return d3.entries(d.value)
          })
          .sum(function (d) {
            return d.value
          })
          .sort(function (a, b) {
            return b.value - a.value;
          });

        partition(root);
        groups = groups
          .data(root.descendants())
          .enter().append("g")
          .attr("fill", function (d) {
            return color((d.children ? d : d.parent).data.key);
          })
          .on("click", clicked);
        //get total size from rect
        totalSize = groups.node().__data__.value;
        console.log(groups.node().__data__.value);
        groups.append('rect')
          .attr("x", function (d) {
            return d.x0;
          })
          .attr("y", function (d) {
            return d.y0;
          })
          .attr("width", function (d) {
            return d.x1 - d.x0;
          })
          .attr("height", function (d) {
            return d.y1 - d.y0;
          });

        groups.append('foreignObject')
          .text(function (d) {
            //return d.data.key + '-' + d.value;
            return d.data.key + ' - ' + (100 * d.value / totalSize).toPrecision(3) + '%';
          })
          .attr("x", function (d) {
            return d.x0;
          })
          .attr("y", function (d) {
            return d.y0;
          })
          .attr("width", function (d) {
            return d.x1 - d.x0;
          })
          .attr("height", function (d) {
            return d.y1 - d.y0;
          });

      });

      function clicked(d) {
        console.log(d);
        x.domain([d.x0, d.x1]);
        y.domain([d.y0, height]).range([d.depth ? 20 : 0, height]);
        groups.transition()
          .duration(750)
          .attr("x", function (d) {
            return x(d.x0);
          })
          .attr("y", function (d) {
            return y(d.y0);
          })
          .attr("width", function (d) {
            return x(d.x1) - x(d.x0);
          })
          .attr("height", function (d) {
            return y(d.y1) - y(d.y0);
          });
      }
    }




当我单击要缩放的项目时,它会进入函数 "clicked" 但什么也没有发生,我想实现与第一个示例类似的效果,它会缩放到该元素级别。 在此先感谢您的支持

通过将 fo.transition() 中的代码替换为:

解决了第一个问题
.attr("x", function (d) {
        return d.x0;
      })
      .attr("y", function (d) {
        return d.y0;
      })
      .attr("width", function (d) {
        return d.x1 - d.x0;
      })
      .attr("height", function (d) {
        return d.y1 - d.y0;
      })

第二个问题,我是这样解决的:


      var width = 500,
        height = 300;
      var partitionLayout = d3.partition().size([width, height]);

      //needed for zoom ? 
      var x = d3.scaleLinear().range([0, width]);
      var y = d3.scaleLinear().range([0, height]);

      //needed to fill the colour
      var colour = d3.scaleOrdinal(d3.schemeCategory20c);

      d3.json("graphs/newstructure.json", function (data) {
        var rootNode = d3.hierarchy(data);
        rootNode.sum(function (d) {
          return d.value;
        });

        // structure the data for the graph
        partitionLayout(rootNode);

        var group = d3.select('#new')
          .selectAll('g')
          .data(rootNode.descendants())
          .enter()
          .append('g')
          .attr("fill", function (d) {
            return colour(d.data.colour);
          })
          .on("click", clicked);

        group.append('rect')
          .attr('x', function (d) {
            console.log(d);
            return d.x0;
          })
          .attr('y', function (d) {
            return d.y0;
          })
          .attr('width', function (d) {
            return d.x1 - d.x0;
          })
          .attr('height', function (d) {
            return d.y1 - d.y0;
          })
          .attr('fill', function (d) {
            return d.data.colour;
          });

        group
          .append('foreignObject')
          .text(function (d) {
            console.log(d);
            return d.data.name + ' - ' + d.value;
          })
          .attr("x", function (d) {
            return d.x0;
          })
          .attr("y", function (d) {
            return d.y0;
          })
          .attr("width", function (d) {
            return d.x1 - d.x0;
          })
          .attr("height", function (d) {
            return d.y1 - d.y0;
          });

        function clicked(d) {
          x.domain([d.x0, d.x1]);
          y.domain([d.y0, height]).range([d.depth ? 20 : 0, height]);

          group.transition()
            .duration(750)
            .attr("x", function (d) {
              return x(d.x0);
            })
            .attr("y", function (d) {
              return y(d.y0);
            })
            .attr("width", function (d) {
              return x(d.x1) - x(d.x0);
            })
            .attr("height", function (d) {
              return y(d.y1) - y(d.y0);
            });

          var rects = d3.select('#new')
            .selectAll('g rect');

          rects.transition()
            .duration(750)
            .attr("x", function (d) {
              return x(d.x0);
            })
            .attr("y", function (d) {
              return y(d.y0);
            })
            .attr("width", function (d) {
              return x(d.x1) - x(d.x0);
            })
            .attr("height", function (d) {
              return y(d.y1) - y(d.y0);
            });

          var rects = d3.select('#new')
            .selectAll('g foreignObject');

          rects.transition()
            .duration(750)
            .attr("x", function (d) {
              return x(d.x0);
            })
            .attr("y", function (d) {
              return y(d.y0);
            })
            .attr("width", function (d) {
              return x(d.x1) - x(d.x0);
            })
            .attr("height", function (d) {
              return y(d.y1) - y(d.y0);
            });
        }
    });