Max*_*chw 3 javascript svg d3.js
我有一个用 制作的折线图d3,但由于数据的形状,线条和点(我在每个特定数据点的线条上使用点)通常最终彼此重叠。
为了解决这个问题,我结束0.4了对线条和点的不透明度,当你将鼠标悬停在一条线上时,这条特定数据线的线条和点会弹出,并将其不透明度设置为1。
我的问题是:我正在使用该.raise()功能使它们弹出并站在其余的线条和点上,该功能仅适用于我的线条选择而不适用于我的点选择,我不知道为什么。
我的代码:
// draw the data lines
const lines = svg.selectAll('.line')
.data(this.data)
.enter()
.append('path')
.attr('class', 'data.line')
.attr("fill", "none")
.attr("stroke", d => colors(d.key))
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 2.5)
.attr('stroke-opacity', 0.4)
.attr('d', d => line(d.values))
.on('mouseenter', d => {
// Highlight them
let myCircles = circles.selectAll('.circle');
lines.attr('stroke-opacity', b => {
return b.key === d.key ? 1 : 0.4;
});
myCircles.attr('fill-opacity', b => {
return b[this.typeIdentifier] === d.key ? 1 : 0.4;
});
// Bring them to the front
myCircles = circles.selectAll('.circle')
.filter(b => b[this.typeIdentifier] === d.key);
const myLines = lines.filter(b => b.key === d.key);
myLines.raise();
myCircles.raise();
});
// draw the circles
const circles = svg.selectAll('.circle')
.data(this.data)
.enter()
.append('g');
circles.selectAll('.circle')
.data(d => d.values)
.enter()
.append('circle')
.attr('class', 'circle')
.attr('stroke', 'white')
.attr('stroke-width', 1)
.attr('r', 6)
.attr('fill', d => colors(d[this.typeIdentifier]))
.attr('fill-opacity', 0.4)
.attr('cx', d => x(d[this.xAxisValue]) + x.bandwidth() / 2)
.attr('cy', d => y(d[this.yAxisValue]))
.on('mouseenter', (d, b, j) => {
tooltip.raise();
tooltip.style("display", null);
tooltip.select("#text1").text(d[this.typeIdentifier])
.attr('fill', colors(d[this.typeIdentifier]));
tooltip.select('#text4').text(d[this.yAxisValue]);
tooltip.select('#text5').text(d[this.xAxisValue]);
const tWidth = tooltip.select('#text1').node().getComputedTextLength() > 60 ? tooltip.select('#text1').node().getComputedTextLength() + 20 : 80;
tooltipRect.attr('width', tWidth);
const xPosition = d3.mouse(j[b])[0];
const yPosition = d3.mouse(j[b])[1];
if (xPosition + tWidth + 35 < this.xWIDTH) { // display on the right
tooltip.attr("transform", `translate(${xPosition + 15}, ${yPosition - 25})`);
} else { // display on the left
tooltip.attr("transform", `translate(${xPosition - tWidth - 15}, ${yPosition - 25})`);
}
})
.on('mouseleave', d => {
tooltip.style("display", "none");
})
Run Code Online (Sandbox Code Playgroud)
因此,当您将鼠标悬停在一条线上时,这应该将与其相关联的线和点带到前面,带有 opacity 1,但出于某种原因,它仅适用于lines选择,而不适用于myCircles选择。选择不是空的,我一直在打印它们以进行测试。此外,我尝试使用该.raise()方法将圆圈一个一个(带有单一选择和原始元素)带到前面,但它不起作用。
为什么它不起作用?它可能与悬停在圆圈上的工具提示有关吗?我做错了什么而没有看到吗?
实际上,selection.raise()正在工作。这里的问题只是 SVG 的树结构:给定行的所有圆圈都属于一个<g>元素。
如果您查看文档,您会看到selection.raise():
按顺序重新插入每个选定元素,作为其父元素的最后一个子元素。
上面的重点是我的:这里的关键工作是parent。因此,您想要的是将<g>包含所选圆圈的元素提升<g>到其他圆圈的其他元素之上,而不是<g>其父级内的圆圈。
在你的情况下,就像改变一样简单......
myCircles = circles.selectAll('.circle').filter(etc...)
Run Code Online (Sandbox Code Playgroud)
...到:
myCircles = circles.filter(etc...)
Run Code Online (Sandbox Code Playgroud)
现在,myCircles是带有<g>元素的选择,您可以提高它。注意filter函数:由于您没有共享数据结构,因此我不知道<g>元素的数据数组(即this.data)是否包含该key属性。相应地更改它。
这是一个演示:
我们为每条线设置了一组圆圈,每个圆圈都在它们自己的<g>父级中。只有左边的圆圈是分开的,所有其他的圆圈都是故意画在另一个上的。当您将鼠标悬停在一个圆圈上(使用左侧的圆圈)时,它的<g>容器会升起,在这种情况下使用...
d3.select(this.parentNode).raise()
Run Code Online (Sandbox Code Playgroud)
...,所以所有圆圈都是可见的:
myCircles = circles.selectAll('.circle').filter(etc...)
Run Code Online (Sandbox Code Playgroud)
myCircles = circles.filter(etc...)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3470 次 |
| 最近记录: |