Javascript d3 raise()不处理特定选择
我用Javascript d3 raise()不处理特定选择,javascript,d3.js,svg,Javascript,D3.js,Svg,我用d3制作了一个折线图,但由于数据的形状,线和点(我在每个特定数据点的线上使用点)通常会位于彼此的顶部 为了解决这个问题,我结束了对线和点的不透明度0.4,当您将鼠标悬停在一条线上时,该特定数据行的线和点会弹出,并将其不透明度设置为1 我的问题是:我正在使用.raise()函数使它们弹出并覆盖其余的线条和点,该函数仅用于我的线条选择,而不用于我的点选择,我不知道为什么 我的代码: // draw the data lines const lines = svg.selectAll('.
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");
})
//绘制数据线
const lines=svg.selectAll(“.line”)
.data(此.data)
.输入()
.append('路径')
.attr('class','data.line')
.attr(“填充”、“无”)
.attr(“笔划”,d=>颜色(d键))
.attr(“笔划线条连接”、“圆形”)
.attr(“笔划线头”、“圆形”)
.attr(“笔划宽度”,2.5)
.attr('stroke-opacity',0.4)
.attr('d',d=>行(d.values))
.on('mouseenter',d=>{
//突出显示它们
让myCircles=circles.selectAll('.circle');
lines.attr('stroke-opacity',b=>{
返回b.key==d.key?1:0.4;
});
myCircles.attr('fill-opacity',b=>{
返回b[this.typeIdentifier]==d.key?1:0.4;
});
//把他们带到前面来
myCircles=circles。选择All(“.circle”)
.filter(b=>b[this.typeIdentifier]==d.key);
常量myLines=lines.filter(b=>b.key==d.key);
myLines.raise();
myCircles.raise();
});
//画圆圈
const circles=svg.selectAll(“.circle”)
.data(此.data)
.输入()
.append('g');
圆圈。选择全部(“.circle”)
.数据(d=>d.值)
.输入()
.append('圆')
.attr('class','circle')
.attr('笔划','白色')
.attr('笔划宽度',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)=>{
工具提示:raise();
样式(“显示”,空);
工具提示。选择(“#text1”).text(d[this.typeIdentifier])
.attr('fill',颜色(d[this.typeIdentifier]);
工具提示。选择('#text4').text(d[this.yAxisValue]);
工具提示。选择('#text5').text(d[this.xAxisValue]);
const tWidth=tooltip.select('#text1').node().getComputedTextLength()>60?工具提示。select('#text1').node().getComputedTextLength()+20:80;
tooltipRect.attr('width',tWidth);
常数xPosition=d3.鼠标(j[b])[0];
constyposition=d3.鼠标(j[b])[1];
如果(xPosition+tWidth+35{
样式(“显示”、“无”);
})
因此,当您将鼠标悬停在一条线上时,这将使与之相关的线和点位于前方,不透明度1
,但由于某些原因,它只在线
选择上起作用,而不在myCircles
选择上起作用。选择不是空的,我一直在打印它们来测试它。此外,我还尝试使用.raise()
方法将一个接一个的圆(使用单数选择和原始元素)带到前面,但它不起作用
为什么它不起作用?这可能与鼠标悬停在圆圈上的工具提示有关吗?我是不是做错了什么事却看不见?事实上,
selection.raise()
正在工作。这里的问题只是SVG的树结构:给定行的所有圆都属于
元素
如果您选择,您将看到selection.raise()
:
按顺序重新插入每个选定元素,作为其父元素的最后一个子元素
上面的重点是我的:这里的关键工作是家长。因此,您需要将包含所选圆的
元素提升到其他圆的其他
元素之上,而不是提升其
父元素中的圆
在你的情况下,这就像改变
myCircles = circles.selectAll('.circle').filter(etc...)
…致:
myCircles = circles.filter(etc...)
现在,myCircles
是带有
元素的选择,您可以将其提升。请注意过滤器
功能:由于您没有共享数据结构,我不知道
元素(即this.data
)的数据数组是否包含键
属性。相应地改变它
下面是一个演示:
我们为每一行设置了一组圆,每一组圆都位于各自的
父对象内。只有左边的圆是分开的,所有其他的圆都是故意一个接一个地画出来的。当您将鼠标悬停在一个圆上(使用左侧的圆)时,它的
容器将升起,在本例中使用
d3.select(this.parentNode).raise()
…,因此所有圆都可见:
const svg=d3.选择(“svg”);
常量比例=d3.scaleOrdinal(d3.schemeSet1);
常量lineGenerator=d3.line()
.x(功能(d){
返回d.x
})
.y(功能(d){
返回d.y
})
常数数据=d3.范围(5).映射(函数(d){
返回{
关键:d,
值:d3.范围(5).映射(函数(e){
返回{
x:50+100*e,
y:e?150:50+50*d
}
})
}
});
const lines=svg.selectAll(空)
.数据(数据)
.输入()
.append(“路径”)
.attr(“d”,函数(d){
返回线生成器(d值);
})
.style(“填充”、“无”)
.style(“笔划”)