gpt4 book ai didi

d3.js - 在 G 元素中选择路径并更改样式

转载 作者:行者123 更新时间:2023-12-03 18:08:36 24 4
gpt4 key购买 nike

本质上,我试图让所有路径,除了悬停在上面的路径变成灰色,而被选中的路径保持原始颜色。我已经能够将所有其他路径变为灰色,但是我在使用“select.this”函数时遇到了问题,并且实际上访问了我想要更改样式的路径。看来我实际上已经设法找到了 g 组中的路径元素,但是我在控制台中遇到了一个错误说

Uncaught TypeError: Property 'style' of object #<SVGGElement> is not a function

相关代码:
    svg.selectAll("g.team")
.on("mouseover",function(){
console.log("I see you!");
var lineName;
var accuracy = 10;

svg.selectAll("path.team.line").style("stroke","#C0C0C0");
//set all to gray

var selectedArray = d3.select(this);
console.log(selectedArray);

var selectGroup = selectedArray[0];
console.log("should be group:"+selectGroup);

var selectedLine = selectGroup[0];;

selectedLine.style("color",function(d){ //let active keep color
lineName = abbrDict[d.name]; //full name to be at end of line
return color(d.name);
});

//get position of end of line
var len = d3.select(this).children().node().getTotalLength();
var pos = d3.select(this).node().getPointAtLength(len);
//append text to end of line
svg.append("text")
.attr("id","tooltip")
.attr("x",pos.x-55)
.attr("y",pos.y)
.text(lineName)
.style("font-family","sans-serif")
.style("font-size",13);

this.parentNode.parentNode.appendChild(this.parentNode);
//brings team to front, must select the path's g parent
//to reorder it

})
.on("mouseout",function(){
d3.select("#tooltip").remove();

d3.selectAll("team").selectAll("path")
.transition()
.style("stroke",function(d){
return color(d.name); //return all the colors
});

d3.selectAll("axis").selectAll("line").style("color","black");

});

谢谢,麻烦您了!

最佳答案

D3 选择是 DOM 元素数组的数组。 (它们是嵌套数组,因此它们可以实现嵌套选择,同时为每个子选择保留单独的索引计数和属性。)

因此,当您运行如下语句时:

var selectedArray = d3.select(this);
selectedArray结构为 [[ {SVGGElement} ]] .这么多你似乎明白了。

但是您的 selectedArray不仅仅是一个包含一个包含单个 DOM 元素的数组的数组。它也是一个 d3.selection 对象,具有选择所具有的所有特殊功能,包括 .style()功能。

但是,当您在下一行中提取子数组时:
var selectGroup = selectedArray[0];

您现在只有一个包含 SVG <g> 的普通数组元素节点。它没有 d3 的特殊功能。最后,当您从该数组中提取元素时:
var selectedLine = selectGroup[0];

您只需返回 DOM 元素节点本身。与 this 完全相同的对象您最初选择的。该节点具有 .style属性,但不是 .style()功能。

有时,您确实想从 d3 选择中提取节点,以便使用属于 DOM 接口(interface)的属性或方法。如果你确实想这样做,上面的方法会起作用,或者你可以在一行中访问它
var svgNode = d3.select("svg")[0][0];

或者,您可以使用 selection.node()做同样事情的方法(在选择的第一个嵌套中抓取第一个节点):
var svgNode = d3.select("svg").node();

但是, 如果您想在单个 DOM 元素上使用 d3 选择方法,请选择该元素,然后调用选择的方法。 选择是否包含一个元素或 1000 个元素都没有关系,您的代码是一样的。 (如果您的选择完全为空,它甚至不会抛出错误——它不会做任何事情!)如果您想对原始选择的子项使用 d3 方法,则需要使用子选择方法(或者 selection.select()selection.selectAll() )。
svg.selectAll("g.team")
.on("mouseover",function(){

var lineName;
svg.selectAll("path.team.line").style("stroke","#C0C0C0");
//set all to gray

var selectedGroup = d3.select(this);
var selectedLine = selectedGroup.select("path.team.line");
//this only selects the (first) path that is a child
//of the selected group

selectedLine.style("color",function(d){ //let active keep color
lineName = abbrDict[d.name]; //full name to be at end of line
return color(d.name);
});

/* ...etc... */

顺便说一句,当您将事件处理程序添加到具有 d3 的 selection.on() 的元素时方法,d3 将自动将该元素的数据对象作为第一个参数传递给您的事件处理函数。这意味着您可以简化代码以避免二次函数调用:
svg.selectAll("g.team")
.on("mouseover",function(d){ //d as a function parameter

var lineName;
svg.selectAll("path.team.line").style("stroke","#C0C0C0");
//set all to gray

var selectedLine = d3.select(this);

selectedLine.style("color", color(d.name) );
//already have the `d` for this element available

lineName = abbrDict[d.name];

/* ...etc... */

继续您的代码:为了定位您的文本元素,您尝试使用 .getTotalLength().getPointAtLength() <path> 的方法元素。现在,这些方法是 DOM 接口(interface)方法,而不是 d3 方法,所以你需要实际的 {SVGPathElement}节点,而不是 d3 选择。但是,您目前正在将 d3 选择与 DOM 方法混为一谈。

this 使用纯 Javascript 访问节点元素(这是它的父 <g> 元素):
 var pathNode = this.children[0]; //assuming the <path> is the first child of <g>
var len = pathNode.getTotalLength();
var pos = pathNode.getPointAtLength( len );

或者,您可以访问 <path>您在上面创建的 d3 选择中的元素:
 var pathNode = selectedLine.node(); //grab the node from the selection
var len = pathNode.getTotalLength();
var pos = pathNode.getPointAtLength( len );

最后,这一行:
this.parentNode.parentNode.appendChild(this.parentNode); 
//brings team to front, must select the path's g parent
//to reorder it

我认为应该只是:
this.parentNode.appendChild(this); 
//brings team to front, must select the path's g parent
//to reorder it

(因为 this 已经是 <g> 元素)。

关于d3.js - 在 G 元素中选择路径并更改样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22116909/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com