关于 javascript:是否可以将 D3.tree() 与包含父母而不是孩子的数据集一起使用?

Is it possible to use D3.tree() with a dataset that includes parents instead of children?

我正在使用 D3 创建家谱。我的数据集确实是分层的,但树的根节点是子节点。每个"子节点"包含两个"父节点"节点,代表每个子节点的两个父节点。这是我的数据示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    {
    name:"Morgans Jumpin Jack Flash",
    imagePath:"",
    description:"",
    subTitle:"",
    body:"",
    icon:"",
    iconColor:"",
    gender:"m",
    parents: [
        {
            name:"Moganas Heart of Fire",
            imagePath:"",
            description:"",
            subTitle:"",
            body:"",
            icon:"",
            iconColor:"",
            gender:"f",
            parents: [
                {
                    name:"Elkhaus Ice Storm",
                    imagePath:"",
                    description:"",
                    subTitle:"",
                    body:"",
                    icon:"",
                    iconColor:"",
                    gender:"m",
                    parents: []
                },{
                    name:"Morganas First Love",
                    imagePath:"",
                    description:"",
                    subTitle:"",
                    body:"",
                    icon:"",
                    iconColor:"",
                    gender:"f",
                    parents: []
                },
            ]
        },{
            name:"Desperado Hogan von der Accani",
            imagePath:"",
            description:"",
            subTitle:"",
            body:"",
            icon:"",
            iconColor:"",
            gender:"m",
            parents: [
                {
                    name:"Jim von Aurachgrund",
                    imagePath:"",
                    description:"",
                    subTitle:"",
                    body:"",
                    icon:"",
                    iconColor:"",
                    gender:"m",
                    parents: []
                },{
                    name:"Heroina D. Altobella",
                    imagePath:"",
                    description:"",
                    subTitle:"",
                    body:"",
                    icon:"",
                    iconColor:"",
                    gender:"f",
                    parents: []
                },
            ]
        },
    ]
}

树中的每个节点代表一只狗。这里的想法是,您可以通过向父母、祖父母等的家谱上溯到给定的 Dogs 谱系。

是否可以在不修改数据的情况下将给定的数据集与 d3.tree() 一起使用? (我知道我可能只是将 "parents" 重命名为 "children",但这会让下一个查看数据集的人感到非常困惑。)


您不需要更改原始数据集,而是在使用 d3.hierarchy 创建根时,您可以指定哪个属性包含 "children":

1
2
3
var root = d3.hierarchy(data, function(d) {
   return d.parents;  
})

第二个参数是"child"访问器,但是你可以用它来表示父母。我只是保留了从左到右的布局,但是将其更改为从右到左的布局相当简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
var data = {
    name:"Morgans Jumpin Jack Flash",
    imagePath:"",
    description:"",
    subTitle:"",
    body:"",
    icon:"",
    iconColor:"",
    gender:"m",
    parents: [
        {
            name:"Moganas Heart of Fire",
            imagePath:"",
            description:"",
            subTitle:"",
            body:"",
            icon:"",
            iconColor:"",
            gender:"f",
            parents: [
                {
                    name:"Elkhaus Ice Storm",
                    imagePath:"",
                    description:"",
                    subTitle:"",
                    body:"",
                    icon:"",
                    iconColor:"",
                    gender:"m",
                    parents: []
                },{
                    name:"Morganas First Love",
                    imagePath:"",
                    description:"",
                    subTitle:"",
                    body:"",
                    icon:"",
                    iconColor:"",
                    gender:"f",
                    parents: []
                },
            ]
        },{
            name:"Desperado Hogan von der Accani",
            imagePath:"",
            description:"",
            subTitle:"",
            body:"",
            icon:"",
            iconColor:"",
            gender:"m",
            parents: [
                {
                    name:"Jim von Aurachgrund",
                    imagePath:"",
                    description:"",
                    subTitle:"",
                    body:"",
                    icon:"",
                    iconColor:"",
                    gender:"m",
                    parents: []
                },{
                    name:"Heroina D. Altobella",
                    imagePath:"",
                    description:"",
                    subTitle:"",
                    body:"",
                    icon:"",
                    iconColor:"",
                    gender:"f",
                    parents: []
                },
            ]
        },
    ]
}

var root = d3.hierarchy(data, function(d) {
  return d.parents;
})



var width =500;
var height = 300;
var margin = {left:100,top:50,right:100,bottom:50};

var svg = d3.select("body")
  .append("svg")
  .attr("width",width)
  .attr("height",height)
var g = svg.append("g")
  .attr("transform","translate("+margin.left+","+margin.top+")");



var tree = d3.tree().size([height-margin.top-margin.bottom,width-margin.left-margin.right]);
var path = d3.linkHorizontal().x(function(d) { return d.y; }).y(function(d) { return d.x; })
var layout = tree(root);

var link = g.selectAll(null)
  .data(layout.links())
  .enter().append("path")
  .attr("class","link")
  .attr("d", path)

var text = g.selectAll(null)
  .data(root.descendants())
  .enter().append("text")
  .attr("transform", function(d) { return"translate(" + d.y +"," + d.x +")"; })
.text(function(d) { return d.data.name; })
  .attr("y",-15)
  .attr("x",-10)

var node = g.selectAll(null)
  .data(root.descendants())
  .enter().append("circle")
  .attr("transform", function(d) { return"translate(" + d.y +"," + d.x +")"; })
  .attr("class","node")
  .attr("r",function(d) { return d.data.name =="" ? 0 : 8; });
1
2
3
4
5
path {
  fill:none;
  stroke: #888;
  stroke-width: 2px;
 }
1
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js">