feat: add GraphDataModel.batchUpdate method (#213)
The method already exists in the `Graph` class. It needs to be made available in `GraphDataModel` as well, to simplify the transaction syntax. Start using it in some places to simplify the syntax and also use `Graph.batchUpdate`.development
parent
0c7a68bcc1
commit
992f3af63d
|
@ -329,8 +329,7 @@ export const setCellStyles = (
|
|||
value: any
|
||||
) => {
|
||||
if (cells.length > 0) {
|
||||
model.beginUpdate();
|
||||
try {
|
||||
model.batchUpdate(() => {
|
||||
for (let i = 0; i < cells.length; i += 1) {
|
||||
const cell = cells[i];
|
||||
|
||||
|
@ -341,9 +340,7 @@ export const setCellStyles = (
|
|||
model.setStyle(cell, style);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -377,8 +374,7 @@ export const setCellStyleFlags = (
|
|||
value: boolean
|
||||
) => {
|
||||
if (cells.length > 0) {
|
||||
model.beginUpdate();
|
||||
try {
|
||||
model.batchUpdate(() => {
|
||||
for (let i = 0; i < cells.length; i += 1) {
|
||||
const cell = cells[i];
|
||||
|
||||
|
@ -387,9 +383,7 @@ export const setCellStyleFlags = (
|
|||
model.setStyle(cell, style);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -397,7 +391,7 @@ export const setCellStyleFlags = (
|
|||
* Sets or removes the given key from the specified style and returns the
|
||||
* new style. If value is null then the flag is toggled.
|
||||
*
|
||||
* @param style String of the form [(stylename|key=value);].
|
||||
* @param style The style of the Cell.
|
||||
* @param key Key of the style to be changed.
|
||||
* @param flag Integer for the bit to be changed.
|
||||
* @param value Optional boolean value for the given flag.
|
||||
|
|
|
@ -484,20 +484,14 @@ class Graph extends EventSource {
|
|||
getContainsValidationErrorsResource = () => this.containsValidationErrorsResource;
|
||||
|
||||
/**
|
||||
* Shortcut for updating the model in a transaction.
|
||||
* Updates the model in a transaction.
|
||||
*
|
||||
* @param fn the update to be performed in the transaction.
|
||||
*
|
||||
* @see {@link GraphDataModel.beginUpdate}
|
||||
* @see {@link GraphDataModel.endUpdate}
|
||||
* @see {@link GraphDataModel.batchUpdate}
|
||||
*/
|
||||
batchUpdate(fn: () => void) {
|
||||
this.getDataModel().beginUpdate();
|
||||
try {
|
||||
fn();
|
||||
} finally {
|
||||
this.getDataModel().endUpdate();
|
||||
}
|
||||
this.getDataModel().batchUpdate(fn);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -956,6 +956,31 @@ export class GraphDataModel extends EventSource {
|
|||
this.endUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the model in a transaction.
|
||||
* This is a shortcut to the usage of {@link beginUpdate} and the {@link endUpdate} methods.
|
||||
*
|
||||
* ```javascript
|
||||
* const model = graph.getDataModel();
|
||||
* const parent = graph.getDefaultParent();
|
||||
* const index = model.getChildCount(parent);
|
||||
* model.batchUpdate(() => {
|
||||
* model.add(parent, v1, index);
|
||||
* model.add(parent, v2, index+1);
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param fn the update to be performed in the transaction.
|
||||
*/
|
||||
batchUpdate(fn: () => void) {
|
||||
this.beginUpdate();
|
||||
try {
|
||||
fn();
|
||||
} finally {
|
||||
this.endUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the {@link updateLevel} by one. The event notification
|
||||
* is queued until {@link updateLevel} reaches 0 by use of
|
||||
|
@ -971,9 +996,9 @@ export class GraphDataModel extends EventSource {
|
|||
* and {@link endUpdate} calls as shown here:
|
||||
*
|
||||
* ```javascript
|
||||
* var model = graph.getDataModel();
|
||||
* var parent = graph.getDefaultParent();
|
||||
* var index = model.getChildCount(parent);
|
||||
* const model = graph.getDataModel();
|
||||
* const parent = graph.getDefaultParent();
|
||||
* const index = model.getChildCount(parent);
|
||||
* model.beginUpdate();
|
||||
* try
|
||||
* {
|
||||
|
|
|
@ -1727,11 +1727,9 @@ class EdgeHandler {
|
|||
isClone: boolean,
|
||||
me: InternalMouseEvent
|
||||
) {
|
||||
const model = this.graph.getDataModel();
|
||||
const parent = edge.getParent();
|
||||
|
||||
model.beginUpdate();
|
||||
try {
|
||||
this.graph.batchUpdate(() => {
|
||||
let constraint = this.constraintHandler.currentConstraint;
|
||||
|
||||
if (constraint == null) {
|
||||
|
@ -1739,9 +1737,7 @@ class EdgeHandler {
|
|||
}
|
||||
|
||||
this.graph.connectCell(edge, terminal, isSource, constraint);
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
return edge;
|
||||
}
|
||||
|
@ -1752,8 +1748,7 @@ class EdgeHandler {
|
|||
changeTerminalPoint(edge: Cell, point: Point, isSource: boolean, clone: boolean) {
|
||||
const model = this.graph.getDataModel();
|
||||
|
||||
model.beginUpdate();
|
||||
try {
|
||||
model.batchUpdate(() => {
|
||||
if (clone) {
|
||||
const parent = edge.getParent();
|
||||
const terminal = edge.getTerminal(!isSource);
|
||||
|
@ -1770,9 +1765,7 @@ class EdgeHandler {
|
|||
model.setGeometry(edge, geo);
|
||||
this.graph.connectCell(edge, null, isSource, new ConnectionConstraint(null));
|
||||
}
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
return edge;
|
||||
}
|
||||
|
@ -1782,8 +1775,7 @@ class EdgeHandler {
|
|||
*/
|
||||
changePoints(edge: Cell, points: Point[], clone: boolean) {
|
||||
const model = this.graph.getDataModel();
|
||||
model.beginUpdate();
|
||||
try {
|
||||
model.batchUpdate(() => {
|
||||
if (clone) {
|
||||
const parent = edge.getParent();
|
||||
const source = edge.getTerminal(true);
|
||||
|
@ -1802,9 +1794,7 @@ class EdgeHandler {
|
|||
|
||||
model.setGeometry(edge, geo);
|
||||
}
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
return edge;
|
||||
}
|
||||
|
@ -2194,7 +2184,7 @@ class EdgeHandler {
|
|||
this.destroyBends(this.virtualBends);
|
||||
this.virtualBends = this.createVirtualBends();
|
||||
}
|
||||
|
||||
|
||||
if (this.customHandles) {
|
||||
this.destroyBends(this.customHandles);
|
||||
this.customHandles = this.createCustomHandles();
|
||||
|
@ -2272,7 +2262,7 @@ class EdgeHandler {
|
|||
this.virtualBends = [];
|
||||
}
|
||||
|
||||
if (this.customHandles){
|
||||
if (this.customHandles) {
|
||||
this.destroyBends(this.customHandles);
|
||||
this.customHandles = [];
|
||||
}
|
||||
|
|
|
@ -86,13 +86,9 @@ class CircleLayout extends GraphLayout {
|
|||
* Implements {@link GraphLayout#execute}.
|
||||
*/
|
||||
execute(parent: Cell) {
|
||||
const model = this.graph.getDataModel();
|
||||
|
||||
// Moves the vertices to build a circle. Makes sure the
|
||||
// radius is large enough for the vertices to not
|
||||
// overlap
|
||||
model.beginUpdate();
|
||||
|
||||
this.graph.batchUpdate(() => {
|
||||
// Gets all vertices inside the parent and finds
|
||||
// the maximum dimension of the largest vertex
|
||||
|
|
|
@ -80,16 +80,11 @@ class CompositeLayout extends GraphLayout {
|
|||
* single transaction.
|
||||
*/
|
||||
execute(parent: Cell): void {
|
||||
const model = this.graph.getDataModel();
|
||||
|
||||
model.beginUpdate();
|
||||
try {
|
||||
this.graph.batchUpdate(() => {
|
||||
for (let i = 0; i < this.layouts.length; i += 1) {
|
||||
this.layouts[i].execute.apply(this.layouts[i], [parent]);
|
||||
}
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,13 +75,10 @@ class EdgeLabelLayout extends GraphLayout {
|
|||
* @param e edges
|
||||
*/
|
||||
placeLabels(v: CellState[], e: CellState[]): void {
|
||||
const model = this.graph.getDataModel();
|
||||
|
||||
// Moves the vertices to build a circle. Makes sure the
|
||||
// radius is large enough for the vertices to not
|
||||
// overlap
|
||||
model.beginUpdate();
|
||||
try {
|
||||
this.graph.batchUpdate(() => {
|
||||
for (let i = 0; i < e.length; i += 1) {
|
||||
const edge = e[i];
|
||||
|
||||
|
@ -95,9 +92,7 @@ class EdgeLabelLayout extends GraphLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -170,7 +170,6 @@ class MxFastOrganicLayout extends GraphLayout {
|
|||
* given parent where <isVertexIgnored> returns false.
|
||||
*/
|
||||
execute(parent: Cell) {
|
||||
const model = this.graph.getDataModel();
|
||||
this.vertexArray = [];
|
||||
let cells = this.graph.getChildVertices(parent);
|
||||
|
||||
|
@ -230,8 +229,7 @@ class MxFastOrganicLayout extends GraphLayout {
|
|||
|
||||
// Moves cell location back to top-left from center locations used in
|
||||
// algorithm, resetting the edge points is part of the transaction
|
||||
model.beginUpdate();
|
||||
try {
|
||||
this.graph.batchUpdate(() => {
|
||||
for (let i = 0; i < n; i += 1) {
|
||||
this.dispX[i] = 0;
|
||||
this.dispY[i] = 0;
|
||||
|
@ -341,9 +339,7 @@ class MxFastOrganicLayout extends GraphLayout {
|
|||
}
|
||||
|
||||
this.graph.moveCells(this.vertexArray, dx, dy);
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -183,7 +183,6 @@ class HierarchicalLayout extends GraphLayout {
|
|||
*/
|
||||
execute(parent: Cell, roots: Cell[] | Cell | null = null): void {
|
||||
this.parent = parent;
|
||||
const { model } = this.graph;
|
||||
this.edgesCache = new Dictionary();
|
||||
this.edgeSourceTermCache = new Dictionary();
|
||||
this.edgesTargetTermCache = new Dictionary();
|
||||
|
@ -234,8 +233,8 @@ class HierarchicalLayout extends GraphLayout {
|
|||
this.roots = rootsCopy;
|
||||
}
|
||||
|
||||
model.beginUpdate();
|
||||
try {
|
||||
const { model } = this.graph;
|
||||
model.batchUpdate(() => {
|
||||
this.run(parent);
|
||||
|
||||
if (this.resizeParent && !parent.isCollapsed()) {
|
||||
|
@ -253,9 +252,7 @@ class HierarchicalLayout extends GraphLayout {
|
|||
model.setGeometry(parent, geo);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -361,8 +361,7 @@ class LayoutManager extends EventSource {
|
|||
// Invokes the layouts while removing duplicates
|
||||
const model = this.getGraph().getDataModel();
|
||||
|
||||
model.beginUpdate();
|
||||
try {
|
||||
model.batchUpdate(() => {
|
||||
let last = null;
|
||||
|
||||
for (const cell of cells) {
|
||||
|
@ -373,9 +372,7 @@ class LayoutManager extends EventSource {
|
|||
}
|
||||
|
||||
this.fireEvent(new EventObject(InternalEvent.LAYOUT_CELLS, { cells }));
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -86,8 +86,7 @@ class ParallelEdgeLayout extends GraphLayout {
|
|||
execute(parent: Cell, cells: Cell[] | null = null): void {
|
||||
const lookup = this.findParallels(parent, cells);
|
||||
|
||||
this.graph.model.beginUpdate();
|
||||
try {
|
||||
this.graph.batchUpdate(() => {
|
||||
for (const i in lookup) {
|
||||
const parallels = lookup[i];
|
||||
|
||||
|
@ -95,9 +94,7 @@ class ParallelEdgeLayout extends GraphLayout {
|
|||
this.layout(parallels);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this.graph.model.endUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -207,18 +207,13 @@ class SwimlaneManager extends EventSource {
|
|||
*/
|
||||
cellsAdded(cells: Cell[]) {
|
||||
if (cells.length > 0) {
|
||||
const model = this.graph.getDataModel();
|
||||
|
||||
model.beginUpdate();
|
||||
try {
|
||||
this.graph.batchUpdate(() => {
|
||||
for (const cell of cells) {
|
||||
if (!this.isSwimlaneIgnored(cell)) {
|
||||
this.swimlaneAdded(cell);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,10 +255,7 @@ class SwimlaneManager extends EventSource {
|
|||
*/
|
||||
cellsResized(cells: Cell[]) {
|
||||
if (cells.length > 0) {
|
||||
const model = this.getGraph().getDataModel();
|
||||
|
||||
model.beginUpdate();
|
||||
try {
|
||||
this.graph.batchUpdate(() => {
|
||||
// Finds the top-level swimlanes and adds offsets
|
||||
for (const cell of cells) {
|
||||
if (!this.isSwimlaneIgnored(cell)) {
|
||||
|
@ -291,9 +283,7 @@ class SwimlaneManager extends EventSource {
|
|||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,8 +297,7 @@ class SwimlaneManager extends EventSource {
|
|||
resizeSwimlane(swimlane: Cell, w: number, h: number, parentHorizontal: boolean) {
|
||||
const model = this.graph.getDataModel();
|
||||
|
||||
model.beginUpdate();
|
||||
try {
|
||||
model.batchUpdate(() => {
|
||||
const horizontal = this.isCellHorizontal(swimlane);
|
||||
|
||||
if (!this.isSwimlaneIgnored(swimlane)) {
|
||||
|
@ -344,9 +333,7 @@ class SwimlaneManager extends EventSource {
|
|||
const child = swimlane.getChildAt(i);
|
||||
this.resizeSwimlane(child, w, h, horizontal);
|
||||
}
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue