2016-05-26 1 views
1

Я создал схему силы d3, и она работает очень хорошо. Теперь я добавлю группу данных на свой график. Надеюсь, я смогу контролировать центр своих новых узлов. Например, предположим, что центр (100 100), я надеюсь, что новые узлы выстроятся в прямоугольную область, например [(50,50) - (150,150)] в целом.Как управлять координатами узлов d3

detail

var width = 500, 
    height = 500; 

var nodes = [{id:0, n:'Tom'}, {id:1, n:'Join'}, {id:2, n:'John'}, {id:3, n:'Bob'}, {id:4, n:'4'}, {id:5, n:'5'}, {id:6, n:'6'}]; 
var links = [{source:0,target:1},{source:0,target:2},{source:0,target:3},{source:0,target:4},{source:0,target:5},{source:1,target:5},{source:1,target:6}]; 

// init force 
var force = d3.layout.force() 
    .charge(-120) 
    .linkDistance(120) 
    .size([width, height]); 
// init svg 
var svg = d3.select("body").append("svg") 
    .attr("width", width) 
    .attr("height", height); 
// set tick function 
force.on("tick", function() { 
    d3.selectAll(".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; 
    }); 

    // controll the coordinates here 
    d3.selectAll(".node").attr("transform", function(d){ 
      if(d.flag == 1){ 
      d.x = Math.max(50, Math.min(150, d.x)); 
      d.y = Math.max(50, Math.min(150, d.y)); 
     } 
      return "translate("+d.x+","+d.y+")"; 
    }); 



}).on('end', function(){ 
     svg.selectAll(".node").each(function(d){d.fixed=true;}); 
}); 




function setData(ns, ls){ 
    var update = svg.selectAll(".link").data(ls); 
    update.enter().append("line") 
     .attr("class", "link") 
     .style("stroke-width", 1); 
    update.exit().remove(); 

    update = svg.selectAll(".node").data(ns); 
    update.enter().append("g") 
     .attr("class", "node") 
     .attr("id", function(d){return d.id}) 
     .call(force.drag) 
     .call(function(p){ 
      p.append("image") 
       .attr("class", "nodeimage") 
       .attr("width", "30px") 
       .attr("height", "30px") 
       .attr("x", "-15px") 
       .attr("y", "-15px"); 
      p.append("text") 
       .attr("class", "nodetext") 
       .attr("dx", "-10px") 
       .attr("dy", "20px") 
       .style("font-size", "15px") 
       .text(function(d){return d.n}); 
     }); 
    update.exit().remove(); 
    update.selectAll(".nodeimage") 
     .each(function() { 
     d3.select(this).datum(d3.select(this.parentNode).datum()); 
     }) 
       .attr("xlink:href", function(d){ 
       var img; 
      if(d.flag == 1){ 
       img = "http://www.gravatar.com/avatar/1eccef322f0beef11e0e47ed7963189b/?default=&s=80" 
      }else{ 
       img = "http://www.gravatar.com/avatar/a1338368fe0b4f3d301398a79c171987/?default=&s=80"; 
      } 
      return img; 
       }); 
    force.nodes(ns) 
     .links(ls) 
     .start(); 
} 
//init 
setData(nodes, links); 
setTimeout(function(){ 
     //generate new data and merge to old data 
     nodes = nodes.concat(generateNewData()); 
     setData(nodes, links); 
    //how do i control the coordinate of new nodes? 
}, 3000); 


function generateNewData(){ 
     var ns = []; 
     for(var i = 0; i < 10; i++){ 
      ns.push({id:i+100,n:'n'+i,flag:1}); 
    } 
    return ns; 
} 

Вот мой демо jsfiddle: http://jsfiddle.net/cs4xhs7s/4/

Последняя демонстрация показывает, что узлы могут отображаться в прямоугольнике, однако, их координаты совпадают. Надеюсь, что это доступный силовой макет.

+0

Проверить это http://stackoverflow.com/questions/10392505/fix-node-position-in-d3-force-directed-layout – Cyril

+0

Спасибо за вы быстрый ответ, однако, это не я хочу. Мне все еще нужен силовой макет, но я не доволен случайным положением. Я надеюсь, что некоторые узлы будут иметь место в области. Возможно ли это? – Does

+1

ОК, тогда вы можете это проверить http://bl.ocks.org/mbostock/1129492 – Cyril

ответ

0

https://jsfiddle.net/wpnq15mf/1/

var width = 500, 
 
    height = 500; 
 

 
var nodes = [{id:0, n:'Tom'}, {id:1, n:'Join'}, {id:2, n:'John'}, {id:3, n:'Bob'}, {id:4, n:'4'}, {id:5, n:'5'}, {id:6, n:'6'}]; 
 
