【问题标题】:centering the svg component after the zoom function in d3js在 d3js 中的缩放功能之后居中 svg 组件
【发布时间】:2016-12-25 01:46:01
【问题描述】:

我用d3js建树,因为树很大,而我的容器很小,所以div在页面加载时无法显示svg组件,像这样 image on load

为了显示树,我必须放大并拖动 svg 组件, 像这样 zoomed image

当页面加载时,有什么方法可以让 svg 组件在 svg 中居中?

这是我的代码

<style>

        .node circle {
          fill: #fff;
          stroke: steelblue;
          stroke-width: 1.5px;
        }

        .node {
          font: 10px sans-serif;
        }

        .link {
          fill: none;
          stroke: #ccc;
          stroke-width: 1.5px;
        }

        </style>
          <!--<img src="../image/dummy5.svg" style='width:100%;margin:3px 0;'/>-->
          <script src="http://d3js.org/d3.v3.min.js"></script>
          <!--******* vertical *******-->
          <script>
          var treeData = [
            <?php echo "{'name' : 'CDS','icon': '../image/logo.png','padding':'0','user_id': 'CDS','level':'CDS','children' : ["; echo get_node_ul_frm_adm ($DBconn, 1); echo "]}"; ?>];

            var width = $("#agent-tree").width(),
              height = 2200;

          var cluster = d3.layout.tree()
              .nodeSize([100, 200])
              .separation(function(){
                return .5;
              })
              .size([height, width - 160]);

          var zoom = d3.behavior.zoom().on("zoom", function () {
              svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")")
              })

          var svg = d3.select("#agent-tree").append("svg")
              .attr("width", width)
              .attr("height", height)
              .attr("object-fit", "cover")
              .call(zoom)
              .append("g")
              .attr("transform", "translate(40,0)");
              root = treeData[0];
            var nodes = cluster.nodes(root).reverse();
            nodes.forEach(function(d) { d.y = d.depth * 100; });
            var link = svg.selectAll(".link")
                .data(cluster.links(nodes))
                .enter().append("path")
                .attr("class", "link")
                .attr("d", elbow);

            var node = svg.selectAll(".node")
                .data(nodes)
                .enter().append("g")
                .attr("class", "node")
                .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })

            node.append("circle")
                .attr("transform", function(d) { return "translate(0,"+d.padding+")"; })
                .attr("r", 12.5);

          function elbow(d) {
            return "M" + d.source.x + "," + d.source.y
              + "H" + ((d.target.x-d.source.x)/2,d.source.x )
              + "V" + d.target.y
              + "H" + d.target.x
              + "v" + ((d.source.y-d.target.y)/2,42 );
          }
          </script>

【问题讨论】:

  • 我认为我的答案不是你想要的?

标签: javascript jquery d3.js svg center


【解决方案1】:

遍历树上的每个节点,并获得其每个对应边界框的最小和最大 x 和 y 值。

var smallestBiggestDim = {
  smallX : "",
  smallY : "",
  bigX : "",
  bigY : ""
}
nodes.each(function(d, i){ //loop through tree nodes
  var thisBBox = d3.select(this).node().getBBox(); //get bbox of current node
  if(i == 0){
    //if i = 0, none are set, so set them
    smallestBiggestDim.smallX = thisBBox.left;
    smallestBiggestDim.smallY = thisBBox.top;
    smallestBiggestDim.bigX = thisBBox.left + thisBBox.width;
    smallestBiggestDim.bigY = thisBBox.top + thisBBox.height;
  } else {
    //check values and set if bigger or smaller
    if(smallestBiggestDim.smallX > thisBBox.left){ smallestBiggestDim.smallX = thisBBox.left }
    if(smallestBiggestDim.smallY > thisBBox.top){ smallestBiggestDim.smallY = thisBBox.top }
    if(smallestBiggestDim.bigX < thisBBox.left + thisBBox.width;){ smallestBiggestDim.bigX = thisBBox.left + thisBBox.width; }
    if(smallestBiggestDim.bigY < thisBBox.top + thisBBox.height;){ smallestBiggestDim.bigY = thisBBox.top + thisBBox.height; }
}
})

上面得到每个节点的边界框,并检查最小和最大的x和y值。

然后使用这些尺寸以及 svg 的宽度和高度来计算缩放。

要计算出新的宽度和高度,只需这样做:

var newWidth = smallestBiggestDim.bigX - smallestBiggestDim.smallX;
var newHeight = smallestBiggestDim.bigY - smallestBiggestDim.smallY;

假设你计算的矩形是 300 x 300,你的 svg 的宽度和高度是 200 x 200。要计算你会做的比例:

var scale = Math.max(rectWidth/svgWidth, rectHeight/svgHeight);
//which is
var scale = Math.max(300/200, 300/200);

我使用 Math.max,因为您只有一个比例值,因此您需要获取最大值以适应宽度和高度。

所以你的比例现在是:

var newScale = 1.5

所以在加载时你会像这样缩小:

svg.attr('transform', 'scale(' + newScale + ')';

应该可以的:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-16
    • 2019-12-30
    • 2010-11-30
    • 2015-08-05
    • 2016-02-27
    • 2018-11-06
    • 2020-07-26
    • 1970-01-01
    相关资源
    最近更新 更多