【问题标题】:How to zoom around an svg如何缩放 svg
【发布时间】:2020-12-11 17:29:14
【问题描述】:

我有一个用 javascript 和 d3 创建的 svg 图形。

我希望能够在您单击任何圆圈时放大它。

我以为我可以通过在整个图表上添加一个变换来做到这一点,即:

翻译 - 移动整个图表,使所选圆圈位于中心

scale - 扩展图表,使选定的圆圈占据整个空间

我错了!

我读了一点,然后尝试了:

翻译 - 所以圆的原点在 0,0

scale - 所以圆的半径被扩大到svg的大小

再次平移 - 将圆移回中心 - 平移按比例因子缩放

还是不行!

谁能解释一下我是怎么做到的?

代码如下:

<!DOCTYPE html>
<head>
<script src="https://d3js.org/d3.v3.min.js"></script>
<style>
  text {
  font: 24px "Helvetica Neue", Helvetica, Arial, sans-serif;
  text-anchor: middle;
  pointer-events: none;
}

circle {
  fill: #ccc;
  stroke: black;
}

.node:hover circle {
  fill: orange;
}
</style>
</head>
<body>
<script>
var json = {
 "name": "flare",
 "children": [
  {
   "name": "analytics",
   "children": [
    {
     "name": "cluster",
     "children": [
      {"name": "AgglomerativeCluster", "value": 3938},
      {"name": "CommunityStructure", "value": 3812},
      {"name": "HierarchicalCluster", "value": 6714},
      {"name": "MergeEdge", "value": 743}
     ]
    },
    {
     "name": "graph",
     "children": [
      {"name": "BetweennessCentrality", "value": 3534},
      {"name": "ShortestPaths", "value": 5914},
      {"name": "SpanningTree", "value": 3416}
     ]
    }
   ]
  },
  {
   "name": "animate",
   "children": [
    {"name": "Easing", "value": 17010},
    {"name": "FunctionSequence", "value": 5842},
    {
     "name": "interpolate",
     "children": [
      {"name": "ArrayInterpolator", "value": 1983},
      {"name": "ObjectInterpolator", "value": 1629},
      {"name": "PointInterpolator", "value": 1675},
      {"name": "RectangleInterpolator", "value": 2042}
     ]
    },
    {"name": "ISchedulable", "value": 1041},
    {"name": "Parallel", "value": 5176},
    {"name": "TransitionEvent", "value": 1116},
    {"name": "Tween", "value": 6006}
   ]
  },
  {
   "name": "query",
   "children": [
    {"name": "AggregateExpression", "value": 1616},
    {"name": "Expression", "value": 5130},
    {"name": "ExpressionIterator", "value": 3617},
    {"name": "Fn", "value": 3240},
    {"name": "If", "value": 2732},
    {"name": "IsA", "value": 2039},
    {"name": "Literal", "value": 1214},
    {"name": "Match", "value": 3748},
    {"name": "Maximum", "value": 843},
    {
     "name": "methods",
     "children": [
      {"name": "add", "value": 593},
      {"name": "where", "value": 299},
      {"name": "xor", "value": 354},
      {"name": "_", "value": 264}
     ]
    },
    {"name": "Minimum", "value": 843},
    {"name": "Not", "value": 1554},
    {"name": "Or", "value": 970},
    {"name": "Query", "value": 13896},
    {"name": "Range", "value": 1594},
    {"name": "StringUtil", "value": 4130},
    {"name": "Sum", "value": 791},
    {"name": "Variable", "value": 1124},
    {"name": "Variance", "value": 1876},
    {"name": "Xor", "value": 1101}
   ]
  }
 ]
}


var bleed = 100,
    width = 960,
    height = 960;

var pack = d3.layout.pack()
    .sort(null)
    .size([width, height + bleed * 2])
    .padding(2);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(0," + -bleed + ")");

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

  node.append("circle")
      .attr("r", function(d) { return d.r; });

  node.filter(function(d) { return !d.children; })
      .append("g")
      .attr("class", "label")
      .append("text")
      .text(function(d) { return d.name; })
      .attr("dy", function(d) {
        // Cheat and calculate text length here
        d.ctl = 2 * d.r / Math.max(this.getComputedTextLength(), 24);
        return ".35em";
      });
   node.selectAll(".label")
    .attr("transform", d => "scale(" + d.ctl + "," + d.ctl + ")");
</script>
</body>
</html>

【问题讨论】:

    标签: svg d3.js


    【解决方案1】:

    顺序在描述转换时很重要。有两种查看方式。

    考虑以下转换序列:

    translate(40, 20) rotate(30) scale(1, 0.5)
    

    如果您按照转换的写入顺序(从左到右,在 DOM 树中向下)读取转换,则您正在转换坐标系。只有在最终的坐标系建立之后,才会将内容绘制到其中:

    每次变换都通过变换当前坐标系来建立下一个坐标系。

    但您也可以将转换解读为内容的转换。但是,您需要在 DOM 树中从右到左向上阅读:

    这样,每个变换都发生在基本坐标系中。

    【讨论】:

      猜你喜欢
      • 2019-05-28
      • 2017-05-08
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-15
      • 2016-01-07
      • 2022-01-11
      相关资源
      最近更新 更多