Anda di halaman 1dari 68

Tutorial de D3 en Espaol

Bienvenido a la versin traducida al espaol del excelente tutorial de D3 escrito por Scott
Murray. En la medida de lo posible, me he ceido estrictamente al contenido de la versin
original, salvo en aquellos casos donde por cuestiones del leguaje, no ha sido posible.

Acerca de este Tutorial


Cada una de las lecciones de este tutorial busca ser:

Breve.

Enfocada, hacia un solo tema a la vez.

Modular, de tal forma que cada persona pueda usar lo que le sea til.

Lo ms Completa posible, con cdigo de ejemplo para cada tema expuesto.

Dinmica, actualizada y expandible en la forma que se requiera.

Gratis y bajo una licencia sin restricciones de uso sobre el cdigo.

Enfoque
Los cursos de este tutorial han evolucionado de mi proceso de aprendizaje de la librera D3.
Como bien se sabe, D3 es una excelente herramienta escrita por Mike Bostock para desplegar
datos dentro de pginas web. Mucha gente, incluyndome a mi, llega a D3 con experiencia en
diseo, cartografa y visualizacin de datos, pero sin ser necesariamente programadores o
ingenieros de sistemas.
D3 utiliza tcnicas avanzadas de JavaScript, por consiguiente para aprender D3 usualmente es
necesario aprender bastante de ese lenguaje de programacin. Para muchas personas
provenientes del rea de visualizacin de datos, D3 es su primera incursin en JavaScript. Si bien
es difcil aprender un lenguaje de programacin nuevo, es an ms difcil cuando se busca
aprender una herramienta nueva construida en ese lenguaje. D3 es muy novedoso y permite crear
cosas increbles con JavaScript que probablemente nunca se hubiera pensado que fueran
factibles. El tiempo que invierta aprendiendo el lenguaje y la herramienta sin duda le traer
grandes beneficios.
Mi objetivo es reducir su tiempo de aprendizaje para que comience a crear visualizaciones
espectaculares muy pronto.

Pre-requisitos

En lo posible, usted debe:

Tener algn conocimiento de HTML, el DOM y CSS.

Alguna experiencia previa en programacin de computadores.

Haya escuchado sobre jQuery o haya escrito algo en JavaScript.

No le tiene temor a ciertas siglas como CSV, SVG, o JSON.

Est interesado en crear visualizaciones interactivas interesantes y tiles.

Estructura
Cada leccin incluye:

Su propia pgina web cuando es til.

Cdigo fuente que se puede copiar o modificar.

Comentarios en todas las secciones.

La fecha de su ms reciente actualizacin.

Licenciamiento
El cdigo de ejemplo en este tutorial se puede copiar, adaptar, modificar y reutilizar para
cualquier propsito, incluyendo con fines comerciales. Los derechos de autor sobre el contenido
y el diseo del tutorial son de propiedad de Scott Murray.

Nota al margen
Con el propsito de cumplir con lo anterior, se cubrirn someramente algunos de los temas
tcnicos, simplificando conceptos fundamentales de la ingeniera de sistemas. Esto puede
agravar a los ingenieros de sistemas verdaderos. Sin embargo, no importa pues este tutorial est
escrito para artistas y diseadores, no para ingenieros.
Siguiente: Fundamentos >
Este tutorial fue traducido por Gabriel Coch
Todo el contenido fue desarrollado por y le pertenece a Scott Murray

Fundamentos

Para trabajar con D3 es indispensable tener conocimiento de los siguientes conceptos:

HTML
Hypertext Mark Language se utiliza para organizar el contenido que muestran los navegadores
de internet.
La pgina ms sencilla de HTML es algo as:
<html>
<head>
<title>Ttulo de la Pgina</title>
</head>
<body>
<h1>Captulo 1</h1>
<p>Este es un prrafo importante</p>
</body>
</html>

DOM
El DOM (Modelo de Objetos del Documento) ser refiere a la estructura jerrquica de HTML.
Cada una de las etiquetas corresponde a un elemento, y los elementos estn relacionados entre s.
Para describir estas relaciones se usan los mismos trminos con los que se describen las
generaciones humanas: padre, hijo, hermano(a), ancestro y descendiente. En el cdigo HTML
anterior, body es el elemento padre de los hijos h1 y p, los cuales a su vez son hermanos. Todos
los elementos de la pgina son descendientes de html.
Los navegadores de la red descomponen el DOM para interpretar el contenido de la pgina.

CSS
Las hojas de estilo en cascada se usan para definir el estilo que se utilizar para mostrar las
pginas de HTML. A continuacin se muestra un ejemplo simple de un archivo CSS:
body {
background-color: white;
color: black;
}

Los estilos de un CSS estn compuestos de selectores y reglas. Selectores identifican elementos
especficos a los cuales se les aplicarn los estilos.
h1
p
.caption
#subnav

/*
/*
/*
/*

Selecciona
Selecciona
Selecciona
Selecciona

los ttulos de primer nivel


prrafs
elementos de clase "caption"
elemento con ID "subnav"

Reglas son propiedades que en conjunto crean los estilos:

*/
*/
*/
*/

color: pink;
background-color: yellow;
margin: 10px;
padding: 25px;

Los selectores y reglas se conectan usando llaves:


