Está en la página 1de 22

Layouts y exportando el resultado a

un archivo
[8.1] ¿Cómo estudiar este tema?

[8.2] Histogram, Stack y Force Layout

[8.3] Exportando el resultado a PDF, Bitmaps y SVG

[8.4] Otras librerías sobre D3.js

8
TEMA
Esquema

TEMA 8 – Esquema
Acabando con las visualizaciones
(Layouts y exportando el resultado a un archivo)

Otras librerías de
Exportando la visualización Exportando la visualización
visualización

Histogram Stack Force PDF PNG SVG Basadas en D3 No D3


Herramienta de Visualización

© Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

Ideas clave

8.1. ¿Cómo estudiar este tema?

Para estudiar este tema lee las Ideas clave que encontrarás a continuación.

En este tema intentaremos ultimar los conceptos básicos de D3.js. Hablaremos de tres
temas principales:

» Layouts, que podríamos decir que son una forma de predefinir el tipo de visualización
que vamos a utilizar.
» Exportar las visualizaciones a otros formatos para poderla utilizar en contextos
diferentes.
» Mencionaremos también otras librerías de visualizaciones, algunas de ellas
basadas en D3.js.

Reflexiona al final de este tema sobre tu nivel de D3.js, porque a estas alturas deberías tener
soltura. En caso contrario, dedícale más horas a practicar.

Acabado este tema ya solo nos quedan dos. Este es el último tema en el que trataremos
conceptos de D3.js, pero eso nunca será un problema. Lo importante es que acabes este curso
siendo capaz de diseñar e implementar nuestras propias visualizaciones, ya sea desde cero o
modificando una existente. En particular, este tema introducirá los conceptos mínimos de
D3.js.

Conceptos e ideas han ido completando las páginas de nuestro temario. Pero solo
conseguirás dominar D3.js cuando hayas practicado e intentes hacer cosas nuevas. Hasta
ahora el nivel ha sido muy básico. Lo que veremos en los siguientes temas requiere
mucho más esfuerzo y, seguramente, equivocarse a menudo.

El mismo discurso que doy en todos los temas… Intenta asentar los conceptos poco a
poco. Si intentas rápidamente modificar visualizaciones tendrás problemas. Estás
aprendiendo, no hay nada malo en empezar lento pero seguro. No te confíes porque
tengas conocimientos de programación o hasta conocimiento de JavaScript. Con D3 es
difícil perderse.

8.2. Histogram, Stack y Force Layout

TEMA 8 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

En esta sección nos apoyaremos principalmente en el libro: Dewar, M. (2012). Getting


started with D3. Sebastopol: O'Reilly Media.

Utilizaremos uno de los datasets que el autor tiene en Github


(https://github.com/mikedewar/getting_started_with_d3). Para generar este gráfico
habría que partir del archivo JSON, cargándolo por ejemplo en Plunker. Se puede
descargar o copiar desde la siguiente dirección:

https://github.com/mikedewar/getting_started_with_d3/blob/master/visualisations/
data/stations_graph.json

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<script language="javascript" type="text/javascript"
src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript">
function read(){
d3.json("stations_graph.json", function(json) {
visualizeLayout(json);
});
}
function visualizeLayout(data){

var width = 1500,


height = 1500;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var node = svg.selectAll("circle.node")
.data(data.nodes)
.enter()
.append("circle")

TEMA 8 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

.attr("class", "node")
.attr("r", 12);
var link = svg.selectAll("line.link")
.data(data.links)
.enter().append("line")
.style("stroke","black");
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height])
.nodes(data.nodes)
.links(data.links)
.start();
force.on("tick", function() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
}
</script>
</head>
<body onload="read()">
</body>
</html>

TEMA 8 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

El resultado que deberías obtener es el siguiente:

Como siempre dividiremos el código y lo explicaremos por partes. Antes explicaremos el


archivo json. Contiene los nodos que son paradas de metro y las conexiones entre las
paradas de metro. El gráfico simboliza las conexiones del metro.

var width = 1500,


height = 1500;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);

Nada nuevo, ¿no?

var node = svg.selectAll("circle.node")


.data(data.nodes)
.enter()
.append("circle")
.attr("class", "node")
.attr("r", 12);

TEMA 8 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

Ahora sí que hay una diferencia, aunque, por ahora, similar a cuando dibujamos el
histograma. Definimos los círculos o puntos del gráfico.

var link = svg.selectAll("line.link")


