|
載入圖表時,動畫可以將注意力集中在重要的事情上。我們的視覺對運動非常敏感,因此明智地使用這些介紹過渡有助於減輕從圖表中獲取正確資訊所需的工作量。
比較這兩個圖表:
哪個更能吸引觀眾對最後一個小節的注意力?
[示例旁註:它們都使用相同的模型。單擊該按鈕即可開始動畫。如果圖表上沒有任何內容,單擊按鈕就會出現一些內容。]
動畫與生長、擴充套件、移動、縮小等隱喻配合得很好,因此它可以真正增強試圖傳達這些想法的視覺化的表現力。
也就是說,動畫肯定也會毀掉你的視覺化效果。以下是三個普遍問題。
動畫效果非常突出。這可以很好地引起人們對星盤中特定的、明確的部分的注意。但是當動畫太多時會發生什麼?如果沒有其他線索,觀眾就很難確定將注意力集中在哪裡。
跨多個狀態的動畫(例如動畫資料的視訊)使得它們很難相互比較,這與並排顯示不同狀態的靜態影象相反。
如果動畫不連續,如果圖表在動畫過程中以某種方式被擦除,這會導致變化盲目性,這幾乎否定了您可能希望從動畫中獲得的任何好處。請看這個示例:
當設定動畫時,線條會經歷空白狀態,這使得幾乎不可能跟蹤原始狀態和最終狀態之間的變化。檢測變化的唯一方法是專注於一個給定點並記住其原始位置,但這非常低效。
現在該怎麼辦呢?
我們已經看到了動畫在資料視覺化中的作用。現在,讓我們開始吧!為此,我們使用d3。d3 在資料動畫方面有很多很多的可能性,而且實現起來相對容易。
原則
如果您知道如何在 d3 中繪圖,那麼您幾乎就知道如何製作動畫了。(如果您還不知道,Alignedleft有一系列精彩的教程可以幫助您入門,d3 站點列出了更多內容,其中包括您真正編寫的一些。) 動畫在 d3 中被稱為“過渡”是有原因的。動畫的技術定義可以是,在一定的時間間隔內,物件的一個或多個特徵將從一個值轉變為另一個值。就特徵而言,我們指的是任何可以用數字表示的東西。
幾個過渡的例子
毫不奇怪,當您隨著時間的推移平穩地更新某個專案的位置時,它就會移動。在 svg 中,大多數形狀的位置是由 x 和 y 屬性確定的,例如這裡的藍色矩形,它們對應於形狀的左上角。對於圓,您可以使用 cx 和 cy,或中心座標。對於路徑,例如我們的紅色三角形,您實際上指定“d”屬性中所有點的位置。
同樣,當您更改大小時,物件會增大(或縮小)。您可以使用寬度和高度來表示矩形等形狀,或使用 r 來表示圓形。
顏色實際上也是一個數字屬性,並且確實可以(並且非常有用)從一種顏色過渡到另一種顏色。在 svg 中,顏色是由填充或描邊定義的樣式屬性。
與顏色不同,能夠改變不透明度非常有用。當不透明度設定為0時,對應的物件是完全透明的。因此,不透明度的過渡對於使物件淡入或淡出非常有用。
這是如何完成的
現在我們已經瞭解了轉換的功能,接下來讓我們看看如何在 d3 中對其進行編碼。讓我們回到第一個例子。事實上,讓我們讓它變得更簡單。
要在 d3 中建立這樣的正方形,我們可以編寫如下內容:
var mySquare=svg.append("矩形") .attr("x",60) .attr("y",60) .attr("寬度",60) .attr("高度",60);
4個屬性。夠簡單的。因此,如果我們想讓它向右移動,我們將更新 x 屬性。我們就是這樣做的:
mySquare .transition() .attr("x",320);
就這麼簡單:使用轉換方法,然後指定您想要看到的所有更改,就像建立新專案一樣。利用這一原則,我們可以輕鬆地重現上述任何示例。
mySquare .transition() .attr("寬度",120); // 會讓它變大 mySquare .style("fill","white") // 如果填充最初留空並且來自 // 樣式表,它將以黑色開始 .transition() .style("fill “,“藍色的”); mySquare .transition() .style("不透明度",0);
現在,在我們的簡單示例中,情況並非如此。轉換髮生在事件之後,即使用者單擊按鈕時。事實上,當與事件和互動相關時,過渡是最有用的。但這並沒有增加全新的複雜性。我們可以這樣寫:
Button.on("點選", function() { mySquare.transition().attr("x",320); })
現在,我們的動畫僅在單擊按鈕時才開始。顯然,由於轉換是在函式內進行的,我們甚至可以以程式設計方式確定正方形應該去哪裡,但讓我們在示例中保持簡單。
動畫102
到目前為止,我們已經瞭解瞭如何在 d3 中製作簡單的動畫,甚至新增一些互動。我們已經看到它實際上就像在同一個地方建立元素一樣簡單。好訊息:d3 中的過渡非常通用,可以通過大量技巧進行自定義,而不會編寫得太複雜。更重要的是知道要做什麼。
使用transition()方法後,可以指定持續時間和延遲的值。持續時間是轉換將持續的毫秒數,而延遲是系統在啟動轉換之前等待的毫秒數。語法是:
mySquare.transition() .attr("x",320) .duration(1000) // 這是 1 秒 .delay(100) // 這是 0.1 秒
預設持續時間為 250 毫秒,無延遲。我覺得 250ms 有點苛刻。在大多數情況下,過渡應該是明顯的,因此我經常發現自己將持續時間增加到 500 或 1000。但除非有充分的理由,否則持續時間工作職能郵件資料庫 不應太長。如果您使用它們來支援您的資料,您不希望讓它們花費幾秒鐘來佔據中心位置。
考慮以下兩個示例(您必須從按鈕開始):
第二個不是太殘忍了嗎?你可能很難相信它只浪費了你 25 秒的時間。
緩動是將時間轉化為屬性變化的實際函式的技術名稱。從前面的示例中,您可能已經注意到,值首先緩慢變化,然後更快,最後緩慢變化。事實證明,您可以使用不同的函式來獲得不同的結果。在我的實踐中,,儘管還有很多其他的。是的,您可以自己編寫,儘管我們不會在這裡討論這一點。語法與上面類似:
mysquare.transition() .attr("x",320) .ease("彈性")
(順便說一句,更改屬性或指定動畫引數的順序沒有影響,因此請隨意先使用 .ease,然後使用 .attr)。
對於路徑物件,通過過渡您可以更新每個點的位置。這使您可以有效地將一種形狀變成另一種形狀。這對於折線圖(或任何路徑圖表)來說尤其有趣。
像這樣,如果效地發現這些變化。相反,如果您只是刪除圖表或重新繪製資料,則很難發現數據發生了變化的位置。對於這兩個示例,路徑的“d”屬性都會更新(因此它們與最簡單的示例沒有本質上的不同)。
有時(實際上,通常是)您希望在另一個轉換之後立即觸發一個轉換。但如果您想知道,以下內容不起作用:
另一種可能性是在轉換完成後刪除物件。這非常有用,特別是當您建立大量臨時物件時。一個有趣的組合是,當您將不透明度一直降低到 0 時,使其不可見,然後如果不再需要它,則使用 remove() 。
|
|
|