Javascript 如何在Konva实现部队布局网络?

Javascript 如何在Konva实现部队布局网络?,javascript,force-layout,konvajs,Javascript,Force Layout,Konvajs,如何在Konva.js中实现部队布局网络 下面是一个例子: Konva没有内置的物理引擎。因此,您必须使用模拟所需物理的外部代码。例如,对于这种情况,您可以使用d3 var w = window.innerWidth; var h = window.innerHeight; var dataset = { nodes:[ {name:"Adam"}, {name:"Bob"}, {name:"Carrie"}, {name:"Donovan"}, {

如何在Konva.js中实现部队布局网络

下面是一个例子:


Konva没有内置的物理引擎。因此,您必须使用模拟所需物理的外部代码。例如,对于这种情况,您可以使用
d3

var w = window.innerWidth;
var h = window.innerHeight;

var dataset = {
  nodes:[
    {name:"Adam"},
    {name:"Bob"},
    {name:"Carrie"},
    {name:"Donovan"},
    {name:"Edward"},
    {name:"Felicity"},
    {name:"George"},
    {name:"Hannah"},
    {name:"Iris"},
    {name:"Jerry"}
  ],
  edges:[
    {source: 0, target: 1},
    {source: 0, target: 2},
    {source: 0, target: 3},
    {source: 0, target: 4},
    {source: 1, target: 5},
    {source: 2, target: 5},
    {source: 2, target: 5},
    {source: 3, target: 4},
    {source: 5, target: 8},
    {source: 5, target: 9},
    {source: 6, target: 7},
    {source: 7, target: 8},
    {source: 8, target: 9},

  ]
};

var force = d3.layout.force()
.nodes(dataset.nodes)
.links(dataset.edges)
.size([w, h])
.linkDistance([100])
.charge([-150])
.start();





const stage = new Konva.Stage({
  container: 'container',
  width: window.innerWidth,
  height: window.innerHeight
});

const layer = new Konva.Layer();
stage.add(layer);


dataset.edges.forEach((edge, i) => {
  const line = new Konva.Line({
    points: [],
    stroke: 'black',
    name: 'edge-' + i
  });
  layer.add(line);
})

dataset.nodes.forEach((n, i) => {
  const circle = new Konva.Circle({
    radius: 30,
    fill: Konva.Util.getRandomColor(),
    name: 'node-' + i,
    draggable: true
  });
  circle.on('dragmove', () => {
    n.x = circle.x(),
    n.y = circle.y();
  })
  circle.on('dragmove', () => {
    force.resume();
  })
  layer.add(circle);
})



force.on("tick", function(){
  dataset.nodes.forEach((node, i) => {
    const circle = layer.findOne('.node-' + i);
    circle.x(node.x);
    circle.y(node.y);
  });
  dataset.edges.forEach((edge, i) => {
    const { target, source } = edge;
    const line = layer.findOne('.edge-' + i);
    line.points([target.x, target.y, source.x, source.y]);
  });
  layer.draw();
});

演示:

Konva没有内置的物理引擎。因此,您必须使用模拟所需物理的外部代码。例如,对于这种情况,您可以使用
d3

var w = window.innerWidth;
var h = window.innerHeight;

var dataset = {
  nodes:[
    {name:"Adam"},
    {name:"Bob"},
    {name:"Carrie"},
    {name:"Donovan"},
    {name:"Edward"},
    {name:"Felicity"},
    {name:"George"},
    {name:"Hannah"},
    {name:"Iris"},
    {name:"Jerry"}
  ],
  edges:[
    {source: 0, target: 1},
    {source: 0, target: 2},
    {source: 0, target: 3},
    {source: 0, target: 4},
    {source: 1, target: 5},
    {source: 2, target: 5},
    {source: 2, target: 5},
    {source: 3, target: 4},
    {source: 5, target: 8},
    {source: 5, target: 9},
    {source: 6, target: 7},
    {source: 7, target: 8},
    {source: 8, target: 9},

  ]
};

var force = d3.layout.force()
.nodes(dataset.nodes)
.links(dataset.edges)
.size([w, h])
.linkDistance([100])
.charge([-150])
.start();





const stage = new Konva.Stage({
  container: 'container',
  width: window.innerWidth,
  height: window.innerHeight
});

const layer = new Konva.Layer();
stage.add(layer);


dataset.edges.forEach((edge, i) => {
  const line = new Konva.Line({
    points: [],
    stroke: 'black',
    name: 'edge-' + i
  });
  layer.add(line);
})

dataset.nodes.forEach((n, i) => {
  const circle = new Konva.Circle({
    radius: 30,
    fill: Konva.Util.getRandomColor(),
    name: 'node-' + i,
    draggable: true
  });
  circle.on('dragmove', () => {
    n.x = circle.x(),
    n.y = circle.y();
  })
  circle.on('dragmove', () => {
    force.resume();
  })
  layer.add(circle);
})



force.on("tick", function(){
  dataset.nodes.forEach((node, i) => {
    const circle = layer.findOne('.node-' + i);
    circle.x(node.x);
    circle.y(node.y);
  });
  dataset.edges.forEach((edge, i) => {
    const { target, source } = edge;
    const line = layer.findOne('.edge-' + i);
    line.points([target.x, target.y, source.x, source.y]);
  });
  layer.draw();
});

演示:

当我移动一个节点并按住它时,它会抖动/抖动一点,过一段时间它就会自行实现?@MartinS可能需要一些修复来更好地集成d3引擎。好的,有什么特别的问题吗?@MartinS可能需要从Konva拖放到d3 force引擎中获得更多反馈。就像在
dragstart
上告诉d3,我的力量不应该移动节点。当我移动节点并握住它时,它会抖动/摇晃一点,过了一段时间它会自行实现?@MartinS可能需要一些修复来更好地集成d3引擎。好的,有什么特别的问题吗?@MartinS可能需要Konva drag&drop向d3 force引擎提供更多反馈。类似于
dragstart
告诉d3不应在我的力下移动节点。