摘要:以的方式來思考聲明原文鏈接來自作者譯文地址如果覺得還不錯不妨去給個打個比方你想用畫一個散點(diǎn)圖用每一個的元素來可視化你的數(shù)據(jù)你會驚訝的發(fā)現(xiàn)居然沒有直接創(chuàng)建多個元素的方法怎么回事當(dāng)然有方法你可以用來創(chuàng)建單個元素比如但這只是一個圓如果你想要創(chuàng)建很
以 Join 的方式來思考D3.js 聲明
原文鏈接: 來自 D3作者 Mike Bostock https://bost.ocks.org/mike/join/
譯文地址: github repository
如果覺得還不錯, 不妨去github給個star ?
Content打個比方, 你想用D3畫一個 散點(diǎn)圖 , 用每一個svg的circle元素來可視化你的數(shù)據(jù). 你會驚訝的發(fā)現(xiàn): D3居然沒有直接創(chuàng)建多個DOM元素的方法! 怎么回事?
當(dāng)然, D3有 append 方法, 你可以用來創(chuàng)建單個元素. 比如:
svg.append("circle") .attr("cx", d.x) .attr("cy", d.y) .attr("r", 2.5);
但這只是一個圓, 如果你想要創(chuàng)建很多個圓(每一個圓代表一個數(shù)據(jù)點(diǎn)). 你可能會想到用一個for循環(huán)來實(shí)現(xiàn) ? 這是非常直觀的想法, 這個想法并沒有什么錯, 但是在這之前不妨看看D3中是如何實(shí)現(xiàn)創(chuàng)建多個元素的:
svg.selectAll("circle") .data(data) .enter().append("circle") .attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }) .attr("r", 2.5);
上面這段代碼完美的實(shí)現(xiàn)了你想要的效果: 為每一個數(shù)據(jù)點(diǎn)創(chuàng)建了一個 circle, 用數(shù)據(jù)點(diǎn)的 x 和 y 屬性作為circle的坐標(biāo). 但這段代碼里面的 selectAll("circle") 是什么意思? 我們?yōu)槭裁匆?select 我們知道當(dāng)前并不存在的 circle, 還用這個方法的返回值去創(chuàng)建新的元素?
這段代碼的思想是: 不要告訴D3如何去做, 而是告訴D3你想要的效果. 你想要circle元素和數(shù)據(jù)一一對應(yīng), 那么你就不應(yīng)該告訴D3去創(chuàng)建circle元素, 而是告訴D3: .selectAll("circle") 得到的circle集合應(yīng)該和 .data(data) 一一對應(yīng). 這個思想就叫做 Join.
從上圖中可以看到:
數(shù)據(jù)集合 和 DOM元素集合 相交產(chǎn)生了中間的 update 集合
沒有DOM元素與之對應(yīng)的Data產(chǎn)生了左邊的 enter 集合 (也就是缺失DOM元素)
同樣的, 所有沒有數(shù)據(jù)與之對應(yīng)的DOM元素產(chǎn)生了右邊的 exit 集合 (也就意味著這些DOM元素將被移除)
現(xiàn)在我們可以再來看看上面那段使用 enter-append 模型的代碼了:
首先, svg.selectAll("circle") 返回的是一個空的集合, 因?yàn)楫?dāng)前 svg 容器還是空的. 這里的 svg 是所有后續(xù)創(chuàng)建的 circle元素的父節(jié)點(diǎn).
svg.selectAll("circle") 返回的集合接下來和 data 進(jìn)行 Join 操作, 得到的就是我們上面提到的三個集合: update 集合 , enter 集合 , exit 集合. 因?yàn)槌跏紩r Elements集合(也就是circle集合)是空的, 所以 update 和 exit 集合為空, 而 enter 集合會自動為每一個新的data元素生成一個占位符.
默認(rèn) .data(data) 返回的是 update 集合, 因?yàn)?update 集合為空, 所以我們不對其進(jìn)行操作, 這里我們調(diào)用 .enter() 得到 enter 集合.
接下來, 對于 enter 集合中的每一個元素, 我們使用 selection.append("circle") (值得注意的是, 對集合的操作會被應(yīng)用到集合中的每一個元素上去). 這樣就為每一個數(shù)據(jù)點(diǎn)創(chuàng)建了一個 circle (這些circle都在他們的父節(jié)點(diǎn) svg 中)
用 Join 的方式來思考意味著, 我們要做的事情僅僅是聲明 DOM集合(比如這里的 circle 集合) 和數(shù)據(jù)集合之間的關(guān)系, 并且通過處理三個不同狀態(tài)的集合 enter, update , exit 來描述這種關(guān)系.
你也許會問, 為什么要用這種方式來進(jìn)行我的數(shù)據(jù)可視化工作呢? 好處在哪? 為什么我不直接用for循環(huán)創(chuàng)建所有我想要的元素? 答案是這個思想確實(shí)是非常有好處的, 它的優(yōu)美之處在于它的概括性. 現(xiàn)在我們的代碼還只是處理了 enter 的部分, 這部分對于展示靜態(tài)的數(shù)據(jù)已經(jīng)足夠了, 但如果你想進(jìn)行動態(tài)的數(shù)據(jù)展示, 這種 Join 的方式將大大簡化你的工作, 你只需要對 update 和 exit 進(jìn)行很少的操作就能得到你想要的效果. 這也意味著你可以輕松的展示實(shí)時數(shù)據(jù), 能夠?yàn)橛脩籼砑觿討B(tài)的交互, 能平滑的切換不同的展示數(shù)據(jù)集.
下面這段代碼展示了對于 exit 和 update 集合的處理:
var circle = svg.selectAll("circle") .data(data); circle.exit().remove(); circle.enter().append("circle") .attr("r", 2.5) .merge(circle) .attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; });
無論什么時候上面的這段代碼被執(zhí)行, 它都將重新計算 Join 并且維護(hù)好 DOM元素集合 和 數(shù)據(jù)集合 之間的對應(yīng)關(guān)系. 如果你的新數(shù)據(jù)集比之前老的數(shù)據(jù)集要小, 多余的DOM元素就會進(jìn)入 exit 集合, 然后被 remove掉. 如果新的數(shù)據(jù)集比老的大, 那么新的數(shù)據(jù)就將進(jìn)入 enter 集合, 并創(chuàng)建出新的DOM元素. 如果新的數(shù)據(jù)集和老的數(shù)目相同, 那么只有 update 集合會被更新坐標(biāo).
使用 Join 的思想能讓我們的代碼更加直觀. 你只需要處理好這三種狀態(tài)的集合, 而不需要 if 和 for 來進(jìn)行復(fù)雜的邏輯判斷. 你只需要描述好你的數(shù)據(jù)集合和DOM集合想要有怎樣的對應(yīng)關(guān)系.
Join 還讓你可以對不同狀態(tài)的DOM元素進(jìn)行不同的操作. 比如, 你可以只對 enter 集合進(jìn)行操作, 這樣就不會每次都對所有的 DOM元素進(jìn)行更新, 這能顯著的提升你的數(shù)據(jù)可視化作品的渲染效率.
同樣的, 你也可以給指定集合的元素添加動畫效果, 比如給 enter 的元素添加放大進(jìn)入的效果:
circle.enter().append("circle") .attr("r", 0) .transition() .attr("r", 2.5);
或者給 exit 的集合添加 縮小隱藏 的效果:
circle.exit().transition() .attr("r", 0) .remove();譯者注:
這里有一個非常好的實(shí)踐 Join 思想的例子(同樣來自D3作者), 不妨看看:
Mike Bostock 的實(shí)現(xiàn)
這里是我對這個例子的實(shí)現(xiàn)(也包括一些其他的案例):在線演示
源代碼
想繼續(xù)了解 D3.js這里是我的 D3.js 、 數(shù)據(jù)可視化 的github 地址, 歡迎 start & fork
D3-blog
如果覺得不錯的話, 不妨點(diǎn)擊下面的鏈接關(guān)注一下 : )github主頁
知乎專欄
掘金
想直接聯(lián)系我 ?郵箱: ssthouse@163.com
微信:
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/95410.html
摘要:本篇的使用的版本為將按照簡要介紹實(shí)驗(yàn)及意義進(jìn)行簡要通過數(shù)據(jù)綁定創(chuàng)建,更新及銷毀元素,如何操作元素則是通過。 本篇blog的使用的d3版本為d3.js v5.9.2 將按照簡要介紹、實(shí)驗(yàn)及意義進(jìn)行 簡要 d3.js通過data join(數(shù)據(jù)綁定)創(chuàng)建,更新及銷毀元素,如何操作元素則是通過selection。總結(jié)如下 showImg(https://segmentfault.com/...
摘要:入門,根據(jù)官網(wǎng)部分教程學(xué)習(xí),發(fā)現(xiàn)因?yàn)榘姹靖拢行┖透拍羁赡懿贿m用,但總體思想未變。 入門d3.js,根據(jù)官網(wǎng)部分教程學(xué)習(xí),發(fā)現(xiàn)因?yàn)榘姹靖拢行゛pi和概念可能不適用,但總體思想未變。本文思路跟隨此篇blogLet’s Make a Bar Chart學(xué)習(xí),加上自己的理解,并且查閱了部分更新資料 元素選擇 d3通過d3.select()或者d3.selectAll()獲取元素,這兩個...
摘要:數(shù)據(jù)可視化圖表圖表作為數(shù)據(jù)可視化最常見的表現(xiàn)形式之一,往往被以偏概全的認(rèn)為圖表就是數(shù)據(jù)可視化。嚴(yán)格來說,數(shù)據(jù)可視化應(yīng)該是連接數(shù)據(jù)與視覺的一個映射關(guān)系,將數(shù)據(jù)映射成人更容易感知其規(guī)律的可視化結(jié)果。 題目中的新一代是個相對的概念,事實(shí)上本文即將介紹的方法已經(jīng)有了生產(chǎn)環(huán)境可用的實(shí)現(xiàn)方案(這也側(cè)面佐證了其可行性),但考慮到此方法與現(xiàn)在大部分前端項(xiàng)目中所使用的數(shù)據(jù)可視化方案相比仍有一些優(yōu)勢,因此...
摘要:它的全稱是數(shù)據(jù)驅(qū)動文檔,并且它被稱為一個互動和動態(tài)的數(shù)據(jù)可視化庫網(wǎng)絡(luò)。我們將使用文本編輯器和瀏覽器。出于測試目的,建議使用工具來檢查和調(diào)試和,例如或。使矩形反映數(shù)據(jù)目前,我們陣列中的所有矩形沿軸具有相同的位置,并且不代表高度方面的數(shù)據(jù)。 歡迎大家前往騰訊云+社區(qū),獲取更多騰訊海量技術(shù)實(shí)踐干貨哦~ 本文由獨(dú)木橋先生 發(fā)表于云+社區(qū)專欄 介紹 D3.js是一個JavaScript庫。它的...
摘要:在本教程中,我們將探討如何使用和構(gòu)建實(shí)時圖形。通過方法監(jiān)聽輪詢更新,并在收到更新后使用最新數(shù)據(jù)調(diào)用函數(shù),以便重新呈現(xiàn)圖形。 首先你需要在計算機(jī)上安裝Node和npm。 數(shù)據(jù)的可視化表示是傳遞復(fù)雜信息的最有效手段之一,D3.js提供了創(chuàng)建這些數(shù)據(jù)可視化的強(qiáng)大工具和靈活性。 D3.js是一個JavaScript庫,用于使用SVG,HTML和CSS在Web瀏覽器中生成動態(tài)的交互式數(shù)據(jù)可視化。...
閱讀 2585·2019-08-30 10:53
閱讀 3189·2019-08-29 16:20
閱讀 2942·2019-08-29 15:35
閱讀 1765·2019-08-29 12:24
閱讀 2871·2019-08-28 18:19
閱讀 1848·2019-08-23 18:07
閱讀 2327·2019-08-23 15:31
閱讀 1166·2019-08-23 14:05