過渡(Transitions)
D3 過渡可以在不同圖表狀態(tài)之間平滑地制作動畫敬惦。
-
創(chuàng)建D3過渡:在要轉換的和方法之前添加一個
.transition()
調用:.attr
、.style
function update() { d3.select('svg') .selectAll('circle') .data(data) .join('circle') .attr('cy', 50) .transition() .attr('cx', function(d) { return d.x; }) .attr('r', function(d) { return d.r; }) .style('fill', function(d) { return d.fill; }); }
-
持續(xù)時間和延遲:可以通過調用
.duration
來更改轉換的持續(xù)時間面睛。該.duration
方法接受一個參數痰滋,該參數以毫秒為單位指定持續(xù)時間;延遲通常用于將選擇中的每個元素延遲不同的量沪饺〖使颍可以通過將函數.delay
傳入并將延遲設置為元素索引的倍數來創(chuàng)建交錯轉換d3.select('svg') .selectAll('circle') .data(data) .join('circle') .attr('cy', 50) .attr('r', 40) .transition() .duration(2000) .attr('cx', function(d) { return d; });
d3.select('svg') .selectAll('circle') .data(data) .join('circle') .attr('cy', 50) .attr('r', 40) .transition() .delay(function(d, i) { return i * 75; }) .attr('cx', function(d) { return d; });
-
緩動函數:定義了元素在過渡期間的速度變化商佛。例如,一些緩動函數會導致元素快速啟動并逐漸變慢垫卤。其他人則相反(開始緩慢并加速),或者是定義特殊效果出牧,例如彈跳穴肘。D3 有許多內置的緩動函數。
一般來說舔痕,“in”是指運動的開始评抚,“out”是指運動的結束。因此伯复,
easeBounceOut
導致元素在過渡結束時反彈慨代。easeBounceInOut
使元素在過渡的開始和結束時反彈。d3.select('svg') .selectAll('circle') .data(data) .join('circle') .attr('cy', 50) .attr('r', 40) .transition() .ease(d3.easeBounceOut) .attr('cx', function(d) { return d; });
-
鏈式轉換:可以通過添加多個調用鏈接在一起
.transition
啸如。每個過渡都將輪流進行侍匙。(當第一個過渡結束時,第二個將開始叮雳,依此類推想暗。)function update() { d3.select('svg') .selectAll('circle') .data(data) .join('circle') .attr('cy', 50) .transition() .attr('cx', function(d) { return d.x; }) .transition() .duration(750) .ease(d3.easeBounce) .attr('r', function(d) { return d.r; }); }
-
.tween:自定義元素所采用的路徑(例如沿著大圓的圓周)。需要將一個名稱(可以是您喜歡的任何名稱)和一個函數傳遞給
.tween
帘不。該函數會被選擇中的每個元素調用一次说莫。它必須返回一個函數,該函數將在轉換的每個步驟中被調用寞焙。t
將0 到 1 之間的值傳遞給tween函數储狭。(t
在過渡開始時為 0,在結束時為 1捣郊。)let data = [], majorRadius = 100; function updateData() { data = [Math.random() * 2 * Math.PI]; } function getCurrentAngle(el) { // Compute the current angle from the current values of cx and cy let x = d3.select(el).attr('cx'); let y = d3.select(el).attr('cy'); return Math.atan2(y, x); } function update() { d3.select('svg g') .selectAll('circle') .data(data) .join('circle') .attr('r', 7) .transition() .tween('circumference', function(d) { let currentAngle = getCurrentAngle(this); let targetAngle = d; // Create an interpolator function let i = d3.interpolate(currentAngle, targetAngle); return function(t) { let angle = i(t); d3.select(this) .attr('cx', majorRadius * Math.cos(angle)) .attr('cy', majorRadius * Math.sin(angle)); }; }); }