Skip to content

Instantly share code, notes, and snippets.

@aaizemberg
Last active March 22, 2023 19:49
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save aaizemberg/6153101 to your computer and use it in GitHub Desktop.
Save aaizemberg/6153101 to your computer and use it in GitHub Desktop.
d3.js para principiantes
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/)
@elfrasco
Copy link

Excelent work!!

@Winia7070
Copy link

Ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment