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"> |