我正在使用vis.js在网页上创建网络图。
我需要将操纵的图形以JSON格式存储到数据库,从网络图中导出json。
我没有找到任何关于它的文档,是否可以将带有操纵数据的vis.js网络导出(以JSON或可转换为JSON的形式)?
答案 0 :(得分:0)
根据Visjs文档,您可能需要的方法是 storePositions()
这是功能描述:
使用vis.DataSet将节点加载到网络中时,此方法会将所有节点的X和Y位置放入该数据集中。如果您从数据库加载节点并使其与DataSet动态耦合,您可以使用它来稳定您的网络一次,然后通过DataSet保存该数据库中的位置,以便下次加载节点时,稳定将接近瞬间。
如果节点仍在移动,并且您正在使用动态平滑边缘 (默认情况下已启用),您可以使用该选项 物理模块中的stabilization.onlyDynamicEdges改进 初始化时间。
此方法不支持群集。目前,在使用群集时无法缓存位置,因为无法从位置正确初始化位置。
答案 1 :(得分:0)
对于数据,这是我提取数据进行存储的方法(我将尝试切断与该问题无关的代码位):
// get nodes and edges
var nodes = network.body.data.nodes._data; // contains id, label, x,y, custom per-node options and doesn't contain options from options.nodes; presumably contains option values set when network was created, not current ones (it is so for x,y)
// network.body.nodes[id].nodeOptions shows options from options.nodes but not custom per-node options (same for edges and network.body.edges[id].edgeOptions)
// network.body.nodes contain much more stuff (x,y, default stuff)
//# look for a suitable getter
var edges = network.body.data.edges._data; // map; for edges to/from? certain node use network.getConnectedNodes(id)
// network.body.data.edges._data is a hash of { id: , from: , to: }
// get node positions
var positions = network.getPositions(),
nodeIds = Object.keys(nodes);
// get data describing nodes, edges and options for storage
var storedEdges = [], storedEdge, storedNodes = [], storedNode;
var indexIds = {}, idIndex = 1, end;
for(var nodeId in nodes) {
// nodes[nodeId].x is the initial value, positions[nodeId].x is the current one
if(positions[nodeId]) { // undefined for hidden
nodes[nodeId].x = positions[nodeId].x;
nodes[nodeId].y = positions[nodeId].y;
}
storedNode = copyObjectProperties(nodes[nodeId]);
// don't store id unless that breaks connected edges
if(!network.getConnectedEdges(nodeId).length)
storedNode.id = undefined;
// substitute generated ids with no semantics with simple indices
if(/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/.exec(storedNode.id)) {
while(nodes[idIndex])
idIndex++;
indexIds[storedNode.id] = idIndex; // remember the given index
storedNode.id = idIndex; // substitute with an index
idIndex++;
}
storedNodes.push(storedNode);
}
for(var edgeId in edges) {
storedEdge = copyObjectProperties(edges[edgeId]);
storedEdge.id = undefined; // then strip id
// change from/to in accord to the substitution above (for nodes' ids)
for(end of ["from","to"])
storedEdge[end] = indexIds[storedEdge[end]] || storedEdge[end];
storedEdges.push(storedEdge);
}
dataAndOptions = {
data: { nodes: storedNodes, edges: storedEdges },
options: storedOptions
};
var dataAndOptionsText = JSON.stringify(dataAndOptions,"",4)
.replace(/ {4}/gm,"\t").replace(/},\n\t\t\t{/gm,"},{");
和帮助程序定义:
// helper for storing options
var copyObjectProperties = function(obj) {
return JSON.parse(JSON.stringify(obj));
};
有关更多上下文,请参阅my plugin以获取TiddlyWiki Classic(saveDataAndOptions
方法)。它不是最新版本,但我会在某个时候进行更新。
关于网络选项(如果已更改),我haven't figured还是不错的方法。
答案 2 :(得分:0)
使用storePositions()
将X和Y坐标加载到数据集中。您可以对其进行序列化,然后在稍后初始化网络时使用序列化的坐标扩展节点。
vis.js Network docs on storePositions()
说:
使用vis.DataSet将节点加载到网络时,此方法会将所有节点的X和Y位置放入该数据集中。如果您要从数据库加载节点并使其与数据集动态耦合,则可以使用它来稳定网络一次,然后通过数据集将位置保存在该数据库中,以便下次加载节点时,稳定化将接近瞬间。
您必须为network.data
使用vis.js的DataSet
。要“保存”,只需调用network.storePositions()
,以便它可以将X和Y坐标加载到network.data.nodes
,然后按需要对其进行序列化。
您只需forEach()
您的network.data.nodes
并通过update()
将序列化的X和Y坐标添加到其节点。
在此演示中,位置被序列化为textarea
。您可以生成随机放置的图(这是默认行为),移动节点,对其进行序列化,可以选择在textarea
中对其进行编辑,然后将其加载回去。
const nodes = [
{ id: 1, label: 1 },
{ id: 2, label: 2 },
{ id: 3, label: 3 },
{ id: 4, label: 4 },
]
const edges = [
{ id: '1-2', from: 1, to: 2 },
{ id: '1-3', from: 1, to: 3 },
{ id: '2-3', from: 2, to: 3 },
{ id: '1-4', from: 1, to: 4 },
]
const positionsElement = document.getElementById('positions')
const container = document.getElementById('graph')
const data = {
nodes: new vis.DataSet(nodes),
edges: new vis.DataSet(edges),
}
const options = {
layout: {
improvedLayout: false,
},
edges: {
smooth: false,
},
physics: false,
}
let network = null
function initGraph(generateRandomPosition = true) {
if (generateRandomPosition) {
data.nodes.forEach(node => {
data.nodes.update({ id: node.id, x: undefined, x: undefined })
})
}
network = new vis.Network(container, data, options)
}
document.getElementById('generate-graph').addEventListener('click', initGraph)
document.getElementById('extract-positions').addEventListener('click', e => {
network.storePositions()
const nodePositions = data.nodes.map(({ id, x, y }) => ({ id, x, y }))
positionsElement.value = JSON.stringify(nodePositions)
})
document.getElementById('load-positions').addEventListener('click', e => {
const nodePositions = JSON.parse(positionsElement.value)
nodePositions.forEach(nodePosition => data.nodes.update(nodePosition))
initGraph(false)
})
#graph {
width: 100%;
height: 300px;
border: 1px solid lightgray;
}
#positions {
width: 100%;
min-height: 60px;
}
<link href="https://visjs.github.io/vis-network/dist/vis-network.min.css" rel="stylesheet" />
<script src="https://visjs.github.io/vis-network/dist/vis-network.min.js"></script>
<div id="graph"></div>
<button id="generate-graph">Generate graph</button>
<button id="extract-positions">Extract positions</button>
<button id="load-positions">Load positions</button>
<textarea id="positions"></textarea>