Datavisualization with D3 – Data Driven Document – D3.js



Datavisualization with D3 – Data Driven Document – D3.js

0 0


d3js-workshop-pres

d3js-workshop-pres

On Github xebia-france / d3js-workshop-pres

Datavisualization with D3

Data Driven Document

Created by Julien Buret / @julien_buret

D3.js

Not new presentation element

Map data to element

Using Web standard

SVG

CSS

JS

The main purpose of d3 are transform, manipulate your data and map them to SVG element

SVG

Hello world in SVG
<svg width="300" height="100">
  <rect fill="white" stroke="black"></rect>
  <text x="10" y="20">Hello world in SVG</text>
</svg>

SVG + CSS

Hello world in SVG
<style>
  .intro-rect {
    fill: gray;
    opacity: 0.3;
    stroke: black;
    stroke-width: 4;
  }

  .intro-text {
    font-size: 34;
    fill: white,
    stroke: black
  }
</style>

Draw basic form with D3

Circle

var svg = d3.select("#d3-slide1").append("svg");
	svg.attr("width", 200).attr("height", 200);
	svg.append("circle")
		.attr("cx", 50)
		.attr("cy", 50)
		.attr("r", 30)
		.attr("fill","red")
		.attr("stroke","black")

Rectangle

var svg = d3.select("#d3-slide1").append("svg");
	svg.attr("width", 200).attr("height", 200);
	svg.append("rect")
		.attr("x", 75)
		.attr("y", 10)
		.attr("width", 50)
		.attr("height", 100)
		.attr("fill","blue")
		.attr("stroke","black")

Path

var lineData = [ { "x": -5,   "y": 25},  { "x": -4,  "y": 16},
                  { "x": -3,  "y": 9}, { "x": -2,  "y": 4},
                  { "x": -1,  "y": 1},  { "x": 0, "y": 0},
                  { "x": 1,   "y": 1},  { "x": 2,  "y": 4},
                  { "x": 3,  "y": 9}, { "x": 4,  "y": 16},
                  { "x": 5,  "y": 25}];
var lineFunction = d3.svg.line()
	.x(function(d) { return (d.x * 20) + 150; })
	.y(function(d) { return -(d.y * 5) + 180; })
	.interpolate("basis");

var lineGraph = svg.append("path")
    .attr("d", lineFunction(lineData))
    .attr("stroke", "blue")
    .attr("stroke-width", 3)
    .attr("fill", "none");

Selection and manipulation

Selection

Select an element

// Select body
var body = d3.select("body")

// Select an element by id
var byId = d3.select("#id_my_element")

Select all element

// Select all rect
d3.selectAll("rect")

Append

Single

// Select svg element
var svg = d3.select("svg")

// Append a rectangle
var rect = svg.append("rect")
rect.attr("x", 10)
rect.attr("y", 10)
rect.attr("width", 30)
rect.attr("height", 30)

Collection

d3.selectAll("section")
  .append("text")

Data manipulation

Data are array

Number

var oneDim = [1,2,3,5]
var twoDim = [[1,1],[2,5],[3,6]]

Or Object

var complexData = [
  {x: 100, y: 80, count: 12},
  {x: 120, y: 60, count: 20},
  {x: 140, y: 40, count: 8},
  {x: 120, y: 120, count: 17}
]

Data to Element

Create a circle selection mapped to data

var complexData = [
  {x: 100, y: 80, count: 12},
  {x: 120, y: 60, count: 20},
  {x: 140, y: 40, count: 8},
  {x: 120, y: 120, count: 17}
]

svg.selectAll("circle")
  .data(complexData)
  .enter().append("circ")
  .attr("cx", function(d){return d.x})
  .attr("cy", function(d){return d.y})
  .attr("r", function(d){return d.count})

Data to Element

Result

.data()

  • Create multiple element
  • Compute join
  • Use .enter() for appending missing element

TODO ENTER UPDATE EXIST AND JOIN

Graph function or data

