gpt4 book ai didi

javascript - D3 在正在进行的过渡期间停止交互

转载 作者:行者123 更新时间:2023-12-04 03:37:24 25 4
gpt4 key购买 nike

我注意到 Control Flow D3 API 中的部分,并尝试将它们应用到我的代码中。我的最终目标是避免任何“mouseenter”、“mouseleave”、“click”等交互,只要 transition() 仍在进行中。

代码片段显示 3 个节点,它们在“mouseenter”事件后交换颜色。 问题是,如果我在“mouseenter”事件中中断正在进行的转换,颜色会变回白色。我怎样才能避免这种行为?

在我尝试应用之后,我收到了一个错误,await is only valid in async functions and async generators

<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>D3v6 Transition Example</title>
<!-- call external d3.js framework -->
<script src="https://d3js.org/d3.v6.js"></script>
</head>

<style>
body {
background-color: rgb(220, 220, 220);
overflow: hidden;
margin: 0px;
}

.node {
stroke: white;
stroke-width: 2px;
cursor: pointer;
}

.node:hover {
stroke: red
}

.link {
fill: none;
cursor: default;
stroke: rgb(0, 0, 0);
stroke-width: 3px;
}
</style>

<body>

<svg id="svg"> </svg>

<script>
var graph = {
"nodes": [
{
"id": 0,
},
{
"id": 1,
},
{
"id": 2,
}
],
"links": [
{
"source": 0,
"target": 1,
},
{
"source": 1,
"target": 2,
},
{
"source": 2,
"target": 0,
}
]
}

var width = window.innerWidth
var height = window.innerHeight

var svg = d3.select("svg")
.attr("class", "canvas")
.attr("width", width)
.attr("height", height)
.call(d3.zoom().on("zoom", function (event) {
svg.attr("transform", event.transform)
}))
.append("g")

// remove zoom on dblclick listener
d3.select("svg").on("dblclick.zoom", null)

var linkContainer = svg.append("g").attr("class", "linkContainer")
var nodeContainer = svg.append("g").attr("class", "nodeContainer")

var isRed = false;

var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function (d) {
return d.id;
}).distance(100))
.force("charge", d3.forceManyBody().strength(-500))
.force("center", d3.forceCenter(width / 2, height / 2))
.force("collision", d3.forceCollide().radius(50))

initialize()

function initialize() {

link = linkContainer.selectAll(".link")
.data(graph.links)
.join("line")
.attr("class", "link")

node = nodeContainer.selectAll(".node")
.data(graph.nodes, d => d.id)
.join("g")
.attr("class", "node")

node.selectAll("circle")
.data(d => [d])
.join("circle")
.attr("r", 30)
.style("fill", "whitesmoke")
.on("mouseenter", mouseEnter)

node.selectAll("text")
.data(d=> [d])
.join("text")
.style("class", "icon")
.attr("font-family", "FontAwesome")
.attr("dominant-baseline", "central")
.attr("text-anchor", "middle")
.attr("font-size", 30)
.attr("fill", "black")
.attr("stroke-width", "0px")
.attr("pointer-events", "none")
.text((d) => {
return d.id
})

simulation
.nodes(graph.nodes)
.on("tick", ticked);

simulation
.force("link")
.links(graph.links)

}

function mouseEnter(d) {
if (!isRed) {
d3.select(this)
.transition()
.duration(1500)
.style("fill", "red")

isRed = true
} else {
d3.select(this)
.transition()
.duration(1500)
.style("fill", "whitesmoke")

isRed = false
}
}

function ticked() {
// update link positions
link
.attr("x1", function (d) {
return d.source.x;
})
.attr("y1", function (d) {
return d.source.y;
})
.attr("x2", function (d) {
return d.target.x;
})
.attr("y2", function (d) {
return d.target.y;
});


// update node positions
node
.attr("transform", function (d) {
return "translate(" + d.x + ", " + d.y + ")";
});
}
</script>
</body>

</html>

最佳答案

有几种方法可以做到这一点,例如使用标志。然而,最惯用的 D3 只是检查元素是否有 active transition。 ,这可以很简单:

if(d3.active(this)) return;

这里是你的代码有那个变化:

<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>D3v6 Transition Example</title>
<!-- call external d3.js framework -->
<script src="https://d3js.org/d3.v6.js"></script>
</head>

<style>
body {
background-color: rgb(220, 220, 220);
overflow: hidden;
margin: 0px;
}

.node {
stroke: white;
stroke-width: 2px;
cursor: pointer;
}

.node:hover {
stroke: red
}

.link {
fill: none;
cursor: default;
stroke: rgb(0, 0, 0);
stroke-width: 3px;
}
</style>

<body>

<svg id="svg"> </svg>

<script>
var graph = {
"nodes": [{
"id": 0,
},
{
"id": 1,
},
{
"id": 2,
}
],
"links": [{
"source": 0,
"target": 1,
},
{
"source": 1,
"target": 2,
},
{
"source": 2,
"target": 0,
}
]
}

var width = window.innerWidth
var height = window.innerHeight

var svg = d3.select("svg")
.attr("class", "canvas")
.attr("width", width)
.attr("height", height)
.call(d3.zoom().on("zoom", function(event) {
svg.attr("transform", event.transform)
}))
.append("g")

// remove zoom on dblclick listener
d3.select("svg").on("dblclick.zoom", null)

var linkContainer = svg.append("g").attr("class", "linkContainer")
var nodeContainer = svg.append("g").attr("class", "nodeContainer")

var isRed = false;

var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) {
return d.id;
}).distance(100))
.force("charge", d3.forceManyBody().strength(-500))
.force("center", d3.forceCenter(width / 2, height / 2))
.force("collision", d3.forceCollide().radius(50))

initialize()

function initialize() {

link = linkContainer.selectAll(".link")
.data(graph.links)
.join("line")
.attr("class", "link")

node = nodeContainer.selectAll(".node")
.data(graph.nodes, d => d.id)
.join("g")
.attr("class", "node")

node.selectAll("circle")
.data(d => [d])
.join("circle")
.attr("r", 30)
.style("fill", "whitesmoke")
.on("mouseenter", mouseEnter)

node.selectAll("text")
.data(d => [d])
.join("text")
.style("class", "icon")
.attr("font-family", "FontAwesome")
.attr("dominant-baseline", "central")
.attr("text-anchor", "middle")
.attr("font-size", 30)
.attr("fill", "black")
.attr("stroke-width", "0px")
.attr("pointer-events", "none")
.text((d) => {
return d.id
})

simulation
.nodes(graph.nodes)
.on("tick", ticked);

simulation
.force("link")
.links(graph.links)

}

function mouseEnter(d) {
if (d3.active(this)) return;
if (!isRed) {
d3.select(this)
.transition()
.duration(1500)
.style("fill", "red")

isRed = true
} else {
d3.select(this)
.transition()
.duration(1500)
.style("fill", "whitesmoke")

isRed = false
}
}

function ticked() {
// update link positions
link
.attr("x1", function(d) {
return d.source.x;
})
.attr("y1", function(d) {
return d.source.y;
})
.attr("x2", function(d) {
return d.target.x;
})
.attr("y2", function(d) {
return d.target.y;
});


// update node positions
node
.attr("transform", function(d) {
return "translate(" + d.x + ", " + d.y + ")";
});
}
</script>
</body>

</html>

关于javascript - D3 在正在进行的过渡期间停止交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66651451/

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