做集團(tuán)網(wǎng)站的營(yíng)銷型網(wǎng)站的類型有哪些
D3:Data-Driven Documents
? 通過D3提供的接口來基于數(shù)據(jù)操控文檔的各個(gè)圖元。
標(biāo)題對(duì)于D3(本講解)最為重要的標(biāo)簽,主要操作的對(duì)象(畫布)
HTML - 導(dǎo)入D3.js
D3.js作為JavaScript的外庫,必須先將其導(dǎo)入,如:
-
Python的import,C/C++的include、
-
Java的import、node.js的require… … …
-
通過Script標(biāo)簽導(dǎo)入
- 直接通過互聯(lián)網(wǎng)鏈接
https://d3js.org/d3.v5.min.js - 通過本地服務(wù)器鏈接(推薦)
./d3.min.js - 通過unpkg鏈接
https://unpkg.com/browse/d3@5.15.0/dist/d3.js
盡可能使用本地的d3.min.js庫。
- 直接通過互聯(lián)網(wǎng)鏈接
svg-可縮放矢量模型
- svg d3用來繪制的"畫布"
- 可縮放矢量圖形(英語:scalable vector graphics,svg)
- svg是d3.js主要操作的對(duì)象
- const svg=de3.select(‘svg’)
- d3.js獲取svg對(duì)象
- svg同時(shí)也是一個(gè)容器,用于包含畫在上面的各個(gè)圖元
- svg作為矢量圖,不會(huì)隨著圖片的縮放而發(fā)生失真
引入svg
<svg height="200" width="200" style="display:block;margin:0 auto"><g transfrom="translate(0,60)"><rect width=100 height=100 fill="#eee" /><circle r=15 fill="#72bf67" cx=25 cy=30></circle><circle r=15 fill="RGB(100,149,237)" cx=75 cy=30></circle><g transform="translate(15,60) rotate(10)"><path d="M0,0 A40,40 10 0,0 65,0" fill="none" stroke="gray" stroke-width=5></path></g></g></svg>
HTML–文檔對(duì)象模型
- HTML -> DOM
- DOM -> Document Object Model
- 對(duì)于根節(jié)點(diǎn)的操作會(huì)影響到子節(jié)點(diǎn);
- 最常用的父節(jié)點(diǎn)
- Axis可封裝成一個(gè)group
- Legend(圖例)可封裝成一個(gè)group
https://en.wikipedia.org/wiki/File:DOM-model.svg
JavaScript – D3中的常用接口
- 模板字符串:
- let a = 10;
- let myString =
abc-${a}
; (myString最終為’abc-10’)
- 數(shù)組 a = [1, 2, 3]
- 對(duì)象 a = {name: ‘Shao-Kui’, age: 24.3, lab: ‘cscg’}
- D3數(shù)據(jù)可視化中常見對(duì)象數(shù)組,如:
- a = [{name: ‘Shao-Kui’, age: 25.3, dept: ‘cs’},
- {name: ‘Wen-Yang’, age: 23, dept: ‘cs’},
- {name: ‘Yuan’, age: 29, dept: ‘cs’}]
- D3數(shù)據(jù)可視化中常見對(duì)象數(shù)組,如:
- 數(shù)組的排序 a.sort()
- 可加入回調(diào)函數(shù)來替代缺省的排序方案,如對(duì)日期排序
- a.sort(function(a,b){ return new Date(b.date) - new Date(a.date); }
- 數(shù)組的查詢 a.find( d => d.name === ‘Wen-Yang’)
- 把字符串轉(zhuǎn)換成數(shù)值:+(‘3.14’)
- D3.js經(jīng)常讀取CSV、JSON等文件,會(huì)涉及大量的數(shù)組、對(duì)象的操作!
D3語法基礎(chǔ)概覽
- 使用D3獲取、修改、增加與刪除節(jié)點(diǎn)(圖元)
- 數(shù)據(jù)的讀取 – CSV
- D3.js的數(shù)值計(jì)算。
- 比例尺:
- 線性比例尺(Linear Scale)
- “條帶”比例尺(Band Scale)
- 坐標(biāo)軸的繪制:
- Margin。
- Data-Join基礎(chǔ)
- 基于D3的基礎(chǔ)語法與Data-Join繪制柱狀圖
元素(標(biāo)簽)的標(biāo)識(shí)
- 當(dāng)我們?cè)谝粋€(gè)同學(xué)群體中(比如微信群)對(duì)某些同學(xué)發(fā)出通知時(shí)
- 請(qǐng)學(xué)號(hào)為2020123456的同學(xué)在東主樓集合
- 請(qǐng)計(jì)算機(jī)系研一的同學(xué)在東主樓集合
- 在一個(gè)群體中,索引個(gè)體:
- 通過唯一的標(biāo)識(shí)索引到唯一的個(gè)體
- 通過共同點(diǎn)索引到一批個(gè)體
元素(標(biāo)簽)的標(biāo)識(shí)
- 操作元素首先需要知道元素的標(biāo)識(shí)
- 即要得到已有或已經(jīng)創(chuàng)建的元素
- 元素的ID
- 可以唯一找到元素的標(biāo)識(shí)符
- 元素的Class
- 人為賦予的“類別”可以標(biāo)記元素的集合,其中的元素標(biāo)簽可以不相同!
- 元素的標(biāo)簽
- HTML自帶的標(biāo)簽名稱,可以找到一批同類別的物體,如所有的“矩形”
- 使用自帶的標(biāo)簽往往難以直接索引到目標(biāo)元素
-
, ,
使用D3查詢SVG
- d3.select(…)
- d3.select(‘#rect1’)
- 查詢ID為’rect1’的元素
- #表示后面的字符串是一個(gè)ID
- 只找一個(gè),若有重名也只返回第一個(gè)
- d3.selectAll(…)
- d3.selectAll(‘.class1’)
- 查詢所有class是’class1’的元素
- d3.selectAll(‘rect’)
- 查詢所有標(biāo)簽是’rect’的元素(rect為SVG中的矩形標(biāo)簽)
- 有多少返回多少
- 可配合Data-Join選取‘不存在’的圖元
- ID前加‘#’,Class前加‘.’ ,標(biāo)簽名前不加符號(hào)。
- 基于層級(jí)的查詢:
- d3.select(‘#maingroup rect’)
- d3.selectAll('.tick text’)
- d3.selectAll(‘#secondgroup rect’)
- 如:’#secondgroup rect’
- 首先會(huì)找到id為secondgroup的標(biāo)簽
- 進(jìn)一步找到secondgroup的子標(biāo)簽中是rect的
- 仍然是對(duì)rect做查詢,只是結(jié)果通過父標(biāo)簽做了篩選
- d3.select(…)也可用于查詢類別,如
- d3.select(‘.class1’)
- 但只會(huì)返回找到的第一個(gè)元素
- 因此對(duì)于class、標(biāo)簽名稱的查詢建議使用d3.selectAll
- 對(duì)于特定某一個(gè)元素的查詢建議使用d3.select
使用D3設(shè)置SVG中的屬性
- 常見的屬性
- id, class(特殊的屬性,可以使用.attr設(shè)置)
- x, y, cx, cy
- fill, stroke
- height, width, r (圓的半徑)
- transform -> translate, rotate, scale
- SVG的屬性非常多,且屬性的取值 **范圍&類型 **各不同
- tip1: 盡可能記住一些常見的屬性,以提高編程速度
- tip2: 遇到不認(rèn)識(shí)or想要設(shè)置某個(gè)屬性,一定要查閱
https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute
- 屏幕空間的坐標(biāo)系與常見坐標(biāo)系不同
- 左上方為原點(diǎn)
- Y、X分別垂直向下、水平向右
element.attr(…)
- 設(shè)置元素的屬性: element.attr(‘a(chǎn)ttr_name’, ‘a(chǎn)ttr_value’)
- 兩個(gè)參數(shù):屬性名、設(shè)置的值
- rect1.attr(‘y’, ‘100’)
- d3.select(‘#rect1’).attr(‘y’, ‘100’)
- 獲取元素的屬性: element.attr(‘a(chǎn)ttr_name’)
- 一個(gè)參數(shù):屬性名
- 鏈?zhǔn)秸{(diào)用
- selection.attr(…).attr(…).attr(…)
- .attr(…)返回的是選擇的圖元本身
修改整組屬性
- DOM
- 父節(jié)點(diǎn)的屬性會(huì)影響子節(jié)點(diǎn)
- 子節(jié)點(diǎn)的屬性會(huì)相對(duì)于父節(jié)點(diǎn)
- 下方代碼可以直接移動(dòng)組內(nèi)所有元素
- d3.select('#maingroup’)
- .attr(‘transform’, ‘translate(200, 100)’)
使用D3 添加&**刪除 **SVG元素
- element.append(…)
- const myRect = svg.append(‘rect’);
- const myRect = d3.select(‘#mainsvg’).append(‘rect’)
- const myRect = d3.select(‘#mainsvg’).append(‘rect’).attr(‘x’, ‘100’)
- D3的鏈?zhǔn)教砑?#xff08;調(diào)用)
- const myRect = d3.select(‘#mainsvg’).append(‘g’).attr(‘id’, ‘maingroup’)
- .append(‘rect’).attr(‘fill’, ‘yellow’)
- element.remove()
- 會(huì)移除整個(gè)標(biāo)簽
- Tip:在debug的過程中可以考慮使用’opacity’屬性hack出移除的效果
- element.attr(‘opacity’, ‘0’)
操控SVG
數(shù)據(jù)的讀取 – CSV數(shù)據(jù)
- 第一行為屬性列表,后續(xù)每行對(duì)應(yīng)一‘條’數(shù)據(jù)。
- CSV本質(zhì)上是純文本,區(qū)別于EXCEL的格式。
-
d3.csv(…):
- 讀取目標(biāo)路徑下的某一個(gè)CSV文件。
- 例:d3.csv(‘static/data/hello.csv’);
-
d3.csv是一個(gè)JavaScript異步函數(shù):
- 不可以直接獲得它的返回值,如:
- let myData = d3.csv(‘static/data/hello.csv’); ?
-
d3.csv(‘path/to/data.csv’).then( data => { // ‘?dāng)?shù)據(jù)讀取后的代碼邏輯’ } )
- 要通過.then( **data **=> {…} )的方式來獲得讀取后的數(shù)據(jù)。
- then(…)中的 ‘data => {…}’ 是一個(gè)函數(shù)。
- 此函數(shù)接受的輸入(參數(shù)),即data,為讀取后的數(shù)據(jù)。
-
JavaScript異步機(jī)制
- d3.csv作為異步函數(shù),即便沒有讀取好數(shù)據(jù),后面的代碼也會(huì)繼續(xù)執(zhí)行
- d3.csv被調(diào)用后,其返回值是一個(gè)JavaScript的‘Promise’對(duì)象(object)
- Promise‘詢問’:數(shù)據(jù)讀取好了之后要做什么?‘做什么’即對(duì)應(yīng).then()中函數(shù)的內(nèi)容。
-
代碼調(diào)用示例:
- 讀取后的數(shù)據(jù)格式(接口)與原本的CSV結(jié)構(gòu)不同。
D3.js的數(shù)值計(jì)算
- 數(shù)據(jù)可視化常涉及對(duì)數(shù)據(jù)的處理與計(jì)算:
- 下述三個(gè)接口分別用于計(jì)算數(shù)組的最大值、最小值、[最小值,最大值]。
- d3.max(array)
- 返回?cái)?shù)組中的最大值。
- d3.max([5,4,6,1,8,16,9]) // 16
- d3.min(array)
- 返回?cái)?shù)組中的最小值。
- d3.min([5,4,6,1,8,16,9]) // 1
- d3.extent(array)
- 同時(shí)返回最小值與最大值,以數(shù)組的形式,即[最小值,最大值]。
- d3.extent([5,4,6,1,8,16,9]) // [1, 16]
- 數(shù)組中的內(nèi)容可以是任意對(duì)象:
- 每個(gè)對(duì)象可能包含多個(gè)屬性。
- 具體取哪個(gè)屬性的最大值通過回調(diào)函數(shù)來提示d3.max、d3.min與d3.extent。
- 例:
- let a = [ {name: ‘Shao-Kui’, age:25, height: 176}, {name:‘Wen-Yang’, age:24, height: 180}, {name:‘Liang Yuan’, age: 29, height: 172}, {name:‘Wei-Yu’, age:23, height: 173}]
- d3.max(a, d => d.age) // 29
- d3.max(a, d => d.height) // 180
- d3.extent(a, d => d.height) // [172, 180]
- d3.min(a, d => d.age) // 23
比例尺
- 比例尺用于把實(shí)際數(shù)據(jù)空間映射到屏幕(畫布)空間,即兩個(gè)空間的轉(zhuǎn)化。
- 常用于映射數(shù)據(jù)and創(chuàng)建坐標(biāo)軸。
- 區(qū)別主要在于數(shù)據(jù)的尺度不同
Scale - Linear
- d3.scaleLinear():
- 定義一個(gè)線性比例尺,返回的是一個(gè)函數(shù)。
- let scale = d3.scaleLinear(); // scale為函數(shù)
- scale.domain([min_d, max_d]).range([min, max]):
- 設(shè)置比例尺的定義域與值域。
- 線性比例尺的定義域和值域都是連續(xù)的(Continuous),需分別給出最大值與最小值。
- const scale = d3.scaleLinear().domain([20, 80]).range([0, 120]);
- 比例尺本質(zhì)上是一個(gè)函數(shù):
- scale(20) // 0
- scale(50) // 60
- 常結(jié)合讀取的數(shù)據(jù)與d3.max等接口連用:
- const xScale = d3.scaleLinear() .domain([0, d3.max(data, d => d.value)]).range([0, innerWidth]);
Scale - Band
- d3.scaleBand():
- 定義一個(gè)‘條帶’比例尺,返回的是一個(gè)函數(shù)。
- let scale = d3.scaleBand();
- scale.domain(array).range([min, max]):
- 設(shè)置比例尺的定義域與值域
- Band比例尺的定義域是離散的(Discrete),值域是連續(xù)的。
- const scale = d3.scaleBand().domain([‘a(chǎn)’, ‘b’, ‘c’]).range([0, 120]);
- 比例尺本質(zhì)上是一個(gè)函數(shù):
- scale(‘b’) // 40
- scale(‘c’) // 80
- 常結(jié)合JavaScript的array.map接口一起使用:
- let a = [{name: ‘Shao-Kui’, value:6}, {name:‘Wen-Yang’, value:6}, {name:‘Yuan Liang’, value:16}]
- a.map(d => d.name) // [‘Shao-Kui’, ‘Wen-Yang’, ‘Yuan Liang’]
- const yScale = d3.scaleBand().domain(data.map(d => d.name)).range([0, innerHeight])
- scale.padding(0.1):
- 設(shè)置條帶的間距占各自區(qū)域的比重。
- scale.bandwidth():
- 返回條帶的長(zhǎng)度。
引入坐標(biāo)軸
- 一個(gè)坐標(biāo)軸為一個(gè)group(
),通常需要兩個(gè)坐標(biāo)軸。 - 坐標(biāo)軸中包含:
- 一個(gè)
用于橫跨坐標(biāo)軸的覆蓋范圍 - 若干個(gè)刻度(.tick)
- 每個(gè)刻度也是一個(gè)group
- 每個(gè)刻度下屬還會(huì)包含一個(gè)
和一個(gè) -
用于展示坐標(biāo)軸的軸線,如左到右或上到下 -
用于展示坐標(biāo)軸的刻度值,如實(shí)數(shù)、姓名、日期
-
- (可選)一個(gè)標(biāo)簽用以描述坐標(biāo)軸
- 一個(gè)
- 坐標(biāo)軸的定義通常需要比例尺。
-
定義坐標(biāo)軸(獲得結(jié)果仍是函數(shù)):
- const yAxis = d3.axisLeft(yScale);
- const xAxis = d3.axisBottom(xScale);
- axisLeft:左側(cè)坐標(biāo)軸。
- axisBottom:底側(cè)坐標(biāo)軸。
- 坐標(biāo)軸的刻度對(duì)應(yīng)比例尺的定義域。
- 坐標(biāo)軸在畫布的繪制對(duì)應(yīng)比例尺的值域。
- 僅是對(duì)坐標(biāo)軸的定義,還未繪制。
-
繪制坐標(biāo)軸:
- const yAxisGroup = g.append(‘g’).call(yAxis);
- const xAxisGroup = g.append(‘g’).call(xAxis);
- 實(shí)際配置后會(huì)發(fā)現(xiàn)
中增添了與坐標(biāo)軸相關(guān)的元素
-
任何坐標(biāo)軸在初始化之后會(huì)默認(rèn)放置在坐標(biāo)原點(diǎn),需要進(jìn)一步的平移。
-
關(guān)于 selection.call(…)
-
函數(shù)的輸入為另一個(gè)函數(shù)。
-
另一個(gè)函數(shù)以selection本身(即圖元)作為輸入
-
另一個(gè)函數(shù)中會(huì)根據(jù)函數(shù)體的內(nèi)容修改selection對(duì)應(yīng)的圖元。
-
定義一個(gè)空白的
,D3會(huì)幫助我們定義好 另一個(gè)函數(shù),我們通過.call(…)讓 得以在 另一個(gè)函數(shù)中修改。 - const yAxis = d3.axisLeft(yScale);
- const yAxisGroup = g.append(‘g’).call(yAxis);
配置坐標(biāo)軸
- 可以對(duì)坐標(biāo)軸的風(fēng)格進(jìn)行修改:
- 坐標(biāo)軸本質(zhì)上是圖元的集合。
- d3.selectAll(‘.tick text’).attr(‘font-size’, ‘2em’);
- .tick是D3對(duì)于坐標(biāo)軸定義的統(tǒng)一class
- 坐標(biāo)軸的標(biāo)簽加入不在D3-Axis接口的負(fù)責(zé)范圍內(nèi):
- 通過對(duì)坐標(biāo)軸的
標(biāo)簽 .append(‘text’)來實(shí)現(xiàn) - (左)縱軸坐標(biāo)需要 .attr(‘transform’, ‘rotate(-90)’) 來旋轉(zhuǎn)
- 縱軸坐標(biāo)旋轉(zhuǎn)后,x / y 會(huì)顛倒甚至取值范圍相反
- 回憶DOM:父節(jié)點(diǎn)的屬性會(huì)影響子節(jié)點(diǎn),而坐標(biāo)軸默認(rèn)的’fill’屬性是 ‘none’,因此請(qǐng)一定手動(dòng)設(shè)置文字顏色 .attr(‘fill’, ‘black’)
- 通過對(duì)坐標(biāo)軸的
引入坐標(biāo)軸 - Margin
- SVG對(duì)于D3.js是一個(gè)“畫布”。
- SVG范圍外的任何內(nèi)容屬于畫布之外,瀏覽器將不予顯示。
- 然而坐標(biāo)軸通常初始化在所在父節(jié)點(diǎn)的左上角。
- 定義Margin:
- const margin = {top: 60, right: 30, bottom: 60, left: 200}
- 計(jì)算實(shí)際操作的 inner 長(zhǎng)/寬
- const innerWidth = width - margin.left - margin.right;
- const innerHeight = height - margin.top - margin.bottom;
- 在SVG下額外定義一個(gè)組作為新的根節(jié)點(diǎn)
- const g = svg.append(‘g’).attr(‘id’, ‘maingroup’).attr(‘transform’,
translate(${margin.left}, ${margin.top})
);
- const g = svg.append(‘g’).attr(‘id’, ‘maingroup’).attr(‘transform’,
- Tip: HTML確實(shí)在樣式表中提供margin屬性,然而設(shè)置其他圖元的位置,仍需要計(jì)算innerWidth(Height)。
引入坐標(biāo)軸
- 調(diào)用示例:
- 比例尺可通過坐標(biāo)軸可視化。
Data-Join
-
本質(zhì)上是將數(shù)據(jù)與圖元進(jìn)行綁定:
- 每個(gè)國(guó)家的人數(shù)綁定到矩形的長(zhǎng)度;
- 疫情感染的人數(shù)比例綁定到圓的半徑;
- 產(chǎn)品的銷量綁定到矩形的長(zhǎng)度;
- 各類別商品的銷售占比綁定到扇形的弧度。
-
Why?
- 以數(shù)據(jù)為中心(Data-Driven)的可視化操作:
- 根據(jù)數(shù)據(jù)自動(dòng)調(diào)整圖元的屬性。
- .attr(…)接口可基于圖元自己綁定的數(shù)據(jù)自動(dòng)調(diào)整屬性值。
- 數(shù)據(jù)發(fā)生變化時(shí)可以自動(dòng)對(duì)圖元增刪改查:
- 不再需要手動(dòng)添加、‘修改’、刪除圖元。
- 根據(jù)數(shù)據(jù)的增加or刪除or更新,自動(dòng)補(bǔ)充or移除or更新圖元。
- 以數(shù)據(jù)為中心(Data-Driven)的可視化操作:
-
Data-Join并不是必要的操作,不使用Data-Join同樣可以畫出所有可視化作品。
-
Data-Join只是讓D3.js編程變得更高效且語法更簡(jiǎn)潔。
-
d3.selectAll(‘.class’)**.data( dataArray ) **
-
dataArray在保證是一個(gè)數(shù)組的前提下可以是任何形式:
- 例: [0, 2, 32, 18];
- 例:[{name: ‘Sebastian’, value:384}, {name:’ Ciel’, value:32}, {name:‘Wen-Yang’, value:16}, {name:‘Shao-Kui’, value:19}];
-
.data(…)只考慮數(shù)據(jù)和圖元數(shù)目相同的情況:
- dataArray是一個(gè)數(shù)組,其中的每‘條’數(shù)據(jù)會(huì)與一個(gè)圖元綁定。
-
默認(rèn)的綁定按照雙方的索引順序:
- (Data的Key:后續(xù)D3中會(huì)討論。)
-
不調(diào)用.data(…),則圖元不會(huì)與任何數(shù)據(jù)綁定!
-
數(shù)據(jù)的更新只需要重新綁定另一個(gè) dataArray 即可。
- 調(diào)用形式:
- **d3.selectAll(‘.class’).data(myData).join(‘圖元’).attr(d => …).attr((d, i) => …) **
- .join(…)會(huì)根據(jù)數(shù)據(jù)的條目補(bǔ)全or刪除圖元。
- 若有新增的數(shù)據(jù),則會(huì)自動(dòng)增加對(duì)應(yīng)圖元。
- 若有修改的數(shù)據(jù),則會(huì)自動(dòng)更新對(duì)應(yīng)圖元。
- 若有刪除的數(shù)據(jù),則會(huì)自動(dòng)移除對(duì)應(yīng)圖元。
Data-Join – 用函數(shù)設(shè)置圖元屬性
- selection.attr(‘a(chǎn)ttrbuteName’, ‘value’)
- 通過值設(shè)置屬性
- selection.attr(‘a(chǎn)ttrbuteName’, (d, i) => {…})
- 通過函數(shù)設(shè)置屬性,函數(shù)的輸入為綁定的數(shù)據(jù),返回值為圖元得到的屬性值
- d為Data-Join中,‘.data(array)’綁定給每個(gè)圖元的數(shù)據(jù)。
- i為Data-Join中,‘.data(array)’綁定圖元的順序,即圖元對(duì)應(yīng)原本數(shù)組的第幾個(gè)
- 例:d3.selectAll(‘rect’).attr(‘width’, (d, i) => 1000 * d.age )
- 例:d3.selectAll(‘circle’).attr(‘cy’, (d, i) => 200 * i + 30);
- 由于綁定數(shù)據(jù)的不同,故得到的結(jié)果也不同。
- 設(shè)置圖元屬性的函數(shù)遵循如下規(guī)則(順序性):
- 函數(shù)可僅使用 d => {…},即只有一個(gè)參數(shù),但此時(shí)函數(shù)體無法使用索引。
- 即使未使用到綁定的數(shù)據(jù),如需使用索引,仍需要完整的寫出 (d, i) => {…}。
基于D3的基礎(chǔ)語法與Data-Join繪制柱狀圖
- 數(shù)據(jù)來源:
- https://www.kaggle.com/gregorut/videogamesales
Tip:顏色 – ‘fill’屬性
- PlanA:人為定義一系列顏色組合
- PlanB:使用D3提供的顏色組合(見下頁)
- PlanC:采樣
Tip:D3提供的各種色盤
- 定義一個(gè)離散數(shù)據(jù)到離散數(shù)據(jù)的映射
- 如:每個(gè)水果對(duì)應(yīng)到某個(gè)顏色
- D3.js的內(nèi)嵌(自帶)配色方案?
- https://github.com/d3/d3-scale-chromatic
網(wǎng)絡(luò)數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)?
- 網(wǎng)絡(luò)數(shù)據(jù)包括節(jié)點(diǎn)的集合與邊的集合:
- 節(jié)點(diǎn)與邊通常分布在不同的文件中,通過節(jié)點(diǎn)的ID索引
- D3.js也沒有統(tǒng)一的網(wǎng)絡(luò)數(shù)據(jù)結(jié)構(gòu)規(guī)范:
- 只要能整理成D3.js對(duì)應(yīng)接口接受的格式即可
- 常見的數(shù)據(jù)形式:
- 【節(jié)點(diǎn)列表】+【連接矩陣】
- 【節(jié)點(diǎn)數(shù)、邊數(shù)與基于ID的連接】
- 【節(jié)點(diǎn)列表】+【邊列表】
【節(jié)點(diǎn)數(shù)、邊數(shù)與基于ID的連接】
【節(jié)點(diǎn)列表】+【邊列表】
【連接矩陣】
d3力模擬基礎(chǔ)
- d3的力模擬與“transition”是完全不同的兩個(gè)體系
- let nodes = [{}, {}, {}, {}, {}, {}];
- let simulation = d3.forceSimulation(nodes) 定義后會(huì)發(fā)生…
- 補(bǔ)全nodes中每個(gè)節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu):
- 包括index, x, y, vx, vy,后兩者為速度。
- 開始模擬粒子運(yùn)動(dòng):
- 粒子質(zhì)量為1。
- 不斷地通過內(nèi)部timer觸發(fā)’tick’事件。
- 根據(jù)一系列的‘力’來計(jì)算每個(gè)例子的加速度、速度、位置…
- ‘力’都是哪來的呢?
- 補(bǔ)全nodes中每個(gè)節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu):
不同力的作用
- d3.forceManyBody().strength( value ):
- 粒子之間兩兩的作用力,類似于‘萬有引力’。
- .strength(value)’用來設(shè)置力的大小,value為正互相吸引,為負(fù)則互相排斥。
- d3.forceCenter(w, h).strength( value ):
- 指向某一個(gè)中心的力,會(huì)盡可能讓粒子向中心靠近。
- .strength(…)的用法同上。
- ‘d3.forceCenter(w, h)’中的‘w’與‘h’為中心的位置,通常為畫布的中心。
- d3.forceLink(links).strength(strength).distance(distance):
- 部分粒子之間的兩兩作用力,不同于‘d3.forceManyBody’。
- 'd3.forceLink’中,每個(gè)節(jié)點(diǎn)僅僅會(huì)與一部分節(jié)點(diǎn)有力的作用。
- 有鏈接的節(jié)點(diǎn)間,受力的作用,保持在特定的距離,即靠近互斥、遠(yuǎn)離吸引。
- 是否有鏈接需要通過圖的邊集合給出。
- ‘.strength( vs )’ 與 ‘.distance( vd )’分別設(shè)置力的大小與預(yù)期的距離。
- Link要通過一個(gè)數(shù)據(jù)格式給出,即link的source與target。
- 格式非常類似于‘d3.hierarchy’給出的root.links()
編程實(shí)例:
‘Tic-Toc’
- forceSimulation會(huì)通過每次‘tick’來更新當(dāng)前節(jié)點(diǎn)的狀態(tài):
- 狀態(tài)包括位置、速度、加速度等。
- 更新后的狀態(tài)僅僅為‘狀態(tài)’:
- 不會(huì)反映到任何圖元,僅修改數(shù)據(jù)。
- 需要添加修改圖元屬性的回調(diào)函數(shù)。
- 人為設(shè)置每次tick要如何更新圖元
- simulation.on(‘tick’, ticked);
- 在初始化每個(gè)圖元后,只要為simulation配置了’tick’的回調(diào),simulation會(huì)自動(dòng)開始模擬。
基于‘d3-force’實(shí)現(xiàn)力導(dǎo)圖
數(shù)據(jù)來源:http://networkrepository.com/socfb-Caltech36.php
編程實(shí)例:
Tip:帶權(quán)重的圖?
- d3.forceLink(links).strength(…).distance(…):
- 本質(zhì)上根據(jù)link的權(quán)重設(shè)置forceLink的strength與distance。
- 分別輸入回調(diào)函數(shù),基于每一個(gè)‘link’元素來設(shè)置各自的力與距離。
- 編程實(shí)例: