Slide 1

Slide 1 text

The ABC of Data Visualization Irene Ros @ireneros Mike Pennisi @jugglinmike http://bocoup.com http://misoproject.com

Slide 2

Slide 2 text

The ABC of Data Visualization Irene Ros @ireneros Mike Pennisi @jugglinmike http://bocoup.com http://misoproject.com Architecting Better Charts

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Cleanup

Slide 5

Slide 5 text

Cleanup Transformation

Slide 6

Slide 6 text

Cleanup Transformation Analysis

Slide 7

Slide 7 text

Cleanup Transformation Analysis Visualization

Slide 8

Slide 8 text

Cleanup Transformation Analysis Visualization

Slide 9

Slide 9 text

Cleanup Transformation Analysis Visualization Is it good enough? Is the story right? Is the conclusion correct? Is it the right message? No

Slide 10

Slide 10 text

Cleanup Transformation Analysis Visualization Is it good enough? Is the story right? Is the conclusion correct? Is it the right message? No Yes! Build it! On the web!

Slide 11

Slide 11 text

We d3.js

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

The Code Spaghetti Monster!

Slide 14

Slide 14 text

? What does it mean to Architect Data Visualization

Slide 15

Slide 15 text

Making Reusable Charts Towards Reusable Charts http://bost.ocks.org/mike/chart/

Slide 16

Slide 16 text

Repeatable Easy to create multiple instances of What is a reusable chart? Difficulty level:

Slide 17

Slide 17 text

Repeatable Easy to create multiple instances of What is a reusable chart? Difficulty level: BarChart Constructor

Slide 18

Slide 18 text

Repeatable Easy to create multiple instances of What is a reusable chart? Difficulty level: BarChart Constructor

Slide 19

Slide 19 text

Configurable Easy to appropriate for a specific task What is a reusable chart? Difficulty level:

Slide 20

Slide 20 text

Configurable Easy to appropriate for a specific task What is a reusable chart? Difficulty level: BarChart Constructor

Slide 21

Slide 21 text

Configurable Easy to appropriate for a specific task What is a reusable chart? Difficulty level: BarChart Constructor

Slide 22

Slide 22 text

Extensible Easy to extend with additional functionality What is a reusable chart? Difficulty level:

Slide 23

Slide 23 text

Extensible Easy to extend with additional functionality What is a reusable chart? Difficulty level: BarChart Constructor

Slide 24

Slide 24 text

Extensible Easy to extend with additional functionality What is a reusable chart? Difficulty level: BarChart Constructor 10 20 60 30

Slide 25

Slide 25 text

Composable Easy to combine into other charts What is a reusable chart? Difficulty level:

Slide 26

Slide 26 text

Composable Easy to combine into other charts What is a reusable chart? Difficulty level: BarChart Constructor

Slide 27

Slide 27 text

Composable Easy to combine into other charts What is a reusable chart? Difficulty level: BarChart Constructor Axis Constructor +

Slide 28

Slide 28 text

Composable Easy to combine into other charts What is a reusable chart? Difficulty level: BarChart Constructor Axis Constructor + Label Constructor 10 40 30 1 +

Slide 29

Slide 29 text

Composable Easy to combine into other charts What is a reusable chart? Difficulty level: BarChart Constructor Axis Constructor + Label Constructor 10 40 30 1 + 10 20 60 30 =

Slide 30

Slide 30 text

A Announcement Big

Slide 31

Slide 31 text

A Announcement Big

Slide 32

Slide 32 text

http://misoproject.com/d3-chart http://github.com/misoproject/d3.chart http://blog.bocoup.com Code: Announcement:

Slide 33

Slide 33 text

Unpacking d3: var data = [1,3,4,6,10]; var chart = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200); var circles = chart.append("g") .classed("circles", true) .selectAll("circle") .data(data) .enter() .append("circle") .attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", "blue");

Slide 34

Slide 34 text

Unpacking d3: var data = [1,3,4,6,10]; var chart = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200); var circles = chart.append("g") .classed("circles", true) .selectAll("circle") .data(data) .enter() .append("circle") .attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", "blue");

Slide 35

Slide 35 text

Unpacking d3: var data = [1,3,4,6,10]; var chart = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200); var circles = chart.append("g") .classed("circles", true) .selectAll("circle") .data(data) .enter() .append("circle") .attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", "blue");

Slide 36

Slide 36 text

Unpacking d3: var data = [1,3,4,6,10]; var chart = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200); var circles = chart.append("g") .classed("circles", true) .selectAll("circle") .data(data) .enter() .append("circle") .attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", "blue");

Slide 37

Slide 37 text

Unpacking d3: var data = [1,3,4,6,10]; var chart = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200); var circles = chart.append("g") .classed("circles", true) .selectAll("circle") .data(data) .enter() .append("circle") .attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", "blue");

