如何更改节点的不透明度?
How to change the opacity of a node?
场景:
鼠标悬停在特定节点上时,我试图通过更改不透明度来突出显示该节点及其所有互连节点,并且所有其他节点都应该模糊。
期望:
当鼠标悬停在一个节点上时,该节点及其所有互连节点的不透明度应为 1,而其他节点应使用较小的不透明度进行模糊处理。
现有功能:
当我第一次悬停在任何节点上时,它没有按预期工作。但是从第二次开始就正常了
请参考jsfiddle:jsfiddle
var nodeElements = g.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 60)
.attr("stroke", "#fff")
.attr('stroke-width', 21)
.attr("id", function(d) { return d.id })
//.attr("fill", function(d) {return color(d.id)})
.attr('fill', function(d, i) { return 'url(#grad' + i + ')'; })
.on('contextmenu', function(d){
d3.event.preventDefault();
menu(d3.mouse(svg.node())[0], d3.mouse(svg.node())[1]);
})
.on('mouseover', selectNode)
.on('mouseout', releaseNode)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
function selectNode(selectedNode) {
var neighbors = getNeighbors(selectedNode)
nodeElements.transition().duration(500)
.attr('opacity', function(node) {
return setOpacity(node,neighbors, selectedNode);
})
.attr('r', function(node) {
return getNodeRadius(node,neighbors);
});
nodeElements.attr('fill', function(node) {
// send selectedNode to your getNodeColor
return getNodeColor(node,neighbors,selectedNode);
})
textElements.style('font-size', function(node) {
return getTextColor(node, neighbors)
})
textElements.attr('opacity', function(node) {
return setOpacity(node,neighbors, selectedNode);
})
linkElements.style('stroke', function(link) {
return getLinkColor(selectedNode, link)
})
}
function releaseNode() {
nodeElements
.attr('r', 60)
.attr('fill', function(d, i) { return 'url(#grad' + i + ')'; })
.attr('opacity', 1);
linkElements.style('stroke', 'grey');
textElements.attr('opacity','1');
}
function setOpacity(node, neighbors, selectedNode) {
if (Array.isArray(neighbors) && neighbors.indexOf(node.id) > -1) {
return 1;
} else {
return 0.3;
}
}
解决方案很简单:不要使用 attr
设置不透明度,而是使用 style
:
nodeElements.transition()
.duration(500)
.style('opacity', function(node) {
return setOpacity(node,neighbors, selectedNode);
})
以下是仅进行了更改的代码:https://jsfiddle.net/uye24zjn/
说明
解释有点复杂。首先,请记住您之前从未设置过任何不透明度,无论是使用 attr
还是 style
。
当您转换不透明度时,D3 使用 getter 检索原始值,应用相应的方法(attr
或 style
)。问题来了:因为您从未使用 attr
方法设置任何不透明度,所以使用 attr
作为 getter 的先前值是 null
。但是,使用style
,值为1
:
const circle = d3.select("g")
.append("circle")
.attr("r", 50);
console.log("The opacity value using 'attr' as a getter is: " + circle.attr("opacity"))
console.log("The opacity value using 'style' as a getter is: " + circle.style("opacity"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
<g transform="translate(150,75)"></g>
</svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
结果是 D3 将尝试从 null
(零)过渡到 1
,您会看到圆圈在过渡开始时消失。作为演示,将鼠标悬停在圆圈上:
const circle = d3.select("g")
.append("circle")
.attr("r", 50);
circle.on("mouseover", function() {
d3.select(this).transition()
.duration(1000)
.attr("opacity", function() {
return 1
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
<g transform="translate(150,75)"></g>
</svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
这个问题只发生在第一次鼠标悬停时(就像你的代码一样),因为在将鼠标悬停在圆上之后,不透明度被设置为一个属性,并且当 [=15= 时不会再有 null
] 用作 getter.
一般来说,使用attr
设置属性,使用style
设置样式.换句话说:使用 style
来设置您使用 CSS 文件所做的任何事情。
场景:
鼠标悬停在特定节点上时,我试图通过更改不透明度来突出显示该节点及其所有互连节点,并且所有其他节点都应该模糊。
期望: 当鼠标悬停在一个节点上时,该节点及其所有互连节点的不透明度应为 1,而其他节点应使用较小的不透明度进行模糊处理。
现有功能: 当我第一次悬停在任何节点上时,它没有按预期工作。但是从第二次开始就正常了
请参考jsfiddle:jsfiddle
var nodeElements = g.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 60)
.attr("stroke", "#fff")
.attr('stroke-width', 21)
.attr("id", function(d) { return d.id })
//.attr("fill", function(d) {return color(d.id)})
.attr('fill', function(d, i) { return 'url(#grad' + i + ')'; })
.on('contextmenu', function(d){
d3.event.preventDefault();
menu(d3.mouse(svg.node())[0], d3.mouse(svg.node())[1]);
})
.on('mouseover', selectNode)
.on('mouseout', releaseNode)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
function selectNode(selectedNode) {
var neighbors = getNeighbors(selectedNode)
nodeElements.transition().duration(500)
.attr('opacity', function(node) {
return setOpacity(node,neighbors, selectedNode);
})
.attr('r', function(node) {
return getNodeRadius(node,neighbors);
});
nodeElements.attr('fill', function(node) {
// send selectedNode to your getNodeColor
return getNodeColor(node,neighbors,selectedNode);
})
textElements.style('font-size', function(node) {
return getTextColor(node, neighbors)
})
textElements.attr('opacity', function(node) {
return setOpacity(node,neighbors, selectedNode);
})
linkElements.style('stroke', function(link) {
return getLinkColor(selectedNode, link)
})
}
function releaseNode() {
nodeElements
.attr('r', 60)
.attr('fill', function(d, i) { return 'url(#grad' + i + ')'; })
.attr('opacity', 1);
linkElements.style('stroke', 'grey');
textElements.attr('opacity','1');
}
function setOpacity(node, neighbors, selectedNode) {
if (Array.isArray(neighbors) && neighbors.indexOf(node.id) > -1) {
return 1;
} else {
return 0.3;
}
}
解决方案很简单:不要使用 attr
设置不透明度,而是使用 style
:
nodeElements.transition()
.duration(500)
.style('opacity', function(node) {
return setOpacity(node,neighbors, selectedNode);
})
以下是仅进行了更改的代码:https://jsfiddle.net/uye24zjn/
说明
解释有点复杂。首先,请记住您之前从未设置过任何不透明度,无论是使用 attr
还是 style
。
当您转换不透明度时,D3 使用 getter 检索原始值,应用相应的方法(attr
或 style
)。问题来了:因为您从未使用 attr
方法设置任何不透明度,所以使用 attr
作为 getter 的先前值是 null
。但是,使用style
,值为1
:
const circle = d3.select("g")
.append("circle")
.attr("r", 50);
console.log("The opacity value using 'attr' as a getter is: " + circle.attr("opacity"))
console.log("The opacity value using 'style' as a getter is: " + circle.style("opacity"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
<g transform="translate(150,75)"></g>
</svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
结果是 D3 将尝试从 null
(零)过渡到 1
,您会看到圆圈在过渡开始时消失。作为演示,将鼠标悬停在圆圈上:
const circle = d3.select("g")
.append("circle")
.attr("r", 50);
circle.on("mouseover", function() {
d3.select(this).transition()
.duration(1000)
.attr("opacity", function() {
return 1
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
<g transform="translate(150,75)"></g>
</svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
这个问题只发生在第一次鼠标悬停时(就像你的代码一样),因为在将鼠标悬停在圆上之后,不透明度被设置为一个属性,并且当 [=15= 时不会再有 null
] 用作 getter.
一般来说,使用attr
设置属性,使用style
设置样式.换句话说:使用 style
来设置您使用 CSS 文件所做的任何事情。