Histogram Layout

En esta sección presentaremos el layout para crear histogramas. Primero, cargamos los datos usando d3.json (recuerde que es asíncrono):

var datos; d3.json('/assets/data/food.json', function(error, data) { if (error) { console.error(error); } datos = data; });

Definimos los parámetros del gráfico y la función de acceso:

var marginBottom = 40, marginLeft = 20, width = 800 - marginLeft, height = 600 - marginBottom; var value = function(d) { return d.calorias; }

Creamos el histogram layout. Observe que el layout necesita conocer los ticks del dominio de la escala de x para generar los intervalos del histograma.

//Escala en x var xScale = d3.scale.linear() .domain([0, d3.max(datos, value)]) .range([0, width]); //Layout var histLayout = d3.layout.histogram() .bins(xScale.ticks(40)) .value(value);

Hemos definido la cantidad de 'bins', esto es, en la práctica, la cantidad de barras que tendrá nuestro histograma. En este caso, estamos dividiendo el dominio de nuestra escala en 40 intervalos disjuntos de misma longitud. Recuerde que, en el histograma, la altura de las barras representa la cantidad de valores que caen en cada uno de estos intervalos. Esto es distinto de un gráfico de barras en el que se grafica alguna observable asociada a un conjunto de entidades.

La variable histLayout es una función de layout. Cuando la aplicamos a nuestros datos, se calcula, entre otras cosas, la posición en la que dibujaremos las barras y la cantidad de valores que caen dentro de cada intervalo. Después de ejecutar el siguiente código, observe la variable hist en la consola.

var hist = histLayout(datos);

Finalmente, graficamos las barras:

// Escala en y var yScale = d3.scale.linear() .domain([0, d3.max(hist, function (d) { return d.y; })]) .range([0,height]); //Creando svg var svg = d3.select('#ejemplo-a01').selectAll('svg').data([hist]); svg.enter().append('svg'); svg .attr('width', width + marginLeft) .attr('height', height + marginBottom); //Definimos el eje x var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom"); var gAxis = svg.selectAll('g.eje').data([hist]); gAxis.enter().append("g") .attr("class", "eje"); gAxis .attr("transform", "translate(" + marginLeft + "," + (height + 1) + ")") .call(xAxis); gAxis.exit().remove(); // Creamos un grupo para cada barra var gBars = svg.selectAll('g.bar').data(hist); gBars.enter().append('g') .classed('bar', true); // Trasladamos los grupos gBars.attr('transform', function(d) { return 'translate(' + ( marginLeft + xScale(d.x) ) + ', ' + 0 + ')'; }); gBars.exit().remove(); // Creamos las barras var rects = gBars.selectAll('rect.bar').data(function(d) { return [d]; }); rects.enter().append('rect') .classed('bar', true) .attr('fill', 'blue') .attr('x', 1) .attr('y', height) .attr('width', xScale(hist[0].dx) - 1) .attr('height', 0); rects.transition().duration(2000) .attr('y', function(d) { return height - yScale(d.y)}) //Observe el posicionamiento de la barra .attr('height', function (d) { return yScale(d.y)}) .attr('width', xScale(hist[0].dx) - 1); rects.exit().remove();