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
530
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
380
Theory of Graphical Perception
tkirby
0
370
Open Refine Course
tkirby
0
170
Language Reference
tkirby
0
87
新聞記者的程式設計第一課
tkirby
0
440
Visualization over Web
tkirby
0
94
迎戰壞資料 @ dbootcamp Taipei
tkirby
0
680
Rasterize D3.js
tkirby
7
1.5k
SVG + D3.JS Course Slide
tkirby
0
180
Other Decks in Technology
See All in Technology
Hands-on Gemini, the Google DeepMind LLM
meteatamel
1
110
Meta Quest 3 で動く桜マシマシ WebXR アプリを IBM Cloud Code Engine と Babylon.js で作った話
1ftseabass
PRO
0
120
開発パフォーマンスを最大化するための開発体制
ham0215
2
330
Delivering Millions of Messages within seconds @ Duolingo
pelelgrino
0
350
推しは推せるときに推せ! プロダクトにフィードバックしていこう
nakasho
0
300
プラットフォームってつくることより計測することが重要なんじゃないかという話 / Platform Engineering Meetup #8
taishin
1
350
MLOpsの「壁」を乗り越える、LINEヤフーの Data Quality as Code
lycorptech_jp
PRO
5
490
リテール金融(キャッシュレス・ネット銀行・ネット証券)の競争環境と経済圏
8maki
0
790
コンテナセキュリティの基本と脅威への対策
kyohmizu
3
760
ExaDB-D dbaascli で出来ること
oracle4engineer
PRO
0
2.1k
ChatGPT for IT Service Management (IT Pro)
dahatake
7
1.6k
開発生産性向上サービスを作るFindyが自分たちで開発生産性を爆上げした組織づくりの歩み / Findy's path to boosting its own development productivity 2024-04-17
ma3tk
3
650
Featured
See All Featured
5 minutes of I Can Smell Your CMS
philhawksworth
199
19k
A designer walks into a library…
pauljervisheath
200
23k
Raft: Consensus for Rubyists
vanstee
132
6.3k
Code Reviewing Like a Champion
maltzj
514
39k
Producing Creativity
orderedlist
PRO
337
39k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
21
1.6k
Building a Modern Day E-commerce SEO Strategy
aleyda
17
6.4k
Building Effective Engineering Teams - LeadDev
addyosmani
28
1.8k
Bootstrapping a Software Product
garrettdimon
PRO
302
110k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
125
32k
Practical Orchestrator
shlominoach
182
9.7k
Imperfection Machines: The Place of Print at Facebook
scottboms
260
12k
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/