in src/visual/Visualizer.js [458:569]
_update() {
const step = this._step;
if (!step) {
return;
}
// validate call <-> step correspondence
const children = this._children;
const declarations = this._declarations;
// handle the renames
const pickBy = _.pickBy || _.pick; // be prepared for legacy lodash 3.10.1
const renamed = pickBy(children, (vStep, name) => name !== generateChildName(vStep.step));
_.forEach(renamed, (vStep, oldName) => {
delete children[oldName];
children[generateChildName(vStep.step)] = vStep;
});
const toRemove = [];
const findChildInModel = (visChild, name, modelChild) => {
const modelChildName = generateChildName(modelChild);
if (modelChildName === name) {
return true;
}
const modelChildren = modelChild.children;
if (_.has(modelChildren, name)) {
return true;
}
let res = false;
_.forEach(modelChildren, (child) => {
res = res || findChildInModel(visChild, name, child);
});
return res;
};
_.forEach(children, (visChild, name) => {
if (!findChildInModel(visChild, name, step)) {
// remove visual step from graph
toRemove[toRemove.length] = visChild;
}
});
this._graph.removeCells(toRemove);
_.forEach(toRemove, (child) => {
const idx = _.indexOf(this.selection, child);
if (idx !== -1) {
this.selection.splice(idx, 1);
}
delete children[generateChildName(child.step)];
});
const cellsToAdd = [];
const updateOrCreateVisualSteps = (innerStep, parent = null) => {
const name = generateChildName(innerStep);
let visChild = children[name];
if (!visChild) {
const opts = this.zoom.fromWidgetToLocal({
x: this.paper.el.offsetWidth / 2,
y: this.paper.el.offsetHeight / 2,
});
opts.step = innerStep;
visChild = createVisual(opts);
children[name] = visChild;
cellsToAdd[cellsToAdd.length] = visChild;
if (_.size(opts.step.ownDeclarations)) {
_.forEach(opts.step.ownDeclarations, (declaration) => {
let visDeclaration = declarations[declaration.name];
if (!visDeclaration) {
visDeclaration = new VisualDeclaration({ declaration, x: opts.x, y: opts.y });
cellsToAdd[cellsToAdd.length] = visDeclaration;
declarations[declaration.name] = visDeclaration;
visChild.embed(visDeclaration);
visChild.fit();
visChild.update();
}
});
}
if (parent) {
parent.embed(visChild);
parent.fit();
parent.update();
}
} else {
// it is essential to update links before the step!
const links = this._graph.getConnectedLinks(visChild);
_.forEach(links, (link) => {
link.refresh();
});
visChild.update();
}
const innerChildren = innerStep.children;
_.forEach(innerChildren, (child) => {
updateOrCreateVisualSteps(child, visChild);
});
};
updateOrCreateVisualSteps(step);
_.forEach(children, (child) => {
this._loopPorts(child.step.o, child, declarations, cellsToAdd, portName => child.isPortEnabled(false, portName));
this._loopPorts(child.step.i, child, declarations, cellsToAdd, portName => child.isPortEnabled(true, portName));
});
this._loopDeclarations(declarations, cellsToAdd);
this._graph.addCells(cellsToAdd);
}