.data(data.links)
.enter()
.append("line")
.style("stroke","black");

Aquí definimos las líneas entre los puntos.

var force = d3.layout.force()


.charge(-120)
.linkDistance(30)
.size([width, height])
.nodes(data.nodes)
.links(data.links)
.start();

Definimos el algoritmo que queremos utilizar. En este caso layout.force. Hemos de


pensar que todos los atributos son particulares a los diferentes algoritmos. Si no se
entiende demasiado lo que acabo de decir, lo expresaré de otra forma: nodes y links no
son elementos generales, sino que existen en el caso particular de layout.force.

force.on("tick", function() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });

Con la función force.on adaptamos los valores de nuestro dataset a los requerimientos del
algoritmo.

TEMA 8 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

Por último, algo muy típico de este tipo de gráficos es proporcionar la habilidad de arrastrar
los nodos por la pantalla. Esto se consigue añadiendo una simple línea de código:

node.call(force.drag);

Haremos lo mismo para trabajar con la idea del histograma. Para este ejemplo crea un
archivo que se llame interarrival_times.json con los datos que tenemos en:

https://github.com/mikedewar/getting_started_with_d3/blob/master/visualisations/
data/interarrival_times.json

Los datos que tenemos en este archivo son los tiempos de llegada en todas las paradas
de cinco líneas de metro. Si te da problemas de memoria Plunker no dudes en utilizar
otros editores como WebStorm.

Para la parte del histograma:

var histogram = d3.layout.histogram()


.bins(d3.range(1.5, 23 , 2.2))
.frequency(false);

Creamos un objeto histograma que nos permite organizar nuestras observaciones, que
tratamos en grupos continuos (bins). Generamos con la función range grupos desde 1.5
hasta 23 en unidades de 2.2. Frequency indica que el histograma ha de ser normalizado
y no hacer un muestreo por grupo o bin.

var counts = data.map(


function(d){
return histogram(d.interarrival_times)
}
);

Con esta función mapeamos los valores a nuestro histograma. El resultado que deberíais
obtener es la figura siguiente.

TEMA 8 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

Tenemos cinco líneas, por lo tanto, combinaremos el layout del histograma con las
barras apiladas: Stack Charts. Introduciremos el nuevo layout:

var stack = d3.layout.stack();

Le pasamos los valores y dibujamos los rectángulos:

svg.selectAll("g")
.data(stack(counts))
.enter()
.append("g")
.attr("class",function(d,i){return lines[i]})
.selectAll("rect")
.data(function(d){return d})
.enter()
.append("rect")
.attr("x",function(d){return x_scale(d.x) })
.attr("y",function(d){return count_scale(d.y) - (height - margin -
count_scale(d.y0))})
.attr("width", function(d){return x_scale(d.x + d.dx) - x_scale(d.x)})
.attr("height", function(d){return height - margin - count_scale(d.y)});

En principio todas las funciones las hemos tratado en temas anteriores. Si tienes dudas,
puedes plantearlas en el foro.

TEMA 8 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

El ejemplo final es el siguiente, basado en el repositorio Github del libro que he


comentado anteriormente:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<link rel="stylesheet" type="text/css"
href="https://github.com/mikedewar/getting_started_with_d3/blob/master
/visualisations/train_colours.css" />
<style>
rect {
stroke: none;
}
line {
stroke: black;
}
path {
stroke: black;
fill: none;
}
</style>
<script>
function draw(data) {
"use strict";
var width = 800,
height = 300,
margin = 50;

var stack = d3.layout.stack()

var bar_width = 2.2,


bar_ max = 23;

var histogram = d3.layout.histogram()

TEMA 8 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

.bins(d3.range(1.5,bar_max,bar_width))
.frequency(false)

var lines = data.map(function(d){return "Line_" + d.route_id});

var counts = data.map(


function(d){
return histogram(d.interarrival_times)
}
);

function nested_stat(d, stat, accessor){


return stat(counts, function(d){
return stat(d.map(accessor))
})
}

var max_count = 2
var count_scale = d3.scale.linear()
.domain([0, max_count])
.range([height-margin, margin])
.nice();

var x_scale = d3.scale.linear()


.domain([
nested_stat(counts, d3.min, function(di){return di.x}),
nested_stat(counts, d3.max, function(di){return di.x})
])
.range([margin, width])

var xaxis = d3.svg.axis().scale(x_scale),


yaxis = d3.svg.axis().scale(count_scale).orient('left');

var svg = d3.select('body')


.append('svg')
.attr('width', width)

TEMA 8 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

.attr('height', height);

svg.selectAll('g')
.data(stack(counts))
.enter()
.append('g')
.attr('class',function(d,i){return lines[i]})
.selectAll('rect')
.data(function(d){return d})
.enter()
.append('rect')
.attr('x',function(d){return x_scale(d.x) })
.attr('y',function(d){return count_scale(d.y) - (height - margin -
count_scale(d.y0))})
.attr('width', function(d){return x_scale(d.x + d.dx) - x_scale(d.x)})
.attr('height', function(d){return height - margin - count_scale(d.y)});

svg.append('g').attr('transform','translate(0,' + (height-margin)
+ ')').call(xaxis)

svg.append('text').attr('x',x_scale(10)).attr('y', height -
margin/5).text('scheduled wait time (minutes)')
}
</script>
</head>
<body>
<script>
d3.json('interarrival_times.json', draw);
</script>
</body>
</html>