p {

font-size: 12px;
line-height: 14px;
color: black;

D3 utiliza el mismo estilo de los selectores en CSS para identificar elementos a los cuales se les
aplicar alguna operacin, por consiguiente es importante entender cmo se usan.
Las reglas de CSS se pueden incluir usando la etiqueta -head- de la siguiente manera:
<head>
<style type="text/css">
p {
font-family: sans-serif;
color: lime;
}
</style>
</head>

Tambin se pueden guardar en un archivo externo con el sufijo .css, para luego referenciarlo
dentro de documento, usando la etiqueta -head- , de la siguiente manera:
<head>
<link rel="stylesheet" href="style.css">
</head>

JavaScript
JavaScript en un lenguaje de programacin interpretado, mediante el cual se pueden enviar
instrucciones al navegador con el propsito de cambiar la pgina despus de que se haya
descargado.
Los programas (scripts) se pueden incluir directamente dentro del HTML, utilizando las
etiquetas -script-, de la siguiente manera:
<body>
<script type="text/javascript">
alert("Hello, world!");
</script>
</body>

Tambin se pueden guardar en otro archivo, el cual debe ser referenciado en algn lugar dentro
del HTML (usualmente en la seccin -head- ), de la siguiente manera:

<head>
<title>Page Title</title>
<script type="text/javascript" src="myscript.js"></script>
</head>

Herramientas de Desarrollo
Es importante familiarizarse con las herramientas de desarrollo del navegador. En los
navegadores WebKit (como Safari o Chrome), es posible abrir el inspector de web, tal como se
ve en la siguiente grfica:

La opcin de View Source o ver cdigo muestra el cdigo HTML original. Ms importante
an es el inspector de web, pues a travs de esta opcin es posible verificar el estado actual del
DOM. As, es posible revisar cmo los programas generan cambios en forma dinmica sobre los
elementos. Tambin es posible utilizar la Consola de JavaScript para depurar el cdigo.

SVG
D3 brilla en rea de despliegue de grficas en formato SGV (Scalable Vector Graphics). SVG es
un formato que utiliza texto para desplegar imgenes. Esto se refiere a que una imagen SVG
puede ser definida utilizando cdigo de etiquetas, de forma similar a HTML. En realidad, el
cdigo SVG se puede integrar dentro de cualquier documento HTML. Los navegadores de la
web han incluido soporte para este formato durante muchos aos (con excepcin de Internet
Explorer), sin embargo solo recientemente ha empezado a tener aceptacin.
Este es un pequeo crculo codificado dentro de la pgina.
<svg width="50" height="50">
<circle cx="25" cy="25" r="22"
fill="blue" stroke="gray" stroke-width="2"/>
</svg>

Intntelo - oprima sobre el crculo y ver que no es una imagen! Ample la pantalla (zoom) y
ver cmo cambia de escala de manera gradual, tal como lo debe hacer una grfica en formato
vectorial .
El uso de formato SVG no es un requisito en D3, sin embargo SVG proporciona una serie de
facilidades de despliegue visual que simplemente no son factibles de replicar con elementos
HTML.
Siguiente: Instalacin >

Instalacin
Descargue de D3
Para comenzar, es necesario crear un directorio para su proyecto. Dentro de ese directorio, se
recomienda crear un subdirectorio bajo el nombre d3, descargar la versin ms reciente de D3 y
descomprimir el archivo ZIP.
D3 tambin viene en un formato comprimido disponible en el repositorio de Github. Este
archivo no tiene espacio en blanco, por lo cual es de menor tamao y se carga ms rpidamente.
Una tercera opcin consiste en descargar el repositorio entero, con lo cual se obtiene no
solamente los archivos de JavaScript sino tambin todo el cdigo fuente de los componentes.
Igualmente, puede revisar el contenido del repositorio o descargarlo todo como un archivo
comprimido en formato ZIP.

Referenciar a D3
Empiece creando un archivo simple en formato HTML de nombre index.html. La estructura del
directorio debe ser similar a:
project-folder/
d3/
d3.js
d3.min.js (opcional)
index.html

Luego, copie el siguiente cdigo a su archivo HTML, de tal manera que ste haga referencia a
D3 en la seccin -head- y deje un espacio para el cdigo de JavaScript:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3 Test</title>
<script type="text/javascript" src="d3/d3.v3.js"></script>
</head>
<body>

<script type="text/javascript">
// Su cdigo de D3 se incluir ac
</script>
</body>
</html>

Despliegue de la Pgina
En algunos casos, es posible abrir el archivo directamente desde el navegador. Sin embargo,
cuando se cargan archivos externos es recomendable correr un servidor de web y visualizar la
pgina desde http://localhost:8888/. Existen opciones como MAMP o SimpleHTTPServer.
Siguiente: Aadir Elementos >

Aadir Elementos
Uno de los primeros pasos en el uso de D3 consiste en crear un nuevo elemento en el DOM. Por
lo general, ste ser un objeto SVG para desplegar una visualizacin grfica de datos, sin
embargo con el propsito de empezar con algo simple, a continuacin se muestra cmo aadir un
elemento -p-.
Se empieza con la siguiente plantilla de HTML.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3 Test</title>
<script type="text/javascript" src="d3/d3.v3.js"></script>
</head>
<body>
<script type="text/javascript">
// Su bello cdigo de D3 vendr ac
</script>
</body>
</html>

En este enlace puede ver la pgina generada por este cdigo. No parece tener mucho, sin
embargo al abrir el inspector de web, se puede ver lo siguiente.

Ahora, en el archivo HTML, cambie el texto dentro de las etiquetas script con el siguiente
cdigo:
d3.select(body).append(p).text(New paragraph!);
Guarde y refresque o revise esta pgina y ver el cambio! Ahora se muestra un texto en la
ventana del navegador, y en el inspector de web se muestra lo siguiente:

Nota la diferencia? Ahora el DOM contiene un nuevo elemento que se gener dinmicamente!
Puede ser que esto no sea muy interesante an, pero pronto podr ver cmo con una tcnica
similarse pueden generar decenas o centenas de elementos, cada uno representando una parte de
sus datos.
Miremos lo que acaba de ocurrir. Secuencialmente:
1. Se invoc el mtodo select de D3, el cual selecciona un solo elemento en el DOM
utilizando la sintaxis del selector en CSS. (En este caso se utiliz body).
2. Se cre un nuevo elemento p y se aadi al final de la seleccin, o sea justo antes de la
etiqueta de cierre -body- en este caso.
3. Se actualiz el contenido del prrafo vaco con la frase New Parragraph.

Al margen, todos esos puntos son parte de la sintaxis de encadenamiento de D3.


Siguiente: Encadenar Mtodos >

Encadenar Mtodos
D3 utiliza una tcnica denominada sintxis de cadena, similar a la de jQuery. Mediante el
encadenamiento de mtodos separados por puntos, es posible ejecutar varias acciones en una
misma lnea de cdigo. Esto puede ser rpido y fcil, pero es importante entender cmo
funciona, para ahorrarse horas de dolores de cabeza depurando el cdigo.
A propsito, funciones y mtodos son dos palabras diferentes para describir el mismo concepto:
una unidad de cdigo que acepta un argumento como entrada, lleva a cabo alguna accin, y
devuelve algn dato de salida.
Revisemos nuevamente la primera lnea de cdigo en D3. Pgina de ejemplo.
d3.select("body").append("p").text("New paragraph!");

Esto puede parecer algo desordenado, especialmente cuando se est comenzando a programar.
Lo primero que toca sabe es que JavaScript, al igual que HTML, ignora el espacio en blanco y
los cambios de lnea, por consiguiente se puede incluir cda uno de los mtodos en su propia
linea, lo cual es ms legible.
d3.select("body")
.append("p")
.text("New paragraph!");

Cada quin tiene su propio estilo de progamar, por consiguiente puede utilizar diferentes
espacios de indentacin (sangra), cambios de lnea, o espacio en blanco de acuerdo con sus
preferencias.

Un Enlace a la Vez
Veamos las diferentes partes del cdigo anterior.
d3 - referencia al objeto D3, de tal forma que se pueda acceder a sus mtodos.
.select(body) - Al darle a select( ) un selector de CSS como entrada, ste devolver una
referencia al primer elemento del DOM que coincida. (Se recomienda usar selectAll( ) cuando se
necesite ms de un elemento). En este caso, solo se necesita la etiqueta body, por eso se pasa la
referencia a body al siguiente mtodo de la cadena.

La Transferencia

Muchos pero no todos los mtodos devuelven una seleccin (realmente la referencia a la
seleccin), lo cual permite aplicar la tcnica tan til que es el encadenamiento de mtodos.
Usualmente, un mtodo devuelve una referencia al objeto que alter, pero no siempre.
Para recordar: Cuando se encadenan mtodos el orden importa. El tipo de salida (output) de un
mtodo debe coincidir con el tipo de entrada (input) del siguiente mtodo de la cadena. Si las
entradas y salidas de mtodos adyacentes no son compatibles, no ocurrir la transferencia de
informacin.

Esquema sin Encadenamientos


El cdigo del ejemplo tambin se puede escribir sin la sintaxis de encadenamiento.
var body = d3.select("body");
var p = body.append("p");
p.text("New paragraph!");
Realmente mucho ms confuso! Sin embargo, abr veces cuando ser necesario
romper la cadena, como cuando se hacen llamados a tantas funciones que no vale
la pena encadenarlas todas. O simplemente porque puede ser mejor organizar el
cdigo de una manera que tenga mayor sentido para quien lo est elaborando.

Siguiente: Asociar Datos >

Asociar Datos
En qu consiste Asociar Datos (Binding) y por qu es aconsejable?
La visualizacin de datos es un proceso de mapeo de datos a despliegues grficos. Los datos
ingresan y su representacin en formato grfico constituyen el resultado final. De esa manera es
probable que nmeros mayores correspondan a barras ms altas o que categoras especiales
correspondan a colores ms llamativos. Las reglas de mapeo son decisin del programador.
Con D3, se asocian los datos de entrada a los elementos del DOM. Asociar en este sentido es
similar a pegarse a elementos especficos, de tal forma que posteriormente se puedan referenciar
esos valores y aplicar la reglas de mapeo. Si no se lleva a cabo el paso de asociacin, lo nico
que se obtiene es un listado de elementos del DOM sin datos que no pueden ser mapeados. A
nadie le interesa eso.

En Asocio
En D3 se utiliza el mtodo selection.data( ) para asociar datos a los elementos del DOM. Sin
embargo, es necesario tener dos componentes organizados antes de poder asociar datos:
1. Los datos
2. Una seleccin de elementos del DOM

Miremos uno a la vez.

Datos
D3 es bastante inteligente con respecto al manejo de diferentes tipos de datos y acepta casi
cualquier tipo de arreglo de nmeros, caracteres u objetos (stos a su vez pueden contener otros
arreglos o pares de llave/valor). D3 puede leer JSON ( y GeoJSON) con facilidad y tiene tambin
un mtodo que ayuda a montar archivos en formato CSV.
Con el propsito de mantener la simplicidad, por el momento vamos a empezar con un arreglo
simple de nmeros. Esta es la muestra:
var dataset = [ 5, 10, 15, 20, 25];

Por Favor Haga su Seleccin


Primero es indispensable decidir qu es lo que se va a seleccionar, o sea, qu elementos estarn
asociados a los datos? Nuevamente, se utilizar un esquema sencillo - esta vez se va a crear un
prrafo nuevo para cada valor en el conjunto de datos. Es posible imaginarse que algo as puede
ser til:
d3.select("body").selectAll("p")

Es correcto, sin embargo toca tener algo en cuenta: Los prrafos que queremos seleccionar an
no existen. Este es uno de los puntos que ms genera confusin con respecto a D3. Cmo puede
ser posible seleccionar elementos que an no existen? Paciencia por favor - la respuesta puede
requerir la maleabilidad de su mente.
La respuesta est en el mtodo enter( ), que es verdaderamente mgico. Ac est el cdigo final
del ejemplo, que ser explicado a continuacin:
d3.select("body").selectAll("p")
.data(dataset)
.enter()
.append("p")
.text("New paragraph!");

Ahora, revise lo que hace el cdigo con la pgina de ejemplo. Puede ver cinco prrafos nuevos,
cada uno con el mismo contenido. Esto es lo que pasa:
d3.select("body")

- encuentra la etiqueta -body- en el DOM y pasa la referencia al siguiente

paso en la cadena.
- Selecciona todos los prrafos del DOM. Como an no existen, devuelve una
seleccin vaca. Esto se debe entender como la representacin de los prrafos que existirn
prximamente.
.selectAll("p")

.data(dataset).

Cuenta y desagrega los valores. Existen cinco valores en la muestra, por


consiguiente de aqu en adelante todo se ejecutar cinco veces, una vez por cada valor.
.enter()- Para crear nuevos elementos que estn asociados a datos, es necesario utilizar
enter(). Este mtodo revisa el DOM y luego revisa los datos que le sern entregados. Si existen
ms datos que elementos del DOM, enter() crea un elemento temporal con el cual se puede
hacer la magia. Luego enter() entrega la referencia al elemento temporal al siguiente paso en la

cadena.
- Utiliza la seleccin temporal creada previamente por el mtodo enter() e inserta el
elemento p en el DOM. Qu bien! Ahora lo pasa como referencia al elemento que acaba de crear
al siguiente paso en la cadena.
.append()

.text("New paragraph!")

- Toma la referencia al recin creado p e inserta el valor del texto.

Asociados y Listos
Muy bien! Los datos se pudieron leer, desagregar y asociar a los nuevos elementos p que se
crearon en el DOM. Si no cree, puede regresar a la pgina de ejemplo y abrir el inspector de web.

Ya se tienen los cinco prrafos, pero donde estn los datos? Oprima la opcin Consola, y escriba
el siguiente cdigo de JavaScript y luego oprima la tecla Enter:
console.log(d3.selectAll("p"))

Un arreglo! Ahora oprima el tringulo gris para ver ms:

Ahora podr ver los cinco HTMLParagraphElements, numerados del 0 al 4. Oprima el


trngulo para ver el primero (nmero 0)

Lo ve? Realmente lo ve? Increble. Ah est:

El primer valor, el nmero 5, se puede ver bajo el atributo _data_ del prrafo. Si oprime los
dems elementos de prrafo, ver que tambin contienen valores en el atributo _data_ 10, 15, 20
y 25, tal como se especificaron.
Los datos estn listos. Es hora de hacer algo con ellos.
SiguientUsando

sus Datos

Cmo se usan los datos, una vez estn cargados y asociados a los elementos del DOM? A
continuacin se muestra el cdigo de la sesin anterior.
var dataset = [ 5, 10, 15, 20, 25 ];
d3.select("body").selectAll("p")
.data(dataset)
.enter()
.append("p")
.text("New paragraph!");

Si se cambia la ltima lnea a:


.text(function(d) { return d; });

Se puede ver cmo el cdigo cambia la pgina de ejemplo.


Vean! Utilizamos los datos para actualizar el contenido de cda prrafo, todo gracias a la magia
del mtodo data(). Cuando se encadenan mtodos, es posible en cualquier momento invocar el
mtodo data() y crear una funcin annima que acepta d como parmetro de entrada. El mtodo
mgico data() asegura que d obtenga el valor correspodiente al conjunto de datos original, para
el elemento actual.
El valor del elemento actual cambia cada vez que D3 hace un recorrido por los elementos. Por
ejemplo, cuando se recorre por tercera vez, el cdigo del ejemplo crea la tercera etiqueta p y d
entonces asume el tercer valor del conjunto de datos (dataset[2]). Por consiguiente, el tercer
prrafo queda actualizado con el valor de texto 15.

Funcionando
En caso de que usted est empezando a escribir sus propias funciones (o mtodos), la estructura
bsica de la definicin de una funcin es la siguiente:
function(input_value) {
//Calculate something here
return output_value;
}

Esta funcin es muy sencilla, bsicamente:

function(d) {
return d;
}

y est encapsulada dentro de la funcin text()de D3, por consiguiente lo que devuelva esta
funcin ser pasado a la funcin text().
.text(function(d) {
return d;
});

Pero se puede crear algo ms sofisticado, porque estas funciones se pueden adecuar de muchas
maneras. Es verdad que escribir cdigo en JavaScript es placentero y doloroso a la vez. El punto
importante es saber que se pueden definir funciones para lo que se necesite. Probablemente, le
gustara aadir algn texto, el cual produce el siguiente resultado
.text(function(d) {
return "I can count up to " + d;
});

A los datos les gusta tener casa


Si se est preguntando por qu toca escribir function(d)... en vez de d, miremos este ejemplo
el cual no funciona:
.text("Puedo contar hasta " + d);

En este contexto, si no se encapsula d dentro de una funcin annima, d no tiene valor. Piense en
d como un valor temporal que est solo y necesita el lugar caluroso que le proporcionan los
parntesis de la funcin.
Ac, la funcin annima se encarga de darle el espacio que necesita d.
.text(function(d) { //
return "Puedo contar hasta " + d;
});

La razn para usar esta sintaxis es que .text(), attr(), y muchos otros mtodos de D3
reciben una funcin como un argumento. Por ejemplo, text() puede recibir o una cadena de
caracteres como un argumento:
.text("Alguna cadena")

O los resultados de una funcin:


.text(algunaFuncion())

o las funcin annima en s puede ser un argumento, como cuando se escribe:

.text(function(d) {
return d;
})

Arriba, se est definiendo una funcin annima. Si D3 encuentra una funcin ac, la procesa y le
pasa el valor actual de d como el argumento de la funcin. Si no existe una funcin, D3 no puede
saber a quin pasarle el argumento d.
Inicialmente esto parece no tener sentido y que es trabajo adicional solamente para obtener el
valor de d, pero prximamente este enfoque ser ms claro a medida que miremos temas ms
complejos.

Ms all del Texto


Las cosas se vuelven an ms interesantes cuando empezamos a mirar otros mtodos de D3,
como son attr() y style(), los cuales permiten actualizar respectivamente los atributos de
HTML y propiedades de CSS sobre selecciones.
Por ejemplo, con una sola lnea de cdigo adicional, se produce el siguiente resultado.
.style("color", "red");

Ahora todo el texto es de color rojo. Lo interesante es que se puede utilizar una funcin para que
el texto se despliegue en rojo solamente cuando el dato est por encima de cierto umbral.
Entonces, es posible alterar la ltima lnea incertando la funcin:
.style("color", function(d) {
if (d > 15) {
//Umbral - 15
return "red";
} else {
return "black";
}
});

Resultados. Puede ver que las primeras tres lneas estn en negro, pero apenas d excede el
nmero 15, el texto cambia de color a rojo.
En la siguiente leccin, se utilizar attr() y style() para manipular divs, y generar un
diagrama de barras simple - nuestra primera visualizacin!
Siguiente: Desplegar Divs>
e: Usando sus Datos >

Desplegar DIVs
Es hora de comenzar a crear diagramas con datos.
Por ltima vez vamos a utilizar el mismo conjunto de datos.

var dataset = [ 5, 10, 15, 20, 25 ];

Este conjunto se va a usar para generar un diagrama de barras muy sencillo. Los diagramas de
barras son en esencia rectngulos y la forma ms fcil de dibujar un rectngulo es usando la
etiqueta de HTML <div>. (En realidad para los navegadores, todo es un rectngulo, entonces es
posible cambiar el ejemplo y usar <span> o el elemento que prefiera).
El siguiente div funciona bien como una barra de datos.
<div style="display: inline-block;
width: 20px;
height: 75px;
background-color: teal;"></div>

(Este ejemplo muestra algo que no se debe hacer. Usualmente, no se debe usar un div vaco para
efectos visuales nicamente, sin embargo para efectos de este tutorial se puede hacer la
excepcin.)
Puesto que este es un div, su ancho width y altura height se definen en los estilos de CSS.
Cada barra en el diagrama puede compartir las mismas propiedades de despliegue (con
excepcin de altura height), por consiguiente se pueden incluir los estilos compartidos dentro de
una clase class de nombre bar:
div.bar {
display: inline-block;
width: 20px;
height: 75px;
/* Esto se cambiar prximamente */
background-color: teal;
}
Ahora a cada div se le debe asignar la clase bar, de tal manera que la regla de CSS

se aplique. Si

estuviera escribiendo cdigo HTML a mano, escribira:


<div class="bar"></div>

Con D3, para aadir una clase a un elemento se utiliza el mtodo selection.attr(). Es
importante entender la diferencia entre attr() y su pariente cercano, style.
Asignacin de Atributos

se usa para asignarle un atributo y su valor a un elemento. Un atributo de HTML es


cualquier dupla propiedad/valor que se pueda insertar dentro de los corchetes. Por ejemplo, estos
elementos de HTML
attr()

<p class="caption">
<select id="country">
<img src="logo.png" width="100px" alt="Logo" />

contienen en total cinco atributos (con sus valores correspondientes), y todos pueden ser
asignados con la funcin attr():
class

caption

id
src
width
alt

|
|
|
|

Para asignarle

country
logo.png
100px
Logo
la clase bar

a los divs, se puede usar:

.attr("class", "bar")

Una Nota sobre Clases

Tome nota de que la clase de un elemento se guarda como un atributo de HTML. La clase, a su
vez, se usa para referenciar la regla del estilo de CSS. Esto puede causar algo de confusin
porque existe una diferencia entre asignar una clase (de la cual se infieren los estilos) y aplicar
un estilo directamente a un elemento. En D3 es factible hacer ambos, y si bien se puede utilizar
el que considere ms conveniente, yo recomiendo usar clases para aquellas propiedades que sean
compartidas por varios elementos, y aplicar reglas de estilo directamente solo cuando se est
desviando de la norma (que es exactamente lo que haremos en un momento.)
Vale la pena mencionar otro mtodo de D3, classed(), que puede ser usado para aplicar o
remover clases rpidamente de los elementos. La lnea de cdigo anterior pudo haber sido escrita
as: .classed(bar, true)
Otra Vez con las Barras

Ahora, se puede ver todo el cdigo de D3 hasta el momento, incluyendo el conjunto de datos:
var dataset = [ 5, 10, 15, 20, 25 ];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class", "bar");

Puede ver esta pgina con cdigo. No olvide revisar el cdigo fuente y abrir el inspector de web
para ver qu est pasando. Debe ver cinco barras verticales, cada una representando a un dato del
conjunto. Como no hay espacio entre las barras, la grfica aparece como un solo rectngulo.
Definicin de Estilos

El mtodo estilo()se usa para aplicar la propiedad y valor de CSS a un elemento de HTML.
Esto es el equivalente a aadir reglas de CSS dentro del atributo style en el cdigo HTML, as:
<div style="height: 75px;"></div>

En el diagrama de barras, la altura de cada barra debe generarse de acuerdo con el dato
correspondiente, entonces si se aade el siguiente cdigo:
.style("height", function(d) {
return d + "px";
});

ver un diagrama de barras muy pequeo. pgina de ejemplo.


Cuando D3 pasa por cada dato, asocia ese dato a d, por consiguiente se est asociando un valor d
al atributo height y se le aade px (para especificar las unidades en pixeles). El resultado son
alturas de 5px, 10px, 15px, 20px, y 25px.
Esto suena un tanto absurdo, entonces hagamos las barras ms altas:
.style("height", function(d) {
var barHeight = d * 5; //Incrementar la escala 5 veces.
return barHeight + "px";
});

e incluyamos un espacio en el lado derecho de cada barra, para alinear todo mejor.

Excelente! Ya podemos ir a SIGGRAPH con este diagrama.


Ac est la pgina final de ejemplo con este cdigo. Nuevamente, es importante revisar el cdigo
y utilizar el inspector de web para comparar el HTML original con el DOM final.
Siguiente: El Poder de la Funcin data( ) >

El Poder de la Funcin data( )


Lo ltimo que hicimos fue un diagrama de barras simple, dibujado utilizando etiquetas div y un
conjunto de datos sencillo.
var dataset = [ 5, 10, 15, 20, 25 ];

Est bien, pero los datos en la vida real nunca son as. Cambiemos nuestros datos
var dataset = [ 25, 7, 5, 26, 11 ];

Tampoco vamos a limitarnos a cinco datos. Podemos aadir ms!


var dataset = [ 25, 7, 5, 26, 11, 8, 25, 14, 23, 19,
14, 11, 22, 29, 11, 13, 12, 17, 18, 10,
24, 18, 25, 9, 3 ];

25 datos en vez de cinco! Cmo es que D3 expande automticamente nuestro diagrama si es


necesario?
d3.select("body").selectAll("div")
.data(dataset) // <-- Ac est la respuesta!
.enter()
.append("div")
.attr("class", "bar")
.style("height", function(d) {
var barHeight = d * 5;
return barHeight + "px";
});

Si se le pasan diez datos a la funcin data(), sta recorrer la cadena diez veces. Si se le pasan
un milln de datos, la recorrer un milln de veces (solo tiene que tener paciencia).
Este es el poder de la funcin data(), la cual es lo suficientemente inteligente para recorrer por
completo cualquier conjunto de datos que se le d y ejecutar cada una de las funciones siguientes
en la cadena. Esto lo hace mientras actualiza el contexto dentro del cual opera cada funcin, de
tal manera que d siempre se refiere al dato actual, o aquel dnde est el ciclo (loop) en ese
momento.
Puede que esto sea demasiada informacin. Si no la entiende del todo en este momento, pronto la
entender. Le recomiendo que guarde el cdigo fuente de las pginas HTML de ejemplo
anteriores, cambie los valores del conjunto de datos y revise cmo cambia el diagrama de barras.
Recuerde, los datos son lo que generan la visualizacin y no al contrario.

Datos Aleatorios
Algunas veces es divertido generar conjuntos con datos aleatorios, pero efectos de chequeo o
solamente por inters en temas tcnicos. Eso es lo que he hecho ac. Puede ver cmo cambia la
grfica cada vez que se refresca la pgina.

Si revisa el cdigo fuente, podr ver: var dataset = []; //Initialize empty array for (var i = 0; i <
25; i++) { //Loop 25 times var newNumber = Math.random() * 30; //New random number (0-30)
dataset.push(newNumber); //Add new number to array }
Este cdigo no utiliza ningn mtodo de D3, es solamente JavaScript. Sin entrar en mucho
detalle, este cdigo:
1. Crea un arreglo vaco denominado dataset.
2. Inicia un ciclo (loop) for, que se ejecuta 25 veces.
3. Por cada ciclo, se genera un nmero aleatorio entre 0 y 30.
4. El nuevo nmero se aade al arreglo dataset. (push() es un mtodo de arreglos que
aade un nuevo valor al final del arreglo.)
Solamente por jugar, abra la consola de JavaScript y escriba console.log(dataset). Podr ver
todo el arreglo con 25 valores generados aleatoriamente.

Puede ver que todos los nmeros son decimales o puntos flotantes (14.793717765714973) y no
nmeros reales o enteros (14) como usamos inicialmente. Para efectos de este ejemplo, esto
basta, pero si alguna vez necesita nmeros enteros, puede usar el mtodo de JavaScript
Math.round(). Por ejemplo, se puede envolver el generador de nmeros aleatorios de esta lnea:
var newNumber = Math.random() * 30;
as:
var newNumber = Math.round(Math.random() * 30);

Prubelo aqu y use la consola para verificar que los nmeros se hayan redondeado a nmeros
enteros.
Ahora vamos a expandir las posibilidades de visualizacin con SVG.
Siguiente: Introduccin a SVG >

Introduccin de SVG
D3 es de mayor utilidad cuando se usa para generar informacin grfica en formato SVG. Si bien
es factible deplegar grficas con etiquetas div y otros elementos nativos de HTML, este mtodo

no es el ideal y est sujeto a las inconsistencias que existen entre los diferentes navegadores. El
uso de SVG es bastante ms confiable, consistente visualmente y ms rpido.
Aplicaciones de dibujo vectorial como Illustrator se pueden usar para generar archivos en
formato SVG, pero es necesario aprender cmo se generan a partir de cdigo.

El Elemento SVG
Grficos Escalables en Formato Vectorial (Scalable Vector Graphics) es un formato que usa texto
para definir imgenes. Cada imagen SVG se define con cdigo similar al de HTML. El cdigo
SVG se puede incluir directamente dentro de cualquier documento de HTML. Todos los
navegadores leen SVG, con excepcin de Internet Explorer 8 y versiones anteriores. SVG est
basado en XML, por consiguiente notar que los elementos que no tienen etiquetas de cierre - se
auto-cierran. Por ejemplo:
<element></element>
<element/>

<!-- Usa una etiqueta de cierra -->


<!-- Se auto-cierra -->

Antes de poder dibujar, se debe crear un elemento SVG. Piense en un elemento SVG como el
lienzo donde se dibujan todos los grficos. (En este contexto, SVG es conceptualmente similar
elemento canvas de HTML). Por lo menos, se deben especificar los valores de ancho (width) y
altura (height). Si stos no se especifican, SVG utilizar todo el espacio que pueda dentro
dentro del elemento que lo contiene.
<svg width="500" height="50">
</svg>

Ac est el SVG generado por este cdigo.


Si no lo ve, puede usar el botn derecho y marcar en el espacio en blanco y luego seleccionar
Inspeccionar Elemento. Su inspector de web mostrar algo similar a esto:

Tome nota de que ya existe un elemento svg (qu bien!) y que ocupa 500 pixeles horizontales y
50 pixeles verticales. No es que se muestre mucho por el momento (qu mal!).

Tambin tome nota de que el navegador asumi que la medida por defecto es el pixel. Se
especific las dimensiones de 500 y 50 y no 500pxy 50px. Se habra podido especificar px
explcitamente, o cualquier otro tipo de unidad de medida, incluyendo em, pt, in, cm, y mm.

Figuras Simples
Existen ciertos elementos visuales que se pueden incluir dentro de las etiquetas svg, incluyendo
rect, circle, ellipse,line, text, y path.
Si usted tiene alguna familiaridad con la programacin grfica, reconocer el sistema de
coordenadas basado en pixeles, en el cual 0, 0 est ubicado en el la parte superior izquierda del
espacio destinado a los dibujos. Al incrementar los valores x, estos se mueven hacia la derecha,
mientras que el incrementar los valores y, se mueven hacia abajo.
0,0 100,20 200,40
dibuja un rectngulo. Se usa x y y para especificar las coordenadas del costado superior
izquierdo y width y height para especificar las dimensiones. Este rectngulo rellena todo el
espacio de nuestro elemento SVG.
rect

<rect x="0" y="0" width="500" height="50"/>

dibuja un crculo. Se usa cx y cy para especificar las coordenada del centro y r para
especificar el radio. Este crculo queda centrado en la mitad del SVG de 500 pixeles de ancho,
porque cx(centro de x) tiene un valor de 250.
circle

ellipse

es similar, pero requiere dos radios, uno por cada eje. En vez de usar r, se usa rx y ry.

<ellipse cx="250" cy="25" rx="100" ry="25"/>


line dibuja una lnea. Se usa x1y y1 para especificar las coordenadas de extremo de la lnea, y
x2y y2para especificar las coordenadas del otro extremo. Tambin es necesario especificar un
color stroke para que se vea la lnea.
<line x1="0" y1="0" x2="500" y2="50" stroke="black"/>

despliega texto. Se usa x para especificar la posicin del lado derecho y y para especificar
la posicin vertical de la lnea de base del tipo.
text

Easy-peasy
tambin hereda los estilos del fuente que se especifican en el CSS, especficamente los de
los elementos del padre, si no se especifican explcitamente. (Prximamente se explicar en ms
detalle el uso de estilos para texto). Tome nota de cmo el estilo del texto de arriba tiene el
mismo formato del texto de este prrafo. Es posible reemplazar ese formato de la siguiente
manera:
text

<text x="250" y="25" font-family="sans-serif"


font-size="25" fill="gray">Easy-peasy</text>

Easy-peasy
Tambin cabe anotar que cuando el elemento visual se corre sobre el costado del elemento SVG,
ste lo corta. Se debe tener cuidado al usar text de tal manera que los descendientes no se corten
(duele!). Puede ver lo que pasa cuando se define la lnea base (y) en 50, lo mismo que la altura
del SVG:
<text x="250" y="50" font-family="sans-serif"
font-size="25" fill="gray">Easy-peasy</text>

Easy-peasy
se usa para dibujar formas ms complejas que aquellas descritas anteriormente (como los
lmites de pases en mapas) y ser explicado en otra seccin. Por el momento seguiremos
trabajando con formas simples.
path

Estilos de los Elementos SVG.


El estilo por defecto de los SVGs es llenado en negro y sin lnea. Si se necesita algo diferente, se
tienen que aplicar estilos a los elementos. Algunas propiedades de SVG que se usan con
frecuencia son:

fill

- Un valor para el color. Igual a que en CSS, los colores se pueden especificar as:

o por nombre orange


o valor HEX #3388aa o #38a
o valor RGB rgb(10, 150, 20)
o RGB con transparencia alfa rgba(10, 150, 20, 0.5)

stroke

stroke-width

opacity

Un valor para el color.


Una medida numrica (usualmente en pixeles).

Un valor numrico entre 0.0 (completamente transparente) y 1.0


(completamente opaco).

Con text, se pueden usar estas propiedades, que funcionan de la misma forma que en CSS

font-family

font-size

Haciendo otro paralelo con CSS, existen dos formas de aplicar estilos a un elemento SVG:
directamente (en lnea) como un atributo del elemento, o dentro de una regla de estilo de CSS.
Ac se muestran algunas propiedades de estilo aplicadas directamente como atributos a circle.
<circle cx="25" cy="25" r="22"
fill="yellow" stroke="orange" stroke-width="5"/>

De otra manera, se pueden omitir los atributos de estilo y asignarle una clase a circle (como si
fuera un elemento HTML)
<circle cx="25" cy="25" r="22" class="pumpkin"/>

y despus incluir las reglas de fill, stroke, y stroke-width dentro de un estilo CSS asignado
a esta nueva clase:
.pumpkin {
fill: yellow;
stroke: orange;
stroke-width: 5;
}

El usar CSS tiene algunos beneficios obvios:


1. El estilo se especifica una vez y se puede aplicar a varios elementos.
2. El cdigo CSS es usualmente ms fcil de leer que el cdigo en lnea.
3. Por esas razones, tiende a ser ms fcil mantener el cdigo con el enfoque de CSS e
igualmente es ms fcil implementar cambios de diseo.
El usar CSS para aplicar estilos SVG, sin embargo, puede ser algo desconcertante para algunos.
fill, stroke, y stroke-width, despus de todo, no son propiedades de CSS. (Los equivalentes
ms cercanos en CSS son background-color y border.). Si en algo ayuda recordarse cuales
reglas dentro de CSS son especficas a SVG, vale la pena incluir svg en los selectores:
svg .pumpkin {
/* ... */
}

Capas y el Orden de Precedencia de los Dibujos


En SVG no existen las capas y no existe el concepto de profundidad. SVG no soporta la
propiedad z-index de CSS, por eso las figuras solamente se pueden organizar en un plano x/y de
dos dimensiones.
Sin embargo, si dibujamos varias figuras, se traslapan:

<rect
<rect
<rect
<rect
<rect

x="0" y="0" width="30" height="30" fill="purple"/>


x="20" y="5" width="30" height="30" fill="blue"/>
x="40" y="10" width="30" height="30" fill="green"/>
x="60" y="15" width="30" height="30" fill="yellow"/>
x="80" y="20" width="30" height="30" fill="red"/>

El orden en que se incluyen los elementos en el cdigo determina su orden (de profundidad). El
cuadrado morado aparece de primero en el cdigo y por eso se dibuja de primero. Luego, el
cuadrado azul se dibuja encima del morado, luego el verde encima del azul, y as en adelante.
Toca pensar en las figuras de SVG como se dibujaran figuras en un lienzo. La pintura de pixeles
que se aplica despus oscurece lo que se haya dibujado antes e igualmente aparece como si
estuviera adelante.
El tema de orden en el dibujo es importante cuando se tienen elementos visuales que nos deben
ser bloqueados por otros. Por ejemplo, cuando se tienen etiquetas para los ejes o los valores en
un diagrama de dispersin. Los ejes y las etiquetas se deben aadir al SVG de ltimo, para que
aparezcan encima de los dems elementos.

Transparencia
Las transparencia puede ser til cuando existen elementos que se traslapan pero que deben ser
visibles. Tambin cuando se le debe quitar algo de importancia a algunos elementos y darle
importancia a otros.
Existen dos formas de aplicar transparencia: usando un color RGB con alpha o asignado un valor
de opaco.
Se puede usar rgba() en cualquier lugar donde se especifique un color, tal como fill o
stroke.rgba() que esperan tres valores entre 0 y 255 para el rojo, verde y azul, ms el valor de
transparencia (alpha) que est entre 0.0 y 1.0.
<circle
<circle
<circle
<circle
<circle

cx="25" cy="25" r="20" fill="rgba(128, 0, 128, 1.0)"/>


cx="50" cy="25" r="20" fill="rgba(0, 0, 255, 0.75)"/>
cx="75" cy="25" r="20" fill="rgba(0, 255, 0, 0.5)"/>
cx="100" cy="25" r="20" fill="rgba(255, 255, 0, 0.25)"/>
cx="125" cy="25" r="20" fill="rgba(255, 0, 0, 0.1)"/>

Cabe anotar que con rgba(), la transparencia se aplica independientemente a los colores de fill
y stroke. Los crculos que se muestran a continuacin tienen un fill de 75% opaco, y sus
valores de stroke son de 25% opaco.
<circle cx="25" cy="25" r="20"
fill="rgba(128, 0, 128, 0.75)"
stroke="rgba(0, 255, 0, 0.25)" stroke-width="10"/>
<circle cx="75" cy="25" r="20"
fill="rgba(0, 255, 0, 0.75)"
stroke="rgba(0, 0, 255, 0.25)" stroke-width="10"/>
<circle cx="125" cy="25" r="20"

fill="rgba(255, 255, 0, 0.75)"


stroke="rgba(255, 0, 0, 0.25)" stroke-width="10"/>

Para aplicar transparencia a todo el elemento, se asigna el atributo opacity. Ac estn unos
crculos completamente opacos
seguidos por los mismos crculos con valores de opacity.
Se puede aplicar opacity a un elemento que tenga los colores definidos con rgba(). Al hacer
eso, las transparencias se multiplican. Los siguientes crculos usan los mismos valores RGBA
para fill y stroke. El primer crculo debajo no tiene el elemento opacity, pero los otros dos
s:
<circle cx="25" cy="25" r="20"
fill="rgba(128, 0, 128, 0.75)"
stroke="rgba(0, 255, 0, 0.25)" stroke-width="10"/>
<circle cx="65" cy="25" r="20"
fill="rgba(128, 0, 128, 0.75)"
stroke="rgba(0, 255, 0, 0.25)" stroke-width="10"
opacity="0.5"/>
<circle cx="105" cy="25" r="20"
fill="rgba(128, 0, 128, 0.75)"
stroke="rgba(0, 255, 0, 0.25)" stroke-width="10"
opacity="0.2"/>

Mire como el tercer crculo tiene el valor opacity de 0.2 o 20%. Sin embargo, el relleno morado
ya tiene un valor alpha de 0.75 o 75%. El rea morada, entonces tiene una transparencia final de
0.2 por 0.75= 0.15 o 15%.
Siguiente : Despliegue de SVG >

Despliegue de SVG
Ahora que ya estamos familiarizados con la estructura bsica y los elementos de una imagen en
formato SVG, cmo podemos comenzar a generar diagramas con nuestros datos?
Usted ha podido ver que todas las propiedades de los elementos se definen como atributos. Eso
quiere decir que se incluyen como pares propiedad/valor dentro de cada etiqueta del elemento, de
esta manera:
<element property="value"/>

Umm, esto se parece extraamente a HTML!


<p class="eureka">

Ya hemos usado los mtodos append() y attr() para crear nuevos elementos de HTML y
asignarles sus atributos. Debido a que los elementos de SVG existen en el DOM, tal como los

elementos de HTML, podemos usar append() y attr() de la misma forma para generar
imgenes en SVG!
Cree el SVG

Primero, debemos crear el elemento SVG que va a contener todas nuestras figuras.
d3.select("body").append("svg");

Se acuerda cmo la mayora de mtodos en D3 devuelven una referencia al elemento del DOM
sobre el cual actan? Al crear una nueva variable svg, podemos capturar la referencia que se le
pasa a append(). Esto se puede entender como que el svg no es una variable sino una
referencia que apunta al objeto SVG recin creado. Esta referencia nos va a ahorrar muchas
lneas de cdigo en el futuro. En vez de buscar ese SVG cada vez - como en d3.select("svg")
solo decimos svg.
svg.attr("width", 500)
.attr("height", 50);

De otra forma, se podra haber escrito todo en una lnea de cdigo:


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

Puede ver el ejemplo de este cdigo. Al inspeccionar el DOM ver que ah est, en verdad, el
elemento SVG vaco.
Para simplificar, recomiendo que se incluyan los valores de ancho y altura como variables al
comienzo del cdigo, de esta manera (vea la fuente):
//Width and height
var w = 500;
var h = 50;

Esto se har en todos los siguientes ejemplos. Al convertir en variables los valores de tamao, es
muy fcil hacer referencia a ellos a lo largo del cdigo, as como:
var svg = d3.select("body")
.append("svg")
.attr("width", w)
// <-- Ac
.attr("height", h); // <-- y aca!

Figuras a Partir de Datos

Ya es hora de aadir algunas figuras. Miremos nuestro conjunto de datos de antao.


var dataset = [ 5, 10, 15, 20, 25 ];

ahora, se usa data() para pasar por cada uno de los datos y as crear un crculo por cada uno:

svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle");
Cabe recordar que selectAll()

devuelve referencias vacas a todos los circles (que an no


existen), data() asocia los datos a los elementos que estn a punto de crearse, enter() devuelve
la referencia al espacio que se utiliza para el nuevo elemento y append() por ltimo aade un
circle al DOM.
Para apuntar a todos los circleen el futuro, se puede crear una variable nueva que almacene la
referencia a todos:
var circles = svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle");

Todo bien, pero todos estos crculos necesitan posiciones y tamaos. Prevngase: El cdigo que
va a ver a continuacin lo va a descrestar.
circles.attr("cx", function(d, i) {
return (i * 50) + 25;
})
.attr("cy", h/2)
.attr("r", function(d) {
return d;
});

Delitese con el ejemplo. Revisemos paso a paso el cdigo.


circles.attr("cx", function(d, i) {
return (i * 50) + 25;
})

Esta parte obtiene la referencia a todos los elementos circle y les asigna a cada uno el atributo
cx. Los datos ya se han asociado a los elementos de tipo circle, entonces para cada circle, el
valor de d equivale al valor correspondiente en el conjunto de datos original (5, 10, 15, 20 o 25).
Otro valor, i, se actualiza automticamente. i es el valor del ndice numrico del elemento
actual. El contador comienza en 0, por consiguiente para el primer crculo i == 0, para el
segundo crculo i == 1 y as sucesivamente. La i se va a usar para mover cada crculo hacia la
derecha, puesto que despus de cada paso del loop incrementa el valor de i.
(0
(1
(2
(3
(4

*
*
*
*
*

50)
50)
50)
50)
50)

+
+
+
+
+

25
25
25
25
25

devuelve
devuelve
devuelve
devuelve
devuelve

25
75
125
175
225

Para garantizar que i est disponible para la funcin, debe incluirse como un argumento dentro
de su definicin (function(d, i)). Tambin es necesario incluir a d, as no se use d, dentro de
la funcin (tal como en el caso de arriba).
Ahora, la siguiente lnea.
'.attr("cy", h/2)
h es la altura de todo el SVG,

entonces h/2 es la mitad de la altura. Esto tiene el efecto de centrar


a todos los crculos desde el punto de vista de alineacin vertical.
.attr("r", function(d) {
return d;
});
Por ltimo, el radio r de cada crculo

es simplemente asignado a d o sea al valor del dato

correspondiente.
Uuy, Bonitos Colores

Llenado y trazado de colores son otros de los atributos que se pueden asignar usando los mismos
mtodos. Simplemente con aadir este cdigo:
.attr("fill", "yellow")
.attr("stroke", "orange")
.attr("stroke-width", function(d) {
return d/2;
});

se obtiene la siguiente pgina de ejemplo.

Por supuesto que se pueden mezclar atributos y funciones especficas para poder aplicar
cualquier combinacin de propiedades. El truco con visualizaciones de datos, por supuesto,
consiste en escoger mapeos apropiados, de tal forma que la expresin visual de sus datos tenga
sentido y le sea til a quin la est viendo.
Siguiente: Tipos de datos >

Diferentes Tipos de Datos


D3 es muy flexible en cuanto a datos de entrada. Este tema introduce las estructuras de datos que
se usan comnmente en JavaScript y D3.

Variables

Una variable es un dato, el bloque ms pequeo de informacin. La variable es el cimiento para


todas las dems estructuras de datos, que simplemente son configuraciones diferentes de las
variable.
Si usted est hasta ahora empezando con JavaScript, sepa que es un lenguaje dbilmente tipado,
lo que quiere decir que no es necesario especificar de antemano el tipo de informacin que se va
a almacenar en una variable. Muchos otros lenguajes, como Java (que es totalmente diferente de
JavaScript!), requieren que se declare el tipo de variable, tal como int, float, boolean, o
String
//Declaracin de variables en Java
int number = 5;
float value = 12.3467;
boolean active = true;
String text = "Crystal clear";

JavaScript, en cambio, le asigna un tipo automticamente a la variable con base en el tipo de


informacin que se le asigne. (Tome nota de que y son indicadores de valores de una
cadena de caracteres. Yo prefiero las comillas dobles , pero algunas personas prefieren las
comillas sencillas .
//Declaracin de variables en JavaScript
var number = 5;
var value = 12.3467;
var active = true;
var text = "Crystal clear";
Qu aburrido - var, var, var, var- sin embargo

es til a medida que declaramos y


nombramos variables antes de que sepamos qu tipo de datos sern almacenados all. Uno puede
tambin cambiar el tipo de dato sobre la marcha sin que JavaScript se enloquezca.
var value = 100;
value = 99.9999;
value = false;
value = "Es imposible que esto funcione";
value = "Ahh, si funciona! No saca errorrrrr!";

Arreglos

Un arreglo es una secuencia de valores, que se almacena muy convenientemente dentro de una
sola variable.
Manejar datos relacionados en diferentes variables es muy ineficiente:
var
var
var
var
var

numberA
numberB
numberC
numberD
numberE

=
=
=
=
=

5;
10;
15;
20;
25;

Al reescribir esto como un arreglo, se vuelven mucho ms sencillos estos valores. Los corchetes
definen un arreglo y las comas separan cada uno de los valores:
var numbers = [ 5, 10, 15, 20, 25 ];

Los arreglos son un componente intrnseco de las visualizaciones de datos, por consiguiente es
necesario entenderlos bien. Se puede acceder al valor almacenado en un arreglo, utilizando
notacin de corchetes:
numbers[2] //Devuelve 15

El numeral dentro del corchete se refiere a la posicin correspondiente en el arreglo. Recuerde


que las posiciones del arreglo comienzan en cero, entonces la primera posicin es 0, la segunda
es 1 y as sucesivamente.
numbers[0]
numbers[1]
numbers[2]
numbers[3]
numbers[4]

//Devuelve
//Devuelve
//Devuelve
//Devuelve
//Devuelve

5
10
15
20
25

Algunas personas encuentran til pensar en arreglos en trminos espaciales, como si tuvieran
filas y columnas, como una hoja de clculo:
ID | Valor
0
1
2
3
4

|
|
|
|
|

5
10
15
20
25

Los arreglos pueden contener cualquier tipo de datos, no solamente enteros.


var percentages = [ 0.55, 0.32, 0.91 ];
var names = [ "Ernie", "Bert", "Oscar" ];
percentages[1]
names[1]

//Returns 0.32
//Returns "Bert"

De qu estn hechos los Arreglos. Funcin for()

La visualizacin de datos basada en cdigo no sera posible sin arreglos y el poderoso loop
for(). Juntos, conforman el do dinmico de los geeks de datos. (En caso de que usted no se
considere un data geek, le recuerdo que est leyendo el documento titulado Tipos de datos.).
Un arreglo organiza muchos datos en un lugar conveniente. Luego, la funcin for() puede
rpidamente recorrer todos los datos del arreglo y ejecutar alguna accin sobre ellos tal como

mostrar su valor de manera visual. D3 por lo general maneja el recorrido (looping) con su
mtodo mgico data(), pero es importante poder escribir nuestros propios loops.
No voy a describir la mecnica de los loops for() ac; esto da para otro tutorial entero por
separado. Pero tome nota de este ejemplo, el cual recorre los valores del arreglo numbers de
arriba.
for (var i = 0; i < numbers.length; i++) {
console.log(numbers[i]); //Imprime el valor a la consola
}
Ve ese numbers.length? Esa es la parte bella. Si numbers tiene diez posiciones,

el loop correr
diez veces. Si tiene diez millones de posiciones s, usted ya sabe. Para esto es que son buenas
las computadores: para recibir un grupo de instrucciones y ejecutarlas una y otra vez. Y esto se
encuentra en el corazn de por qu son tan satisfactorias las visualizaciones de datos uno
disea y codifica el sistema de visualizacin y el sistema responde acorde, an cuando se le
entrega diferentes datos. Las reglas de mapeo del sistema son consistentes, an cuando los datos
no lo son.
Objetos

Los arreglos son excelentes para listas simples de valores, pero cuando se tienen conjuntos
complejos de datos, es deseable almacenar los datos en un objeto. Para nuestro propsito, se debe
pensar en un objeto de JavaScript como si fuera una estructura de datos hecha a la medida. Se
usan las entre llaves {} para identificar a un objeto. Dentro de las llaves, se incluyen ndices y
valores. Dos puntos : separan cada ndice de su valor, y una coma separa cada par de
ndice/valor.
var fruta = {
tipo: "uva",
color: "rojo",
cantidad: 12,
dulce: true
};

Para referenciar cada valor, se utiliza la notacin de puntos, especificando el nombre del ndice.
fruta.tipo
fruta.color
fruta.cantidad
fruta.dulce

//Devuelve
//Devuelve
//Devuelve
//Devuelve

"uva"
"rojo"
12
true

Piense en el valor como perteneciendo al objeto. Mire, una fruta. Qu tipo de fruta es? puede
que se pregunte. Y de veras, fruta.tipoes "uva". Y es dulce? S, definitivamente, puesto que
fruta.dulce es true.

Objetos y Arreglos

Es posible combinar estas dos estructura y crear arreglos de objetos, u objetos de arreglos, u
objetos de objetos, o bsicamente cualquier estructura que tenga sentido para su conjunto de
datos.
Digamos que hemos adquirido otras frutas y que queremos expandir nuestro catlogo.
Utilizamos los corchetes []en la parte de afuera par indicar que es un arreglo, seguido por las
entre llaves {}y notacin de objetos en la parte de adentro, con una coma separando a cada
objeto.
var frutas = [
{
tipo: "uva",
color: "rojo",
cantidad: 12,
dulce: true
},
{
tipo: "kiwi",
color: "cafe",
cantidad: 98,
dulce: true
},
{
tipo: "banano",
color: "amarillo",
cantidad: 0,
dulce: true
}
];

Para obtener acceso a estos datos, debemos seguir el sendero de los ndices hacia los valores que
buscamos. Recuerde, [] significa arreglo, y {} significa objeto.frutas es un arreglo, entonces
utilizamos la notacin de corchetes primero para especificar el ndice del arreglo.
fruta[1]

Seguido, cada elemento del arreglo es un objeto, entonces se aade un punto y un ndice:
fruta[1].cantidad //Devuelve 98

Ac est el mapa de cmo acceder a todos los valores del arreglo de objetos denominado
frutas:
frutas[0].tipo
frutas[0].color
frutas[0].cantidad
frutas[0].dulce

==
==
==
==

"uva"
"rojo"
12
true

frutas[1].tipo

==

"kiwi"

frutas[1].color
frutas[1].cantidad
frutas[1].dulce
frutas[2].tipo
frutas[2].color
frutas[2].cantidad
frutas[2].dulce

Ciertamente, sabemos

==
==
==

"cafe"
98
true

== "banano"
== "amarillo"
== 0
== true
que frutas[2].cantidad

bananos.

JSON

En algn punto de su carrera de D3, encontrar la Notacin de Objetos de Javascript. Puede leer
los detalles, sin embargo JSON es bsicamente un tipo de sintaxis especfico para organizar datos
como objetos de JavaScript. Esta sintaxis se ha optimizado para uso con JavaScript (obviamente)
y llamadas AJAX, por eso es que ver muchos de los APIs de la red botando datos en formato
JSON. Es ms rpido y fcil de descomponer con JavaScript que XML y por supuesto, D3
funciona bien con este formato.
Todo esto, y en resumen no se ve mucho ms raro que lo que ya hemos visto:
var jsonFruta = {
"tipo": "uva",
"color": "rojo",
"cantidad": 12,
"dulce": true
};

La nica diferencia ac es que nuestros ndices ahora estn rodeados por comillas , de tal
forma que todos los valores son cadenas de caracteres.
GeoJSON

As como JSON es solamente un formalismo para la sintaxis de objetos de JavaScript existente,


GeoJSON es la sintaxis formal de objetos JSON, optimizada para almacenar informacin
geogrfica. Todos los objetos GeoJSON son objetos JSON, y todos los objetos JSON son objetos
de JavaScript.
GeoJSON puede almacenar puntos en un espacio geogrfico (tpicamente coordenadas
longitud/latitud), pero tambin formas (como lneas y polgonos) y otro tipo de representaciones
espaciales. Si tiene bastante informacin geogrfica, vale la pena descomponerla en formato
GeoJSON para optimizar su uso en D3.
Entraremos en detalles acerca de GeoJSON cuando hablemos de mapas geogrficos, pero por el
momento, es suficiente con saber que un dato simple en formato GeoJSON puede representarse
as:
var geodata = {
"type": "FeatureCollection",

"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [ 150.1282427, -24.471803 ]
},
"properties": {
"type": "town"
}
}
]
};

