2016-10-30 6 views
1

Я делаю d3-направленный граф, и он работает нормально (this is the working version on codepen), пока я не попытаюсь добавить метки для узлов.D3 force direction graph issue: узлы укладываются в координаты (0,0)

Насколько я понимаю, узел должен быть обернут элементом 'g', но когда я его попробую, все узлы укладываются в верхний левый угол. Я очень незнакомый с JavaScript, и, очевидно, я что-то пропустил. Буду признателен, если кто-нибудь поможет мне исправить мою ошибку.
Я попытался решением от подобной темы: labels wont show up on d3 force diagram

var dataURL = "https://raw.githubusercontent.com/Aeternia-ua/temp1/c50fa778c12c6d355fe08b54cb3f1ce24acfa4e9/graphtest.json"; 

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

var color = d3.scaleOrdinal(d3.schemeCategory20c); 

var simulation = d3.forceSimulation() 
    .force("link", d3.forceLink().id(function(d) { 
     return d.id; 
    })) 
    .force("charge", d3.forceManyBody().strength(-150)) 
    .force("center", d3.forceCenter(width/2, height/2)); 

d3.json(dataURL, function(error, graph) { 
    if (error) throw error; 

    simulation.nodes(graph.nodes); 
    simulation.force("link").links(graph.links); 

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

    var node = svg.append("g") 
     .attr("class", "nodes") 
     .selectAll("circle") 
     .data(graph.nodes) 
     .enter().append("circle") 

    //Setting node radius by group value. If 'group' key doesn't exist, set radius to 8 
    .attr("r", function(d) { 
      if (d.hasOwnProperty('group')) { 
       return d.group * 2; 
      } else { 
       return 9; 
      } 
     }) 
     //Colors by 'group' value 
     .style("fill", function(d) { 
      return color(d.group); 
     }) 
     .call(d3.drag() 
      .on("start", dragstarted) 
      .on("drag", dragged) 
      .on("end", dragended)); 

    node.append("svg:title") 
     .attr("dx", 12) 
     .attr("dy", ".35em") 
     .text(function(d) { 
      return d.id 
     }); 

    var labels = svg.append("g") 
     .attr("class", "label") 
     .selectAll("text") 
     .data(graph.nodes) 
     .enter().append("text") 
     .attr("dx", 6) 
     .attr("dy", ".35em") 
     .style("font-size", 10) 
     .text(function(d) { 
      return d.id 
     }); 


    simulation 
     .nodes(graph.nodes) 
     .on("tick", ticked); 

    simulation.force("link") 
     .links(graph.links); 
}); 

function ticked() { 

    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("cx", function(d) { 
      return d.x; 
     }) 
     .attr("cy", function(d) { 
      return d.y; 
     }); 

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

function dragstarted(d) { 
    if (!d3.event.active) simulation.alphaTarget(0.3).restart(); 
    d.fx = d.x; 
    d.fy = d.y; 
} 

function dragged(d) { 
    d.fx = d3.event.x; 
    d.fy = d3.event.y; 
} 

function dragended(d) { 
    if (!d3.event.active) simulation.alphaTarget(0); 
    d.fx = null; 
    d.fy = null; 
} 

Full code on codepen

ответ

2

Переместить функцию ticked() внутрь вашего d3.json обратного вызова:

d3.json(dataURL, function(error, graph) { 
    //... 
    function ticked(){ 
     //... 
    }; 
}; 

Кроме того, изменить класс ссылок от .links к .link:

var link = svg.append("g") 
    .attr("class", "link") 

Вот ваш обновленный CodePen: http://codepen.io/anon/pen/ORejme?editors=0110

+0

Он работает, спасибо! – Aeternia

2

link, node и labels определены локально анонимной функции в d3.json() вызова и поэтому не доступны из ticked().