Last active
March 22, 2023 19:49
-
-
Save aaizemberg/6153101 to your computer and use it in GitHub Desktop.
d3.js para principiantes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Ariel Aizemberg | |
@aaizemberg ( https://twitter.com/aaizemberg ) | |
http://www.linkedin.com/in/arielaizemberg | |
Introducción | |
Que es D3 | |
Quién creó esta librería | |
Mirar algunos ejemplos de la galería | |
https://github.com/mbostock/d3/wiki/Gallery | |
http://visualizing.org/explore#featured=1&tools=741&sort=recent | |
http://biovisualize.github.io/d3visualization/ | |
Ventajas de esta librería, con respecto a su antecesor Protovis ( http://stackoverflow.com/questions/6212104/protovis-vs-d3-js ) | |
Como podemos representar los datos | |
string | |
vector | |
csv | |
xml | |
JSON | |
Mapeando datos (binding data) | |
Asociando datos a elementos de una página HTML5 | |
armando una página HTML5 | |
<p> párrafos | |
<div> div | |
<svg> elementos gráficos | |
... también se podría usar <canvas> o <WebGL> (no en este workshop) | |
Bibliografía: | |
- Getting Started with D3, Mike Dewar, 2012 | |
- Scott Murray ( http://alignedleft.com/ ) | |
Interactive Data Visualization for the Web, Scott Murray, 2013 | |
http://chimera.labs.oreilly.com/books/1230000000345/index.html | |
bayd3: Scott Murray - Learning d3.js 02.21.2013 | |
Scott Murray giving an introduction to d3.js at the Bay Area d3 User group meetup | |
http://youtu.be/b9s7B7HYXhc | |
- Try D3 now > http://christopheviau.com/d3_tutorial/ | |
- stackoverflow > http://stackoverflow.com/questions/tagged/d3.js | |
Duración: 2 a 4 hs | |
= Que es D3 = | |
D3.js | |
Data-Driven Documents | |
A JavaScript library for manipulating documents based on data using HTML (CSS, SVG, ...) | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
= Quién creó esta librería = | |
Mike Bostock | |
http://bost.ocks.org/mike/ | |
https://github.com/mbostock | |
Mike Bostock - D3 - Data Visualization Meetup | |
video -> http://vimeo.com/29458354 | |
presentación -> http://mbostock.github.com/d3/talk/20110921/#0 | |
Entrevista que le hicieron a Mike Bostock (y a Shan Carter) en DataStories | |
http://datastori.es/data-stories-22-nyt-graphics-and-d3-with-mike-bostock-and-shan-carter/ | |
Nota: | |
vamos a usar jsbin ( http://jsbin.com/ ) para probar los ejemplos y ver el resultado | |
= Datos = | |
string ó cadena de caracteres = "Hola Mundo" | |
var s = "hola mundo" | |
vector = ["hola", "mundo"] | |
vector = [0, 1, 1, 2, 3, 5, 8, 13, 21] | |
un archivo csv | |
a,b,c | |
1,2,3 | |
4,5,6 | |
7,8,9 | |
xml | |
http://www.w3schools.com/xml/ | |
json | |
http://www.w3schools.com/json/ | |
Variables en Javascript | |
var mensaje = "esto es un string o cadena de caracteres"; | |
var vocales = ["a","e","i","o","u"]; | |
var fibonacci = [0,1,1,2,3,5,8,13]; | |
var matrix = [ | |
[ 0, 1, 2, 3], | |
[ 4, 5, 6, 7], | |
[ 8, 9, 10, 11], | |
[12, 13, 14, 15] | |
]; | |
# JSON | |
var letters = [ | |
{name: "A", frequency: 0.08167}, | |
{name: "B", frequency: 0.01492}, | |
{name: "C", frequency: 0.02780}, | |
{name: "D", frequency: 0.04253}, | |
{name: "E", frequency: 0.12702} | |
]; | |
otro ejemplo | |
{ | |
"firstName": "John", | |
"lastName": "Smith", | |
"isAlive": true, | |
"age": 25, | |
"height_cm": 167.6, | |
"address": { | |
"streetAddress": "21 2nd Street", | |
"city": "New York", | |
"state": "NY", | |
"postalCode": "10021-3100" | |
}, | |
"phoneNumbers": [ | |
{ | |
"type": "home", | |
"number": "212 555-1234" | |
}, | |
{ | |
"type": "office", | |
"number": "646 555-4567" | |
} | |
], | |
"children": [], | |
"spouse": null | |
} | |
---------------------------------------------------------------------- | |
# | |
# mi primer página HTML5 | |
# | |
<!DOCTYPE html> | |
<html> | |
<body> | |
<p>este es un párrafo</p> | |
</body> | |
</html> | |
---------------------------------------------------------------------- | |
# | |
# Agregamos la librería d3.js | |
# | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
</head> | |
<body> | |
<p>este es un párrafo</p> | |
<script> | |
d3.select("body").append("p").text("este párrafo lo estoy creando desde d3.js"); | |
</script> | |
</body> | |
</html> | |
---------------------------------------------------------------------- | |
# | |
# Agregamos D3.js | |
# Mapeando datos a elementos de la página | |
# Binding Data | |
# | |
# .. tenemos todo listo, pero hay que explicar el function(d,i) | |
# | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
var v = ["hola","mundo","esto es muy","complicado"]; | |
var body = d3.select("body"); | |
body.selectAll("p") | |
.data(v) | |
.enter() | |
.append("p") | |
.text("aqui va el texto"); | |
// .text( function(d) { return d; } ); | |
// .text( function(d,i) { return i + " - " + d; } ); | |
</script> | |
</body> | |
</html> | |
---------------------------------------------------------------------- | |
# | |
# usando CSS | |
# | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<style> | |
p.min { color: #f0f0f0; } | |
p.max { color: #636363; } | |
p.resto { color: #bdbdbd; } | |
</style> | |
</head> | |
<body> | |
<script> | |
var data = [ | |
{"id":"danielscioli", "followers":803859, "nombre":"Daniel Scioli"}, | |
{"id":"SergioMassa", "followers":404578, "nombre":"Sergio Massa"}, | |
{"id":"fernandosolanas", "followers":167367, "nombre":"Pino Solanas"}, | |
{"id":"minsaurralde", "followers":364368, "nombre":"Martín Insaurralde"} | |
]; | |
var max = data[0].followers; | |
var min = data[0].followers; | |
for (var i = 0; i < data.length; i++) { | |
if ( data[i].followers > max ) { max = data[i].followers; } | |
if ( data[i].followers < min ) { min = data[i].followers; } | |
} | |
var body = d3.select("body"); | |
body.selectAll("p") | |
.data(data) | |
.enter() | |
.append("p") | |
.attr("class",function(d,i) { | |
if (d.followers == min) { | |
return "min"; | |
} else if (d.followers == max) { | |
return "max"; | |
} else { | |
return "resto"; | |
} | |
}) | |
.text( function(d,i) { return i+1 + ") " + d.nombre + " tiene " + d.followers + " seguidores" ; } ); | |
</script> | |
</body> | |
</html> | |
---------------------------------------------------------------------- | |
# | |
# SVG (gráficos vectoriales escalables) | |
# | |
# http://es.wikipedia.org/wiki/Scalable_Vector_Graphics | |
# http://en.wikipedia.org/wiki/Scalable_Vector_Graphics | |
# | |
# SVG Basic Shapes | |
# http://www.w3.org/TR/SVG/shapes.html | |
# | |
# Ej. | |
<svg width="200" height="200"> | |
<rect x="0" y="0" rx="5" ry="5" width="200" height="200" fill="none" stroke-width="1" stroke="grey" /> | |
<circle cx="10" cy="10" r="5" fill="blue" stroke="white" stroke-width="1"/> | |
<circle cx="25" cy="25" r="10" fill="blue" stroke="white" stroke-width="1"/> | |
<circle cx="50" cy="50" r="30" fill="blue" fill-opacity="0.5" stroke="white" stroke-width="1.5"/> | |
<circle cx="100" cy="100" r="60" fill="blue" fill-opacity="0.5" stroke="white" stroke-width="1.5"/> | |
<text x="45" y=185 font-family="ubuntu,arial,sans-serif" font-size="20" fill="black" > | |
hola mundo | |
</text> | |
</svg> | |
---------------------------------------------------------------------- | |
# | |
# <svg> dos círculos uno generado desde D3 y otro no (con algo de interacción) | |
# | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
</head> | |
<body> | |
<div id="viz"></div> | |
<script type="text/javascript"> | |
var svg_generado_desde_d3 = d3.select("#viz") | |
.append("svg") | |
.attr("width", 100) | |
.attr("height", 100); | |
svg_generado_desde_d3.append("circle") | |
.attr("r", 40).attr("cx", 50).attr("cy", 50).style("stroke", "white").style("fill", "black") | |
.on("mouseover", function() { d3.select(this).style("fill", "gray"); }) | |
.on("mouseout" , function() { d3.select(this).style("fill", "black"); }); | |
</script> | |
<svg width="100" height="100"> | |
<circle r="40" cx="50" cy="50" stroke="white" fill="black" | |
onmouseover="evt.target.setAttribute('fill', 'gray');" | |
onmouseout="evt.target.setAttribute('fill', 'black');" /> | |
</svg> | |
</body> | |
</html> | |
---------------------------------------------------------------------- | |
# | |
# <svg> un círculo y actualizo el radio con un boton | |
# | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
</head> | |
<body> | |
<div id="viz"></div> | |
<button onclick="actualizar()">cambiar el radio</button> | |
<script> | |
var svg = d3.select("#viz") | |
.append("svg") | |
.attr("width", 100) | |
.attr("height", 100); | |
var myCircle = svg.append("circle") | |
.attr("r", 50) | |
.attr("cx", 50) | |
.attr("cy", 50) | |
.attr("fill","red"); | |
function actualizar() { | |
myCircle.transition() | |
.attr("r",50*Math.random()); | |
} | |
</script> | |
</body> | |
</html> | |
---------------------------------------------------------------------- | |
# | |
# <svg> un círculo y actualizo su radio con un timer (una vez por segundo) | |
# | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
</head> | |
<body> | |
<div id="viz"></div> | |
<button id="btn" onclick="stop()">stop</button> | |
<script> | |
var svg = d3.select("#viz") | |
.append("svg") | |
.attr("width", 100) | |
.attr("height", 100); | |
var myCircle = svg.append("circle") | |
.attr("r", 50) | |
.attr("cx", 50) | |
.attr("cy", 50) | |
.attr("fill","red"); | |
var timer = setInterval(function() { | |
myCircle.transition() | |
.attr("r",50*Math.random()); | |
},1000); | |
function stop() { | |
clearInterval(timer); | |
} | |
</script> | |
</body> | |
</html> | |
---------------------------------------------------------------------- | |
# | |
# actualizando el origen de los datos en cada click del boton | |
# | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
</head> | |
<body> | |
<div id="viz"></div> | |
<button onclick="update()">cambiar el indice de los datos</button> | |
<script> | |
var idx = 0; | |
var data = [ [50,10] , [15,45], [10,10], [50,50] ]; | |
var svg = d3.select("#viz") | |
.append("svg") | |
.attr("width", 200) | |
.attr("height", 100); | |
var rectangle = svg.append("rect") | |
.attr("x", 0) | |
.attr("y", 0) | |
.attr("rx", 5) | |
.attr("ry", 5) | |
.attr("width", 200) | |
.attr("height", 100) | |
.style("fill","black"); | |
var myCircle = svg.selectAll("circulos") | |
.data(data[idx]).enter().append("circle") | |
.attr("r", function(d,i) {return d;}) | |
.attr("cx", function(d,i) {return 50+(i*100);}) | |
.attr("cy", 50) | |
.style("fill","CornflowerBlue"); | |
function update() { | |
idx++; | |
idx = idx % 4; | |
myCircle.data(data[idx]) | |
.transition() | |
.attr("r",function(d){return d;}); | |
} | |
</script> | |
</body> | |
</html> | |
---------------------------------------------------------------------- | |
# | |
# Armando un scatterplot | |
# | |
# Input! Domain! (mi conjunto de datos de entrada es el dominio) | |
# Output! Range! (la salida, son los pixeles en la pantalla) | |
# | |
# consoleLog entendiendo el vector que se genera a partir de la llamada a "ticks(n)" | |
# <scale>.ticks | |
# | |
# truco para invertir el eje Y | |
# .range([height,0]); | |
# | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<meta charset=utf-8 /> | |
</head> | |
<body> | |
<script> | |
var datos = [ [1, 1], [2, 2], [3, 3], [4, 4] ]; | |
var width = 300; | |
var height = 300; | |
var x = d3.scale.linear() | |
.domain ([0, 5]) | |
.range([0, width]); | |
var y = d3.scale.linear() | |
.domain ([0, 5]) | |
.range([height,0]); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
svg.selectAll("xline") | |
.data(x.ticks(4)) | |
.enter().append("line") | |
.attr("x1", x) | |
.attr("x2", x) | |
// .attr("x1", function(d,i) { return x(i) } ) | |
// .attr("x2", function(d,i) { return x(i) } ) | |
.attr("y1", 0) | |
.attr("y2", height) | |
.style("stroke", "#ccc"); | |
svg.selectAll("yline") | |
.data(y.ticks(4)) | |
.enter().append("line") | |
.attr("y1", y) | |
.attr("y2", y) | |
.attr("x1", 0) | |
.attr("x2", width) | |
.style("stroke", "#ccc"); | |
svg.selectAll("dots") | |
.data(datos) | |
.enter() | |
.append("circle") | |
.attr("cx", function (d) { return x(d[0]); } ) | |
.attr("cy", function (d) { return y(d[1]); } ) | |
.attr("r", 8) | |
.style("opacity", 0.5); | |
</script> | |
</body> | |
</html> | |
---------------------------------------------------------------------- | |
# | |
# Terminamos con el cuarteto de Anscombe | |
# | |
http://bl.ocks.org/aaizemberg/8245718 | |
---------------------------------------------------------------------- | |
# | |
# FIN | |
# | |
bonus track | |
=========== | |
Si no queres programar y queres usar algo de D3 | |
1. http://app.raw.densitydesign.org/ | |
Si queres programar, pero te piden un gráfico estándar: | |
1. [C3](http://c3js.org/) | |
2. [D3 plus](http://d3plus.org/) | |
3. [Rickshaw | is a JavaScript toolkit for creating interactive time series graphs](http://code.shutterstock.com/rickshaw/) | |
4. [dimple | An object-oriented API for business analytics powered by d3](http://dimplejs.org/) | |
5. [NVD3 | Re-usable charts for d3.js](http://nvd3.org/) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Excelent work!!