Узлы D3 не отображают тип формы

Я работаю над принудительным макетом d3.js,

Я определил узлы и связи. Но у узлов есть параметры, которые относятся к типу прямоугольника и круга. Итак, я хочу прочитать данные узла и соответственно нарисовать их. Когда я проверяю DOM, я вижу элементы круга и прямоугольника, но они не отображаются на экране. Ссылки для узлов показаны.

Я использую Chrome на компьютере с Windows 10.

Предоставление ссылки jsbin для справки. Динамическое создание типа формы узлов на основе данных

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

<style>

  .node {
    fill: #ccc;
    stroke: #fff;
    stroke-width: 2px;
  }

  .link {
    stroke: #777;
    stroke-width: 2px;
  }

</style>
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js">
</script>
</head>
<body>

<script type="text/javascript">

    var width = 600,
      height = 500;

  var graph = {
"nodes": [  { "x": 80, "y": 20, "height": 30, "width": 30, "color" : "blue" },
            { "x": 595.98896,  "y":  56.377057 },
            { "x": 319.568434, "y": 278.523637 },
            { "x": 214.494264, "y": 214.893585 },
            { "x": 130, "y": 20, "height": 30, "width": 30, "color" : "red" },
            { "x":  84.078465, "y": 192.021902 },
            { "x": 196.952261, "y": 370.798667 },
            { "x": 107.358165, "y": 435.15643  }

        ],
"links": [  { "target": 0, "source":  1 },
            { "target":  0, "source":  2 },
            { "target": 0, "source":  3 },
            { "target":  4, "source":  0},
            { "target": 6, "source":  4 },
            { "target": 7, "source":  4 },
            { "target": 5, "source":  4 }
        ]
};

  var nodes = graph.nodes,
   links = graph.links;

  var svg = d3.select('body').append('svg')
  .attr('width', width)
  .attr('height', height);

  var force = d3.layout.force()
  .size([width, height])
  .nodes(nodes)
  .links(links);

  force.linkDistance(width/2);

  var link = svg.selectAll('.link')
  .data(links)
  .enter().append('line')
  .attr('class', 'link');

  // Each node is drawn as a circle or rect based on the data.

  var node = svg.selectAll('.node')
  .data(nodes)
  .enter()
  .append(function(d,i){
    if(d.height){
      //debugger;
      return document.createElement("rect");
    }
    else
      return document.createElement("circle");
   })
  .attr('class', 'node');


  force.on('end', function() { 

     var circles = svg.selectAll('circle');
    //console.log(circles);
    var circleAttributes = circles
    .attr("cx", function (d) { return d.x; })
    .attr("cy", function (d) { return d.y; })
    .attr("r", function (d) { return 12; });

    var rectangles = svg.selectAll('rect');
    //console.log(rectangles);
    var rectangleAttributes = rectangles
    .attr("x", function (d) { return d.x; })
    .attr("y", function (d) { return d.y; })
    .attr("height", function (d) { return d.height; })
    .attr("width", function (d) { return d.width; })
    .style("fill", function(d) { return d.color; });

    link.attr('x1', function(d) { return d.source.x; })
      .attr('y1', function(d) { return d.source.y; })
      .attr('x2', function(d) { return d.target.x; })
      .attr('y2', function(d) { return d.target.y; });

  });
  force.start();

</script>


person nilesh    schedule 10.03.2017    source источник


Ответы (1)


Я считаю, что вы не можете append условно, как в вашем примере, создавая элементы. (По крайней мере, я не нашел такого примера)

Простым, но, вероятно, не элегантным решением было бы что-то вроде этого (jsbin) :

// create a group element to hold the data
var node = svg.append('g')
               .selectAll('.node')
               .data(nodes)
               .enter()
               .append('g')

// filter the rectangles and the circles
var rects = node.filter(function(d){ return d.height!=undefined;}) // or simply return d.height 
var circles = node.filter(function(d){ return d.height==undefined;}) // and return !d.height

// append circle or rect on the filtered values and go on from that
circles.append('circle')
       .attr('class', 'node');

rects.append('rect')
     .attr('class', 'node');

Надеюсь это поможет! Удачи!

person mkaran    schedule 10.03.2017
comment
Спасибо mkaran, ваш подход сработал, но мы можем условно создавать элементы, просто для справки, проверьте ссылку jsbin Динамическое создание типа формы узлов на основе данных - person nilesh; 14.03.2017
comment
@nilesh хорошо, я пока не сталкивался с таким подходом, приятно знать! - person mkaran; 14.03.2017