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(“笔划”)