(Si es confuso, la longitud siempre se pone antes que la latitud. Tiene que acostumbrarse a pensar
en trminos de longitud/latitud en vez de latitud/longitud).
Siguiente: Diagrama de Barras >

Cmo Hacer un Diagrama de Barras


Ahora vamos a integrar todo lo que hemos aprendido hasta el momento para generar un
diagrama de barras simple con D3.
Empezamos revisando el diagrama de barras que hicimos anteriormente usando elementos div.
Luego, vamos a adaptar ese cdigo para dibujar las barras esta vez con SVG, lo cual nos da ms
flexibilidad en cuanto a la presentacin visual. Por ltimo, vamos a aadir etiquetas, de tal
manera que podamos ver el valor de los datos claramente.

El Diagrama Anterior
Ac est lo que hicimos la ltima vez, con datos nuevos.
var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,
11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class", "bar")
.style("height", function(d) {
var barHeight = d * 5;
return barHeight + "px";
});

Puede ser difcil imaginrselo, pero definitivamente podemos mejorar este diagrama hecho con
divs.

El Nuevo Diagrama
Lo primero es lo primero - toca decidir el tamao del nuevo SVG:
//Ancho y Altura
var w = 500;
var h = 100;

(Por supuesto, se debe nombrar w y h diferente, como svgWidth y svgHeight. Utilice lo que
tenga ms sentido para usted. JavaScript tiene una fijacin cultural con la eficiencia, entonces es
comn encontrar variables de un solo caracter, cdigo escrito sin espacios y otro tipo de sintaxis
que es difcil de leer pero que es eficiente desde el punto de vista de programacin.)
Luego, le decimos a D3 que cree un elemento SVG vaco y que lo aada al DOM:
//Crear un elemento SVG
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);

