D3 设置间隔 在单击按钮时对文本进行动画处理并删除图像



嗨,我有一个单击按钮事件来启动某些文本的设置间隔/清除间隔动画,并在单击按钮时添加图像。我需要有关如何更好地停止和删除动画文本并在单击新按钮时删除图像的帮助。目前,当数组结束时,文本被空字符串替换。每次我单击按钮时,图像都会重复。

我已经查看了使用 exit((.remove(( 或 merge 的示例,但我无法弄清楚如何在我的情况下应用它。我的代码使用 D3 嵌套,并且是使用 svg 和 d3.line 以及其他过渡元素的更大地图项目的一部分。

这是我的 D3 代码的简化示例:

<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v0.min.js"></script>
<style>
</style>
</head>
<body>
<div id ="container">
<div id ="mapdata"></div>
<div id = "buttons"></div>
</div>
<script>

d3.queue()
.defer(d3.csv, "data/testData.csv")
.await(ready);
function ready (error, data){
var dataGroup = d3.nest()
.key(function(d) {return d.year;}).sortKeys(d3.ascending)
.key(function(d){return d.VoyageID;}).sortKeys(d3.ascending)
.entries(data);
dataGroup.forEach(function(yearObject,i) {
var buttons = d3.select("#buttons").selectAll("button")
.data(dataGroup)
.enter()
.append("button")
.attr("class", "buttons")
.attr("data-group", function(d){return d.key})
.attr("id", function(d){return "button_" + d.key})
.append("label")
.text(function(d){return d.key;})

var testData = d3.select("#mapdata").selectAll(".voyageData")
.data(dataGroup)
.enter()
.append("div")
.attr("class", "voyageData")
.attr("data-group", function(d){return d.key})
.attr("id", function(d){return "voyageText_" + d.key})
var data = testData.selectAll(".data")
.data(function(d) {return d.values;})
.enter()
.append("div")
.attr("class", "data")
.attr("id", function(d){return "data_" + d.key})
var images = testData.selectAll(".images")
.data(function(d) {return d.values;})
images.exit().remove();
images.enter()
.append("div")
.attr("class", "images")
.attr("id", function(d){return "images_" + d.key})

//buttons
d3.select("#button_1906").on("click", function(d){
clickButton(d,i);
});
d3.select("#button_1845").on("click", function(d){
clickButton(d,i);
});
function clickButton(d,i) {
var voyageClass = d.key;
var voyageID = d.values[0].key;

//animate place name and dates
var j = 0;
var animation = setInterval(function(){
d3.select("#data_"+ voyageID)
.text(function(d) { return d.values[j].arrivalDateTxt +" "+d.values[j].placeName; });
j = j + 1;
if(j==d.values[0].values.length)
clearInterval(animation)
if(j==d.values[0].values.length)
d3.select("#data_"+ voyageID)
.text("") // is there a better way to stop or remove text on completion of animation? I am just replacing it with an empty string.
},1000);
//add image
d3.select("#images_" + voyageID)
.append("img")
.attr("src", function(d){return  d.values[j].groupPic })
.attr("width", "40")
//how do I remove image on completion of animation or click of new button?
}
});
}
</script>
</body>
</html>

这是我的示例 csv:

VoyageID,arrivalDateTxt,year,placeName,groupPic
1,14 January 1906,1906,Place 1,ANMS1113[006].jpg
1,1 May 1907,1906,Place 2,ANMS1113[006].jpg
1,26 October 1907,1906,Place 3,ANMS1113[006].jpg
1,4 November 1907,1906,Place 4,ANMS1113[006].jpg
1,26 November 1907,1906,Place 5,ANMS1113[006].jpg
1,3 December 1907,1906,Place 6,ANMS1113[006].jpg
1,10 December 1907,1906,Place 7,ANMS1113[006].jpg
1,20 December 1907,1906,Place 8,ANMS1113[006].jpg
1,26 December 1907,1906,Place 9,ANMS1113[006].jpg
3,12 March 1845,1845,Island 1,00038301_4.jpg
3,15 March 1845,1845,Island 2,00038301_4.jpg
3,22 March 1845,1845,Place in ocean 3,00038301_4.jpg
3,23 July 1845,1845,Place in ocean 4,00038301_4.jpg
3,19 December 1845,1845,Place in ocean 5,00038301_4.jpg
3,22 January 1846,1845,Place in ocean 6,00038301_4.jpg
3,30 January 1846,1845,Back home,00038301_4.jpg

我非常希望有人可以帮助我,帮助我以更 D3 的方式改进我的代码。

提前感谢,莎莉

要在完成后删除图像,您可以使用:

//animate place name and dates
var j = 0;
var animation = setInterval(function(){
d3.select("#data_"+ voyageID)
.text(function(d) { return d.values[j].arrivalDateTxt +" "+d.values[j].placeName; });
j = j + 1;
if(j==d.values[0].values.length) {
clearInterval(animation);
d3.select("#data_"+ voyageID).text("");
d3.select("#images_" + voyageID).select("img").remove();
}
},1000);

设置.text("")会像动画之前一样恢复状态/DOM,所以我认为这没有问题。

要停止动画,您必须跟踪上一个动画

var runningAnimation = null;
function stopAnimation(animation, voyageID) {
clearInterval(animation);
d3.select("#data_"+ voyageID).text(""); // is there a better way to stop or remove text on completion of animation? I am just replacing it with an empty string.
d3.select("#images_" + voyageID).select("img").remove();
runningAnimation = null;
}
function clickButton(d,i) {
if (runningAnimation) { stopAnimation(runningAnimation.animation, runningAnimation.voyageID); }
var voyageClass = d.key;
var voyageID = d.values[0].key;
//animate place name and dates
var j = 0;
var animation = setInterval(function(){
d3.select("#data_"+ voyageID)
.text(function(d) { return d.values[j].arrivalDateTxt +" "+d.values[j].placeName; });
j = j + 1;
if(j==d.values[0].values.length) { stopAnimation(animation, voyageID); }
},1000);
runningAnimation = { animation: animation, voyageID: voyageID };
//add image
d3.select("#images_" + voyageID)
.append("img")
.attr("src", function(d){return  d.values[j].groupPic })
.attr("width", "40");
}

可以简化按钮单击处理程序的设置

buttons.on("click", clickButton);
//buttons
// d3.select("#button_1906").on("click", function(d){
//   clickButton(d,i);
// });
// d3.select("#button_1845").on("click", function(d){
//   clickButton(d,i);
// });

最新更新