Можно ли использовать D3.tree () с набором данных, который включает родителей вместо детей? - PullRequest
2 голосов
/ 01 мая 2020

Я нахожусь в процессе создания генеалогического дерева, используя D3. Мой набор данных действительно иерархический, но узел дерева root является дочерним. Каждый «дочерний узел» содержит два «родительских» узла, которые представляют каждого дочернего узла двумя родителями. Вот пример моих данных.

    {
    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: []
                },
            ]
        },
    ]
}

Каждый узел в дереве представляет Собаку. Идея в том, что вы можете увидеть данную родословную Собак, поднявшись по генеалогическому древу до родителей, бабушек и дедушек и т. Д. c.

Можно ли использовать данный набор данных с помощью d3.tree ()? без изменения данных? (Я знаю, что, возможно, я мог бы просто переименовать «родителей» в «детей», но это было бы НЕВЕРОЯТНО путать со следующим человеком, который смотрит на набор данных.)

1 Ответ

2 голосов
/ 01 мая 2020

Вам не нужно изменять исходный набор данных, вместо этого, когда вы создаете root с помощью d3.hierarchy, вы можете указать, какое свойство содержит «children»:

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

Второй параметр: «дочерний» аксессор, но вы можете использовать его для представления родителей. Я только что сохранил расположение слева направо, но было бы довольно тривиально изменить его расположение справа налево:

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; });
path {
  fill:none;
  stroke: #888;
  stroke-width: 2px;
 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
...