Skip to content

Commit

Permalink
feat(dia.Graph): add transferCellHierarchy() and transferCellLinks() …
Browse files Browse the repository at this point in the history
…methods
  • Loading branch information
MartinKanera committed Sep 6, 2024
1 parent f5df2d1 commit f749a0b
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 0 deletions.
35 changes: 35 additions & 0 deletions packages/joint-core/src/dia/Graph.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,41 @@ export const Graph = Model.extend({
this.get('cells').remove(cell, { silent: true });
},

transferCellHierarchy: function(sourceCell, targetCell) {

// Embed children of the source cell in the target cell.
const children = sourceCell.getEmbeddedCells();
if (children.length > 0) {
sourceCell.unembed(children);
targetCell.embed(children);
}

// Embed the target cell in the parent of the source cell, if any.
const parent = sourceCell.getParentCell();
if (parent) {
parent.unembed(sourceCell);
parent.embed(targetCell);
}

return this;
},

transferCellLinks: function(sourceCell, targetCell) {

// Reconnect all the links connected to the old cell to the new cell.
const connectedLinks = this.getConnectedLinks(sourceCell);
connectedLinks.forEach((link) => {

if (link.getSourceCell() === sourceCell) {
link.prop(['source', 'id'], targetCell.id);
} else {
link.prop(['target', 'id'], targetCell.id);
}
});

return this;
},

// Get a cell by `id`.
getCell: function(id) {

Expand Down
124 changes: 124 additions & 0 deletions packages/joint-core/test/jointjs/graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -1546,4 +1546,128 @@ QUnit.module('graph', function(hooks) {
assert.notOk(graph.hasActiveBatch());
});
});

QUnit.module('graph.transferCellHierarchy()', function() {

QUnit.test('should transfer hierarchy of elements', function(assert) {

const topLevelElement = new joint.shapes.standard.Rectangle();
const originalElement = new joint.shapes.standard.Rectangle();
const child = new joint.shapes.standard.Rectangle();
const replacementElement = new joint.shapes.standard.Rectangle();

topLevelElement.embed(originalElement);
originalElement.embed(child);

this.graph.addCells([topLevelElement, originalElement, child, replacementElement]);
this.graph.transferCellHierarchy(originalElement, replacementElement);

assert.equal(replacementElement.getParentCell(), topLevelElement);
assert.equal(replacementElement.getEmbeddedCells()[0], child);
});

QUnit.test('should transfer hierarchy of links', function(assert) {

const parent = new joint.shapes.standard.Rectangle();
const originalLink = new joint.shapes.standard.Link();
const replacementLink = new joint.shapes.standard.Link();

parent.embed(originalLink);

this.graph.addCells([parent, originalLink, replacementLink]);
this.graph.transferCellHierarchy(originalLink, replacementLink);

assert.equal(replacementLink.getParentCell(), parent);
});

QUnit.test('should work when transferring hierarchy from a link to an element', function(assert) {

const parent = new joint.shapes.standard.Rectangle();
const link = new joint.shapes.standard.Link();
const element = new joint.shapes.standard.Rectangle();

parent.embed(link);

this.graph.addCells([parent, link, element]);
this.graph.transferCellHierarchy(link, element);

assert.equal(element.getParentCell(), parent);
});

QUnit.test('should work when transferring hierarchy from an element to a link', function(assert) {

const parent = new joint.shapes.standard.Rectangle();
const link = new joint.shapes.standard.Link();
const child = new joint.shapes.standard.Rectangle();
const element = new joint.shapes.standard.Rectangle();

element.embed(child);
parent.embed(element);

this.graph.addCells([parent, link, child, element]);
this.graph.transferCellHierarchy(element, link);

assert.equal(link.getParentCell(), parent);
assert.equal(link.getEmbeddedCells()[0], child);
});
});

QUnit.module('graph.transferCellLinks()', function() {

QUnit.test('should transfer links of an element', function(assert) {

const originalElement = new joint.shapes.standard.Rectangle();
const link1 = new joint.shapes.standard.Link({ source: { id: originalElement.id }});
const link2 = new joint.shapes.standard.Link({ target: { id: originalElement.id }});
const replacementElement = new joint.shapes.standard.Rectangle();

this.graph.addCells([originalElement, link1, link2]);
this.graph.transferCellLinks(originalElement, replacementElement);

assert.equal(link1.source().id, replacementElement.id);
assert.equal(link2.target().id, replacementElement.id);
});

QUnit.test('should transfer links of a link', function(assert) {

const originalLink = new joint.shapes.standard.Link();
const link1 = new joint.shapes.standard.Link({ source: { id: originalLink.id }});
const link2 = new joint.shapes.standard.Link({ target: { id: originalLink.id }});
const replacementLink = new joint.shapes.standard.Link();

this.graph.addCells([originalLink, link1, link2]);
this.graph.transferCellLinks(originalLink, replacementLink);

assert.equal(link1.source().id, replacementLink.id);
assert.equal(link2.target().id, replacementLink.id);
});

QUnit.test('should work when transferring links from a link to an element', function(assert) {

const originalLink = new joint.shapes.standard.Link();
const link1 = new joint.shapes.standard.Link({ source: { id: originalLink.id }});
const link2 = new joint.shapes.standard.Link({ target: { id: originalLink.id }});
const element = new joint.shapes.standard.Rectangle();

this.graph.addCells([originalLink, link1, link2, element]);
this.graph.transferCellLinks(originalLink, element);

assert.equal(link1.source().id, element.id);
assert.equal(link2.target().id, element.id);
});

QUnit.test('should work when transferring links from an element to a link', function(assert) {

const originalElement = new joint.shapes.standard.Rectangle();
const link1 = new joint.shapes.standard.Link({ source: { id: originalElement.id }});
const link2 = new joint.shapes.standard.Link({ target: { id: originalElement.id }});
const replacementLink = new joint.shapes.standard.Link();

this.graph.addCells([originalElement, link1, link2, replacementLink]);
this.graph.transferCellLinks(originalElement, replacementLink);

assert.equal(link1.source().id, replacementLink.id);
assert.equal(link2.target().id, replacementLink.id);
});
});
});
4 changes: 4 additions & 0 deletions packages/joint-core/types/joint.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ export namespace dia {

removeCells(cells: Cell[], opt?: Cell.DisconnectableOptions): this;

transferCellHierarchy(sourceCell: Cell, targetCell: Cell): this;

transferCellLinks(sourceCell: Cell, targetCell: Cell): this;

resize(width: number, height: number, opt?: S): this;

resizeCells(width: number, height: number, cells: Cell[], opt?: S): this;
Expand Down

0 comments on commit f749a0b

Please sign in to comment.