Esto inserta un nuevo elemento <svg> inmediatamente antes de la etiqueta de cierre </body>, y
le asigna el ancho de y la altura de 500 por 100 pixeles. Esta clusula tambin asigna el resultado
a la nueva variable llamada svg, de tal manera que se pueda referenciar fcilmente sin tener que
volver a seleccionarla en el futuro usando algo as como d3.select("svg").
Luego, en vez de crear divs, vamos a generar rect y los vamos a aadir a svg.
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", 20)
.attr("height", 100);

Este cdigo selecciona todos los rect dentro de svg. Por supuesto, an no existen, entonces el
programa devuelve una seleccin vaca. (S es raro, pero qudese y ver. Con D3 siempre es
necesario seleccionar primero aquello sobre lo que va a aplicar una accin, an cuando esa
seleccin est vaca por el momento.)
Luego, data(dataset) ve que existen 20 valores en el conjunto de datos, y llama 20 veces a
enter(). enter() a su vez devuelve la posicin a una seleccin por cada dato que hasta el
momento no tiene un rect correspondiente o sea, todos.
Para cada una de esas posiciones, la funcin append("rect") inserta la etiqueta rect en el
DOM. Como aprendimos en la introduccin a SVG, cada rect debe tener valores de x,y,
width y height Se utiliza attr() para aadir estos atributos a cada uno de los rectngulos que
se acaban de crear.
Qu belleza, no?