TEMA 8 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

Y el resultado gráfico:

8.3. Exportando el resultado a PDF, Bitmaps y SVG

Esta sección no está muy relacionada con D3.js en sí, pero es evidente la utilidad de poder
exportar nuestro gráfico desde la ventana del navegador a otros formatos.

Tenemos la primera opción que es la captura de pantalla que nos generará un archivo de tipo
Bitmap o PNG. Es la forma más antigua y más fácil para obtener resultados, aunque de baja
calidad.

Print Screen en PC y ⌘-Shift-4 en Mac.

También podemos «Imprimir en PDF». Pero la opción más interesante es trabajar con
SVG, así podremos modificar la imagen en Photoshop, escalar la imagen a todos los
tamaños, etc.

Para eso, en el caso anterior, seleccionaremos el gráfico, pulsaremos el botón derecho del
ratón y seleccionaremos «Inspeccionar elemento». Como indica la siguiente figura.

TEMA 8 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

Copiaremos todo lo que hay entre las etiquetas <svg>…</svg>.

Lo copiaremos en un archivo nuevo que tenga la extensión .svg. Ese archivo lo podrás
abrir con Acrobat Reader, Photoshop, etc.

8.4. Otras librerías sobre D3.js

En este apartado mencionamos algunas librerías que, basadas en D3, intentan


simplificar la toma de contacto con esta flexible librería:

» Insights. Alojada en Github, leeremos el archivo README.md para saber cómo


hacerla funcionar. Es una librería para dibujar grafos.

https://github.com/ignacioola/insights

TEMA 8 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

» Dimple. Con Dimple, convertiremos visualizaciones D3js en una librería bastante


parecida en simplicidad a Google Charts.

http://dimplejs.org/

» Visual Sedimentation. Basada en D3.js, JQuery y Box2DWeb, se especializa en


visualizar datos en tiempo real.

http://www.visualsedimentation.org/

» NVD3. Simplifica de manera similar a Dimple las visualizaciones más populares


basadas en D3.js.

http://nvd3.org/

» Tenxer. Otro ejemplo de librería que simplifica line charts y bar charts basadas en D3js.

http://tenxer.github.io/xcharts/

Al margen de las librerías basadas en D3.js, podemos tener en cuenta las siguientes
librerías:

» Flot charts. Una librería basada en JQuery al estilo jqPlot.

http://www.flotcharts.org/

» Infovis JT. Una de las librerías de visualizaciones en JavaScript más antiguas con
visualizaciones comunes.

http://philogb.github.io/jit/

» HighCharts. Basada también en JavaScript, incluye a parte de las visualizaciones


más comunes mapas.

http://www.highcharts.com/

TEMA 8 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

» Timeline JS. Se especializa en visualizar líneas del tiempo.

http://timeline.knightlab.com/

» Kartograph. A diferencia del resto se basa en Python y es para visualizar mapas.

http://kartograph.org/

TEMA 8 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

Lo + recomendado

No dejes de leer…

Getting started with D3

Dewar, M. (2012). Getting started with D3. Sebastopol: O'Reilly Media.

Este libro es muy práctico para aprender a utilizar una combinación


de JavaScript y SVG y construir desde gráficos de barras simples a
infografías complejas.

No dejes de ver…

Drawing dynamic visualizations (Stanford HCI seminar)

En este seminario podrás ver la presentación de una herramienta para la elaboración de


imágenes dinámicas.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


