成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

以 Join 的方式來思考D3.js

mikasa / 3114人閱讀

摘要:以的方式來思考聲明原文鏈接來自作者譯文地址如果覺得還不錯不妨去給個打個比方你想用畫一個散點圖用每一個的元素來可視化你的數(shù)據(jù)你會驚訝的發(fā)現(xiàn)居然沒有直接創(chuàng)建多個元素的方法怎么回事當然有方法你可以用來創(chuàng)建單個元素比如但這只是一個圓如果你想要創(chuàng)建很

Join 的方式來思考D3.js 聲明

原文鏈接: 來自 D3作者 Mike Bostock https://bost.ocks.org/mike/join/

譯文地址: github repository

如果覺得還不錯, 不妨去github給個star ?

Content

打個比方, 你想用D3畫一個 散點圖 , 用每一個svg的circle元素來可視化你的數(shù)據(jù). 你會驚訝的發(fā)現(xiàn): D3居然沒有直接創(chuàng)建多個DOM元素的方法! 怎么回事?

當然, D3有 append 方法, 你可以用來創(chuàng)建單個元素. 比如:

svg.append("circle")
    .attr("cx", d.x)
    .attr("cy", d.y)
    .attr("r", 2.5);

但這只是一個圓, 如果你想要創(chuàng)建很多個圓(每一個圓代表一個數(shù)據(jù)點). 你可能會想到用一個for循環(huán)來實現(xiàn) ? 這是非常直觀的想法, 這個想法并沒有什么錯, 但是在這之前不妨看看D3中是如何實現(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);

上面這段代碼完美的實現(xiàn)了你想要的效果: 為每一個數(shù)據(jù)點創(chuàng)建了一個 circle, 用數(shù)據(jù)點的 xy 屬性作為circle的坐標. 但這段代碼里面的 selectAll("circle") 是什么意思? 我們?yōu)槭裁匆?select 我們知道當前并不存在的 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") 返回的是一個空的集合, 因為當前 svg 容器還是空的. 這里的 svg 是所有后續(xù)創(chuàng)建的 circle元素的父節(jié)點.

svg.selectAll("circle") 返回的集合接下來和 data 進行 Join 操作, 得到的就是我們上面提到的三個集合: update 集合 , enter 集合 , exit 集合. 因為初始時 Elements集合(也就是circle集合)是空的, 所以 updateexit 集合為空, 而 enter 集合會自動為每一個新的data元素生成一個占位符.

默認 .data(data) 返回的是 update 集合, 因為 update 集合為空, 所以我們不對其進行操作, 這里我們調(diào)用 .enter() 得到 enter 集合.

接下來, 對于 enter 集合中的每一個元素, 我們使用 selection.append("circle") (值得注意的是, 對集合的操作會被應(yīng)用到集合中的每一個元素上去). 這樣就為每一個數(shù)據(jù)點創(chuàng)建了一個 circle (這些circle都在他們的父節(jié)點 svg 中)

Join 的方式來思考意味著, 我們要做的事情僅僅是聲明 DOM集合(比如這里的 circle 集合) 和數(shù)據(jù)集合之間的關(guān)系, 并且通過處理三個不同狀態(tài)的集合 enter, update , exit 來描述這種關(guān)系.

你也許會問, 為什么要用這種方式來進行我的數(shù)據(jù)可視化工作呢? 好處在哪? 為什么我不直接用for循環(huán)創(chuàng)建所有我想要的元素? 答案是這個思想確實是非常有好處的, 它的優(yōu)美之處在于它的概括性. 現(xiàn)在我們的代碼還只是處理了 enter 的部分, 這部分對于展示靜態(tài)的數(shù)據(jù)已經(jīng)足夠了, 但如果你想進行動態(tài)的數(shù)據(jù)展示, 這種 Join 的方式將大大簡化你的工作, 你只需要對 updateexit 進行很少的操作就能得到你想要的效果. 這也意味著你可以輕松的展示實時數(shù)據(jù), 能夠為用戶添加動態(tài)的交互, 能平滑的切換不同的展示數(shù)據(jù)集.

下面這段代碼展示了對于 exitupdate 集合的處理:

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 并且維護好 DOM元素集合 和 數(shù)據(jù)集合 之間的對應(yīng)關(guān)系. 如果你的新數(shù)據(jù)集比之前老的數(shù)據(jù)集要小, 多余的DOM元素就會進入 exit 集合, 然后被 remove掉. 如果新的數(shù)據(jù)集比老的大, 那么新的數(shù)據(jù)就將進入 enter 集合, 并創(chuàng)建出新的DOM元素. 如果新的數(shù)據(jù)集和老的數(shù)目相同, 那么只有 update 集合會被更新坐標.

使用 Join 的思想能讓我們的代碼更加直觀. 你只需要處理好這三種狀態(tài)的集合, 而不需要 iffor 來進行復(fù)雜的邏輯判斷. 你只需要描述好你的數(shù)據(jù)集合和DOM集合想要有怎樣的對應(yīng)關(guān)系.

