javascript - 如何用 d3 表示可变嵌套深度的数组

标签 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>
我尝试使用对 d3 选择的递归调用来执行此操作,但它一直告诉我找不到 groupData 并在嵌套的第一层结束。

最佳答案

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

  1. 展平您的数组并为每个对象添加一个 level 属性。
  2. 为所有这些创建文本
  3. 根据层级设置缩进
  4. 根据索引垂直放置它们。

请注意,alignment-base 确定行中文本的位置。

将其设置为 hanging 后,如果我将 y-position 设置为 0,您将看到文本。

您可以阅读更多相关信息 here你可以了解它们的样子here

 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;
            });
<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>


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

关于javascript - 如何用 d3 表示可变嵌套深度的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36201962/

相关文章:

javascript - 递归 JavaScript 方法范围

javascript - 在 NodeJS 中使用 AWS.DynamoDB.DocumentClient 获取排序键以子字符串开头的 get() 条目的正确语法是什么?

javascript - Angular 2 Observable 服务集成测试

Javascript:如何获取实例化某个对象的类?

主动镜像部分屏幕的 jQuery 和 HTML5 Canvas

javascript - 如果其中的内容被删除,则向 DIV 提供新代码

javascript - 为什么我的所有 DOM 元素属性都返回为空字符串?

javascript - 单击按钮时将值附加到文本框

javascript - 在 Vanilla JS 中使用 ReplaceWith 将一个元素替换为 DOMstring 或多个元素

html - CSS 宽度 100% 无效