Bueno, tal vez no. Todas las barras estn ah (puede chequear el DOM de la pgina de ejemplo,
con el inspector de web), pero todas comparten los mismos valores de x, y, width y height,
y el resultado es que todas quedan sobrepuestas. Esto an no es una visualizacin de datos.
Arreglemos primero el tema de la sobre posicin. En vez de x con cero, se le asignar un valor
dinmico que corresponde a i, o la posicin del valor dentro del conjunto de datos. Entonces, la
primera barra tendr cero, pero las siguientes se ubicarn en el 21, luego el 42y as en adelante.
.attr("x", function(d, i) {
return i * 21; //Ancho de barras de 20 ms 1 espacio
})

Ac se ve el cdigo en accin.
Esto funciona pero no es particularmente flexible. Si el conjunto de datos tuviera ms elementos,
las barras seguiran hacia la derecha y se saldran del SVG! Debido a que cada barra tiene un
ancho de 20 pixeles y uno adicional para presentacin, el SVG de 500 pixeles solo puede incluir
23 datos. Mire cmo se corta la vigsima cuarta barra.

Es muy buena prctica utilizar coordenadas dinmicas y flexibles alturas, anchos, valores x y y
para que la visualizacin pueda cambiar de escala de acuerdo con los datos.
Como todo en programacin, existen mil maneras de lograr ese objetivo. Ac se va a mostrar una
sencilla. Primero, se cambia la lnea donde se defini la posicin x de cada barra.
.attr("x", function(d, i) {
return i * (w / dataset.length);
})

