如何用d3.js透视表?

kjo*_*kjo 5 pivot-table d3.js

考虑以下表格数据(仅作为示例):

A,B,C,D,x,y,z
a0,b0,c0,d0,0.007,0.710,0.990
a0,b0,c0,d1,0.283,0.040,1.027
a0,b0,c1,d0,0.017,0.688,2.840
a0,b0,c1,d1,0.167,0.132,2.471
a0,b1,c0,d0,0.041,0.851,1.078
a0,b1,c0,d1,0.235,1.027,1.027
a0,b1,c1,d0,0.037,0.934,2.282
a0,b1,c1,d1,0.023,1.049,2.826
a1,b0,c0,d0,0.912,0.425,1.055
a1,b0,c0,d1,0.329,0.932,0.836
a1,b0,c1,d0,0.481,0.681,0.997
a1,b0,c1,d1,0.782,0.595,2.294
a1,b1,c0,d0,0.264,0.918,0.857
a1,b1,c0,d1,0.053,1.001,0.920
a1,b1,c1,d0,1.161,1.090,1.470
a1,b1,c1,d1,0.130,0.992,2.121
Run Code Online (Sandbox Code Playgroud)

请注意,对于不同的列值的每个组合A,B,CD发生在这个表一次.因此,可以将这个列的子集视为"键列",将其余列视为"值列".

假设这个数据在某个文件中data.csv,并且我们将这个文件读d3.csv入回调参数中data,如下所示:

d3.csv('data.csv', function (error, data) {
    ...
});
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种方便的d3.js操作来进行转换,data以便使C列"旋转".我的意思是,转化的表的"值"列是那些由"交叉"的所述的值而获得C与原来的"值"列,列x,yz.换句话说,在csv格式中,转换后的表格如下所示:

A,B,D,x_c0,x_c1,y_c0,y_c1,z_c0,z_c1
a0,b0,d0,0.007,0.017,0.710,0.688,0.990,2.840
a0,b0,d1,0.283,0.167,0.040,0.132,1.027,2.471
a0,b1,d0,0.041,0.037,0.851,0.934,1.078,2.282
a0,b1,d1,0.235,0.023,1.027,1.049,1.027,2.826
a1,b0,d0,0.912,0.481,0.425,0.681,1.055,0.997
a1,b0,d1,0.329,0.782,0.932,0.595,0.836,2.294
a1,b1,d0,0.264,1.161,0.918,1.090,0.857,1.470
a1,b1,d1,0.053,0.130,1.001,0.992,0.920,2.121
Run Code Online (Sandbox Code Playgroud)

如果没有简单的方法可以做到这一点,一个更简单(但仍然有用)的变体是在首先丢弃除"一个"值之外的所有列之后进行类似的转换.例如,在丢弃xy列后,旋转C列将产生(以csv格式):

A,B,D,c0,c1
a0,b0,d0,0.990,2.840
a0,b0,d1,1.027,2.471
a0,b1,d0,1.078,2.282
a0,b1,d1,1.027,2.826
a1,b0,d0,1.055,0.997
a1,b0,d1,0.836,2.294
a1,b1,d0,0.857,1.470
a1,b1,d1,0.920,2.121
Run Code Online (Sandbox Code Playgroud)

的简化在于,现在的原始值列(z)可以通过一组(该值命名的列简单地更换c0,并c1在这种情况下)在被枢柱(C).

mus*_*_ut 7

您正在寻找d3.nest:

d3.csv('data.csv', function (data) {
  var nester = d3.nest()
    .key(function (d) { return d.A; })
    .key(function (d) { return d.B; })
    .key(function (d) { return d.D; })
    .rollup(function (values) {
       var sortedValues = values.sort(function (x, y) { 
        return x.C < y.C ? -1 : x.C > y.C ? 1 : 0; 
       });
       var mkKey = function (c, name, v) {
         return {
           name: 'C_' + c + '_' + name,
           value: v
         };
       }

       var pivotedX = sortedValues.map(function (d) { return mkKey(d.C, 'x', d.x); }),
           pivotedY = sortedValues.map(function (d) { return mkKey(d.C, 'y', d.y); }),
           pivotedZ = sortedValues.map(function (d) { return mkKey(d.C, 'z', d.z); });

       return Array.prototype.concat.apply([], [pivotedX, pivotedY, pivotedZ]);
    });

  var nestedData = nester.entries(data);
  var pivotedData = [];

  nestedData.forEach(function (kv1) {
    var a = kv1.key;
    kv1.values.forEach(function (kv2) {
      var b = kv2.key;
      kv2.values.forEach(function (kv3) {
        var d = kv3.key;
        var obj = {
          A: a,
          B: b,
          D: d
        };

        kv3.values.forEach(function (d){
          obj[d.name] = d.value;
        })
        pivotedData.push(obj);
      })
    })
  })  
  console.log(JSON.stringify(pivotedData, null, '  '));
});
Run Code Online (Sandbox Code Playgroud)

结果nestedData将是以下形式:

[
  {
    "A": "a0",
    "B": "b0",
    "D": "d0",
    "C_c0_x": "0.007",
    "C_c1_x": "0.017",
    "C_c0_y": "0.710",
    "C_c1_y": "0.688",
    "C_c0_z": "0.990",
    "C_c1_z": "2.840"
  },
  ...,
  {
    "A": "a1",
    "B": "b1",
    "D": "d1",
    "C_c0_x": "0.053",
    "C_c1_x": "0.130",
    "C_c0_y": "1.001",
    "C_c1_y": "0.992",
    "C_c0_z": "0.920",
    "C_c1_z": "2.121"
  }
]
Run Code Online (Sandbox Code Playgroud)

Demo看看script.js和输出console.

  • @musically_ut,看来您的示例链接无效。 (2认同)