Подтвердить что ты не робот

Правильно отобразить ширину ячейки в 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

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

4b9b3361

Ответ 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;});});

Однако это приведет к сбою (т.е. приведет к неправильной ширине бара), когда есть пустые ячейки.

Для справки: