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
590
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
570
Theory of Graphical Perception
tkirby
0
600
Open Refine Course
tkirby
0
250
Language Reference
tkirby
0
120
新聞記者的程式設計第一課
tkirby
0
580
Visualization over Web
tkirby
0
150
迎戰壞資料 @ dbootcamp Taipei
tkirby
0
790
Rasterize D3.js
tkirby
7
1.8k
SVG + D3.JS Course Slide
tkirby
0
270
Other Decks in Technology
See All in Technology
Cosmos World Foundation Model Platform for Physical AI
takmin
0
770
プロダクト成長を支える開発基盤とスケールに伴う課題
yuu26
4
1.3k
生成AIを活用した音声文字起こしシステムの2つの構築パターンについて
miu_crescent
PRO
2
180
GitLab Duo Agent Platform × AGENTS.md で実現するSpec-Driven Development / GitLab Duo Agent Platform × AGENTS.md
n11sh1
0
130
Introduction to Sansan for Engineers / エンジニア向け会社紹介
sansan33
PRO
6
68k
茨城の思い出を振り返る ~CDKのセキュリティを添えて~ / 20260201 Mitsutoshi Matsuo
shift_evolve
PRO
1
230
生成AI時代にこそ求められるSRE / SRE for Gen AI era
ymotongpoo
5
3k
Kiro IDEのドキュメントを全部読んだので地味だけどちょっと嬉しい機能を紹介する
khmoryz
0
180
仕様書駆動AI開発の実践: Issue→Skill→PRテンプレで 再現性を作る
knishioka
2
620
超初心者からでも大丈夫!オープンソース半導体の楽しみ方〜今こそ!オレオレチップをつくろう〜
keropiyo
0
110
Azure Durable Functions で作った NL2SQL Agent の精度向上に取り組んだ話/jat08
thara0402
0
170
CDK対応したAWS DevOps Agentを試そう_20260201
masakiokuda
1
240
Featured
See All Featured
The World Runs on Bad Software
bkeepers
PRO
72
12k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
210
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
0
200
Faster Mobile Websites
deanohume
310
31k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
150
Git: the NoSQL Database
bkeepers
PRO
432
66k
Un-Boring Meetings
codingconduct
0
200
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.8k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
92
Producing Creativity
orderedlist
PRO
348
40k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
1
49
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
49
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/