javascript - D3 过渡:持续时间不适用于线路路径
问题描述
我是 javascript 的新手,我正在尝试用一条需要 1 秒才能出现的线来为我的图表制作动画(使用.transition().duration(1000)
)。
不幸的是,我无法得到这个结果。.duration(1000)
似乎不适用于线条绘制。
我的摘要
svg.append("path")
.data([data])
.transition().duration(1000)
.attr("class", "line")
.attr("d", valueline(xy));
如果我输入 a .transition().duration(1000).style("color", "red)
,字体会在 1 秒内变为红色。
我的问题:为什么持续时间适用于颜色而不是线条绘制?
如果你能帮助我,我将非常感激!
我你需要我的整个代码,但它在那里:
//VOLCAN FUNCTION
function draw_volcan(url){
d3.select("svg").remove() // remove the old graph
// set the dimensions and margins of the graph
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
d3.json(url, function(error, data) { //chargement des data volcans
if(error) throw ('There was an error while getting geoData: '+error);
//get in an array the occurance of eruptions
var volcans_incidence_annee_2018 = new Array(59).fill(0) // on prépare une array avec pour le nombre d'éruptions de volcan par année
data.forEach(function(d) {
var single_date_index = d.Date-1960 //année-1960 = index où il faudra ajouter 1 pour l'occurence de l'année
volcans_incidence_annee_2018[single_date_index] += 1 //ajoute 1 d'occurance à l'année souhaitée
});
var volcans_incidence_annee = new Array(56).fill(0)
for(i in volcans_incidence_annee_2018){ //créé un array volcans_incidence_annee qui contient les données de 1960 à 2015 uniquement
if(i<56){
volcans_incidence_annee[i] = volcans_incidence_annee_2018[i]
};
};
var year_array = []
for(var i = 1960; i<=2015; i++) {year_array.push(i);} //créé un array avec chaque année
//create array with all the points
var xy=[];
for(var i = 0; i < year_array.length; i++ ) {
xy.push({x: year_array[i], y: volcans_incidence_annee[i]});
};
// set the ranges
var x = d3.scaleLinear().domain([1960, 2015]).range([0, width]);
var y = d3.scaleLinear().domain([Math.min(...volcans_incidence_annee), Math.max(...volcans_incidence_annee)]).range([height, 0]);
// create a line function that can convert data[] into x and y points
var valueline = d3.line()
.x(function(d) { return x(d.x);})
.y(function(d) { return y(d.y);});
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("#graph_draw").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// Add the valueline path.
svg.append("path")
.data([data])
.transition().duration(1000)
.attr("class", "line")
.attr("d", valueline(xy));
// Add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// Add the Y Axis
svg.append("g")
.call(d3.axisLeft(y));
//svg.append("g").attr("d", line(+volcans_incidence_annee));
});
解决方案
In D3, a transition changes a DOM element from an initial state, the source state, to a final state, the target state.
Everything before creating a transition with selection.transition
belongs to the initial state, and everything after it belongs to the desired (target) state.
That said, the issue in your question is quite simple: you cannot interpolate the creation of a class or the definition of the d
attribute. As Bostock (D3 creator) once said:
When modifying the DOM, use selections for any changes that cannot be interpolated; only use transitions for animation. For example, it is impossible to interpolate the creation of an element: it either exists or it doesn’t.
We can clearly see this in the demos below.
It makes no sense transitioning from having no d
attribute to having one:
var d = "M38.8 68.4l37.8 7.9 1.6-7.6-37.8-7.9-1.6 7.6zm5-18l35 16.3 3.2-7-35-16.4-3.2 7.1zm9.7-17.2l29.7 24.7 4.9-5.9-29.7-24.7-4.9 5.9zm19.2-18.3l-6.2 4.6 23 31 6.2-4.6-23-31zM38 86h38.6v-7.7H38V86z";
var d2 = "M84.4 93.8V70.6h7.7v30.9H22.6V70.6h7.7v23.2z";
var svg = d3.select("svg");
var path = svg.append("path")
.style("fill", "#f48023")
.transition()
.duration(1000)
.attr("d", d)
var path2 = svg.append("path")
.style("fill", "#bcbbbb")
.transition()
.duration(1000)
.attr("d", d2)
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>
However, we can transition from 0
opacity to 1
:
var d = "M38.8 68.4l37.8 7.9 1.6-7.6-37.8-7.9-1.6 7.6zm5-18l35 16.3 3.2-7-35-16.4-3.2 7.1zm9.7-17.2l29.7 24.7 4.9-5.9-29.7-24.7-4.9 5.9zm19.2-18.3l-6.2 4.6 23 31 6.2-4.6-23-31zM38 86h38.6v-7.7H38V86z";
var d2 = "M84.4 93.8V70.6h7.7v30.9H22.6V70.6h7.7v23.2z";
var svg = d3.select("svg");
var path = svg.append("path")
.style("fill", "#f48023")
.attr("d", d)
.style("opacity", 0)
.transition()
.duration(1000)
.style("opacity", 1);
var path2 = svg.append("path")
.style("fill", "#bcbbbb")
.attr("d", d2)
.style("opacity", 0)
.transition()
.duration(1000)
.style("opacity", 1);
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>
推荐阅读
- javascript - 将 observable 转换为数组
- java - 如何在 Spring Boot 的 application.properties 中指定外部属性文件?
- c# - 我正在做一个 Xamarin 跨平台项目,无法在我的 UI 上显示 uri 图像。我总是收到一个错误,说位图太大
- javascript - 为什么我的角色动作感觉不对?
- ios - 每次单击按钮时如何更改标签文本上的int值
- c - 使用 autotools 时原始 .h 文件会发生什么情况?
- postgresql - postgresql:dockerfile 从入口点脚本创建用户和数据库
- java - 如何比较 2 个不同的列表
? - python - Python包安装问题:终端(Anaconda Prompt)和Jupyter Notebook上的安装检查之间的差异
- google-chrome-extension - 如何动态更改 chrome 扩展的图标?