Join 還讓你可以對不同狀態(tài)的DOM元素進行不同的操作. 比如, 你可以只對 enter 集合進行操作, 這樣就不會每次都對所有的 DOM元素進行更新, 這能顯著的提升你的數(shù)據(jù)可視化作品的渲染效率.
同樣的, 你也可以給指定集合的元素添加動畫效果, 比如給 enter 的元素添加放大進入的效果:

circle.enter().append("circle")
    .attr("r", 0)
  .transition()
    .attr("r", 2.5);

或者給 exit 的集合添加 縮小隱藏 的效果:

circle.exit().transition()
    .attr("r", 0)
    .remove();
譯者注:

這里有一個非常好的實踐 Join 思想的例子(同樣來自D3作者), 不妨看看:

Mike Bostock 的實現(xiàn)

這里是我對這個例子的實現(xiàn)(也包括一些其他的案例):

在線演示

源代碼

想繼續(xù)了解 D3.js

這里是我的 D3.js 、 數(shù)據(jù)可視化 的github 地址, 歡迎 start & fork

D3-blog

如果覺得不錯的話, 不妨點擊下面的鏈接關(guān)注一下 : )

github主頁

知乎專欄

掘金

想直接聯(lián)系我 ?

郵箱: [email protected]

微信:

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/95410.html

相關(guān)文章

  • d3數(shù)據(jù)綁定與selection實踐

    摘要:本篇的使用的版本為將按照簡要介紹實驗及意義進行簡要通過數(shù)據(jù)綁定創(chuàng)建,更新及銷毀元素,如何操作元素則是通過。 本篇blog的使用的d3版本為d3.js v5.9.2 將按照簡要介紹、實驗及意義進行 簡要 d3.js通過data join(數(shù)據(jù)綁定)創(chuàng)建,更新及銷毀元素,如何操作元素則是通過selection??偨Y(jié)如下 showImg(https://segmentfault.com/...

    Tangpj 評論0 收藏0
  • d3.js入門——selection與創(chuàng)建條形圖

    摘要:入門,根據(jù)官網(wǎng)部分教程學(xué)習(xí),發(fā)現(xiàn)因為版本更新,有些和概念可能不適用,但總體思想未變。 入門d3.js,根據(jù)官網(wǎng)部分教程學(xué)習(xí),發(fā)現(xiàn)因為版本更新,有些api和概念可能不適用,但總體思想未變。本文思路跟隨此篇blogLet’s Make a Bar Chart學(xué)習(xí),加上自己的理解,并且查閱了部分更新資料 元素選擇 d3通過d3.select()或者d3.selectAll()獲取元素,這兩個...

    yanbingyun1990 評論0 收藏0
  • 聲明式與響應(yīng)式——前端新一代數(shù)據(jù)可視化方案

    摘要:數(shù)據(jù)可視化圖表圖表作為數(shù)據(jù)可視化最常見的表現(xiàn)形式之一,往往被以偏概全的認為圖表就是數(shù)據(jù)可視化。嚴格來說,數(shù)據(jù)可視化應(yīng)該是連接數(shù)據(jù)與視覺的一個映射關(guān)系,將數(shù)據(jù)映射成人更容易感知其規(guī)律的可視化結(jié)果。 題目中的新一代是個相對的概念,事實上本文即將介紹的方法已經(jīng)有了生產(chǎn)環(huán)境可用的實現(xiàn)方案(這也側(cè)面佐證了其可行性),但考慮到此方法與現(xiàn)在大部分前端項目中所使用的數(shù)據(jù)可視化方案相比仍有一些優(yōu)勢,因此...

    xuhong 評論0 收藏0
  • 使用JavaScript和D3.js實現(xiàn)數(shù)據(jù)可視化

    摘要:它的全稱是數(shù)據(jù)驅(qū)動文檔,并且它被稱為一個互動和動態(tài)的數(shù)據(jù)可視化庫網(wǎng)絡(luò)。我們將使用文本編輯器和瀏覽器。出于測試目的,建議使用工具來檢查和調(diào)試和,例如或。使矩形反映數(shù)據(jù)目前,我們陣列中的所有矩形沿軸具有相同的位置,并且不代表高度方面的數(shù)據(jù)。 歡迎大家前往騰訊云+社區(qū),獲取更多騰訊海量技術(shù)實踐干貨哦~ 本文由獨木橋先生 發(fā)表于云+社區(qū)專欄 介紹 D3.js是一個JavaScript庫。它的...

    mingde 評論0 收藏0
  • 使用D3.js構(gòu)建實時圖形

    摘要:在本教程中,我們將探討如何使用和構(gòu)建實時圖形。通過方法監(jiān)聽輪詢更新,并在收到更新后使用最新數(shù)據(jù)調(diào)用函數(shù),以便重新呈現(xiàn)圖形。 首先你需要在計算機上安裝Node和npm。 數(shù)據(jù)的可視化表示是傳遞復(fù)雜信息的最有效手段之一,D3.js提供了創(chuàng)建這些數(shù)據(jù)可視化的強大工具和靈活性。 D3.js是一個JavaScript庫,用于使用SVG,HTML和CSS在Web瀏覽器中生成動態(tài)的交互式數(shù)據(jù)可視化。...

    Ryan_Li 評論0 收藏0

發(fā)表評論

0條評論

mikasa

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<