Slide 38

Slide 38 text

Unpacking d3: var data = [1,3,4,6,10]; var chart = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200); var circles = chart.append("g") .classed("circles", true) .selectAll("circle") .data(data) .enter() .append("circle") .attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", "blue");

Slide 39

Slide 39 text

Unpacking d3: var data = [1,3,4,6,10]; var chart = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200); var circles = chart.append("g") .classed("circles", true) .selectAll("circle") .data(data) .enter() .append("circle") .attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", "blue");

Slide 40

Slide 40 text

Now in d3.chart d3.chart("CircleChart", { initialize: function() { this.layer("circles", this.base.append("g"), { dataBind: function(data) { return this.selectAll("circle") .data(data); }, insert: function() { return this.append("circle"); }, events : { enter: function() { return this.attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", "blue"); } } }); } }); var chart1 = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200) .chart("CircleChart"); chart1.draw(data);

Slide 41

Slide 41 text

Now in d3.chart d3.chart("CircleChart", { initialize: function() { this.layer("circles", this.base.append("g"), { dataBind: function(data) { return this.selectAll("circle") .data(data); }, insert: function() { return this.append("circle"); }, events : { enter: function() { return this.attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", "blue"); } } }); } }); var chart1 = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200) .chart("CircleChart"); chart1.draw(data);

Slide 42

Slide 42 text

Now in d3.chart d3.chart("CircleChart", { initialize: function() { this.layer("circles", this.base.append("g"), { dataBind: function(data) { return this.selectAll("circle") .data(data); }, insert: function() { return this.append("circle"); }, events : { enter: function() { return this.attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", "blue"); } } }); } }); var chart1 = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200) .chart("CircleChart"); chart1.draw(data);

Slide 43

Slide 43 text

Now in d3.chart d3.chart("CircleChart", { initialize: function() { this.layer("circles", this.base.append("g"), { dataBind: function(data) { return this.selectAll("circle") .data(data); }, insert: function() { return this.append("circle"); }, events : { enter: function() { return this.attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", "blue"); } } }); } }); var chart1 = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200) .chart("CircleChart"); chart1.draw(data);

Slide 44

Slide 44 text

Now in d3.chart d3.chart("CircleChart", { initialize: function() { this.layer("circles", this.base.append("g"), { dataBind: function(data) { return this.selectAll("circle") .data(data); }, insert: function() { return this.append("circle"); }, events : { enter: function() { return this.attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", "blue"); } } }); } }); var chart1 = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200) .chart("CircleChart"); chart1.draw(data);

Slide 45

Slide 45 text

Now in d3.chart d3.chart("CircleChart", { initialize: function() { this.layer("circles", this.base.append("g"), { dataBind: function(data) { return this.selectAll("circle") .data(data); }, insert: function() { return this.append("circle"); }, events : { enter: function() { return this.attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", "blue"); } } }); } }); var chart1 = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200) .chart("CircleChart"); chart1.draw(data);

Slide 46

Slide 46 text

Now in d3.chart d3.chart("CircleChart", { initialize: function() { this.layer("circles", this.base.append("g"), { dataBind: function(data) { return this.selectAll("circle") .data(data); }, insert: function() { return this.append("circle"); }, events : { enter: function() { return this.attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", "blue"); } } }); } }); var chart1 = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200) .chart("CircleChart"); chart1.draw(data);

Slide 47

Slide 47 text

Repeatable var chart2 = d3.select("#vis2") .append("svg") .attr("height", 1000) .attr("width", 1000) .chart("CircleChart"); chart2.draw([10,20,400]); var chart1 = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200) .chart("CircleChart"); chart1.draw([1,2,4]);

Slide 48

Slide 48 text

Configurable Configurable d3.chart("CircleChart", { initialize: function() { this.layer("circles", this.base.append("g"), { // other layer instructions... events : { enter: function() { return this.attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", this.chart().fill()); } } }); }, fill: function(newFill) { if (arguments.length === 0) { return this._fill; } this._fill = newFill; return this; } });

Slide 49

Slide 49 text

Configurable Configurable d3.chart("CircleChart", { initialize: function() { this.layer("circles", this.base.append("g"), { // other layer instructions... events : { enter: function() { return this.attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", this.chart().fill()); } } }); }, fill: function(newFill) { if (arguments.length === 0) { return this._fill; } this._fill = newFill; return this; } });

Slide 50

Slide 50 text

Configurable Configurable d3.chart("CircleChart", { initialize: function() { this.layer("circles", this.base.append("g"), { // other layer instructions... events : { enter: function() { return this.attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", this.chart().fill()); } } }); }, fill: function(newFill) { if (arguments.length === 0) { return this._fill; } this._fill = newFill; return this; } }); var chart1 = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200) .chart("CircleChart") .fill("blue"); chart1.draw(data);

Slide 51

Slide 51 text

Configurable Extensible d3.chart("CircleChart").extend("CirclesWithNumbersChart", { initialize: function() { this.layer("labels", this.base.append("g"), { dataBind: function(data) { return this.selectAll("text") .data(data); }, insert: function() { return this.append("text"); }, events: { enter: function() { return this.attr("x", function(d) { return d * 10; }) .attr("y", 80) .style("text-anchor", "middle") .text(function(d) { return d; }); } } }); } });

Slide 52

Slide 52 text

Extensible d3.chart("CircleChart").extend("CirclesWithNumbersChart", { initialize: function() { this.layer("labels", this.base.append("g"), { dataBind: function(data) { return this.selectAll("text") .data(data); }, insert: function() { return this.append("text"); }, events: { enter: function() { return this.attr("x", function(d) { return d * 10; }) .attr("y", 80) .style("text-anchor", "middle") .text(function(d) { return d; }); } } }); } });

Slide 53

Slide 53 text

Extensible d3.chart("CircleChart").extend("CirclesWithNumbersChart", { initialize: function() { this.layer("labels", this.base.append("g"), { dataBind: function(data) { return this.selectAll("text") .data(data); }, insert: function() { return this.append("text"); }, events: { enter: function() { return this.attr("x", function(d) { return d * 10; }) .attr("y", 80) .style("text-anchor", "middle") .text(function(d) { return d; }); } } }); } });

Slide 54

Slide 54 text

Extensible d3.chart("CircleChart").extend("CirclesWithNumbersChart", { initialize: function() { this.layer("labels", this.base.append("g"), { dataBind: function(data) { return this.selectAll("text") .data(data); }, insert: function() { return this.append("text"); }, events: { enter: function() { return this.attr("x", function(d) { return d * 10; }) .attr("y", 80) .style("text-anchor", "middle") .text(function(d) { return d; }); } } }); } }); var chart1 = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200) .chart("CirclesWithNumbersChart") .fill("blue");

Slide 55

Slide 55 text

Composable

Slide 56

Slide 56 text

Composable d3.chart("CircleChart", { initialize: function() { this.layer("circles", this.base.append("g"), { // other layer instructions... events : { enter: function() { return this.attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", this.chart().fill()); } } }); }, fill: function(newFill) { if (arguments.length === 0) { return this._fill; } this._fill = newFill; return this; } });

Slide 57

Slide 57 text

Composable d3.chart("LabelsChart", { initialize: function() { this.layer("labels", this.base.append("g"), { dataBind: function(data) { return this.selectAll("text") .data(data); }, insert: function() { return this.append("text"); }, events: { enter: function() { return this.attr("x", function(d) { return d * 10; }) .attr("y", 80) .style("text-anchor", "middle") .text(function(d) { return d; }); } } }); } }); d3.chart("CircleChart", { initialize: function() { this.layer("circles", this.base.append("g"), { // other layer instructions... events : { enter: function() { return this.attr("cy", 100) .attr("cx", function(d) { return d * 10; }) .attr("r", 5) .style("fill", this.chart().fill()); } } }); }, fill: function(newFill) { if (arguments.length === 0) { return this._fill; } this._fill = newFill; return this; } });

Slide 58

Slide 58 text

Composable d3.chart("CLChart", { initialize: function() { var circles = this.mixin( this.base.append("g"), "CircleChart" ); var labels = this.mixin( this.base.append("g"), "LabelsChart" ); } });

Slide 59

Slide 59 text

Composable d3.chart("CLChart", { initialize: function() { var circles = this.mixin( this.base.append("g"), "CircleChart" ); var labels = this.mixin( this.base.append("g"), "LabelsChart" ); } });

Slide 60

Slide 60 text

Composable d3.chart("CLChart", { initialize: function() { var circles = this.mixin( this.base.append("g"), "CircleChart" ); var labels = this.mixin( this.base.append("g"), "LabelsChart" ); } });

Slide 61

Slide 61 text

Composable d3.chart("CLChart", { initialize: function() { var circles = this.mixin( this.base.append("g"), "CircleChart" ); var labels = this.mixin( this.base.append("g"), "LabelsChart" ); } }); var chart1 = d3.select("#vis") .append("svg") .attr("height", 200) .attr("width", 200) .chart("CLChart"); chart1.draw(data);

Slide 62

Slide 62 text

Let’s All Build Charts! http://github.com/misoproject/d3.chart http://misoproject.com/d3-chart Irene Ros @ireneros Mike Pennisi @jugglinmike http://bocoup.com http://misoproject.com