如何正确调整分层数据的大小

时间:2014-08-20 15:49:28

标签: javascript svg d3.js

我一直在努力学习d3.js项目。我想要显示的数据格式为:

var data = [{
    "name": "parent",
        "top": ["t1", "t2"],
        "bottom": [{
        "upper": "u1",
            "lower": "l1"
    }, {
        "upper": "u2",
            "lower": "l2"
    }]
}];

任意长的数组。我想像这样显示数据:

 -----------------
| name 
|      -----------
|     | t1  
|     |-----------
|     | t2
|     |-----------
|     | u1
|     |-----------
|     | u2
|      -----------
 -----------------
       -----------
      | l2      
      |-----------
      | l1
       -----------

我需要尽可能紧密地打包这些数据。还要注意我需要" l"元素颠倒了。所以我的问题是:

  1. 我应该如何定位" u"直接位于" t"元素?
  2. 如何根据" t"确定父母周围的盒子大小?和"你"元素?
  3. 我应该如何定位" l"直接位于父框下方的元素,顺序相反吗?
  4. 以下是一个工作示例http://jsfiddle.net/p3wg0L8v/

    如果您无法访问jsfiddle,则重新发布代码:

    var data = [{
        "name": "parent",
            "top": ["t1", "t2"],
            "bottom": [{
            "upper": "u1",
                "lower": "l1"
        }, {
            "upper": "u2",
                "lower": "l2"
        }]
    }];
    
    var textSpacing = 16;
    
    var svg = d3.select("body").append("svg").attr("width", 480).attr("height", 160);
    
    var parents = svg.selectAll("g").data(data).enter();
    
    var parent = parents.append("g");
    
    parent.append("text").text(function (d) {
        return d.name;
    }).attr("x", textSpacing).attr("y", textSpacing);
    
    parent.append("rect").attr("x", 0).attr("y", 0).attr("width", 400).attr("height", 90).attr("fill", "none").attr("stroke", "black").attr("stroke-width", 1);
    
    var top = parent.selectAll("text.top").data(function (d) {
        return d.top;
    }).enter().append("text").attr("class", "top").attr("x", 60).attr("y", function (d, i) {
        return textSpacing * (i + 2);
    }).text(function (d) {
        return d;
    });
    
    var bottom = parent.selectAll("g").data(function (d) {
        return d.bottom
    }).enter().append("g");
    
    bottom.append("text").attr("x", 60).attr("y", function (d, i) {
        return textSpacing * (i + 4);
    }).text(function (d) {
        return d.upper;
    });
    
    bottom.append("text").attr("x", 60).attr("y", function (d, i) {
        return textSpacing * (8 - i);
    }).text(function (d) {
        return d.lower;
    });
    

    现在我基本上是硬编码数组的长度,但我需要能够处理各种大小,因为会有很多" parent"对象。

1 个答案:

答案 0 :(得分:0)

您可以计算bottomtop数组的大小,并将它们一起添加,以获得每个parent对象的总大小。

将每个父对象的大小添加到一起将为data中的所有对象提供总大小。然后,您可以使用该大小为所有内容指定总大小。

编辑: 要定位所有内容,一旦您拥有每个底部,顶部和父级的大小,就可以使用g属性定位父transform个元素:

.attr('transform',function(d){
    return 'translate(' + xPosition + ',' + yPosition + ')'
});

然后将底部和顶部定位为相对于父项的g元素,再次使用transform属性来定位相对于其父项的每个底部或顶部。 (设置第一个元素等于x属性,第二个元素等于0表示顶部,相应顶部的高度表示底部)

最后,当你将鞋面和底部附加到底部时,你可以将它们分成两组,设置一个transform以将所有底部向下移动所有鞋面的高度,最后定位text元素仅基于它们在数组最低级别中的位置,因为您transform已放置在父级,底部和上级的g元素上(g或者文本节点的祖先是什么)将决定它在层次结构中的位置。

本质上,使用y元素上的变换来构建层次结构的大块的位置,然后仅使用{{1}}属性来定位元素相对于层次结构中的兄弟节点。