我想制作一个D3图表,它应该如下:
加载html页面时,固定位置会有一个节点。让我们说左上角。我们称之为模板节点,此节点不可移动。
当用户在模板节点上按下鼠标时,会在与模板节点相同的位置创建新节点,并且用户应该能够将新节点拖动到他想要的位置。新节点应该保持用户将其移动到的位置。
用户应该能够随时移动节点。同样,节点应该保留在用户离开的位置。
用户应该能够在任意两个节点之间绘制链接。让我们假设如果他在没有按住ctrl键的情况下从一个节点拖动到另一个节点,则绘制一个链接,如果他在按住控制键的同时拖动,则节点移动。
在两个节点之间绘制链接时,节点不应更改位置。
当链接两个节点并通过拖动移动其中一个节点时,链接应根据需要改变大小和方向。
我正在使用强制布局。
我能够创建一个模板节点,但它总是到达容器的中心 - 我认为这是因为容器的中心是重心。但不确定如何通过代码将其位置固定在左上角。
我可以创建链接和新节点。但是节点移动并且链接调整大小。可能是因为力布局试图使链接长度等于力布局中的链接距离。但我不知道如何使用链接距离函数?我甚至不确定这是否真的有用。
那么我应该使用什么方法?有什么想法吗?
答案 0 :(得分:1)
对于强制布局,您可以将节点的“固定”属性设置为true,以防止它受到模拟的影响。之后,您应该能够手动设置它的位置。您可以选择在函数调用中执行此操作:
function pinNode(node) {
node.fixed = true;
}
function unpinNode(node) {
node.fixed = false;
}
我相信你可以通过这样的调用得到左上角的节点:。只要节点的固定属性设置为true,它就不会受到sim的影响。您可能会发现文档中的这个片段很有用;它描述了force.drag对固定属性的影响:pinNode(node, 0, 0)
将行为绑定到节点以允许交互式拖动,使用 鼠标或触摸。将此与呼叫运算符结合使用 节点;例如,在初始化时说node.call(force.drag)。 拖动事件在鼠标悬停时设置节点的固定属性,例如 只要鼠标在节点上,它就会停止移动。修复 鼠标悬停,而不是mousedown,使捕捉移动更容易 节点。当收到mousedown事件时,以及随后的每个事件 mousemove直到mouseup,节点中心设置为当前鼠标 位置。此外,每个鼠标移动触发力的恢复 布局,重新加热模拟。如果要保留拖动的节点 拖动后固定,在dragstart上将fixed属性设置为true,如 在粘力布局示例中。
如果要使用链接距离函数,请在创建强制布局时包含它:
var force = d3.layout.force()
.size(width, height)
.linkStrength(0.5) // how much can link distance be overridedn by the simulation
.linkDistance(function() {return /* some evaluation */;});
// ...
// You might need to defer the calculation of linkDistance until later,
// such as in update(), since nodes might not have the properties
// that you need to check until that point:
function update() {
force
.nodes(nodes)
.links(links)
.linkDistance(function(link) {
// The function gets called for each link in the simulation.
// Each link will be connected to two nodes, source and target,
// which may be useful in determining link distance.
if (link.source.someProperty || link.target.somePropery) {
return /* something */;
} else {
return /* something else */;
}
});
}