Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
d3js tips and tricks
Search
tkirby
April 12, 2014
Technology
630
9
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
d3js tips and tricks
talks in OSDC 2014, Taiwan.
tkirby
April 12, 2014
More Decks by tkirby
See All by tkirby
前端網頁資料視覺化設計
tkirby
1
670
Theory of Graphical Perception
tkirby
0
690
Open Refine Course
tkirby
0
340
Language Reference
tkirby
0
150
新聞記者的程式設計第一課
tkirby
0
650
Visualization over Web
tkirby
0
190
迎戰壞資料 @ dbootcamp Taipei
tkirby
0
890
Rasterize D3.js
tkirby
7
1.8k
SVG + D3.JS Course Slide
tkirby
0
300
Other Decks in Technology
See All in Technology
AIで選択肢が広がった組織設計の理想と現実
konifar
16
7.5k
Copilot Coworkで「みのるん式」やってみた
minorun365
PRO
1
600
AIがGISを代替する日:〜すべてをAIが創る時代に、私たちがFOSS4Gに関わる意味〜
lehupa
0
190
今から始めるAWS環境の暗号移行 - ポスト量子時代に備える
sato4mi
0
150
バイブコーディングの特徴と「コケて直す」ループ
happysamurai294
0
140
Claude Codeから見る、エンジニアの世界の変容とその先
oikon48
8
5.1k
詳解 never 型 - ボトム型の性質を深掘り
nealle
0
130
eBPF 簡介 2026 版
shunghsiyu
0
130
E2Eってつらくないですか?E2Eの管理コストを下げる手段とその実践
akaboshinit
6
2.9k
Vibe-to-Spec開発_実践ガイド
happysamurai294
0
140
Snowflake でできることが増えたら、 ABAC が必要になった
kaeton
0
130
[re:Invent2026事前勉強会(有志開催)]続きは、ラスベガスの廊下で / continue-in-the-vegas-hallway
sh_fk2
0
470
Featured
See All Featured
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
1
650
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
68
60k
The Curious Case for Waylosing
cassininazir
1
600
Reality Check: Gamification 10 Years Later
codingconduct
0
2.4k
Building Flexible Design Systems
yeseniaperezcruz
330
41k
New Earth Scene 8
popppiees
4
2.7k
Discover your Explorer Soul
emna__ayadi
2
1.3k
What's in a price? How to price your products and services
michaelherold
247
13k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
59k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
203
77k
Building AI with AI
inesmontani
PRO
1
1.3k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.5k
Transcript
d3js - tips and tricks tkirby@osdc 2014
0 Convention Difficulty Number
1 Visualization 123
Purpose
None
None
None
None
1 2 3 4 反⿊黑箱 ⽩白⾊色正義 (⼈人次)
1 2 3 4 反⿊黑箱 ⽩白⾊色正義 2 2 y (⼈人次)
50萬 反⿊黑箱 ⽩白⾊色正義 10萬 錯誤的⻑⾧長條圖使⽤用⽅方式! 基準點需要從零開始
50萬 反⿊黑箱 ⽩白⾊色正義 0 正確的⻑⾧長條圖使⽤用⽅方式! ...好吧這是個失敗的例⼦子
1000 反⿊黑箱 ⽩白⾊色正義 0 換個觀點,陳述的事實也不同
1000 反⿊黑箱 ⽩白⾊色正義 0 萬⼈人響應 ———— 九⼈人到場 少數⼈人 不代表主流⺠民意 y:
響應 / 到場
None
zbryikt.github.io/visualize/jobless/ 台灣⼈人失業原因統計圖 / ⽉月
2 d3js 123
Data Driven ! Document Model Powerful Visualizing Lib d3js d3js
d3js d3js d3js d3js d3js d3js d3js d3js
data data data data data selection enter exit selection
data data data data selection enter exit selection d3.selectAll(“div”) .data(data)
.enter().append(“div”) .exit().remove() d3.selectAll(“div”)
new data data new data.onChange enter exit selection
None
3 Read Examples
None
http://mbostock.github.io/d3/talk/20111018/collision.html zbryikt.github.io/visualize/dorling/
4 Attributes with {}
d3.select(“circle”) .attr(“cx”, “100px”)
d3.select(“circle”) .attr(“class”, “ball”)! .attr(“cx”, “100px”)! .attr(“cy”, “100px”)! .attr(“r”, “10px”)! .attr(“stroke”,
“#f00”)! .attr(“stroke-width”, “100px”)! .attr(“fill”, “#f00”)! …
attrs = { class: "ball" cx: "100px" cy: "100px" r:
"10px" stroke: "#f00" "stroke-width": "100px" fill: “#f00” }; d3.select(“circle”).attr(attrs) d3.select(“circle”) .attr(“class”, “ball”) .attr(“cx”, “100px”) .attr(“cy”, “100px”) .attr(“r”, “10px”) .attr(“stroke”, “#f00”) .attr(“stroke-width”, “100px”) .attr(“fill”, “#f00”) …
5 with CSS
attrs = { class: "ball" cx: "100px" cy: "100px" r:
"10px" stroke: "#f00" "stroke-width": "100px" fill: “#f00” }; ! d3.select(“circle”).attr(attrs) attrs = { class: "ball" cx: "100px" cy: "100px" r: "10px" }; d3.select(“circle”).attr(attrs) .ball { stroke: #f00 stroke-width: 100px fill: #f00 } javascript css
attrs = { class: "ball" cx: function(it) { return it.cx;
} cy: function(it) { return it.cy; } r: function(it) { return it.r; } }; .…selectAll(“circle”).attr(attrs) .ball { stroke: #f00 stroke-width: 100px fill: #f00 } javascript css attrs = { class: "ball" cx: "100px" cy: "100px" r: "10px" }; d3.select(“circle”).attr(attrs) .ball { stroke: #f00 stroke-width: 100px fill: #f00 } javascript css
attrs = { class: "ball" cx: function(it) { return it.cx;
} cy: function(it) { return it.cy; } r: function(it) { return it.r; } stroke:! function(it) { return it.s; }! fill:! ! function(it) { return it.fill; }! “stroke-width”: function(it) {! return it.strokeWidth;! } }; .…selectAll(“circle”).attr(attrs) javascript .ball { stroke: #f00 stroke-width: 100px fill: #f00 } javascript css attrs = { class: "ball" cx: function(it) { return it.cx; } cy: function(it) { return it.cy; } r: function(it) { return it.r; } }; .…selectAll(“circle”).attr(attrs)
6 with AngularJS
[“red”,”green”,”blue”,”purple”, “blue”]
a = d3.select(“body”).selectAll(“div.bk”).data(data) a.enter().append(“div”)! .attr(“class”,”bk”)! .style(“background”, function(it){! return it;! });!
a.exit().remove();! 1. choose div.bk 3. append div 2. set data 4. update attribute 6. remove div
a = d3.select(“body”).selectAll(“div.bk”).data(data) a.enter().append(“div”) .attr(“class”,”bk”) .text(function(it){ return it; }); a.exit().remove();
javascript: function main($scope) { $scope.data = data; } ! html: <div class=“bk” ng-repeat=“d in data”! ng-attr-style=“background:{{d}}”>
attrs = { class: "ball" cx: function(it) { return it.cx;
} cy: function(it) { return it.cy; } r: function(it) { return it.r; } stroke:! function(it) { return it.s; }! fill:!! ! function(it) { return it.fill; }! “stroke-width”: function(it) {! return it.strokeWidth;! } }; .…selectAll(“circle”).attr(attrs)
<circle class=“ball” ng-repeat=“c in data” cx=“{{cx}}” cy=“{{cy}}” r=“{{r}}” stroke=“{{s}}” fill=“{{fill}}”
stroke-width=“{{strokeWidth}}” /> attrs = { class: "ball" cx: function(it) { return it.cx; } cy: function(it) { return it.cy; } r: function(it) { return it.r; } stroke:! function(it) { return it.s; }! fill:! ! function(it) { return it.fill; }! “stroke-width”: function(it) {! return it.strokeWidth;! }}; .…selectAll(“circle”).attr(attrs)
<circle class=“ball” ng-repeat=“c in data” cx=“{{cx}}” cy=“{{cy}}” r=“{{r}}” stroke=“{{s}}” fill=“{{fill}}”
stroke-width=“{{strokeWidth}}” /> javascript:! function main($scope) { $scope.data = data; } html
7 use Jade
<g id=“group1” class=“text-group”> <text class=“text” id=“text1” ng-repeat=“t in text”> <textspan>
{{t[0]}} </textspan> <textspan> {{t[1]}} </textspan> <animationmotion dur=“2s”> <mpath xlink:href=“#somepath”/> </animatemotion> </text> </g> html
<g id=“group1” class=“text-group”> <text class=“text” id=“text1” ng-repeat=“t in text”> <textspan>
{{t[0]}} </textspan> <textspan> {{t[1]}} </textspan> <animationmotion dur=“2s”> <mpath xlink:href=“#somepath”/> </animatemotion> </text> </g> html
<g id=“group1” class=“text-group”> <text class=“text” id=“text1” ng-repeat=“t in text”> <textspan>
{{t[0]}} <textspan> {{t[1]}} <animationmotion dur=“2s”> <mpath xlink:href=“#somepath”>
<g id=“group1” class=“text-group”> <text class=“text” id=“text1” ng-repeat=“t in text”> <textspan>
{{t[0]}} <textspan> {{t[1]}} <animationmotion dur=“2s”> <mpath xlink:href=“#somepath”>
g(id=“group1” class=“text-group”) text(class=“text” id=“text1” ng-repeat=“t in text”) textspan {{t[0]}} textspan
{{t[1]}} animationmotion(dur=“2s”) mpath( xlink:href=“#somepath”)
g(id=“group1” class=“text-group”) text(class=“text” id=“text1” ng-repeat=“t in text”) textspan {{t[0]}} textspan
{{t[1]}} animationmotion(dur=“2s”) mpath( xlink:href=“#somepath”)
g#group1.text-group text#text1.text(ng-repeat=“t in text”) textspan {{t[0]}} textspan {{t[1]}} animationmotion(dur=“2s”) mpath(xlink:href=“#somepath”)
<g id=“group1” class=“text-group”> <text class=“text” id=“text1” ng-repeat=“t in text”> <textspan>
{{t[0]}} </textspan> <textspan> {{t[1]}} </textspan> <animationmotion dur=“2s”> <mpath xlink:href=“#somepath”/> </animatemotion> </text> </g> g#group1.text-group text#text1.text(ng-repeat=“t in text”) textspan {{t[0]}} textspan {{t[1]}} animationmotion(dur=“2s”) mpath(xlink:href=“#somepath”)
8 use LiveScript
a = d3.select(“body”).selectAll(“div.bk”).data(data) a.enter().append(“div”)! .attr(“class”,”bk”)! .style(“background”, function(it){! return it;! });!
a.exit().remove();!
a = d3.select(“body”).selectAll(“div.bk”).data(data) a.enter().append(“div”) .attr(“class”,”bk”) .text(function(it){ return it; }); a.exit().remove();
d3.select(“body”).selectAll(“div.bk”).data(data) ..enter().append(“div”) .attr(“class”,”bk”) .text(function(it){ return it; }); ..exit().remove();
d3.select(“body”).selectAll(“div.bk”).data(data) ..enter().append(“div”) .attr(“class”,”bk”) .text( -> it ) ..exit().remove(); d3.select(“body”).selectAll(“div.bk”).data(data) ..enter().append(“div”)
.attr(“class”,”bk”) .text(function(it){! return it;! }); ..exit().remove();
d3.select “body” .selectAll “div.bk” .data data ..enter!append “div” .attr “class”,”bk”
.text -> it ..exit!remove!; d3.select(“body”).selectAll(“div.bk”).data(data) ..enter().append(“div”) .attr(“class”,”bk”) .text( -> it ) ..exit().remove();
9 Angular ! + ! Jade ! +! LiveScript
attrs = { class: "ball" cx: function(it) { return it.cx;
} cy: function(it) { return it.cy; } r: function(it) { return it.r; } stroke: function(it) { return it.s; } fill: function(it) { return it.fill; } “stroke-width”: function(it) { return it.strokeWidth; } }; p = d3.select(“body”).selectAll(“circle”) .data(data); p.enter().attr(attrs); p.exit().remove();
circle.ball( ng-controller=“main” ng-repeat=“c in data”, cx=“{{cx}}”, cy=“{{cy}}”, r=“{{r}}”, stroke=“{{s}}”, fill=“{{fill}}”,
stroke-width=“{{strokeWidth}}”) javascript:! main = ($scope) -> $scope.data = data; html
so.. this session is not about! D3JS?
10 as aux library D3JS
ng-repeat d3.fisheye http://zbryikt.github.io/visualize/ajd3/
<svg> <path ng-repeat="x in geoblock” ng-attr-d=“{{x}}"> </svg> $scope.geoblock = data.map($scope.path);
$scope.fish = d3.fisheye.circular(); $scope.path = d3.geo.path!projection( function(v) { return fish(d3.geo.mercator(v)); } );
svg path(ng-repeat=“x in geoblock”,ng-attr-d=“{{x}}”) $scope ..fish = d3.fisheye.circular! ..geoblock =
data.map $scope.path ..path = d3.geo.path!.projection -> $scope.fish! d3.geo.mercator v
fish = d3.circular.fisheye(); function projection(v) { return fish(d3.geo.mercator(v)); } path
= d3.geo.path().projection(projection); g = d3.select(“body”).selectAll(“path.geo”).data(data); g.exit().remove(); g.enter().append(“path”) ..attr(“class”,”geo”) ..attr(“d”, function(it) { return path(it); });
fish = d3.circular.fisheye(); function projection(v) { return fish(d3.geo.mercator(v)); } path
= d3.geo.path().projection(proje ction); g = d3.select(“body”).selectAll(“p ath.geo”).data(data); g.exit().remove(); g.enter().append(“path”) ..attr(“class”,”geo”) ..attr(“d”, function(it) { return path(it); }); svg path(ng-repeat=“x in geoblock”, ng-attr-d=“{{x}}”) $scope ..fish = d3.fisheye.circular! ..geoblock = data.map $scope.path ..path = d3.geo.path!.projection -> $scope.fish! d3.geo.mercator v
台北市親⼭山步道列表
11 Animation
d3.select “circle” .transition!duration 500 .style “top”, “200px”
12 Multiple Animation
d3.select “circle” .transition!duration 500 .style “top”, “200px” .transition!delay 500 !
.duration 500 .style “left”, “200px”
13 Animation in CSS
d3.select “circle” .transition!duration 500 .style “top”, “200px” .transition!delay 500 .duration
500 .style “left”, “200px” @keyframes move { 50% top: 200px! 100% left: 200px! ! circle.move { animation: move 1s linear 1 forwards }
d3.select “circle” .transition!duration 500 .style “top”, “200px” .transition!delay 500 .duration
500 .style “left”, “200px” d3.select “circle” .attr “class”, “move”
14 Animation in SVG
@keyframes move { 50% top: 200px! 100% left: 200px! !
circle.move { animation: move 1s linear 1 forwards } d3.select “circle” .attr “class”, “move” javascript css
@keyframes move { 50% top: {{top}} 100% left: {{left}} !
circle.move { animation: move {{dur}} linear {{count}} forwards } d3.select “circle” .attr “class”, “move” javascript css
attrs = { class: ! "ball"! cx: ! ! function(it)
{ return it.cx; }! cy: ! ! function(it) { return it.cy; }! r: ! ! function(it) { return it.r; }! stroke: function(it) { return it.s; } fill: function(it) { return it.fill; } “stroke-width”: function(it) { return it.strokeWidth; } }; .…selectAll(“circle”).attr(attrs) javascript .ball { stroke: #f00 stroke-width: 100px fill: #f00 } javascript css attrs = { class: "ball"! cx:function(it) { return it.cx; }! cy:function(it) { return it.cy; }! r: function(it) { return it.r; }! }; .…selectAll(“circle”).attr(attrs)
SMIL <rect> <animate attributeName=“width” from=“2” to=“10” dur=“1s”/> </rect>
SMIL rect: animate(attribute=“width”, ng-attr-from=“{{from}}”, ng-attr-to=“{{to}}”, ng-attr-dur=“{{dur}}s”) angularjs + jade
http://zbryikt.github.io/visualize/svg-animate/
g0v hackath8n 快到了...
15 z-index
circle text A circle text B circle text C ……
circle text A circle text B circle text C ……
Z > B Z > A
circle text text circle <g class=“text-group”> <g class=“circle-group”> <g class=“item”>
16 with Canvas
Like a Library data = [[0 0] [20 20]]! line
= d3.canvas.line!! d3.select “canvas” .call line, data d3 canvas plugin
As a DOM Model selectAll “custom:circle” .data data! .enter! .append
“custom:circle”! .exit! .remove! http://bl.ocks.org/mbostock/1276463 d3.timer -> selectAll “custom:*” .each ->! if @tagName==“circle” => …! else …!
SVG 2 Canvas - CANVG http://loading.io SVG Animation —> Tick
by JS Tick by JS —> SVG SVG —> Canvas by canvg Canvas —> GIF by gif.js
17 prerendering
CANVG svg to canvas canvg(canvas, “<svg>…”, { renderCallback: cb })
<script src=“canvg.js”> function cb(canvas) { … }
PHANTOMJS page = WebPage.create(); page.onLoadFinished = -> page.render(“screenshot.png”);
18 D3js, in 3D
http://bl.ocks.org/zbryikt/raw/4539556/ 3D, in SVG
http://bl.ocks.org/dcposch/4056536 D3GL — d3 globe plugin globe = d3.gl.globe! d3.selectAll
“span” .data texture … .call globe
http://www.x3dom.org X3DOM = 3D in DOM http://bl.ocks.org/camio/5087116
http://jsfiddle.net/XG7s8/ X3D, in AngularJS
http://zbryikt.github.io/visualize/banana/ X3D + D3JS + AngularJS
19 Other Topics
Other Topics • with Google Maps and geographics • with
Firebase • with Text, Link, Images and HTML • with Crossfilter • Plugins • Optimization
Summary d3js + svg + jade + css3 + livescript
+ angularjs + x3d + webgl + canvg + phantomjs + canvas + smil …
0media 零傳媒 http://0media.tw
Attributions Magic Wand by Lemon Liu, http://thenounproject.com/term/magic-wand/1294/ Flame by iconoci,
http://thenounproject.com/term/flame/9209/
links http://zbryikt.github.io/visualize/jobless/ http://mbostock.github.io/d3/talk/20111018/collision.html http://zbryikt.github.io/visualize/dorling/ http://zbryikt.github.io/visualize/ajd3/ http://zbryikt.github.io/visualize/hiking/ http://zbryikt.github.io/visualize/svg-animate/ http://bl.ocks.org/mbostock/1276463 http://loading.io http://bl.ocks.org/dcposch/4056536
http://bl.ocks.org/zbryikt/raw/4539556/ http://bl.ocks.org/camio/5087116 http://jsfiddle.net/XG7s8/ http://zbryikt.github.io/visualize/banana/