2013-11-03 23 views
6

Hãy xem xét các dữ liệu sau bảng (chỉ là ví dụ):Làm cách nào để xoay bảng với 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 

Lưu ý rằng mỗi sự kết hợp của các giá trị khác biệt cho cột A, B, C, và D xảy ra đúng một lần trong bảng này. Do đó, người ta có thể nghĩ về tập hợp con cột này là "cột khóa" và các cột còn lại là "cột giá trị".

Hãy nói rằng dữ liệu này là trong một số tập tin data.csv, và rằng chúng ta đọc tập tin này với d3.csv, vào lập luận callback data, như vậy:

d3.csv('data.csv', function (error, data) { 
    ... 
}); 

Tôi đang tìm kiếm một d3.js thao tác thuận tiện để chuyển đổi data để cột C được "xoay vòng". Bằng cách này, tôi có nghĩa là các cột "giá trị" của bảng được chuyển đổi là các cột thu được bằng cách "vượt qua" các giá trị của cột C với cột "giá trị" ban đầu, x, yz. Nói cách khác, ở định dạng csv, bảng chuyển đổi sẽ trông như thế này:

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 

Trong trường hợp không có cách nào dễ dàng để làm được điều này, một biến thể đơn giản hơn (nhưng vẫn hữu ích) sẽ làm một sự thay đổi tương tự sau khi lần đầu tiên loại bỏ tất cả trừ một cột "giá trị". Ví dụ, sau khi loại bỏ các cột xy, xoay vòng cột C sẽ tạo ra (ở định dạng 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 

Việc đơn giản hóa nằm ở chỗ nay là cột giá trị ban đầu (z) có thể được chỉ đơn giản là thay thế bằng một bộ các cột được đặt tên theo các giá trị (c0c1 trong trường hợp này) trong cột được xoay vòng (C).

Trả lời

8

Bạn đang tìm kiếm 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, ' ')); 
}); 

Kết quả trong nestedData sẽ có dạng sau:

[ 
    { 
    "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" 
    } 
] 

Demo Nhìn vào script.js và đầu ra trên console.

+0

xin lỗi, phải có một sự hiểu lầm ở đâu đó, bởi vì điều này thậm chí còn không gần với những gì tôi đang tìm kiếm ... – kjo

+0

Lời xin lỗi của tôi. Sai lầm đã được nhìn thấy hình thức chính xác mà bạn cần dữ liệu, tôi đã giả định rằng bạn chỉ muốn một 'GROUP BY' trên cột' C'. Tôi đã cập nhật câu trả lời với giải pháp chính xác: http://plnkr.co/edit/Pr1Fnak6y3suSaY4j9pt?p=preview –

+0

+1 rất tuyệt! cảm ơn! – kjo