commit
02ea6f1ceb
|
@ -25,7 +25,6 @@ import { getClientX, getClientY } from '../util/EventUtils';
|
||||||
import { makeDraggable } from '../util/gestureUtils';
|
import { makeDraggable } from '../util/gestureUtils';
|
||||||
import Editor from './Editor';
|
import Editor from './Editor';
|
||||||
import Cell from '../view/cell/Cell';
|
import Cell from '../view/cell/Cell';
|
||||||
import CellArray from '../view/cell/CellArray';
|
|
||||||
import { Graph } from '../view/Graph';
|
import { Graph } from '../view/Graph';
|
||||||
import EventObject from '../view/event/EventObject';
|
import EventObject from '../view/event/EventObject';
|
||||||
import ObjectCodec from '../serialization/ObjectCodec';
|
import ObjectCodec from '../serialization/ObjectCodec';
|
||||||
|
@ -62,7 +61,7 @@ import type { DropHandler } from '../view/other/DragSource';
|
||||||
* description of the configuration format.
|
* description of the configuration format.
|
||||||
*/
|
*/
|
||||||
export class EditorToolbar {
|
export class EditorToolbar {
|
||||||
constructor(container: HTMLElement | null=null, editor: Editor | null=null) {
|
constructor(container: HTMLElement | null = null, editor: Editor | null = null) {
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
|
|
||||||
if (container != null && editor != null) {
|
if (container != null && editor != null) {
|
||||||
|
@ -108,7 +107,9 @@ export class EditorToolbar {
|
||||||
|
|
||||||
// Installs the insert function in the editor if an item is
|
// Installs the insert function in the editor if an item is
|
||||||
// selected in the toolbar
|
// selected in the toolbar
|
||||||
this.toolbar.addListener(InternalEvent.SELECT, (sender: Element, evt: EventObject) => {
|
this.toolbar.addListener(
|
||||||
|
InternalEvent.SELECT,
|
||||||
|
(sender: Element, evt: EventObject) => {
|
||||||
const funct = evt.getProperty('function');
|
const funct = evt.getProperty('function');
|
||||||
|
|
||||||
if (funct != null) {
|
if (funct != null) {
|
||||||
|
@ -119,7 +120,8 @@ export class EditorToolbar {
|
||||||
} else {
|
} else {
|
||||||
(<Editor>this.editor).insertFunction = null;
|
(<Editor>this.editor).insertFunction = null;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Resets the selected tool after a doubleclick or escape keystroke
|
// Resets the selected tool after a doubleclick or escape keystroke
|
||||||
this.resetHandler = () => {
|
this.resetHandler = () => {
|
||||||
|
@ -128,7 +130,10 @@ export class EditorToolbar {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
(<Editor>this.editor).graph.addListener(InternalEvent.DOUBLE_CLICK, this.resetHandler);
|
(<Editor>this.editor).graph.addListener(
|
||||||
|
InternalEvent.DOUBLE_CLICK,
|
||||||
|
this.resetHandler
|
||||||
|
);
|
||||||
(<Editor>this.editor).addListener(InternalEvent.ESCAPE, this.resetHandler);
|
(<Editor>this.editor).addListener(InternalEvent.ESCAPE, this.resetHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,7 +205,11 @@ export class EditorToolbar {
|
||||||
* @param title - String that represents the title of the combo.
|
* @param title - String that represents the title of the combo.
|
||||||
* @param value - Object that represents the value of the option.
|
* @param value - Object that represents the value of the option.
|
||||||
*/
|
*/
|
||||||
addOption(combo: HTMLSelectElement, title: string, value: string | ((evt: any) => void) | null): HTMLElement {
|
addOption(
|
||||||
|
combo: HTMLSelectElement,
|
||||||
|
title: string,
|
||||||
|
value: string | ((evt: any) => void) | null
|
||||||
|
): HTMLElement {
|
||||||
return (<MaxToolbar>this.toolbar).addOption(combo, title, value);
|
return (<MaxToolbar>this.toolbar).addOption(combo, title, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,14 +227,14 @@ export class EditorToolbar {
|
||||||
title: string,
|
title: string,
|
||||||
icon: string,
|
icon: string,
|
||||||
mode: string,
|
mode: string,
|
||||||
pressed: string | null=null,
|
pressed: string | null = null,
|
||||||
funct: Function | null=null
|
funct: Function | null = null
|
||||||
): any {
|
): any {
|
||||||
const clickHandler = () => {
|
const clickHandler = () => {
|
||||||
(<Editor>this.editor).setMode(mode);
|
(<Editor>this.editor).setMode(mode);
|
||||||
|
|
||||||
if (funct != null) {
|
if (funct != null) {
|
||||||
funct((<Editor>this.editor));
|
funct(<Editor>this.editor);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return (<MaxToolbar>this.toolbar).addSwitchMode(title, icon, clickHandler, pressed);
|
return (<MaxToolbar>this.toolbar).addSwitchMode(title, icon, clickHandler, pressed);
|
||||||
|
@ -253,8 +262,13 @@ export class EditorToolbar {
|
||||||
icon: string,
|
icon: string,
|
||||||
ptype: Function | Cell,
|
ptype: Function | Cell,
|
||||||
pressed: string,
|
pressed: string,
|
||||||
insert: (editor: Editor, cell: Cell, me: MouseEvent, cellUnderMousePointer?: Cell | null) => void,
|
insert: (
|
||||||
toggle: boolean=true
|
editor: Editor,
|
||||||
|
cell: Cell,
|
||||||
|
me: MouseEvent,
|
||||||
|
cellUnderMousePointer?: Cell | null
|
||||||
|
) => void,
|
||||||
|
toggle: boolean = true
|
||||||
): HTMLImageElement | HTMLButtonElement {
|
): HTMLImageElement | HTMLButtonElement {
|
||||||
// Creates a wrapper function that is in charge of constructing
|
// Creates a wrapper function that is in charge of constructing
|
||||||
// the new cell instance to be inserted into the graph
|
// the new cell instance to be inserted into the graph
|
||||||
|
@ -272,7 +286,7 @@ export class EditorToolbar {
|
||||||
// after this item has been selected in the toolbar
|
// after this item has been selected in the toolbar
|
||||||
const clickHandler = (evt: MouseEvent, cell: Cell | null) => {
|
const clickHandler = (evt: MouseEvent, cell: Cell | null) => {
|
||||||
if (typeof insert === 'function') {
|
if (typeof insert === 'function') {
|
||||||
insert((<Editor>this.editor), factory(), evt, cell);
|
insert(<Editor>this.editor, factory(), evt, cell);
|
||||||
} else {
|
} else {
|
||||||
this.drop(factory(), evt, cell);
|
this.drop(factory(), evt, cell);
|
||||||
}
|
}
|
||||||
|
@ -281,11 +295,22 @@ export class EditorToolbar {
|
||||||
InternalEvent.consume(evt);
|
InternalEvent.consume(evt);
|
||||||
};
|
};
|
||||||
|
|
||||||
const img = (<MaxToolbar>this.toolbar).addMode(title, icon, clickHandler, pressed, null, toggle);
|
const img = (<MaxToolbar>this.toolbar).addMode(
|
||||||
|
title,
|
||||||
|
icon,
|
||||||
|
clickHandler,
|
||||||
|
pressed,
|
||||||
|
null,
|
||||||
|
toggle
|
||||||
|
);
|
||||||
|
|
||||||
// Creates a wrapper function that calls the click handler without
|
// Creates a wrapper function that calls the click handler without
|
||||||
// the graph argument
|
// the graph argument
|
||||||
const dropHandler: DropHandler = (graph: Graph, evt: MouseEvent, cell: Cell | null) => {
|
const dropHandler: DropHandler = (
|
||||||
|
graph: Graph,
|
||||||
|
evt: MouseEvent,
|
||||||
|
cell: Cell | null
|
||||||
|
) => {
|
||||||
clickHandler(evt, cell);
|
clickHandler(evt, cell);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -302,8 +327,8 @@ export class EditorToolbar {
|
||||||
* @param evt - Mouse event that represents the drop.
|
* @param evt - Mouse event that represents the drop.
|
||||||
* @param target - Optional {@link Cell} that represents the drop target.
|
* @param target - Optional {@link Cell} that represents the drop target.
|
||||||
*/
|
*/
|
||||||
drop(vertex: Cell, evt: MouseEvent, target: Cell | null=null): void {
|
drop(vertex: Cell, evt: MouseEvent, target: Cell | null = null): void {
|
||||||
const { graph } = (<Editor>this.editor);
|
const { graph } = <Editor>this.editor;
|
||||||
const model = graph.getDataModel();
|
const model = graph.getDataModel();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -312,7 +337,7 @@ export class EditorToolbar {
|
||||||
!this.connectOnDrop ||
|
!this.connectOnDrop ||
|
||||||
!target.isConnectable()
|
!target.isConnectable()
|
||||||
) {
|
) {
|
||||||
while (target != null && !graph.isValidDropTarget(target, new CellArray(vertex), evt)) {
|
while (target != null && !graph.isValidDropTarget(target, [vertex], evt)) {
|
||||||
target = target.getParent();
|
target = target.getParent();
|
||||||
}
|
}
|
||||||
this.insert(vertex, evt, target);
|
this.insert(vertex, evt, target);
|
||||||
|
@ -329,8 +354,8 @@ export class EditorToolbar {
|
||||||
* @param evt - Mouse event that represents the drop.
|
* @param evt - Mouse event that represents the drop.
|
||||||
* @param target - Optional {@link Cell} that represents the parent.
|
* @param target - Optional {@link Cell} that represents the parent.
|
||||||
*/
|
*/
|
||||||
insert(vertex: Cell, evt: MouseEvent, target: Cell | null=null): any {
|
insert(vertex: Cell, evt: MouseEvent, target: Cell | null = null): any {
|
||||||
const { graph } = (<Editor>this.editor);
|
const { graph } = <Editor>this.editor;
|
||||||
|
|
||||||
if (graph.canImportCell(vertex)) {
|
if (graph.canImportCell(vertex)) {
|
||||||
const x = getClientX(evt);
|
const x = getClientX(evt);
|
||||||
|
@ -338,8 +363,12 @@ export class EditorToolbar {
|
||||||
const pt = convertPoint(graph.container, x, y);
|
const pt = convertPoint(graph.container, x, y);
|
||||||
|
|
||||||
// Splits the target edge or inserts into target group
|
// Splits the target edge or inserts into target group
|
||||||
if (target && graph.isSplitEnabled() && graph.isSplitTarget(target, new CellArray(vertex), evt)) {
|
if (
|
||||||
return graph.splitEdge(target, new CellArray(vertex), null, pt.x, pt.y);
|
target &&
|
||||||
|
graph.isSplitEnabled() &&
|
||||||
|
graph.isSplitTarget(target, [vertex], evt)
|
||||||
|
) {
|
||||||
|
return graph.splitEdge(target, [vertex], null, pt.x, pt.y);
|
||||||
}
|
}
|
||||||
return (<Editor>this.editor).addVertex(target, vertex, pt.x, pt.y);
|
return (<Editor>this.editor).addVertex(target, vertex, pt.x, pt.y);
|
||||||
}
|
}
|
||||||
|
@ -353,7 +382,7 @@ export class EditorToolbar {
|
||||||
* @param evt - Mouse event that represents the drop.
|
* @param evt - Mouse event that represents the drop.
|
||||||
* @param source - Optional {@link Cell} that represents the source terminal.
|
* @param source - Optional {@link Cell} that represents the source terminal.
|
||||||
*/
|
*/
|
||||||
connect(vertex: Cell, evt: MouseEvent, source: Cell | null=null): void {
|
connect(vertex: Cell, evt: MouseEvent, source: Cell | null = null): void {
|
||||||
const { graph } = <Editor>this.editor;
|
const { graph } = <Editor>this.editor;
|
||||||
const model = graph.getDataModel();
|
const model = graph.getDataModel();
|
||||||
|
|
||||||
|
@ -407,7 +436,7 @@ export class EditorToolbar {
|
||||||
model.endUpdate();
|
model.endUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
graph.setSelectionCells(new CellArray(vertex, edge));
|
graph.setSelectionCells([vertex, edge]);
|
||||||
graph.scrollCellToVisible(vertex);
|
graph.scrollCellToVisible(vertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -586,21 +615,16 @@ export class EditorToolbarCodec extends ObjectCodec {
|
||||||
const mode = node.getAttribute('mode');
|
const mode = node.getAttribute('mode');
|
||||||
const template = node.getAttribute('template');
|
const template = node.getAttribute('template');
|
||||||
const toggle = node.getAttribute('toggle') != '0';
|
const toggle = node.getAttribute('toggle') != '0';
|
||||||
const text = getTextContent(<Text><unknown>node);
|
const text = getTextContent(<Text>(<unknown>node));
|
||||||
let elt = null;
|
let elt = null;
|
||||||
let funct: any;
|
let funct: any;
|
||||||
|
|
||||||
if (action != null) {
|
if (action != null) {
|
||||||
elt = into.addItem(as, icon, action, pressedIcon);
|
elt = into.addItem(as, icon, action, pressedIcon);
|
||||||
} else if (mode != null) {
|
} else if (mode != null) {
|
||||||
funct = EditorToolbarCodec.allowEval
|
funct = EditorToolbarCodec.allowEval ? eval(text) : null;
|
||||||
? eval(text)
|
|
||||||
: null;
|
|
||||||
elt = into.addMode(as, icon, mode, pressedIcon, funct);
|
elt = into.addMode(as, icon, mode, pressedIcon, funct);
|
||||||
} else if (
|
} else if (template != null || (text != null && text.length > 0)) {
|
||||||
template != null ||
|
|
||||||
(text != null && text.length > 0)
|
|
||||||
) {
|
|
||||||
let cell = template ? editor.templates[template] : null;
|
let cell = template ? editor.templates[template] : null;
|
||||||
const style = node.getAttribute('style');
|
const style = node.getAttribute('style');
|
||||||
|
|
||||||
|
@ -611,11 +635,7 @@ export class EditorToolbarCodec extends ObjectCodec {
|
||||||
|
|
||||||
let insertFunction = null;
|
let insertFunction = null;
|
||||||
|
|
||||||
if (
|
if (text != null && text.length > 0 && EditorToolbarCodec.allowEval) {
|
||||||
text != null &&
|
|
||||||
text.length > 0 &&
|
|
||||||
EditorToolbarCodec.allowEval
|
|
||||||
) {
|
|
||||||
insertFunction = eval(text);
|
insertFunction = eval(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,14 +687,7 @@ export class EditorToolbarCodec extends ObjectCodec {
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const img = into.addPrototype(
|
const img = into.addPrototype(as, icon, create, null, null, toggle);
|
||||||
as,
|
|
||||||
icon,
|
|
||||||
create,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
toggle
|
|
||||||
);
|
|
||||||
select = into.addCombo();
|
select = into.addCombo();
|
||||||
|
|
||||||
// Selects the toolbar icon if a selection change
|
// Selects the toolbar icon if a selection change
|
||||||
|
@ -702,11 +715,7 @@ export class EditorToolbarCodec extends ObjectCodec {
|
||||||
} else if (child.nodeName === 'add') {
|
} else if (child.nodeName === 'add') {
|
||||||
const lab = child.getAttribute('as');
|
const lab = child.getAttribute('as');
|
||||||
const tmp = child.getAttribute('template');
|
const tmp = child.getAttribute('template');
|
||||||
const option = into.addOption(
|
const option = into.addOption(select, lab, tmp || template);
|
||||||
select,
|
|
||||||
lab,
|
|
||||||
tmp || template
|
|
||||||
);
|
|
||||||
option.cellStyle = child.getAttribute('style');
|
option.cellStyle = child.getAttribute('style');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,10 @@ export { default as GeometryChange } from './view/undoable_changes/GeometryChang
|
||||||
export { RootChange, RootChangeCodec } from './view/undoable_changes/RootChange';
|
export { RootChange, RootChangeCodec } from './view/undoable_changes/RootChange';
|
||||||
export { default as SelectionChange } from './view/undoable_changes/SelectionChange';
|
export { default as SelectionChange } from './view/undoable_changes/SelectionChange';
|
||||||
export { default as StyleChange } from './view/undoable_changes/StyleChange';
|
export { default as StyleChange } from './view/undoable_changes/StyleChange';
|
||||||
export { TerminalChange, TerminalChangeCodec } from './view/undoable_changes/TerminalChange';
|
export {
|
||||||
|
TerminalChange,
|
||||||
|
TerminalChangeCodec,
|
||||||
|
} from './view/undoable_changes/TerminalChange';
|
||||||
export { default as ValueChange } from './view/undoable_changes/ValueChange';
|
export { default as ValueChange } from './view/undoable_changes/ValueChange';
|
||||||
export { default as VisibleChange } from './view/undoable_changes/VisibleChange';
|
export { default as VisibleChange } from './view/undoable_changes/VisibleChange';
|
||||||
|
|
||||||
|
@ -158,6 +161,7 @@ export * as stringUtils from './util/StringUtils';
|
||||||
export * as xmlUtils from './util/xmlUtils';
|
export * as xmlUtils from './util/xmlUtils';
|
||||||
export * as styleUtils from './util/styleUtils';
|
export * as styleUtils from './util/styleUtils';
|
||||||
export * as mathUtils from './util/mathUtils';
|
export * as mathUtils from './util/mathUtils';
|
||||||
|
export * as cellArrayUtils from './util/cellArrayUtils';
|
||||||
|
|
||||||
export { default as Animation } from './view/animate/Animation';
|
export { default as Animation } from './view/animate/Animation';
|
||||||
export { default as Effects } from './view/animate/Effects';
|
export { default as Effects } from './view/animate/Effects';
|
||||||
|
@ -220,7 +224,6 @@ export { default as CellPath } from './view/cell/CellPath';
|
||||||
export { default as CellRenderer } from './view/cell/CellRenderer';
|
export { default as CellRenderer } from './view/cell/CellRenderer';
|
||||||
export { default as CellState } from './view/cell/CellState';
|
export { default as CellState } from './view/cell/CellState';
|
||||||
export { default as CellStatePreview } from './view/cell/CellStatePreview';
|
export { default as CellStatePreview } from './view/cell/CellStatePreview';
|
||||||
export { default as CellArray } from './view/cell/CellArray';
|
|
||||||
export { default as TemporaryCellStates } from './view/cell/TemporaryCellStates';
|
export { default as TemporaryCellStates } from './view/cell/TemporaryCellStates';
|
||||||
export { default as ConnectionConstraint } from './view/other/ConnectionConstraint';
|
export { default as ConnectionConstraint } from './view/other/ConnectionConstraint';
|
||||||
export { default as Multiplicity } from './view/other/Multiplicity';
|
export { default as Multiplicity } from './view/other/Multiplicity';
|
||||||
|
|
|
@ -16,8 +16,9 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import Cell from '../view/cell/Cell';
|
||||||
import { Graph } from '../view/Graph';
|
import { Graph } from '../view/Graph';
|
||||||
import CellArray from '../view/cell/CellArray';
|
import { getTopmostCells } from './cellArrayUtils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class
|
* @class
|
||||||
|
@ -104,12 +105,12 @@ class Clipboard {
|
||||||
/**
|
/**
|
||||||
* Holds the array of {@link mxCell} currently in the clipboard.
|
* Holds the array of {@link mxCell} currently in the clipboard.
|
||||||
*/
|
*/
|
||||||
static cells: CellArray;
|
static cells: Cell[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the cells in the clipboard. Fires a {@link mxEvent.CHANGE} event.
|
* Sets the cells in the clipboard. Fires a {@link mxEvent.CHANGE} event.
|
||||||
*/
|
*/
|
||||||
static setCells(cells: CellArray) {
|
static setCells(cells: Cell[]) {
|
||||||
Clipboard.cells = cells;
|
Clipboard.cells = cells;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +136,7 @@ class Clipboard {
|
||||||
* @param graph - {@link graph} that contains the cells to be cut.
|
* @param graph - {@link graph} that contains the cells to be cut.
|
||||||
* @param cells - Optional array of {@link mxCell} to be cut.
|
* @param cells - Optional array of {@link mxCell} to be cut.
|
||||||
*/
|
*/
|
||||||
static cut(graph: Graph, cells?: CellArray) {
|
static cut(graph: Graph, cells: Cell[] = []) {
|
||||||
cells = Clipboard.copy(graph, cells);
|
cells = Clipboard.copy(graph, cells);
|
||||||
Clipboard.insertCount = 0;
|
Clipboard.insertCount = 0;
|
||||||
Clipboard.removeCells(graph, cells);
|
Clipboard.removeCells(graph, cells);
|
||||||
|
@ -150,8 +151,7 @@ class Clipboard {
|
||||||
* @param graph - {@link graph} that contains the cells to be cut.
|
* @param graph - {@link graph} that contains the cells to be cut.
|
||||||
* @param cells - Array of {@link mxCell} to be cut.
|
* @param cells - Array of {@link mxCell} to be cut.
|
||||||
*/
|
*/
|
||||||
static removeCells(graph: Graph, cells: CellArray) {
|
static removeCells(graph: Graph, cells: Cell[]) {
|
||||||
// @ts-ignore
|
|
||||||
graph.removeCells(cells);
|
graph.removeCells(cells);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,11 +163,11 @@ class Clipboard {
|
||||||
* @param graph - {@link graph} that contains the cells to be copied.
|
* @param graph - {@link graph} that contains the cells to be copied.
|
||||||
* @param cells - Optional array of {@link mxCell} to be copied.
|
* @param cells - Optional array of {@link mxCell} to be copied.
|
||||||
*/
|
*/
|
||||||
static copy(graph: Graph, cells?: CellArray) {
|
static copy(graph: Graph, cells?: Cell[]) {
|
||||||
cells = cells || graph.getSelectionCells();
|
cells = cells || graph.getSelectionCells();
|
||||||
const result = graph.getExportableCells(cells).getTopmostCells();
|
const result = getTopmostCells(graph.getExportableCells(cells));
|
||||||
Clipboard.insertCount = 1;
|
Clipboard.insertCount = 1;
|
||||||
// @ts-ignore
|
|
||||||
Clipboard.setCells(graph.cloneCells(result));
|
Clipboard.setCells(graph.cloneCells(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -190,12 +190,12 @@ class Clipboard {
|
||||||
cells = graph.getImportableCells(Clipboard.getCells());
|
cells = graph.getImportableCells(Clipboard.getCells());
|
||||||
const delta = Clipboard.insertCount * Clipboard.STEPSIZE;
|
const delta = Clipboard.insertCount * Clipboard.STEPSIZE;
|
||||||
const parent = graph.getDefaultParent();
|
const parent = graph.getDefaultParent();
|
||||||
// @ts-ignore
|
|
||||||
cells = graph.importCells(cells, delta, delta, parent);
|
cells = graph.importCells(cells, delta, delta, parent);
|
||||||
|
|
||||||
// Increments the counter and selects the inserted cells
|
// Increments the counter and selects the inserted cells
|
||||||
Clipboard.insertCount++;
|
Clipboard.insertCount++;
|
||||||
graph.setSelectionCells(<CellArray>cells);
|
graph.setSelectionCells(cells);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cells;
|
return cells;
|
||||||
|
|
|
@ -0,0 +1,198 @@
|
||||||
|
import Cell from '../view/cell/Cell';
|
||||||
|
import Dictionary from './Dictionary';
|
||||||
|
import ObjectIdentity from './ObjectIdentity';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the cells from the given array where the given filter function
|
||||||
|
* returns true.
|
||||||
|
*/
|
||||||
|
export const filterCells = (filter: Function) => (cells: Cell[]) => {
|
||||||
|
let result = [] as Cell[];
|
||||||
|
|
||||||
|
for (let i = 0; i < cells.length; i += 1) {
|
||||||
|
if (filter(cells[i])) {
|
||||||
|
result.push(cells[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all opposite vertices wrt terminal for the given edges, only
|
||||||
|
* returning sources and/or targets as specified. The result is returned
|
||||||
|
* as an array of {@link Cell}.
|
||||||
|
*
|
||||||
|
* @param {Cell} terminal that specifies the known end of the edges.
|
||||||
|
* @param sources Boolean that specifies if source terminals should be contained
|
||||||
|
* in the result. Default is true.
|
||||||
|
* @param targets Boolean that specifies if target terminals should be contained
|
||||||
|
* in the result. Default is true.
|
||||||
|
*/
|
||||||
|
export const getOpposites =
|
||||||
|
(terminal: Cell, sources: boolean = true, targets: boolean = true) =>
|
||||||
|
(edges: Cell[]) => {
|
||||||
|
const terminals = [] as Cell[];
|
||||||
|
|
||||||
|
for (let i = 0; i < edges.length; i += 1) {
|
||||||
|
const source = edges[i].getTerminal(true);
|
||||||
|
const target = edges[i].getTerminal(false);
|
||||||
|
|
||||||
|
// Checks if the terminal is the source of
|
||||||
|
// the edge and if the target should be
|
||||||
|
// stored in the result
|
||||||
|
if (source === terminal && target != null && target !== terminal && targets) {
|
||||||
|
terminals.push(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the terminal is the taget of
|
||||||
|
// the edge and if the source should be
|
||||||
|
// stored in the result
|
||||||
|
else if (target === terminal && source != null && source !== terminal && sources) {
|
||||||
|
terminals.push(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return terminals;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the topmost cells of the hierarchy in an array that contains no
|
||||||
|
* descendants for each {@link Cell} that it contains. Duplicates should be
|
||||||
|
* removed in the cells array to improve performance.
|
||||||
|
*/
|
||||||
|
export const getTopmostCells = (cells: Cell[]) => {
|
||||||
|
const dict = new Dictionary();
|
||||||
|
const tmp = [] as Cell[];
|
||||||
|
|
||||||
|
for (let i = 0; i < cells.length; i += 1) {
|
||||||
|
dict.put(cells[i], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < cells.length; i += 1) {
|
||||||
|
const cell = cells[i];
|
||||||
|
let topmost = true;
|
||||||
|
let parent = cell.getParent();
|
||||||
|
|
||||||
|
while (parent != null) {
|
||||||
|
if (dict.get(parent)) {
|
||||||
|
topmost = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parent = parent.getParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (topmost) {
|
||||||
|
tmp.push(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array that represents the set (no duplicates) of all parents
|
||||||
|
* for the given array of cells.
|
||||||
|
*/
|
||||||
|
export const getParents = (cells: Cell[]) => {
|
||||||
|
const parents = [];
|
||||||
|
const dict = new Dictionary();
|
||||||
|
|
||||||
|
for (const cell of cells) {
|
||||||
|
const parent = cell.getParent();
|
||||||
|
if (parent != null && !dict.get(parent)) {
|
||||||
|
dict.put(parent, true);
|
||||||
|
parents.push(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parents;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of clones for the given array of {@link Cell}`.
|
||||||
|
* Depending on the value of includeChildren, a deep clone is created for
|
||||||
|
* each cell. Connections are restored based if the corresponding
|
||||||
|
* cell is contained in the passed in array.
|
||||||
|
*
|
||||||
|
* @param includeChildren Boolean indicating if the cells should be cloned
|
||||||
|
* with all descendants.
|
||||||
|
* @param mapping Optional mapping for existing clones.
|
||||||
|
*/
|
||||||
|
export const cloneCells =
|
||||||
|
(includeChildren = true, mapping: any = {}) =>
|
||||||
|
(cells: Cell[]) => {
|
||||||
|
const clones = [] as Cell[];
|
||||||
|
|
||||||
|
for (const cell of cells) {
|
||||||
|
clones.push(cloneCellImpl(cell, mapping, includeChildren));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < clones.length; i += 1) {
|
||||||
|
if (clones[i] != null) {
|
||||||
|
restoreClone(<Cell>clones[i], cells[i], mapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return clones;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inner helper method for cloning cells recursively.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
const cloneCellImpl = (
|
||||||
|
cell: Cell,
|
||||||
|
mapping: any = {},
|
||||||
|
includeChildren: boolean = false
|
||||||
|
): Cell => {
|
||||||
|
const ident = <string>ObjectIdentity.get(cell);
|
||||||
|
let clone = mapping ? mapping[ident] : null;
|
||||||
|
|
||||||
|
if (clone == null) {
|
||||||
|
clone = cell.clone();
|
||||||
|
mapping[ident] = clone;
|
||||||
|
|
||||||
|
if (includeChildren) {
|
||||||
|
const childCount = cell.getChildCount();
|
||||||
|
|
||||||
|
for (let i = 0; i < childCount; i += 1) {
|
||||||
|
const cloneChild = cloneCellImpl(<Cell>cell.getChildAt(i), mapping, true);
|
||||||
|
clone.insert(cloneChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clone;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inner helper method for restoring the connections in
|
||||||
|
* a network of cloned cells.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
export const restoreClone =
|
||||||
|
(clone: Cell, cell: Cell, mapping: any) => (cells: Cell[]) => {
|
||||||
|
const source = cell.getTerminal(true);
|
||||||
|
|
||||||
|
if (source != null) {
|
||||||
|
const tmp = mapping[<string>ObjectIdentity.get(source)];
|
||||||
|
if (tmp != null) {
|
||||||
|
tmp.insertEdge(clone, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const target = cell.getTerminal(false);
|
||||||
|
if (target != null) {
|
||||||
|
const tmp = mapping[<string>ObjectIdentity.get(target)];
|
||||||
|
if (tmp != null) {
|
||||||
|
tmp.insertEdge(clone, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const childCount = clone.getChildCount();
|
||||||
|
for (let i = 0; i < childCount; i += 1) {
|
||||||
|
restoreClone(<Cell>clone.getChildAt(i), <Cell>cell.getChildAt(i), mapping);
|
||||||
|
}
|
||||||
|
};
|
|
@ -30,7 +30,7 @@ import CellPath from '../view/cell/CellPath';
|
||||||
import Rectangle from '../view/geometry/Rectangle';
|
import Rectangle from '../view/geometry/Rectangle';
|
||||||
import Cell from '../view/cell/Cell';
|
import Cell from '../view/cell/Cell';
|
||||||
import GraphDataModel from '../view/GraphDataModel';
|
import GraphDataModel from '../view/GraphDataModel';
|
||||||
import CellArray from '../view/cell/CellArray';
|
|
||||||
import type { CellStateStyle, CellStyle, NumericCellStateStyleKeys } from '../types';
|
import type { CellStateStyle, CellStyle, NumericCellStateStyleKeys } from '../types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -438,7 +438,7 @@ export const removeAllStylenames = (style: string) => {
|
||||||
*/
|
*/
|
||||||
export const setCellStyles = (
|
export const setCellStyles = (
|
||||||
model: GraphDataModel,
|
model: GraphDataModel,
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
key: keyof CellStateStyle,
|
key: keyof CellStateStyle,
|
||||||
value: any
|
value: any
|
||||||
) => {
|
) => {
|
||||||
|
@ -534,7 +534,7 @@ export const setStyle = (style: string | null, key: string, value: any) => {
|
||||||
*/
|
*/
|
||||||
export const setCellStyleFlags = (
|
export const setCellStyleFlags = (
|
||||||
model: GraphDataModel,
|
model: GraphDataModel,
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
key: NumericCellStateStyleKeys,
|
key: NumericCellStateStyleKeys,
|
||||||
flag: number,
|
flag: number,
|
||||||
value: boolean
|
value: boolean
|
||||||
|
@ -685,7 +685,7 @@ export const getSizeForString = (
|
||||||
* Sorts the given cells according to the order in the cell hierarchy.
|
* Sorts the given cells according to the order in the cell hierarchy.
|
||||||
* Ascending is optional and defaults to true.
|
* Ascending is optional and defaults to true.
|
||||||
*/
|
*/
|
||||||
export const sortCells = (cells: CellArray, ascending = true): CellArray => {
|
export const sortCells = (cells: Cell[], ascending = true): Cell[] => {
|
||||||
const lookup = new Dictionary<Cell, string[]>();
|
const lookup = new Dictionary<Cell, string[]>();
|
||||||
|
|
||||||
cells.sort((o1, o2) => {
|
cells.sort((o1, o2) => {
|
||||||
|
|
|
@ -15,7 +15,6 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Cell from '../view/cell/Cell';
|
import Cell from '../view/cell/Cell';
|
||||||
import CellArray from '../view/cell/CellArray';
|
|
||||||
import Dictionary from './Dictionary';
|
import Dictionary from './Dictionary';
|
||||||
import { Graph } from '../view/Graph';
|
import { Graph } from '../view/Graph';
|
||||||
|
|
||||||
|
@ -42,7 +41,7 @@ export function findTreeRoots(
|
||||||
isolate: boolean = false,
|
isolate: boolean = false,
|
||||||
invert: boolean = false
|
invert: boolean = false
|
||||||
) {
|
) {
|
||||||
const roots: CellArray = new CellArray();
|
const roots: Cell[] = [];
|
||||||
|
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
let best = null;
|
let best = null;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright 2021-present The maxGraph project Contributors
|
Copyright 2021-present The maxGraph project Contributors
|
||||||
Copyright (c) 2006-2015, JGraph Ltd
|
Copyright (c) 2006-2015, JGraph Ltd
|
||||||
|
@ -20,7 +19,6 @@ limitations under the License.
|
||||||
import { DIALECT, NODETYPE, NS_SVG } from './Constants';
|
import { DIALECT, NODETYPE, NS_SVG } from './Constants';
|
||||||
import Point from '../view/geometry/Point';
|
import Point from '../view/geometry/Point';
|
||||||
import Cell from '../view/cell/Cell';
|
import Cell from '../view/cell/Cell';
|
||||||
import CellArray from '../view/cell/CellArray';
|
|
||||||
import { Graph } from '../view/Graph';
|
import { Graph } from '../view/Graph';
|
||||||
import { htmlEntities, trim } from './StringUtils';
|
import { htmlEntities, trim } from './StringUtils';
|
||||||
import TemporaryCellStates from '../view/cell/TemporaryCellStates';
|
import TemporaryCellStates from '../view/cell/TemporaryCellStates';
|
||||||
|
@ -38,19 +36,18 @@ export const createXmlDocument = () => {
|
||||||
|
|
||||||
export const parseXml = (xmlString: string): HTMLElement => {
|
export const parseXml = (xmlString: string): HTMLElement => {
|
||||||
return new DOMParser().parseFromString(xmlString, 'text/xml').documentElement;
|
return new DOMParser().parseFromString(xmlString, 'text/xml').documentElement;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getViewXml = (
|
export const getViewXml = (
|
||||||
graph: Graph,
|
graph: Graph,
|
||||||
scale: number=1,
|
scale: number = 1,
|
||||||
cells: CellArray | null=null,
|
cells: Cell[] | null = null,
|
||||||
x0: number=0,
|
x0: number = 0,
|
||||||
y0: number=0
|
y0: number = 0
|
||||||
) => {
|
) => {
|
||||||
|
|
||||||
if (cells == null) {
|
if (cells == null) {
|
||||||
const model = graph.getDataModel();
|
const model = graph.getDataModel();
|
||||||
cells = new CellArray(<Cell>model.getRoot());
|
cells = [<Cell>model.getRoot()];
|
||||||
}
|
}
|
||||||
|
|
||||||
const view = graph.getView();
|
const view = graph.getView();
|
||||||
|
@ -114,7 +111,7 @@ export const getViewXml = (
|
||||||
* @param linefeed Optional string that linefeeds are converted into. Default is
|
* @param linefeed Optional string that linefeeds are converted into. Default is
|
||||||
* 

|
* 

|
||||||
*/
|
*/
|
||||||
export const getXml = (node: Element, linefeed: string='
'): string => {
|
export const getXml = (node: Element, linefeed: string = '
'): string => {
|
||||||
const xmlSerializer = new XMLSerializer();
|
const xmlSerializer = new XMLSerializer();
|
||||||
let xml = xmlSerializer.serializeToString(node);
|
let xml = xmlSerializer.serializeToString(node);
|
||||||
|
|
||||||
|
@ -136,7 +133,13 @@ export const getXml = (node: Element, linefeed: string='
'): string => {
|
||||||
* Default is an empty string.
|
* Default is an empty string.
|
||||||
* @param newline Option string that represents a linefeed. Default is '\n'.
|
* @param newline Option string that represents a linefeed. Default is '\n'.
|
||||||
*/
|
*/
|
||||||
export const getPrettyXml = (node: Element, tab: string, indent: string, newline: string, ns: string): string => {
|
export const getPrettyXml = (
|
||||||
|
node: Element,
|
||||||
|
tab: string,
|
||||||
|
indent: string,
|
||||||
|
newline: string,
|
||||||
|
ns: string
|
||||||
|
): string => {
|
||||||
const result = [];
|
const result = [];
|
||||||
|
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
|
@ -154,7 +157,13 @@ export const getPrettyXml = (node: Element, tab: string, indent: string, newline
|
||||||
|
|
||||||
if (node.nodeType === NODETYPE.DOCUMENT) {
|
if (node.nodeType === NODETYPE.DOCUMENT) {
|
||||||
result.push(
|
result.push(
|
||||||
getPrettyXml((<Document><unknown>node).documentElement, tab, indent, newline, ns)
|
getPrettyXml(
|
||||||
|
(<Document>(<unknown>node)).documentElement,
|
||||||
|
tab,
|
||||||
|
indent,
|
||||||
|
newline,
|
||||||
|
ns
|
||||||
|
)
|
||||||
);
|
);
|
||||||
} else if (node.nodeType === NODETYPE.DOCUMENT_FRAGMENT) {
|
} else if (node.nodeType === NODETYPE.DOCUMENT_FRAGMENT) {
|
||||||
let tmp = node.firstChild;
|
let tmp = node.firstChild;
|
||||||
|
@ -166,19 +175,19 @@ export const getPrettyXml = (node: Element, tab: string, indent: string, newline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (node.nodeType === NODETYPE.COMMENT) {
|
} else if (node.nodeType === NODETYPE.COMMENT) {
|
||||||
const value = getTextContent(<Text><unknown>node);
|
const value = getTextContent(<Text>(<unknown>node));
|
||||||
|
|
||||||
if (value.length > 0) {
|
if (value.length > 0) {
|
||||||
result.push(`${indent}<!--${value}-->${newline}`);
|
result.push(`${indent}<!--${value}-->${newline}`);
|
||||||
}
|
}
|
||||||
} else if (node.nodeType === NODETYPE.TEXT) {
|
} else if (node.nodeType === NODETYPE.TEXT) {
|
||||||
const value = trim(getTextContent(<Text><unknown>node));
|
const value = trim(getTextContent(<Text>(<unknown>node)));
|
||||||
|
|
||||||
if (value && value.length > 0) {
|
if (value && value.length > 0) {
|
||||||
result.push(indent + htmlEntities(value, false) + newline);
|
result.push(indent + htmlEntities(value, false) + newline);
|
||||||
}
|
}
|
||||||
} else if (node.nodeType === NODETYPE.CDATA) {
|
} else if (node.nodeType === NODETYPE.CDATA) {
|
||||||
const value = getTextContent(<Text><unknown>node);
|
const value = getTextContent(<Text>(<unknown>node));
|
||||||
|
|
||||||
if (value.length > 0) {
|
if (value.length > 0) {
|
||||||
result.push(`${indent}<![CDATA[${value}]]${newline}`);
|
result.push(`${indent}<![CDATA[${value}]]${newline}`);
|
||||||
|
@ -205,9 +214,7 @@ export const getPrettyXml = (node: Element, tab: string, indent: string, newline
|
||||||
result.push(`>${newline}`);
|
result.push(`>${newline}`);
|
||||||
|
|
||||||
while (tmp != null) {
|
while (tmp != null) {
|
||||||
result.push(
|
result.push(getPrettyXml(<Element>tmp, tab, indent + tab, newline, ns));
|
||||||
getPrettyXml(<Element>tmp, tab, indent + tab, newline, ns)
|
|
||||||
);
|
|
||||||
tmp = tmp.nextSibling;
|
tmp = tmp.nextSibling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +231,7 @@ export const getPrettyXml = (node: Element, tab: string, indent: string, newline
|
||||||
* Returns the first node where attr equals value.
|
* Returns the first node where attr equals value.
|
||||||
* This implementation does not use XPath.
|
* This implementation does not use XPath.
|
||||||
*/
|
*/
|
||||||
export const findNode = (
|
export const findNode = (
|
||||||
node: Element,
|
node: Element,
|
||||||
attr: string,
|
attr: string,
|
||||||
value: StyleValue
|
value: StyleValue
|
||||||
|
|
|
@ -57,7 +57,6 @@ import ObjectCodec from '../serialization/ObjectCodec';
|
||||||
|
|
||||||
import type { GraphPlugin, GraphPluginConstructor, MouseListenerSet } from '../types';
|
import type { GraphPlugin, GraphPluginConstructor, MouseListenerSet } from '../types';
|
||||||
import Multiplicity from './other/Multiplicity';
|
import Multiplicity from './other/Multiplicity';
|
||||||
import CellArray from './cell/CellArray';
|
|
||||||
import ImageBundle from './image/ImageBundle';
|
import ImageBundle from './image/ImageBundle';
|
||||||
import GraphSelectionModel from './GraphSelectionModel';
|
import GraphSelectionModel from './GraphSelectionModel';
|
||||||
|
|
||||||
|
@ -102,7 +101,7 @@ class Graph extends EventSource {
|
||||||
* Group: Variables (that maybe should be in the mixins, but need to be created for each new class instance)
|
* Group: Variables (that maybe should be in the mixins, but need to be created for each new class instance)
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
cells = new CellArray();
|
cells: Cell[] = [];
|
||||||
|
|
||||||
imageBundles: ImageBundle[] = [];
|
imageBundles: ImageBundle[] = [];
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,9 @@ import TerminalChange from './undoable_changes/TerminalChange';
|
||||||
import ValueChange from './undoable_changes/ValueChange';
|
import ValueChange from './undoable_changes/ValueChange';
|
||||||
import VisibleChange from './undoable_changes/VisibleChange';
|
import VisibleChange from './undoable_changes/VisibleChange';
|
||||||
import Geometry from './geometry/Geometry';
|
import Geometry from './geometry/Geometry';
|
||||||
import CellArray from './cell/CellArray';
|
|
||||||
import ObjectCodec from '../serialization/ObjectCodec';
|
import ObjectCodec from '../serialization/ObjectCodec';
|
||||||
import CodecRegistry from '../serialization/CodecRegistry';
|
import CodecRegistry from '../serialization/CodecRegistry';
|
||||||
|
import { cloneCells, filterCells } from '../util/cellArrayUtils';
|
||||||
|
|
||||||
import type { CellStyle, FilterFunction } from '../types';
|
import type { CellStyle, FilterFunction } from '../types';
|
||||||
|
|
||||||
|
@ -338,8 +338,8 @@ export class GraphDataModel extends EventSource {
|
||||||
return this.cells ? this.cells[id] : null;
|
return this.cells ? this.cells[id] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
filterCells(cells: CellArray, filter: FilterFunction) {
|
filterCells(cells: Cell[], filter: FilterFunction) {
|
||||||
return new CellArray(...cells).filterCells(filter);
|
return filterCells(filter)(cells);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRoot(cell: Cell | null = null) {
|
getRoot(cell: Cell | null = null) {
|
||||||
|
@ -759,7 +759,7 @@ export class GraphDataModel extends EventSource {
|
||||||
* @param directed Optional boolean that specifies if the direction of the
|
* @param directed Optional boolean that specifies if the direction of the
|
||||||
* edge should be taken into account. Default is false.
|
* edge should be taken into account. Default is false.
|
||||||
*/
|
*/
|
||||||
getEdgesBetween(source: Cell, target: Cell, directed: boolean = false): CellArray {
|
getEdgesBetween(source: Cell, target: Cell, directed: boolean = false): Cell[] {
|
||||||
const tmp1 = source.getEdgeCount();
|
const tmp1 = source.getEdgeCount();
|
||||||
const tmp2 = target.getEdgeCount();
|
const tmp2 = target.getEdgeCount();
|
||||||
|
|
||||||
|
@ -774,7 +774,7 @@ export class GraphDataModel extends EventSource {
|
||||||
terminal = target;
|
terminal = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = new CellArray();
|
const result = [];
|
||||||
|
|
||||||
// Checks if the edge is connected to the correct
|
// Checks if the edge is connected to the correct
|
||||||
// cell and returns the first match
|
// cell and returns the first match
|
||||||
|
@ -1169,7 +1169,7 @@ export class GraphDataModel extends EventSource {
|
||||||
*/
|
*/
|
||||||
cloneCell(cell: Cell | null = null, includeChildren: boolean = true): Cell | null {
|
cloneCell(cell: Cell | null = null, includeChildren: boolean = true): Cell | null {
|
||||||
if (cell != null) {
|
if (cell != null) {
|
||||||
return new CellArray(cell).cloneCells(includeChildren)[0];
|
return cloneCells(includeChildren)([cell])[0];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,15 +16,14 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Client from "../Client";
|
import Client from '../Client';
|
||||||
import CellArray from "./cell/CellArray"
|
|
||||||
import EventSource from '../view/event/EventSource';
|
import EventSource from '../view/event/EventSource';
|
||||||
import { Graph } from "./Graph"
|
import { Graph } from './Graph';
|
||||||
import Cell from "./cell/Cell";
|
import Cell from './cell/Cell';
|
||||||
import SelectionChange from "./undoable_changes/SelectionChange";
|
import SelectionChange from './undoable_changes/SelectionChange';
|
||||||
import UndoableEdit from "./undoable_changes/UndoableEdit";
|
import UndoableEdit from './undoable_changes/UndoableEdit';
|
||||||
import EventObject from "./event/EventObject";
|
import EventObject from './event/EventObject';
|
||||||
import InternalEvent from "./event/InternalEvent";
|
import InternalEvent from './event/InternalEvent';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class: mxGraphSelectionModel
|
* Class: mxGraphSelectionModel
|
||||||
|
@ -69,11 +68,11 @@ class GraphSelectionModel extends EventSource {
|
||||||
constructor(graph: Graph) {
|
constructor(graph: Graph) {
|
||||||
super();
|
super();
|
||||||
this.graph = graph;
|
this.graph = graph;
|
||||||
this.cells = new CellArray();
|
this.cells = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
graph: Graph;
|
graph: Graph;
|
||||||
cells: CellArray;
|
cells: Cell[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the resource key for the status message after a long operation.
|
* Specifies the resource key for the status message after a long operation.
|
||||||
|
@ -140,7 +139,7 @@ class GraphSelectionModel extends EventSource {
|
||||||
* @param cell {@link mxCell} to be selected.
|
* @param cell {@link mxCell} to be selected.
|
||||||
*/
|
*/
|
||||||
setCell(cell: Cell) {
|
setCell(cell: Cell) {
|
||||||
this.setCells(cell ? new CellArray(cell) : new CellArray());
|
this.setCells(cell ? [cell] : []);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -148,12 +147,12 @@ class GraphSelectionModel extends EventSource {
|
||||||
*
|
*
|
||||||
* @param cells Array of {@link Cell} to be selected.
|
* @param cells Array of {@link Cell} to be selected.
|
||||||
*/
|
*/
|
||||||
setCells(cells: CellArray) {
|
setCells(cells: Cell[]) {
|
||||||
if (this.singleSelection) {
|
if (this.singleSelection) {
|
||||||
cells = new CellArray(<Cell>this.getFirstSelectableCell(cells));
|
cells = [<Cell>this.getFirstSelectableCell(cells)];
|
||||||
}
|
}
|
||||||
|
|
||||||
const tmp = new CellArray();
|
const tmp = [];
|
||||||
for (let i = 0; i < cells.length; i += 1) {
|
for (let i = 0; i < cells.length; i += 1) {
|
||||||
if (this.graph.isCellSelectable(cells[i])) {
|
if (this.graph.isCellSelectable(cells[i])) {
|
||||||
tmp.push(cells[i]);
|
tmp.push(cells[i]);
|
||||||
|
@ -165,7 +164,7 @@ class GraphSelectionModel extends EventSource {
|
||||||
/**
|
/**
|
||||||
* Returns the first selectable cell in the given array of cells.
|
* Returns the first selectable cell in the given array of cells.
|
||||||
*/
|
*/
|
||||||
getFirstSelectableCell(cells: CellArray) {
|
getFirstSelectableCell(cells: Cell[]) {
|
||||||
for (let i = 0; i < cells.length; i += 1) {
|
for (let i = 0; i < cells.length; i += 1) {
|
||||||
if (this.graph.isCellSelectable(cells[i])) {
|
if (this.graph.isCellSelectable(cells[i])) {
|
||||||
return cells[i];
|
return cells[i];
|
||||||
|
@ -180,7 +179,7 @@ class GraphSelectionModel extends EventSource {
|
||||||
* @param cell {@link mxCell} to add to the selection.
|
* @param cell {@link mxCell} to add to the selection.
|
||||||
*/
|
*/
|
||||||
addCell(cell: Cell) {
|
addCell(cell: Cell) {
|
||||||
this.addCells(new CellArray(cell));
|
this.addCells([cell]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,16 +188,16 @@ class GraphSelectionModel extends EventSource {
|
||||||
*
|
*
|
||||||
* @param cells Array of {@link Cell} to add to the selection.
|
* @param cells Array of {@link Cell} to add to the selection.
|
||||||
*/
|
*/
|
||||||
addCells(cells: CellArray) {
|
addCells(cells: Cell[]) {
|
||||||
let remove = null;
|
let remove = null;
|
||||||
if (this.singleSelection) {
|
if (this.singleSelection) {
|
||||||
remove = this.cells;
|
remove = this.cells;
|
||||||
|
|
||||||
const selectableCell = this.getFirstSelectableCell(cells);
|
const selectableCell = this.getFirstSelectableCell(cells);
|
||||||
cells = selectableCell ? new CellArray(selectableCell) : new CellArray();
|
cells = selectableCell ? [selectableCell] : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const tmp = new CellArray();
|
const tmp = [];
|
||||||
for (let i = 0; i < cells.length; i += 1) {
|
for (let i = 0; i < cells.length; i += 1) {
|
||||||
if (!this.isSelected(cells[i]) && this.graph.isCellSelectable(cells[i])) {
|
if (!this.isSelected(cells[i]) && this.graph.isCellSelectable(cells[i])) {
|
||||||
tmp.push(cells[i]);
|
tmp.push(cells[i]);
|
||||||
|
@ -215,7 +214,7 @@ class GraphSelectionModel extends EventSource {
|
||||||
* @param cell {@link mxCell} to remove from the selection.
|
* @param cell {@link mxCell} to remove from the selection.
|
||||||
*/
|
*/
|
||||||
removeCell(cell: Cell) {
|
removeCell(cell: Cell) {
|
||||||
this.removeCells(new CellArray(cell));
|
this.removeCells([cell]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -224,8 +223,8 @@ class GraphSelectionModel extends EventSource {
|
||||||
*
|
*
|
||||||
* @param cells {@link mxCell}s to remove from the selection.
|
* @param cells {@link mxCell}s to remove from the selection.
|
||||||
*/
|
*/
|
||||||
removeCells(cells: CellArray) {
|
removeCells(cells: Cell[]) {
|
||||||
const tmp = new CellArray();
|
const tmp = [];
|
||||||
|
|
||||||
for (let i = 0; i < cells.length; i += 1) {
|
for (let i = 0; i < cells.length; i += 1) {
|
||||||
if (this.isSelected(cells[i])) {
|
if (this.isSelected(cells[i])) {
|
||||||
|
@ -241,16 +240,12 @@ class GraphSelectionModel extends EventSource {
|
||||||
* @param added Array of {@link Cell} to add to the selection.
|
* @param added Array of {@link Cell} to add to the selection.
|
||||||
* @param remove Array of {@link Cell} to remove from the selection.
|
* @param remove Array of {@link Cell} to remove from the selection.
|
||||||
*/
|
*/
|
||||||
changeSelection(added: CellArray | null=null, removed: CellArray | null=null) {
|
changeSelection(added: Cell[] | null = null, removed: Cell[] | null = null) {
|
||||||
if (
|
if (
|
||||||
(added && added.length > 0 && added[0]) ||
|
(added && added.length > 0 && added[0]) ||
|
||||||
(removed && removed.length > 0 && removed[0])
|
(removed && removed.length > 0 && removed[0])
|
||||||
) {
|
) {
|
||||||
const change = new SelectionChange(
|
const change = new SelectionChange(this.graph, added || [], removed || []);
|
||||||
this.graph,
|
|
||||||
added || new CellArray(),
|
|
||||||
removed || new CellArray()
|
|
||||||
);
|
|
||||||
change.execute();
|
change.execute();
|
||||||
const edit = new UndoableEdit(this.graph, false);
|
const edit = new UndoableEdit(this.graph, false);
|
||||||
edit.add(change);
|
edit.add(change);
|
||||||
|
|
|
@ -42,7 +42,6 @@ import ConnectionConstraint from './other/ConnectionConstraint';
|
||||||
import PopupMenuHandler from './handler/PopupMenuHandler';
|
import PopupMenuHandler from './handler/PopupMenuHandler';
|
||||||
import { getClientX, getClientY, getSource, isConsumed } from '../util/EventUtils';
|
import { getClientX, getClientY, getSource, isConsumed } from '../util/EventUtils';
|
||||||
import { clone } from '../util/cloneUtils';
|
import { clone } from '../util/cloneUtils';
|
||||||
import CellArray from './cell/CellArray';
|
|
||||||
import type { Graph } from './Graph';
|
import type { Graph } from './Graph';
|
||||||
import StyleRegistry from './style/StyleRegistry';
|
import StyleRegistry from './style/StyleRegistry';
|
||||||
import TooltipHandler from './handler/TooltipHandler';
|
import TooltipHandler from './handler/TooltipHandler';
|
||||||
|
@ -346,7 +345,7 @@ export class GraphView extends EventSource {
|
||||||
*
|
*
|
||||||
* @param cells Array of {@link Cell} whose bounds should be returned.
|
* @param cells Array of {@link Cell} whose bounds should be returned.
|
||||||
*/
|
*/
|
||||||
getBounds(cells: CellArray) {
|
getBounds(cells: Cell[]) {
|
||||||
let result: Rectangle | null = null;
|
let result: Rectangle | null = null;
|
||||||
|
|
||||||
if (cells.length > 0) {
|
if (cells.length > 0) {
|
||||||
|
@ -1973,7 +1972,7 @@ export class GraphView extends EventSource {
|
||||||
* have less elements than the given array. If no argument is given, then
|
* have less elements than the given array. If no argument is given, then
|
||||||
* this returns {@link states}.
|
* this returns {@link states}.
|
||||||
*/
|
*/
|
||||||
getCellStates(cells: CellArray | null = null) {
|
getCellStates(cells: Cell[] | null = null) {
|
||||||
if (!cells) {
|
if (!cells) {
|
||||||
return this.states.getValues();
|
return this.states.getValues();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import Animation from './Animation';
|
||||||
import CellState from '../cell/CellState';
|
import CellState from '../cell/CellState';
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements animation for morphing cells. Here is an example of
|
* Implements animation for morphing cells. Here is an example of
|
||||||
|
@ -57,7 +56,7 @@ import CellArray from '../cell/CellArray';
|
||||||
* @param delay Optional delay between the animation steps. Passed to <Animation>.
|
* @param delay Optional delay between the animation steps. Passed to <Animation>.
|
||||||
*/
|
*/
|
||||||
class Morphing extends Animation {
|
class Morphing extends Animation {
|
||||||
constructor(graph: Graph, steps: number=6, ease: number=1.5, delay: number) {
|
constructor(graph: Graph, steps: number = 6, ease: number = 1.5, delay: number) {
|
||||||
super(delay);
|
super(delay);
|
||||||
this.graph = graph;
|
this.graph = graph;
|
||||||
this.steps = steps;
|
this.steps = steps;
|
||||||
|
@ -90,7 +89,7 @@ class Morphing extends Animation {
|
||||||
* then all cells are checked and animated if they have been moved
|
* then all cells are checked and animated if they have been moved
|
||||||
* in the current transaction.
|
* in the current transaction.
|
||||||
*/
|
*/
|
||||||
cells: CellArray | null = null;
|
cells: Cell[] | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animation step.
|
* Animation step.
|
||||||
|
@ -127,7 +126,7 @@ class Morphing extends Animation {
|
||||||
/**
|
/**
|
||||||
* Animates the given cell state using <CellStatePreview.moveState>.
|
* Animates the given cell state using <CellStatePreview.moveState>.
|
||||||
*/
|
*/
|
||||||
animateCell(cell: Cell, move: CellStatePreview, recurse: boolean=false) {
|
animateCell(cell: Cell, move: CellStatePreview, recurse: boolean = false) {
|
||||||
const state = this.graph.getView().getState(cell);
|
const state = this.graph.getView().getState(cell);
|
||||||
let delta = null;
|
let delta = null;
|
||||||
|
|
||||||
|
@ -136,10 +135,7 @@ class Morphing extends Animation {
|
||||||
// change by subtracting the given delta vector from that location
|
// change by subtracting the given delta vector from that location
|
||||||
delta = this.getDelta(state);
|
delta = this.getDelta(state);
|
||||||
|
|
||||||
if (
|
if (cell.isVertex() && (delta.x != 0 || delta.y != 0)) {
|
||||||
cell.isVertex() &&
|
|
||||||
(delta.x != 0 || delta.y != 0)
|
|
||||||
) {
|
|
||||||
const translate = this.graph.view.getTranslate();
|
const translate = this.graph.view.getTranslate();
|
||||||
const scale = this.graph.view.getScale();
|
const scale = this.graph.view.getScale();
|
||||||
|
|
||||||
|
@ -154,11 +150,7 @@ class Morphing extends Animation {
|
||||||
const childCount = cell.getChildCount();
|
const childCount = cell.getChildCount();
|
||||||
|
|
||||||
for (let i = 0; i < childCount; i += 1) {
|
for (let i = 0; i < childCount; i += 1) {
|
||||||
this.animateCell(
|
this.animateCell(cell.getChildAt(i), move, recurse);
|
||||||
cell.getChildAt(i),
|
|
||||||
move,
|
|
||||||
recurse
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,7 +159,7 @@ class Morphing extends Animation {
|
||||||
* Returns true if the animation should not recursively find more
|
* Returns true if the animation should not recursively find more
|
||||||
* deltas for children if the given parent state has been animated.
|
* deltas for children if the given parent state has been animated.
|
||||||
*/
|
*/
|
||||||
stopRecursion(state: CellState | null=null, delta: Point | null=null) {
|
stopRecursion(state: CellState | null = null, delta: Point | null = null) {
|
||||||
return delta != null && (delta.x != 0 || delta.y != 0);
|
return delta != null && (delta.x != 0 || delta.y != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +182,7 @@ class Morphing extends Animation {
|
||||||
* by using caching inside this method as the result per cell never changes
|
* by using caching inside this method as the result per cell never changes
|
||||||
* during the lifecycle of this object.
|
* during the lifecycle of this object.
|
||||||
*/
|
*/
|
||||||
getOriginForCell(cell: Cell | null=null): Point | null {
|
getOriginForCell(cell: Cell | null = null): Point | null {
|
||||||
let result = null;
|
let result = null;
|
||||||
|
|
||||||
if (cell != null) {
|
if (cell != null) {
|
||||||
|
|
|
@ -22,7 +22,6 @@ import CellOverlay from './CellOverlay';
|
||||||
import { clone } from '../../util/cloneUtils';
|
import { clone } from '../../util/cloneUtils';
|
||||||
import Point from '../geometry/Point';
|
import Point from '../geometry/Point';
|
||||||
import CellPath from './CellPath';
|
import CellPath from './CellPath';
|
||||||
import CellArray from './CellArray';
|
|
||||||
import { isNotNullish } from '../../util/Utils';
|
import { isNotNullish } from '../../util/Utils';
|
||||||
import ObjectCodec from '../../serialization/ObjectCodec';
|
import ObjectCodec from '../../serialization/ObjectCodec';
|
||||||
import CodecRegistry from '../../serialization/CodecRegistry';
|
import CodecRegistry from '../../serialization/CodecRegistry';
|
||||||
|
@ -91,8 +90,8 @@ export class Cell {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Document me!!!
|
// TODO: Document me!!!
|
||||||
getChildren(): CellArray {
|
getChildren(): Cell[] {
|
||||||
return this.children || new CellArray();
|
return this.children || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Document me!
|
// TODO: Document me!
|
||||||
|
@ -168,12 +167,12 @@ export class Cell {
|
||||||
/**
|
/**
|
||||||
* Holds the child cells.
|
* Holds the child cells.
|
||||||
*/
|
*/
|
||||||
children: CellArray = new CellArray();
|
children: Cell[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the edges.
|
* Holds the edges.
|
||||||
*/
|
*/
|
||||||
edges: CellArray = new CellArray();
|
edges: Cell[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of members that should not be cloned inside <clone>. This field is
|
* List of members that should not be cloned inside <clone>. This field is
|
||||||
|
@ -684,14 +683,14 @@ export class Cell {
|
||||||
/**
|
/**
|
||||||
* Returns the child vertices of the given parent.
|
* Returns the child vertices of the given parent.
|
||||||
*/
|
*/
|
||||||
getChildVertices(): CellArray {
|
getChildVertices() {
|
||||||
return this.getChildCells(true, false);
|
return this.getChildCells(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the child edges of the given parent.
|
* Returns the child edges of the given parent.
|
||||||
*/
|
*/
|
||||||
getChildEdges(): CellArray {
|
getChildEdges() {
|
||||||
return this.getChildCells(false, true);
|
return this.getChildCells(false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,9 +703,9 @@ export class Cell {
|
||||||
* @param edges Boolean indicating if child edges should be returned.
|
* @param edges Boolean indicating if child edges should be returned.
|
||||||
* Default is false.
|
* Default is false.
|
||||||
*/
|
*/
|
||||||
getChildCells(vertices: boolean = false, edges: boolean = false): CellArray {
|
getChildCells(vertices: boolean = false, edges: boolean = false) {
|
||||||
const childCount = this.getChildCount();
|
const childCount = this.getChildCount();
|
||||||
const result = new CellArray();
|
const result = [];
|
||||||
|
|
||||||
for (let i = 0; i < childCount; i += 1) {
|
for (let i = 0; i < childCount; i += 1) {
|
||||||
const child = this.getChildAt(i);
|
const child = this.getChildAt(i);
|
||||||
|
@ -748,21 +747,21 @@ export class Cell {
|
||||||
/**
|
/**
|
||||||
* Returns all edges of the given cell without loops.
|
* Returns all edges of the given cell without loops.
|
||||||
*/
|
*/
|
||||||
getConnections(): CellArray {
|
getConnections() {
|
||||||
return this.getEdges(true, true, false);
|
return this.getEdges(true, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the incoming edges of the given cell without loops.
|
* Returns the incoming edges of the given cell without loops.
|
||||||
*/
|
*/
|
||||||
getIncomingEdges(): CellArray {
|
getIncomingEdges() {
|
||||||
return this.getEdges(true, false, false);
|
return this.getEdges(true, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the outgoing edges of the given cell without loops.
|
* Returns the outgoing edges of the given cell without loops.
|
||||||
*/
|
*/
|
||||||
getOutgoingEdges(): CellArray {
|
getOutgoingEdges() {
|
||||||
return this.getEdges(false, true, false);
|
return this.getEdges(false, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -783,9 +782,9 @@ export class Cell {
|
||||||
incoming: boolean = true,
|
incoming: boolean = true,
|
||||||
outgoing: boolean = true,
|
outgoing: boolean = true,
|
||||||
includeLoops: boolean = true
|
includeLoops: boolean = true
|
||||||
): CellArray {
|
) {
|
||||||
const edgeCount = this.getEdgeCount();
|
const edgeCount = this.getEdgeCount();
|
||||||
const result = new CellArray();
|
const result = [];
|
||||||
|
|
||||||
for (let i = 0; i < edgeCount; i += 1) {
|
for (let i = 0; i < edgeCount; i += 1) {
|
||||||
const edge = this.getEdgeAt(i);
|
const edge = this.getEdgeAt(i);
|
||||||
|
@ -831,7 +830,7 @@ export class Cell {
|
||||||
/**
|
/**
|
||||||
* Returns all descendants of the given cell and the cell itself in an array.
|
* Returns all descendants of the given cell and the cell itself in an array.
|
||||||
*/
|
*/
|
||||||
getDescendants(): CellArray {
|
getDescendants() {
|
||||||
return this.filterDescendants(null);
|
return this.filterDescendants(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -854,9 +853,9 @@ export class Cell {
|
||||||
* @param filter JavaScript function that takes an {@link Cell} as an argument
|
* @param filter JavaScript function that takes an {@link Cell} as an argument
|
||||||
* and returns a boolean.
|
* and returns a boolean.
|
||||||
*/
|
*/
|
||||||
filterDescendants(filter: FilterFunction | null): CellArray {
|
filterDescendants(filter: FilterFunction | null): Cell[] {
|
||||||
// Creates a new array for storing the result
|
// Creates a new array for storing the result
|
||||||
let result = new CellArray();
|
let result: Cell[] = [];
|
||||||
|
|
||||||
// Checks if the filter returns true for the cell
|
// Checks if the filter returns true for the cell
|
||||||
// and adds it to the result array
|
// and adds it to the result array
|
||||||
|
@ -868,7 +867,7 @@ export class Cell {
|
||||||
const childCount = this.getChildCount();
|
const childCount = this.getChildCount();
|
||||||
for (let i = 0; i < childCount; i += 1) {
|
for (let i = 0; i < childCount; i += 1) {
|
||||||
const child = this.getChildAt(i);
|
const child = this.getChildAt(i);
|
||||||
result = new CellArray(...result.concat(child.filterDescendants(filter)));
|
result = result.concat(child.filterDescendants(filter));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -1,237 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2021-present The maxGraph project Contributors
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import Cell from './Cell';
|
|
||||||
import Dictionary from '../../util/Dictionary';
|
|
||||||
import ObjectIdentity from '../../util/ObjectIdentity';
|
|
||||||
|
|
||||||
class CellArray extends Array<Cell> {
|
|
||||||
constructor(...items: Cell[]) {
|
|
||||||
super(...items);
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
concat(items: any): CellArray {
|
|
||||||
return new CellArray(...super.concat(items));
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
splice(arg0: number, ...args: any): CellArray {
|
|
||||||
return new CellArray(...super.splice(arg0, ...args));
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
slice(...args: any): CellArray {
|
|
||||||
return new CellArray(...super.slice(...args));
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
map(arg0: any, ...args: any): CellArray {
|
|
||||||
return new CellArray(...(<Cell[]>super.map(arg0, ...args)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
filter(arg0: any, ...args: any): CellArray {
|
|
||||||
return new CellArray(...(<Cell[]>super.filter(arg0, ...args)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the cells from the given array where the given filter function
|
|
||||||
* returns true.
|
|
||||||
*/
|
|
||||||
filterCells(filter: Function): CellArray {
|
|
||||||
let result = new CellArray();
|
|
||||||
|
|
||||||
for (let i = 0; i < this.length; i += 1) {
|
|
||||||
if (filter(this[i])) {
|
|
||||||
result.push(this[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all opposite vertices wrt terminal for the given edges, only
|
|
||||||
* returning sources and/or targets as specified. The result is returned
|
|
||||||
* as an array of {@link Cell}.
|
|
||||||
*
|
|
||||||
* @param {Cell} terminal that specifies the known end of the edges.
|
|
||||||
* @param sources Boolean that specifies if source terminals should be contained
|
|
||||||
* in the result. Default is true.
|
|
||||||
* @param targets Boolean that specifies if target terminals should be contained
|
|
||||||
* in the result. Default is true.
|
|
||||||
*/
|
|
||||||
getOpposites(
|
|
||||||
terminal: Cell,
|
|
||||||
sources: boolean = true,
|
|
||||||
targets: boolean = true
|
|
||||||
): CellArray {
|
|
||||||
const terminals = new CellArray();
|
|
||||||
|
|
||||||
for (let i = 0; i < this.length; i += 1) {
|
|
||||||
const source = this[i].getTerminal(true);
|
|
||||||
const target = this[i].getTerminal(false);
|
|
||||||
|
|
||||||
// Checks if the terminal is the source of
|
|
||||||
// the edge and if the target should be
|
|
||||||
// stored in the result
|
|
||||||
if (source === terminal && target != null && target !== terminal && targets) {
|
|
||||||
terminals.push(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks if the terminal is the taget of
|
|
||||||
// the edge and if the source should be
|
|
||||||
// stored in the result
|
|
||||||
else if (target === terminal && source != null && source !== terminal && sources) {
|
|
||||||
terminals.push(source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return terminals;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the topmost cells of the hierarchy in an array that contains no
|
|
||||||
* descendants for each {@link Cell} that it contains. Duplicates should be
|
|
||||||
* removed in the cells array to improve performance.
|
|
||||||
*/
|
|
||||||
getTopmostCells(): CellArray {
|
|
||||||
const dict = new Dictionary();
|
|
||||||
const tmp = new CellArray();
|
|
||||||
|
|
||||||
for (let i = 0; i < this.length; i += 1) {
|
|
||||||
dict.put(this[i], true);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < this.length; i += 1) {
|
|
||||||
const cell = this[i];
|
|
||||||
let topmost = true;
|
|
||||||
let parent = cell.getParent();
|
|
||||||
|
|
||||||
while (parent != null) {
|
|
||||||
if (dict.get(parent)) {
|
|
||||||
topmost = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
parent = parent.getParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (topmost) {
|
|
||||||
tmp.push(cell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array that represents the set (no duplicates) of all parents
|
|
||||||
* for the given array of cells.
|
|
||||||
*/
|
|
||||||
getParents(): CellArray {
|
|
||||||
const parents = [];
|
|
||||||
const dict = new Dictionary();
|
|
||||||
|
|
||||||
for (const cell of this) {
|
|
||||||
const parent = cell.getParent();
|
|
||||||
if (parent != null && !dict.get(parent)) {
|
|
||||||
dict.put(parent, true);
|
|
||||||
parents.push(parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new CellArray(...parents);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of clones for the given array of {@link Cell}`.
|
|
||||||
* Depending on the value of includeChildren, a deep clone is created for
|
|
||||||
* each cell. Connections are restored based if the corresponding
|
|
||||||
* cell is contained in the passed in array.
|
|
||||||
*
|
|
||||||
* @param includeChildren Boolean indicating if the cells should be cloned
|
|
||||||
* with all descendants.
|
|
||||||
* @param mapping Optional mapping for existing clones.
|
|
||||||
*/
|
|
||||||
cloneCells(includeChildren: boolean = true, mapping: any = {}): CellArray {
|
|
||||||
const clones: CellArray = new CellArray();
|
|
||||||
|
|
||||||
for (const cell of this) {
|
|
||||||
clones.push(this.cloneCellImpl(cell, mapping, includeChildren));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < clones.length; i += 1) {
|
|
||||||
if (clones[i] != null) {
|
|
||||||
this.restoreClone(<Cell>clones[i], this[i], mapping);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return clones;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inner helper method for cloning cells recursively.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
cloneCellImpl(cell: Cell, mapping: any = {}, includeChildren: boolean): Cell {
|
|
||||||
const ident = <string>ObjectIdentity.get(cell);
|
|
||||||
let clone = mapping ? mapping[ident] : null;
|
|
||||||
|
|
||||||
if (clone == null) {
|
|
||||||
clone = cell.clone();
|
|
||||||
mapping[ident] = clone;
|
|
||||||
|
|
||||||
if (includeChildren) {
|
|
||||||
const childCount = cell.getChildCount();
|
|
||||||
|
|
||||||
for (let i = 0; i < childCount; i += 1) {
|
|
||||||
const cloneChild = this.cloneCellImpl(<Cell>cell.getChildAt(i), mapping, true);
|
|
||||||
clone.insert(cloneChild);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return clone;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inner helper method for restoring the connections in
|
|
||||||
* a network of cloned cells.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
restoreClone(clone: Cell, cell: Cell, mapping: any): void {
|
|
||||||
const source = cell.getTerminal(true);
|
|
||||||
|
|
||||||
if (source != null) {
|
|
||||||
const tmp = mapping[<string>ObjectIdentity.get(source)];
|
|
||||||
if (tmp != null) {
|
|
||||||
tmp.insertEdge(clone, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const target = cell.getTerminal(false);
|
|
||||||
if (target != null) {
|
|
||||||
const tmp = mapping[<string>ObjectIdentity.get(target)];
|
|
||||||
if (tmp != null) {
|
|
||||||
tmp.insertEdge(clone, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const childCount = clone.getChildCount();
|
|
||||||
for (let i = 0; i < childCount; i += 1) {
|
|
||||||
this.restoreClone(<Cell>clone.getChildAt(i), <Cell>cell.getChildAt(i), mapping);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default CellArray;
|
|
|
@ -61,7 +61,6 @@ import CellOverlay from './CellOverlay';
|
||||||
import { getClientX, getClientY, getSource } from '../../util/EventUtils';
|
import { getClientX, getClientY, getSource } from '../../util/EventUtils';
|
||||||
import { isNode } from '../../util/domUtils';
|
import { isNode } from '../../util/domUtils';
|
||||||
import { CellStateStyle } from '../../types';
|
import { CellStateStyle } from '../../types';
|
||||||
import CellArray from './CellArray';
|
|
||||||
import SelectionCellsHandler from '../handler/SelectionCellsHandler';
|
import SelectionCellsHandler from '../handler/SelectionCellsHandler';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
|
|
||||||
|
@ -612,7 +611,7 @@ class CellRenderer {
|
||||||
return (evt: Event) => {
|
return (evt: Event) => {
|
||||||
if (this.forceControlClickHandler || graph.isEnabled()) {
|
if (this.forceControlClickHandler || graph.isEnabled()) {
|
||||||
const collapse = !state.cell.isCollapsed();
|
const collapse = !state.cell.isCollapsed();
|
||||||
graph.foldCells(collapse, false, new CellArray(state.cell), false, evt);
|
graph.foldCells(collapse, false, [state.cell], false, evt);
|
||||||
InternalEvent.consume(evt);
|
InternalEvent.consume(evt);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,7 +22,6 @@ import GraphView from '../GraphView';
|
||||||
import Cell from './Cell';
|
import Cell from './Cell';
|
||||||
import CellState from './CellState';
|
import CellState from './CellState';
|
||||||
import Shape from '../geometry/Shape';
|
import Shape from '../geometry/Shape';
|
||||||
import CellArray from './CellArray';
|
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,7 +52,7 @@ class TemporaryCellStates {
|
||||||
constructor(
|
constructor(
|
||||||
view: GraphView,
|
view: GraphView,
|
||||||
scale: number = 1,
|
scale: number = 1,
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
isCellVisibleFn: Function | null = null,
|
isCellVisibleFn: Function | null = null,
|
||||||
getLinkForCellState: Function | null = null
|
getLinkForCellState: Function | null = null
|
||||||
) {
|
) {
|
||||||
|
@ -85,7 +84,9 @@ class TemporaryCellStates {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
(<Function>self.oldDoRedrawShape).apply((<Graph>view.graph).cellRenderer, [state]);
|
(<Function>self.oldDoRedrawShape).apply((<Graph>view.graph).cellRenderer, [
|
||||||
|
state,
|
||||||
|
]);
|
||||||
shape.paint = oldPaint;
|
shape.paint = oldPaint;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import Shape from '../geometry/Shape';
|
||||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||||
import ImageBox from '../image/ImageBox';
|
import ImageBox from '../image/ImageBox';
|
||||||
import CellState from './CellState';
|
import CellState from './CellState';
|
||||||
import CellArray from './CellArray';
|
|
||||||
|
|
||||||
import type { Graph } from '../Graph';
|
import type { Graph } from '../Graph';
|
||||||
import type { CellHandle, CellStateStyle } from '../../types';
|
import type { CellHandle, CellStateStyle } from '../../types';
|
||||||
|
@ -101,7 +100,7 @@ class VertexHandle implements CellHandle {
|
||||||
* Sets the cell style with the given name to the corresponding value in <state>.
|
* Sets the cell style with the given name to the corresponding value in <state>.
|
||||||
*/
|
*/
|
||||||
copyStyle(key: keyof CellStateStyle) {
|
copyStyle(key: keyof CellStateStyle) {
|
||||||
this.graph.setCellStyles(key, this.state.style[key], new CellArray(this.state.cell));
|
this.graph.setCellStyles(key, this.state.style[key], [this.state.cell]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,10 +17,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { getValue } from '../../util/Utils';
|
import { getValue } from '../../util/Utils';
|
||||||
import {
|
import { getAlignmentAsPoint, setPrefixedStyle } from '../../util/styleUtils';
|
||||||
getAlignmentAsPoint,
|
|
||||||
setPrefixedStyle,
|
|
||||||
} from '../../util/styleUtils';
|
|
||||||
import Rectangle from '../geometry/Rectangle';
|
import Rectangle from '../geometry/Rectangle';
|
||||||
import InternalEvent from '../event/InternalEvent';
|
import InternalEvent from '../event/InternalEvent';
|
||||||
import Client from '../../Client';
|
import Client from '../../Client';
|
||||||
|
@ -42,7 +39,11 @@ import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||||
import CellState from '../cell/CellState';
|
import CellState from '../cell/CellState';
|
||||||
import Shape from '../geometry/Shape';
|
import Shape from '../geometry/Shape';
|
||||||
import { clearSelection, extractTextWithWhitespace, isNode } from '../../util/domUtils';
|
import { clearSelection, extractTextWithWhitespace, isNode } from '../../util/domUtils';
|
||||||
import { getStringValue, htmlEntities, replaceTrailingNewlines } from '../../util/StringUtils';
|
import {
|
||||||
|
getStringValue,
|
||||||
|
htmlEntities,
|
||||||
|
replaceTrailingNewlines,
|
||||||
|
} from '../../util/StringUtils';
|
||||||
import {
|
import {
|
||||||
getSource,
|
getSource,
|
||||||
isConsumed,
|
isConsumed,
|
||||||
|
@ -54,7 +55,6 @@ import EventSource from '../event/EventSource';
|
||||||
|
|
||||||
import type { Graph } from '../Graph';
|
import type { Graph } from '../Graph';
|
||||||
import type { GraphPlugin } from '../../types';
|
import type { GraphPlugin } from '../../types';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import TooltipHandler from './TooltipHandler';
|
import TooltipHandler from './TooltipHandler';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -889,7 +889,7 @@ class CellEditorHandler implements GraphPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.align !== null) {
|
if (this.align !== null) {
|
||||||
this.graph.setCellStyles('align', this.align, new CellArray(state.cell));
|
this.graph.setCellStyles('align', this.align, [state.cell]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,6 @@ import { Graph } from '../Graph';
|
||||||
import ConnectionConstraint from '../other/ConnectionConstraint';
|
import ConnectionConstraint from '../other/ConnectionConstraint';
|
||||||
import Shape from '../geometry/Shape';
|
import Shape from '../geometry/Shape';
|
||||||
import { CellStyle, GraphPlugin, Listenable } from '../../types';
|
import { CellStyle, GraphPlugin, Listenable } from '../../types';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
|
|
||||||
type FactoryMethod = (
|
type FactoryMethod = (
|
||||||
source: Cell | null,
|
source: Cell | null,
|
||||||
|
@ -1749,7 +1748,7 @@ class ConnectionHandler extends EventSource implements GraphPlugin {
|
||||||
target = this.createTargetVertex(evt, source);
|
target = this.createTargetVertex(evt, source);
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
dropTarget = this.graph.getDropTarget(new CellArray(target), evt, dropTarget);
|
dropTarget = this.graph.getDropTarget([target], evt, dropTarget);
|
||||||
terminalInserted = true;
|
terminalInserted = true;
|
||||||
|
|
||||||
// Disables edges as drop targets if the target cell was created
|
// Disables edges as drop targets if the target cell was created
|
||||||
|
|
|
@ -18,12 +18,7 @@ limitations under the License.
|
||||||
|
|
||||||
import Client from '../../Client';
|
import Client from '../../Client';
|
||||||
import InternalEvent from '../event/InternalEvent';
|
import InternalEvent from '../event/InternalEvent';
|
||||||
import {
|
import { contains, getRotatedPoint, isNumeric, toRadians } from '../../util/mathUtils';
|
||||||
contains,
|
|
||||||
getRotatedPoint,
|
|
||||||
isNumeric,
|
|
||||||
toRadians,
|
|
||||||
} from '../../util/mathUtils';
|
|
||||||
import { convertPoint } from '../../util/styleUtils';
|
import { convertPoint } from '../../util/styleUtils';
|
||||||
import RectangleShape from '../geometry/node/RectangleShape';
|
import RectangleShape from '../geometry/node/RectangleShape';
|
||||||
import mxGuide from '../other/Guide';
|
import mxGuide from '../other/Guide';
|
||||||
|
@ -39,7 +34,12 @@ import {
|
||||||
import Dictionary from '../../util/Dictionary';
|
import Dictionary from '../../util/Dictionary';
|
||||||
import CellHighlight from '../cell/CellHighlight';
|
import CellHighlight from '../cell/CellHighlight';
|
||||||
import Rectangle from '../geometry/Rectangle';
|
import Rectangle from '../geometry/Rectangle';
|
||||||
import { getClientX, getClientY, isAltDown, isMultiTouchEvent } from '../../util/EventUtils';
|
import {
|
||||||
|
getClientX,
|
||||||
|
getClientY,
|
||||||
|
isAltDown,
|
||||||
|
isMultiTouchEvent,
|
||||||
|
} from '../../util/EventUtils';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import Guide from '../other/Guide';
|
import Guide from '../other/Guide';
|
||||||
import Shape from '../geometry/Shape';
|
import Shape from '../geometry/Shape';
|
||||||
|
@ -48,7 +48,6 @@ import SelectionCellsHandler from './SelectionCellsHandler';
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import PopupMenuHandler from './PopupMenuHandler';
|
import PopupMenuHandler from './PopupMenuHandler';
|
||||||
import EventSource from '../event/EventSource';
|
import EventSource from '../event/EventSource';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import CellState from '../cell/CellState';
|
import CellState from '../cell/CellState';
|
||||||
import EventObject from '../event/EventObject';
|
import EventObject from '../event/EventObject';
|
||||||
import ConnectionHandler from './ConnectionHandler';
|
import ConnectionHandler from './ConnectionHandler';
|
||||||
|
@ -325,7 +324,7 @@ class SelectionHandler implements GraphPlugin {
|
||||||
delayedSelection = false;
|
delayedSelection = false;
|
||||||
|
|
||||||
first: Point | null = null;
|
first: Point | null = null;
|
||||||
cells: CellArray | null = null;
|
cells: Cell[] | null = null;
|
||||||
bounds: Rectangle | null = null;
|
bounds: Rectangle | null = null;
|
||||||
pBounds: Rectangle | null = null;
|
pBounds: Rectangle | null = null;
|
||||||
allCells: Dictionary<Cell, CellState> = new Dictionary();
|
allCells: Dictionary<Cell, CellState> = new Dictionary();
|
||||||
|
@ -481,7 +480,9 @@ class SelectionHandler implements GraphPlugin {
|
||||||
if (!this.graph.isToggleEvent(me.getEvent()) || !isAltDown(me.getEvent())) {
|
if (!this.graph.isToggleEvent(me.getEvent()) || !isAltDown(me.getEvent())) {
|
||||||
while (c) {
|
while (c) {
|
||||||
if (selectionCellsHandler.isHandled(c)) {
|
if (selectionCellsHandler.isHandled(c)) {
|
||||||
const cellEditor = this.graph.getPlugin('CellEditorHandler') as CellEditorHandler;
|
const cellEditor = this.graph.getPlugin(
|
||||||
|
'CellEditorHandler'
|
||||||
|
) as CellEditorHandler;
|
||||||
return cellEditor.getEditingCell() !== c;
|
return cellEditor.getEditingCell() !== c;
|
||||||
}
|
}
|
||||||
c = c.getParent();
|
c = c.getParent();
|
||||||
|
@ -629,9 +630,9 @@ class SelectionHandler implements GraphPlugin {
|
||||||
*
|
*
|
||||||
* @param initialCell <Cell> that triggered this handler.
|
* @param initialCell <Cell> that triggered this handler.
|
||||||
*/
|
*/
|
||||||
getCells(initialCell: Cell) {
|
getCells(initialCell: Cell): Cell[] {
|
||||||
if (!this.delayedSelection && this.graph.isCellMovable(initialCell)) {
|
if (!this.delayedSelection && this.graph.isCellMovable(initialCell)) {
|
||||||
return new CellArray(initialCell);
|
return [initialCell];
|
||||||
}
|
}
|
||||||
return this.graph.getMovableCells(this.graph.getSelectionCells());
|
return this.graph.getMovableCells(this.graph.getSelectionCells());
|
||||||
}
|
}
|
||||||
|
@ -640,7 +641,7 @@ class SelectionHandler implements GraphPlugin {
|
||||||
* Returns the {@link Rectangle} used as the preview bounds for
|
* Returns the {@link Rectangle} used as the preview bounds for
|
||||||
* moving the given cells.
|
* moving the given cells.
|
||||||
*/
|
*/
|
||||||
getPreviewBounds(cells: CellArray) {
|
getPreviewBounds(cells: Cell[]) {
|
||||||
const bounds = this.getBoundingBox(cells);
|
const bounds = this.getBoundingBox(cells);
|
||||||
|
|
||||||
if (bounds) {
|
if (bounds) {
|
||||||
|
@ -678,7 +679,7 @@ class SelectionHandler implements GraphPlugin {
|
||||||
*
|
*
|
||||||
* @param cells Array of {@link Cells} whose bounding box should be returned.
|
* @param cells Array of {@link Cells} whose bounding box should be returned.
|
||||||
*/
|
*/
|
||||||
getBoundingBox(cells: CellArray) {
|
getBoundingBox(cells: Cell[]) {
|
||||||
let result = null;
|
let result = null;
|
||||||
|
|
||||||
if (cells.length > 0) {
|
if (cells.length > 0) {
|
||||||
|
@ -742,7 +743,7 @@ class SelectionHandler implements GraphPlugin {
|
||||||
/**
|
/**
|
||||||
* Starts the handling of the mouse gesture.
|
* Starts the handling of the mouse gesture.
|
||||||
*/
|
*/
|
||||||
start(cell: Cell, x: number, y: number, cells?: CellArray) {
|
start(cell: Cell, x: number, y: number, cells?: Cell[]) {
|
||||||
this.cell = cell;
|
this.cell = cell;
|
||||||
this.first = convertPoint(this.graph.container, x, y);
|
this.first = convertPoint(this.graph.container, x, y);
|
||||||
this.cells = cells ? cells : this.getCells(this.cell);
|
this.cells = cells ? cells : this.getCells(this.cell);
|
||||||
|
@ -1369,7 +1370,7 @@ class SelectionHandler implements GraphPlugin {
|
||||||
* @param visible Boolean that specifies if the handles should be visible.
|
* @param visible Boolean that specifies if the handles should be visible.
|
||||||
* @param force Forces an update of the handler regardless of the last used value.
|
* @param force Forces an update of the handler regardless of the last used value.
|
||||||
*/
|
*/
|
||||||
setHandlesVisibleForCells(cells: CellArray, visible: boolean, force = false) {
|
setHandlesVisibleForCells(cells: Cell[], visible: boolean, force = false) {
|
||||||
if (force || this.handlesVisible !== visible) {
|
if (force || this.handlesVisible !== visible) {
|
||||||
this.handlesVisible = visible;
|
this.handlesVisible = visible;
|
||||||
|
|
||||||
|
@ -1517,7 +1518,7 @@ class SelectionHandler implements GraphPlugin {
|
||||||
* Returns true if the given cells should be removed from the parent for the specified
|
* Returns true if the given cells should be removed from the parent for the specified
|
||||||
* mousereleased event.
|
* mousereleased event.
|
||||||
*/
|
*/
|
||||||
shouldRemoveCellsFromParent(parent: Cell, cells: CellArray, evt: MouseEvent) {
|
shouldRemoveCellsFromParent(parent: Cell, cells: Cell[], evt: MouseEvent) {
|
||||||
if (parent.isVertex()) {
|
if (parent.isVertex()) {
|
||||||
const pState = this.graph.getView().getState(parent);
|
const pState = this.graph.getView().getState(parent);
|
||||||
|
|
||||||
|
@ -1544,7 +1545,7 @@ class SelectionHandler implements GraphPlugin {
|
||||||
* Moves the given cells by the specified amount.
|
* Moves the given cells by the specified amount.
|
||||||
*/
|
*/
|
||||||
moveCells(
|
moveCells(
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
dx: number,
|
dx: number,
|
||||||
dy: number,
|
dy: number,
|
||||||
clone: boolean,
|
clone: boolean,
|
||||||
|
@ -1608,7 +1609,7 @@ class SelectionHandler implements GraphPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.graph.removeCells(new CellArray(...temp), false);
|
this.graph.removeCells(temp, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Selects the new cells if cells have been cloned
|
// Selects the new cells if cells have been cloned
|
||||||
|
|
|
@ -45,7 +45,6 @@ import Cell from '../cell/Cell';
|
||||||
import { CellHandle, Listenable } from '../../types';
|
import { CellHandle, Listenable } from '../../types';
|
||||||
import Shape from '../geometry/Shape';
|
import Shape from '../geometry/Shape';
|
||||||
import InternalMouseEvent from '../event/InternalMouseEvent';
|
import InternalMouseEvent from '../event/InternalMouseEvent';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import EdgeHandler from './EdgeHandler';
|
import EdgeHandler from './EdgeHandler';
|
||||||
import EventSource from '../event/EventSource';
|
import EventSource from '../event/EventSource';
|
||||||
import SelectionHandler from './SelectionHandler';
|
import SelectionHandler from './SelectionHandler';
|
||||||
|
@ -214,7 +213,7 @@ class VertexHandler {
|
||||||
|
|
||||||
constructor(state: CellState) {
|
constructor(state: CellState) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.graph = (<Graph>this.state.view.graph);
|
this.graph = <Graph>this.state.view.graph;
|
||||||
this.selectionBounds = this.getSelectionBounds(this.state);
|
this.selectionBounds = this.getSelectionBounds(this.state);
|
||||||
this.bounds = new Rectangle(
|
this.bounds = new Rectangle(
|
||||||
this.selectionBounds.x,
|
this.selectionBounds.x,
|
||||||
|
@ -659,7 +658,7 @@ class VertexHandler {
|
||||||
this.ghostPreview = this.createGhostPreview();
|
this.ghostPreview = this.createGhostPreview();
|
||||||
} else {
|
} else {
|
||||||
// Saves reference to parent state
|
// Saves reference to parent state
|
||||||
const { model } = (<Graph>this.state.view.graph);
|
const { model } = <Graph>this.state.view.graph;
|
||||||
const parent = this.state.cell.getParent();
|
const parent = this.state.cell.getParent();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -1299,7 +1298,7 @@ class VertexHandler {
|
||||||
if (!cell.isEdge()) {
|
if (!cell.isEdge()) {
|
||||||
const style = this.graph.getCurrentCellStyle(cell);
|
const style = this.graph.getCurrentCellStyle(cell);
|
||||||
const total = (style.rotation || 0) + angle;
|
const total = (style.rotation || 0) + angle;
|
||||||
this.graph.setCellStyles('rotation', total, new CellArray(cell));
|
this.graph.setCellStyles('rotation', total, [cell]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let geo = cell.getGeometry();
|
let geo = cell.getGeometry();
|
||||||
|
@ -1877,7 +1876,9 @@ class VertexHandler {
|
||||||
|
|
||||||
// Hides rotation handle during text editing
|
// Hides rotation handle during text editing
|
||||||
this.rotationShape.node.style.visibility =
|
this.rotationShape.node.style.visibility =
|
||||||
(<Graph>this.state.view.graph).isEditing() || !this.handlesVisible ? 'hidden' : '';
|
(<Graph>this.state.view.graph).isEditing() || !this.handlesVisible
|
||||||
|
? 'hidden'
|
||||||
|
: '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1896,7 +1897,9 @@ class VertexHandler {
|
||||||
* Returns true if the given custom handle is visible.
|
* Returns true if the given custom handle is visible.
|
||||||
*/
|
*/
|
||||||
isCustomHandleVisible(handle: CellHandle) {
|
isCustomHandleVisible(handle: CellHandle) {
|
||||||
return !this.graph.isEditing() && (<Graph>this.state.view.graph).getSelectionCount() === 1;
|
return (
|
||||||
|
!this.graph.isEditing() && (<Graph>this.state.view.graph).getSelectionCount() === 1
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
import GraphLayout from './GraphLayout';
|
import GraphLayout from './GraphLayout';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,7 +140,7 @@ class CircleLayout extends GraphLayout {
|
||||||
left = this.x0;
|
left = this.x0;
|
||||||
top = this.y0;
|
top = this.y0;
|
||||||
}
|
}
|
||||||
this.circle(new CellArray(...vertices), r, <number>left, <number>top);
|
this.circle(vertices, r, <number>left, <number>top);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +157,7 @@ class CircleLayout extends GraphLayout {
|
||||||
* of vertices and the given radius. This is called from
|
* of vertices and the given radius. This is called from
|
||||||
* <execute>.
|
* <execute>.
|
||||||
*/
|
*/
|
||||||
circle(vertices: CellArray, r: number, left: number, top: number) {
|
circle(vertices: Cell[], r: number, left: number, top: number) {
|
||||||
const vertexCount = vertices.length;
|
const vertexCount = vertices.length;
|
||||||
const phi = (2 * Math.PI) / vertexCount;
|
const phi = (2 * Math.PI) / vertexCount;
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ import WeightedCellSorter from './util/WeightedCellSorter';
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import { findTreeRoots } from '../../util/treeTraversal';
|
import { findTreeRoots } from '../../util/treeTraversal';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
|
|
||||||
export interface _mxCompactTreeLayoutNode {
|
export interface _mxCompactTreeLayoutNode {
|
||||||
cell?: Cell;
|
cell?: Cell;
|
||||||
|
@ -37,11 +36,11 @@ export interface _mxCompactTreeLayoutNode {
|
||||||
offsetX?: number;
|
offsetX?: number;
|
||||||
offsetY?: number;
|
offsetY?: number;
|
||||||
contour?: {
|
contour?: {
|
||||||
upperTail?: _mxCompactTreeLayoutLine,
|
upperTail?: _mxCompactTreeLayoutLine;
|
||||||
upperHead?: _mxCompactTreeLayoutLine,
|
upperHead?: _mxCompactTreeLayoutLine;
|
||||||
lowerTail?: _mxCompactTreeLayoutLine,
|
lowerTail?: _mxCompactTreeLayoutLine;
|
||||||
lowerHead?: _mxCompactTreeLayoutLine,
|
lowerHead?: _mxCompactTreeLayoutLine;
|
||||||
[key: string]: any,
|
[key: string]: any;
|
||||||
};
|
};
|
||||||
next?: _mxCompactTreeLayoutNode;
|
next?: _mxCompactTreeLayoutNode;
|
||||||
child?: _mxCompactTreeLayoutNode;
|
child?: _mxCompactTreeLayoutNode;
|
||||||
|
@ -212,7 +211,7 @@ export class CompactTreeLayout extends GraphLayout {
|
||||||
* An array of the maximum height of cells (relative to the layout direction)
|
* An array of the maximum height of cells (relative to the layout direction)
|
||||||
* per rank
|
* per rank
|
||||||
*/
|
*/
|
||||||
maxRankHeight: CellArray | null = null;
|
maxRankHeight: Cell[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The cell to use as the root of the tree
|
* The cell to use as the root of the tree
|
||||||
|
@ -232,9 +231,7 @@ export class CompactTreeLayout extends GraphLayout {
|
||||||
* @param vertex {@link mxCell} whose ignored state should be returned.
|
* @param vertex {@link mxCell} whose ignored state should be returned.
|
||||||
*/
|
*/
|
||||||
isVertexIgnored(vertex: Cell): boolean {
|
isVertexIgnored(vertex: Cell): boolean {
|
||||||
return (
|
return super.isVertexIgnored(vertex) || vertex.getConnections().length === 0;
|
||||||
super.isVertexIgnored(vertex) || vertex.getConnections().length === 0
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -320,7 +317,7 @@ export class CompactTreeLayout extends GraphLayout {
|
||||||
this.node = this.dfs(this.root, parent);
|
this.node = this.dfs(this.root, parent);
|
||||||
|
|
||||||
if (this.alignRanks) {
|
if (this.alignRanks) {
|
||||||
this.maxRankHeight = new CellArray();
|
this.maxRankHeight = [];
|
||||||
this.findRankHeights(this.node, 0);
|
this.findRankHeights(this.node, 0);
|
||||||
this.setCellHeights(this.node, 0);
|
this.setCellHeights(this.node, 0);
|
||||||
}
|
}
|
||||||
|
@ -410,7 +407,7 @@ export class CompactTreeLayout extends GraphLayout {
|
||||||
/**
|
/**
|
||||||
* Called if {@link sortEdges} is true to sort the array of outgoing edges in place.
|
* Called if {@link sortEdges} is true to sort the array of outgoing edges in place.
|
||||||
*/
|
*/
|
||||||
sortOutgoingEdges(source: Cell, edges: CellArray): void {
|
sortOutgoingEdges(source: Cell, edges: Cell[]): void {
|
||||||
const lookup = new Dictionary();
|
const lookup = new Dictionary();
|
||||||
|
|
||||||
edges.sort((e1, e2) => {
|
edges.sort((e1, e2) => {
|
||||||
|
@ -439,7 +436,7 @@ export class CompactTreeLayout extends GraphLayout {
|
||||||
* direction) of cells in each rank
|
* direction) of cells in each rank
|
||||||
*/
|
*/
|
||||||
findRankHeights(node: any, rank: number): void {
|
findRankHeights(node: any, rank: number): void {
|
||||||
const maxRankHeight = <CellArray>this.maxRankHeight;
|
const maxRankHeight = this.maxRankHeight;
|
||||||
if (maxRankHeight[rank] == null || maxRankHeight[rank] < node.height) {
|
if (maxRankHeight[rank] == null || maxRankHeight[rank] < node.height) {
|
||||||
maxRankHeight[rank] = node.height;
|
maxRankHeight[rank] = node.height;
|
||||||
}
|
}
|
||||||
|
@ -456,7 +453,7 @@ export class CompactTreeLayout extends GraphLayout {
|
||||||
* direction) when the tops of each rank are to be aligned
|
* direction) when the tops of each rank are to be aligned
|
||||||
*/
|
*/
|
||||||
setCellHeights(node: any, rank: number): void {
|
setCellHeights(node: any, rank: number): void {
|
||||||
const maxRankHeight = <CellArray>this.maxRankHeight;
|
const maxRankHeight = this.maxRankHeight;
|
||||||
if (maxRankHeight[rank] != null && maxRankHeight[rank] > node.height) {
|
if (maxRankHeight[rank] != null && maxRankHeight[rank] > node.height) {
|
||||||
node.height = maxRankHeight[rank];
|
node.height = maxRankHeight[rank];
|
||||||
}
|
}
|
||||||
|
@ -557,7 +554,12 @@ export class CompactTreeLayout extends GraphLayout {
|
||||||
* Starts the actual compact tree layout algorithm
|
* Starts the actual compact tree layout algorithm
|
||||||
* at the given node.
|
* at the given node.
|
||||||
*/
|
*/
|
||||||
horizontalLayout(node: any, x0: number, y0: number, bounds: Rectangle | null=null): Rectangle | null {
|
horizontalLayout(
|
||||||
|
node: any,
|
||||||
|
x0: number,
|
||||||
|
y0: number,
|
||||||
|
bounds: Rectangle | null = null
|
||||||
|
): Rectangle | null {
|
||||||
node.x += x0 + node.offsetX;
|
node.x += x0 + node.offsetX;
|
||||||
node.y += y0 + node.offsetY;
|
node.y += y0 + node.offsetY;
|
||||||
bounds = this.apply(node, bounds);
|
bounds = this.apply(node, bounds);
|
||||||
|
@ -586,7 +588,7 @@ export class CompactTreeLayout extends GraphLayout {
|
||||||
parent: _mxCompactTreeLayoutNode | null,
|
parent: _mxCompactTreeLayoutNode | null,
|
||||||
x0: number,
|
x0: number,
|
||||||
y0: number,
|
y0: number,
|
||||||
bounds: Rectangle | null=null
|
bounds: Rectangle | null = null
|
||||||
): Rectangle | null {
|
): Rectangle | null {
|
||||||
node.x = <number>node.x + x0 + <number>node.offsetY;
|
node.x = <number>node.x + x0 + <number>node.offsetY;
|
||||||
node.y = <number>node.y + y0 + <number>node.offsetX;
|
node.y = <number>node.y + y0 + <number>node.offsetX;
|
||||||
|
@ -824,7 +826,10 @@ export class CompactTreeLayout extends GraphLayout {
|
||||||
* Starts the actual compact tree layout algorithm
|
* Starts the actual compact tree layout algorithm
|
||||||
* at the given node.
|
* at the given node.
|
||||||
*/
|
*/
|
||||||
apply(node: _mxCompactTreeLayoutNode, bounds: Rectangle | null=null): Rectangle | null {
|
apply(
|
||||||
|
node: _mxCompactTreeLayoutNode,
|
||||||
|
bounds: Rectangle | null = null
|
||||||
|
): Rectangle | null {
|
||||||
const model = this.graph.getDataModel();
|
const model = this.graph.getDataModel();
|
||||||
const cell = <Cell>node.cell;
|
const cell = <Cell>node.cell;
|
||||||
let g: Rectangle = <Rectangle>cell.getGeometry();
|
let g: Rectangle = <Rectangle>cell.getGeometry();
|
||||||
|
@ -863,11 +868,11 @@ export class CompactTreeLayout extends GraphLayout {
|
||||||
* Starts the actual compact tree layout algorithm
|
* Starts the actual compact tree layout algorithm
|
||||||
* at the given node.
|
* at the given node.
|
||||||
*/
|
*/
|
||||||
createLine(dx: number, dy: number, next: any=null): _mxCompactTreeLayoutLine {
|
createLine(dx: number, dy: number, next: any = null): _mxCompactTreeLayoutLine {
|
||||||
let line: _mxCompactTreeLayoutLine = {
|
let line: _mxCompactTreeLayoutLine = {
|
||||||
dx,
|
dx,
|
||||||
dy,
|
dy,
|
||||||
next
|
next,
|
||||||
};
|
};
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
@ -878,7 +883,7 @@ export class CompactTreeLayout extends GraphLayout {
|
||||||
* a padding.
|
* a padding.
|
||||||
*/
|
*/
|
||||||
adjustParents(): void {
|
adjustParents(): void {
|
||||||
const tmp = new CellArray();
|
const tmp = [];
|
||||||
|
|
||||||
for (const id in this.parentsChanged) {
|
for (const id in this.parentsChanged) {
|
||||||
tmp.push(this.parentsChanged[id]);
|
tmp.push(this.parentsChanged[id]);
|
||||||
|
|
|
@ -19,7 +19,6 @@ import ObjectIdentity from '../../util/ObjectIdentity';
|
||||||
import GraphLayout from './GraphLayout';
|
import GraphLayout from './GraphLayout';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends {@link GraphLayout} to implement a fast organic layout algorithm.
|
* Extends {@link GraphLayout} to implement a fast organic layout algorithm.
|
||||||
|
@ -106,7 +105,7 @@ class MxFastOrganicLayout extends GraphLayout {
|
||||||
/**
|
/**
|
||||||
* An array of all vertices to be laid out.
|
* An array of all vertices to be laid out.
|
||||||
*/
|
*/
|
||||||
vertexArray: CellArray = new CellArray();
|
vertexArray: Cell[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array of locally stored X co-ordinate displacements for the vertices.
|
* An array of locally stored X co-ordinate displacements for the vertices.
|
||||||
|
@ -172,7 +171,7 @@ class MxFastOrganicLayout extends GraphLayout {
|
||||||
*/
|
*/
|
||||||
execute(parent: Cell) {
|
execute(parent: Cell) {
|
||||||
const model = this.graph.getDataModel();
|
const model = this.graph.getDataModel();
|
||||||
this.vertexArray = new CellArray();
|
this.vertexArray = [];
|
||||||
let cells = this.graph.getChildVertices(parent);
|
let cells = this.graph.getChildVertices(parent);
|
||||||
|
|
||||||
for (let i = 0; i < cells.length; i += 1) {
|
for (let i = 0; i < cells.length; i += 1) {
|
||||||
|
|
|
@ -22,7 +22,6 @@ import Geometry from '../geometry/Geometry';
|
||||||
import Point from '../geometry/Point';
|
import Point from '../geometry/Point';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class GraphLayout
|
* @class GraphLayout
|
||||||
|
@ -241,14 +240,14 @@ class GraphLayout {
|
||||||
* Disables or enables the edge style of the given edge.
|
* Disables or enables the edge style of the given edge.
|
||||||
*/
|
*/
|
||||||
setEdgeStyleEnabled(edge: Cell, value: any): void {
|
setEdgeStyleEnabled(edge: Cell, value: any): void {
|
||||||
this.graph.setCellStyles('noEdgeStyle', value ? '0' : '1', new CellArray(edge));
|
this.graph.setCellStyles('noEdgeStyle', value ? '0' : '1', [edge]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disables or enables orthogonal end segments of the given edge.
|
* Disables or enables orthogonal end segments of the given edge.
|
||||||
*/
|
*/
|
||||||
setOrthogonalEdge(edge: Cell, value: any): void {
|
setOrthogonalEdge(edge: Cell, value: any): void {
|
||||||
this.graph.setCellStyles('orthogonal', value ? '1' : '0', new CellArray(edge));
|
this.graph.setCellStyles('orthogonal', value ? '1' : '0', [edge]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -419,7 +418,7 @@ class GraphLayout {
|
||||||
* Shortcut to {@link Graph#updateGroupBounds} with moveGroup set to true.
|
* Shortcut to {@link Graph#updateGroupBounds} with moveGroup set to true.
|
||||||
*/
|
*/
|
||||||
arrangeGroups(
|
arrangeGroups(
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
border: number,
|
border: number,
|
||||||
topBorder: number,
|
topBorder: number,
|
||||||
rightBorder: number,
|
rightBorder: number,
|
||||||
|
|
|
@ -26,7 +26,6 @@ import MinimumCycleRemover from './hierarchical/MinimumCycleRemover';
|
||||||
import MedianHybridCrossingReduction from './hierarchical/MedianHybridCrossingReduction';
|
import MedianHybridCrossingReduction from './hierarchical/MedianHybridCrossingReduction';
|
||||||
import CoordinateAssignment from './hierarchical/CoordinateAssignment';
|
import CoordinateAssignment from './hierarchical/CoordinateAssignment';
|
||||||
import { Graph } from '../../view/Graph';
|
import { Graph } from '../../view/Graph';
|
||||||
import CellArray from '../../view/cell/CellArray';
|
|
||||||
import Cell from '../../view/cell/Cell';
|
import Cell from '../../view/cell/Cell';
|
||||||
import GraphHierarchyNode from './datatypes/GraphHierarchyNode';
|
import GraphHierarchyNode from './datatypes/GraphHierarchyNode';
|
||||||
|
|
||||||
|
@ -48,8 +47,8 @@ import GraphHierarchyNode from './datatypes/GraphHierarchyNode';
|
||||||
class HierarchicalLayout extends GraphLayout {
|
class HierarchicalLayout extends GraphLayout {
|
||||||
constructor(
|
constructor(
|
||||||
graph: Graph,
|
graph: Graph,
|
||||||
orientation: DIRECTION=DIRECTION.NORTH,
|
orientation: DIRECTION = DIRECTION.NORTH,
|
||||||
deterministic: boolean=true
|
deterministic: boolean = true
|
||||||
) {
|
) {
|
||||||
super(graph);
|
super(graph);
|
||||||
this.orientation = orientation;
|
this.orientation = orientation;
|
||||||
|
@ -63,7 +62,7 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
/**
|
/**
|
||||||
* Holds the array of <Cell> that this layout contains.
|
* Holds the array of <Cell> that this layout contains.
|
||||||
*/
|
*/
|
||||||
roots: CellArray | null = null;
|
roots: Cell[] | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies if the parent should be resized after the layout so that it
|
* Specifies if the parent should be resized after the layout so that it
|
||||||
|
@ -151,7 +150,7 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
/**
|
/**
|
||||||
* A cache of edges whose source terminal is the key
|
* A cache of edges whose source terminal is the key
|
||||||
*/
|
*/
|
||||||
edgesCache: Dictionary<Cell, CellArray> = new Dictionary();
|
edgesCache: Dictionary<Cell, Cell[]> = new Dictionary();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A cache of edges whose source terminal is the key
|
* A cache of edges whose source terminal is the key
|
||||||
|
@ -182,7 +181,7 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
* @param parent Parent <Cell> that contains the children to be laid out.
|
* @param parent Parent <Cell> that contains the children to be laid out.
|
||||||
* @param roots Optional starting roots of the layout.
|
* @param roots Optional starting roots of the layout.
|
||||||
*/
|
*/
|
||||||
execute(parent: Cell, roots: CellArray | null=null): void {
|
execute(parent: Cell, roots: Cell[] | Cell | null = null): void {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
const { model } = this.graph;
|
const { model } = this.graph;
|
||||||
this.edgesCache = new Dictionary();
|
this.edgesCache = new Dictionary();
|
||||||
|
@ -190,7 +189,7 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
this.edgesTargetTermCache = new Dictionary();
|
this.edgesTargetTermCache = new Dictionary();
|
||||||
|
|
||||||
if (roots != null && !(roots instanceof Array)) {
|
if (roots != null && !(roots instanceof Array)) {
|
||||||
roots = new CellArray(roots);
|
roots = [roots];
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the roots are set and the parent is set, only
|
// If the roots are set and the parent is set, only
|
||||||
|
@ -223,7 +222,7 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roots != null) {
|
if (roots != null) {
|
||||||
const rootsCopy = new CellArray();
|
const rootsCopy = [];
|
||||||
|
|
||||||
for (let i = 0; i < roots.length; i += 1) {
|
for (let i = 0; i < roots.length; i += 1) {
|
||||||
const ancestor = parent != null ? parent.isAncestor(roots[i]) : true;
|
const ancestor = parent != null ? parent.isAncestor(roots[i]) : true;
|
||||||
|
@ -240,7 +239,7 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
this.run(parent);
|
this.run(parent);
|
||||||
|
|
||||||
if (this.resizeParent && !parent.isCollapsed()) {
|
if (this.resizeParent && !parent.isCollapsed()) {
|
||||||
this.graph.updateGroupBounds(new CellArray(parent), this.parentBorder, this.moveParent);
|
this.graph.updateGroupBounds([parent], this.parentBorder, this.moveParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maintaining parent location
|
// Maintaining parent location
|
||||||
|
@ -269,8 +268,8 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
* @param parent <Cell> whose children should be checked.
|
* @param parent <Cell> whose children should be checked.
|
||||||
* @param vertices array of vertices to limit search to
|
* @param vertices array of vertices to limit search to
|
||||||
*/
|
*/
|
||||||
findRoots(parent: Cell, vertices: CellArray): CellArray {
|
findRoots(parent: Cell, vertices: Cell[]): Cell[] {
|
||||||
const roots = new CellArray();
|
const roots = [];
|
||||||
|
|
||||||
if (parent != null && vertices != null) {
|
if (parent != null && vertices != null) {
|
||||||
const { model } = this.graph;
|
const { model } = this.graph;
|
||||||
|
@ -320,14 +319,14 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
*
|
*
|
||||||
* @param cell <Cell> whose edges should be returned.
|
* @param cell <Cell> whose edges should be returned.
|
||||||
*/
|
*/
|
||||||
getEdges(cell: Cell): CellArray {
|
getEdges(cell: Cell) {
|
||||||
const cachedEdges = this.edgesCache.get(cell);
|
const cachedEdges = this.edgesCache.get(cell);
|
||||||
if (cachedEdges != null) {
|
if (cachedEdges != null) {
|
||||||
return cachedEdges;
|
return cachedEdges;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { model } = this.graph;
|
const { model } = this.graph;
|
||||||
let edges = new CellArray();
|
let edges: Cell[] = [];
|
||||||
const isCollapsed = cell.isCollapsed();
|
const isCollapsed = cell.isCollapsed();
|
||||||
const childCount = cell.getChildCount();
|
const childCount = cell.getChildCount();
|
||||||
|
|
||||||
|
@ -342,7 +341,7 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
edges = edges.concat(cell.getEdges(true, true));
|
edges = edges.concat(cell.getEdges(true, true));
|
||||||
const result = new CellArray();
|
const result = [];
|
||||||
|
|
||||||
for (let i = 0; i < edges.length; i += 1) {
|
for (let i = 0; i < edges.length; i += 1) {
|
||||||
const source = this.getVisibleTerminal(edges[i], true);
|
const source = this.getVisibleTerminal(edges[i], true);
|
||||||
|
@ -423,7 +422,7 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
const filledVertexSet = Object();
|
const filledVertexSet = Object();
|
||||||
this.filterDescendants(parent, filledVertexSet);
|
this.filterDescendants(parent, filledVertexSet);
|
||||||
|
|
||||||
this.roots = new CellArray();
|
this.roots = [];
|
||||||
let filledVertexSetEmpty = true;
|
let filledVertexSetEmpty = true;
|
||||||
|
|
||||||
// Poor man's isSetEmpty
|
// Poor man's isSetEmpty
|
||||||
|
@ -472,7 +471,7 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Find vertex set as directed traversal from roots
|
// Find vertex set as directed traversal from roots
|
||||||
const roots = <CellArray>this.roots;
|
const roots = this.roots as Cell[]; // NEED CHECK - roots cannot be null
|
||||||
|
|
||||||
for (let i = 0; i < roots.length; i += 1) {
|
for (let i = 0; i < roots.length; i += 1) {
|
||||||
const vertexSet = Object();
|
const vertexSet = Object();
|
||||||
|
@ -498,7 +497,7 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
|
|
||||||
for (let i = 0; i < hierarchyVertices.length; i += 1) {
|
for (let i = 0; i < hierarchyVertices.length; i += 1) {
|
||||||
const vertexSet = hierarchyVertices[i];
|
const vertexSet = hierarchyVertices[i];
|
||||||
const tmp = new CellArray();
|
const tmp = [];
|
||||||
|
|
||||||
for (var key in vertexSet) {
|
for (var key in vertexSet) {
|
||||||
tmp.push(vertexSet[key]);
|
tmp.push(vertexSet[key]);
|
||||||
|
@ -507,7 +506,7 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
this.model = new GraphHierarchyModel(
|
this.model = new GraphHierarchyModel(
|
||||||
this,
|
this,
|
||||||
tmp,
|
tmp,
|
||||||
<CellArray>this.roots,
|
this.roots as Cell[],
|
||||||
parent,
|
parent,
|
||||||
this.tightenToSource
|
this.tightenToSource
|
||||||
);
|
);
|
||||||
|
@ -566,10 +565,10 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
* target -
|
* target -
|
||||||
* directed -
|
* directed -
|
||||||
*/
|
*/
|
||||||
getEdgesBetween(source: Cell, target: Cell, directed: boolean): CellArray {
|
getEdgesBetween(source: Cell, target: Cell, directed: boolean): Cell[] {
|
||||||
directed = directed != null ? directed : false;
|
directed = directed != null ? directed : false;
|
||||||
const edges = this.getEdges(source);
|
const edges = this.getEdges(source);
|
||||||
const result = new CellArray();
|
const result = [];
|
||||||
|
|
||||||
// Checks if the edge is connected to the correct
|
// Checks if the edge is connected to the correct
|
||||||
// cell and returns the first match
|
// cell and returns the first match
|
||||||
|
@ -604,12 +603,12 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
traverse(
|
traverse(
|
||||||
vertex: Cell,
|
vertex: Cell,
|
||||||
directed: boolean=false,
|
directed: boolean = false,
|
||||||
edge: Cell | null=null,
|
edge: Cell | null = null,
|
||||||
allVertices: { [key: string]: Cell } | null=null,
|
allVertices: { [key: string]: Cell } | null = null,
|
||||||
currentComp: { [key: string]: (Cell | null) },
|
currentComp: { [key: string]: Cell | null },
|
||||||
hierarchyVertices: GraphHierarchyNode[],
|
hierarchyVertices: GraphHierarchyNode[],
|
||||||
filledVertexSet: { [key: string]: Cell } | null=null
|
filledVertexSet: { [key: string]: Cell } | null = null
|
||||||
) {
|
) {
|
||||||
if (vertex != null && allVertices != null) {
|
if (vertex != null && allVertices != null) {
|
||||||
// Has this vertex been seen before in any traversal
|
// Has this vertex been seen before in any traversal
|
||||||
|
|
|
@ -29,7 +29,6 @@ import EventObject from '../event/EventObject';
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import Rectangle from '../geometry/Rectangle';
|
import Rectangle from '../geometry/Rectangle';
|
||||||
import { getClientX, getClientY } from '../../util/EventUtils';
|
import { getClientX, getClientY } from '../../util/EventUtils';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import GraphLayout from './GraphLayout';
|
import GraphLayout from './GraphLayout';
|
||||||
import UndoableEdit from '../undoable_changes/UndoableEdit';
|
import UndoableEdit from '../undoable_changes/UndoableEdit';
|
||||||
|
@ -225,7 +224,7 @@ class LayoutManager extends EventSource {
|
||||||
* @param cell Array of {@link Cell} that have been moved.
|
* @param cell Array of {@link Cell} that have been moved.
|
||||||
* @param evt Mouse event that represents the mousedown.
|
* @param evt Mouse event that represents the mousedown.
|
||||||
*/
|
*/
|
||||||
cellsMoved(cells: CellArray, evt: MouseEvent) {
|
cellsMoved(cells: Cell[], evt: MouseEvent) {
|
||||||
if (cells.length > 0 && evt) {
|
if (cells.length > 0 && evt) {
|
||||||
const point = convertPoint(
|
const point = convertPoint(
|
||||||
this.getGraph().container,
|
this.getGraph().container,
|
||||||
|
@ -250,9 +249,9 @@ class LayoutManager extends EventSource {
|
||||||
* @param bounds {@link mxRectangle} taht represents the new bounds.
|
* @param bounds {@link mxRectangle} taht represents the new bounds.
|
||||||
*/
|
*/
|
||||||
cellsResized(
|
cellsResized(
|
||||||
cells: CellArray | null = null,
|
cells: Cell[] | null = null,
|
||||||
bounds: Rectangle[] | null = null,
|
bounds: Rectangle[] | null = null,
|
||||||
prev: CellArray | null = null
|
prev: Cell[] | null = null
|
||||||
) {
|
) {
|
||||||
if (cells && bounds) {
|
if (cells && bounds) {
|
||||||
for (let i = 0; i < cells.length; i += 1) {
|
for (let i = 0; i < cells.length; i += 1) {
|
||||||
|
@ -267,11 +266,11 @@ class LayoutManager extends EventSource {
|
||||||
/**
|
/**
|
||||||
* Returns the cells for which a layout should be executed.
|
* Returns the cells for which a layout should be executed.
|
||||||
*/
|
*/
|
||||||
getCellsForChanges(changes: any[]): CellArray {
|
getCellsForChanges(changes: any[]): Cell[] {
|
||||||
let result: CellArray = new CellArray();
|
let result: Cell[] = [];
|
||||||
for (const change of changes) {
|
for (const change of changes) {
|
||||||
if (change instanceof RootChange) {
|
if (change instanceof RootChange) {
|
||||||
return new CellArray();
|
return [];
|
||||||
}
|
}
|
||||||
result = result.concat(this.getCellsForChange(change));
|
result = result.concat(this.getCellsForChange(change));
|
||||||
}
|
}
|
||||||
|
@ -283,7 +282,7 @@ class LayoutManager extends EventSource {
|
||||||
* changes.
|
* changes.
|
||||||
* @param change mxChildChange|mxTerminalChange|mxVisibleChange|...
|
* @param change mxChildChange|mxTerminalChange|mxVisibleChange|...
|
||||||
*/
|
*/
|
||||||
getCellsForChange(change: any): CellArray {
|
getCellsForChange(change: any): Cell[] {
|
||||||
if (change instanceof ChildChange) {
|
if (change instanceof ChildChange) {
|
||||||
return this.addCellsWithLayout(
|
return this.addCellsWithLayout(
|
||||||
change.child,
|
change.child,
|
||||||
|
@ -299,23 +298,20 @@ class LayoutManager extends EventSource {
|
||||||
return this.addCellsWithLayout(change.cell);
|
return this.addCellsWithLayout(change.cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CellArray();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds all ancestors of the given cell that have a layout.
|
* Adds all ancestors of the given cell that have a layout.
|
||||||
*/
|
*/
|
||||||
addCellsWithLayout(cell: Cell | null, result: CellArray = new CellArray()) {
|
addCellsWithLayout(cell: Cell | null, result: Cell[] = []) {
|
||||||
return this.addDescendantsWithLayout(cell, this.addAncestorsWithLayout(cell, result));
|
return this.addDescendantsWithLayout(cell, this.addAncestorsWithLayout(cell, result));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds all ancestors of the given cell that have a layout.
|
* Adds all ancestors of the given cell that have a layout.
|
||||||
*/
|
*/
|
||||||
addAncestorsWithLayout(
|
addAncestorsWithLayout(cell: Cell | null, result: Cell[] = []): Cell[] {
|
||||||
cell: Cell | null,
|
|
||||||
result: CellArray = new CellArray()
|
|
||||||
): CellArray {
|
|
||||||
if (cell) {
|
if (cell) {
|
||||||
const layout = this.hasLayout(cell);
|
const layout = this.hasLayout(cell);
|
||||||
|
|
||||||
|
@ -333,7 +329,7 @@ class LayoutManager extends EventSource {
|
||||||
/**
|
/**
|
||||||
* Adds all descendants of the given cell that have a layout.
|
* Adds all descendants of the given cell that have a layout.
|
||||||
*/
|
*/
|
||||||
addDescendantsWithLayout(cell: Cell | null, result: CellArray = new CellArray()) {
|
addDescendantsWithLayout(cell: Cell | null, result: Cell[] = []) {
|
||||||
if (cell && this.hasLayout(cell)) {
|
if (cell && this.hasLayout(cell)) {
|
||||||
for (let i = 0; i < cell.getChildCount(); i += 1) {
|
for (let i = 0; i < cell.getChildCount(); i += 1) {
|
||||||
const child = <Cell>cell.getChildAt(i);
|
const child = <Cell>cell.getChildAt(i);
|
||||||
|
@ -351,16 +347,16 @@ class LayoutManager extends EventSource {
|
||||||
/**
|
/**
|
||||||
* Executes the given layout on the given parent.
|
* Executes the given layout on the given parent.
|
||||||
*/
|
*/
|
||||||
executeLayoutForCells(cells: CellArray) {
|
executeLayoutForCells(cells: Cell[]) {
|
||||||
const sorted = sortCells(cells, false);
|
const sorted = sortCells(cells, false);
|
||||||
this.layoutCells(sorted, true);
|
this.layoutCells(sorted, true);
|
||||||
this.layoutCells(new CellArray(...sorted.reverse()), false);
|
this.layoutCells(sorted.reverse(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes all layouts which have been scheduled during the changes.
|
* Executes all layouts which have been scheduled during the changes.
|
||||||
*/
|
*/
|
||||||
layoutCells(cells: CellArray, bubble: boolean = false) {
|
layoutCells(cells: Cell[], bubble: boolean = false) {
|
||||||
if (cells.length > 0) {
|
if (cells.length > 0) {
|
||||||
// Invokes the layouts while removing duplicates
|
// Invokes the layouts while removing duplicates
|
||||||
const model = this.getGraph().getDataModel();
|
const model = this.getGraph().getDataModel();
|
||||||
|
|
|
@ -20,7 +20,6 @@ import Point from '../geometry/Point';
|
||||||
import GraphLayout from './GraphLayout';
|
import GraphLayout from './GraphLayout';
|
||||||
import ObjectIdentity from '../../util/ObjectIdentity';
|
import ObjectIdentity from '../../util/ObjectIdentity';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import Geometry from '../geometry/Geometry';
|
import Geometry from '../geometry/Geometry';
|
||||||
|
|
||||||
|
@ -84,7 +83,7 @@ class ParallelEdgeLayout extends GraphLayout {
|
||||||
/**
|
/**
|
||||||
* Implements {@link GraphLayout#execute}.
|
* Implements {@link GraphLayout#execute}.
|
||||||
*/
|
*/
|
||||||
execute(parent: Cell, cells: CellArray | null=null): void {
|
execute(parent: Cell, cells: Cell[] | null = null): void {
|
||||||
const lookup = this.findParallels(parent, cells);
|
const lookup = this.findParallels(parent, cells);
|
||||||
|
|
||||||
this.graph.model.beginUpdate();
|
this.graph.model.beginUpdate();
|
||||||
|
@ -104,7 +103,7 @@ class ParallelEdgeLayout extends GraphLayout {
|
||||||
/**
|
/**
|
||||||
* Finds the parallel edges in the given parent.
|
* Finds the parallel edges in the given parent.
|
||||||
*/
|
*/
|
||||||
findParallels(parent: Cell, cells: CellArray | null=null) {
|
findParallels(parent: Cell, cells: Cell[] | null = null) {
|
||||||
const lookup: any = [];
|
const lookup: any = [];
|
||||||
|
|
||||||
const addCell = (cell: Cell) => {
|
const addCell = (cell: Cell) => {
|
||||||
|
@ -178,7 +177,7 @@ class ParallelEdgeLayout extends GraphLayout {
|
||||||
/**
|
/**
|
||||||
* Lays out the parallel edges in the given array.
|
* Lays out the parallel edges in the given array.
|
||||||
*/
|
*/
|
||||||
layout(parallels: CellArray) {
|
layout(parallels: Cell[]) {
|
||||||
const edge = parallels[0];
|
const edge = parallels[0];
|
||||||
const view = this.graph.getView();
|
const view = this.graph.getView();
|
||||||
const model = this.graph.getDataModel();
|
const model = this.graph.getDataModel();
|
||||||
|
|
|
@ -24,7 +24,6 @@ import { DEFAULT_STARTSIZE } from '../../util/Constants';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import Geometry from '../geometry/Geometry';
|
import Geometry from '../geometry/Geometry';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends {@link GraphLayout} to create a horizontal or vertical stack of the
|
* Extends {@link GraphLayout} to create a horizontal or vertical stack of the
|
||||||
|
@ -46,11 +45,11 @@ import CellArray from '../cell/CellArray';
|
||||||
class StackLayout extends GraphLayout {
|
class StackLayout extends GraphLayout {
|
||||||
constructor(
|
constructor(
|
||||||
graph: Graph,
|
graph: Graph,
|
||||||
horizontal: boolean | null=null,
|
horizontal: boolean | null = null,
|
||||||
spacing: number | null=null,
|
spacing: number | null = null,
|
||||||
x0: number | null=null,
|
x0: number | null = null,
|
||||||
y0: number | null=null,
|
y0: number | null = null,
|
||||||
border: number | null=null
|
border: number | null = null
|
||||||
) {
|
) {
|
||||||
super(graph);
|
super(graph);
|
||||||
this.horizontal = horizontal != null ? horizontal : true;
|
this.horizontal = horizontal != null ? horizontal : true;
|
||||||
|
@ -231,10 +230,10 @@ class StackLayout extends GraphLayout {
|
||||||
/**
|
/**
|
||||||
* Returns the cells to be layouted.
|
* Returns the cells to be layouted.
|
||||||
*/
|
*/
|
||||||
getLayoutCells(parent: Cell): CellArray {
|
getLayoutCells(parent: Cell): Cell[] {
|
||||||
const model = this.graph.getDataModel();
|
const model = this.graph.getDataModel();
|
||||||
const childCount = parent.getChildCount();
|
const childCount = parent.getChildCount();
|
||||||
const cells = new CellArray();
|
const cells = [];
|
||||||
|
|
||||||
for (let i = 0; i < childCount; i += 1) {
|
for (let i = 0; i < childCount; i += 1) {
|
||||||
const child = parent.getChildAt(i);
|
const child = parent.getChildAt(i);
|
||||||
|
@ -252,12 +251,12 @@ class StackLayout extends GraphLayout {
|
||||||
return this.horizontal
|
return this.horizontal
|
||||||
? geo1.x === geo2.x
|
? geo1.x === geo2.x
|
||||||
? 0
|
? 0
|
||||||
: (geo1.x > geo2.x && geo2.x > 0)
|
: geo1.x > geo2.x && geo2.x > 0
|
||||||
? 1
|
? 1
|
||||||
: -1
|
: -1
|
||||||
: geo1.y === geo2.y
|
: geo1.y === geo2.y
|
||||||
? 0
|
? 0
|
||||||
: (geo1.y > geo2.y && geo2.y > 0)
|
: geo1.y > geo2.y && geo2.y > 0
|
||||||
? 1
|
? 1
|
||||||
: -1;
|
: -1;
|
||||||
});
|
});
|
||||||
|
|
|
@ -28,7 +28,6 @@ import MedianHybridCrossingReduction from './hierarchical/MedianHybridCrossingRe
|
||||||
import CoordinateAssignment from './hierarchical/CoordinateAssignment';
|
import CoordinateAssignment from './hierarchical/CoordinateAssignment';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import Geometry from '../../view/geometry/Geometry';
|
import Geometry from '../../view/geometry/Geometry';
|
||||||
import GraphHierarchyNode from './datatypes/GraphHierarchyNode';
|
import GraphHierarchyNode from './datatypes/GraphHierarchyNode';
|
||||||
|
|
||||||
|
@ -48,7 +47,11 @@ import GraphHierarchyNode from './datatypes/GraphHierarchyNode';
|
||||||
* deterministic. Default is true.
|
* deterministic. Default is true.
|
||||||
*/
|
*/
|
||||||
class SwimlaneLayout extends GraphLayout {
|
class SwimlaneLayout extends GraphLayout {
|
||||||
constructor(graph: Graph, orientation: DIRECTION | null, deterministic: boolean = true) {
|
constructor(
|
||||||
|
graph: Graph,
|
||||||
|
orientation: DIRECTION | null,
|
||||||
|
deterministic: boolean = true
|
||||||
|
) {
|
||||||
super(graph);
|
super(graph);
|
||||||
this.orientation = orientation != null ? orientation : DIRECTION.NORTH;
|
this.orientation = orientation != null ? orientation : DIRECTION.NORTH;
|
||||||
this.deterministic = deterministic != null ? deterministic : true;
|
this.deterministic = deterministic != null ? deterministic : true;
|
||||||
|
@ -61,12 +64,12 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
/**
|
/**
|
||||||
* Holds the array of <Cell> that this layout contains.
|
* Holds the array of <Cell> that this layout contains.
|
||||||
*/
|
*/
|
||||||
roots: CellArray | null = null;
|
roots: Cell[] | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the array of <Cell> of the ordered swimlanes to lay out
|
* Holds the array of <Cell> of the ordered swimlanes to lay out
|
||||||
*/
|
*/
|
||||||
swimlanes: CellArray | null = null;
|
swimlanes: Cell[] | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The cell width of any dummy vertices inserted
|
* The cell width of any dummy vertices inserted
|
||||||
|
@ -159,7 +162,7 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
/**
|
/**
|
||||||
* A cache of edges whose source terminal is the key
|
* A cache of edges whose source terminal is the key
|
||||||
*/
|
*/
|
||||||
edgesCache: Dictionary<Cell, CellArray> = new Dictionary();
|
edgesCache: Dictionary<Cell, Cell[]> = new Dictionary();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A cache of edges whose source terminal is the key
|
* A cache of edges whose source terminal is the key
|
||||||
|
@ -190,7 +193,7 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
* @param parent Parent <Cell> that contains the children to be laid out.
|
* @param parent Parent <Cell> that contains the children to be laid out.
|
||||||
* @param swimlanes Ordered array of swimlanes to be laid out
|
* @param swimlanes Ordered array of swimlanes to be laid out
|
||||||
*/
|
*/
|
||||||
execute(parent: Cell, swimlanes: CellArray | null=null): void {
|
execute(parent: Cell, swimlanes: Cell[] | null = null): void {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
const { model } = this.graph;
|
const { model } = this.graph;
|
||||||
this.edgesCache = new Dictionary();
|
this.edgesCache = new Dictionary();
|
||||||
|
@ -231,7 +234,7 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.swimlanes = swimlanes;
|
this.swimlanes = swimlanes;
|
||||||
const dummyVertices = new CellArray();
|
const dummyVertices = [];
|
||||||
|
|
||||||
// Check the swimlanes all have vertices
|
// Check the swimlanes all have vertices
|
||||||
// in them
|
// in them
|
||||||
|
@ -257,7 +260,7 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
this.run(parent);
|
this.run(parent);
|
||||||
|
|
||||||
if (this.resizeParent && !parent.isCollapsed()) {
|
if (this.resizeParent && !parent.isCollapsed()) {
|
||||||
this.graph.updateGroupBounds(new CellArray(parent), this.parentBorder, this.moveParent);
|
this.graph.updateGroupBounds([parent], this.parentBorder, this.moveParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maintaining parent location
|
// Maintaining parent location
|
||||||
|
@ -285,7 +288,7 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
*/
|
*/
|
||||||
updateGroupBounds(): void {
|
updateGroupBounds(): void {
|
||||||
// Get all vertices and edge in the layout
|
// Get all vertices and edge in the layout
|
||||||
const cells = new CellArray();
|
const cells = [];
|
||||||
const model = <SwimlaneModel>this.model;
|
const model = <SwimlaneModel>this.model;
|
||||||
|
|
||||||
for (const key in model.edgeMapper) {
|
for (const key in model.edgeMapper) {
|
||||||
|
@ -299,7 +302,7 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
|
|
||||||
let layoutBounds = this.graph.getBoundingBoxFromGeometry(cells, true);
|
let layoutBounds = this.graph.getBoundingBoxFromGeometry(cells, true);
|
||||||
const childBounds = [];
|
const childBounds = [];
|
||||||
const swimlanes = <CellArray>this.swimlanes;
|
const swimlanes = this.swimlanes as Cell[];
|
||||||
|
|
||||||
for (let i = 0; i < swimlanes.length; i += 1) {
|
for (let i = 0; i < swimlanes.length; i += 1) {
|
||||||
const lane = swimlanes[i];
|
const lane = swimlanes[i];
|
||||||
|
@ -350,7 +353,8 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
newGeo.y = y;
|
newGeo.y = y;
|
||||||
|
|
||||||
newGeo.width = childBounds[i].width + w + this.interRankCellSpacing / 2;
|
newGeo.width = childBounds[i].width + w + this.interRankCellSpacing / 2;
|
||||||
newGeo.height = (<Rectangle>layoutBounds).height + size.height + 2 * this.parentBorder;
|
newGeo.height =
|
||||||
|
(<Rectangle>layoutBounds).height + size.height + 2 * this.parentBorder;
|
||||||
|
|
||||||
this.graph.model.setGeometry(lane, newGeo);
|
this.graph.model.setGeometry(lane, newGeo);
|
||||||
this.graph.moveCells(children, -x, geo.y - y);
|
this.graph.moveCells(children, -x, geo.y - y);
|
||||||
|
@ -368,8 +372,8 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
* @param parent <Cell> whose children should be checked.
|
* @param parent <Cell> whose children should be checked.
|
||||||
* @param vertices array of vertices to limit search to
|
* @param vertices array of vertices to limit search to
|
||||||
*/
|
*/
|
||||||
findRoots(parent: Cell, vertices: { [key: string]: Cell }): CellArray {
|
findRoots(parent: Cell, vertices: { [key: string]: Cell }): Cell[] {
|
||||||
const roots = new CellArray();
|
const roots = [];
|
||||||
|
|
||||||
if (parent != null && vertices != null) {
|
if (parent != null && vertices != null) {
|
||||||
const { model } = this.graph;
|
const { model } = this.graph;
|
||||||
|
@ -429,14 +433,14 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
*
|
*
|
||||||
* @param cell <Cell> whose edges should be returned.
|
* @param cell <Cell> whose edges should be returned.
|
||||||
*/
|
*/
|
||||||
getEdges(cell: Cell): CellArray {
|
getEdges(cell: Cell): Cell[] {
|
||||||
const cachedEdges = this.edgesCache.get(cell);
|
const cachedEdges = this.edgesCache.get(cell);
|
||||||
|
|
||||||
if (cachedEdges != null) {
|
if (cachedEdges != null) {
|
||||||
return cachedEdges;
|
return cachedEdges;
|
||||||
}
|
}
|
||||||
|
|
||||||
let edges = new CellArray();
|
let edges: Cell[] = [];
|
||||||
const isCollapsed = cell.isCollapsed();
|
const isCollapsed = cell.isCollapsed();
|
||||||
const childCount = cell.getChildCount();
|
const childCount = cell.getChildCount();
|
||||||
|
|
||||||
|
@ -451,7 +455,7 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
edges = edges.concat(cell.getEdges(true, true));
|
edges = edges.concat(cell.getEdges(true, true));
|
||||||
const result = new CellArray();
|
const result = [];
|
||||||
|
|
||||||
for (let i = 0; i < edges.length; i += 1) {
|
for (let i = 0; i < edges.length; i += 1) {
|
||||||
const source = this.getVisibleTerminal(edges[i], true);
|
const source = this.getVisibleTerminal(edges[i], true);
|
||||||
|
@ -462,7 +466,11 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
(source !== target &&
|
(source !== target &&
|
||||||
((target === cell &&
|
((target === cell &&
|
||||||
(this.parent == null ||
|
(this.parent == null ||
|
||||||
this.graph.isValidAncestor(<Cell>source, this.parent, this.traverseAncestors))) ||
|
this.graph.isValidAncestor(
|
||||||
|
<Cell>source,
|
||||||
|
this.parent,
|
||||||
|
this.traverseAncestors
|
||||||
|
))) ||
|
||||||
(source === cell &&
|
(source === cell &&
|
||||||
(this.parent == null ||
|
(this.parent == null ||
|
||||||
this.graph.isValidAncestor(
|
this.graph.isValidAncestor(
|
||||||
|
@ -539,7 +547,7 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
this.filterDescendants(this.swimlanes[i], filledVertexSet);
|
this.filterDescendants(this.swimlanes[i], filledVertexSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.roots = new CellArray();
|
this.roots = [];
|
||||||
let filledVertexSetEmpty = true;
|
let filledVertexSetEmpty = true;
|
||||||
|
|
||||||
// Poor man's isSetEmpty
|
// Poor man's isSetEmpty
|
||||||
|
@ -599,21 +607,36 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Find vertex set as directed traversal from roots
|
// Find vertex set as directed traversal from roots
|
||||||
const roots = <CellArray>this.roots;
|
const roots = this.roots as Cell[];
|
||||||
|
|
||||||
for (let i = 0; i < roots.length; i += 1) {
|
for (let i = 0; i < roots.length; i += 1) {
|
||||||
const vertexSet = Object();
|
const vertexSet = Object();
|
||||||
hierarchyVertices.push(vertexSet);
|
hierarchyVertices.push(vertexSet);
|
||||||
this.traverse(roots[i], true, null, allVertexSet, vertexSet, hierarchyVertices, null, i); // CHECK THIS PARAM!! ====================
|
this.traverse(
|
||||||
|
roots[i],
|
||||||
|
true,
|
||||||
|
null,
|
||||||
|
allVertexSet,
|
||||||
|
vertexSet,
|
||||||
|
hierarchyVertices,
|
||||||
|
null,
|
||||||
|
i
|
||||||
|
); // CHECK THIS PARAM!! ====================
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tmp = new CellArray();
|
const tmp = [];
|
||||||
for (var key in allVertexSet) {
|
for (var key in allVertexSet) {
|
||||||
tmp.push(allVertexSet[key]);
|
tmp.push(allVertexSet[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.model = new SwimlaneModel(this, tmp, <CellArray>this.roots, parent, this.tightenToSource);
|
this.model = new SwimlaneModel(
|
||||||
|
this,
|
||||||
|
tmp,
|
||||||
|
this.roots as Cell[],
|
||||||
|
parent,
|
||||||
|
this.tightenToSource
|
||||||
|
);
|
||||||
|
|
||||||
this.cycleStage(parent);
|
this.cycleStage(parent);
|
||||||
this.layeringStage();
|
this.layeringStage();
|
||||||
|
@ -675,7 +698,7 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
*/
|
*/
|
||||||
getEdgesBetween(source: Cell, target: Cell, directed: boolean = false) {
|
getEdgesBetween(source: Cell, target: Cell, directed: boolean = false) {
|
||||||
const edges = this.getEdges(source);
|
const edges = this.getEdges(source);
|
||||||
const result = new CellArray();
|
const result = [];
|
||||||
|
|
||||||
// Checks if the edge is connected to the correct
|
// Checks if the edge is connected to the correct
|
||||||
// cell and returns the first match
|
// cell and returns the first match
|
||||||
|
@ -710,13 +733,13 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
*/
|
*/
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
traverse(
|
traverse(
|
||||||
vertex: Cell | null=null,
|
vertex: Cell | null = null,
|
||||||
directed: boolean,
|
directed: boolean,
|
||||||
edge: Cell | null,
|
edge: Cell | null,
|
||||||
allVertices: { [key: string]: Cell } | null=null,
|
allVertices: { [key: string]: Cell } | null = null,
|
||||||
currentComp: { [key: string]: Cell },
|
currentComp: { [key: string]: Cell },
|
||||||
hierarchyVertices: GraphHierarchyNode[],
|
hierarchyVertices: GraphHierarchyNode[],
|
||||||
filledVertexSet: { [key: string]: Cell } | null=null,
|
filledVertexSet: { [key: string]: Cell } | null = null,
|
||||||
swimlaneIndex: number
|
swimlaneIndex: number
|
||||||
) {
|
) {
|
||||||
if (vertex != null && allVertices != null) {
|
if (vertex != null && allVertices != null) {
|
||||||
|
@ -752,7 +775,7 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
let otherIndex = 0;
|
let otherIndex = 0;
|
||||||
const swimlanes = <CellArray>this.swimlanes;
|
const swimlanes = this.swimlanes as Cell[];
|
||||||
|
|
||||||
// Get the swimlane index of the other terminal
|
// Get the swimlane index of the other terminal
|
||||||
for (otherIndex = 0; otherIndex < swimlanes.length; otherIndex++) {
|
for (otherIndex = 0; otherIndex < swimlanes.length; otherIndex++) {
|
||||||
|
|
|
@ -22,7 +22,6 @@ import Rectangle from '../geometry/Rectangle';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import EventObject from '../event/EventObject';
|
import EventObject from '../event/EventObject';
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class SwimlaneManager
|
* @class SwimlaneManager
|
||||||
|
@ -211,7 +210,7 @@ class SwimlaneManager extends EventSource {
|
||||||
*
|
*
|
||||||
* @param cell Array of {@link Cell} that have been added.
|
* @param cell Array of {@link Cell} that have been added.
|
||||||
*/
|
*/
|
||||||
cellsAdded(cells: CellArray) {
|
cellsAdded(cells: Cell[]) {
|
||||||
if (cells.length > 0) {
|
if (cells.length > 0) {
|
||||||
const model = this.graph.getDataModel();
|
const model = this.graph.getDataModel();
|
||||||
|
|
||||||
|
@ -264,7 +263,7 @@ class SwimlaneManager extends EventSource {
|
||||||
*
|
*
|
||||||
* @param cells Array of {@link Cell} whose size was changed.
|
* @param cells Array of {@link Cell} whose size was changed.
|
||||||
*/
|
*/
|
||||||
cellsResized(cells: CellArray) {
|
cellsResized(cells: Cell[]) {
|
||||||
if (cells.length > 0) {
|
if (cells.length > 0) {
|
||||||
const model = this.getGraph().getDataModel();
|
const model = this.getGraph().getDataModel();
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ limitations under the License.
|
||||||
|
|
||||||
import GraphAbstractHierarchyCell from './GraphAbstractHierarchyCell';
|
import GraphAbstractHierarchyCell from './GraphAbstractHierarchyCell';
|
||||||
import ObjectIdentity from '../../../util/ObjectIdentity';
|
import ObjectIdentity from '../../../util/ObjectIdentity';
|
||||||
import CellArray from '../../cell/CellArray';
|
|
||||||
import Cell from '../../cell/Cell';
|
import Cell from '../../cell/Cell';
|
||||||
import GraphHierarchyNode from './GraphHierarchyNode';
|
import GraphHierarchyNode from './GraphHierarchyNode';
|
||||||
|
|
||||||
|
@ -27,7 +26,7 @@ class GraphHierarchyEdge extends GraphAbstractHierarchyCell {
|
||||||
* The graph edge(s) this object represents. Parallel edges are all grouped
|
* The graph edge(s) this object represents. Parallel edges are all grouped
|
||||||
* together within one hierarchy edge.
|
* together within one hierarchy edge.
|
||||||
*/
|
*/
|
||||||
edges: CellArray;
|
edges: Cell[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The object identities of the wrapped cells
|
* The object identities of the wrapped cells
|
||||||
|
@ -63,7 +62,7 @@ class GraphHierarchyEdge extends GraphAbstractHierarchyCell {
|
||||||
*
|
*
|
||||||
* edges - a list of real graph edges this abstraction represents
|
* edges - a list of real graph edges this abstraction represents
|
||||||
*/
|
*/
|
||||||
constructor(edges: CellArray) {
|
constructor(edges: Cell[]) {
|
||||||
super();
|
super();
|
||||||
this.edges = edges;
|
this.edges = edges;
|
||||||
this.ids = [];
|
this.ids = [];
|
||||||
|
@ -114,7 +113,9 @@ class GraphHierarchyEdge extends GraphAbstractHierarchyCell {
|
||||||
this.previousLayerConnectedCells[i] = [];
|
this.previousLayerConnectedCells[i] = [];
|
||||||
|
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
this.previousLayerConnectedCells[i].push(this.target as GraphAbstractHierarchyCell);
|
this.previousLayerConnectedCells[i].push(
|
||||||
|
this.target as GraphAbstractHierarchyCell
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.previousLayerConnectedCells[i].push(this);
|
this.previousLayerConnectedCells[i].push(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,14 +109,16 @@ class GraphHierarchyNode extends GraphAbstractHierarchyCell {
|
||||||
getPreviousLayerConnectedCells(layer: number): GraphAbstractHierarchyCell[] {
|
getPreviousLayerConnectedCells(layer: number): GraphAbstractHierarchyCell[] {
|
||||||
if (this.previousLayerConnectedCells == null) {
|
if (this.previousLayerConnectedCells == null) {
|
||||||
this.previousLayerConnectedCells = [];
|
this.previousLayerConnectedCells = [];
|
||||||
this.previousLayerConnectedCells[0] = []; // new CellArray()??
|
this.previousLayerConnectedCells[0] = [];
|
||||||
|
|
||||||
for (let i = 0; i < this.connectsAsSource.length; i += 1) {
|
for (let i = 0; i < this.connectsAsSource.length; i += 1) {
|
||||||
const edge = this.connectsAsSource[i];
|
const edge = this.connectsAsSource[i];
|
||||||
|
|
||||||
if (edge.minRank === -1 || edge.minRank === layer - 1) {
|
if (edge.minRank === -1 || edge.minRank === layer - 1) {
|
||||||
// No dummy nodes in edge, add node of other side of edge
|
// No dummy nodes in edge, add node of other side of edge
|
||||||
this.previousLayerConnectedCells[0].push(<GraphAbstractHierarchyCell>edge.target);
|
this.previousLayerConnectedCells[0].push(
|
||||||
|
<GraphAbstractHierarchyCell>edge.target
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// Edge spans at least two layers, add edge
|
// Edge spans at least two layers, add edge
|
||||||
this.previousLayerConnectedCells[0].push(edge);
|
this.previousLayerConnectedCells[0].push(edge);
|
||||||
|
|
|
@ -20,7 +20,6 @@ import Dictionary from '../../../util/Dictionary';
|
||||||
import GraphHierarchyNode from '../datatypes/GraphHierarchyNode';
|
import GraphHierarchyNode from '../datatypes/GraphHierarchyNode';
|
||||||
import GraphHierarchyEdge from '../datatypes/GraphHierarchyEdge';
|
import GraphHierarchyEdge from '../datatypes/GraphHierarchyEdge';
|
||||||
import Cell from '../../cell/Cell';
|
import Cell from '../../cell/Cell';
|
||||||
import CellArray from '../../cell/CellArray';
|
|
||||||
import HierarchicalLayout from '../HierarchicalLayout';
|
import HierarchicalLayout from '../HierarchicalLayout';
|
||||||
import GraphAbstractHierarchyCell from '../datatypes/GraphAbstractHierarchyCell';
|
import GraphAbstractHierarchyCell from '../datatypes/GraphAbstractHierarchyCell';
|
||||||
|
|
||||||
|
@ -49,8 +48,8 @@ import GraphAbstractHierarchyCell from '../datatypes/GraphAbstractHierarchyCell'
|
||||||
class GraphHierarchyModel {
|
class GraphHierarchyModel {
|
||||||
constructor(
|
constructor(
|
||||||
layout: HierarchicalLayout,
|
layout: HierarchicalLayout,
|
||||||
vertices: CellArray,
|
vertices: Cell[],
|
||||||
roots: CellArray,
|
roots: Cell[],
|
||||||
parent: Cell,
|
parent: Cell,
|
||||||
tightenToSource: boolean
|
tightenToSource: boolean
|
||||||
) {
|
) {
|
||||||
|
@ -146,7 +145,7 @@ class GraphHierarchyModel {
|
||||||
* Store of roots of this hierarchy model, these are real graph cells, not
|
* Store of roots of this hierarchy model, these are real graph cells, not
|
||||||
* internal cells
|
* internal cells
|
||||||
*/
|
*/
|
||||||
roots: CellArray | null = null;
|
roots: Cell[] | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The parent cell whose children are being laid out
|
* The parent cell whose children are being laid out
|
||||||
|
@ -180,7 +179,7 @@ class GraphHierarchyModel {
|
||||||
*/
|
*/
|
||||||
createInternalCells(
|
createInternalCells(
|
||||||
layout: HierarchicalLayout,
|
layout: HierarchicalLayout,
|
||||||
vertices: CellArray,
|
vertices: Cell[],
|
||||||
internalVertices: { [key: number]: GraphHierarchyNode }
|
internalVertices: { [key: number]: GraphHierarchyNode }
|
||||||
) {
|
) {
|
||||||
const graph = layout.getGraph();
|
const graph = layout.getGraph();
|
||||||
|
@ -392,7 +391,7 @@ class GraphHierarchyModel {
|
||||||
* to create dummy nodes for edges that cross layers.
|
* to create dummy nodes for edges that cross layers.
|
||||||
*/
|
*/
|
||||||
fixRanks(): void {
|
fixRanks(): void {
|
||||||
// TODO: Should this be a CellArray?
|
// TODO: Should this be a Cell[]?
|
||||||
const rankList: { [key: number]: GraphAbstractHierarchyCell[] } = {};
|
const rankList: { [key: number]: GraphAbstractHierarchyCell[] } = {};
|
||||||
this.ranks = [];
|
this.ranks = [];
|
||||||
|
|
||||||
|
@ -418,7 +417,13 @@ class GraphHierarchyModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.visit(
|
this.visit(
|
||||||
(parent: GraphHierarchyNode, node: GraphHierarchyNode, edge: GraphHierarchyNode, layer: number, seen: number) => {
|
(
|
||||||
|
parent: GraphHierarchyNode,
|
||||||
|
node: GraphHierarchyNode,
|
||||||
|
edge: GraphHierarchyNode,
|
||||||
|
layer: number,
|
||||||
|
seen: number
|
||||||
|
) => {
|
||||||
if (seen == 0 && node.maxRank < 0 && node.minRank < 0) {
|
if (seen == 0 && node.maxRank < 0 && node.minRank < 0) {
|
||||||
rankList[node.temp[0]].push(node);
|
rankList[node.temp[0]].push(node);
|
||||||
node.maxRank = node.temp[0];
|
node.maxRank = node.temp[0];
|
||||||
|
|
|
@ -16,14 +16,13 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import GraphHierarchyNode from "../datatypes/GraphHierarchyNode";
|
import GraphHierarchyNode from '../datatypes/GraphHierarchyNode';
|
||||||
import GraphHierarchyEdge from "../datatypes/GraphHierarchyEdge";
|
import GraphHierarchyEdge from '../datatypes/GraphHierarchyEdge';
|
||||||
import CellPath from "../../cell/CellPath";
|
import CellPath from '../../cell/CellPath';
|
||||||
import Dictionary from "../../../util/Dictionary";
|
import Dictionary from '../../../util/Dictionary';
|
||||||
import CellArray from "../../cell/CellArray";
|
import Cell from '../../cell/Cell';
|
||||||
import Cell from "../../cell/Cell";
|
import { clone } from '../../../util/cloneUtils';
|
||||||
import { clone } from "../../../util/cloneUtils";
|
import SwimlaneLayout from '../SwimlaneLayout';
|
||||||
import SwimlaneLayout from "../SwimlaneLayout";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal model of a hierarchical graph. This model stores nodes and edges
|
* Internal model of a hierarchical graph. This model stores nodes and edges
|
||||||
|
@ -50,8 +49,8 @@ import SwimlaneLayout from "../SwimlaneLayout";
|
||||||
class SwimlaneModel {
|
class SwimlaneModel {
|
||||||
constructor(
|
constructor(
|
||||||
layout: SwimlaneLayout,
|
layout: SwimlaneLayout,
|
||||||
vertices: CellArray,
|
vertices: Cell[],
|
||||||
roots: CellArray,
|
roots: Cell[],
|
||||||
parent: Cell,
|
parent: Cell,
|
||||||
tightenToSource: boolean
|
tightenToSource: boolean
|
||||||
) {
|
) {
|
||||||
|
@ -103,10 +102,7 @@ class SwimlaneModel {
|
||||||
internalTargetCell = <GraphHierarchyNode>this.vertexMapper.get(targetCell);
|
internalTargetCell = <GraphHierarchyNode>this.vertexMapper.get(targetCell);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (internalTargetCell != null && internalVertices[i] !== internalTargetCell) {
|
||||||
internalTargetCell != null &&
|
|
||||||
internalVertices[i] !== internalTargetCell
|
|
||||||
) {
|
|
||||||
internalEdge.target = internalTargetCell;
|
internalEdge.target = internalTargetCell;
|
||||||
|
|
||||||
if (internalTargetCell.connectsAsTarget.length == 0) {
|
if (internalTargetCell.connectsAsTarget.length == 0) {
|
||||||
|
@ -150,7 +146,7 @@ class SwimlaneModel {
|
||||||
* Store of roots of this hierarchy model, these are real graph cells, not
|
* Store of roots of this hierarchy model, these are real graph cells, not
|
||||||
* internal cells
|
* internal cells
|
||||||
*/
|
*/
|
||||||
roots: CellArray;
|
roots: Cell[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The parent cell whose children are being laid out
|
* The parent cell whose children are being laid out
|
||||||
|
@ -189,11 +185,11 @@ class SwimlaneModel {
|
||||||
*/
|
*/
|
||||||
createInternalCells(
|
createInternalCells(
|
||||||
layout: SwimlaneLayout,
|
layout: SwimlaneLayout,
|
||||||
vertices: CellArray,
|
vertices: Cell[],
|
||||||
internalVertices: GraphHierarchyNode[]
|
internalVertices: GraphHierarchyNode[]
|
||||||
): void {
|
): void {
|
||||||
const graph = layout.getGraph();
|
const graph = layout.getGraph();
|
||||||
const swimlanes = <CellArray>layout.swimlanes;
|
const swimlanes = layout.swimlanes as Cell[];
|
||||||
|
|
||||||
// Create internal edges
|
// Create internal edges
|
||||||
for (let i = 0; i < vertices.length; i += 1) {
|
for (let i = 0; i < vertices.length; i += 1) {
|
||||||
|
@ -220,11 +216,7 @@ class SwimlaneModel {
|
||||||
const cell = <Cell>layout.getVisibleTerminal(conns[j], false);
|
const cell = <Cell>layout.getVisibleTerminal(conns[j], false);
|
||||||
|
|
||||||
// Looking for outgoing edges only
|
// Looking for outgoing edges only
|
||||||
if (
|
if (cell !== vertices[i] && cell.isVertex() && !layout.isVertexIgnored(cell)) {
|
||||||
cell !== vertices[i] &&
|
|
||||||
cell.isVertex() &&
|
|
||||||
!layout.isVertexIgnored(cell)
|
|
||||||
) {
|
|
||||||
// We process all edge between this source and its targets
|
// We process all edge between this source and its targets
|
||||||
// If there are edges going both ways, we need to collect
|
// If there are edges going both ways, we need to collect
|
||||||
// them all into one internal edges to avoid looping problems
|
// them all into one internal edges to avoid looping problems
|
||||||
|
@ -238,11 +230,7 @@ class SwimlaneModel {
|
||||||
// are the same. All the graph edges will have been assigned to
|
// are the same. All the graph edges will have been assigned to
|
||||||
// an internal edge going the other way, so we don't want to
|
// an internal edge going the other way, so we don't want to
|
||||||
// process them again
|
// process them again
|
||||||
const undirectedEdges = layout.getEdgesBetween(
|
const undirectedEdges = layout.getEdgesBetween(vertices[i], cell, false);
|
||||||
vertices[i],
|
|
||||||
cell,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
const directedEdges = layout.getEdgesBetween(vertices[i], cell, true);
|
const directedEdges = layout.getEdgesBetween(vertices[i], cell, true);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -269,9 +257,7 @@ class SwimlaneModel {
|
||||||
|
|
||||||
internalEdge.source = internalVertices[i];
|
internalEdge.source = internalVertices[i];
|
||||||
|
|
||||||
if (
|
if (internalVertices[i].connectsAsSource.indexOf(internalEdge) < 0) {
|
||||||
internalVertices[i].connectsAsSource.indexOf(internalEdge) < 0
|
|
||||||
) {
|
|
||||||
internalVertices[i].connectsAsSource.push(internalEdge);
|
internalVertices[i].connectsAsSource.push(internalEdge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -468,10 +454,7 @@ class SwimlaneModel {
|
||||||
const slIndex = <number>root.swimlaneIndex;
|
const slIndex = <number>root.swimlaneIndex;
|
||||||
const ranksPerGroup = <{ [key: number]: number }>this.ranksPerGroup;
|
const ranksPerGroup = <{ [key: number]: number }>this.ranksPerGroup;
|
||||||
|
|
||||||
if (
|
if (ranksPerGroup[slIndex] == null || ranksPerGroup[slIndex] < chainCount) {
|
||||||
ranksPerGroup[slIndex] == null ||
|
|
||||||
ranksPerGroup[slIndex] < chainCount
|
|
||||||
) {
|
|
||||||
ranksPerGroup[slIndex] = chainCount;
|
ranksPerGroup[slIndex] = chainCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,13 +469,7 @@ class SwimlaneModel {
|
||||||
// Only navigate in source->target direction within the same
|
// Only navigate in source->target direction within the same
|
||||||
// swimlane, or from a lower index swimlane to a higher one
|
// swimlane, or from a lower index swimlane to a higher one
|
||||||
if (<number>root.swimlaneIndex < <number>targetNode.swimlaneIndex) {
|
if (<number>root.swimlaneIndex < <number>targetNode.swimlaneIndex) {
|
||||||
this.maxChainDfs(
|
this.maxChainDfs(root, targetNode, internalEdge, clone(seen, null, true), 0);
|
||||||
root,
|
|
||||||
targetNode,
|
|
||||||
internalEdge,
|
|
||||||
clone(seen, null, true),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
} else if (root.swimlaneIndex === targetNode.swimlaneIndex) {
|
} else if (root.swimlaneIndex === targetNode.swimlaneIndex) {
|
||||||
this.maxChainDfs(
|
this.maxChainDfs(
|
||||||
root,
|
root,
|
||||||
|
@ -537,7 +514,13 @@ class SwimlaneModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.visit(
|
this.visit(
|
||||||
(parent: GraphHierarchyNode, node: GraphHierarchyNode, edge: GraphHierarchyNode, layer: number, seen: number) => {
|
(
|
||||||
|
parent: GraphHierarchyNode,
|
||||||
|
node: GraphHierarchyNode,
|
||||||
|
edge: GraphHierarchyNode,
|
||||||
|
layer: number,
|
||||||
|
seen: number
|
||||||
|
) => {
|
||||||
if (seen === 0 && node.maxRank < 0 && node.minRank < 0) {
|
if (seen === 0 && node.maxRank < 0 && node.minRank < 0) {
|
||||||
rankList[node.temp[0]].push(node);
|
rankList[node.temp[0]].push(node);
|
||||||
node.maxRank = node.temp[0];
|
node.maxRank = node.temp[0];
|
||||||
|
|
|
@ -15,7 +15,6 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import { mixInto } from '../../util/Utils';
|
import { mixInto } from '../../util/Utils';
|
||||||
import {
|
import {
|
||||||
contains,
|
contains,
|
||||||
|
@ -47,6 +46,7 @@ import Point from '../geometry/Point';
|
||||||
import { htmlEntities } from '../../util/StringUtils';
|
import { htmlEntities } from '../../util/StringUtils';
|
||||||
import CellState from '../cell/CellState';
|
import CellState from '../cell/CellState';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
|
import { cloneCells, getTopmostCells } from '../../util/cellArrayUtils';
|
||||||
|
|
||||||
import type { CellStateStyle, CellStyle, NumericCellStateStyleKeys } from '../../types';
|
import type { CellStateStyle, CellStyle, NumericCellStateStyleKeys } from '../../types';
|
||||||
|
|
||||||
|
@ -66,12 +66,12 @@ declare module '../Graph' {
|
||||||
extendParentsOnAdd: boolean;
|
extendParentsOnAdd: boolean;
|
||||||
extendParentsOnMove: boolean;
|
extendParentsOnMove: boolean;
|
||||||
|
|
||||||
getBoundingBox: (cells: CellArray) => Rectangle | null;
|
getBoundingBox: (cells: Cell[]) => Rectangle | null;
|
||||||
removeStateForCell: (cell: Cell) => void;
|
removeStateForCell: (cell: Cell) => void;
|
||||||
getCurrentCellStyle: (cell: Cell, ignoreState?: boolean) => CellStateStyle;
|
getCurrentCellStyle: (cell: Cell, ignoreState?: boolean) => CellStateStyle;
|
||||||
getCellStyle: (cell: Cell) => CellStateStyle;
|
getCellStyle: (cell: Cell) => CellStateStyle;
|
||||||
postProcessCellStyle: (style: CellStateStyle) => CellStateStyle;
|
postProcessCellStyle: (style: CellStateStyle) => CellStateStyle;
|
||||||
setCellStyle: (style: CellStyle, cells: CellArray) => void;
|
setCellStyle: (style: CellStyle, cells: Cell[]) => void;
|
||||||
toggleCellStyle: (
|
toggleCellStyle: (
|
||||||
key: keyof CellStateStyle,
|
key: keyof CellStateStyle,
|
||||||
defaultValue: boolean,
|
defaultValue: boolean,
|
||||||
|
@ -80,25 +80,25 @@ declare module '../Graph' {
|
||||||
toggleCellStyles: (
|
toggleCellStyles: (
|
||||||
key: keyof CellStateStyle,
|
key: keyof CellStateStyle,
|
||||||
defaultValue: boolean,
|
defaultValue: boolean,
|
||||||
cells: CellArray
|
cells: Cell[]
|
||||||
) => boolean | null;
|
) => boolean | null;
|
||||||
setCellStyles: (
|
setCellStyles: (
|
||||||
key: keyof CellStateStyle,
|
key: keyof CellStateStyle,
|
||||||
value: CellStateStyle[keyof CellStateStyle],
|
value: CellStateStyle[keyof CellStateStyle],
|
||||||
cells?: CellArray
|
cells?: Cell[]
|
||||||
) => void;
|
) => void;
|
||||||
toggleCellStyleFlags: (
|
toggleCellStyleFlags: (
|
||||||
key: NumericCellStateStyleKeys,
|
key: NumericCellStateStyleKeys,
|
||||||
flag: number,
|
flag: number,
|
||||||
cells?: CellArray | null
|
cells?: Cell[] | null
|
||||||
) => void;
|
) => void;
|
||||||
setCellStyleFlags: (
|
setCellStyleFlags: (
|
||||||
key: NumericCellStateStyleKeys,
|
key: NumericCellStateStyleKeys,
|
||||||
flag: number,
|
flag: number,
|
||||||
value?: boolean | null,
|
value?: boolean | null,
|
||||||
cells?: CellArray | null
|
cells?: Cell[] | null
|
||||||
) => void;
|
) => void;
|
||||||
alignCells: (align: string, cells?: CellArray, param?: number | null) => void;
|
alignCells: (align: string, cells?: Cell[], param?: number | null) => void;
|
||||||
cloneCell: (
|
cloneCell: (
|
||||||
cell: Cell,
|
cell: Cell,
|
||||||
allowInvalidEdges?: boolean,
|
allowInvalidEdges?: boolean,
|
||||||
|
@ -106,11 +106,11 @@ declare module '../Graph' {
|
||||||
keepPosition?: boolean
|
keepPosition?: boolean
|
||||||
) => Cell;
|
) => Cell;
|
||||||
cloneCells: (
|
cloneCells: (
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
allowInvalidEdges: boolean,
|
allowInvalidEdges?: boolean,
|
||||||
mapping: any,
|
mapping?: any,
|
||||||
keepPosition?: boolean
|
keepPosition?: boolean
|
||||||
) => CellArray;
|
) => Cell[];
|
||||||
addCell: (
|
addCell: (
|
||||||
cell: Cell,
|
cell: Cell,
|
||||||
parent: Cell | null,
|
parent: Cell | null,
|
||||||
|
@ -119,15 +119,15 @@ declare module '../Graph' {
|
||||||
target?: Cell | null
|
target?: Cell | null
|
||||||
) => Cell;
|
) => Cell;
|
||||||
addCells: (
|
addCells: (
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
parent: Cell | null,
|
parent: Cell | null,
|
||||||
index: number | null,
|
index: number | null,
|
||||||
source: Cell | null,
|
source: Cell | null,
|
||||||
target: Cell | null,
|
target: Cell | null,
|
||||||
absolute?: boolean
|
absolute?: boolean
|
||||||
) => CellArray;
|
) => Cell[];
|
||||||
cellsAdded: (
|
cellsAdded: (
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
parent: Cell,
|
parent: Cell,
|
||||||
index: number,
|
index: number,
|
||||||
source: Cell | null,
|
source: Cell | null,
|
||||||
|
@ -137,16 +137,16 @@ declare module '../Graph' {
|
||||||
extend?: boolean
|
extend?: boolean
|
||||||
) => void;
|
) => void;
|
||||||
autoSizeCell: (cell: Cell, recurse?: boolean) => void;
|
autoSizeCell: (cell: Cell, recurse?: boolean) => void;
|
||||||
removeCells: (cells?: CellArray | null, includeEdges?: boolean | null) => CellArray;
|
removeCells: (cells?: Cell[] | null, includeEdges?: boolean | null) => Cell[];
|
||||||
cellsRemoved: (cells: CellArray) => void;
|
cellsRemoved: (cells: Cell[]) => void;
|
||||||
toggleCells: (show: boolean, cells: CellArray, includeEdges: boolean) => CellArray;
|
toggleCells: (show: boolean, cells: Cell[], includeEdges: boolean) => Cell[];
|
||||||
cellsToggled: (cells: CellArray, show: boolean) => void;
|
cellsToggled: (cells: Cell[], show: boolean) => void;
|
||||||
updateCellSize: (cell: Cell, ignoreChildren?: boolean) => Cell;
|
updateCellSize: (cell: Cell, ignoreChildren?: boolean) => Cell;
|
||||||
cellSizeUpdated: (cell: Cell, ignoreChildren: boolean) => void;
|
cellSizeUpdated: (cell: Cell, ignoreChildren: boolean) => void;
|
||||||
getPreferredSizeForCell: (cell: Cell, textWidth?: number | null) => Rectangle | null;
|
getPreferredSizeForCell: (cell: Cell, textWidth?: number | null) => Rectangle | null;
|
||||||
resizeCell: (cell: Cell, bounds: Rectangle, recurse?: boolean) => Cell;
|
resizeCell: (cell: Cell, bounds: Rectangle, recurse?: boolean) => Cell;
|
||||||
resizeCells: (cells: CellArray, bounds: Rectangle[], recurse: boolean) => CellArray;
|
resizeCells: (cells: Cell[], bounds: Rectangle[], recurse: boolean) => Cell[];
|
||||||
cellsResized: (cells: CellArray, bounds: Rectangle[], recurse: boolean) => void;
|
cellsResized: (cells: Cell[], bounds: Rectangle[], recurse: boolean) => void;
|
||||||
cellResized: (
|
cellResized: (
|
||||||
cell: Cell,
|
cell: Cell,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
|
@ -158,24 +158,24 @@ declare module '../Graph' {
|
||||||
scaleCell: (cell: Cell, dx: number, dy: number, recurse: boolean) => void;
|
scaleCell: (cell: Cell, dx: number, dy: number, recurse: boolean) => void;
|
||||||
extendParent: (cell: Cell) => void;
|
extendParent: (cell: Cell) => void;
|
||||||
importCells: (
|
importCells: (
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
dx: number,
|
dx: number,
|
||||||
dy: number,
|
dy: number,
|
||||||
target: Cell | null,
|
target?: Cell | null,
|
||||||
evt: MouseEvent | null,
|
evt?: MouseEvent | null,
|
||||||
mapping: any
|
mapping?: any
|
||||||
) => CellArray;
|
) => Cell[];
|
||||||
moveCells: (
|
moveCells: (
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
dx: number,
|
dx: number,
|
||||||
dy: number,
|
dy: number,
|
||||||
clone?: boolean,
|
clone?: boolean,
|
||||||
target?: Cell | null,
|
target?: Cell | null,
|
||||||
evt?: MouseEvent | null,
|
evt?: MouseEvent | null,
|
||||||
mapping?: any
|
mapping?: any
|
||||||
) => CellArray;
|
) => Cell[];
|
||||||
cellsMoved: (
|
cellsMoved: (
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
dx: number,
|
dx: number,
|
||||||
dy: number,
|
dy: number,
|
||||||
disconnect: boolean,
|
disconnect: boolean,
|
||||||
|
@ -185,11 +185,7 @@ declare module '../Graph' {
|
||||||
translateCell: (cell: Cell, dx: number, dy: number) => void;
|
translateCell: (cell: Cell, dx: number, dy: number) => void;
|
||||||
getCellContainmentArea: (cell: Cell) => Rectangle | null;
|
getCellContainmentArea: (cell: Cell) => Rectangle | null;
|
||||||
constrainChild: (cell: Cell, sizeFirst?: boolean) => void;
|
constrainChild: (cell: Cell, sizeFirst?: boolean) => void;
|
||||||
getChildCells: (
|
getChildCells: (parent?: Cell | null, vertices?: boolean, edges?: boolean) => Cell[];
|
||||||
parent?: Cell | null,
|
|
||||||
vertices?: boolean,
|
|
||||||
edges?: boolean
|
|
||||||
) => CellArray;
|
|
||||||
getCellAt: (
|
getCellAt: (
|
||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
|
@ -204,40 +200,40 @@ declare module '../Graph' {
|
||||||
width: number,
|
width: number,
|
||||||
height: number,
|
height: number,
|
||||||
parent?: Cell | null,
|
parent?: Cell | null,
|
||||||
result?: CellArray,
|
result?: Cell[],
|
||||||
intersection?: Rectangle | null,
|
intersection?: Rectangle | null,
|
||||||
ignoreFn?: Function | null,
|
ignoreFn?: Function | null,
|
||||||
includeDescendants?: boolean
|
includeDescendants?: boolean
|
||||||
) => CellArray;
|
) => Cell[];
|
||||||
getCellsBeyond: (
|
getCellsBeyond: (
|
||||||
x0: number,
|
x0: number,
|
||||||
y0: number,
|
y0: number,
|
||||||
parent: Cell | null,
|
parent: Cell | null,
|
||||||
rightHalfpane: boolean,
|
rightHalfpane: boolean,
|
||||||
bottomHalfpane: boolean
|
bottomHalfpane: boolean
|
||||||
) => CellArray;
|
) => Cell[];
|
||||||
intersects: (state: CellState, x: number, y: number) => boolean;
|
intersects: (state: CellState, x: number, y: number) => boolean;
|
||||||
isValidAncestor: (cell: Cell, parent: Cell, recurse: boolean) => boolean;
|
isValidAncestor: (cell: Cell, parent: Cell, recurse: boolean) => boolean;
|
||||||
isCellLocked: (cell: Cell) => boolean;
|
isCellLocked: (cell: Cell) => boolean;
|
||||||
isCellsLocked: () => boolean;
|
isCellsLocked: () => boolean;
|
||||||
setCellsLocked: (value: boolean) => void;
|
setCellsLocked: (value: boolean) => void;
|
||||||
getCloneableCells: (cells: CellArray) => CellArray;
|
getCloneableCells: (cells: Cell[]) => Cell[];
|
||||||
isCellCloneable: (cell: Cell) => boolean;
|
isCellCloneable: (cell: Cell) => boolean;
|
||||||
isCellsCloneable: () => boolean;
|
isCellsCloneable: () => boolean;
|
||||||
setCellsCloneable: (value: boolean) => void;
|
setCellsCloneable: (value: boolean) => void;
|
||||||
getExportableCells: (cells: CellArray) => CellArray;
|
getExportableCells: (cells: Cell[]) => Cell[];
|
||||||
canExportCell: (cell: Cell | null) => boolean;
|
canExportCell: (cell: Cell | null) => boolean;
|
||||||
getImportableCells: (cells: CellArray) => CellArray;
|
getImportableCells: (cells: Cell[]) => Cell[];
|
||||||
canImportCell: (cell: Cell | null) => boolean;
|
canImportCell: (cell: Cell | null) => boolean;
|
||||||
isCellSelectable: (cell: Cell) => boolean;
|
isCellSelectable: (cell: Cell) => boolean;
|
||||||
isCellsSelectable: () => boolean;
|
isCellsSelectable: () => boolean;
|
||||||
setCellsSelectable: (value: boolean) => void;
|
setCellsSelectable: (value: boolean) => void;
|
||||||
getDeletableCells: (cells: CellArray) => CellArray;
|
getDeletableCells: (cells: Cell[]) => Cell[];
|
||||||
isCellDeletable: (cell: Cell) => boolean;
|
isCellDeletable: (cell: Cell) => boolean;
|
||||||
isCellsDeletable: () => boolean;
|
isCellsDeletable: () => boolean;
|
||||||
setCellsDeletable: (value: boolean) => void;
|
setCellsDeletable: (value: boolean) => void;
|
||||||
isCellRotatable: (cell: Cell) => boolean;
|
isCellRotatable: (cell: Cell) => boolean;
|
||||||
getMovableCells: (cells: CellArray) => CellArray;
|
getMovableCells: (cells: Cell[]) => Cell[];
|
||||||
isCellMovable: (cell: Cell) => boolean;
|
isCellMovable: (cell: Cell) => boolean;
|
||||||
isCellsMovable: () => boolean;
|
isCellsMovable: () => boolean;
|
||||||
setCellsMovable: (value: boolean) => void;
|
setCellsMovable: (value: boolean) => void;
|
||||||
|
@ -264,7 +260,7 @@ declare module '../Graph' {
|
||||||
includeDescendants?: boolean
|
includeDescendants?: boolean
|
||||||
) => Rectangle | null;
|
) => Rectangle | null;
|
||||||
getBoundingBoxFromGeometry: (
|
getBoundingBoxFromGeometry: (
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
includeEdges?: boolean
|
includeEdges?: boolean
|
||||||
) => Rectangle | null;
|
) => Rectangle | null;
|
||||||
}
|
}
|
||||||
|
@ -660,7 +656,7 @@ export const CellsMixin: PartialType = {
|
||||||
*/
|
*/
|
||||||
toggleCellStyle(key, defaultValue = false, cell?) {
|
toggleCellStyle(key, defaultValue = false, cell?) {
|
||||||
cell = cell ?? this.getSelectionCell();
|
cell = cell ?? this.getSelectionCell();
|
||||||
return this.toggleCellStyles(key, defaultValue, new CellArray(cell));
|
return this.toggleCellStyles(key, defaultValue, [cell]);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -807,14 +803,14 @@ export const CellsMixin: PartialType = {
|
||||||
this.batchUpdate(() => {
|
this.batchUpdate(() => {
|
||||||
const p = param as number;
|
const p = param as number;
|
||||||
|
|
||||||
for (const cell of <CellArray>cells) {
|
for (const cell of cells as Cell[]) {
|
||||||
const state = this.getView().getState(cell);
|
const state = this.getView().getState(cell);
|
||||||
|
|
||||||
if (state != null) {
|
if (state != null) {
|
||||||
let geo = cell.getGeometry();
|
let geo = cell.getGeometry();
|
||||||
|
|
||||||
if (geo != null && !cell.isEdge()) {
|
if (geo != null && !cell.isEdge()) {
|
||||||
geo = <Geometry>geo.clone();
|
geo = geo.clone();
|
||||||
|
|
||||||
if (align === ALIGN.CENTER) {
|
if (align === ALIGN.CENTER) {
|
||||||
geo.x += (p - state.x - state.width / 2) / s;
|
geo.x += (p - state.x - state.width / 2) / s;
|
||||||
|
@ -857,14 +853,8 @@ export const CellsMixin: PartialType = {
|
||||||
* @param keepPosition Optional boolean indicating if the position of the cells should
|
* @param keepPosition Optional boolean indicating if the position of the cells should
|
||||||
* be updated to reflect the lost parent cell. Default is `false`.
|
* be updated to reflect the lost parent cell. Default is `false`.
|
||||||
*/
|
*/
|
||||||
// cloneCell(cell: mxCell, allowInvalidEdges?: boolean, mapping?: any, keepPosition?: boolean): mxCellArray;
|
|
||||||
cloneCell(cell, allowInvalidEdges = false, mapping = null, keepPosition = false) {
|
cloneCell(cell, allowInvalidEdges = false, mapping = null, keepPosition = false) {
|
||||||
return this.cloneCells(
|
return this.cloneCells([cell], allowInvalidEdges, mapping, keepPosition)[0];
|
||||||
new CellArray(cell),
|
|
||||||
allowInvalidEdges,
|
|
||||||
mapping,
|
|
||||||
keepPosition
|
|
||||||
)[0];
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -880,9 +870,8 @@ export const CellsMixin: PartialType = {
|
||||||
* @param keepPosition Optional boolean indicating if the position of the cells should
|
* @param keepPosition Optional boolean indicating if the position of the cells should
|
||||||
* be updated to reflect the lost parent cell. Default is `false`.
|
* be updated to reflect the lost parent cell. Default is `false`.
|
||||||
*/
|
*/
|
||||||
// cloneCells(cells: mxCellArray, allowInvalidEdges?: boolean, mapping?: any, keepPosition?: boolean): mxCellArray;
|
|
||||||
cloneCells(cells, allowInvalidEdges = true, mapping = {}, keepPosition = false) {
|
cloneCells(cells, allowInvalidEdges = true, mapping = {}, keepPosition = false) {
|
||||||
let clones;
|
let clones: Cell[];
|
||||||
|
|
||||||
// Creates a dictionary for fast lookups
|
// Creates a dictionary for fast lookups
|
||||||
const dict = new Dictionary<Cell, boolean>();
|
const dict = new Dictionary<Cell, boolean>();
|
||||||
|
@ -896,8 +885,8 @@ export const CellsMixin: PartialType = {
|
||||||
if (tmp.length > 0) {
|
if (tmp.length > 0) {
|
||||||
const { scale } = this.getView();
|
const { scale } = this.getView();
|
||||||
const trans = this.getView().translate;
|
const trans = this.getView().translate;
|
||||||
const out: CellArray = new CellArray();
|
const out: Cell[] = [];
|
||||||
clones = cells.cloneCells(true, mapping);
|
clones = cloneCells(true, mapping)(cells);
|
||||||
|
|
||||||
for (let i = 0; i < cells.length; i += 1) {
|
for (let i = 0; i < cells.length; i += 1) {
|
||||||
const cell = cells[i];
|
const cell = cells[i];
|
||||||
|
@ -976,7 +965,7 @@ export const CellsMixin: PartialType = {
|
||||||
}
|
}
|
||||||
clones = out;
|
clones = out;
|
||||||
} else {
|
} else {
|
||||||
clones = new CellArray();
|
clones = [];
|
||||||
}
|
}
|
||||||
return clones;
|
return clones;
|
||||||
},
|
},
|
||||||
|
@ -994,7 +983,7 @@ export const CellsMixin: PartialType = {
|
||||||
* @param target Optional {@link Cell} that represents the target terminal.
|
* @param target Optional {@link Cell} that represents the target terminal.
|
||||||
*/
|
*/
|
||||||
addCell(cell, parent = null, index = null, source = null, target = null) {
|
addCell(cell, parent = null, index = null, source = null, target = null) {
|
||||||
return this.addCells(new CellArray(cell), parent, index, source, target)[0];
|
return this.addCells([cell], parent, index, source, target)[0];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1196,13 +1185,13 @@ export const CellsMixin: PartialType = {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.batchUpdate(() => {
|
this.batchUpdate(() => {
|
||||||
this.cellsRemoved(<CellArray>cells);
|
this.cellsRemoved(cells as Cell[]);
|
||||||
this.fireEvent(
|
this.fireEvent(
|
||||||
new EventObject(InternalEvent.REMOVE_CELLS, { cells, includeEdges })
|
new EventObject(InternalEvent.REMOVE_CELLS, { cells, includeEdges })
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return cells ?? new CellArray();
|
return cells ?? [];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1226,7 +1215,7 @@ export const CellsMixin: PartialType = {
|
||||||
|
|
||||||
for (const cell of cells) {
|
for (const cell of cells) {
|
||||||
// Disconnects edges which are not being removed
|
// Disconnects edges which are not being removed
|
||||||
const edges = this.getAllEdges(new CellArray(cell));
|
const edges = this.getAllEdges([cell]);
|
||||||
|
|
||||||
const disconnectTerminal = (edge: Cell, source: boolean) => {
|
const disconnectTerminal = (edge: Cell, source: boolean) => {
|
||||||
let geo = edge.getGeometry();
|
let geo = edge.getGeometry();
|
||||||
|
@ -1447,7 +1436,7 @@ export const CellsMixin: PartialType = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cellsResized(new CellArray(cell), [geo], false);
|
this.cellsResized([cell], [geo], false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -1567,7 +1556,7 @@ export const CellsMixin: PartialType = {
|
||||||
* @param bounds {@link mxRectangle} that represents the new bounds.
|
* @param bounds {@link mxRectangle} that represents the new bounds.
|
||||||
*/
|
*/
|
||||||
resizeCell(cell, bounds, recurse = false) {
|
resizeCell(cell, bounds, recurse = false) {
|
||||||
return this.resizeCells(new CellArray(cell), [bounds], recurse)[0];
|
return this.resizeCells([cell], [bounds], recurse)[0];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1578,7 +1567,7 @@ export const CellsMixin: PartialType = {
|
||||||
* @param cells Array of {@link Cell} whose bounds should be changed.
|
* @param cells Array of {@link Cell} whose bounds should be changed.
|
||||||
* @param bounds Array of {@link mxRectangles} that represent the new bounds.
|
* @param bounds Array of {@link mxRectangles} that represent the new bounds.
|
||||||
*/
|
*/
|
||||||
resizeCells(cells, bounds, recurse): CellArray {
|
resizeCells(cells, bounds, recurse): Cell[] {
|
||||||
recurse = recurse ?? this.isRecursiveResize();
|
recurse = recurse ?? this.isRecursiveResize();
|
||||||
|
|
||||||
this.batchUpdate(() => {
|
this.batchUpdate(() => {
|
||||||
|
@ -1821,7 +1810,7 @@ export const CellsMixin: PartialType = {
|
||||||
p.width = Math.max(p.width, geo.x + geo.width);
|
p.width = Math.max(p.width, geo.x + geo.width);
|
||||||
p.height = Math.max(p.height, geo.y + geo.height);
|
p.height = Math.max(p.height, geo.y + geo.height);
|
||||||
|
|
||||||
this.cellsResized(new CellArray(parent), [p], false);
|
this.cellsResized([parent], [p], false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1878,7 +1867,7 @@ export const CellsMixin: PartialType = {
|
||||||
) {
|
) {
|
||||||
if (dx !== 0 || dy !== 0 || clone || target) {
|
if (dx !== 0 || dy !== 0 || clone || target) {
|
||||||
// Removes descendants with ancestors in cells to avoid multiple moving
|
// Removes descendants with ancestors in cells to avoid multiple moving
|
||||||
cells = cells.getTopmostCells();
|
cells = getTopmostCells(cells);
|
||||||
const origCells = cells;
|
const origCells = cells;
|
||||||
|
|
||||||
this.batchUpdate(() => {
|
this.batchUpdate(() => {
|
||||||
|
@ -1901,7 +1890,7 @@ export const CellsMixin: PartialType = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Removes relative edge labels with selected terminals
|
// Removes relative edge labels with selected terminals
|
||||||
const checked = new CellArray();
|
const checked = [];
|
||||||
|
|
||||||
for (const cell of cells) {
|
for (const cell of cells) {
|
||||||
const geo = cell.getGeometry();
|
const geo = cell.getGeometry();
|
||||||
|
@ -2137,7 +2126,7 @@ export const CellsMixin: PartialType = {
|
||||||
|
|
||||||
// Finds parent offset
|
// Finds parent offset
|
||||||
if (max && parent) {
|
if (max && parent) {
|
||||||
const off = this.getBoundingBoxFromGeometry(new CellArray(parent), false);
|
const off = this.getBoundingBoxFromGeometry([parent], false);
|
||||||
|
|
||||||
if (off) {
|
if (off) {
|
||||||
max = Rectangle.fromRectangle(max);
|
max = Rectangle.fromRectangle(max);
|
||||||
|
@ -2173,7 +2162,7 @@ export const CellsMixin: PartialType = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max) {
|
if (max) {
|
||||||
const cells = new CellArray(cell);
|
const cells = [cell];
|
||||||
|
|
||||||
if (!cell.isCollapsed()) {
|
if (!cell.isCollapsed()) {
|
||||||
const desc = cell.getDescendants();
|
const desc = cell.getDescendants();
|
||||||
|
@ -2260,7 +2249,7 @@ export const CellsMixin: PartialType = {
|
||||||
parent = parent ?? this.getDefaultParent();
|
parent = parent ?? this.getDefaultParent();
|
||||||
|
|
||||||
const cells = parent.getChildCells(vertices, edges);
|
const cells = parent.getChildCells(vertices, edges);
|
||||||
const result = new CellArray();
|
const result = [];
|
||||||
|
|
||||||
// Filters out the non-visible child cells
|
// Filters out the non-visible child cells
|
||||||
for (const cell of cells) {
|
for (const cell of cells) {
|
||||||
|
@ -2348,7 +2337,7 @@ export const CellsMixin: PartialType = {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
parent = null,
|
parent = null,
|
||||||
result = new CellArray(),
|
result = [],
|
||||||
intersection = null,
|
intersection = null,
|
||||||
ignoreFn = null,
|
ignoreFn = null,
|
||||||
includeDescendants = false
|
includeDescendants = false
|
||||||
|
@ -2444,7 +2433,7 @@ export const CellsMixin: PartialType = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new CellArray(...result);
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2937,7 +2926,7 @@ export const CellsMixin: PartialType = {
|
||||||
* of all descendants should be included. Default is `false`.
|
* of all descendants should be included. Default is `false`.
|
||||||
*/
|
*/
|
||||||
getCellBounds(cell, includeEdges = false, includeDescendants = false) {
|
getCellBounds(cell, includeEdges = false, includeDescendants = false) {
|
||||||
let cells = new CellArray(cell);
|
let cells = [cell];
|
||||||
|
|
||||||
// Includes all connected edges
|
// Includes all connected edges
|
||||||
if (includeEdges) {
|
if (includeEdges) {
|
||||||
|
@ -3039,7 +3028,7 @@ export const CellsMixin: PartialType = {
|
||||||
|
|
||||||
if (geo.relative && parent) {
|
if (geo.relative && parent) {
|
||||||
if (parent.isVertex() && parent !== this.getView().currentRoot) {
|
if (parent.isVertex() && parent !== this.getView().currentRoot) {
|
||||||
tmp = this.getBoundingBoxFromGeometry(new CellArray(parent), false);
|
tmp = this.getBoundingBoxFromGeometry([parent], false);
|
||||||
|
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
bbox = new Rectangle(
|
bbox = new Rectangle(
|
||||||
|
@ -3059,7 +3048,7 @@ export const CellsMixin: PartialType = {
|
||||||
bbox = Rectangle.fromRectangle(geo);
|
bbox = Rectangle.fromRectangle(geo);
|
||||||
|
|
||||||
if (parent && parent.isVertex() && cells.indexOf(parent) >= 0) {
|
if (parent && parent.isVertex() && cells.indexOf(parent) >= 0) {
|
||||||
tmp = this.getBoundingBoxFromGeometry(new CellArray(parent), false);
|
tmp = this.getBoundingBoxFromGeometry([parent], false);
|
||||||
|
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
bbox.x += tmp.x;
|
bbox.x += tmp.x;
|
||||||
|
|
|
@ -23,7 +23,6 @@ import { DIRECTION } from '../../util/Constants';
|
||||||
import { mixInto } from '../../util/Utils';
|
import { mixInto } from '../../util/Utils';
|
||||||
import { getRotatedPoint, toRadians } from '../../util/mathUtils';
|
import { getRotatedPoint, toRadians } from '../../util/mathUtils';
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import EventObject from '../event/EventObject';
|
import EventObject from '../event/EventObject';
|
||||||
import InternalEvent from '../event/InternalEvent';
|
import InternalEvent from '../event/InternalEvent';
|
||||||
import Dictionary from '../../util/Dictionary';
|
import Dictionary from '../../util/Dictionary';
|
||||||
|
@ -74,8 +73,8 @@ declare module '../Graph' {
|
||||||
source: boolean,
|
source: boolean,
|
||||||
constraint?: ConnectionConstraint | null
|
constraint?: ConnectionConstraint | null
|
||||||
) => void;
|
) => void;
|
||||||
disconnectGraph: (cells: CellArray) => void;
|
disconnectGraph: (cells: Cell[]) => void;
|
||||||
getConnections: (cell: Cell, parent?: Cell | null) => CellArray;
|
getConnections: (cell: Cell, parent?: Cell | null) => Cell[];
|
||||||
isConstrainChild: (cell: Cell) => boolean;
|
isConstrainChild: (cell: Cell) => boolean;
|
||||||
isConstrainChildren: () => boolean;
|
isConstrainChildren: () => boolean;
|
||||||
setConstrainChildren: (value: boolean) => void;
|
setConstrainChildren: (value: boolean) => void;
|
||||||
|
@ -308,50 +307,22 @@ const ConnectionsMixin: PartialType = {
|
||||||
if (constraint) {
|
if (constraint) {
|
||||||
this.batchUpdate(() => {
|
this.batchUpdate(() => {
|
||||||
if (!constraint || !constraint.point) {
|
if (!constraint || !constraint.point) {
|
||||||
this.setCellStyles(source ? 'exitX' : 'entryX', null, new CellArray(edge));
|
this.setCellStyles(source ? 'exitX' : 'entryX', null, [edge]);
|
||||||
this.setCellStyles(source ? 'exitY' : 'entryY', null, new CellArray(edge));
|
this.setCellStyles(source ? 'exitY' : 'entryY', null, [edge]);
|
||||||
this.setCellStyles(source ? 'exitDx' : 'entryDx', null, new CellArray(edge));
|
this.setCellStyles(source ? 'exitDx' : 'entryDx', null, [edge]);
|
||||||
this.setCellStyles(source ? 'exitDy' : 'entryDy', null, new CellArray(edge));
|
this.setCellStyles(source ? 'exitDy' : 'entryDy', null, [edge]);
|
||||||
this.setCellStyles(
|
this.setCellStyles(source ? 'exitPerimeter' : 'entryPerimeter', null, [edge]);
|
||||||
source ? 'exitPerimeter' : 'entryPerimeter',
|
|
||||||
null,
|
|
||||||
new CellArray(edge)
|
|
||||||
);
|
|
||||||
} else if (constraint.point) {
|
} else if (constraint.point) {
|
||||||
this.setCellStyles(
|
this.setCellStyles(source ? 'exitX' : 'entryX', constraint.point.x, [edge]);
|
||||||
source ? 'exitX' : 'entryX',
|
this.setCellStyles(source ? 'exitY' : 'entryY', constraint.point.y, [edge]);
|
||||||
constraint.point.x,
|
this.setCellStyles(source ? 'exitDx' : 'entryDx', constraint.dx, [edge]);
|
||||||
new CellArray(edge)
|
this.setCellStyles(source ? 'exitDy' : 'entryDy', constraint.dy, [edge]);
|
||||||
);
|
|
||||||
this.setCellStyles(
|
|
||||||
source ? 'exitY' : 'entryY',
|
|
||||||
constraint.point.y,
|
|
||||||
new CellArray(edge)
|
|
||||||
);
|
|
||||||
this.setCellStyles(
|
|
||||||
source ? 'exitDx' : 'entryDx',
|
|
||||||
constraint.dx,
|
|
||||||
new CellArray(edge)
|
|
||||||
);
|
|
||||||
this.setCellStyles(
|
|
||||||
source ? 'exitDy' : 'entryDy',
|
|
||||||
constraint.dy,
|
|
||||||
new CellArray(edge)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Only writes 0 since 1 is default
|
// Only writes 0 since 1 is default
|
||||||
if (!constraint.perimeter) {
|
if (!constraint.perimeter) {
|
||||||
this.setCellStyles(
|
this.setCellStyles(source ? 'exitPerimeter' : 'entryPerimeter', '0', [edge]);
|
||||||
source ? 'exitPerimeter' : 'entryPerimeter',
|
|
||||||
'0',
|
|
||||||
new CellArray(edge)
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
this.setCellStyles(
|
this.setCellStyles(source ? 'exitPerimeter' : 'entryPerimeter', null, [edge]);
|
||||||
source ? 'exitPerimeter' : 'entryPerimeter',
|
|
||||||
null,
|
|
||||||
new CellArray(edge)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -519,7 +490,7 @@ const ConnectionsMixin: PartialType = {
|
||||||
|
|
||||||
// Sets or resets all previous information for connecting to a child port
|
// Sets or resets all previous information for connecting to a child port
|
||||||
const key = source ? 'sourcePort' : 'targetPort';
|
const key = source ? 'sourcePort' : 'targetPort';
|
||||||
this.setCellStyles(key, id, new CellArray(edge));
|
this.setCellStyles(key, id, [edge]);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getDataModel().setTerminal(edge, terminal, source);
|
this.getDataModel().setTerminal(edge, terminal, source);
|
||||||
|
|
|
@ -16,7 +16,6 @@ limitations under the License.
|
||||||
|
|
||||||
import { mixInto } from '../../util/Utils';
|
import { mixInto } from '../../util/Utils';
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
|
|
||||||
declare module '../Graph' {
|
declare module '../Graph' {
|
||||||
|
@ -32,7 +31,7 @@ declare module '../Graph' {
|
||||||
setDropEnabled: (value: boolean) => void;
|
setDropEnabled: (value: boolean) => void;
|
||||||
isSplitEnabled: () => boolean;
|
isSplitEnabled: () => boolean;
|
||||||
setSplitEnabled: (value: boolean) => void;
|
setSplitEnabled: (value: boolean) => void;
|
||||||
isSplitTarget: (target: Cell, cells?: CellArray, evt?: MouseEvent | null) => boolean;
|
isSplitTarget: (target: Cell, cells?: Cell[], evt?: MouseEvent | null) => boolean;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +148,7 @@ const DragDropMixin: PartialType = {
|
||||||
* @param cells {@link mxCell} that should split the edge.
|
* @param cells {@link mxCell} that should split the edge.
|
||||||
* @param evt Mouseevent that triggered the invocation.
|
* @param evt Mouseevent that triggered the invocation.
|
||||||
*/
|
*/
|
||||||
isSplitTarget(target, cells=new CellArray(), evt) {
|
isSplitTarget(target, cells = [], evt) {
|
||||||
if (
|
if (
|
||||||
target.isEdge() &&
|
target.isEdge() &&
|
||||||
cells.length === 1 &&
|
cells.length === 1 &&
|
||||||
|
|
|
@ -15,7 +15,6 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import { mixInto } from '../../util/Utils';
|
import { mixInto } from '../../util/Utils';
|
||||||
import { removeDuplicates } from '../../util/arrayUtils';
|
import { removeDuplicates } from '../../util/arrayUtils';
|
||||||
import { findNearestSegment } from '../../util/mathUtils';
|
import { findNearestSegment } from '../../util/mathUtils';
|
||||||
|
@ -52,7 +51,7 @@ declare module '../Graph' {
|
||||||
flipEdge: (edge: Cell) => Cell;
|
flipEdge: (edge: Cell) => Cell;
|
||||||
splitEdge: (
|
splitEdge: (
|
||||||
edge: Cell,
|
edge: Cell,
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
newEdge: Cell | null,
|
newEdge: Cell | null,
|
||||||
dx?: number,
|
dx?: number,
|
||||||
dy?: number,
|
dy?: number,
|
||||||
|
@ -76,10 +75,10 @@ declare module '../Graph' {
|
||||||
target: Cell | null,
|
target: Cell | null,
|
||||||
index?: number | null
|
index?: number | null
|
||||||
) => Cell;
|
) => Cell;
|
||||||
addAllEdges: (cells: CellArray) => CellArray;
|
addAllEdges: (cells: Cell[]) => Cell[];
|
||||||
getAllEdges: (cells: CellArray | null) => CellArray;
|
getAllEdges: (cells: Cell[] | null) => Cell[];
|
||||||
getIncomingEdges: (cell: Cell, parent: Cell | null) => CellArray;
|
getIncomingEdges: (cell: Cell, parent: Cell | null) => Cell[];
|
||||||
getOutgoingEdges: (cell: Cell, parent: Cell | null) => CellArray;
|
getOutgoingEdges: (cell: Cell, parent: Cell | null) => Cell[];
|
||||||
getEdges: (
|
getEdges: (
|
||||||
cell: Cell,
|
cell: Cell,
|
||||||
parent?: Cell | null,
|
parent?: Cell | null,
|
||||||
|
@ -87,10 +86,10 @@ declare module '../Graph' {
|
||||||
outgoing?: boolean,
|
outgoing?: boolean,
|
||||||
includeLoops?: boolean,
|
includeLoops?: boolean,
|
||||||
recurse?: boolean
|
recurse?: boolean
|
||||||
) => CellArray;
|
) => Cell[];
|
||||||
getChildEdges: (parent: Cell) => CellArray;
|
getChildEdges: (parent: Cell) => Cell[];
|
||||||
getEdgesBetween: (source: Cell, target: Cell, directed?: boolean) => CellArray;
|
getEdgesBetween: (source: Cell, target: Cell, directed?: boolean) => Cell[];
|
||||||
resetEdges: (cells: CellArray) => void;
|
resetEdges: (cells: Cell[]) => void;
|
||||||
resetEdge: (edge: Cell) => Cell;
|
resetEdge: (edge: Cell) => Cell;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -385,7 +384,7 @@ const EdgeMixin: PartialType = {
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
this.cellsAdded(
|
this.cellsAdded(
|
||||||
new CellArray(newEdge),
|
[newEdge],
|
||||||
parent as Cell,
|
parent as Cell,
|
||||||
parent ? parent.getChildCount() : 0,
|
parent ? parent.getChildCount() : 0,
|
||||||
source,
|
source,
|
||||||
|
@ -492,14 +491,14 @@ const EdgeMixin: PartialType = {
|
||||||
*/
|
*/
|
||||||
addAllEdges(cells) {
|
addAllEdges(cells) {
|
||||||
const allCells = cells.slice();
|
const allCells = cells.slice();
|
||||||
return new CellArray(...removeDuplicates(allCells.concat(this.getAllEdges(cells))));
|
return removeDuplicates(allCells.concat(this.getAllEdges(cells)));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all edges connected to the given cells or its descendants.
|
* Returns all edges connected to the given cells or its descendants.
|
||||||
*/
|
*/
|
||||||
getAllEdges(cells) {
|
getAllEdges(cells) {
|
||||||
let edges: CellArray = new CellArray();
|
let edges: Cell[] = [];
|
||||||
|
|
||||||
if (cells) {
|
if (cells) {
|
||||||
for (let i = 0; i < cells.length; i += 1) {
|
for (let i = 0; i < cells.length; i += 1) {
|
||||||
|
@ -571,7 +570,7 @@ const EdgeMixin: PartialType = {
|
||||||
includeLoops = true,
|
includeLoops = true,
|
||||||
recurse = false
|
recurse = false
|
||||||
) {
|
) {
|
||||||
let edges: CellArray = new CellArray();
|
let edges: Cell[] = [];
|
||||||
const isCollapsed = cell.isCollapsed();
|
const isCollapsed = cell.isCollapsed();
|
||||||
const childCount = cell.getChildCount();
|
const childCount = cell.getChildCount();
|
||||||
|
|
||||||
|
@ -584,7 +583,7 @@ const EdgeMixin: PartialType = {
|
||||||
}
|
}
|
||||||
|
|
||||||
edges = edges.concat(cell.getEdges(incoming, outgoing));
|
edges = edges.concat(cell.getEdges(incoming, outgoing));
|
||||||
const result = new CellArray();
|
const result = [];
|
||||||
|
|
||||||
for (let i = 0; i < edges.length; i += 1) {
|
for (let i = 0; i < edges.length; i += 1) {
|
||||||
const state = this.getView().getState(edges[i]);
|
const state = this.getView().getState(edges[i]);
|
||||||
|
@ -636,7 +635,7 @@ const EdgeMixin: PartialType = {
|
||||||
*/
|
*/
|
||||||
getEdgesBetween(source, target, directed = false) {
|
getEdgesBetween(source, target, directed = false) {
|
||||||
const edges = this.getEdges(source);
|
const edges = this.getEdges(source);
|
||||||
const result = new CellArray();
|
const result = [];
|
||||||
|
|
||||||
// Checks if the edge is connected to the correct
|
// Checks if the edge is connected to the correct
|
||||||
// cell and returns the first match
|
// cell and returns the first match
|
||||||
|
|
|
@ -18,7 +18,6 @@ import Image from '../image/ImageBox';
|
||||||
import Client from '../../Client';
|
import Client from '../../Client';
|
||||||
import CellState from '../cell/CellState';
|
import CellState from '../cell/CellState';
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import EventObject from '../event/EventObject';
|
import EventObject from '../event/EventObject';
|
||||||
import InternalEvent from '../event/InternalEvent';
|
import InternalEvent from '../event/InternalEvent';
|
||||||
import Geometry from '../geometry/Geometry';
|
import Geometry from '../geometry/Geometry';
|
||||||
|
@ -34,18 +33,18 @@ declare module '../Graph' {
|
||||||
|
|
||||||
getCollapseExpandResource: () => string;
|
getCollapseExpandResource: () => string;
|
||||||
isFoldingEnabled: () => boolean;
|
isFoldingEnabled: () => boolean;
|
||||||
getFoldableCells: (cells: CellArray, collapse: boolean) => CellArray | null;
|
getFoldableCells: (cells: Cell[], collapse: boolean) => Cell[] | null;
|
||||||
isCellFoldable: (cell: Cell, collapse: boolean) => boolean;
|
isCellFoldable: (cell: Cell, collapse: boolean) => boolean;
|
||||||
getFoldingImage: (state: CellState) => Image | null;
|
getFoldingImage: (state: CellState) => Image | null;
|
||||||
foldCells: (
|
foldCells: (
|
||||||
collapse: boolean,
|
collapse: boolean,
|
||||||
recurse?: boolean,
|
recurse?: boolean,
|
||||||
cells?: CellArray | null,
|
cells?: Cell[] | null,
|
||||||
checkFoldable?: boolean,
|
checkFoldable?: boolean,
|
||||||
evt?: Event | null
|
evt?: Event | null
|
||||||
) => CellArray | null;
|
) => Cell[] | null;
|
||||||
cellsFolded: (
|
cellsFolded: (
|
||||||
cells: CellArray | null,
|
cells: Cell[] | null,
|
||||||
collapse: boolean,
|
collapse: boolean,
|
||||||
recurse: boolean,
|
recurse: boolean,
|
||||||
checkFoldable?: boolean
|
checkFoldable?: boolean
|
||||||
|
|
|
@ -15,7 +15,6 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import { mixInto } from '../../util/Utils';
|
import { mixInto } from '../../util/Utils';
|
||||||
import { sortCells } from '../../util/styleUtils';
|
import { sortCells } from '../../util/styleUtils';
|
||||||
import Geometry from '../geometry/Geometry';
|
import Geometry from '../geometry/Geometry';
|
||||||
|
@ -27,27 +26,27 @@ import { Graph } from '../Graph';
|
||||||
|
|
||||||
declare module '../Graph' {
|
declare module '../Graph' {
|
||||||
interface Graph {
|
interface Graph {
|
||||||
groupCells: (group: Cell, border: number, cells?: CellArray | null) => Cell;
|
groupCells: (group: Cell, border: number, cells?: Cell[] | null) => Cell;
|
||||||
getCellsForGroup: (cells: CellArray) => CellArray;
|
getCellsForGroup: (cells: Cell[]) => Cell[];
|
||||||
getBoundsForGroup: (
|
getBoundsForGroup: (
|
||||||
group: Cell,
|
group: Cell,
|
||||||
children: CellArray,
|
children: Cell[],
|
||||||
border: number | null
|
border: number | null
|
||||||
) => Rectangle | null;
|
) => Rectangle | null;
|
||||||
createGroupCell: (cells: CellArray) => Cell;
|
createGroupCell: (cells: Cell[]) => Cell;
|
||||||
ungroupCells: (cells?: CellArray | null) => CellArray;
|
ungroupCells: (cells?: Cell[] | null) => Cell[];
|
||||||
getCellsForUngroup: () => CellArray;
|
getCellsForUngroup: () => Cell[];
|
||||||
removeCellsAfterUngroup: (cells: CellArray) => void;
|
removeCellsAfterUngroup: (cells: Cell[]) => void;
|
||||||
removeCellsFromParent: (cells?: CellArray | null) => CellArray;
|
removeCellsFromParent: (cells?: Cell[] | null) => Cell[];
|
||||||
updateGroupBounds: (
|
updateGroupBounds: (
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
border?: number,
|
border?: number,
|
||||||
moveGroup?: boolean,
|
moveGroup?: boolean,
|
||||||
topBorder?: number,
|
topBorder?: number,
|
||||||
rightBorder?: number,
|
rightBorder?: number,
|
||||||
bottomBorder?: number,
|
bottomBorder?: number,
|
||||||
leftBorder?: number
|
leftBorder?: number
|
||||||
) => CellArray;
|
) => Cell[];
|
||||||
enterGroup: (cell: Cell) => void;
|
enterGroup: (cell: Cell) => void;
|
||||||
exitGroup: () => void;
|
exitGroup: () => void;
|
||||||
}
|
}
|
||||||
|
@ -141,24 +140,15 @@ const GroupingMixin: PartialType = {
|
||||||
|
|
||||||
// Adds the group into the parent
|
// Adds the group into the parent
|
||||||
let index = (<Cell>parent).getChildCount();
|
let index = (<Cell>parent).getChildCount();
|
||||||
this.cellsAdded(
|
this.cellsAdded([group], <Cell>parent, index, null, null, false, false, false);
|
||||||
new CellArray(group),
|
|
||||||
<Cell>parent,
|
|
||||||
index,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
// Adds the children into the group and moves
|
// Adds the children into the group and moves
|
||||||
index = group.getChildCount();
|
index = group.getChildCount();
|
||||||
this.cellsAdded(<CellArray>cells, group, index, null, null, false, false, false);
|
this.cellsAdded(<Cell[]>cells, group, index, null, null, false, false, false);
|
||||||
this.cellsMoved(<CellArray>cells, -bounds.x, -bounds.y, false, false, false);
|
this.cellsMoved(<Cell[]>cells, -bounds.x, -bounds.y, false, false, false);
|
||||||
|
|
||||||
// Resizes the group
|
// Resizes the group
|
||||||
this.cellsResized(new CellArray(group), [bounds], false);
|
this.cellsResized([group], [bounds], false);
|
||||||
|
|
||||||
this.fireEvent(
|
this.fireEvent(
|
||||||
new EventObject(InternalEvent.GROUP_CELLS, { group, border, cells })
|
new EventObject(InternalEvent.GROUP_CELLS, { group, border, cells })
|
||||||
|
@ -173,7 +163,7 @@ const GroupingMixin: PartialType = {
|
||||||
* in the given array.
|
* in the given array.
|
||||||
*/
|
*/
|
||||||
getCellsForGroup(cells) {
|
getCellsForGroup(cells) {
|
||||||
const result = new CellArray();
|
const result = [];
|
||||||
if (cells != null && cells.length > 0) {
|
if (cells != null && cells.length > 0) {
|
||||||
const parent = cells[0].getParent();
|
const parent = cells[0].getParent();
|
||||||
result.push(cells[0]);
|
result.push(cells[0]);
|
||||||
|
@ -247,7 +237,7 @@ const GroupingMixin: PartialType = {
|
||||||
* selection cells are used.
|
* selection cells are used.
|
||||||
*/
|
*/
|
||||||
ungroupCells(cells) {
|
ungroupCells(cells) {
|
||||||
let result: CellArray = new CellArray();
|
let result: Cell[] = [];
|
||||||
|
|
||||||
if (cells == null) {
|
if (cells == null) {
|
||||||
cells = this.getCellsForUngroup();
|
cells = this.getCellsForUngroup();
|
||||||
|
@ -255,7 +245,7 @@ const GroupingMixin: PartialType = {
|
||||||
|
|
||||||
if (cells != null && cells.length > 0) {
|
if (cells != null && cells.length > 0) {
|
||||||
this.batchUpdate(() => {
|
this.batchUpdate(() => {
|
||||||
const _cells = <CellArray>cells;
|
const _cells = <Cell[]>cells;
|
||||||
|
|
||||||
for (let i = 0; i < _cells.length; i += 1) {
|
for (let i = 0; i < _cells.length; i += 1) {
|
||||||
let children = _cells[i].getChildren();
|
let children = _cells[i].getChildren();
|
||||||
|
@ -299,7 +289,7 @@ const GroupingMixin: PartialType = {
|
||||||
const cells = this.getSelectionCells();
|
const cells = this.getSelectionCells();
|
||||||
|
|
||||||
// Finds the cells with children
|
// Finds the cells with children
|
||||||
const tmp = new CellArray();
|
const tmp = [];
|
||||||
|
|
||||||
for (let i = 0; i < cells.length; i += 1) {
|
for (let i = 0; i < cells.length; i += 1) {
|
||||||
if (cells[i].isVertex() && cells[i].getChildCount() > 0) {
|
if (cells[i].isVertex() && cells[i].getChildCount() > 0) {
|
||||||
|
@ -332,10 +322,8 @@ const GroupingMixin: PartialType = {
|
||||||
const parent = this.getDefaultParent();
|
const parent = this.getDefaultParent();
|
||||||
const index = parent.getChildCount();
|
const index = parent.getChildCount();
|
||||||
|
|
||||||
this.cellsAdded(<CellArray>cells, parent, index, null, null, true);
|
this.cellsAdded(<Cell[]>cells, parent, index, null, null, true);
|
||||||
this.fireEvent(
|
this.fireEvent(new EventObject(InternalEvent.REMOVE_CELLS_FROM_PARENT, { cells }));
|
||||||
new EventObject(InternalEvent.REMOVE_CELLS_FROM_PARENT, { cells })
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
return cells;
|
return cells;
|
||||||
},
|
},
|
||||||
|
@ -383,7 +371,7 @@ const GroupingMixin: PartialType = {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const children = <CellArray>this.getChildCells(cells[i]);
|
const children = this.getChildCells(cells[i]);
|
||||||
if (children != null && children.length > 0) {
|
if (children != null && children.length > 0) {
|
||||||
const bounds = this.getBoundingBoxFromGeometry(children, true);
|
const bounds = this.getBoundingBoxFromGeometry(children, true);
|
||||||
|
|
||||||
|
|
|
@ -14,17 +14,17 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import { mixInto } from '../../util/Utils';
|
import { mixInto } from '../../util/Utils';
|
||||||
import { sortCells } from '../../util/styleUtils';
|
import { sortCells } from '../../util/styleUtils';
|
||||||
import EventObject from '../event/EventObject';
|
import EventObject from '../event/EventObject';
|
||||||
import InternalEvent from '../event/InternalEvent';
|
import InternalEvent from '../event/InternalEvent';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
|
import Cell from '../cell/Cell';
|
||||||
|
|
||||||
declare module '../Graph' {
|
declare module '../Graph' {
|
||||||
interface Graph {
|
interface Graph {
|
||||||
orderCells: (back: boolean, cells?: CellArray) => CellArray;
|
orderCells: (back: boolean, cells?: Cell[]) => Cell[];
|
||||||
cellsOrdered: (cells: CellArray, back: boolean) => void;
|
cellsOrdered: (cells: Cell[], back: boolean) => void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ const OrderMixin: PartialType = {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.batchUpdate(() => {
|
this.batchUpdate(() => {
|
||||||
this.cellsOrdered(<CellArray>cells, back);
|
this.cellsOrdered(<Cell[]>cells, back);
|
||||||
const event = new EventObject(
|
const event = new EventObject(
|
||||||
InternalEvent.ORDER_CELLS,
|
InternalEvent.ORDER_CELLS,
|
||||||
'back',
|
'back',
|
||||||
|
@ -86,13 +86,15 @@ const OrderMixin: PartialType = {
|
||||||
if (back) {
|
if (back) {
|
||||||
this.getDataModel().add(parent, cells[i], i);
|
this.getDataModel().add(parent, cells[i], i);
|
||||||
} else {
|
} else {
|
||||||
this.getDataModel().add(parent, cells[i], parent ? parent.getChildCount() - 1 : 0);
|
this.getDataModel().add(
|
||||||
|
parent,
|
||||||
|
cells[i],
|
||||||
|
parent ? parent.getChildCount() - 1 : 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.fireEvent(
|
this.fireEvent(new EventObject(InternalEvent.CELLS_ORDERED, { back, cells }));
|
||||||
new EventObject(InternalEvent.CELLS_ORDERED, { back, cells })
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,7 +15,6 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import Rectangle from '../geometry/Rectangle';
|
import Rectangle from '../geometry/Rectangle';
|
||||||
import Dictionary from '../../util/Dictionary';
|
import Dictionary from '../../util/Dictionary';
|
||||||
import RootChange from '../undoable_changes/RootChange';
|
import RootChange from '../undoable_changes/RootChange';
|
||||||
|
@ -26,7 +25,7 @@ import GraphSelectionModel from '../GraphSelectionModel';
|
||||||
|
|
||||||
declare module '../Graph' {
|
declare module '../Graph' {
|
||||||
interface Graph {
|
interface Graph {
|
||||||
cells: CellArray;
|
cells: Cell[];
|
||||||
doneResource: string;
|
doneResource: string;
|
||||||
updatingSelectionResource: string;
|
updatingSelectionResource: string;
|
||||||
singleSelection: boolean;
|
singleSelection: boolean;
|
||||||
|
@ -39,14 +38,14 @@ declare module '../Graph' {
|
||||||
clearSelection: () => void;
|
clearSelection: () => void;
|
||||||
getSelectionCount: () => number;
|
getSelectionCount: () => number;
|
||||||
getSelectionCell: () => Cell;
|
getSelectionCell: () => Cell;
|
||||||
getSelectionCells: () => CellArray;
|
getSelectionCells: () => Cell[];
|
||||||
setSelectionCell: (cell: Cell | null) => void;
|
setSelectionCell: (cell: Cell | null) => void;
|
||||||
setSelectionCells: (cells: CellArray) => void;
|
setSelectionCells: (cells: Cell[]) => void;
|
||||||
addSelectionCell: (cell: Cell) => void;
|
addSelectionCell: (cell: Cell) => void;
|
||||||
addSelectionCells: (cells: CellArray) => void;
|
addSelectionCells: (cells: Cell[]) => void;
|
||||||
removeSelectionCell: (cell: Cell) => void;
|
removeSelectionCell: (cell: Cell) => void;
|
||||||
removeSelectionCells: (cells: CellArray) => void;
|
removeSelectionCells: (cells: Cell[]) => void;
|
||||||
selectRegion: (rect: Rectangle, evt: MouseEvent) => CellArray;
|
selectRegion: (rect: Rectangle, evt: MouseEvent) => Cell[];
|
||||||
selectNextCell: () => void;
|
selectNextCell: () => void;
|
||||||
selectPreviousCell: () => void;
|
selectPreviousCell: () => void;
|
||||||
selectParentCell: () => void;
|
selectParentCell: () => void;
|
||||||
|
@ -62,9 +61,9 @@ declare module '../Graph' {
|
||||||
selectGroups?: boolean
|
selectGroups?: boolean
|
||||||
) => void;
|
) => void;
|
||||||
selectCellForEvent: (cell: Cell, evt: MouseEvent) => void;
|
selectCellForEvent: (cell: Cell, evt: MouseEvent) => void;
|
||||||
selectCellsForEvent: (cells: CellArray, evt: MouseEvent) => void;
|
selectCellsForEvent: (cells: Cell[], evt: MouseEvent) => void;
|
||||||
isSiblingSelected: (cell: Cell) => boolean;
|
isSiblingSelected: (cell: Cell) => boolean;
|
||||||
getSelectionCellsForChanges: (changes: any[], ignoreFn?: Function | null) => CellArray;
|
getSelectionCellsForChanges: (changes: any[], ignoreFn?: Function | null) => Cell[];
|
||||||
updateSelection: () => void;
|
updateSelection: () => void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,7 +286,8 @@ const SelectionMixin: PartialType = {
|
||||||
* @param isChild Boolean indicating if the first child cell should be selected.
|
* @param isChild Boolean indicating if the first child cell should be selected.
|
||||||
*/
|
*/
|
||||||
selectCell(isNext = false, isParent = false, isChild = false) {
|
selectCell(isNext = false, isParent = false, isChild = false) {
|
||||||
const cell = this.selectionModel.cells.length > 0 ? this.selectionModel.cells[0] : null;
|
const cell =
|
||||||
|
this.selectionModel.cells.length > 0 ? this.selectionModel.cells[0] : null;
|
||||||
|
|
||||||
if (this.selectionModel.cells.length > 1) {
|
if (this.selectionModel.cells.length > 1) {
|
||||||
this.selectionModel.clear();
|
this.selectionModel.clear();
|
||||||
|
@ -468,7 +468,7 @@ const SelectionMixin: PartialType = {
|
||||||
*/
|
*/
|
||||||
getSelectionCellsForChanges(changes, ignoreFn = null) {
|
getSelectionCellsForChanges(changes, ignoreFn = null) {
|
||||||
const dict = new Dictionary();
|
const dict = new Dictionary();
|
||||||
const cells: CellArray = new CellArray();
|
const cells: Cell[] = [];
|
||||||
|
|
||||||
const addCell = (cell: Cell) => {
|
const addCell = (cell: Cell) => {
|
||||||
if (!dict.get(cell) && this.getDataModel().contains(cell)) {
|
if (!dict.get(cell) && this.getDataModel().contains(cell)) {
|
||||||
|
@ -510,7 +510,7 @@ const SelectionMixin: PartialType = {
|
||||||
*/
|
*/
|
||||||
updateSelection() {
|
updateSelection() {
|
||||||
const cells = this.getSelectionCells();
|
const cells = this.getSelectionCells();
|
||||||
const removed = new CellArray();
|
const removed = [];
|
||||||
|
|
||||||
for (const cell of cells) {
|
for (const cell of cells) {
|
||||||
if (!this.getDataModel().contains(cell) || !cell.isVisible()) {
|
if (!this.getDataModel().contains(cell) || !cell.isVisible()) {
|
||||||
|
|
|
@ -20,7 +20,6 @@ import { mixInto } from '../../util/Utils';
|
||||||
import { convertPoint } from '../../util/styleUtils';
|
import { convertPoint } from '../../util/styleUtils';
|
||||||
import { mod } from '../../util/mathUtils';
|
import { mod } from '../../util/mathUtils';
|
||||||
import { DEFAULT_STARTSIZE, DIRECTION, SHAPE } from '../../util/Constants';
|
import { DEFAULT_STARTSIZE, DIRECTION, SHAPE } from '../../util/Constants';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import { getClientX, getClientY } from '../../util/EventUtils';
|
import { getClientX, getClientY } from '../../util/EventUtils';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
|
|
||||||
|
@ -39,13 +38,9 @@ declare module '../Graph' {
|
||||||
getSwimlaneDirection: (style: CellStateStyle) => DirectionValue;
|
getSwimlaneDirection: (style: CellStateStyle) => DirectionValue;
|
||||||
getActualStartSize: (swimlane: Cell, ignoreState: boolean) => Rectangle;
|
getActualStartSize: (swimlane: Cell, ignoreState: boolean) => Rectangle;
|
||||||
isSwimlane: (cell: Cell, ignoreState?: boolean) => boolean;
|
isSwimlane: (cell: Cell, ignoreState?: boolean) => boolean;
|
||||||
isValidDropTarget: (
|
isValidDropTarget: (cell: Cell, cells?: Cell[], evt?: MouseEvent | null) => boolean;
|
||||||
cell: Cell,
|
|
||||||
cells?: CellArray,
|
|
||||||
evt?: MouseEvent | null
|
|
||||||
) => boolean;
|
|
||||||
getDropTarget: (
|
getDropTarget: (
|
||||||
cells: CellArray,
|
cells: Cell[],
|
||||||
evt: MouseEvent,
|
evt: MouseEvent,
|
||||||
cell: Cell | null,
|
cell: Cell | null,
|
||||||
clone?: boolean
|
clone?: boolean
|
||||||
|
|
|
@ -14,7 +14,6 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import Dictionary from '../../util/Dictionary';
|
import Dictionary from '../../util/Dictionary';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
|
@ -24,11 +23,11 @@ declare module '../Graph' {
|
||||||
interface Graph {
|
interface Graph {
|
||||||
isTerminalPointMovable: (cell: Cell, source: boolean) => boolean;
|
isTerminalPointMovable: (cell: Cell, source: boolean) => boolean;
|
||||||
getOpposites: (
|
getOpposites: (
|
||||||
edges: CellArray,
|
edges: Cell[],
|
||||||
terminal: Cell | null,
|
terminal: Cell | null,
|
||||||
sources?: boolean,
|
sources?: boolean,
|
||||||
targets?: boolean
|
targets?: boolean
|
||||||
) => CellArray;
|
) => Cell[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +73,7 @@ const TerminalMixin: PartialType = {
|
||||||
* included in the result. Default is `true`.
|
* included in the result. Default is `true`.
|
||||||
*/
|
*/
|
||||||
getOpposites(edges, terminal = null, sources = true, targets = true) {
|
getOpposites(edges, terminal = null, sources = true, targets = true) {
|
||||||
const terminals = new CellArray();
|
const terminals = [];
|
||||||
|
|
||||||
// Fast lookup to avoid duplicates in terminals array
|
// Fast lookup to avoid duplicates in terminals array
|
||||||
const dict = new Dictionary<Cell, boolean>();
|
const dict = new Dictionary<Cell, boolean>();
|
||||||
|
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import Geometry from '../geometry/Geometry';
|
import Geometry from '../geometry/Geometry';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import { mixInto } from '../../util/Utils';
|
import { mixInto } from '../../util/Utils';
|
||||||
import type { CellStyle } from '../../types';
|
import type { CellStyle } from '../../types';
|
||||||
|
|
||||||
|
@ -41,7 +40,7 @@ declare module '../Graph' {
|
||||||
relative: boolean,
|
relative: boolean,
|
||||||
geometryClass: typeof Geometry
|
geometryClass: typeof Geometry
|
||||||
) => Cell;
|
) => Cell;
|
||||||
getChildVertices: (parent?: Cell | null) => CellArray;
|
getChildVertices: (parent?: Cell | null) => Cell[];
|
||||||
isVertexLabelsMovable: () => boolean;
|
isVertexLabelsMovable: () => boolean;
|
||||||
setVertexLabelsMovable: (value: boolean) => void;
|
setVertexLabelsMovable: (value: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ import { DIALECT } from '../../util/Constants';
|
||||||
import { addLinkToHead, write } from '../../util/domUtils';
|
import { addLinkToHead, write } from '../../util/domUtils';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import CellState from '../cell/CellState';
|
import CellState from '../cell/CellState';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -178,14 +177,14 @@ import Cell from '../cell/Cell';
|
||||||
class PrintPreview {
|
class PrintPreview {
|
||||||
constructor(
|
constructor(
|
||||||
graph: Graph,
|
graph: Graph,
|
||||||
scale: number | null=null,
|
scale: number | null = null,
|
||||||
pageFormat: Rectangle | null=null,
|
pageFormat: Rectangle | null = null,
|
||||||
border: number | null=null,
|
border: number | null = null,
|
||||||
x0: number=0,
|
x0: number = 0,
|
||||||
y0: number=0,
|
y0: number = 0,
|
||||||
borderColor: string | null=null,
|
borderColor: string | null = null,
|
||||||
title: string='Printer-friendly version',
|
title: string = 'Printer-friendly version',
|
||||||
pageSelector: boolean | null=null
|
pageSelector: boolean | null = null
|
||||||
) {
|
) {
|
||||||
this.graph = graph;
|
this.graph = graph;
|
||||||
this.scale = scale != null ? scale : 1 / graph.pageScale;
|
this.scale = scale != null ? scale : 1 / graph.pageScale;
|
||||||
|
@ -340,7 +339,14 @@ class PrintPreview {
|
||||||
* @param targetWindow Optional window that should be used for rendering. If
|
* @param targetWindow Optional window that should be used for rendering. If
|
||||||
* this is specified then no HEAD tag, CSS and BODY tag will be written.
|
* this is specified then no HEAD tag, CSS and BODY tag will be written.
|
||||||
*/
|
*/
|
||||||
appendGraph(graph: Graph, scale: number, x0: number, y0: number, forcePageBreaks: boolean, keepOpen: boolean) {
|
appendGraph(
|
||||||
|
graph: Graph,
|
||||||
|
scale: number,
|
||||||
|
x0: number,
|
||||||
|
y0: number,
|
||||||
|
forcePageBreaks: boolean,
|
||||||
|
keepOpen: boolean
|
||||||
|
) {
|
||||||
this.graph = graph;
|
this.graph = graph;
|
||||||
this.scale = scale != null ? scale : 1 / graph.pageScale;
|
this.scale = scale != null ? scale : 1 / graph.pageScale;
|
||||||
this.x0 = x0;
|
this.x0 = x0;
|
||||||
|
@ -357,10 +363,10 @@ class PrintPreview {
|
||||||
* this is specified then no HEAD tag, CSS and BODY tag will be written.
|
* this is specified then no HEAD tag, CSS and BODY tag will be written.
|
||||||
*/
|
*/
|
||||||
open(
|
open(
|
||||||
css: string | null=null,
|
css: string | null = null,
|
||||||
targetWindow: Window | null=null,
|
targetWindow: Window | null = null,
|
||||||
forcePageBreaks: boolean=false,
|
forcePageBreaks: boolean = false,
|
||||||
keepOpen: boolean=false
|
keepOpen: boolean = false
|
||||||
): Window | null {
|
): Window | null {
|
||||||
// Closing the window while the page is being rendered may cause an
|
// Closing the window while the page is being rendered may cause an
|
||||||
// exception in IE. This and any other exceptions are simply ignored.
|
// exception in IE. This and any other exceptions are simply ignored.
|
||||||
|
@ -398,7 +404,7 @@ class PrintPreview {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.wnd) {
|
if (!this.wnd) {
|
||||||
throw new Error("Create new window not allowed");
|
throw new Error('Create new window not allowed');
|
||||||
}
|
}
|
||||||
const doc = this.wnd.document;
|
const doc = this.wnd.document;
|
||||||
|
|
||||||
|
@ -666,7 +672,7 @@ class PrintPreview {
|
||||||
*/
|
*/
|
||||||
createPageSelector(vpages: number, hpages: number): HTMLTableElement {
|
createPageSelector(vpages: number, hpages: number): HTMLTableElement {
|
||||||
if (!this.wnd) {
|
if (!this.wnd) {
|
||||||
throw new Error("Popup window not created");
|
throw new Error('Popup window not created');
|
||||||
}
|
}
|
||||||
const doc = this.wnd.document;
|
const doc = this.wnd.document;
|
||||||
const table = doc.createElement('table');
|
const table = doc.createElement('table');
|
||||||
|
@ -713,7 +719,14 @@ class PrintPreview {
|
||||||
* Takes the inner div as the argument.
|
* Takes the inner div as the argument.
|
||||||
* @param pageNumber Integer representing the page number.
|
* @param pageNumber Integer representing the page number.
|
||||||
*/
|
*/
|
||||||
renderPage(w: number, h: number, dx: number, dy: number, content: (div: HTMLDivElement) => void, pageNumber?: number): HTMLDivElement{
|
renderPage(
|
||||||
|
w: number,
|
||||||
|
h: number,
|
||||||
|
dx: number,
|
||||||
|
dy: number,
|
||||||
|
content: (div: HTMLDivElement) => void,
|
||||||
|
pageNumber?: number
|
||||||
|
): HTMLDivElement {
|
||||||
let div: HTMLDivElement | null = document.createElement('div');
|
let div: HTMLDivElement | null = document.createElement('div');
|
||||||
let arg = null;
|
let arg = null;
|
||||||
|
|
||||||
|
@ -805,7 +818,14 @@ class PrintPreview {
|
||||||
* @param div Div that contains the output.
|
* @param div Div that contains the output.
|
||||||
* @param clip Contains the clipping rectangle as an {@link Rectangle}.
|
* @param clip Contains the clipping rectangle as an {@link Rectangle}.
|
||||||
*/
|
*/
|
||||||
addGraphFragment(dx: number, dy: number, scale: number, pageNumber: number, div: HTMLDivElement, clip: Rectangle) {
|
addGraphFragment(
|
||||||
|
dx: number,
|
||||||
|
dy: number,
|
||||||
|
scale: number,
|
||||||
|
pageNumber: number,
|
||||||
|
div: HTMLDivElement,
|
||||||
|
clip: Rectangle
|
||||||
|
) {
|
||||||
const view = this.graph.getView();
|
const view = this.graph.getView();
|
||||||
const previousContainer = this.graph.container;
|
const previousContainer = this.graph.container;
|
||||||
this.graph.container = div;
|
this.graph.container = div;
|
||||||
|
@ -895,7 +915,7 @@ class PrintPreview {
|
||||||
try {
|
try {
|
||||||
// Creates the temporary cell states in the view and
|
// Creates the temporary cell states in the view and
|
||||||
// draws them onto the temporary DOM nodes in the view
|
// draws them onto the temporary DOM nodes in the view
|
||||||
const cells = new CellArray(<Cell>this.getRoot());
|
const cells = [<Cell>this.getRoot()];
|
||||||
temp = new TemporaryCellStates(view, scale, cells, null, (state: CellState) => {
|
temp = new TemporaryCellStates(view, scale, cells, null, (state: CellState) => {
|
||||||
return this.getLinkForCellState(state);
|
return this.getLinkForCellState(state);
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,21 +17,17 @@ limitations under the License.
|
||||||
import EventObject from '../event/EventObject';
|
import EventObject from '../event/EventObject';
|
||||||
import Translations from '../../util/Translations';
|
import Translations from '../../util/Translations';
|
||||||
import InternalEvent from '../event/InternalEvent';
|
import InternalEvent from '../event/InternalEvent';
|
||||||
import CellArray from '../cell/CellArray';
|
|
||||||
|
|
||||||
import type { UndoableChange } from '../../types';
|
import type { UndoableChange } from '../../types';
|
||||||
import type { Graph } from '../Graph';
|
import type { Graph } from '../Graph';
|
||||||
|
import Cell from '../cell/Cell';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class SelectionChange
|
* @class SelectionChange
|
||||||
* Action to change the current root in a view.
|
* Action to change the current root in a view.
|
||||||
*/
|
*/
|
||||||
class SelectionChange implements UndoableChange {
|
class SelectionChange implements UndoableChange {
|
||||||
constructor(
|
constructor(graph: Graph, added: Cell[] = [], removed: Cell[] = []) {
|
||||||
graph: Graph,
|
|
||||||
added: CellArray = new CellArray(),
|
|
||||||
removed: CellArray = new CellArray()
|
|
||||||
) {
|
|
||||||
this.graph = graph;
|
this.graph = graph;
|
||||||
this.added = added.slice();
|
this.added = added.slice();
|
||||||
this.removed = removed.slice();
|
this.removed = removed.slice();
|
||||||
|
@ -39,9 +35,9 @@ class SelectionChange implements UndoableChange {
|
||||||
|
|
||||||
graph: Graph;
|
graph: Graph;
|
||||||
|
|
||||||
added: CellArray;
|
added: Cell[];
|
||||||
|
|
||||||
removed: CellArray;
|
removed: Cell[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the current root of the view.
|
* Changes the current root of the view.
|
||||||
|
|
|
@ -27,6 +27,7 @@ import {
|
||||||
GraphDataModel,
|
GraphDataModel,
|
||||||
styleUtils,
|
styleUtils,
|
||||||
stringUtils,
|
stringUtils,
|
||||||
|
cellArrayUtils,
|
||||||
} from '@maxgraph/core';
|
} from '@maxgraph/core';
|
||||||
|
|
||||||
import { globalTypes } from '../.storybook/preview';
|
import { globalTypes } from '../.storybook/preview';
|
||||||
|
@ -171,7 +172,7 @@ const Template = ({ label, ...args }) => {
|
||||||
if (graph.isEnabled() && !graph.isSelectionEmpty()) {
|
if (graph.isEnabled() && !graph.isSelectionEmpty()) {
|
||||||
copyCells(
|
copyCells(
|
||||||
graph,
|
graph,
|
||||||
utils.sortCells(graph.model.getTopmostCells(graph.getSelectionCells()))
|
styleUtils.sortCells(cellArrayUtils.getTopmostCells(graph.getSelectionCells()))
|
||||||
);
|
);
|
||||||
dx = 0;
|
dx = 0;
|
||||||
dy = 0;
|
dy = 0;
|
||||||
|
@ -194,7 +195,7 @@ const Template = ({ label, ...args }) => {
|
||||||
let cells = [];
|
let cells = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const doc = utils.parseXml(xml);
|
const doc = xmlUtils.parseXml(xml);
|
||||||
const node = doc.documentElement;
|
const node = doc.documentElement;
|
||||||
|
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
|
|
|
@ -26,7 +26,6 @@ import {
|
||||||
Guide,
|
Guide,
|
||||||
eventUtils,
|
eventUtils,
|
||||||
Cell,
|
Cell,
|
||||||
CellArray,
|
|
||||||
Geometry,
|
Geometry,
|
||||||
} from '@maxgraph/core';
|
} from '@maxgraph/core';
|
||||||
|
|
||||||
|
@ -151,7 +150,7 @@ const Template = ({ label, ...args }) => {
|
||||||
const funct = (graph, evt, target, x, y) => {
|
const funct = (graph, evt, target, x, y) => {
|
||||||
const cell = new Cell('Test', new Geometry(0, 0, 120, 40));
|
const cell = new Cell('Test', new Geometry(0, 0, 120, 40));
|
||||||
cell.vertex = true;
|
cell.vertex = true;
|
||||||
const cells = graph.importCells(new CellArray(cell), x, y, target);
|
const cells = graph.importCells([cell], x, y, target);
|
||||||
|
|
||||||
if (cells != null && cells.length > 0) {
|
if (cells != null && cells.length > 0) {
|
||||||
graph.scrollCellToVisible(cells[0]);
|
graph.scrollCellToVisible(cells[0]);
|
||||||
|
@ -175,7 +174,16 @@ const Template = ({ label, ...args }) => {
|
||||||
// if scalePreview (last) argument is true. Dx and dy are null to force
|
// if scalePreview (last) argument is true. Dx and dy are null to force
|
||||||
// the use of the defaults. Note that dx and dy are only used for the
|
// the use of the defaults. Note that dx and dy are only used for the
|
||||||
// drag icon but not for the preview.
|
// drag icon but not for the preview.
|
||||||
const ds = gestureUtils.makeDraggable(img, graphF, funct, dragElt, null, null, graphs[0].autoscroll, true);
|
const ds = gestureUtils.makeDraggable(
|
||||||
|
img,
|
||||||
|
graphF,
|
||||||
|
funct,
|
||||||
|
dragElt,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
graphs[0].autoscroll,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
// Redirects feature to global switch. Note that this feature should only be used
|
// Redirects feature to global switch. Note that this feature should only be used
|
||||||
// if the the x and y arguments are used in funct to insert the cell.
|
// if the the x and y arguments are used in funct to insert the cell.
|
||||||
|
|
|
@ -15,7 +15,12 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Graph, RubberBandHandler, SelectionHandler, PopupMenuHandler } from '@maxgraph/core';
|
import {
|
||||||
|
Graph,
|
||||||
|
RubberBandHandler,
|
||||||
|
SelectionHandler,
|
||||||
|
PopupMenuHandler,
|
||||||
|
} from '@maxgraph/core';
|
||||||
|
|
||||||
import { globalTypes } from '../.storybook/preview';
|
import { globalTypes } from '../.storybook/preview';
|
||||||
|
|
||||||
|
@ -58,8 +63,9 @@ const Template = ({ label, ...args }) => {
|
||||||
const graphHandlerGetInitialCellForEvent =
|
const graphHandlerGetInitialCellForEvent =
|
||||||
SelectionHandler.prototype.getInitialCellForEvent;
|
SelectionHandler.prototype.getInitialCellForEvent;
|
||||||
SelectionHandler.prototype.getInitialCellForEvent = function (me) {
|
SelectionHandler.prototype.getInitialCellForEvent = function (me) {
|
||||||
const model = this.graph.getDataModel();
|
const psel = this.graph.getSelectionCell()
|
||||||
const psel = this.graph.getSelectionCell().getParent();
|
? this.graph.getSelectionCell().getParent()
|
||||||
|
: null;
|
||||||
let cell = graphHandlerGetInitialCellForEvent.apply(this, arguments);
|
let cell = graphHandlerGetInitialCellForEvent.apply(this, arguments);
|
||||||
let parent = cell.getParent();
|
let parent = cell.getParent();
|
||||||
|
|
||||||
|
@ -82,8 +88,9 @@ const Template = ({ label, ...args }) => {
|
||||||
const graphHandlerIsDelayedSelection = SelectionHandler.prototype.isDelayedSelection;
|
const graphHandlerIsDelayedSelection = SelectionHandler.prototype.isDelayedSelection;
|
||||||
SelectionHandler.prototype.isDelayedSelection = function (cell) {
|
SelectionHandler.prototype.isDelayedSelection = function (cell) {
|
||||||
let result = graphHandlerIsDelayedSelection.apply(this, arguments);
|
let result = graphHandlerIsDelayedSelection.apply(this, arguments);
|
||||||
const model = this.graph.getDataModel();
|
const psel = this.graph.getSelectionCell()
|
||||||
const psel = this.graph.getSelectionCell().getParent();
|
? this.graph.getSelectionCell().getParent()
|
||||||
|
: null;
|
||||||
const parent = cell.getParent();
|
const parent = cell.getParent();
|
||||||
|
|
||||||
if (psel == null || (psel != cell && psel != parent)) {
|
if (psel == null || (psel != cell && psel != parent)) {
|
||||||
|
|
|
@ -21,7 +21,6 @@ import {
|
||||||
RubberBandHandler,
|
RubberBandHandler,
|
||||||
ImageBox,
|
ImageBox,
|
||||||
Rectangle,
|
Rectangle,
|
||||||
CellArray,
|
|
||||||
mathUtils,
|
mathUtils,
|
||||||
domUtils,
|
domUtils,
|
||||||
ConnectionHandler,
|
ConnectionHandler,
|
||||||
|
@ -73,7 +72,7 @@ const Template = ({ label, ...args }) => {
|
||||||
|
|
||||||
InternalEvent.addGestureListeners(img, (evt) => {
|
InternalEvent.addGestureListeners(img, (evt) => {
|
||||||
const s = graph.gridSize;
|
const s = graph.gridSize;
|
||||||
graph.setSelectionCells(graph.moveCells(new CellArray(state.cell), s, s, true));
|
graph.setSelectionCells(graph.moveCells([state.cell], s, s, true));
|
||||||
InternalEvent.consume(evt);
|
InternalEvent.consume(evt);
|
||||||
this.destroy();
|
this.destroy();
|
||||||
});
|
});
|
||||||
|
@ -99,7 +98,7 @@ const Template = ({ label, ...args }) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
InternalEvent.addListener(img, 'click', (evt) => {
|
InternalEvent.addListener(img, 'click', (evt) => {
|
||||||
graph.removeCells(new CellArray(state.cell));
|
graph.removeCells([state.cell]);
|
||||||
InternalEvent.consume(evt);
|
InternalEvent.consume(evt);
|
||||||
this.destroy();
|
this.destroy();
|
||||||
});
|
});
|
||||||
|
|
|
@ -24,7 +24,6 @@ import {
|
||||||
GraphDataModel,
|
GraphDataModel,
|
||||||
KeyHandler,
|
KeyHandler,
|
||||||
Cell,
|
Cell,
|
||||||
CellArray,
|
|
||||||
Geometry,
|
Geometry,
|
||||||
DragSource,
|
DragSource,
|
||||||
DomHelpers,
|
DomHelpers,
|
||||||
|
@ -160,7 +159,7 @@ const Template = ({ label, ...args }) => {
|
||||||
vertex.geometry.x = pt.x;
|
vertex.geometry.x = pt.x;
|
||||||
vertex.geometry.y = pt.y;
|
vertex.geometry.y = pt.y;
|
||||||
|
|
||||||
graph.setSelectionCells(graph.importCells(new CellArray(vertex), 0, 0, cell));
|
graph.setSelectionCells(graph.importCells([vertex], 0, 0, cell));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Creates the image which is used as the drag icon (preview)
|
// Creates the image which is used as the drag icon (preview)
|
||||||
|
|
Loading…
Reference in New Issue