【问题标题】:Properly display bin width in barChart using dc.js and crossfilter.js使用 dc.js 和 crossfilter.js 在 barChart 中正确显示 bin 宽度
【发布时间】:2013-02-17 22:23:44
【问题描述】:

我正在使用基于 d3 和 crossfilter 的 Dimensional Charting javascript 库 dc.js 制作条形图。

我想要做的就是显示一个带有指定数量的 bin 的直方图,这应该很容易使用 barChart 函数。

我有一个名为 data 的数组,其中包含 0 到 90000 之间的浮点值,我只想使用具有 10 个 bin 的直方图来显示分布。

我使用以下代码生成下面的直方图:

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

这看起来不太对劲:每个酒吧都非常瘦!我想要一个看起来很正常的直方图,其中的条很粗并且几乎相互接触,每个条之间可能有几个像素的填充。知道我做错了什么吗?

【问题讨论】:

    标签: javascript d3.js crossfilter dc.js


    【解决方案1】:

    dc.js 中的条形图使用xUnits function 根据您的 x 轴范围自动计算直方图中条形的宽度。如果要将宽度设置为静态值,可以使用自定义 xUnits 函数,例如:

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

    这应该会给你一个更合适的宽度。

    【讨论】:

      【解决方案2】:

      suggestion given by user2129903 使用chart.xUnits() 指定自定义xUnits 函数确实是要走的路。 我想添加一个示例和一些解释,以选择该自定义函数的返回值。

      文档说:

      这个函数预计会返回一个包含所有 x 轴上的数据点,或轴上的点数。

      也就是说,假设您要制作直方图,您可以直接指定 bin 的数量,也可以根据所需的 bin 大小计算它并从该函数返回。当分组的数字键不是连续的等距整数时,您需要指定此项。

      这是一个例子:

      <!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>
      

      请注意,在此示例中,它还可以从组对象本身检索 bin 的数量或 bin 的键值,例如,像这样

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

      但是,当有空箱时,这将失败(即,产生错误的条宽)。

      供参考:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-12-20
        • 2016-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-15
        • 1970-01-01
        相关资源
        最近更新 更多