2015-07-01 10 views
5

Tôi có biểu đồ mạng trong vis.js với nhiều nút. Khi chọn một nhóm nhất định, tôi muốn xoay và thu phóng biểu đồ để tất cả các nút của nhóm đó vừa với màn hình.vis.js - phù hợp với một tập các nút trên màn hình

Tôi đang duyệt qua từng nút trong biểu đồ và tính toán một hộp giới hạn cho tất cả các nút mà tôi quan tâm, sau đó tôi sử dụng phương thức moveTo để di chuyển và chia tỷ lệ đồ thị thành tâm của hộp giới hạn đó. Mã giả:

var allNodes = data.nodes.get({ 
    returnType: "Object" 
}); 
var bounds; 
for (n in allNodes) { 
    if (matchesCondition(allNodes[n])) { 
     bounds = extendBounds(bounds, graph.getBoundingBox(allNodes[n]));     
    } 
} 
var newViewport = { 
    position: { 
     x: (bounds.x1+bounds.x2)/2; 
     y: (bounds.y1+bounds.y2)/2; 
    }, 
    // What is the visible width, where do I get it from? 
    scale: Math.min(???/(bounds.x2-bounds.x1), ???/(bounds.y2-bounds.y1)) 
} 
graph.moveTo(newViewport); 

Câu hỏi: làm cách nào để tính tỷ lệ, tức là tôi phải thay thế cái gì ??? với trong mã giả ở trên?

Trả lời

7

Dữ liệu mẫu từ Vis.js groups example.

Để lắp khung nhìn, bạn có thể chỉ cần sử dụng phương thức gốc .fit(). Vì the documentation không cung cấp liên kết có thể bắt đầu bằng #, đây là mô tả API:

Thu nhỏ sao cho tất cả các nút vừa với khung vẽ. Bạn có thể cung cấp tùy chọn để tùy chỉnh này:

{ 
    nodes:[Array of nodeIds], 
    animation: { //can be a boolean too 
    duration: Number 
    easingFunction: String 
    } 
} 

Các nút có thể được sử dụng để phóng to để phù hợp với các nút chỉ cụ thể trong giao diện.

Với điều này trong tâm trí, tất cả những gì chúng ta cần làm là nhận tất cả các nút trong một nhóm nhất định. Đáng ngạc nhiên, API của người sử dụng đất dường như không cung cấp một phương thức cho điều này (?), Do đó, một phương pháp lọc nhỏ là cần thiết.

//TODO: Is there no user-land API for this? 
 
var getGroup = function getGroup(nodeId) { 
 
    var nodesHandler = network.nodesHandler; 
 
    var innerNodes = nodesHandler.body.nodes; 
 
    //Lazily assume ids match indices 
 
    var node = innerNodes[nodeId]; 
 
    return node.options.group; 
 
}; 
 

 
var getGroupNodes = function getGroupNodes(group) { 
 
    // http://elijahmanor.com/reducing-filter-and-map-down-to-reduce/ 
 
    var filtered = nodes.reduce(function(output, node) { 
 
    if (node.group === group) { 
 
     output.push(node.id); 
 
    } 
 
    return output; 
 
    }, []); 
 
    return filtered; 
 
}; 
 

 
//START Vis.js group example 
 

 
var color = 'gray'; 
 
var len = undefined; 
 

 
var nodes = [{ 
 
    id: 0, 
 
    label: "0", 
 
    group: 0 
 
}, { 
 
    id: 1, 
 
    label: "1", 
 
    group: 0 
 
}, { 
 
    id: 2, 
 
    label: "2", 
 
    group: 0 
 
}, { 
 
    id: 3, 
 
    label: "3", 
 
    group: 1 
 
}, { 
 
    id: 4, 
 
    label: "4", 
 
    group: 1 
 
}, { 
 
    id: 5, 
 
    label: "5", 
 
    group: 1 
 
}, { 
 
    id: 6, 
 
    label: "6", 
 
    group: 2 
 
}, { 
 
    id: 7, 
 
    label: "7", 
 
    group: 2 
 
}, { 
 
    id: 8, 
 
    label: "8", 
 
    group: 2 
 
}, { 
 
    id: 9, 
 
    label: "9", 
 
    group: 3 
 
}, { 
 
    id: 10, 
 
    label: "10", 
 
    group: 3 
 
}, { 
 
    id: 11, 
 
    label: "11", 
 
    group: 3 
 
}, { 
 
    id: 12, 
 
    label: "12", 
 
    group: 4 
 
}, { 
 
    id: 13, 
 
    label: "13", 
 
    group: 4 
 
}, { 
 
    id: 14, 
 
    label: "14", 
 
    group: 4 
 
}, { 
 
    id: 15, 
 
    label: "15", 
 
    group: 5 
 
}, { 
 
    id: 16, 
 
    label: "16", 
 
    group: 5 
 
}, { 
 
    id: 17, 
 
    label: "17", 
 
    group: 5 
 
}, { 
 
    id: 18, 
 
    label: "18", 
 
    group: 6 
 
}, { 
 
    id: 19, 
 
    label: "19", 
 
    group: 6 
 
}, { 
 
    id: 20, 
 
    label: "20", 
 
    group: 6 
 
}, { 
 
    id: 21, 
 
    label: "21", 
 
    group: 7 
 
}, { 
 
    id: 22, 
 
    label: "22", 
 
    group: 7 
 
}, { 
 
    id: 23, 
 
    label: "23", 
 
    group: 7 
 
}, { 
 
    id: 24, 
 
    label: "24", 
 
    group: 8 
 
}, { 
 
    id: 25, 
 
    label: "25", 
 
    group: 8 
 
}, { 
 
    id: 26, 
 
    label: "26", 
 
    group: 8 
 
}, { 
 
    id: 27, 
 
    label: "27", 
 
    group: 9 
 
}, { 
 
    id: 28, 
 
    label: "28", 
 
    group: 9 
 
}, { 
 
    id: 29, 
 
    label: "29", 
 
    group: 9 
 
}]; 
 
