javascript - Visualice correctamente el ancho del contenedor en barChart usando dc.js y crossfilter.js
d3.js (2)
La sugerencia dada por user2129903 para usar el chart.xUnits()
para especificar una función xUnits
personalizada es de hecho el camino a seguir. Me gustaría agregar a esto un ejemplo y una pequeña explicación para elegir el valor de retorno de esa función personalizada.
El doc dice:
Se espera que esta función devuelva una matriz Javascript de todos los puntos de datos en el eje x, o la cantidad de puntos en el eje.
Es decir, suponiendo que quiera hacer un histograma, puede especificar directamente el número de contenedores o calcularlo a partir del tamaño de contenedor deseado y devolverlo desde esa función. Debe especificar esto cuando las teclas numéricas de su agrupación no sean enteros sucesivos equidistantes.
Aquí hay un ejemplo:
<!DOCTYPE html><meta charset="utf-8">
<head>
<link rel="stylesheet" type="text/css" href="js/dc.css"/>
<script src="js/crossfilter.js"></script>
<script src="js/d3.js"></script>
<script src="js/dc.js"></script>
</head>
<body>
<div id="chart"></div>
</body>
<script>
// generate data
var min_value = 0, max_value = 18, value_range = max_value-min_value;
var data = [];
for (var i = 0; i < 1000; i++)
data.push({x: Math.random()*value_range+min_value});
// create crossfilter dimension for column x
var cf = crossfilter(data),
x = cf.dimension(function(d) {return d.x;});
// create histogram: group values to `number_of_bins` bins
var number_of_bins = 10,
bin_width = value_range/number_of_bins,
//number_of_bins = value_range/bin_width,
x_grouped = x.group(
function(d) {return Math.floor(d/bin_width)*bin_width;});
// generate chart
dc.barChart("#chart").dimension(x)
.group(x_grouped)
.x(d3.scale.linear().domain([min_value,max_value]))
// let the bar widths be adjusted correctly
.xUnits(function(){return number_of_bins;})
.xAxis();
dc.renderAll();
</script>
Tenga en cuenta que en este ejemplo también puede funcionar para recuperar el número de contenedores o los valores clave de los contenedores del objeto del grupo en sí, por ejemplo, como este
// number of bins
chart.xUnits(function(){return x_grouped.all().length;});
// bins'' key values
chart.xUnits(function(){return x_grouped.all().map(function(d) {return d.key;});});
Sin embargo, esto fallará (es decir, producirá el ancho de barra incorrecto), cuando haya contenedores vacíos.
Para referencia:
Estoy haciendo un gráfico de barras usando la biblioteca de Dimension Charting javascript dc.js , que se basa en d3 y crossfilter.
Todo lo que quiero hacer es mostrar un histograma con un número específico de bandejas --- esto debería ser fácil usando la función barChart
. Tengo una matriz llamada data
que contiene valores de coma flotante entre 0 y 90000, y solo quiero mostrar la distribución usando un histograma con 10 contenedores. Uso el siguiente código para producir el histograma a continuación:
var cf = crossfilter(data);
var dim = cf.dimension(function(d){ return d[attribute.name]; });
var n_bins = 10;
var xExtent = d3.extent(data, function(d) { return d[attribute.name]; });
var binWidth = (xExtent[1] - xExtent[0]) / n_bins;
grp = dim.group(function(d){return Math.floor(d / binWidth) * binWidth;});
chart = dc.barChart("#" + id_name);
chart.width(200)
.height(180)
.margins({top: 15, right: 10, bottom: 20, left: 40})
.dimension(dim)
.group(grp)
.round(Math.floor)
.centerBar(false)
.x(d3.scale.linear().domain(xExtent).range([0,n_bins]))
.elasticY(true)
.xAxis()
.ticks(4);
Eso realmente no se ve bien: ¡cada bar es realmente flaco! Quiero un histograma de aspecto normal, donde las barras son gruesas y casi se tocan, con tal vez un par de píxeles de relleno entre cada barra. ¿Alguna idea de lo que estoy haciendo mal?
Los gráficos de barras en dc.js usan la función xUnits para calcular automáticamente el ancho de las barras en un histograma en función del rango de su eje x. Si desea establecer el ancho en un valor estático, puede usar una función xUnits personalizada, por ejemplo:
chart.xUnits(function(){return 10;});
Esto debería darle un ancho más apropiado.