2015-05-29 1 views
1

Я пытаюсь изменить пример Майка Force-Directed Graph, чтобы использовать прямоугольники вместо кругов в качестве узлов. Кроме того, я хочу текст внутри прямоугольника.График сети D3.js с использованием форсированного макета и прямоугольников для узлов

У меня есть прямоугольники, отображающие текст правильно, однако они не привязаны к ссылкам, и они не двигаются.

Вот codepen ссылка: http://codepen.io/anon/pen/gpgWaz

var width = 960, 
    height = 500; 

var color = d3.scale.category20(); 

var force = d3.layout.force() 
    .charge(-120) 
    .linkDistance(30) 
    .size([width, height]); 

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

force 
    .nodes(graph.nodes) 
    .links(graph.links) 
    .start(); 

var link = svg.selectAll(".link") 
    .data(graph.links) 
    .enter().append("line") 
    .attr("class", "link") 
    .style("stroke-width", function(d) { 
     return Math.sqrt(d.value); 
    }); 

var node = svg.selectAll(".node") 
    .data(graph.nodes) 
    .enter() 
    .append("g") 
    .attr("transform", function(d) { 
     return "translate(" + d.x + "," + d.y + ")"; 
    }) 
    .call(force.drag); 

node.append("rect") 
    .attr("class", "node") 
    .attr("width", 100) 
    .attr("height", 35) 
    .style("fill", function(d) { 
     return color(d.group); 
    }) 
    .style("stroke", "black") 
    .style("stroke-width", "1px"); 

node.append("text") 
    .text(function(d) { 
     return d.name; 
    }) 
    .style("font-size", "12px") 
    .attr("dy", "1em"); 

node.append("title") 
    .text(function(d) { 
     return d.name; 
    }); 

force.on("tick", function() { 
    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; 
     }); 

    node.attr("x", function(d) { 
      return d.x; 
     }) 
     .attr("y", function(d) { 
      return d.y; 
     }); 
}); 

Update

Благодаря Lars «s комментарий, и его codepen он работает сейчас.

Обновление, которое я сделал мой код:

  1. Добавить преобразование иллюстрируется Lars
  2. Изменены ссылки для подключения в центре прямоугольников
  3. Добавлено закругленные углы, чтобы прямоугольники
  4. Дал тексту небольшое margin indentation
  5. Изменено на использование ширина/высота окна

Вот мои новые codepen: http://codepen.io/anon/pen/bdgREd

var width = window.innerWidth, 
    height = window.innerHeight, 
    nodeWidth = 100, 
    nodeHeight = 35; 

var color = d3.scale.category20(); 

var force = d3.layout.force() 
    .charge(-1500) 
    .linkDistance(100) 
    .friction(0.5) 
    .size([width, height]); 

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

force 
    .nodes(graph.nodes) 
    .links(graph.links) 
    .start(); 

var link = svg.selectAll(".link") 
    .data(graph.links) 
    .enter().append("line") 
    .attr("class", "link") 
    .style("stroke-width", function(d) { 
     return Math.sqrt(d.value); 
    }); 

var node = svg.selectAll(".node") 
    .data(graph.nodes) 
    .enter() 
    .append("g") 
    .attr("transform", function(d) { 
     return "translate(" + d.x + "," + d.y + ")"; 
    }) 
    .call(force.drag); 

node.append("rect") 
    .attr("class", "node") 
    .attr("width", nodeWidth) 
    .attr("height", nodeHeight) 
    .attr("rx", 5) 
    .attr("ry", 5) 
    .style("fill", function(d) { 
     return color(d.group); 
    }) 
    .style("stroke", "black") 
    .style("stroke-width", "1px"); 

node.append("text") 
    .attr("x", 5) 
    .attr("y", 2) 
    .text(function(d) { 
     return d.name; 
    }) 
    .style("font-size", "12px") 
    .attr("dy", "1em"); 

node.append("title") 
    .text(function(d) { 
     return d.name; 
    }); 

force.on("tick", function() { 
    link.attr("x1", function(d) { 
      return d.source.x + (nodeWidth/2); 
     }) 
     .attr("y1", function(d) { 
      return d.source.y + (nodeHeight/2); 
     }) 
     .attr("x2", function(d) { 
      return d.target.x + (nodeWidth/2); 
     }) 
     .attr("y2", function(d) { 
      return d.target.y + (nodeHeight/2); 
     }); 

    node.attr("transform", function(d) { 
      return "translate(" + d.x + "," + d.y + ")"; 
     }); 
}); 
+1

Вам нужно установить атрибут 'transform', как вы делаете, когда добавляете прямоугольники: http://codepen.io/anon/pen/YXNVNY –

+0

Это сделало это. Если вы опубликуете это как ответ, я приму это. Благодаря! –

ответ

1

Вы установки x и y атрибуты в g элементов, чтобы изменить свои позиции, - это ничего не делать. Вам нужно установить атрибут transform, как и при добавлении элементов g. Так что ваша tick функция обработчика будет содержать

node.attr("transform", function(d) { 
    return "translate(" + d.x + "," + d.y + ")"; 
}); 

вместо

node.attr("x", function(d) { 
     return d.x; 
    }) 
    .attr("y", function(d) { 
     return d.y; 
    }); 

Полная демо here.

Смежные вопросы