我正在尝试在d3中制作一个既可缩放又路径可悬停的流图。
从阅读的内容中可以看到,从v4 d3开始,缩放消耗了该事件,因此可能是为什么我的鼠标悬停事件不再触发的原因,但是我设置的任何重新排序或pointer-events: all
似乎都没有效果。
在下面的示例中,有人能帮助我了解如何使缩放和悬停工作吗? (还有一个codesandbox with the example)
const width = 500;
const height = 500;
let numberOfDataPoints = 5;
const numberOfLayers = 3;
let data = [];
for (let i = 0; i < numberOfDataPoints; i++) {
let point = [];
for (let j = 0; j < numberOfLayers; j++) {
point.push(Math.floor(Math.random() * Math.floor(120)));
}
data.push(point);
}
const x = d3
.scaleLinear()
.domain([0, numberOfDataPoints - 1])
.range([0, width]);
const y = d3.scaleLinear().range([height, 0]);
const area = d3
.area()
.x((d, i) => x(i))
.y0(d => y(d[0]))
.y1(d => y(d[1]));
const stack = d3
.stack()
.keys(d3.range(numberOfLayers))
.offset(d3.stackOffsetWiggle)
.order(d3.stackOrderNone);
let layers = stack(data);
y.domain([
d3.min(layers, l => d3.min(l, d => d[0])),
d3.max(layers, l => d3.max(l, d => d[1]))
]);
update();
const zoomContainer = d3
.select('svg')
.append('rect')
.attr('width', width)
.attr('height', height)
.attr('fill', 'none')
.style('pointer-events', 'all');
const zoom = d3
.zoom()
.scaleExtent([1, 8])
.on('zoom', zoomed);
zoomContainer.call(zoom);
function update() {
let path = d3
.select('svg')
.selectAll('path')
.data(layers);
path
.enter()
.append('path')
.attr('fill', 'red')
.merge(path)
.attr('d', d => area(d))
.on('mouseover', () => {
d3.select('svg')
.selectAll('path')
.attr('fill', 'red');
d3.select(d3.event.target).attr('fill', 'green');
});
}
function zoomed() {
let transform = d3.event.transform;
transform.y = 0;
let updatedScale = transform.rescaleX(x);
d3.select('svg')
.selectAll('path')
.attr('d', area.x((d, i) => updatedScale(i)));
}
答案 0 :(得分:0)
关于此操作无效的假设是正确的(缩放容器占用了事件),解决方法是仅删除zoomContainer
并将缩放应用于svg,即
const zoom = d3
.zoom()
.on('zoom', zoomed);
d3.select('svg').call(zoom);