Data Driven Documents
David García Garzón
Explicar los conceptos detrás de D3.
Una librería Javascript para
representación visual de datos
Base: Javascript, SVG
Cómo se integra con nuestra pila:
Mithril, Webpack…
Puedes escoger lo que cargas
Se puede ampliar vía plugins
d3.selection
: buscar y alterar DOMd3.array
: manipular los datos a visualizard3.scale
: mapeo datos-representaciónd3.axis
: dibujar ejesd3.transition
: cambios animadosLos setters retornan this
en vez de undefined
. Para poder encadenar varios setters sin mediar variables.
Convención: En una cadena de setters se desindentan los que no retornan this, para indicar que el objeto cambia.
API D3 usa el setter sin parámetro como getter
Ojo, fallo típico: Llamar setter con valor undefined
.
La base de operación de D3.
Muy parecido a JQuery. Usa selectores XPath/CSS.
d3.select(selector)
: first matching elements in the whole document
d3.selectAll(selector)
: all matching elements in the whole document
selection.select[All](selector):
first/all matching child elements in selections
// Crean elementos nuevos y los retornan
sel.append('ul'); // como último hijo
sel.insert('ul', hermano); // antes de hermano o primer hijo
sel.clone(); // replica la selección en el mismo padre
sel.remove(); // eliminan la selección
// Reordenar
sel.raise(); sel.lower(); // mueve como primer o último hijo
sel.sort(orderFunction); // reordena la selección
sel.order() // fija el orden de la selección
// Con valor son setters, retornan la selección original
sel.attr(name, value);
sel.style('attrib' , value);
sel.classed('class1 class2', true);
sel.property('checked', value);
sel.text(text);
sel.html(htmlLiteral);
Si el valor es una función, recibe: (datum, index, nodes). this
seria nodes[i]
.
Si no se pone valor, hace de getter, no de setter.
En el oncreate
, ampliamos con D3 el nodo raiz que ha construido Mithril.
myd3widget.view = function(vn) {
return m('svg', ...);
};
myd3widget.oncreate = function(vn) {
var visualization = d3.select(vn.dom);
// Rellenamos con código D3 aquí
};
Dejamos a D3 gestionar el binding de datos y las animaciones.
Selecciones especiales de asociación de datos
var circle = svg.selectAll("circle")
.data(data) // UPDATE: datos ya asociados
.style("fill", "blue");
circle.exit().remove(); // EXIT: elementos sin datos
circle = circle.enter() // ENTER: datos sin elementos
.append("circle")
.style("fill", "green")
.merge(circle) // ENTER + UPDATE: nuevos y añadidos
.style("stroke", "black");
Podemos usar los setters pasando funciones como valor. La función se llama para cada elemento de la selección, pasando el dato asociado.
Las escalas mapean valores de dominio de datos a valores de representación (posición, color, etiquetas…)
// Tipos: scaleLinear, scalePow, scaleLog, scaleOrdinal...
var scale = d3.scaleLinear()
.domain([10, 130])
.range([0, 960]);
// Ojo: Arrays de dos posiciones, no dos parámetros
// Son callables
scale(20); // 80
scale(50); // 320
scale.invert(80); // 20, de representación a dominio
scale.domain(); // [10, 130], getter/setter
scale.ticks(10); // 10 puntos representativos
// [ 200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000 ]
Puntos representativos (redondos)
scale.ticks(10); // 10 puntos
// [ 200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000 ]
// Funcion o especificador de formato para los valores de tick
scale.tickFormat(
scale.ticks(10).map(scale.tickFormat())
scale.nice()
extiende los limites del dominio a valores redondos.
Linear
: x: y = mx + b
Pow
: x: y = mx^k + b
(configurable exponent
)Log
: x: y = m log(x) + b
(configurable base
)Identity
: Alias para Linear
de [0,1] a [0,1]Sqrt
: Alias para Pow
con exponent 0.5
Por defecto, un valor fuera del intervalo/dominio se extrapola.
Si indicamos scale.clamp()
, se mapea al valor extremo.
Se usa una funcion en vez de un intervalo de salida
Pensados para usar interpoladores de colores del paquete d3.scale-chromatic
Sequential
: Dominio definido por dos valores, se mapean a 0,1 que se pasa al interpolador
Diverging
: Dominio definido por tres valores, se mapean a -1, 0, 1, y se pasa al interpolador
Dominios continuos a un conjunto limitado de valores
Quantize
: Segmentos de igual longitud en el dominioQuantile
: Segmentos con igual numero de elementos del domainThreshold
: Segmentos con umbrales arbitrarios (domain define N umbrales, range N+1 salidas)scale.invertExtend(valorSalida)
-> [inicio, fin]
Ordinal
: Discretos a discretos, por ordenPoint
: Discretos a puntos espaciados en el intervalo
padding
(outer) como ratio del rangeBand
: Distribuye y expande elementos discretos en el intervalo
paddingInner
y paddingOuter
bandwidth
resultanteTime
: domain is local timeUtc
: domain is utc timeGenera SVG’s para los ejes de una gráfica.
Se basa en un scale.
Movimientos suaves de un estado a otro.
// Definimos la transición a partir de una selección
var t = selection.transition('mytransition')
// Timing de la transición
.delay(100) // milliseconds, default 0
.duration(6000) // milliseconds, default 250ms
.ease(d3.easeLinear) // default d3.easeCubica
// el módulo d3-ease contiene diversos tipos de transiciones
// Despues decimos que parametros transicionamos
.attr('attribute', targetValue)
.style('attribute', targetValue)
.text(targetText) # busca patrones numericos y los interpola
.remove() // borra lo seleccionado cuando acabe la transición
t.interrupt(name); // Para la transición
t.transition(name); // Crea una transicion sequencial a la anterior
t.select(...); // Crea una subtransicion paralela con un
// subconjunto de elementos
t.selection(); // Devuelve la selección orignal (sin transición)
// Util para seguir con la cascada
t.merge(nodes); // Añade nodos a la transición
t.on('start', callback)
// Llama el callback cuando empiece la transicion
// Tambien 'end' y 'interrupt'
Cuando los interpoladores por defecto no bastan
transition
// Llamadas equivalentes
.style('fill', 'blue') // por defecto
.styleTween("fill", function() {
// podriamos escoger otro del módulo d3-interpolate
return d3.interpolateRgb(this.style.fill, "blue");
});
// O nuestro propio interpolador
.attrTween('attribute', function() {
// Initialization here
return function(t) {
// t is 0 to 1 point from the ease
return computedAttrValue;
}
}
d3-dispatch: Mecanismo de signal-slot
d3-timer: Temporizador pensado para funcionar con animaciones
d3-ease: Libreria de funciones de transición
d3-scale-chromatic: Libreria de escalas de color
d3-random: Generar diversas distribuciones
d3-interpolate: Métodos de interpolación entre diversos tipos de objetos: numeros, colores, curvas…
d3-format: Number formating
d3-time: Operaciones convenientes para tiempo
d3-time-format: Date/Time formating
d3-path: Permite reusar codigo canvas para generar svg d3 compatible
d3-quadtree: Divide y venceras para optimizar busquedas multidimensionales
Manipulacion de color.
Map, Set y Nest
Nest esta pensado para hacer ‘group by’.
Contiene tipos de curbas de transición