2017-02-15 10 views
0

Я создал пять узлов, использующих d3.js, и сделаю ссылки друг на друга, чтобы сделать многоугольник, но они не являются смежным положением, чтобы сделать многоугольник, вместо этого он создает случайный вид, отличный от polygon.Am Я пропустил что-то здесь, пожалуйста, взгляните и предложите мне.как рисовать многоугольник от d3.js

var width = 300, 
 
    height = 300 
 

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

 

 
var force = d3.layout.force() 
 
    .gravity(1) 
 
    .linkDistance(200) 
 
    .charge(-100) 
 
    .size([width, height]); 
 

 

 
var datajson = { 
 
    "nodes": [{ 
 
    "name": "a", 
 
    "group": 2 
 
    }, { 
 
    "name": "b", 
 
    "group": 1 
 
    }, { 
 
    "name": "c", 
 
    "group": 1 
 
    }, { 
 
    "name": "d", 
 
    "group": 2 
 
    }, { 
 
    "name": "e", 
 
    "group": 2 
 
    }], 
 
    "links": [{ 
 
    "source": 0, 
 
    "target": 1, 
 
    "value": 1, 
 
    "distance": 90 
 
    }, { 
 
    "source": 1, 
 
    "target": 2, 
 
    "value": 2, 
 
    "distance": 90 
 
    }, { 
 
    "source": 2, 
 
    "target": 3, 
 
    "value": 3, 
 
    "distance": 90 
 
    }, { 
 
    "source": 3, 
 
    "target": 4, 
 
    "value": 5, 
 
    "distance": 90 
 
    }, { 
 
    "source": 4, 
 
    "target": 0, 
 
    "value": 5, 
 
    "distance": 90 
 
    }] 
 
} 
 

 

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

 

 
var drag = force.drag() 
 
    .on("dragstart", dblclick); 
 

 

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

 
var node = svg.selectAll(".node") 
 
    .data(datajson.nodes) 
 
    .enter().append("g") 
 
    .attr("class", "node") 
 
    .call(force.drag); 
 

 
node.append("image") 
 
    .attr("x", -8) 
 
    .attr("y", -8) 
 
    .attr("width", 45) 
 
    .attr("height", 45) 
 
    .attr("xlink:href", function(d) { 
 
    var rnd = Math.floor(Math.random() * 64 + 1); 
 

 

 
    return null; 
 
    }); 
 

 
node.append("text") 
 
    .attr("dx", 12) 
 
    .attr("dy", ".35em") 
 
    .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("transform", function(d) { 
 
    return "translate(" + d.x + "," + d.y + ")"; 
 
    }); 
 
}); 
 

 
function dblclick(d) { 
 

 

 
    d3.select(this).classed("fixed", d.px = d.x, d.py = d.y); 
 
    console.log(d); 
 
}
.link { 
 
    stroke: #dfdfdf; 
 
} 
 
.node text { 
 
    pointer-events: none; 
 
    font: 10px sans-serif; 
 
} 
 
.link.red { 
 
    stroke: blue; 
 
}
<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 

 
<body> 
 
    <script src="http://d3js.org/d3.v3.min.js"></script> 
 
</body>

+1

Вы используете неправильный инструмент для выполнения этой задачи, но один раствор уменьшения заряда: https://jsfiddle.net/gerardofurtado/b10q68fo/ –

+0

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

ответ

0

Когда вы звоните

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

d3 случайным образом выбирает стартовые позиции для узлов, так как они еще не имеют x и y свойства присвоенного.

Однако, прежде чем вызывать код выше, вы можете перебрать каждый узел и назначить ему x и y из углов многоугольника, и они должны поддерживать эти отношения. Они могут не подпрыгивать много, хотя, потому что они уже были в своем намеренном положении. В этом случае вы можете слегка изменить свое положение относительно их конечной предполагаемой позиции, добавив некоторые случайные смещения x и y к стартовым значениям.

Рабочий пример

