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
640
Theory of Graphical Perception
tkirby
0
680
Open Refine Course
tkirby
0
320
Language Reference
tkirby
0
150
新聞記者的程式設計第一課
tkirby
0
620
Visualization over Web
tkirby
0
180
迎戰壞資料 @ dbootcamp Taipei
tkirby
0
870
Rasterize D3.js
tkirby
7
1.8k
SVG + D3.JS Course Slide
tkirby
0
290
Other Decks in Technology
See All in Technology
いちAWSエンジニアのAI活用を振り返る #devio2026 / devio osaka 2026 kawahara
masahirokawahara
1
290
20260915deck.gl-raster を使ってみた
rena1208
0
180
Harness Engineering on Rails
joelq
0
770
「大丈夫そう?」をObservabilityで確かめる
mrmtsu
0
240
20260930_Gemma4_Hands-on
tsho
0
180
BedrockとLambdaで作る リアルタイム進行型推理ゲーム
kawametho
0
120
Azure Copilot Resiliency Agentをいろいろ試してみる
tomokusaba
0
140
AIに会社の文脈を理解させる技術~上流工程・非エンジニアにも広げるハーネスエンジニアリング実践~
ochtum
0
200
MCPゲートウェイを作って運用してわかったこと — Agent時代の権限管理の現在地
mtpooh
6
1.7k
雪かき部 #7 もう怖くない!SELECT文!
foursue
0
230
AWS DevOps Agent スキルをつかいこなそう / Master AWS DevOps Agent Skills
kinunori
2
640
なぜAI任せのゲームは面白くならないのか?
hirohasuyoutube
0
340
Featured
See All Featured
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
440
Writing Fast Ruby
sferik
630
63k
Designing Powerful Visuals for Engaging Learning
tmiket
1
580
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
Practical Orchestrator
shlominoach
192
12k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
2
2.9k
Google's AI Overviews - The New Search
badams
0
1.6k
Raft: Consensus for Rubyists
vanstee
142
7.7k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
So, you think you're a good person
axbom
PRO
2
2.2k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.1k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
340
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/