进入和悬停时的 D3 转换圆环图

问题描述

尽管围绕这个话题已经有很多问题,但我仍然无法回答。

我正在绘制这样的圆环图:

const svg = d3.select(svgRef.current);

        const size = 500;
        const radius = size / 2;
;
        svg.attr("viewBox",[-size / 2,-size / 2,size,size]);

        const pie = d3.pie()
            .padAngle(0.02)
            .sort(null)
            .value(d => d.value);

        const arc =  d3.arc()
            .innerRadius(radius * 0.67)
            .outerRadius(radius - 1);

        const color = d3.scaleOrdinal()
            .domain(data.map(d => d.name))
            .range(d3.quantize(t => d3.interpolateSpectral(t * 0.8 + 0.1),data.length).reverse());

        const arcs = pie(data);

        svg.selectAll("path")
            .data(arcs)
            .join("path")
            .attr("fill",d => color(d.data.name))
            .transition()
                .delay((_,i) => i * 500)
                .duration(500)
                .attrTween('d',(d) => {
                    const i = d3.interpolate(d.startAngle+0.1,d.endAngle);
                    return (t) => {
                        d.endAngle = i(t); 
                        return arc(d)
                        }
                    }); 

图表按预期进行动画处理。问题是:我希望细分在悬停时扩展一点。我该怎么做?

.on('mouSEOver',...) 到底去哪儿了?我知道我需要另一个 attrTween,但我不知道如何。

非常感谢!

编辑:

我现在找到了一种方法,但我仍然想知道是否有更好的方法来做到这一点?

const svg = d3.select(svgRef.current);

        const size = 500;
        const radius = size / 2;
;
        svg.attr("viewBox",size]);

        const pie = d3.pie()
            .padAngle(0.02)
            .sort(null)
            .value(d => d.value);

        const initialArc = d3.arc()
            .innerRadius(radius * 0.67)
            .outerRadius(radius - 20);

        const transformedArc = d3.arc().innerRadius(radius * 0.67);

        const color = d3.scaleOrdinal()
            .domain(data.map(d => d.name))
            .range(d3.quantize(t => d3.interpolateSpectral(t * 0.8 + 0.1),data.length).reverse());

        const arcs = pie(data);

        function arcTween(nextOuterRadius,currentOuterRadius) {
            return function() {
              d3.select(this).transition().duration(500).attrTween("d",function(d) {
                const i = d3.interpolate(currentOuterRadius,nextOuterRadius);
                return (t) => { d.outerRadius = i(t); return transformedArc(d); };
              });
            };
          }

        svg.selectAll("path")
            .data(arcs)
            .join("path")
            .attr("fill",d => color(d.data.name))
            .on("mouSEOver",arcTween(radius,radius - 20))
            .on('mouSEOut',arcTween(radius - 20,radius))
            .transition()
                .delay((_,d.endAngle);
                    return (t) => {
                        d.endAngle = i(t); 
                        return initialArc(d)
                        }
                    });

解决方法

如果您尝试将效果添加到所有 path 元素,您可以将其放置在 transition 之前或将选择保存到一个变量并分别附加过渡和鼠标悬停事件。

svg.selectAll("path")
    ... // Your existing code
    .on('mouseover',function () {
        svg.selectAll('[YOUR_ELEMENTS]')
            .transition()
    });
   .transition()
   ... // initial transition

let pies = svg.selectAll("path")
    ... // Your existing code
    .on('mouseover',function () {
        svg.selectAll('[YOUR_ELEMENTS]')
            .transition()
    });
pies.transition()
    ... // initial transition
pies.on('mouseover',function () {
        svg.selectAll('[YOUR_ELEMENTS]')
            .transition()
       });

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...