Se puede apreciar cmo el valor de x ahora est directamente asociado al ancho del SVG (w) y al
nmero total de valores del conjunto de datos (dataset.length). Esto es novedoso, porque
ahora las barras estn bien distribuidas, si se tienen 20 valores

o solo cinco:

Ac est el cdigo hasta el momento


Ahora se debe definir el ancho de las barras para que sean proporcionales, de tal manera que se
vuelvan ms angostas cuando se aaden ms datos o se agranden cuando hayan menos valores.
Voy a aadir una nueva variable cerca de donde se definen el ancho y la altura del SVG.
//Width and height
var w = 500;
var h = 100;
var barPadding = 1;

// <-- Nueva!

y luego se referencia esta variable en la lnea donde se define el ancho de cada barra. En vez de
tener un valor esttico de 20, el ancho se define como una fraccin del ancho del SVG y del
nmero de datos, menos el valor del espacio de colchn (padding).
`.attr("width", w / dataset.length - barPadding)`

Funciona!. El ancho de las barras y la posicin horizontal cambian de escala correctamente


cuando hay 20 datos o solo cinco.

O tambin 100:

Por ltimo, codificamos los datos de tal forma que correspondan a la altura de cada barra.
Pensara uno que es tan fcil como referenciar el valor del dato d para asignarle la altura
(height) a cada barra:
.attr("height", function(d) {
return d;
});

Se va raro. Tratamos de cambiar la escala de los nmero un poco?


.attr("height", function(d) {
return d * 4; // <-- Cuatro veces!
});

Realmente no es as de fcil se quiere que las barras crezcan hacia arriba desde el borde
inferior, no hacia abajo desde el tope. No se le debe echar la culpa a D3, ms bien a SVG.
Si recuerda del captulo de introduccin a SVG, cuando se dibujan rect, la x y la y se
especifican las coordenadas de la esquina superior izquierda. Esto quiere decir que el origen o
punto de referencia de cada rect es esa esquina. Para nuestro propsito, sera mucho ms fcil
definir el origen en la esquina inferior izquierda, pero as no es como funciona SVG, y en
realidad a SVG no le interesa qu pensemos al respecto.
Dado que nuestras barras deben crecer hacia abajo desde la parte superior, dnde queda
entonces el tope de cada barra con respecto al tope del SVG? El tope de cada barra se puede
expresar como la relacin entre la altura del SVG y el valor del dato correspondiente, de la
siguiente manera:
.attr("y", function(d) {
return h - d; //Altura menos el dato
})

Ahora, para poner la parte inferior de la barra en el fondo del SVG, cada altura de rect puede
ser el dato en s.
.attr("height", function(d) {
return d; //Solo el dato
});

Cambiemos la escala vertical multiplicando d por 4, o d*4. (Prximamente aprenderemos acerca


de las escalas en D3, que tiene mejores maneras de lograr esto mismo.)

Ac est el cdigo de nuestro diagrama de barras que est creciendo de arriba hacia abajo.

Color

Aadir color es fcil. Solamente utilice attr() y asigne un color de relleno fill:
.attr("fill", "teal");

Ac est el diagrama de barras verde azulado. Usualmente se usa el color de la figura para
mostrar algn otro atributo del dato. Esto quiere decir que se puede codificar un dato con el uso
de colores. (En el caso de nuestro diagrama de barras, esto permite codificacin doble, con lo
cual un solo dato tiene dos tipos de cdigos visuales: altura y color.)
Definir el color del grfico a partir de los datos es muy fcil - se escribe una funcin que
nuevamente referencia a d. Ac, se reemplaza el color verde azulado ("teal") con una funcin:
.attr("fill", function(d) {
return "rgb(0, 0, " + (d * 10) + ")";
});

Ac est el cdigo. No es particularmente til desde el punto de vista visual, pero ya se empieza
a tener la idea de cmo se puede traducir un dato a un color. Ac, d se multiplica por 10, y luego
se usa el valor azul en la definicin del color con la funcin rgb(). Con esto, a medida que el
valor de d es mayor (ms alta la barra), la barra toma un color ms azul. A medida que es menor
el valor, la barra tendr menos azul (se ver ms cerca del color negro).

Etiquetas
Las grficas son excelentes pero con alguna frecuencia tambin es necesario desplegar los
valores de los datos dentro de la grfica. Ac es donde las etiquetas de datos juegan un papel y es
muy, muy fcil desplegarlas con D3.
Si recuerda, en la introduccin a SVG se vio cmo se puede aadir elementos de texto (texto) a
un elemento de SVG. Se empieza con:
svg.selectAll("text")
.data(dataset)
.enter()

.append("text")

LO reconoce? De igual manera a como se hizo con rect, ac se hace con text. Primero, se
selecciona lo que se necesita, se traen los datos, se crean nuevos elementos (que inicialmente son
solamente espacios vacos), y finalmente se aaden nuevos elementos text al DOM.
Vamos a aadir al cdigo para incluir el valor del dato dentro de cada elemento text, por medio
del mtodo text().
.text(function(d) {
return d;
})

y luego se va a ampliar esto an ms, incluyendo los valores xy y para ubicar el texto. La forma
ms fcil consiste en copiar y pegar el mismo cdigo de x/y que se us antes para las barras.
.attr("x",
return
})
.attr("y",
return
});

function(d, i) {
i * (w / dataset.length);
function(d) {
h - (d * 4);

Aj! Etiquetas para los datos! Pero algunos estn cortados en la parte de arriba. Tratemos de
moverlos hacia abajo hacia el interior de las barras, lo cual se puede hacer con solo aadir
algunos clculos para los valores de x y y.
.attr("x",
return
})
.attr("y",
return
});

function(d, i) {
i * (w / dataset.length) + 5;

// +5

function(d) {
h - (d * 4) + 15;

// +15

Mejor, pero an no es muy legible. Afortunadamente se puede corregir esto:

.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "white");

Fantsti-cdigo!. Si no vive obsesionado con la tipografa, ya termin. Pero si es como yo, notar
que las etiquetas no estn alineadas perfectamente dentro de las barras. Eso se puede resolver
muy fcilmente. Usemos el atributo text-anchor para centrar el texto horizontalmente sobre al
valor de x.
`.attr("text-anchor", "middle")`

Ahora, cambiemos la manera como se calcula la posicin x asignndole el borde izquierdo ms


la mitad del ancho de la barra:
.attr("x", function(d, i) {
return i * (w / dataset.length) + (w / dataset.length - barPadding) / 2;
})

Completo!. Ya podemos salirnos de los diagramas de barras hacia otros temas.


Siguiente: Diagrama de Dispersin >

Cmo Hacer un Diagrama de Dispersin


Hasta el momento, hemos dibujado solamente diagramas de barra con datos simples solo
conjuntos de datos uni-dimensionales.
Cuando se tienen dos conjuntos de datos y se quiere generar una grfica en la cual se presentan
los dos, es necesario tener una segunda dimensin. El diagrama de dispersin es una
visualizacin comn con la que se pueden representar dos conjuntos de datos relacionadas en dos
ejes: horizontal y vertical, x y y.

Los Datos

Como se pudo ver en Tipos de Datos, existe mucha flexibilidad en cuanto se refiere a la
estructuracin de los conjuntos de datos. Para el diagrama de dispersin, se va a utilizar un
arreglo de arreglos. El arreglo primario contiene un elemento por cada dato. Cada uno de los
elementos de este dato ser a su vez otro arreglo, con dos datos, uno con el valor de x y otro
con el valor de y.
var dataset = [
[5, 20], [480, 90], [250, 50], [100, 33], [330, 95],
[410, 12], [475, 44], [25, 67], [85, 21], [220, 88]
];

Recuerde que [] significa arreglo, por consiguiente cuando se anidan los corchetes [[]] esto
significa que existe un arreglo dentro de otro arreglo. Los elementos dentro de un arreglo se
separan con comas, entonces un arreglo que contiene tres arreglos se muestra de la siguiente
manera: [[].[].[]]
Nuestros datos se pueden volver a escribir de la siguiente manera, que es ms fcil de leer:
var dataset = [
[
[
[
[
[
[
[
[
[
[
];

5,
480,
250,
100,
330,
410,
475,
25,
85,
220,

20
90
50
33
95
12
44
67
21
88

],
],
],
],
],
],
],
],
],
]

Ahora puede ver cada una de las diez filas le corresponder un punto de nuestra visualizacin.
En la fila [5,20] usaremos 5 como el valor de x y 20para el valor de y.
El Diagrama de Dispersin

Podemos traspasar la mayora del cdigo de nuestros experimentos con diagramas de barras,
incluyendo el que genera el elemento SVG.
//Crear un elemento SVG
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
En vez crear rect (rectngulos) en
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")

este caso se crearn circle (crculos) para cada dato.

Igualmente, en vez de especificar los atributos x, y, width y height de rect(rectngulo),


nuestros circle(crculos) necesitan cx, cy, y r:
.attr("cx", function(d) {
return d[0];
})
.attr("cy", function(d) {
return d[1];
})
.attr("r", 5);

Ac est el diagrama de dispersin funcionando.


Tome nota cmo es que accedemos a los valores de los datos y los usamos para definir los
valores de cx y cy. Cuando se usa la funtion(d), D3 entrega automticamente el valor actual de
d a su funcin. En este caso el valor actual es uno de los arreglos pequeos dentro del arreglo
ms grande denominado dataset.
Cuando d es un arreglo de valores ( y no un solo valor, como 3.14159), es necesario usar la
notacin de corchetes para obtener estos valores. Por eso, en vez de return d(o devolver d),
debemos usar return d[0] (devolver d[0]) y return d[1] (devolver d[1]), que devuelven los
primeros dos valores del arreglo.
Por ejemplo, en el caso de nuestro primer data [5, 20], el primer valor (posicin 0 del arreglo) es
5, y el segundo valor (posicin del arreglo 1) es 20. Por consiguiente:
d[0]

devuelve 5 d[1] devuelve 20

Por si acaso, si necesita obtener datos almacenados en un conjunto de datos grande (por fuera de
D3), lo puede hacer usando la notacin de corchetes. Por ejemplo.
dataset[5] returns [410, 12]

No me cree? Mire nuevamente el diagrama de dispersin, abra la consola de JavaScript y escriba


dataset[5] o dataset[5][1] y mire qu pasa.

Tamao

De pronto quiere que sus crculos tengan diferentes tamaos, de tal manera que sus radios se
definan en funcin de los valores de y. En vez de asignarle a todos los radios r, el valor de 5,
intente:
.attr("r", function(d) {
return Math.sqrt(h - d[1]);
});

Esto no es ni atractivo ni til, pero ilustra cmo se puede usar d con la notacin de corchetes para
referenciar valores y asignrselos a r.
Etiquetas

Pongmosle etiquetas a nuestros puntos con elementos text(texto). Ac voy a modificar el


cdigo de nuestros experimentos con diagramas de barras, empezando por:
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")

Hasta el momento, el cdigo busca los elementos text dentro del SVG (no existen an), y luego
aade un elemento text por cada dato. Ac se utiliza el mtodo text() para especificar el
contenido de cada elemento.
.text(function(d) {
return d[0] + "," + d[1];
})

Esto se ver desordenado, pero tenga paciencia. Ac otra vez estamos usando funtion(d) para
accesar los datos. Luego, dentro de la funcin, estamos usando d[0] y d[1] para obtener los
dos valores que estn almacenados en el arreglo de datos.
Los signos de +, cuando se usan con las cadenas de caracteres, tal como la coma entre las
comillas , actan como operadores de concatenacin. Entonces lo que est pasando en esta
lnea de cdigo realmente es: Obtenga los valores d[0] y d[1]y nalos con una coma en la
mitad. El resultado es algo similar a 5,20 o 25, 67.
Ahora especificamos donde se va ubicar el texto, con los valores x y y. Por el momento, usemos
d[0] y d[1], los mismos valores que usamos para especificar las posiciones del crculo
(circle).

.attr("x",
return
})
.attr("y",
return
})

