Правильно отобразить ширину ячейки в barChart с помощью dc.js и crossfilter.js
Я делаю гистограмму, используя библиотеку javascript Dimensional Charting dc.js, которая основана на d3 и crossfilter.
Все, что я хочу сделать, это отобразить гистограмму с указанным количеством ящиков --- это должно быть легко с помощью функции barChart
. У меня есть массив с именем data
, который содержит значения с плавающей запятой между 0 и 90000, и я просто хочу отобразить распределение с использованием гистограммы с 10 ячейками. Я использую следующий код для создания гистограммы ниже:
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);
![histogram]()
Это действительно не выглядит правильно: каждый бар действительно тощий! Я хочу нормальную гистограмму, где бары толстые и почти касаются друг друга, возможно, пару пикселов прокладки между каждым баром. Любая идея, что я делаю неправильно?
Ответы
Ответ 1
В столбчатых диаграммах dc.js используйте функцию xUnits, чтобы автоматически вычислять ширину баров в гистограмме в зависимости от диапазона ваших ось х. Если вы хотите установить ширину в статическое значение, вы можете использовать пользовательскую функцию xUnits, например:
chart.xUnits(function(){return 10;});
Это должно дать вам более подходящую ширину.
Ответ 2
Рекомендация заданная пользователем2129903, чтобы использовать chart.xUnits()
для указания пользовательской функции xUnits
, действительно является способом выхода.
Я хотел бы добавить к этому пример и немного объяснения, чтобы выбрать возвращаемое значение этой пользовательской функции.
Док говорит:
Ожидается, что эта функция вернет массив Javascript для всех точек данных по оси x или числа точек на оси.
То есть, предполагая, что вы хотите сделать гистограмму, вы можете либо напрямую указать количество ящиков, либо вычислить их из нужного размера бункера и вернуть это из этой функции. Вы должны указать это, когда числовые клавиши вашей группировки не являются последовательными, равноудаленные целые числа.
Вот пример:
<!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>
Обратите внимание, что в этом примере он также может работать для извлечения количества бинов или значений ключей бункеров из самого объекта группы, например, как это
// 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;});});
Однако это приведет к сбою (т.е. приведет к неправильной ширине бара), когда есть пустые ячейки.
Для справки: