Slide 1

Slide 1 text

d3js - tips and tricks tkirby@osdc 2014

Slide 2

Slide 2 text

0 Convention Difficulty Number

Slide 3

Slide 3 text

1 Visualization 123

Slide 4

Slide 4 text

Purpose

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

1 2 3 4 反⿊黑箱 ⽩白⾊色正義 (⼈人次)

Slide 10

Slide 10 text

1 2 3 4 反⿊黑箱 ⽩白⾊色正義 2 2 y (⼈人次)

Slide 11

Slide 11 text

50萬 反⿊黑箱 ⽩白⾊色正義 10萬 錯誤的⻑⾧長條圖使⽤用⽅方式! 基準點需要從零開始

Slide 12

Slide 12 text

50萬 反⿊黑箱 ⽩白⾊色正義 0 正確的⻑⾧長條圖使⽤用⽅方式! ...好吧這是個失敗的例⼦子

Slide 13

Slide 13 text

1000 反⿊黑箱 ⽩白⾊色正義 0 換個觀點,陳述的事實也不同

Slide 14

Slide 14 text

1000 反⿊黑箱 ⽩白⾊色正義 0 萬⼈人響應 ———— 九⼈人到場 少數⼈人
 不代表主流⺠民意 y: 響應 / 到場

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

zbryikt.github.io/visualize/jobless/ 台灣⼈人失業原因統計圖 / ⽉月

Slide 17

Slide 17 text

2 d3js 123

Slide 18

Slide 18 text

Data Driven ! Document Model Powerful
 Visualizing Lib d3js d3js d3js d3js d3js d3js d3js d3js d3js d3js

Slide 19

Slide 19 text

data data data data data selection enter exit selection

Slide 20

Slide 20 text

data data data data selection enter exit selection d3.selectAll(“div”) .data(data) .enter().append(“div”) .exit().remove() d3.selectAll(“div”)

Slide 21

Slide 21 text

new
 data data new data.onChange enter exit selection

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

3 Read Examples

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

http://mbostock.github.io/d3/talk/20111018/collision.html zbryikt.github.io/visualize/dorling/

Slide 26

Slide 26 text

4 Attributes with {}

Slide 27

Slide 27 text

d3.select(“circle”) .attr(“cx”, “100px”)

Slide 28

Slide 28 text

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”)! …

Slide 29

Slide 29 text

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”) …

Slide 30

Slide 30 text

5 with CSS

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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)

Slide 34

Slide 34 text

6 with AngularJS

Slide 35

Slide 35 text

[“red”,”green”,”blue”,”purple”, “blue”]

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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:

Slide 38

Slide 38 text

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)

Slide 39

Slide 39 text

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)

Slide 40

Slide 40 text

javascript:! function main($scope) { $scope.data = data; } html

Slide 41

Slide 41 text

7 use Jade

Slide 42

Slide 42 text

{{t[0]}} {{t[1]}} html

Slide 43

Slide 43 text

{{t[0]}} {{t[1]}} html

Slide 44

Slide 44 text

{{t[0]}} {{t[1]}}

Slide 45

Slide 45 text

{{t[0]}} {{t[1]}}

Slide 46

Slide 46 text

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”)

Slide 47

Slide 47 text

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”)

Slide 48

Slide 48 text

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”)

Slide 49

Slide 49 text

{{t[0]}} {{t[1]}} 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”)

Slide 50

Slide 50 text

8 use LiveScript

Slide 51

Slide 51 text

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();!

Slide 52

Slide 52 text

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();

Slide 53

Slide 53 text

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();

Slide 54

Slide 54 text

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();

Slide 55

Slide 55 text

9 Angular ! + ! Jade ! +! LiveScript

Slide 56

Slide 56 text

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();

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

so.. this session is not about! D3JS?

Slide 59

Slide 59 text

10 as aux library D3JS

Slide 60

Slide 60 text

ng-repeat d3.fisheye http://zbryikt.github.io/visualize/ajd3/

Slide 61

Slide 61 text

$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)); } );

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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); });

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