function(d) {
d[0];
function(d) {
d[1];

Por ltimo, vamos a aadir algo de estilo con:


.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "red");

Ac est el cdigo funcionando.


Siguientes Pasos

Ojal que los conceptos fundamentales de D3 ya estn quedando claros: cmo cargar datos,
generar nuevos elementos, y usar valores de datos para generar los atributos de esos elementos.
Sin embargo, la imagen de arriba a duras penas pasa por una visualizacin de datos. El diagrama
de dispersin es difcil de leer y el cdigo no es muy flexible. Honestamente, an no hemos
mejorado broma con respecto al Asistente de Diagramas de Excel!
No hay por qu preocuparse: D3 es mucho ms interesante que el Asistente de Grficos (y eso
sin mencionar Clippy), pero para generar un diagrama interactivo y atractivo requiere que
subamos de nivel en nuestra destreza de D3. Para usar datos en forma flexible, vamos a aprender
acerca de las escalas de D3. Para que nuestro diagrama de dispersin sea ms fcil de leer,
vamos a aprender acerca de los generadores de ejes y las etiquetas de los ejes. Luego, vamos a
hacer que las cosas sean interactivas y vamos a aprender cmo actualizar los datos sobre la
marcha.
Siguiente: Escalas >

Escalas
Las escalas son funciones que mapean un dominio de datos de entrada a un rango de datos de
salida.
Definicin de escalas, segn Mike Bostock

No es usual que exista una correspondencia exacta entre los datos de un conjunto y las medidas
de los pixeles que se van a utilizar para una visualizacin. Las escalas proveen una manera
conveniente de mapear los datos originales a nuevos valores que son tiles para el propsito de
visualizacin.
Las escalas de D3 son funciones en las que quin hace la visualizacin es quien define los
parmetros. Una vez creada esta funcin, se invoca, se le pasa un valor y sta devuelve el valor
de salida, ya con el factor de conversin. Uno puede definir y usar tantas escalas como quiera.
Puede ser tentador pensar en una escala como algo que aparece visualmente en la imagen final
como una serie de marcadores que muestran una progresin de datos. No se deje engaar! Estos
marcadores son parte del eje, el cual es en esencia la representacin visual de la escala. Una
escala es una relacin matemtica, que no tiene un resultado visual como tal. Le recomiendo que
piense en escalas y ejes como dos elementos que estn relacionados.
Este tema describe nicamente escalas lineales puesto que son las ms comunes y fciles de
entender. Una vez entienda las escalas lineales, entender las dems va a ser muy fcil.
Manzanas y Pixeles

Imagnese que el siguiente conjunto de datos representa el nmero de manzanas que se vende
mensualmente en una tienda de frutas a lo largo de la carretera.
var dataset = [ 100, 200, 300, 400, 500 ];

Primero que todo, esto es buena noticia, pues la tienda est vendiendo 100 manzanas adicionales
cada mes! El negocio est creciendo. Para mostrar el xito, usted quiere mostrar en un diagrama
de barras la curva empinada hacia arriba desplegando las ventas de manzanas, en la que cada
dato corresponde a la altura de una barra.
Hasta el momento, hemos usado los datos directamente para su despliegue y se ha ignorado la
diferencia de unidades. Entonces, si se vendieron 500 manzana, esto significa que la barra
tendra un tamao de 500 pixeles.
Eso puede que funcione, pero que tal si al mes siguiente se venden 600 manzanas? Y que el ao
que viene se venden 1,800 manzanas? Las personas que ven sus datos tendran que adquirir
monitores ms grandes solamente para ver el tamao real de esas barras de manzanas! (Mmm,
barras de manzanas!)
Ac es donde entran a jugar las escalas. Puesto que las manzanas no son pixeles (tampoco son
naranjas), necesitamos utilizar escalas para traducir de una a la otra.

Dominios y Rangos

El dominio de entrada de una escala es el rango de los valores iniciales. Con los datos de
manzanas de arriba, el dominio de entrada sera 100 y 500 (para el mnimo y el mximo) o cero y
500.
El rango de salida de la escala es el rango de valores posibles de salida, que usualmente se
denominan valores de despliegue y usan pixeles por unidad de medida. El rango de salida lo
decide usted como diseador. Si usted decide que la barra ms pequea tendr una altura de 10
pixeles y que la ms alta tendr 350 pixeles, entonces usted puede definir el rango de salida de
10 a 350.
Por ejemplo, puede crear una escala donde el dominio de entrada es 100, 500 y el rango de
salida es de 10, 350. Si usted le da a esa escala un valor de 100, sta le devolver 10. Si usted le
da 500, le devolver 350. Si le da 300, le entrega 180 en una bandeja de plata. (300 es el centro
del dominio y 180es el centro del rango.)
Podemos visualizar el dominio y el rango como dos ejes correspondientes, uno junto al otro:
Dominio de Entrada 100 300 500 10 180 350 Rango de Salida

Un cosa ms. Dado que es muy fcil mezclar la terminologa de dominio de entrada y rango de
salida, les sugiero un pequeo ejercicio. Cuando diga entrada, usted dice dominio. Luego
digo salida y usted dice rango.
Listo? Bueno:

Entrada! Dominio!

Salida! Rango!

Entrada! Dominio!

Salida! Rango!

Entendi? Muy bien.


Normalizacin

Si est familiarizado con el concepto de normalizacin, puede ser conveniente que sepa que eso
es todo lo que est pasando aqu con una escala lineal.
La normalizacin es el proceso de mapeo de un valor numrico a un nuevo valor que est entre 0
y 1, basado en los posibles valores mnimos y mximos. Por ejemplo, con 365 das al ao, el da
nmero 310 se mapea a ms o menos 0.85 o 85% del recorrido del ao.

Con escalas lineales, dejamos que D3 se encargue de la matemtica que est detrs del proceso
de normalizacin. El valor de entrada se normaliza de acuerdo con el dominio y el valor
normalizado se cambia de escala para el rango de salida.
Creacin de una Escala

Los generadores de escala de D3 se puede acceder con d3.scale seguidos por el tipo de escala
que se desee.
var scale = d3.scale.linear();

Felicitaciones! Ya scale es una funcin a la que le puede pasar datos de entrada. (No se deje
confundir con var arriba; recuerde que en JavaScript las variables pueden guardar funciones.)
scale(2.5); //Devuelve 2.5

Puesto que no hemos definido un dominio ni un rango, esta funcin est mapeando la entrada a
la salida con una escala de 1:1. Esto quiere decir que lo que ingrese saldr sin ningn cambio.
Podemos fijar el dominio de entrada de la escala en 100, 500 si le pasamos esos valores como
un arreglo al mtodo domain().
scale.domain([100, 500]);

y los del rango de salida en forma similar, con range():


scale.range([10, 350]);

Estos dos pasos se pueden hacer por separado, como se acaba de mostrar, o se pueden encadenar
en una lnea de cdigo:
var scale = d3.scale.linear()
.domain([100, 500])
.range([10, 350]);

En cualquier caso, nuestra escala est lista!


scale(100);
scale(300);
scale(500);

//Devuelve 10
//Devuelve 180
//Devuelve 350

Por lo general, las funciones de escala se llaman desde el mtodo attr() u otros similares.
Cambiemos la visualizacin del Diagrama de Dispersin de tal manera que use escalas
dinmicas.
Definiendo la Escala de un Diagrama de Dispersin

Revisemos los datos del Diagrama de Dispersin:

var dataset = [
[5, 20], [480, 90], [250, 50], [100, 33], [330, 95],
[410, 12], [475, 44], [25, 67], [85, 21], [220, 88]
];
Si recuerda, dataset es un arreglo de arreglos. Mapeamos el primer valor en cada arreglo

al eje

x y el segundo valor al eje y. Empecemos con el eje x.


Mirando por encima los valores de x, vemos que el rango va de 5 a 480, por consiguiente un
dominio de entrada razonable puede ser 0, 500, cierto?
...

Por qu me mira de esa manera? Ah, porque quiere que su cdigo siga siendo flexible y
escalable, de tal manera que funcione cuando cambien los datos en el futuro. Muy inteligente!
En vez de especificar valores fijos para el dominio, podemos usar funciones que se aplican a los
arreglos y que son muy convenientes, tales como min() y max() para analizar el conjunto de
datos sobre la marcha. Por ejemplo, este cdigo pasa por todos los valores de x en nuestros
arreglos y devuelve el valor del mayor:
d3.max(dataset, function(d) {
//Devuelve 480
return d[0]; //Referencia el primer valor del sub-arreglo
});

Si se junta todo, podemos crear una funcin para cambiar la escala de nuestro eje de x:
var xScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[0]; })])
.range([0, w]);
Primero, observe que la nombramos xScale. Por supuesto que se puede usar cualquier nombra

para la escala, pero uno como xScale ayuda a recordarme lo que hace esta funcin.
Segundo, tome nota de que le asign cero al rango inferior del dominio de entrada. (De otra
manera, habra podido usar min() para calcular un valor dinmico.) El punto superior del
dominio se fij en el valor mximo del arreglo dataset (que es 480).
Por ltimo, observe que el rango de salida qued en 0 y w, el ancho del SVG.
Vamos a usar un cdigo similar para crear la funcin de escala en el eje y.
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[1]; })])
.range([0, h]);
Observe que la funcin max() referencia a d[1], el valor y de cada sub-arreglo. Tambin, el

punto superior del range() est definido como h en vez de w.

Las funciones de cambio de escala estn en su sitio! Ahora lo nico que falta es usarlas.
Simplemente toca modificar el cdigo donde se crea un circle (crculo) para cada dato.
.attr("cx", function(d) {
return d[0];
})

Para devolver un valor ajustado a la escala (en vez del valor original):
.attr("cx", function(d) {
return xScale(d[0]);
})

Igualmente, para el eje y, ste


.attr("cy", function(d) {
return d[1];
})

se cambia a:
.attr("cy", function(d) {
return yScale(d[1]);
})

Y por aadidura, hagamos el mismo cambio con las coordenadas de las etiquetas, entonces estas
lneas
.attr("x", function(d) {
return d[0];
})
.attr("y", function(d) {
return d[1];
})

se convierten en:
.attr("x",
return
})
.attr("y",
return
})

function(d) {
xScale(d[0]);
function(d) {
yScale(d[1]);

Y ya est!

Ac encuentra el cdigo funcionando. Visualmente, es tan decepcionante como el Diagrama de


Dispersin original! Sin embargo, hemos progresado ms de los que parece.

Refinando el Diagrama de Dispersin

Seguramente ha notado que los valores y ms pequeos estn ubicados en la parte alta de la
grfica, y que los ms grandes estn en la parte baja. Ya que estamos usando escalas, es muy fcil
cambiar esto, de tal manera que los mayores valores se muestren en la parte superior, como es de
esperarse. Es solo cuestin de cambiar el rango de salida de yScale de
.range([0,h]);

a
.range([h,0);

Ac encuentra este cdigo. S, ahora una menor entrada a yScale produce un valor de salida
mayor, de tal forma que los circle(crculos) y el text (texto) se empujan hacia abajo, ms cerca
de la base de la imagen. Yo s, parece demasiado fcil!
Sin embargo, algunos de los elementos salen cortados. Debemos introducir una variable de
padding.
var padding = 20;

Ac entonces podemos incorporar la cantidad de padding cuando estemos definiendo el rango


de las dos escalas. El rango de xScale era range([0, w]), y ahora queda como
.range([padding, w - padding])

El rango de yScale era range([h, 0]), y ahora es


.range([h - padding, padding]);

Esto nos debe dar 20 pixeles adicionales de espacio en los bordes izquierdo, derecho, superior e
inferior del SVG. Y efectivamente as es!

Pero las etiquetas en el costado derecho todava estn cortadas, entonces toca duplicar el tamao
del relleno (padding) de xScale, entonces se multiplica por dos:
.range([padding, w - padding * 2]);

Mejor! Ac est el cdigo. Pero an toca hacer un cambio. En vez de definir el radio de cada
circle(crculo) como la raz cuadrada de su valor y (que es un hack y realmente tampoco es
muy til), por qu no crear una escala a la medida?
var rScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[1]; })])
.range([2, 5]);

As, para definir el valor del radio, se programa de esta manera:


.attr("r", function(d) {
return rScale(d[1]);
});

Esto es emocionante, porque de esta manera se garantiza que todos los valores de los radios
siempre aparezcan dentro del rango 2,5. (O * casi* siempre. Vea la referencia a clamp()
debajo.) Los valores de 0 (el dato de entrada mnimo) recibirn crculos con radio de 2 (o un
dimetro de 4 pixeles). Los valores ms grandes se mostrarn como un crculo con radio de 5
(dimetro de 10 pixeles).

