2013-03-03 4 views
21

Я делаю гистограмму с использованием библиотеки javascript Dimensional Charting dc.js, которая основана на d3 и crossfilter.Правильно отображать ширину бункера в barChart с помощью dc.js и crossfilter.js

Все, что я хочу сделать, это показать гистограмму с указанным количеством ящиков --- это должно быть легко с помощью функции 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

Это на самом деле не выглядит правильно: каждый бар действительно тощий! Я хочу нормальную гистограмму, где бары толстые и почти касаются друг друга, возможно, пару пикселов прокладки между каждым баром. Любая идея, что я делаю неправильно?

ответ

27

Таблицы диаграмм в dc.js используют xUnits function, чтобы автоматически рассчитать ширину баров в гистограмме в зависимости от диапазона вашей оси х. Если вы хотите установить ширину статического значение, которое вы можете использовать функцию пользовательских xUnits, например:

chart.xUnits(function(){return 10;}); 

Это должно дать вам более подходящую ширину.

2

suggestion given by user2129903, чтобы использовать chart.xUnits(), чтобы указать пользовательскую функцию xUnits, действительно, это путь. Я хотел бы добавить к этому пример и немного объяснения, чтобы выбрать возвращаемое значение этой пользовательской функции.

Док говорит:

Эта функция должна вернуть массив Javascript всех точек на оси х, или число точек на оси.

То есть, предполагая, что вы хотите сделать гистограмму, вы можете либо указать количество ячеек, либо вычислить его из нужного размера бункера и вернуть его из этой функции. Вы должны указать это, когда числовые клавиши вашей группировки не являются последовательными, равноудаленными целыми числами.

Вот пример:

<!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;});}); 

Это, однако, приведет к сбою (т. Е. Приведет к неправильной ширине бара) при наличии пустых бункеров.

Для справки: