保存和加载 jsPlumb 流程图,包括准确的锚点和连接
这是我正在构建的流程图编辑器的 开始.
为此,我添加了保存"和加载"按钮,用于将流程图导出/导入 JSON(保存后在 jsFiddle 中的文本表单中显示 - 相同的文本表单可用于加载).
保存功能:
函数 saveFlowchart(){变量节点 = []$(".node").each(function (idx, elem) {变量 $elem = $(elem);var endpoints = jsPlumb.getEndpoints($elem.attr('id'));console.log(''+$elem.attr('id')的端点);控制台.log(端点);节点.push({blockId: $elem.attr('id'),节点类型:$elem.attr('data-nodetype'),positionX: parseInt($elem.css("left"), 10),positionY: parseInt($elem.css("top"), 10)});});var 连接 = [];$.each(jsPlumb.getConnections(), function (idx, connection) {连接.push({连接ID:连接ID,pageSourceId:connection.sourceId,pageTargetId:connection.targetId});});var 流程图 = {};flowChart.nodes = 节点;flowChart.connections = 连接;flowChart.numberOfElements = numberOfElements;var flowChartJson = JSON.stringify(flowChart);//console.log(flowChartJson);$('#jsonOutput').val(flowChartJson);}
上面示例的结果 JSON:
<块引用>{"nodes":[{"blockId":"startpoint","nodetype":"startpoint","positionX":273,"positionY":8},{"blockId":"endpoint","nodetype":"endpoint","positionX":310,"positionY":385},{"blockId":"taskcontainer1","nodetype":"task","positionX":381,"positionY":208},{"blockId":"decisioncontainer2","nodetype":"decision","positionX":261,"positionY":103}],"connections":[{"connectionId":"con_18","pageSourceId":"decisioncontainer2","pageTargetId":"taskcontainer1"},{"connectionId":"con_25","pageSourceId":"taskcontainer1","pageTargetId":"endpoint"},{"connectionId":"con_32","pageSourceId":"decisioncontainer2","pageTargetId":"endpoint"},{"connectionId":"con_46","pageSourceId":"startpoint","pageTargetId":"decisioncontainer2"}],"numberOfElements":2}
这样我就可以保存元素的位置以及连接的部分信息.这里是加载函数:
函数 loadFlowchart(){var flowChartJson = $('#jsonOutput').val();var flowChart = JSON.parse(flowChartJson);var 节点 = flowChart.nodes;$.each(节点,函数(索引,元素){如果(elem.nodetype === '起点'){repositionElement('起点', elem.positionX, elem.positionY);}else if(elem.nodetype === 'endpoint'){repositionElement('endpoint', elem.positionX, elem.positionY);}else if(elem.nodetype === 'task'){var id = addTask(elem.blockId);重新定位元素(id,elem.positionX,elem.positionY);}else if(elem.nodetype === 'decision'){var id = addDecision(elem.blockId);重新定位元素(id,elem.positionX,elem.positionY);}别的{}});var 连接 = flowChart.connections;$.each(连接,函数(索引,元素){var connection1 = jsPlumb.connect({来源:elem.pageSourceId,目标:elem.pageTargetId,锚点:["BottomCenter", [0.75, 0, 0, -1]]});});numberOfElements = flowChart.numberOfElements;}
但是,锚点和连接的确切位置会丢失.还是同样的例子,删除元素再加载导出的 JSON 后的结果:
这并不奇怪,因为我还没有存储信息.但我被困在这一点上.
我的问题是:我需要为整个流程图设计存储哪些关于锚点/连接器位置的信息,以及如何从 jsPlumb 中提取(并再次加载到其中)?
解决方案请参阅此 JSFiddle 以获得解决方案.
您需要按如下方式保存锚点详细信息.这符合此处定义的锚表示.注意双重嵌套以避免 JQuery 在地图上自动展平.
$.each(jsPlumb.getConnections(), function (idx, connection) {连接.push({连接ID:连接ID,pageSourceId:connection.sourceId,pageTargetId:connection.targetId,锚点:$.map(connection.endpoints, function(endpoint) {返回 [[endpoint.anchor.x,端点.anchor.y,端点.anchor.orientation[0],端点.anchor.orientation[1],端点.anchor.offsets[0],端点.anchor.offsets[1]]];})});});
...并加载它们,如下所示:
$.each(connections, function( index, elem ) {var connection1 = jsPlumb.connect({来源:elem.pageSourceId,目标:elem.pageTargetId,锚点:elem.anchors});});
请注意,此解决方案不保留端点详细信息,包括端点的形状和类型.它只会按照您的要求保留锚点详细信息.
This is the jsFiddle of the flowchart editor I am building.
This is an example of what can be easily created with "Add Decision" + "Add Task", connecting and moving the elements.
Now for the hard part: I want to be able to save and load the exact flowchart. For this I got started based with a similar thread here at Stackoverflow.
For this I added the "Save" and "Load" buttons that export/import the flowchart to/from JSON (shown in a textform in the jsFiddle after save - same textform can be used for loading).
The save function:
function saveFlowchart(){
var nodes = []
$(".node").each(function (idx, elem) {
var $elem = $(elem);
var endpoints = jsPlumb.getEndpoints($elem.attr('id'));
console.log('endpoints of '+$elem.attr('id'));
console.log(endpoints);
nodes.push({
blockId: $elem.attr('id'),
nodetype: $elem.attr('data-nodetype'),
positionX: parseInt($elem.css("left"), 10),
positionY: parseInt($elem.css("top"), 10)
});
});
var connections = [];
$.each(jsPlumb.getConnections(), function (idx, connection) {
connections.push({
connectionId: connection.id,
pageSourceId: connection.sourceId,
pageTargetId: connection.targetId
});
});
var flowChart = {};
flowChart.nodes = nodes;
flowChart.connections = connections;
flowChart.numberOfElements = numberOfElements;
var flowChartJson = JSON.stringify(flowChart);
//console.log(flowChartJson);
$('#jsonOutput').val(flowChartJson);
}
The resulting JSON of the example above:
{"nodes":[{"blockId":"startpoint","nodetype":"startpoint","positionX":273,"positionY":8},{"blockId":"endpoint","nodetype":"endpoint","positionX":310,"positionY":385},{"blockId":"taskcontainer1","nodetype":"task","positionX":381,"positionY":208},{"blockId":"decisioncontainer2","nodetype":"decision","positionX":261,"positionY":103}],"connections":[{"connectionId":"con_18","pageSourceId":"decisioncontainer2","pageTargetId":"taskcontainer1"},{"connectionId":"con_25","pageSourceId":"taskcontainer1","pageTargetId":"endpoint"},{"connectionId":"con_32","pageSourceId":"decisioncontainer2","pageTargetId":"endpoint"},{"connectionId":"con_46","pageSourceId":"startpoint","pageTargetId":"decisioncontainer2"}],"numberOfElements":2}
With that I am able to save the position of the elements as well as part of the information of the connections. Here the load function:
function loadFlowchart(){
var flowChartJson = $('#jsonOutput').val();
var flowChart = JSON.parse(flowChartJson);
var nodes = flowChart.nodes;
$.each(nodes, function( index, elem ) {
if(elem.nodetype === 'startpoint'){
repositionElement('startpoint', elem.positionX, elem.positionY);
}else if(elem.nodetype === 'endpoint'){
repositionElement('endpoint', elem.positionX, elem.positionY);
}else if(elem.nodetype === 'task'){
var id = addTask(elem.blockId);
repositionElement(id, elem.positionX, elem.positionY);
}else if(elem.nodetype === 'decision'){
var id = addDecision(elem.blockId);
repositionElement(id, elem.positionX, elem.positionY);
}else{
}
});
var connections = flowChart.connections;
$.each(connections, function( index, elem ) {
var connection1 = jsPlumb.connect({
source: elem.pageSourceId,
target: elem.pageTargetId,
anchors: ["BottomCenter", [0.75, 0, 0, -1]]
});
});
numberOfElements = flowChart.numberOfElements;
}
However, the exact position of the anchors and connections are lost. Same example again, the result after deleting the elements and then loading the exported JSON:
This comes not as a big surprise as I have not yet stored the information. But I am stuck at this point.
My question is: which information regarding the anchors/connectors position do I need to store for the whole flowchart design and how I can extract it from (& load into it again) jsPlumb?
解决方案See this JSFiddle for a solution.
You need to save the anchor details as follows. This conforms to the Anchor representation defined here. Note the double nesting to avoid the JQuery auto-flatten on the map.
$.each(jsPlumb.getConnections(), function (idx, connection) {
connections.push({
connectionId: connection.id,
pageSourceId: connection.sourceId,
pageTargetId: connection.targetId,
anchors: $.map(connection.endpoints, function(endpoint) {
return [[endpoint.anchor.x,
endpoint.anchor.y,
endpoint.anchor.orientation[0],
endpoint.anchor.orientation[1],
endpoint.anchor.offsets[0],
endpoint.anchor.offsets[1]]];
})
});
});
...and load them, as follows:
$.each(connections, function( index, elem ) {
var connection1 = jsPlumb.connect({
source: elem.pageSourceId,
target: elem.pageTargetId,
anchors: elem.anchors
});
});
Note that this solution does not preserve end-point details including the shape and type of end-points. It only preserves the anchor details, as you requested.
相关文章