Draw your graph with d3

  • Create the SVG canvas
  • Load some data
  • Define scale
  • Draw axes
  • Draw function or data
  • add label, change color, configure ticks, etc

Create SVG canvas

var margin = {top: 20, right: 20, bottom: 30, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var svg = d3.select("#my_svg").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

Loading data

  • d3.xhr
  • d3.tsv
  • d3.json
  • d3.xml
  • Use other library (JQuery, AngularJS, etc)

For this demo, we use static data in a var

var data = [[1393940673, 14], [1393940683, 27], ...

Define scale

Exemple: Linear scale

var y = d3.scale.linear().range([height,0]);
y.domain([0,d3.max(data, function (d) {return d[1]})]);
var axey = d3.svg.axis().scale(y).orient('left');
svg.append('g').attr('class', 'axis').call(axey);

Exemple: Linear time scale

var x = d3.time.scale().range([0,width]);
x.domain(d3.extent(data, function (d) {
	return new Date(d[0] * 1000);
}));
var axex = d3.svg.axis().scale(x).orient('bottom');
var xaxis = svg.append('g').attr('class', 'axis').attr('transform', 'translate(0,' + height + ')').call(axex);
xaxis.selectAll('text').style('text-anchor', 'end').attr('dx', '-.8em').attr('dy', '.15em').attr('transform', function () {
	return 'rotate(-60)';
});

Draw axes

Draw axes CSS

CSS

.axis_d3_h1_axes {
	font: 16px sans-serif;
}
.axis_d3_h1_axes path,
.axis_d3_h1_axes line {
	fill: none;
	stroke: #000;
	shape-rendering: crispEdges;
}
.x.axis_d3_h1_axes path {
	display: none;
}
.line_d3_h1_axes {
	fill: none;
	stroke: steelblue;
	stroke-width: 2px;
}

Draw axes with CSS

Draw data

var line = d3.svg.line()
	.x(function (d) {return x(d[0] * 1000);})
	.y(function (d) {return y(d[1]);});
svg.append('path').datum(data).attr('class', 'line_d3_h1_axes').attr('d', line);

Draw data

SVG et CSS


					

Finaliser le graphe

Visualiser une distribution

Histogramme

Histogramme

  • Utiliser une échelle discrète
  • Dessiner un histogramme

Utiliser une échelle discrète

var x = d3.scale.ordinal().rangeRoundBands([0,width], 0.1);
x.domain(distributionData.map(function (d) {return d[0];}));
var axex = d3.svg.axis().scale(x).orient('bottom');
var xaxis = svg.append('g').attr('class', 'axis').attr('transform', 'translate(0,' + height + ')').call(axex);
xaxis.selectAll('text').style('text-anchor', 'end').attr('dx', '-.8em').attr('dy', '.15em').attr('transform', function () {
	return 'rotate(-60)';
});

Utiliser une échelle discrète

Dessiner l'histogramme

var x = d3.scale.ordinal().rangeRoundBands([0,width], 0.1);
x.domain(distributionData.map(function (d) {return d[0];}));
var axex = d3.svg.axis().scale(x).orient('bottom');
var xaxis = svg.append('g').attr('class', 'axis').attr('transform', 'translate(0,' + height + ')').call(axex);
xaxis.selectAll('text').style('text-anchor', 'end').attr('dx', '-.8em').attr('dy', '.15em').attr('transform', function () {
	return 'rotate(-60)';
});

Ajouter la distribution

var line = d3.svg.line().interpolate('basis').x(function (d) {
  return x(d.key);
}).y(function (d) {
  return y1(d.totalcount / distributionDataFull.total);
});
svg.datum(distributionData);
svg.append('path').attr('class', 'line').attr('d', line).style('stroke', 'orange')
.style('fill', 'none').style('stroke-width', '2px');

Dessiner la grille

var ygrid = d3.svg.axis().scale(y1).orient('left');
svg.append('g').attr('class', 'grid').call(ygrid.tickSize(-width, 0, 0).tickFormat(''));

Résultat

D3 Layout

Display Hierarchical data

Display graph data

First Result

Using group info