2016-12-09 33 views
0

我有幾個節點(例如應用程序名稱)和一些帶標籤的邊(例如信息流/系統接口及其信息對象)。我希望能夠以自由重疊的方式編寫一個javascript腳本,以此繪製節點網格(例如信息流圖),這意味着:算法以重疊自由的方式呈現節點網格

  • 邊緣的標籤不會被節點和/或彼此
  • 節點不是由邊緣線和/或邊緣的標籤和/或彼此

另外節點需要被放置的方式,儘可能多的邊緣線儘可能的是可見的和重疊不要混淆彼此 - 所以需要進行某種優化。 需求也是任何節點都可能連接到任何其他節點。

爲了做到這一點,我正在尋找關於如何做到這一點(高級僞代碼)或者準備好的JavaScript實現的粗略想法。

我不喜歡下面的,因爲我知道如何工作的:

  • 配售/移動的div
  • 繪製SVG線
  • 任何形式的訓練數據轉換工作或數據資產必須如何(向量,矩陣,稀疏矩陣...)

我已經開始喜歡的東西:

  1. 把節點只有一個邊緣到畫布
  2. 與之相連接的接近他們

這樣,我想有一個樹放節點的外部空間,我可以輕鬆地來回價差我的畫布。最初的想法是從那裏做一些排序和分組。然而,我很難將子樹從網格結構中分組出來,並且以某種方式陷入了困境。

我也在想碰撞檢測可能對我有幫助。然而,我沒有明確指出如何能夠幫助我放置節點,以便邊緣在可見方面是最佳的。

爲了讓這個更可見這裏是輸入數據結構的樣子:

var nodeseq=[ // id,name 
 
{id:'i1',name:'app1'}, 
 
{id:'i2',name:'app2'}; 
 
... 
 
]; 
 

 
var edgeseq=[ // id,sourcenodeid,targetnodeid,label 
 
{id:'i1',sourcenodeid:'i33',targetnodeid:'i25',label:'Invoice'}, 
 
{id:'i2',sourcenodeid:'i3',targetnodeid:'i5',label:'Advise'}, 
 
... 
 
];

回答

1

或可選地準備到去JavaScript實現

Springy.js可能適合您的需求...自從我上次使用它以來已經有一段時間了,但它已經它是一個非常直接的API,因此可能值得嘗試。一個例子:

var nodeseq = [ // id,name 
 
    {id:'i1',name:'app1'}, 
 
    {id:'i2',name:'app2'}, 
 
    {id:'i3',name:'app3'}, 
 
    {id:'i4',name:'app4'}, 
 
]; 
 

 
var edgeseq = [ // id,sourcenodeid,targetnodeid,label 
 
    {id:'i1',sourcenodeid:'i1',targetnodeid:'i2',label:'Invoice'}, 
 
    {id:'i2',sourcenodeid:'i1',targetnodeid:'i3',label:'Advise'}, 
 
    {id:'i3',sourcenodeid:'i3',targetnodeid:'i3',label:'Test'}, 
 
    {id:'i4',sourcenodeid:'i3',targetnodeid:'i4',label:'Test'}, 
 
    {id:'i5',sourcenodeid:'i2',targetnodeid:'i3',label:'Test'}, 
 
]; 
 

 
var graph = new Springy.Graph(); 
 
var createNode = node => graph.newNode({label: node.name }); 
 

 
var nodeMap = makeMap("id", nodeseq, createNode); 
 

 
// connect them with an edge 
 
edgeseq.forEach(edge => graph.newEdge(
 
    nodeMap[edge.sourcenodeid], 
 
    nodeMap[edge.targetnodeid], 
 
    { label: edge.label } 
 
)); 
 

 
$('canvas').springy({ graph: graph }); 
 

 
// Utils 
 
function makeMap(prop, arr, t) { 
 
    t = t || (v => v); 
 
    return arr 
 
    .reduce((map, item) => Object.assign(map, { 
 
      [item[prop]] : t(item) 
 
     }), {}); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/springy/2.7.1/springyui.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/springy/2.7.1/springy.min.js"></script> 
 
<canvas width="400" height="200" />

+0

哇。是否有可能將標籤貼到邊緣? – Quicker

+1

當然,'newEdge'方法有第三個參數,允許您指定屬性。我在我的答案中編輯了這個例子。我們現在通過'label'屬性來標記箭頭。 – user3297291