台北市親⼭山步道列表

Slide 66

Slide 66 text

11 Animation

Slide 67

Slide 67 text

d3.select “circle” .transition!duration 500 .style “top”, “200px”

Slide 68

Slide 68 text

12 Multiple Animation

Slide 69

Slide 69 text

d3.select “circle” .transition!duration 500 .style “top”, “200px” .transition!delay 500 ! .duration 500 .style “left”, “200px”

Slide 70

Slide 70 text

13 Animation in CSS

Slide 71

Slide 71 text

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 }

Slide 72

Slide 72 text

d3.select “circle” .transition!duration 500 .style “top”, “200px” .transition!delay 500 .duration 500 .style “left”, “200px” d3.select “circle” .attr “class”, “move”

Slide 73

Slide 73 text

14 Animation in SVG

Slide 74

Slide 74 text

@keyframes move { 50% top: 200px! 100% left: 200px! ! circle.move { animation: move 1s linear 1 forwards } d3.select “circle” .attr “class”, “move” javascript css

Slide 75

Slide 75 text

@keyframes move { 50% top: {{top}} 100% left: {{left}} ! circle.move { animation: move {{dur}} linear {{count}} forwards } d3.select “circle” .attr “class”, “move” javascript css

Slide 76

Slide 76 text

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)

Slide 77

Slide 77 text

SMIL

Slide 78

Slide 78 text

SMIL rect: animate(attribute=“width”, ng-attr-from=“{{from}}”, ng-attr-to=“{{to}}”, ng-attr-dur=“{{dur}}s”) angularjs + jade

Slide 79

Slide 79 text

http://zbryikt.github.io/visualize/svg-animate/

Slide 80

Slide 80 text

g0v hackath8n 快到了...

Slide 81

Slide 81 text

15 z-index

Slide 82

Slide 82 text

circle text A circle text B circle text C ……

Slide 83

Slide 83 text

circle text A circle text B circle text C …… Z > B Z > A

Slide 84

Slide 84 text

circle text text circle

Slide 85

Slide 85 text

16 with Canvas

Slide 86

Slide 86 text

Like a Library data = [[0 0] [20 20]]! line = d3.canvas.line!! d3.select “canvas” .call line, data d3 canvas plugin

Slide 87

Slide 87 text

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 …!

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

17 prerendering

Slide 90

Slide 90 text

CANVG svg to canvas canvg(canvas, “

Slide 91

Slide 91 text

PHANTOMJS page = WebPage.create(); page.onLoadFinished = -> page.render(“screenshot.png”);

Slide 92

Slide 92 text

18 D3js, in 3D

Slide 93

Slide 93 text

http://bl.ocks.org/zbryikt/raw/4539556/ 3D, in SVG

Slide 94

Slide 94 text

http://bl.ocks.org/dcposch/4056536 D3GL — d3 globe plugin globe = d3.gl.globe! d3.selectAll “span” .data texture … .call globe

Slide 95

Slide 95 text

http://www.x3dom.org X3DOM = 3D in DOM http://bl.ocks.org/camio/5087116

Slide 96

Slide 96 text

http://jsfiddle.net/XG7s8/ X3D, in AngularJS

Slide 97

Slide 97 text

http://zbryikt.github.io/visualize/banana/ X3D + D3JS + AngularJS

Slide 98

Slide 98 text

19 Other Topics

Slide 99

Slide 99 text

Other Topics • with Google Maps and geographics • with Firebase • with Text, Link, Images and HTML • with Crossfilter • Plugins • Optimization

Slide 100

Slide 100 text

Summary d3js + svg + jade + css3 + livescript + angularjs + x3d + webgl + canvg + phantomjs + canvas + smil …

Slide 101

Slide 101 text

0media 零傳媒 http://0media.tw

Slide 102

Slide 102 text

Attributions Magic Wand by Lemon Liu, http://thenounproject.com/term/magic-wand/1294/ Flame by iconoci,
 http://thenounproject.com/term/flame/9209/

Slide 103

Slide 103 text

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/