http://vimeo.com/66085662

TEMA 8 – Lo + recomendado © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

Europe 24

Este vídeo nos muestra un buen ejemplo de visualización de tráfico aéreo.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


http://vimeo.com/88093956

WDCNZ 2013: Data Driven Delirious: An Intro to Data Visualisation


Using D3.js

Es bueno escuchar lo que nos pueden enseñar otros expertos, así que en este vídeo podéis
encontrar una excelente charla de Alex Gibson en WDCNZ sobre visualización de datos
con D3.js.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


http://vimeo.com/72467564

TEMA 8 – Lo + recomendado © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

+ Información

A fondo

Interactive Data Visualization for the Web

Murray, S. (2013). Interactive Data Visualization for the Web. Sebastopol: O’ Reilly.

En el capítulo 2, apartado «Alternatives», de este libro, que ya conoces


y puedes leerlo online, podrás encontrar más librerías que enlazan
directamente a sus páginas.

Accede al capítulo desde el aula virtual o a través de las siguientes direcciones web:
http://chimera.labs.oreilly.com/books/1230000000345/ch02.html#_easy_charts

Data Visualization Libraries Based on D3.js

Este artículo contiene un listado de librerías especializadas en D3.

Accede al artículo desde el aula virtual o a través de las siguientes direcciones web:
http://mikemcdearmon.com/portfolio/techposts/charting-libraries-using-d3

TEMA 8 – + Información © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

Webgrafía

Till Nagel

Till Nagel tiene su propia web y creó su propia librería (unfolding).

Accede a la página desde el aula virtual o a través de la siguiente dirección:


http://tillnagel.com/

Aesthetics Weblog

Este interesante weblog sobre infographics explora la relación simbiótica entre el diseño
creativo y el campo de la visualización de la información. Más específicamente, recoge
proyectos que representan los datos o la información de un modo original.

Accede a la página desde el aula virtual o a través de la siguiente dirección:


http://infosthetics.com/

TEMA 8 – + Información © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

Test

1. Cuál de los layouts no existe:


A. d3.layout.stack().
B. d3.layout.histogram()
C. d3.layout.force()
D. Todos los anteriores existen y son correctos.

2. Wait time aparece en el código que tienes a continuación ¿tiene este alguna
repercusión en lo que tarda en visualizarse el gráfico?
svg.append('text').attr('x',x_scale(10)).attr('y', height -
margin/5).text('scheduled wait time (minutes)')
A. Sí.
B. No.

3. Si queremos exportar nuestra visualización a un archivo SVG, tenemos que:


A. Exportar nuestro gráfico con la función D3.exportSVG.
B. Copiar el código HTML generado y copiarlo en un archivo SVG.
C. Ambas opciones son válidas.

4. ¿Cuál de las siguientes librerías está basada en D3?


A. Infovis JT.
B. NVD3.
C. HighCharts.

5. ¿Cuál de las siguientes librerías no es basada en D3?


A. Infovis JT.
B. NVD3.
C. Visual Sedimentation.

TEMA 8 – Test © Universidad Internacional de La Rioja (UNIR)


Herramienta de Visualización

6. ¿Es la sintaxis correcta?


var node = svg.selectAll("circle.node")
.data(data.nodes)
.enter()
.append("circle")
.attr("class", "node")
.attr("r", 12);
A. Sí.
B. No

7. ¿Qué es lo que no hace el siguiente código?


var histogram = d3.layout.histogram()
.bins(d3.range(1.5, 23 , 2.2))
.frequency(false);

A. Crea un objeto histograma.


B. Lo divide en bins que van desde 1.5 hasta 23 en grupos de 2.2.
C. Dibuja un histograma.
D. Hace todo lo anterior.

8. La librería Kartograph:
A. Es para dibujar mapas.
B. No existe.

9. Utilizando captura de pantalla para exportar nuestra visualización a otro formato:


A. Generamos un archivo Bitmaps.
B. Generamos un archivo SVG.
C. Generamos un archivo PDF

10. ¿Cuál es el comportamiento al aplicar la función node.call(force.drag);?


A. Los nodos se pueden arrastrar y cuando sueltas el nodo se queda en esa misma
posición.
B. Los nodos se pueden arrastrar y cuando sueltas el nodo vuelve a su posición
original.
C. Ninguna de las anteriores.

TEMA 8 – Test © Universidad Internacional de La Rioja (UNIR)

También podría gustarte