var edges = [{ 
 
    from: 1, 
 
    to: 0 
 
}, { 
 
    from: 2, 
 
    to: 0 
 
}, { 
 
    from: 4, 
 
    to: 3 
 
}, { 
 
    from: 5, 
 
    to: 4 
 
}, { 
 
    from: 4, 
 
    to: 0 
 
}, { 
 
    from: 7, 
 
    to: 6 
 
}, { 
 
    from: 8, 
 
    to: 7 
 
}, { 
 
    from: 7, 
 
    to: 0 
 
}, { 
 
    from: 10, 
 
    to: 9 
 
}, { 
 
    from: 11, 
 
    to: 10 
 
}, { 
 
    from: 10, 
 
    to: 4 
 
}, { 
 
    from: 13, 
 
    to: 12 
 
}, { 
 
    from: 14, 
 
    to: 13 
 
}, { 
 
    from: 13, 
 
    to: 0 
 
}, { 
 
    from: 16, 
 
    to: 15 
 
}, { 
 
    from: 17, 
 
    to: 15 
 
}, { 
 
    from: 15, 
 
    to: 10 
 
}, { 
 
    from: 19, 
 
    to: 18 
 
}, { 
 
    from: 20, 
 
    to: 19 
 
}, { 
 
    from: 19, 
 
    to: 4 
 
}, { 
 
    from: 22, 
 
    to: 21 
 
}, { 
 
    from: 23, 
 
    to: 22 
 
}, { 
 
    from: 22, 
 
    to: 13 
 
}, { 
 
    from: 25, 
 
    to: 24 
 
}, { 
 
    from: 26, 
 
    to: 25 
 
}, { 
 
    from: 25, 
 
    to: 7 
 
}, { 
 
    from: 28, 
 
    to: 27 
 
}, { 
 
    from: 29, 
 
    to: 28 
 
}, { 
 
    from: 28, 
 
    to: 0 
 
}]; 
 

 
// create a network 
 
var container = document.getElementById('mynetwork'); 
 
var data = { 
 
    nodes: nodes, 
 
    edges: edges 
 
}; 
 
var options = { 
 
    nodes: { 
 
    shape: 'dot', 
 
    size: 30, 
 
    font: { 
 
     size: 32, 
 
     color: '#ffffff' 
 
    }, 
 
    borderWidth: 2 
 
    }, 
 
    edges: { 
 
    width: 2 
 
    } 
 
}; 
 
network = new vis.Network(container, data, options); 
 

 
//END Vis.js group example 
 

 
network.on("click", function(e) { 
 
    //Zoom only on single node clicks, zoom out otherwise 
 
    if (e.nodes.length !== 1) { 
 
    network.fit(); 
 
    return; 
 
    } 
 
    var nodeId = e.nodes[0]; 
 
    //Find out what group the node belongs to 
 
    var group = getGroup(nodeId); 
 
    //TODO: How do you want to handle ungrouped nodes? 
 
    if (group === undefined) return; 
 
    var groupNodes = getGroupNodes(group); 
 
    network.fit({ 
 
    nodes: groupNodes 
 
    }); 
 
});
html, 
 
body, 
 
#mynetwork { 
 
    width: 100%; 
 
    height: 100%; 
 
    margin: 0; 
 
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/vis/4.3.0/vis.min.js"></script> 
 
<div id="mynetwork"></div>

+0

Cảm ơn, tôi phải đọc cẩn thận hơn các tài liệu của 'phương pháp fit' ;-) –

Các vấn đề liên quan