首页 > 解决方案 > D3 共享缩放/过渡

问题描述

我希望有人可以深入了解我在共享缩放和使用过渡重置时遇到的 D3 问题。 

我有一个包含多个 SVG 的应用程序,我都共享一个缩放/平移行为。这似乎工作得很好。但随后我添加了一个“重置”按钮,我想使用该按钮使用 D3 的平滑过渡功能返回到身份转换。这行得通,除了...

如果只有一个 SVG 监听缩放,工作完美
/
流畅

这似乎是某种竞争条件,但我不确定我是否编码错误,或者违反了共享缩放的使用规则。

下面是该行为的简化工作演示代码(您可以输入不同#s 的 SVG 进行绘制,然后您可以将它们平移/缩放在一起,然后点击重置按钮):
您可以在 codepen 上尝试此操作:https: //codepen.io/MatthewMJ/pen/ZEEEjPE

感谢您的任何见解。

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <script src="https://d3js.org/d3.v4.js"></script>
  <script src="https://d3js.org/d3-random.v2.min.js"></script>
</head>
<body>
How many rows?&nbsp;<input id="numrows"/><button onClick="repaint()">repaint</button>
<br><br>
<div id="block" display="block"></div>
<button onClick="reset()">reset zoom/pan</button>

<script>

    // One Zoom to Zoom them All
    var zoom = d3.zoom();

    // we'll have a user-specified # of SVGs of same size/layout defined here
    var dims = {
        width: 800,
        height: 50,
        svg_dx: 100,
        svg_dy: 25
    };

    // max value for made-up data
    var pointMax = 1000;

    var xScale = d3.scaleLinear()
        .domain([0, pointMax])
        .range([dims.svg_dx, dims.width - (dims.svg_dx * 2)]);


    function repaint() {
        d3.selectAll("svg").remove(); // clear out everything to start over
        for (var i = 0; i < document.getElementById("numrows").value; i++) {
            paint_one_row(i);
        }
    }

    function paint_one_row(i) {

        // generate 10 random points
        var data = d3.range(10).map(d3.randomInt(pointMax));

        // create the SVG into which we'll paint
        var svg = d3.select('#block')
            .append("div")
            .append("svg")
            .attr("width", dims.width)
            .attr("height", dims.height);

        // draw the circles
        var circles = svg.selectAll('circle')
            .data(data)
            .enter()
            .append('circle')
            .attr('r', 7)
            .attr('cx', function (d) {
                return xScale(d);
            })
            .attr('cy', 10);

        // hook this SVG in with the central zoom
        svg.call(zoom);
        zoom.on('zoom.row' + i, zoomed.bind(svg));

        // each row should have it's own closure of 'zoomed' with differing 'circles'
        function zoomed() {
            var transform = d3.event.transform;

            // Zoom the circles
            var xNewScale = transform.rescaleX(xScale);
            circles
                .attr("cx", function (d) {
                    return xNewScale(d);
                });
        }
    }

    function reset() {
        d3.selectAll("svg").transition().duration(750).call(zoom.transform, d3.zoomIdentity);
    }

</script>
</body>

标签: d3.js

解决方案


推荐阅读