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
d3js tips and tricks
Search
tkirby
April 12, 2014
Technology
9
560
d3js tips and tricks
talks in OSDC 2014, Taiwan.
tkirby
April 12, 2014
Tweet
Share
More Decks by tkirby
See All by tkirby
前端網頁資料視覺化設計
tkirby
1
490
Theory of Graphical Perception
tkirby
0
510
Open Refine Course
tkirby
0
190
Language Reference
tkirby
0
110
新聞記者的程式設計第一課
tkirby
0
560
Visualization over Web
tkirby
0
120
迎戰壞資料 @ dbootcamp Taipei
tkirby
0
750
Rasterize D3.js
tkirby
7
1.7k
SVG + D3.JS Course Slide
tkirby
0
220
Other Decks in Technology
See All in Technology
Road to SRE NEXT@仙台 IVRyの組織の形とSLO運用の現状
abnoumaru
0
380
AI・LLM事業部のSREとタスクの自動運転
shinyorke
PRO
0
300
IAMのマニアックな話 2025 ~40分バージョン ~
nrinetcom
PRO
8
890
頻繁リリース × 高品質 = 無理ゲー? いや、できます!/20250306 Shoki Hyo
shift_evolve
0
150
Cline、めっちゃ便利、お金が飛ぶ💸
iwamot
19
18k
Engineering Managementのグローバルトレンド #emoasis / Engineering Management Global Trend
kyonmm
PRO
6
980
OCI見積もり入門セミナー
oracle4engineer
PRO
0
110
PHPStan をできる限り高速化してみる
colopl
0
250
Cloud Native PG 使ってみて気づいたことと最新機能の紹介 - 第52回PostgreSQLアンカンファレンス
seinoyu
1
180
日本MySQLユーザ会ができるまで / making MyNA
tmtms
1
350
LINEギフトのLINEミニアプリアクセシビリティ改善事例
lycorptech_jp
PRO
0
240
空が堕ち、大地が割れ、海が涸れた日~もしも愛用しているフレームワークが開発停止したら?~ #phperkaigi 2025
77web
2
990
Featured
See All Featured
Producing Creativity
orderedlist
PRO
344
40k
Code Review Best Practice
trishagee
67
18k
What's in a price? How to price your products and services
michaelherold
245
12k
Site-Speed That Sticks
csswizardry
4
450
Measuring & Analyzing Core Web Vitals
bluesmoon
6
320
The Power of CSS Pseudo Elements
geoffreycrofte
75
5.7k
Raft: Consensus for Rubyists
vanstee
137
6.8k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
11
610
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Making Projects Easy
brettharned
116
6.1k
We Have a Design System, Now What?
morganepeng
51
7.5k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
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/