如何用d3表示变量嵌套深度的数组

时间:2016-03-24 13:58:43

标签: javascript jquery html css d3.js

我有一个数组,它是一个数组。数据集具有这种结构。

    [{

    "rowLabel": "Alimentary Sytem",
    "values": [{
        "columnLabel": "Microarray",
        "value": "High"
    }, {
        "columnLabel": "IHC",
        "value": "High"
    }],
    "children": [

        {
            "rowLabel": "Stomach",
            "values": [{
                "columnLabel": "Microarray",
                "value": "Moderate"
            }, {
                "columnLabel": "IHC",
                "value": "Moderate"
            }]
        }, {
            "rowLabel": "Mouth",
            "values": [{
                "columnLabel": "Microarray",
                "value": "High"
            }, {
                "columnLabel": "IHC",
                "value": "High"
            }],
            "children": [{
                    "label": "Tongue",
                    "values": [{
                        "columnLabel": "Microarray",
                        "value": "High"
                    }, {
                        "columnLabel": "IHC",
                        "value": "Negative"
                    }]
                }
            ]
        }
    ]
}, {
    "rowLabel": "Muscle",
    "values": [{
        "columnLabel": "Microarray",
        "value": "Low"
    }, {
        "columnLabel": "IHC",
        "value": "Low"
    }],
    "children":[{
            "rowLabel": "tendon",
            "values": [{
                "columnLabel": "Microarray",
                "value": "Moderate"
            }, {
                "columnLabel": "IHC",
                "value": "Moderate"
            }]
        }]

}]

` 我想用d3以这种格式表示。



<ul>
  <li>Alimentry Canal
    <ul>
      <li>Stomach</li>
      <li>Mouth
      <ul>
        <li>Tongue</li>
      </ul>
      </li>
    </ul>
  </li>
  <li>Muscles</li>
</ul>
&#13;
&#13;
&#13; 我尝试使用d3选择的递归调用来执行此操作,但它一直告诉我找不到groupData并在第一级嵌套结束。

1 个答案:

答案 0 :(得分:0)

我会选择下面的代码段。基本上我们正在做的是:

  1. 展平您的数组并为每个对象添加level属性。
  2. 为所有人创建文字
  3. 根据级别设置缩进
  4. 根据索引垂直放置。
  5. 请注意alignment-base确定文本在该行的位置。

    将其设置为hanging,如果我将y-position设置为0,您将会看到该文字。

    您可以详细了解here,了解它们的外观here

    &#13;
    &#13;
     var tree = [{
    
       "rowLabel": "Alimentary Sytem",
       "values": [{
         "columnLabel": "Microarray",
         "value": "High"
       }, {
         "columnLabel": "IHC",
         "value": "High"
       }],
       "children": [
    
         {
           "rowLabel": "Stomach",
           "values": [{
             "columnLabel": "Microarray",
             "value": "Moderate"
           }, {
             "columnLabel": "IHC",
             "value": "Moderate"
           }]
         }, {
           "rowLabel": "Mouth",
           "values": [{
             "columnLabel": "Microarray",
             "value": "High"
           }, {
             "columnLabel": "IHC",
             "value": "High"
           }],
           "children": [{
             "rowLabel": "Tongue",
             "values": [{
               "columnLabel": "Microarray",
               "value": "High"
             }, {
               "columnLabel": "IHC",
               "value": "Negative"
             }]
           }]
         }
       ]
     }, {
       "rowLabel": "Muscle",
       "values": [{
         "columnLabel": "Microarray",
         "value": "Low"
       }, {
         "columnLabel": "IHC",
         "value": "Low"
       }],
       "children": [{
         "rowLabel": "tendon",
         "values": [{
           "columnLabel": "Microarray",
           "value": "Moderate"
         }, {
           "columnLabel": "IHC",
           "value": "Moderate"
         }]
       }]
    
     }]
    
    
     function flatten(arr, level) {
    
       return arr.reduce(function(flat, toFlatten) {
         toFlatten.level = level;
         var result = flat.concat(toFlatten);
         if (Array.isArray(toFlatten.children)) {
           result = result.concat(flatten(toFlatten.children, level + 1));
         }
         return result;
       }, []);
     }
    
    var flatTree = flatten(tree, 0);
    var indentWidth = 50;
    var lineHeight = 20;
    
    var svg = d3.select('#svg').append('svg').attr("width", 200).attr("height", 500).append('g');
    
    var texts = svg.selectAll("text")
                .data(flatTree)
                .enter()
                .append('text')
                .text(function(d){ 
                  return d.rowLabel; 
                })
                .attr('alignment-baseline', 'hanging')
                .attr('x', function(d){
                   return indentWidth * d.level;
                })
                .attr('y', function(d, i){
                   return lineHeight * i;
                });
    &#13;
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
    
    <div id="svg"></div>
    &#13;
    &#13;
    &#13;

    *更新:* 鉴于OP的最后评论,我认为这是最合适的解决方案:Collapsible Tree