2014-02-25 56 views
0

我有一個簡單的「類型」的TSV文件「伯爵」這樣的內容:d3.nest可變孩子深度

type count 
level1/level2/level3/Foo 24 
level1/level2/level3/Bar 2 
level1/level2/Baz 28 
level1/level2/Quz 3 
... 

level字符串可以是任意的字符串,我只是將它們命名爲這樣的在這裏,傳達意義。該類型的最後一個元素Foo,Bar等可以被認爲是數據的葉子。

使用d3,我想把它變成旭日圖。爲此,我使用d3.nest函數來分割斜線的類型。

d3.tsv("data.tsv", function(error, data) { 
    data.forEach(function(d) { 
    d.count = +d.count; 
    }); 

    // define key functions for a depth up to 4 
    var nestedData = d3.nest() 
    .key(function(d) { return level(d.type, 2); }) 
    .key(function(d) { return level(d.type, 3); }) 
    .key(function(d) { return level(d.type, 4); }) 
    .entries(data); 

    // create the key for a specified level 
    function level(type, l) { 
    var parts = type.split("/"); 
    var result = ""; 
    for (i = 0; i < l && i < parts.length; i++) { 
     result += parts[i]; 
     if (i < l-1 && i < parts.length-1) { 
      result += "/"; 
     } 
    } 
    return result; 
    } 
    ... 

的這裏的問題是,所產生的nestedData總是在4的深度,你可以看到示例數據條目/葉子,那葉子可以在任何深度。

我怎樣才能構建嵌套的數據,使條目可以發生在任何深度,不僅在預定義的深度?

回答

0

由於d3.nest使您在撥打nest.entries之前提前註冊嵌套鍵,因此無法通過預先指定所有內容來執行可變數目的嵌套。

可能有用的一件事是遞歸地使用nest.rollup函數來控制每個級別的值是什麼樣子。在rollup的內部,您可以決定每個條目元素是否應該是新的d3.nest,其中包含下一級別的詳細信息,或者它應該是葉節點。

下面是在這一個粗略的裂紋(假定level1將始終存在):

function rollupFn(group) { 
    var leaves = [], 
     groups = []; 

    // Split the items into leaves and groups 
    group.forEach(function(item) { 
     // First eliminate level already accounted for by d3.nest key 
     item.type = item.type.substr(item.type.indexOf('/')+1); 

     if (item.type.indexOf('/') > -1) { 
      groups.push(item); 
     } else { 
      leaves.push(item); 
     } 
    }); 

    // Convert the "group" items into a d3.nest object 
    groups = d3.nest().key(function(d) { 
      return d.type.split('/')[0]; 
     }) 
     .rollup(rollupFn) 
     .entries(groups); 

    var results = []; 
    if (groups.length > 0) { results.push(groups); } 
    if (leaves.length > 0) { results.push(leaves); } 
    return results; 
}; 

var nestedData = d3.nest() 
    .key(function(d) { return "level1" }) // optional: first group contains everything 
    .rollup(rollupFn) 
    .entries(data); 

在每個級別中的值將包含表示所有較低級別,隨後所有的d3.nest對象由一個元件的葉節點。如果沒有其他級別,則values數組將是所有葉節點。

下面是一些工作的代碼,你可以通過步:http://jsfiddle.net/S8aMU/10

+0

我一直沒能得到這個工作。 「rollup」的文檔很少。使用它,葉節點都被添加到嵌套數據的第二層。我認爲這個問題可能是'item.type'被重新分配,從而刪除之間的級別。 –

+0

我應該知道我第一次得到這個權利的機會基本上是零。 :P我創建了一個jsfiddle,所以我可以玩一下,所以現在應該會更好。 –

+0

這個很好用,謝謝!爲了在sunburst圖表中使用,我只更改了它,以便'groups'和'leaves'元素都直接在'results'數組中。 –