我的问题如下:虽然我为我的节点设置了fixed : true
,但只修复了第一个(从json文件加载)。新的(由用户创建)不固定,即使使用浏览器的开发人员工具,我们也可以看到fixed="true"
属性。 redraw()
函数中缺少哪些内容?我应该使用tick()
吗?我正在为这个问题奋斗一个星期,我不知道了。
这是我的整个代码(初始节点确实是固定的),但我也建议jsfiddle(初始节点也不固定)。
// Plan
var width = 960,
height = 500;
// Orange selected element
var selected_node = null,
selected_link = null;
// Element we clicked on it
var mouseclick_node = null,
mouseclick_link = null;
// To detect click or double click.
var clickedOnce = false,
timer;
// Useful function to compute the size of an element.
d3.selection.prototype.size = function() {
var n = 0;
this.each(function() { ++n; });
return n;
};
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.attr("pointer-events", "all");
var visual = svg
.append('svg:g')
.append('svg:g')
.on("mousemove", mousemove)
.on("click", click);
// ajoute une balise rect nested dans g, ave préfix svg
visual.append('svg:rect')
.attr('width', width)
.attr('height', height)
.attr('fill', 'white');
var force = d3.layout.force()
.size([width, height])
.charge(-400)
.on("tick", tick);
// Future link
var drag_line = visual.append("line")
.attr("class", "drag_line")
.attr("x1", 0)
.attr("y1", 0)
.attr("x2", 0)
.attr("y2", 0);
// get layout properties
var nodes = force.nodes(),
links = force.links();
var node = visual.selectAll(".node"),
link = visual.selectAll(".link");
// Allows the drag actions
var drag = force.drag();
// Read the json file and creates the links and the nodes
d3.json("graph_empty.json", function(error, graph) {
if (error) console.log("error: " + error);
nodes = graph.nodes;
links = graph.links;
// To redraw after loading nodes and links
redraw();
});
// Add properties to links and nodes
function tick() {
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;
});
}
function mousemove() {
var point = d3.mouse(this), p = {x: point[0], y: point[1]};
if (selected_node) {
drag_line
.attr("x1", selected_node.x)
.attr("y1", selected_node.y)
.attr("x2", p.x)
.attr("y2", p.y);
}
}
function click() {
var point = d3.mouse(this), p = {x: point[0], y: point[1]};
// if already clicked once
if (clickedOnce) {
run_on_double_click();
}
// otherwise
else {
timer = setTimeout(function() {
run_on_simple_click(point);
}, 150);
clickedOnce = true;
}
}
function run_on_simple_click(p) {
console.log("[run_on_simple_click]");
clickedOnce = false;
if (!mouseclick_node && selected_node) {
// add a new node
point = {x: p[0], y: p[1]};
nodes.push(point);
// add link to mousedown node
links.push({source: selected_node, target: point});
// select the new node
selected_node = point;
selected_link = null;
// update the drag line
drag_line
.attr("x1", selected_node.x)
.attr("y1", selected_node.y)
.attr("x2", p.x)
.attr("y2", p.y);
redraw();
}
}
function run_on_double_click() {
clickedOnce = false;
clearTimeout(timer);
console.log("[run_on_double_click]");
}
function resetMouseVars() {
console.log("[resetMouseVars]");
mouseclick_node = null;
mouseclick_link = null;
}
function redraw() {
console.log("[redraw start]");
force
.nodes(nodes)
.links(links)
link = link.data(links);
link.enter().append("line")
.attr("class", "link")
.on("click", function(d) {
// double click:
if (clickedOnce_On) {
clickedOnce_On = false;
clearTimeout(timer);
mouseclick_link = d;
if (!selected_link)
selected_link = mouseclick_link;
else if (mouseclick_link == selected_link)
selected_link = null;
else if (mouseclick_link == selected_link) {
selected_link = null;
selected_link = mouseclick_link;
}
selected_node = null;
resetMouseVars();
redraw();
}
// single click:
else {
timer = setTimeout(function() {
// to do... create a new node between !
}, 250);
clickedOnce_On = true;
}
});
link.exit().remove();
link.classed("link_selected", function(d) {
return d === selected_link;
});
node = node.data(nodes);
var clickedOnce_On = false;
node.enter().append("circle")
.attr("class", "node")
.attr("r", 6)
.attr("fixed", true)
.call(drag)
.on("click", function(d) {
mouseclick_node = d;
// double click:
if (clickedOnce_On) {
clickedOnce_On = false;
clearTimeout(timer);
if (!selected_node)
selected_node = mouseclick_node;
else if (mouseclick_node == selected_node)
selected_node = null;
else if (mouseclick_node == selected_node) {
selected_node = null;
selected_node = mouseclick_node;
}
selected_link = null;
resetMouseVars();
redraw();
}
// single click:
else {
timer = setTimeout(function() {
// close the surface if
if ((selected_node) && (mouseclick_node) && (selected_node != mouseclick_node)) {
console.log("mouseclick_node: "+ mouseclick_node);
// Here: count the number of links for each node
// and find the node with only one link.
// If this node == mouseclick_node,
// we add a new link between it and the selected_node.
resetMouseVars();
redraw();
}
}, 250);
clickedOnce_On = true;
}
});
node.exit().transition()
.attr("r", 0)
.remove();
node.classed("node_selected", function(d) {
return d === selected_node;
});
force
.start()
.tick();
console.log("[redraw end]");
}
非常感谢您提出任何建议/意见/解决方案!
答案 0 :(得分:0)
最后我找到了一个解决方案:我像这样设置force
的属性:
var force = d3.layout.force()
.size([width, height])
.charge(0)
.gravity(0)
.linkStrength(0)
.friction(0)
.on("tick", tick);
这样,除非我拖动它们,否则我的所有固定节点都不会移动。