Introducción
Objetivo
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...
Librería Modular
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 animados- ...
Idiomas
Los 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.
Idiomas
API D3 usa el setter sin parámetro como getter
Ojo, fallo típico: Llamar setter con valor undefined
.
d3.select('circles')
// Error rabiox en vez de radiox
// es undefined, y se llama como getter
// retorna el valor actual de rx y no this
.attr('rx', config.posx)
// Missleading Error: 100.attr is not a function
.attr('ry', config.poxy)
Selections
Selecciones
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
Modificando selecciones
// 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
Modificando selecciones
// 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.
Integración Mithril {
data-background-image="../images/logo-somenergia-nobg.svg"
data-background-size="80%"
}
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.
Integración de datos
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");
Usando los datos
Podemos usar los setters pasando funciones como valor. La función se llama para cada elemento de la selección, pasando el dato asociado.
circle = circle.enter() // ENTER: datos sin elementos
.append("circle")
.style("stroke", function(d, i, nodes) {
return domainFieldToStrokeScale(d.mydomainField)+'px';
})
Control flow
Scales
Scale
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 ]
Ticks
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.
Escalas Numéricas
Linear
:x: y = mx + b
Pow
:x: y = mx^k + b
(configurableexponent
)Log
:x: y = m log(x) + b
(configurablebase
)Identity
: Alias paraLinear
de [0,1] a [0,1]Sqrt
: Alias paraPow
conexponent 0.5
Por defecto, un valor fuera del intervalo/dominio se extrapola.
Si indicamos scale.clamp()
, se mapea al valor extremo.
Escalas interpoladas
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\
{height=20px}
Diverging
: Dominio definido por tres valores, se mapean a -1, 0, 1, y se pasa al interpolador\
{height=20px}
Escalas discretas
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]
Dominios Discretos
Ordinal
: Discretos a discretos, por ordenPoint
: Discretos a puntos espaciados en el intervalo- Definimos
padding
(outer) como ratio del range
- Definimos
Band
: Distribuye y expande elementos discretos en el intervalo- Definimos
paddingInner
ypaddingOuter
- Devuelve el inicio de cada banda y el
bandwidth
resultante
- Definimos
Dominio temporal
Time
: domain is local timeUtc
: domain is utc time
Axis
Axis
Genera SVG's para los ejes de una gráfica.
Se basa en un scale.
var axis = d3.axisLeft/Right/Top/Bottom(scale);
axis.ticks(...); // set explicit ticks
axis.ticks(); // get the ticks
Animaciones
Transition
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
Avanzado
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'
Tweening
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;
}
}
Otros módulos
Infrastructura básica
- d3-selection: Busqueda y manejo en bloque de elementos del dom a partir de selectores css
- d3-transition: TODO
- d3-scale: Abstrae correspondencias entre datos y representación
Interacción
- d3-axis: Ejes de coordenadas según una escala
- d3-brush: Selector de rango uni o bidireccional
- d3-zoom: Maneja transformaciones de panning y zoom
- d3-drag: Gestionar eventos de drag and drop
Datos dominio
- d3-fetch: Load external data (json, dsv, binary, xml...)
- d3-dsv: Cargador de Delimiter Separated Values (CSV, TSV...)
- d3-array: Augmenta los métodos de array: estadisticos, busqueda, histogramas, transformación...
- d3-collection: Mapas, Conjuntos con api mas guai y Nests (datos anidados)
- d3-hierarchy: Navegación en estructuras jerarquicas y varios tipos de visualizaciones
Visualizaciones
- d3-shape: Dibuja Tartas, sectores, linieas punteadas, curvas, areas, linieas de enlace, barras apiladas...
- d3-polygon: Cálculos con poligonos: area, perímetro, centroide, inclusion, casco convexo
- d3-color: Manipulacion de colores en varios espacios cromáticos
- d3-geo: Como polygon pero en geodesicas, y transforma a diversas proyecciones, carga geojson
- d3-contour: Genera diagramas de controrno sobre datos, dispersiones y funciones 2D
- d3-voronoi: Genera diagramas de voronoi
- d3-chord: Genera diagramas de cuerdas (relaciones entre elementos en un circulo)
- d3-force: Anima posiciones de los nodos simulando fuerzas: de enlace, campos, direccionales, radiales...
Otros
- 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
d3.color
Manipulacion de color.
d3.collections
Map, Set y Nest
Nest esta pensado para hacer 'group by'.
d3.ease
Contiene tipos de curbas de transición