【问题标题】:D3 zoom behavior with multiple containers for a chart in one svg一个 svg 中图表的多个容器的 D3 缩放行为
【发布时间】:2026-02-22 19:15:01
【问题描述】:

目前,我有一个 SVG,里面有多个容器,即多个较小的 svg,它们根据 json 数据中的组数呈现。如果 json 中有 5 组数据,则 5 个较小的多个容器将适合该外部 svg。

另外,如果一个容器被缩放,其他容器应该反映相同的缩放行为并且应该是同步的。这将在散点图和多线图上实现。

当前的问题是多个容器按需要呈现,但只有最后一个容器在放大时的行为是正确的。在其他容器上,当调用缩放函数时,缩放行为不正确,即认为它是散点图,刻度上的气泡和轴不放大或缩小。

1) 假设其他容器中的轴选择正确,我如何使轴也放大其他容器?
2) 无论我放大哪个容器,如何同步所有容器中的缩放行为?

代码:

    d3.select(that.selector+" #svgContainer"+index)
      .call(d3.behavior.zoom()
      .x(that.xScale)
      .y(that.yScale)
      .scaleExtent([1, 10])
      .on("zoom", zoomed)); /*Attaching Zoom behavior to each container id '#svgContainer0','#svgContainer1',so on.*/

    function zoomed() {
        that.zoomed_out = false;
        that.k.isOrdinal(that.selector,"#"+this.id+" .x.axis",that.xScale);
        isOrdinal(that.selector,"#"+this.id+" .x.grid",that.xScale);
        isOrdinal(that.selector,"#"+this.id+" .y.axis",that.yScale);
        isOrdinal(that.selector,"#"+this.id+" .y.grid",that.yScale);

        that.optionalFeatures()
            .plotCircle()
            .label();
        d3.select(that.selector)
            .selectAll(".dot")
            .attr("r", function (d) {
                return that.sizes(d.weight)*d3.event.scale;
            });
    };

    function isOrdinal(svg,container,scale) {
        var l = container.length;
        var temp = container.substr((l-7),7);
        if(temp === ".x.axis") {                                
                d3.select(svg).select(container).call(makeXAxis(options,scale));
            }
            else if(temp === ".y.axis") {
                d3.select(svg).select(container).call(makeYAxis(options,scale));
            }
    };

    function makeXAxis(options,xScale) {
    var xaxis = d3.svg.axis()
                    .scale(xScale)
                    .ticks(options.axis.x.no_of_ticks)
                    .tickSize(options.axis.x.tickSize)
                    .outerTickSize(options.axis.x.outer_tick_size)
                    .tickPadding(options.axis.x.ticksPadding)
                    .orient(options.axis.x.orient);
    return xaxis;
};

    function makeYAxis(options,yScale) {
    var yaxis = d3.svg.axis()
                    .scale(yScale)
                    .orient(options.axis.y.orient)
                    .ticks(options.axis.y.no_of_ticks)
                    .tickSize(options.axis.y.tickSize)
                    .outerTickSize(options.axis.y.outer_tick_size)
                    .tickPadding(options.axis.y.ticksPadding);
    return yaxis;
};

【问题讨论】:

标签: javascript svg d3.js zooming scatter-plot


【解决方案1】:

我可能为时已晚,但这是我对这个问题的看法:

基本上每个.call(d3.behavior.zoom()...) 都是独立的,只有最后一个会捕获触发的事件。您是否尝试过创建自己的事件并手动将其重新分配到预先声明的缩放列表中?

.on("d3Zoom", function(){ //zoom1 //zoom2 //... })

此外,不要循环遍历仅是 #svgContainer+index 的正则表达式的 ID,而是使用类:class=svgContainer, id=index。 这样你就可以selectAll(".svgContainer").call(d3Zoom...)The way selections are implemented as joints,这可能会解决您的独立缩放问题(selectAll 表示将与一个缩放关联的单个选择,而 select 循环表示多个选择,因此具有独立缩放功能)。

我希望它对某人有所帮助。

【讨论】: