Fix loading of relationships

This commit is contained in:
Paulo Gustavo Veiga 2021-12-15 17:59:51 -08:00
parent b397a583d6
commit fc4cb9cd83
10 changed files with 53 additions and 62 deletions

View File

@ -33,8 +33,10 @@
"dependencies": { "dependencies": {
"@wisemapping/core-js": "^0.0.1", "@wisemapping/core-js": "^0.0.1",
"@wisemapping/web2d": "^0.0.1", "@wisemapping/web2d": "^0.0.1",
"add": "^2.0.6",
"jest": "^27.4.3", "jest": "^27.4.3",
"jquery": "^3.6.0" "jquery": "^3.6.0",
"lodash": "^4.17.21"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.14.6", "@babel/core": "^7.14.6",
@ -55,9 +57,9 @@
"eslint-plugin-only-warn": "^1.0.3", "eslint-plugin-only-warn": "^1.0.3",
"html-webpack-plugin": "^5.3.2", "html-webpack-plugin": "^5.3.2",
"jest-webpack": "^0.5.1", "jest-webpack": "^0.5.1",
"mocha": "^9.1.3",
"less": "^4.1.2", "less": "^4.1.2",
"less-loader": "^10.2.0", "less-loader": "^10.2.0",
"mocha": "^9.1.3",
"nodemon": "^2.0.12", "nodemon": "^2.0.12",
"start-server-and-test": "^1.14.0", "start-server-and-test": "^1.14.0",
"webpack": "^5.44.0", "webpack": "^5.44.0",

View File

@ -635,16 +635,16 @@ class Designer extends Events {
} }
/** /**
* @param {mindplot.Mindmap} mindmapModel * @param {mindplot.Mindmap} model
* @throws will throw an error if mindmapModel is null or undefined * @throws will throw an error if mindmapModel is null or undefined
*/ */
loadMap(mindmapModel) { loadMap(model) {
$assert(mindmapModel, 'mindmapModel can not be null'); $assert(model, 'mindmapModel can not be null');
this._mindmap = mindmapModel; this._mindmap = model;
// Init layout manager ... // Init layout manager ...
const size = { width: 25, height: 25 }; const size = { width: 25, height: 25 };
const layoutManager = new LayoutManager(mindmapModel.getCentralTopic().getId(), size); const layoutManager = new LayoutManager(model.getCentralTopic().getId(), size);
const me = this; const me = this;
layoutManager.addEvent('change', (event) => { layoutManager.addEvent('change', (event) => {
const id = event.getId(); const id = event.getId();
@ -655,14 +655,14 @@ class Designer extends Events {
this._eventBussDispatcher.setLayoutManager(layoutManager); this._eventBussDispatcher.setLayoutManager(layoutManager);
// Building node graph ... // Building node graph ...
const branches = mindmapModel.getBranches(); const branches = model.getBranches();
branches.forEach((branch) => { branches.forEach((branch) => {
const nodeGraph = this.nodeModelToNodeGraph(branch); const nodeGraph = this.nodeModelToNodeGraph(branch);
nodeGraph.setBranchVisibility(true); nodeGraph.setBranchVisibility(true);
}); });
// Connect relationships ... // Connect relationships ...
const relationships = mindmapModel.getRelationships(); const relationships = model.getRelationships();
relationships.forEach((relationship) => this._relationshipModelToRelationship(relationship)); relationships.forEach((relationship) => this._relationshipModelToRelationship(relationship));
// Place the focus on the Central Topic // Place the focus on the Central Topic

View File

@ -47,7 +47,7 @@ class LinkIcon extends Icon {
}); });
// FIXME: we shouldn't have timeout of that.. // FIXME: we shouldn't have timeout of that..
this.addEvent('mouseleave', (event) => { this.addEvent('mouseleave', (event) => {
window.setTimeout(() => { setTimeout(() => {
if (!$('#linkPopover:hover').length) { if (!$('#linkPopover:hover').length) {
me._tip.hide(); me._tip.hide();
} }

View File

@ -1,12 +1,11 @@
class Options { class Options {
setOptions(...args) { setOptions(...args) {
this.options = { ...this.options, ...args }; this.options = { ...this.options, ...args };
const { options } = this; const { options } = this;
if (this.addEvent) { if (this.addEvent) {
for (const option in options) { for (const option in options) {
if (typeof (options[option]) != 'function' || !(/^on[A-Z]/).test(option) ){ if (typeof (options[option]) !== 'function' || !(/^on[A-Z]/).test(option)) {
continue; continue;
} }
this.addEvent(option, options[option]); this.addEvent(option, options[option]);
@ -15,7 +14,6 @@ class Options {
} }
return this; return this;
} }
} }
export default Options; export default Options;

View File

@ -74,6 +74,7 @@ class FeatureModel {
/** */ /** */
setId(id) { setId(id) {
$assert(Number.isFinite(id));
this._id = id; this._id = id;
} }

View File

@ -31,6 +31,7 @@ class INodeModel {
/** */ /** */
setId(id) { setId(id) {
$assert(Number.isFinite(id));
if ($defined(id) && id > INodeModel._uuid) { if ($defined(id) && id > INodeModel._uuid) {
INodeModel._uuid = id; INodeModel._uuid = id;
} }
@ -140,7 +141,7 @@ class INodeModel {
/** */ /** */
setOrder(value) { setOrder(value) {
$assert( $assert(
(typeof value === 'number' && isFinite(value)) || value == null, (typeof value === 'number' && Number.isFinite(value)) || value == null,
'Order must be null or a number', 'Order must be null or a number',
); );
this.putProperty('order', value); this.putProperty('order', value);

View File

@ -127,12 +127,12 @@ class Mindmap extends IMindmap {
} }
/** /**
* @param sourceNodeId * @param sourceNodeId
* @param targetNodeId * @param targetNodeId
* @throws will throw an error if source node is null or undefined * @throws will throw an error if source node is null or undefined
* @throws will throw an error if target node is null or undefined * @throws will throw an error if target node is null or undefined
* @return the relationship model created * @return the relationship model created
*/ */
createRelationship(sourceNodeId, targetNodeId) { createRelationship(sourceNodeId, targetNodeId) {
$assert($defined(sourceNodeId), 'from node cannot be null'); $assert($defined(sourceNodeId), 'from node cannot be null');
$assert($defined(targetNodeId), 'to node cannot be null'); $assert($defined(targetNodeId), 'to node cannot be null');
@ -141,8 +141,8 @@ class Mindmap extends IMindmap {
} }
/** /**
* @param relationship * @param relationship
*/ */
addRelationship(relationship) { addRelationship(relationship) {
this._relationships.push(relationship); this._relationships.push(relationship);
} }
@ -154,10 +154,6 @@ class Mindmap extends IMindmap {
this._relationships = this._branches.filter((r) => r !== relationship); this._relationships = this._branches.filter((r) => r !== relationship);
} }
/**
* @param id
* @return the node with the respective id or null if not in the mindmap
*/
findNodeById(id) { findNodeById(id) {
let result = null; let result = null;
for (let i = 0; i < this._branches.length; i++) { for (let i = 0; i < this._branches.length; i++) {

View File

@ -16,6 +16,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { $assert, $defined } from '@wisemapping/core-js'; import { $assert, $defined } from '@wisemapping/core-js';
import { cloneDeep } from 'lodash';
import INodeModel from './INodeModel'; import INodeModel from './INodeModel';
import TopicFeature from '../TopicFeature'; import TopicFeature from '../TopicFeature';
@ -121,16 +122,7 @@ class NodeModel extends INodeModel {
* @return {mindplot.model.NodeModel} an identical clone of the NodeModel * @return {mindplot.model.NodeModel} an identical clone of the NodeModel
*/ */
clone() { clone() {
const result = new NodeModel(this.getType(), this._mindmap); return cloneDeep(this);
result._children = this._children.map((node) => {
const cnode = node.clone();
cnode._parent = result;
return cnode;
});
result._properties = { ...this._properties };
result._feature = { ...this._feature };
return result;
} }
/** /**
@ -211,6 +203,7 @@ class NodeModel extends INodeModel {
* @return {mindplot.model.NodeModel} the node with the respective id * @return {mindplot.model.NodeModel} the node with the respective id
*/ */
findNodeById(id) { findNodeById(id) {
$assert(Number.isFinite(id));
let result = null; let result = null;
if (this.getId() === id) { if (this.getId() === id) {
result = this; result = this;

View File

@ -22,6 +22,8 @@ class RelationshipModel {
constructor(sourceTopicId, targetTopicId) { constructor(sourceTopicId, targetTopicId) {
$assert($defined(sourceTopicId), 'from node type can not be null'); $assert($defined(sourceTopicId), 'from node type can not be null');
$assert($defined(targetTopicId), 'to node type can not be null'); $assert($defined(targetTopicId), 'to node type can not be null');
$assert(Number.isFinite(sourceTopicId), 'sourceTopicId is not a number');
$assert(Number.isFinite(targetTopicId), 'targetTopicId is not a number');
this._id = RelationshipModel._nextUUID(); this._id = RelationshipModel._nextUUID();
this._sourceTargetId = sourceTopicId; this._sourceTargetId = sourceTopicId;

View File

@ -247,30 +247,28 @@ class XMLSerializer_Pela {
this._idsMap = {}; this._idsMap = {};
// Start the loading process ... // Start the loading process ...
const version = rootElem.getAttribute('version'); const version = rootElem.getAttribute('version');
const mindmap = new Mindmap(mapId, version); const mindmap = new Mindmap(mapId, version);
const children = rootElem.childNodes;
for (let i = 0; i < children.length; i++) { // Add all the topics nodes ...
const child = children[i]; const childNodes = Array.from(rootElem.childNodes);
if (child.nodeType === 1) { const topicsNodes = childNodes.filter((child) => (child.nodeType === 1 && child.tagName === 'topic'));
switch (child.tagName) { topicsNodes.forEach((child) => {
case 'topic': { const topic = this._deserializeNode(child, mindmap);
const topic = this._deserializeNode(child, mindmap); mindmap.addBranch(topic);
mindmap.addBranch(topic); });
break;
} // Then all relationshops, they are connected to topics ...
case 'relationship': { const relationshipsNodes = childNodes.filter((child) => (child.nodeType === 1 && child.tagName === 'relationship'));
const relationship = XMLSerializer_Pela._deserializeRelationship(child, mindmap); relationshipsNodes.forEach((child) => {
if (relationship != null) { try {
mindmap.addRelationship(relationship); const relationship = XMLSerializer_Pela._deserializeRelationship(child, mindmap);
} mindmap.addRelationship(relationship);
break; } catch (e) {
} console.error(e);
default:
break;
}
} }
} });
// Clean up from the recursion ...
this._idsMap = null; this._idsMap = null;
mindmap.setId(mapId); mindmap.setId(mapId);
return mindmap; return mindmap;
@ -446,19 +444,19 @@ class XMLSerializer_Pela {
} }
static _deserializeRelationship(domElement, mindmap) { static _deserializeRelationship(domElement, mindmap) {
const srcId = domElement.getAttribute('srcTopicId'); const srcId = Number.parseInt(domElement.getAttribute('srcTopicId'), 10);
const destId = domElement.getAttribute('destTopicId'); const destId = Number.parseInt(domElement.getAttribute('destTopicId'), 10);
const lineType = domElement.getAttribute('lineType'); const lineType = domElement.getAttribute('lineType');
const srcCtrlPoint = domElement.getAttribute('srcCtrlPoint'); const srcCtrlPoint = domElement.getAttribute('srcCtrlPoint');
const destCtrlPoint = domElement.getAttribute('destCtrlPoint'); const destCtrlPoint = domElement.getAttribute('destCtrlPoint');
// If for some reason a relationship lines has source and dest nodes the same, don't import it. // If for some reason a relationship lines has source and dest nodes the same, don't import it.
if (srcId === destId) { if (srcId === destId) {
return null; throw new Error('Invalid relationship, dest and source are equals');
} }
// Is the connections points valid ?. If it's not, do not load the relationship ... // Is the connections points valid ?. If it's not, do not load the relationship ...
if (mindmap.findNodeById(srcId) == null || mindmap.findNodeById(destId) == null) { if (mindmap.findNodeById(srcId) == null || mindmap.findNodeById(destId) == null) {
return null; throw new Error('Transition could not created, missing node for relationship');
} }
const model = mindmap.createRelationship(srcId, destId); const model = mindmap.createRelationship(srcId, destId);