在一个 svg 中对图表的多个容器进行 D3 缩放行为

D3 zoom behavior with multiple containers for a chart in one svg

本文关键字:D3 缩放 一个 svg      更新时间:2023-09-26

目前,我有一个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;
};

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

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

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

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

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