首页 > 解决方案 > 如何使用 dc.js 绘制表格列的箱线图

问题描述

我有一张如下表:

桌子

实验次数是任意的,但列名的前缀是“client_”,后跟客户编号。

我想使用 dc.js 针对“client_#”绘制值的箱线图。该表是使用 d3.csv() 加载的 csv 文件。

有使用普通组的示例,但是我需要将每列显示为自己的箱线图,并且没有一个示例这样做。如何从每一列创建箱线图?

标签: boxplotdc.js

解决方案


This is very similar to this question:

dc.js - how to create a row chart from multiple columns

Many of the same caveats apply - it will not be possible to filter (brush) using this chart, since every row contributes to every box plot.

The difference is that we will need all the individual values, not just the sum total.

I didn't have an example to test with, but hopefully this code will work:

function column_values(dim, cols) {
  var _groupAll = dim.groupAll().reduce(
    function(p, v) { // add
      cols.forEach(function(c) {
        p[c].splice(d3.bisectLeft(p[c], v[c]), 0, v[c]);
      });
      return p;
    },
    function(p, v) { // remove
      cols.forEach(function(c) {
        p[c].splice(d3.bisectLeft(p[c], v[c]), 1);
      });
      return p;
    },
    function() { // init
      var p = {};
      cols.forEach(function(c) {
        p[c] = [];
      });
      return p;
    });
  return {
    all: function() {
      // or _.pairs, anything to turn the object into an array
      return d3.map(_groupAll.value()).entries();
    }
  };
}

As with the row chart question, we'll need to group all the data in one bin using groupAll - ordinary crossfilter bins won't work since every row contributes to every bin.

The init function creates an object which will be keyed by column name. Each entry is an array of the values in that column.

The add function goes through all the columns and inserts each column's value into each array in sorted order.

The remove function finds the value using binary search and removes it.

When .all() is called, the {key,value} pairs will be built from the object.

The column_values function takes either a dimension or a crossfilter object for the first parameter, and an array of column names for the second parameter. It returns a fake group with a bin for each client, where the key is the client name and the value is all of the values for that client in sorted order.

You can use column_values like this:

var boxplotColumnsGroup = column_values(cf, ['client_1', 'client_2', 'client_3', 'client_4']);
boxPlot
  .dimension({}) // no valid dimension as explained in earlier question
  .group(boxplotColumnsGroup);

If this does not work, please attach an example so we can debug this together.


推荐阅读