код, который препозициями узлы является

var numNodes = datajson.nodes.length 
var r = 20; 
datajson.nodes.forEach(function(node, i) { 
    node.x = width/2 + r * Math.sin(2 * Math.PI * i/numNodes) 
    node.y = height/2 + r * Math.cos(2 * Math.PI * i/numNodes) 
    console.log(node) 
}) 

Я также должен был настроить заряд (-1000) и linkDistance (100), чтобы заставить его работать.


var width = 300, 
 
    height = 300 
 

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

 

 
var force = d3.layout.force() 
 
    .gravity(.5) 
 
    .linkDistance(100) 
 
    .charge(-1000) 
 
    .size([width, height]); 
 

 

 
var datajson = { 
 
    "nodes": [{ 
 
    "name": "a", 
 
    "group": 2 
 
    }, { 
 
    "name": "b", 
 
    "group": 1 
 
    }, { 
 
    "name": "c", 
 
    "group": 1 
 
    }, { 
 
    "name": "d", 
 
    "group": 2 
 
    }, { 
 
    "name": "e", 
 
    "group": 2 
 
    }], 
 
    "links": [{ 
 
    "source": 0, 
 
    "target": 1, 
 
    "value": 1, 
 
    "distance": 90 
 
    }, { 
 
    "source": 1, 
 
    "target": 2, 
 
    "value": 2, 
 
    "distance": 90 
 
    }, { 
 
    "source": 2, 
 
    "target": 3, 
 
    "value": 3, 
 
    "distance": 90 
 
    }, { 
 
    "source": 3, 
 
    "target": 4, 
 
    "value": 5, 
 
    "distance": 90 
 
    }, { 
 
    "source": 4, 
 
    "target": 0, 
 
    "value": 5, 
 
    "distance": 90 
 
    }] 
 
} 
 

 
var numNodes = datajson.nodes.length 
 
var r = 20; 
 
datajson.nodes.forEach(function(node, i) { 
 
    node.x = width/2 + r * Math.sin(2 * Math.PI * i/numNodes) 
 
    node.y = height/2 + r * Math.cos(2 * Math.PI * i/numNodes) 
 
    console.log(node) 
 
}) 
 

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

 

 
var drag = force.drag() 
 
    .on("dragstart", dblclick); 
 

 

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

 
var node = svg.selectAll(".node") 
 
    .data(datajson.nodes) 
 
    .enter().append("g") 
 
    .attr("class", "node") 
 
    .call(force.drag); 
 

 
node.append("image") 
 
    .attr("x", -8) 
 
    .attr("y", -8) 
 
    .attr("width", 45) 
 
    .attr("height", 45) 
 
    .attr("xlink:href", function(d) { 
 
    var rnd = Math.floor(Math.random() * 64 + 1); 
 

 

 
    return null; 
 
    }); 
 

 
node.append("text") 
 
    .attr("dx", 12) 
 
    .attr("dy", ".35em") 
 
    .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("transform", function(d) { 
 
    return "translate(" + d.x + "," + d.y + ")"; 
 
    }); 
 
}); 
 

 
function dblclick(d) { 
 

 

 
    d3.select(this).classed("fixed", d.px = d.x, d.py = d.y); 
 
    console.log(d); 
 
}
.link { 
 
    stroke: #dfdfdf; 
 
} 
 
.node text { 
 
    pointer-events: none; 
 
    font: 10px sans-serif; 
 
} 
 
.link.red { 
 
    stroke: blue; 
 
}
<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 

 
<body> 
 
    <script src="http://d3js.org/d3.v3.min.js"></script> 
 
</body>

+0

Да, узлы не будут отскакивать, если эти узлы расположены первоначально с фиксированными x, y. как это http://stackoverflow.com/questions/40146952/force-layout-set-fixed-distance-each-nodes-even-after-draging/40150750#40150750 – Subrata

+0

@ Субрата Я добавил рабочий пример – meetamit