[英]D3 force layout graph zoom functionality
我是js的新手,無法解決自己面對的問題,因此,我將很高興為您提供任何建議或幫助。
在我的項目中,我創建了力布局圖。 我應該做的是為圖形添加放大和縮小功能。
我創建了一個小例子來說明我面臨的問題。
function myGraph(el){
this.addNode = function (id, category, opened, parentT, name, nodeType, countLinks, dob, country, childsCount) {
var parent = [];
parent.push(parentT);
nodes.push({ "id": id, "category": category, "opened": opened, "parent": parent, "name": name, "nodeType": nodeType, "countLinks": countLinks, "dob": dob, "country": country, "childCount": childsCount });
update();
}
this.addLink = function (sourceId, targetId, type) {
var sourceNode = findNode(sourceId);
var targetNode = findNode(targetId);
if ((sourceNode !== undefined) && (targetNode !== undefined)) {
links.push({ "source": sourceNode, "target": targetNode, "type": type });
update();
}
}
var findNode = function (id) {
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].id === id)
return nodes[i]
};
}
var w = 360,
h = 200;
var vis = this.vis = d3.select(el).append("svg:svg")
.attr("id", "mySvg")
.attr("width", w)
.attr("height", h)
.attr("viewBox", "0 0 " + w + " " + h)
.call(d3.behavior.zoom().scaleExtent([-0.5, 1]).on("zoom", redraw))
var g = vis.append('svg:g')
function redraw(e) {
if (!e) e = window.event;
if (e.type == "wheel" || e.shiftKey == true) {
g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
}
var force = d3.layout.force()
.gravity(0.05)
.distance(100)
.charge(-200)
.size([w, h]);
var nodes = force.nodes(),
links = force.links();
var hiddenType = [];
g.append("g").attr("class", "links");
g.append("g").attr("class", "nodes");
var update = function () {
for (var i=0; i<links.length; i++) {
if (i != 0 &&
links[i].source == links[i-1].source &&
links[i].target == links[i-1].target) {
links[i].linknum = links[i-1].linknum + 1;
}
else {links[i].linknum = 1;};
};
var myLink = g.select(".links").selectAll(".link");
myLink.remove();
var link = g.select(".links").selectAll(".link")
.data(links);
link.enter().append("polyline")
.attr("class", "link")
.attr("type", function (d) { return "link_" + d.type; })
link.exit().remove();
var node = g.select(".nodes").selectAll(".node")
.data(nodes, function (d) { return d.id; })
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("links", function (d) { return d.countLinks })
.attr("type", function (d) { return d.nodeType })
.on("mousedown", mousedown)
.call(force.drag);
nodeEnter.append("circle")
.attr("r", "10px")
.attr("x", "-8px")
.attr("y", "-8px")
.attr("width", "16px")
.attr("height", "16px")
.style("fill", "white")
.style("stroke", "#ccc")
nodeEnter.append("rect")
.attr("pointer-events", "none")
.attr("class", "shape")
.attr("width", "250px")
.attr("height", "150px")
.style("fill", "transparent")
nodeEnter.append("text")
.attr("pointer-events", "none")
.attr("class", function (d) { return "nodetext_" + d.id })
.attr("y", "-10")
.text(function (d) { return d.id })
nodeEnter.append("title")
.text(function (d) { return d.id });
node.exit().remove();
function mousedown(d) {
d.fixed = true;
}
force.on("tick", function () {
link.attr("points", function(d){
if (d.source.y > d.target.y) {
return d.source.x + "," + d.source.y + " " + (d.source.x + ((d.target.x - d.source.x) / 2)) + "," + (d.target.y + ((d.source.y - d.target.y) / 2) + (15 * (d.linknum - 1))) + " " + d.target.x + "," + d.target.y;
}
if (d.source.y < d.target.y) {
return d.source.x + "," + d.source.y + " " + (d.source.x + ((d.target.x - d.source.x) / 2)) + "," + (d.source.y + ((d.target.y - d.source.y) / 2) + (15 * (d.linknum - 1))) + " " + d.target.x + "," + d.target.y;
}
})
node.attr("transform", function (d) {
if (d.fixed !== true) {
return "translate(" + d.x + "," + d.y + ")";
}
else {
return "translate(" + d.px + "," + d.py + ")";
}
});
});
force.start();
}
update();
}
graph = new myGraph("#graph");
graph.addNode("A")
graph.addNode("B")
graph.addNode("C")
graph.addLink("A", "B")
graph.addLink("A", "C")
https://jsfiddle.net/IMykytiv/nsxL8c52/
所以問題是:
在我的圖中,在該節點的位置固定之后,用戶可以向任意方向拖動節點。 當我添加縮放時,我無法拖動節點,因為縮放首先生效,因此我添加了僅在按下Shift鍵時縮放才起作用的條件。 所以現在我既可以拖動節點也可以縮放。
但是現在我遇到了一個問題,如果我拖動節點並嘗試使用鼠標滾輪進行縮放,則它不是從鼠標位置而是從另一點改變了變換,而我不明白為什么。 如果我刪除了Shift鍵,條件縮放將按預期進行。
我終於找到了解決方案,這非常容易。 我要做的只是在啟動Draggin節點事件時防止觸發縮放功能,而不是在按住Shift鍵的情況下添加條件:
var drag = force.drag()
.on("dragstart", function (d) {
d3.event.sourceEvent.stopPropagation();
});
在這里更新了jsfiddle: https ://jsfiddle.net/IMykytiv/nsxL8c52/2/
希望對任何人都有用:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.