Voil: Nuestra primera escala para una propiedad visual con un uso diferente al valor de un eje.
Por ltimo y en el caso de que el poder de las escalas an no lo haya descrestado, me gustara
aadir un arreglo al conjunto de datos: [600, 150]

Boom! Ac est el cdigo. Puede notar cmo todos los puntos anteriores mantuvieron sus
posiciones relativas, pero ahora estn ms cerca de s mismos, ms abajo y hacia la izquierda
para acomodar al nuevo miembro.
Y ya, para una ltima revelacin: Muy fcilmente podemos cambiar el tamao de nuestro SVG,
y todo cambiar de escala conforme al cambio. Ac he incrementado el valor de h1 de 100 a 300
sin hacer ningn otro cambio:

Boom, nuevamente! El cdigo actualizado. Ojal que al ver esto pueda caer en cuenta que no es
necesario pasar largas noches cambiando cdigo porque un cliente decidi que la grfica debera
ser de 800 pixeles de ancho en vez de 600. S, va a poder dormir ms gracias a m (y los
excelentes mtodos que se hacen parte de D3). Estar descansado es una ventaja competitiva. Me
dar las gracias prximamente.
Otros Mtodos
d3.scale.linear()

tiene otros mtodos tiles que cabe mencionar brevemente ac:

nice() Esto le dice a la escala que tome cualquier dominio de entrada que
se le haya pasado a range(), y lo expanda al valor redondeado ms cercano.

Del wiki de D3 Por ejemplo, del dominio [0.20147987687960267,


0.996679553296417], el dominio nicees [0.2, 1]. Esto es bastante til para

personas normales que usualmente encuentran algo difcil leer nmeros


como 0.20147987687960267.
rangeRound()

Use rangeRound() en lugar de range() y todos los valores a los que se le


aplica la escala sern redondeados al nmero entero ms cercano. Esto es til si quiere que las
figuras tengan valores exactos en pixeles, para que los bordes no se vean borrosos por causa de
antialiasing.
clamp()

Por defecto, una escala lineal puede devolver valores que estn por fuera del rango
especificado. Por ejemplo, si se da un valor por fuera del dominio de entrada esperado, la escala
producir un nmero que tambin est por fuera del rango de salida. Al llamar a .clamp(true)
dentro de la escala, se encarga de que todos los valores queden dentro del rango especificado. Lo
que esto significa es que los valores excesivos se redondearn a los valores bajos y altos del
rango (aquel est ms cercano).
Otras Escalas

Adicionalmente a las escalas lineales(que se han explicado arriba), D3 incluye otros mtodos
para cambios de escala.

identity Una escala de 1:1 que se usa principalmente con valores en

pixeles.

sqrt Una escala de raz cuadrada

pow Una escala de potencia (buena para el gimnasio)

log Una escala logartmica

quatize Una escala lineal con valores discretos para el rango de salida, para

aquellos casos en que quiere organizar datos en buckets.

ordinal Escalas ordinales utilizan valores que nos son cuantitativos (como

nombres de categoras) como salida: perfecto para comparar peras y


manzanas.

Siguiente: Ejes >

Ejes
Ya con la maestra en el uso de escalas en D3, ahora tenemos el siguiente diagrama de
dispersin:

Si aadimos los ejes horizontal y vertical, podemos deshacernos de esos nmeros rojos tan
horribles que congestionan el diagrama.
Introduccin a Ejes

De manera similar a las funciones de escala, los ejes de D3 son realmente funciones a las que se
les pueden definir los parmetros. A diferencia de las escalas, cuando se invoca una funcin de
eje, sta no devuelve un valor, sino que genera los elementos visuales del eje, incluyendo lneas,
etiquetas y marcadores.
Tome nota que las funciones de ejes son especficas a SVG, puesto que generan elementos de
SVG. Tambin, el objetivo de los ejes es de que se usen en escalas cuantitativas (y no ordinales).
Construccin del Eje

Use d3.svg.axis() para cerrar una funcin genrica de eje.


var xAxis = d3.svg.axis();

Como mnimo, cada eje debe saber sobre qu escala debe operar. Ac le pasamos xScale del
cdigo del diagrama de dispersin:
xAxis.scale(xScale);

Tambin podemos especificar en donde deben aparecer las etiquetas con respecto al eje en s. Por
defecto se despliegan en la parte baja o bottom, lo que significa que aparecern debajo de la
lnea del eje (Aunque esto se asigna por defecto, no sobra especificarlo explcitamente.)
xAxis.orient("bottom");

Por supuesto que podemos ser ms concisos y encadenar todo esto en una sola lnea:
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");

Por ltimo, para generar el eje e insertar todos estos marcadores pequeos y etiquetas dentro de
nuestro SVG, debemos llamar a la funcin xAxis. Voy a aadir este cdigo al final de nuestro
script, de tal manera que el eje se genere despus de los dems elementos del SVG:
svg.append("g")

.call(xAxis);

La funcin call() de D3 toma una seleccin como entrada y entrega esa seleccin a cualquier
funcin. Entonces, en este caso, hemos aadido un nuevo elemento de grupo g que contiene
todos los elementos de los ejes que estn para ser generados. (La g no es estrictamente necesaria,
pero ayuda a mantener organizados a los elementos y nos permite aplicar una clase al grupo
entero, que es lo que voy a hacer en un instante.)
La g se convierte en la seleccin para el siguiente eslabn de la cadena. call() entrega esta
seleccin a la funcin xAxis, para que se genere nuestro eje dentro del la nueva g. Las lneas de
cdigo de arriba son la versin limpia y abreviada de su equivalente:
svg.append("g")
.call(d3.svg.axis()
.scale(xScale)
.orient("bottom"));

Ve, es posible empaquetar toda la funcin de eje dentro de call(), sin embargo es ms fcil por
lo general para nuestras mentes definir primero la funcin y luego invocarlas.
En todo caso, ac se ve

Haciendo Limpieza

Tcnicamente, ese es un eje, pero no es ni agradable a la vista ni til. Para limpiarlo, empecemos
por asignarle una clase de axis a nuestro nuevo elemento g, de tal manera que lo podamos usar
con CSS:
svg.append("g")
.attr("class", "axis")
.call(xAxis);

//Assign "axis" class

Despus, introducimos nuestros primeros estilos de CSS, en la etiqueta <head> de nuestra


pgina:
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
La propiedad shape-rendering es

un atributo de SVG, que se utiliza para asegurarse de que


nuestros ejes y marcadores estn perfectos a nivel de pixel. No podemos tener ejes borrosos!

Se ve mejor, pero la parte de arriba del eje est cortada, y queremos que est en la parte inferior
del diagrama. Podemos transform (transformar) el grupo entero del eje, empujndolo al fondo:
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis);
Tome nota del uso de (h - padding), pra que el borde de arriba se le asigne h,

la altura de la
imagen completa, menos el valor de padding (colchn) que creamos anteriormente.

Mucho mejor! Ac est el cdigo que llevamos hasta el momento.


Buscando Marcadores

Los marcadores en D3 proporcionan informacin. Aadir ms marcadores es necesariamente


mejor, pero despus de cierto punto empiezan a congestionar el diagrama. Podr notar que nunca
hemos especificado cuntos marcadores se deben incluir en el eje y a qu intervalos deben
aparecer. Sin instrucciones claras, D3 en forma automtica y mgica examin nuestra escala
xScaley determin a su juicio cuntos marcadores debi incluir y a qu intervalos (cada 50 en
este caso).
Como puede imaginrselo, es posible adecuar todos los aspectos de los ejes, empezando con el
nmero aproximado de marcadores, usando la funcin ticks():
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(5); //Nmero aproximado de marcadores

Ac est este cdigo


Probablemente not que cuando an cuando especificamos solamente cinco marcadores, D3 ha
tomado la decisin ejecutiva y pedido un total de siete. Esto es porque D3 nos est protegiendo y
calcul que si se incluan solo cinco marcadores, esto habra requerido dividir el dominio de
entrada en valores no muy vistosos es este caso 0, 150, 300, 450, y 600. D3 interpreta el valor
de ticks() solamente como una sugerencia y lo sobreescribe con lo que considere con los
valores que considere como los ms legibles en este caso intervalos de 100 as sea que esto
requiera aadir ms o disminuir el nmero de marcadores que usted solicit. Esto es una
funcionalidad totalmente brillante que incrementa la escalabilidad de su diseo: a medida que
cambia su conjunto de datos, y el dominio de entrada se expande o se contrae (nmeros ms
grandes o ms pequeos), D3 se asegura que las etiquetas de los marcadores permanezcan
legibles y fciles de leer.
Y No?

Es hora de aadirle etiquetas al eje vertical! Si copiamos y cambiamos el cdigo que ya


escribimos para xAxis, debemos aadir esto en la parte de arriba de nuestro cdigo
//Define Y axis
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(5);

y esto hacia la parte de abajo:


//Create Y axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding + ",0)")

.call(yAxis);

Puede darse cuenta que las etiquetas estn orientadas hacia la izquierda (left) y que el yAxis
perteneciente al grupo g se ha trasladado hacia la derecha en la cantidad que se ha determinado
con padding (colchn).

Esto est empezando a verse como algo real! Pero las etiquetas de yAxis estn quedando
cortadas. Para darles ms espacio a la izquierda, voy a incrementar el valor de padding de 20 a
30:
var padding = 30;

Por supuesto, tambin se habra podido introducir variables separadas de padding para cada eje,
por decir algo xPaddingy yPadding , para obtener an ms control sobre el despliegue.
Ac est el cdigo y as se ve:

Toques Finales

Para probarle que nuestros nuevos ejes son dinmicos y escalables, quiero reemplazar nuestro
conjunto de datos esttico por una serie de nmeros generados al azar:
//Dynamic, random dataset
var dataset = [];
var numDataPoints = 50;
var xRange = Math.random() * 1000;
var yRange = Math.random() * 1000;
for (var i = 0; i < numDataPoints; i++) {
var newNumber1 = Math.round(Math.random() * xRange);
var newNumber2 = Math.round(Math.random() * yRange);
dataset.push([newNumber1, newNumber2]);
}

Este cdigo inicializa un arreglo vaco, y luego lo recorre 50 veces, selecciona dos nmeros al
azar cada vez y aade (empuja) ese par de datos al arreglo dataset.

Intente el cdigo aqu. Cada vez que refresque la pgina ver valores diferentes. Mire cmo los
dos ejes se ajustan a los nuevos dominios y cmo se escogen marcadores y etiquetas conforme a
los cambios.
Ya que he dicho lo que tena decir al respecto, creo que podemos por fin omitir esas etiquetas
rojas tan feas y omitir las lneas de cdigo relevante:

Nuestro cdigo final del diagrama de dispersin!


Formateo de las Etiquetas de Marcadores

Una ltima cosa: Hasta el momento hemos estado trabajando con nmeros enteros que son
agradables y fciles. Pero por lo general los datos son ms complejos y en esos casos, es posible
que quiera tener ms control sobre los formatos de las etiquetas de los ejes. Ingrese

tickFormat(),

que permite especificar cmo puede formatear los nmeros. Por ejemplo, si
quiere incluir tres puntos decimales o mostrar los valores como porcentajes, o ambos.
En este caso, podra definir una funcin para formateo de nmeros primero. Esta, por ejemplo,
dice que se deben tratar como porcentajes con un solo nmero decimal. (Revise el documento de
referencia de d3.format() para ver ms opciones).
var formatAsPercentage = d3.format(".1%");

Luego, dgale a su eje que use esta funcin de formateo para las etiquetas, p. ej.:
xAxis.tickFormat(formatAsPercentage);

Consejo para desarrolladores: Yo encuentro que lo ms fcil es chequear estas funciones de


formateo en la consola de JavaScript. Por ejemplo, abra cualquier pgina que carga D3, como
nuestro diagrama de dispersin final y escriba su regla de formateo en la consola. Luego,
chequela entregndole un valor, tal como lo hara con cualquier otra funcin:

Puede rever que el dato 0.54321 se convierte a 54.3% para efectos de despliegue perfecto!
Intente el cdigo aqu. El formato de porcentaje no tiene sentido con el conjunto de datos actual,
pero como ejercicio, puede intentar modificar cmo es que se generan los nmeros aleatorios,
para lograr valores que no son enteros, pero que sean ms apropiados. Tambin puede
experimentar con la funcin de formateo en s.
Ha terminado el tutorial de D3, pero es posible que aada ms en el futuro. Para recibir
notificaciones en el futuro, sgame por Twitter o observe este RSS feed

Anda mungkin juga menyukai