var links = [{source:0,target:1},{source:0,target:2},{source:0,target:3},{source:0,target:4},{source:0,target:5},{source:1,target:5},{source:1,target:6}]; 
 

 
// init force 
 
var force = d3.layout.force() 
 
    .charge(-500) 
 
    .linkDistance(120) 
 
    .gravity(0.1) 
 
    .size([width, height]); 
 
// init svg 
 
var svg = d3.select("body").append("svg") 
 
    .attr("width", width) 
 
    .attr("height", height); 
 
// set tick function 
 
force.on("tick", function() { 
 
    d3.selectAll(".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; 
 
    }); 
 
\t \t 
 
    // controll the coordinates here 
 
    d3.selectAll(".node").attr("transform", function(d){ 
 
      if(d.flag == 1){ 
 
       d.x = Math.max(50, Math.min(150, d.x)); 
 
       d.y = Math.max(50, Math.min(150, d.y)); 
 
       } 
 
    \t \t return "translate("+d.x+","+d.y+")"; 
 
    }); 
 
    
 
    
 
    
 
}).on('end', function(){ 
 
\t \t svg.selectAll(".node").each(function(d){d.fixed=true;}); 
 
}); 
 

 

 

 

 
function setData(ns, ls){ 
 
    var update = svg.selectAll(".link").data(ls); 
 
    update.enter().append("line") 
 
     .attr("class", "link") 
 
     .style("stroke-width", 1); 
 
    update.exit().remove(); 
 

 
    update = svg.selectAll(".node").data(ns); 
 
    update.enter().append("g") 
 
     .attr("class", "node") 
 
     .attr("id", function(d){return d.id}) 
 
     .call(force.drag) 
 
     .call(function(p){ 
 
      p.append("image") 
 
       .attr("class", "nodeimage") 
 
       .attr("width", "30px") 
 
       .attr("height", "30px") 
 
       .attr("x", "-15px") 
 
       .attr("y", "-15px"); 
 
      p.append("text") 
 
       .attr("class", "nodetext") 
 
       .attr("dx", "-10px") 
 
       .attr("dy", "20px") 
 
       .style("font-size", "15px") 
 
       .text(function(d){return d.n}); 
 
     }); 
 
    update.exit().remove(); 
 
    update.selectAll(".nodeimage") 
 
     .each(function() { 
 
     d3.select(this).datum(d3.select(this.parentNode).datum()); 
 
     }) 
 
       .attr("xlink:href", function(d){ 
 
       \t var img; 
 
      if(d.flagx == 1){ 
 
       img = "http://www.gravatar.com/avatar/1eccef322f0beef11e0e47ed7963189b/?default=&s=80" 
 
      }else{ 
 
       img = "http://www.gravatar.com/avatar/a1338368fe0b4f3d301398a79c171987/?default=&s=80"; 
 
      } 
 
      return img; 
 
       }); 
 
    force.nodes(ns) 
 
     .links(ls) 
 
     .start(); 
 
} 
 
//init 
 
setData(nodes, links); 
 
setTimeout(function(){ 
 
\t \t //generate new data and merge to old data 
 
\t \t nodes = nodes.concat(generateNewData()); 
 
    links = links.concat(generateNewLinks()); 
 
\t \t setData(nodes, links); 
 
    //how do i control the coordinate of new nodes? 
 
}, 3000); 
 

 

 
function generateNewData(){ 
 
\t \t var ns = []; 
 
    ns.push({id:6,n:'n'+i,flag:1, flagx:1}); 
 
\t \t for(var i = 1; i < 10; i++){ 
 
    \t \t \t ns.push({id:i+6,n:'n'+i, flagx:1}); 
 
    } 
 
    return ns; 
 
} 
 

 
function generateNewLinks(){ 
 
\t \t var ns = []; 
 
    \t ns.push({source:7,target:8}); 
 
    ns.push({source:7,target:9}); 
 
    ns.push({source:7,target:10}); 
 
    ns.push({source:7,target:11}); 
 
    ns.push({source:7,target:12}); 
 
    ns.push({source:7,target:13}); 
 
    ns.push({source:7,target:14}); 
 
    ns.push({source:7,target:15}); 
 
    ns.push({source:7,target:16}); 
 
    return ns; 
 
}
.node { 
 
    stroke: #fff; 
 
    stroke-width: 1.5px; 
 
} 
 
.link { 
 
    stroke: #999; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

+0

Спасибо. Кажется, что здесь очень важна ссылка. – Does

+0

@Does Если это решит вашу проблему. Можете ли вы пометить ответ как принятый? –

+0

Aha, i will.However, я обнаружил, что вы управляете центральным узлом в прямоугольнике, но не можете убедиться, что все остальные узлы находятся в прямоугольнике. – Does

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

  • Нет связанных вопросов^_^