Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
D3.js 資料視覺化入門
Search
Kuro Hsu
December 23, 2015
Technology
2
230
D3.js 資料視覺化入門
2015/12/23 @ 朝陽科技大學
Kuro Hsu
December 23, 2015
Tweet
Share
More Decks by Kuro Hsu
See All by Kuro Hsu
Laravel x Vite
kurotanshi
0
600
[.NET Conf 2020 Taiwan] 以輕前端視角進入 Vue 3.0 的世界
kurotanshi
0
660
[MOPCON 2020] vite: Make web dev fast again
kurotanshi
0
2.3k
[ModernWeb'20] Vue.js :The Bad Parts
kurotanshi
1
91
[MOPCON 2019] Vue.js 3.0 與 Composition API 的變革
kurotanshi
1
1.2k
[JSDC2019] 我有一堆選擇 Vue 開發框架的理由
kurotanshi
1
700
[COSCUP 2019] 前端工程師的養成之路與開源工具
kurotanshi
3
380
初探 Vue 3.0 Function API
kurotanshi
4
2.9k
VueJS Style Guide 導讀
kurotanshi
6
1.8k
Other Decks in Technology
See All in Technology
I tried the newly introduced certification "Applied Skills" on Microsoft Learn
mappie_kochi
0
150
Databricks Appのご紹介
databricksjapan
0
250
Strict Concurrencyにしたらdeinitでクラッシュする話
0si43
0
130
クレジットカードを製造する技術
yutadayo
81
47k
入門 KRR
donkomura
0
110
コード✕AIーソフトウェア開発者のための生成AI実践入門~
yuhattor
3
810
シェルとPerlの使い分け、 そういった思考の道具は、どこから来て、どこへゆくのか?v1.1.0
fmlorg
0
200
エムスリー全チーム紹介資料 / Introduction of M3 All Teams
m3_engineering
1
320
DenoでもViteしたい!インポートパスのエイリアスを指定してラクラクアプリ開発
bengo4com
2
2k
Pythonを活用したLLMによる構造的データ生成の手法と実践
brainpadpr
3
350
【shownet.conf_】ネットワークテストの最適化と利便性の追求
shownet
PRO
0
340
kube-vipとkube-proxy置き換えCiliumを積んだ究極のK3sクラスタを建てる
logica0419
4
210
Featured
See All Featured
Docker and Python
trallard
40
3k
Faster Mobile Websites
deanohume
304
30k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
3
230
Designing with Data
zakiwarfel
98
5.1k
Designing for humans not robots
tammielis
249
25k
Why Our Code Smells
bkeepers
PRO
334
57k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
4
120
How STYLIGHT went responsive
nonsquared
95
5.1k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
26
4.1k
Keith and Marios Guide to Fast Websites
keithpitt
408
22k
Robots, Beer and Maslow
schacon
PRO
157
8.2k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
130k
Transcript
Kuro Hsu @ ๖檚ᑀದय़䋊 D3.js 虻碘憙憽玕獈槹 2015/12/23
ᛔ౯Օ奧 Kuro Hsu • 獮ᒒૡ纷䒍 @ 睃瞆叨褸㿁 • COSCUP 拻ᘏ
• JSDC 拻ᘏ • kurotanshi [at] gmail.com • http://kuro.tw
̿ض獨ᓕ D3 ԧ牧֦肯螂虻懱憙憽玕㻟牫̀ 磪䷱磪Օ奧 D3.js 墋䁭ጱᒫӞ殷疰ݞՈ獨ᓕ D3 ጱ獌ܠ
ݶ䰬ฎ Web 懿袅獤ຉ牧ߺ㮆ฃ睞牫
ݶ䰬ฎ Web 懿袅獤ຉ牧ߺ㮆ฃ睞牫
傶Ջ讕襑ᥝ疥虻懱憙憽玕 • य़ᰁ虻碘ݢࣁ縣樌ᤩቘ薹牧虻懱㯽螏ๅ磪硳ሲ • 磪ۗෝ薪疗ڊٌ犢珊匍ොୗ犋ฃ疗憽کጱ虻碘粬 • ݢ犥盄ฃ፡ڊ虻碘蛪ጱቭ綦膏梊藮 • ֵአٌ犢承ጱ捝ᘏ犖胼ฃ፡睞
None
None
None
蕣֢虻懱瑽蔭ጱᥝᔰ • ก嘦ጱԆ氂 • 虻懱羊墋玕牧Ԇ氂ๅ统ڊ • 殼䛑憙憽㵕娄牧珅捝ᘏፓط • 篷襑ਁ藯ก犖胼ቘ薹
None
http://d3js.org/ Demo: https://goo.gl/idrDMt
None
* svg 媑瑽襑ᥝ IE9+
• D3 = Data-Driven Documents. • ֵአ翕殷秂伛ದ蔩 (HTML / CSS
/ JavaScript / SVG) • 䔶य़ጱ Data-Driven 疥虻碘䌘䛑ک DOM Ӥ牧۱ೡزᔰ ጱी㳫现痀虋玕 • ׀ SVG ፘ橕媑瑽ૡٍ䓚牧蒈圸 SVG ኴጱ jQuery • 䕃᩻य़֕䋿֢斃ٌ犢憙憽玕ૡٍ耆卓 D3.js ฎՋ讕
螡䢔瑊膏 DOM 砺֢
螡䢔瑊 JavaScript jQuery D3.js document.querySelectorAll(".block") $(".block") d3.selectAll(".block")
螡䢔瑊 d3.select("body").selectAll(".block") d3.selectAll("body .block")
ොဩ袽 (method chaining) var box = d3.selectAll('.box'); box.style('color', '#f00');
box.text('Hello World!'); var box = d3.selectAll('.box') .style('color', '#f00') .text('Hello World!');
痀 (attr) // attr() d3.selectAll("circle") .attr("cx", 50) .attr("cy", 50)
.attr("r", 25) .style("fill", "red");
痀 (attr) // 犥̿ᇔկ̀ጱොୗ瞲ਧ痀 d3.selectAll("circle") .attr({ "cx": 50, "cy":
50, "r": 25 }) .style("fill", "red"); // 玲 circle cx 痀ጱ独 d3.select("circle").attr("cx");
痀 (property) d3.selectAll('.name') .property('value', 'Kuro'); አဩ膏 attr() ፘݶ牧֕
property() ֵአࣁ篷ਁᶎ瞲ਧጱ痀牐 ই: disabled, checked 犥现 value 缛牐 d3.selectAll('.name') .property('disabled');
class d3.selectAll('.block') .classed('item', true); d3.selectAll('.block') .classed('item', false);
d3.selectAll('.block') .classed('item big', true);
styles d3.selectAll('.block') .style('color', '#f00'); d3.selectAll('.block') .style({ 'color':
'#f00', 'font-size': '15px' });
text & html var foo = d3.selectAll('.foo'); foo.text('Hello World!'); foo.html('<div
class="bar">Hello</div>');
ℂ虻碘ک瑽猟زᔰ
Data - ಅ磪ጱ虻碘᮷ฎ檋ڜ var data = [1, 3, 5, 2,
4, 6, 8, 10];
Data - ಅ磪ጱ虻碘᮷ฎ檋ڜ jsbin.com/kifihirugu var data = [ {x: 10.0,
y: 9.14}, {x: 8.0, y: 8.14}, {x: 13.0, y: 8.74}, {x: 9.0, y: 8.77}, …… ];
key function var data = [ { 'name': 'kuro', 'age':
30 }, { 'name': 'John', 'age': 20 }, { 'name': 'Mary', 'age': 18 } ]; var p = d3.select('body') .selectAll('p') .data(data) .enter() .append('p') .text(function(d, i) { return d.name + ': ' + d.age + '䵇'; });
None
Enter, Update, Exit Pattern var data = [1, 2,
3, 4, 5]; d3.select('body') .selectAll('div') .data( data ) .enter() .append('div') .text(function(d, i){ return d; }); 1 2 3 4 5
Enter, Update, Exit Pattern data = [1, 3, 5,
7, 9]; d3.select('body') .selectAll('div') .data( data ) .text(function(d, i){ return d }); 1 3 5 7 9
Enter, Update, Exit Pattern data = [10, 20, 30]; d3.select('body')
.selectAll('div') .data( data ) .exit() .remove(); 1 3 5 7 9
Enter, Update, Exit Pattern data = [10, 20, 30]; d3.select('body')
.selectAll('div') .data( data ) .exit() .remove(); 1 3 5 7 9 ?
Enter, Update, Exit Pattern data = [10, 20, 30]; d3.select('body')
.selectAll('div') .data( data ) .text( function(d, i){ return d; }) .exit() .remove(); 10 20 30 7 9
None
SELECTION Datas Enter & Update Exit & Remove SELECTION
Enter: Data > Elements. Update: Data = Elements. Remove: Data
< Elements.
Ajax with D3 d3.json([URL], function(error, data){ if (error) return console.warn(error);
// do something }); d3.csv([URL]).get(function(error, data){ // do something });
穉ֺ疳膏ଷ秂數
d3.scale.linear().domain().range() 補間⽅法 輸入範圍 輸出範圍
Domain Range
穉ֺ疳 0 1000 0 100 500 50 Domain Range
var d3Scale = d3.scale.linear() // linear .domain([0, 1000]) //
㯽獈塅瑻 .range([0, 100]); // 蜍ڊ塅瑻 console.log( d3Scale(500) ); // 50 console.log( d3Scale(123) ); // 12.3 穉ֺ疳
var colorScale = d3.scale.linear() .domain([0, 20]) .range(["#f00", "#0f0"]); for (var
i = 0; i < 21; i++) { body.append('div') .style('background-color', colorScale(i)); }
var widthScale = d3.scale.linear() .domain([0, 12]) .range(["0px", "720px"]); for (var
i = 0; i < 13; i++) { body.append('div').text( widthScale(i) ); }
var red = d3.rgb(255,0,0); var green = d3.rgb(0,255,0); var compute
= d3.interpolate(red, green); console.log( compute(0) ); // #ff0000 console.log( compute(0.3) ); // #b34d00 console.log( compute(0.5) ); // #808000 console.log( compute(0.7) ); // #4db300 console.log( compute(1) ); // #00ff00
var a = "50px"; var b = "1000px"; var compute
= d3.interpolate(a, b); console.log( compute(0) ); // 50px console.log( compute(0.3) ); // 335px console.log( compute(0.5) ); // 525px console.log( compute(0.7) ); // 715px console.log( compute(1) ); // 1000px
d3.scale.category10() d3.scale.category20() d3.scale.category20b() d3.scale.category20c()
ଷ秂數
數娄 var data = [0, 150, 200, 300, 500, 1000];
// x 數 scale 穉ֺ疳 var xScale = d3.scale.linear() .domain(d3.extent(data)) // [0, 1000] .range([0, 500]); // x-range አ㬵蔭纈疝ଶ // y 數 scale 穉ֺ疳 var yScale = d3.scale.linear() .domain(d3.extent(data)) // [0, 1000] .range([0, 300]); // y-range አ㬵蔭纈ṛଶ
數娄 // x 數 var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom");
// ڰଶ֖ᗝ // y 數 var yAxis = d3.svg.axis() .scale(yScale) .orient("left"); // ڰଶ֖ᗝ
數娄 蝚螂 orient() 矒ګ數娄ොݻ现ڰଶ֖ᗝ
Ticks - ڰଶ jsbin.com/cuvubiwipo // x 數 var xAxis =
d3.svg.axis() .scale(xScale) .orient("bottom") .ticks(15) // 瞲ਧڰଶ碍ᰁ, 㻌֖ .tickFormat(function(d){ return d + "px"; }); // y 數 var yAxis = d3.svg.axis() .scale(yScale) .orient("left");
裾礿瑽
㾼讨瑽
穥ု瑽 http://jsbin.com/yepapa
螂䁰㵕向 SELECTION.transition() .duration(1000) // 㵕向䁆ᤈ碻樌 .delay(1000) // 皤螛 .ease( ...
) // Easing 獢碍 .attr({ 'transform': function(d){ ....... } }); *D3.js Easing Checker - http://bl.ocks.org/hunzy/9929724
螂䁰㵕向 SELECTION.transition() .duration(1000) .each('start', function(){ … }) // 㵕向樄ত獮䁆ᤈ .attr({
… }) .each('end', function(){ … }); // 㵕向奾盅䁆ᤈ
ے獈Ԫկ SELECTION.on('click', function(){ alert('Hello D3!'); }); SELECTION.on('click', null);
ے獈Ԫկ SELECTION.on('click.event1', function(){ alert('Hello D3 event 1'); }); SELECTION.on('click.event2', function(){
alert('Hello D3 event 2'); });
穥ု瑽ےӤ㵕向硳ຎ
SVG च器
SVG 讨檋ୗ瑽粙婘硯碻䨝叨ኞ०፥硳䛑 source: http://www.cs.cmu.edu/~chuck/lennapg/lenna.shtml
SVG ݻᰁୗ瑽粙ኧӞ蝫Ԁଷ秂懯ᓒ奲౮牧硯ٚय़犖犋ொ source: http://komica.chiisana.net/vector/src/1205520731301.svg
rect <rect x="20" y="20" width="150" height="100" rx="0"></rect>
circle <circle cx="55" cy="55" r="50"></circle>
line <line x1="10" y1="30" x2="230" y2="60"></line> x1, y1 x2, y2
text <text x="0" y="0" dx="0" dy="0" font-size="50" text-anchor="start"> Hello
</text> text-anchor="[start/middle/end]"
text - tspan <text x="0" y="20" style="font-size: 17px;"> <tspan>Hello,
</tspan> <tspan fill="red">World </tspan> </text>
text - tspan <text x="0" y="20" style="font-size: 17px;"> <tspan
x="10" dy="10">Hello, </tspan> <tspan x="10" dy="20">World </tspan> </text>
g (group) <g transform="rotate(45 50 50)"> <line> … </line> <rect>
… </rect> <text> … </text> </g>
path • 犨娄ྦྷጱ奲ݳ牧ಅ磪瑽୵᮷向ڊ㬵 • d 痀物Ӟᗭ̿瞲犤̀+̿ଷ秂̀ጱ奲ݳ
path • ᑏ㵕: M (MoveTo) • ፗ娄: L (LineTo) /
H (Horizontal) / V (Vertical) • ใ娄: C (CurveTo) / S (Shorthand/Smooth CurveTo) Q (Quadratic Bezier CurveTo) T (smooth quadratic Bezier CurveTo) • 皭娄: A (elliptical Arc) • 樂ݳ: Z (close-path)
path <line x1="10" y1="50" x2="390" y2="130"> <path d="M10,50L390,130">
娄ྦྷ叨ኞ瑊 - d3.svg.line var linePath = d3.svg.line(); var data =
[[10,50], [390, 130]]; svg.append('path') .attr('d', linePath(data)); <path d="M10,50L390,130">
娄ྦྷ叨ኞ瑊 - d3.svg.line var svg = d3.select('.svg'); var linePath
= d3.svg.line() .x(function(d, i){ return d; }) .y(function(d, i){ return (i%2 === 0) ? 40 : 120;}) var data = [40, 80, 120, 160, 200, 240, 280, 320, 360]; svg.append('path') .attr({ 'd': linePath(data) });
ರ娄瑽
d3.svg.line() .x(…).y(…) .interpolate("linear"); .interpolate("linear-closed"); .interpolate("basis"); .interpolate("cardinal"); .interpolate("step"); https://github.com/mbostock/d3/wiki/SVG-Shapes#user-content-line_interpolate
ರ娄瑽 - 虋୵
ୡ娄ྦྷ叨ኞ瑊 - d3.svg.arc
ୡ娄ྦྷ叨ኞ瑊 - d3.svg.arc var myArc1 = { "startAngle": 0, "endAngle":
Math.PI }; var myArc2 = { "startAngle": Math.PI, "endAngle": Math.PI * 1.5 }; var myArc3 = { "startAngle": Math.PI * 1.5, "endAngle": Math.PI * 2 };
ୡ娄ྦྷ叨ኞ瑊 - d3.svg.arc var arc = d3.svg.arc() .innerRadius(50) .outerRadius(150); svg.append('path')
.attr({ 'd': arc(myArc1) });
ୡ娄ྦྷ叨ኞ瑊 - d3.svg.arc
ୡ娄ྦྷ叨ኞ瑊 - d3.svg.arc http://community.yungching.com.tw/Building/9443
ୡ娄ྦྷ叨ኞ瑊 - d3.svg.arc
Responsive with D3
www.nytimes.com/interactive/2015/06/17/world/middleeast/map-isis-attacks-around-the-world.html
www.nytimes.com/interactive/2015/06/17/world/middleeast/map-isis-attacks-around-the-world.html
Responsive with D3
Responsive with D3 // 疥疳ੑ硬౮ܨ碻玲ጱ疝ṛ width = parseInt(d3.select(".content").style("width")) -
margin*2; height = parseInt(d3.select(".content").style("height")) - margin*2; // 䌃稴ጱ疝ṛ var margin = 40, width = 960 - margin*2, height = 500 - margin*2;
var svg = d3.select('.svg'); // 疥媑蕣㵕֢۱蕕ᛗ function 獉 function
rendering() { // 疥媑蕣ጱ纷ୗ嘨蝢蝢砆ک愊ᶎ // ኼ } // 疥 window 翉ਧ resize Ԫկ牧㪔᯿碝媑蕣瑽ࣳ d3.select(window).on('resize', rendering); // Ḓ稞媑蕣 rendering();
None
// resize 碻, 㵕眲ๅ碝 x, y 數ڰଶ, ๅ螕ݳ褂捝 var yAxis
= d3.svg.axis() .scale(yScale2) .orient("left") .ticks( Math.max(height/50, 2) ); Responsive with D3
None
Responsive with D3 • य़ग़碍ᤈ㵕蕕ᗝ䌘 SVG ඪൔ臑অ • ݻᰁ瑽୵牧婘硯犋०፥ •
㵕向 / زᔰ螂ग़碻ฃ磪硳胼㺔氂 • 犋ฎ犨֜瑽୵᮷螕ݳࣁಋ秚Ӥ氥纈物 狶 RWD ฎݚ狶Ӟ㮆ಋ秚粚牫
d3 Layouts
D3.js Layouts • d3.js ׀ԧ 11 圵粚ࣳ (layouts) • ݝ襑׀扗粚ࣳ瞲ਧጱ虻碘໒ୗ疰ݢ犥ፗ矑ॺአ
• layouts 蛪犋׀媑瑽ۑ胼牧ᘒฎ疥ܻতጱ虻碘 旉矦౮螕ݳᤩ d3 媑瑽ጱ虻碘໒ୗ • 睱懯ᓒ top, left, d 缛缛痀ጱ碻狡粬獨অአ
Pie Layout
Pie Layout - Ӟᑁ虋綎綎瑹
Chord Layout 2015 ᒫӞ䌵Ӯኴ12䔶༉純搴 A 奲毆搴䌘䜗奾ຎ
Chord Layout ݣ傀 ݘ૬ 艰葦 ے೭ य़ ူग़ 讝ݱ 嬝य़ڥ
ݣ傀 - 4 4 8 4 7 ݘ૬ 1 - 6 1 8 2 艰葦 7 5 - 1 11 16 ے೭य़ 9 5 3 - 2 4 ူग़ 讝ݱ 7 7 7 0 - 7 嬝य़ڥ 1 1 1 0 1 -
Chord Layout
Chord Layout
Chord Layout
Chord Layout
Hierarchy Layout 塅ֺ虻碘: 2014 ݣ玖૱裾螡膐ݱᤈ硰玟ಭ纏翄懯
Partition Layout
Partition Layout // 疥ኞ౮অጱ nodes 蝚螂 data() 癲獈 var gRects
= svg.selectAll("g").data(nodes).enter().append("g"); // ے獈 rect gRects.append("rect").attr({ ... }).style({ ... }); // ے獈ਁ gRects.append("text").attr({ ... }).style({ ... }); // 縷୵褩䍅瑽: d3.layout.partition() // size 瞲ਧ瑽礯य़ੜ, ڥአ .nodes 癲獈虻碘 var nodes = d3.layout.partition() .size([600, 400]) // [width, height] .nodes(data);
Partition Layout
Partition Layout // 㾼୵褩䍅瑽: d3.layout.partition() // size 瞲ਧ瑽礯य़ੜ, ڥአ .nodes
癲獈虻碘 var nodes = d3.layout.partition() .size([2 * Math.PI, radius * radius]) .nodes(data); // d3.svg.arc 蕣֢皭୵ var arc = d3.svg.arc() .startAngle(function (d) { return d.x; }) .endAngle(function (d) { return d.x + d.dx; }) .innerRadius(function (d) { return Math.sqrt(d.y); }) .outerRadius(function (d) { return Math.sqrt(d.y + d.dy); });
http://bl.ocks.org/mbostock/1256572
捝ᘏ蚤֦మጱ犋Ӟ䰬 ইຎ獉瑹դ蔭 100牧 क़瑹䨝ฎग़牫
捝ᘏ蚤֦మጱ犋Ӟ䰬 500 1500
捝ᘏ蚤֦మጱ犋Ӟ䰬 500 1500 1500 500
憙憽玕犋ฎ磪瑽疰অ 瑽粙㬵რ物 https://www.facebook.com/forpeople/photos/a. 989035831154301.1073741835.153819538009272/989036197820931/
憙憽玕犋ฎ笖犝疰অ (睃瞆լ翕ᤈ眐毱螇) (礓瞆լ翕ᒊ)
窾窫憙肯
ై螡Ԇ氂
ై螡Ԇ氂 0 200000000000000000000 400000000000000000000 600000000000000000000 800000000000000000000 1000000000000000000000 ྎॠ聲䒍 碝ڥ
None
http://p.udn.com.tw/upf/newmedia/2015_data/20150930_udntyphoon/udntyphoon/index.html
None
http://blog.infographics.tw/
None
– Randy Krum, Author of Cool Infographics. ̿፡ک牧疰睞ԧ牐̀
Q & A
• Kuro Hsu • Demo code: https://github.com/kurotanshi/d3js-samples • kurotanshi [at]
gmail.com • http://kuro.tw Thanks!