/* * Type definitions for GoJS v2.3.17 * Project: https://gojs.net * Definitions by: Northwoods Software * Definitions: https://github.com/NorthwoodsSoftware/GoJS * Copyright (C) 1998-2023 by Northwoods Software Corporation. * This requires TypeScript v2.8 or later. */ // UMD. For ES6, use go-module.d.ts export as namespace go; /** * The ObjectData type is the same as `{ [index: string]: any; }`. * This is to ease writing `someDataObject.anyPropertyName`, * when dealing with arbitrary JavaScript Objects used as model data. * @category Type */ export interface ObjectData { [index: string]: any; } /** * (undocumented) * @unrestricted */ export class EnumValue { /** * @param {function()} classfunc * @param {string} name * @param {number} val */ constructor(classfunc: Function, name: string, val: number); /** */ get classType(): Function; /** */ get name(): string; } /** * This interface is implemented by the List, Set, and Map * classes; it provides the #iterator read-only property that returns an Iterator. * * Typical usage is: * ```js * var it = anIterableCollection.iterator; * while (it.next()) { * var item = it.value; * } * ``` * @interface * @template T * @category Collection */ export interface Iterable { /** * Gets an Iterator that can iterate over the items in the collection. * * Typical usage is: * ```js * var it = anIterableCollection.iterator; * while (it.next()) { * var item = it.value; * } * ``` * @return {Iterator.} */ iterator: Iterator; /** * Returns the first item in the list, or null if there is none. * @return {T|null} This returns null if there are no items in the list. */ first(): T | null; /** * This read-only property is the number of elements in the collection. */ readonly count: number; } /** * This interface defines properties and methods for iterating over a collection; * it provides the #next predicate and the #value read-only property. * Some Iterators also provide `key` property values along with each `value`. * * Typical usage is: * ```js * var it = anIterableCollection.iterator; * while (it.next()) { * var item = it.value; * } * ``` * * Many iterators will signal an error if #next is called * after the underlying collection has been modified. * * To avoid confusion when dealing with Iterables, * iterators implement the Iterable#iterator property * by just returning themselves. * @interface * @template T * @extends {Iterable.} * @category Collection */ export interface Iterator extends Iterable { /** * Returns itself, which is convenient for code that expects an Iterable * instead of an Iterator. * @return {Iterator.} */ iterator: Iterator; /** * Call this method to advance the iterator to the next item in the collection. * This should be called before accessing any #value. * @return {boolean} whether another item is available; when true the value of #value will be that item. */ next(): boolean; /** * Call this method to advance the iterator to the next item in the collection. * This should be called before accessing any #value. * @return {boolean} whether another item is available; when true the value of #value will be that item. */ hasNext(): boolean; /** * Advance if needed to the first item in the collection and return it, or return null if there is none. * * Caution: this returns a *key/value pair*, not a *value*, for Map iterators. * @return {T|null} * @since 1.1 */ first(): T | null; /** * Start this iterator all over again. */ reset(): void; /** * This is true if any invocation of the given predicate on items in the collection is true. * * Call the given predicate on each item in the collection. * As soon as a call returns true, this returns true. * Otherwise this returns false. * For an empty collection this returns false. * * This automatically #reset's itself when it is called. * @expose * @param {function(T):boolean} pred This function must not have any side-effects. * @return {boolean} True if any predicate call is true; false otherwise. * @since 1.4 */ any(pred: (x: T) => boolean): boolean; /** * This is true if all invocations of the given predicate on items in the collection are true. * * Call the given predicate on each item in the collection. * As soon as a call returns false, this returns false. * Otherwise this returns true. * For an empty collection this returns true. * * This automatically #reset's itself when it is called. * @expose * @param {function(T):boolean} pred This function must not have any side-effects. * @return {boolean} True if all predicate calls are true; false otherwise. * @since 1.4 */ all(pred: (x: T) => boolean): boolean; /** * Call the given function on each item in the collection. * * This automatically #reset's itself when it is called. * @expose * @param {function(T)} func This function must not modify the collection. * @return {Iterator} this iterator itself * @since 1.4 */ each(func: (x: T) => void): void; /** * Call the given function on each item in the collection and present the results in an iterator. * * This automatically #reset's itself when it is called. * @expose * @param {function(T)} func This function must not modify the collection. * @return {Iterator} this */ map(func: (x: T) => S): Iterator; /** * Call the given predicate on each item in the collection and for each item that it returns true, present the item in an iterator. * * This automatically #reset's itself when it is called. * @expose * @param {function(T):boolean} pred This function must not have any side-effects. * @return {Iterator.} this */ filter(pred: (x: T) => boolean): Iterator; /** * Gets the current item in the collection, assuming #next has just returned true. */ readonly value: T; /** * Gets the current index to the item in the collection, assuming #next has just returned true. */ readonly key: any; /** * This read-only property is the total number of items in the iterated collection. */ readonly count: number; } /** * (undocumented) interface used for both the SVGSurface and the CanvasSurface, which are undocumented classes. */ export interface ISurface { domElement: Element; context: IContext; width: number; height: number; ownerDocument: Document; resize(pixelWidth: number, pixelHeight: number, width: number, height: number): boolean; elementFinished: ((a: GraphObject, b: SVGElement) => void) | null; getBoundingClientRect(): DOMRect; focus(): void; dispose(): void; style: CSSStyleDeclaration; } /** * (undocumented) interface used for both the SVGContext and the CanvasSurfaceContext, which are undocumented classes. */ export interface IContext { fillStyle: string | CanvasGradient | CanvasPattern | SGradient; font: string; globalAlpha: number; lineCap: string; lineDashOffset: number; lineJoin: string; lineWidth: number; miterLimit: number; shadowBlur: number; shadowColor: string; shadowOffsetX: number; shadowOffsetY: number; strokeStyle: string | CanvasGradient | CanvasPattern | SGradient; textAlign: string; imageSmoothingEnabled: boolean; clipInsteadOfFill: boolean; currentlyShadowed: boolean; isTemporary: boolean; filter: string; cachedTransform: any; commitTransform(): void; setImageSmoothingEnabled(smooth: boolean): void; arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise: boolean, lx?: number, ly?: number): void; beginPath(): void; endPath(pathIndex?: number): void; bezierCurveTo(a: number, b: number, c: number, d: number, e: number, f: number): void; clearRect(x: number, y: number, w: number, h: number): void; clip(): void; closePath(): void; createLinearGradient(aX0: number, aY0: number, aX1: number, aY1: number): CanvasGradient | SGradient; createPattern(image: HTMLCanvasElement | HTMLImageElement, repetition: string): CanvasPattern | string; createRadialGradient(aX0: number, aY0: number, aR0: number, aX1: number, aY1: number, aR1: number): CanvasGradient | SGradient; drawImage(src: HTMLCanvasElement | HTMLImageElement | HTMLVideoElement, sx: number, sy: number, sw?: number, sh?: number, dx?: number, dy?: number, dw?: number, dh?: number): void; fill(fillRule?: boolean): void; fillRect(x: number, y: number, w: number, h: number): void; fillBackground(x: number, y: number, w: number, h: number): void; fillText(str: string, x: number, y: number): void; getImageData(x: number, y: number, w: number, h: number): ImageData; lineTo(x: number, y: number): void; measureText(text: string): TextMetrics; moveTo(x: number, y: number): void; quadraticCurveTo(a: number, b: number, c: number, d: number): void; rect(x: number, y: number, w: number, h: number): void; restore(): void; rotate(angle: number): void; save(): void; setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void; scale(x: number, y: number): void; stroke(): void; transform(a: number, b: number, c: number, d: number, e: number, f: number): void; translate(x: number, y: number): void; fillContext(brush: BrushLike, fillRule?: boolean): void; strokeContext(): void; shadowsSet(x: number, y: number, blur: number): void; shadowsOff(): void; shadowsOn(): void; enableDash(strokeDashArray: Array, strokeDashOffset: number): void; disableDash(): void; clearContextCache(clearFont: boolean): void; removePartFromView(p: GraphObject): void; } /** * NOTE: For 2.0 the #constructor argument has changed. * List now optionally accepts a collection, and only checks types in TypeScript. * * An ordered iterable collection. * In TypeScript it is a generic class that enforces at compile-time the type of elements that may be added to the List. * * An example usage: * ```js * var list = new go.List(); // or in TypeScript: new go.List(); * list.add(new go.Point(0, 0)); * list.add(new go.Point(20, 10)); * list.add(new go.Point(10, 20)); * // now list.length === 3 * // and list.elt(1) instanceof go.Point * ``` * * You can iterate over the items in a List: * ```js * var it = aList.iterator; * while (it.next()) { * console.log("#" + it.key + " is " + it.value); * } * ``` * Or: * ```js * aList.each(val => { * console.log(val); * }); * ``` * The key will range from zero to #count-1. * * For convenience this **GoJS** List class has synonyms for the following methods and property: * - **get(idx)**: #elt * - **set(idx,val)**: #setElt * - **has(val)**: #contains * - **delete(val)**: #remove * - **clear()**: #clear * - **size**: #count * * The constructor now takes an optional Iterable or Array argument that provides the initial elements for the new List. * * Note that GoJS iteration is quite different than ES6 iteration, so that functionality has not been made somewhat compatible. * These collection classes were defined in GoJS before the ES6 collection classes were proposed. * @template T * @implements {Iterable.} * @unrestricted * @category Collection */ export class List implements Iterable { /** * There are two possible constructors: * * `new go.List()`, for JavaScript * * `new go.List()` for TypeScript, to enforce type checking. * * Typical usage would be something like: * ```js * var list = new go.List(); // keep a list of GraphObjects * ``` * @param {Iterable.|Array.=} coll an optional collection of items to add. */ constructor(coll?: Iterable | Array); /** * @return {string} */ toString(): string; /** * Adds a given value to the end of the List. * * Be careful not to call this method while iterating over the collection. * @param {*} val * @return {List.} This modified List. */ add(val: T): List; /** * Adds a given value to the end of the List. * * Be careful not to call this method while iterating over the collection. * @param {*} val */ push(val: T): void; /** * Adds all of the values of a collection to the end of this List. * * Be careful not to call this method while iterating over the collection. * @param {Iterable.|Array.} coll the collection of items to add. * @return {List.} This modified List. */ addAll(coll: Iterable | Array): List; /** * Clears the List. * This sets the #count to zero. * * Be careful not to call this method while iterating over the collection. */ clear(): void; /** * Returns whether the given value is in this List. * @param {T} val The value to check. * @return {boolean} Whether or not the value is contained within the List. */ contains(val: T): boolean; /** * Returns whether the given value is in this List. * @param {T} val The value to check. * @return {boolean} Whether or not the value is contained within the List. */ has(val: T): boolean; /** * Returns the index of the given value if it is in this List. * @param {T} val The value to check. * @return {number} int returns -1 if the value is not in this list. */ indexOf(val: T): number; /** * Returns the element at the given index. * @param {number} i int The index of the element to return. * @return {T} the value at the given index. */ elt(i: number): T; /** * Returns the element at the given index. * @param {number} i int The index of the element to return. * @return {T} the value at the given index. */ get(i: number): T; /** * Set the element at the given index to a given value. * @param {number} i int The index of the element to set. * @param {T} val The value to set at the index. */ setElt(i: number, val: T): void; /** * Set the element at the given index to a given value. * @param {number} i int The index of the element to set. * @param {T} val The value to set at the index. */ set(i: number, val: T): void; /** * Returns the first item in the list, or null if there is none. * @return {T|null} This returns null if there are no items in the list. */ first(): T | null; /** * Returns the last item in the list, or null if these is none. * @return {T|null} This returns null if there are no items in the list. * @since 1.5 */ last(): T | null; /** * Returns the last item in the list and removes it from the list, or just return null if these is none. * Use #add to push an item onto the end of the list. * Use #last to get the last item without reducing the length of the list. * @return {T|null} This returns null if there are no items in the list. * @since 1.5 */ pop(): T | null; /** * This is true if any invocation of the given predicate on items in the collection is true. * * Call the given predicate on each item in the collection. * As soon as a call returns true, this returns true. * Otherwise this returns false. * For an empty collection this returns false. * @expose * @param {function(T):boolean} pred This function must not have any side-effects. * @return {boolean} True if any predicate call is true; false otherwise. * @since 1.4 */ any(pred: ((a: T) => boolean)): boolean; /** * This is true if all invocations of the given predicate on items in the collection are true. * * Call the given predicate on each item in the collection. * As soon as a call returns false, this returns false. * Otherwise this returns true. * For an empty collection this returns true. * @expose * @param {function(T):boolean} pred This function must not have any side-effects. * @return {boolean} True if all predicate calls are true; false otherwise. * @since 1.4 */ all(pred: ((a: T) => boolean)): boolean; /** * Call the given function on each item in the collection. * @expose * @param {function(T)} func This function must not modify the collection. * @return {List.} This List itself * @since 1.4 */ each(func: ((a: T) => void)): List; /** * Call the given function on each item in the collection and collect the results in a new List. * * Unlike Iterator#map, this returns a List, not an Iterator. * @expose * @param {function(T):*} func This function must not modify the collection. * @return {List.} */ map(func: ((a: T) => S)): List; /** * Call the given predicate on each item in the collection and for each item that it returns true, collect the item in a new List. * * Unlike Iterator#filter, this returns a List, not an Iterator. * @expose * @param {function(T):boolean} pred This function must not have any side-effects. * @return {List.} */ filter(pred: ((a: T) => boolean)): List; /** * Insert a value before the index i. * * Be careful not to call this method while iterating over the collection. * @param {number} i int The index to insert before. * @param {T} val The value to insert. */ insertAt(i: number, val: T): void; /** * Removes a given value (if found) from the List. * * Be careful not to call this method while iterating over the collection. * @param {T} val The value to remove. * @return {boolean} true if the value was found and removed, false otherwise. */ remove(val: T): boolean; /** * Removes a given value (if found) from the List. * * Be careful not to call this method while iterating over the collection. * @param {T} val The value to remove. * @return {boolean} true if the value was found and removed, false otherwise. */ delete(val: T): boolean; /** * Removes a value at a given index from the List. * * Be careful not to call this method while iterating over the collection. * @param {number} i int The index to remove. */ removeAt(i: number): void; /** * Removes a range of values from the List, given both the starting and the ending zero-based indexes. * For example, * ```js * list.removeRange(2, 4) * ``` * will remove elements 2, 3, and 4 from the list. * If there were two or fewer elements in the list to begin with, the list is unchanged. * If *from* is greater than *to*, the list is unchanged. * If *from* is greater than or equal to the length, the list is unchanged. * If *to* is less than zero, the list is unchanged. * * Be careful not to call this method while iterating over the collection. * @param {number} from int The starting index of the range to remove, inclusive; negative values are treated as zero * @param {number} to int The ending index of the range to remove, inclusive; values greater than the length of the list are treated as referring to the last element * @return {List.} This modified List */ removeRange(from: number, to: number): List; /** * Makes a shallow copy of this List. * The values are not copied, * so if they are objects they may continue to be shared with the original List. * @expose * @return {List.} The new List with the same elements. */ copy(): List; /** * Produces a JavaScript Array from the contents of this List. * @return {Array.} A copy of the List in Array form. */ toArray(): Array; /** * Converts the List to a Set. * The count of the resulting Set may be less than the count of this List * if any duplicates were removed. * @return {Set.} A copy of the contents of this List, * but with duplicates removed and ordering lost. */ toSet(): Set; /** * Sort the List according to a comparison function. * @param {function(T,T):number} sortfunc This function is passed two items in the list. * It should return zero if they are equal, * less than zero if the first value should come before the second value, * or greater than zero if the first value should come after the second value. * @return {List.} This modified List. */ sort(sortfunc: ((a: T, b: T) => number)): List; /** * (undocumented) * Sorts a range of consecutive elements in this List based on the given comparison function. * @param {function(*,*):number} sortfunc This function is passed two elements in the list. * It should return zero if they are equal, * less than zero if the first value should come before the second value, * or greater than zero if the first value should come after the second value. * @param {number=} from int The optional index at which to start the sort, including that element; * default to zero, the first element of the list. * @param {number=} to int The optional index at which to end the sort, excluding that element; * defaults to the end of the list. * @return {List.} This modified List. */ sortRange(sortfunc: ((a: T, b: T) => number), from?: number, to?: number): List; /** * Reverse the order of items in this List. * @return {List.} This modified List. */ reverse(): List; /** * This read-only property is the length of the List. */ get count(): number; /** * This read-only property is the length of the List. */ get size(): number; /** * This read-only property is the length of the List, a synonym for the #count property. */ get length(): number; /** * Gets an object that you can use for iterating over the List. * The key will be an integer from zero to the count-1. * The value will be the item at that index in the list. * Typical usage: * ```js * var it = aList.iterator; * while (it.next()) { * . . . "index: " + it.key + " value: " + it.value . . . * } * ``` */ get iterator(): Iterator; /** * Gets an object that you can use for iterating over the List in backwards order. * The key will be an integer from count-1 to zero. * The value will be the item at that index in the list. * The list is not modified by traversing in reverse order. * Typical usage: * ```js * var it = aList.iteratorBackwards; * while (it.next()) { * . . . 'key: ' + it.key + ' value: ' + it.value . . . * } * ``` */ get iteratorBackwards(): Iterator; } /** * NOTE: For 2.0 the #constructor argument has changed. * Set now optionally accepts a collection, and only checks types in TypeScript. * * An unordered iterable collection that cannot contain two instances of the same value. * In TypeScript it is a generic class that enforces at compile-time the type of elements that may be added to the Set. * * An example usage: * ```js * var set = new go.Set(); // In TypeScript: new go.Set(); * set.add("orange"); * set.add("apple"); * set.add("orange"); * // now set.count === 2 * // and set.contains("orange") === true * // and set.contains("banana") === false * ``` * * You can iterate over the items in a Set: * ```js * var it = aSet.iterator; * while (it.next()) { * . . . it.value . . . * } * ``` * Or: * ```js * aSet.each(val => { * . . . val . . . * }); * ``` * * Although not precisely implementing the features of the EcmaScript 6 **Set** class, * this **GoJS** Set class has synonyms for the following methods and property: * - **add(val)**: #add * - **delete(val)**: #remove * - **has(val)**: #contains * - **clear()**: #clear * - **size**: #count * * The constructor now takes an optional Iterable or Array argument that provides the initial elements for the new Set. * * Note that GoJS iteration is quite different than ES6 iteration, so that functionality has not been made somewhat compatible. * These collection classes were defined in GoJS before the ES6 collection classes were proposed. * @template T * @implements {Iterable.} * @unrestricted * @category Collection */ export class Set implements Iterable { /** * There are two possible constructors: * * `new go.Set()`, for JavaScript * * `new go.Set()` for TypeScript * * In TypeScript, the optional generic argument describes the type of values * that this Set may hold. * * For example, the expression: * ```js * // TypeScript: * new go.Set() * ``` * * Creates a new Set that may only contain Points. * * @param {Iterable.|Array.=} coll an optional collection of items to add. */ constructor(coll?: Iterable | Array); /** * @return {string} */ toString(): string; /** * Adds a given value to the Set, if not already present. * * Be careful not to call this method while iterating over the collection. * @param {T} val The value to add to the Set; must not be null. * @return {Set.} This modified Set. */ add(val: T): Set; /** * Adds all of the values of a collection to this Set. * * Be careful not to call this method while iterating over the collection. * @param {Iterable.|Array.} coll the collection of items to add. * @return {Set.} This modified Set. */ addAll(coll: Iterable | Array): Set; /** * Returns whether the given value is in this Set. * @param {T} val The value to check. * @return {boolean} Whether or not the value is contained within the Set. */ contains(val: T): boolean; /** * Returns whether the given value is in this Set. * @param {T} val The value to check. * @return {boolean} Whether or not the value is contained within the Set. */ has(val: T): boolean; /** * Returns true if all of the values of a given collection are in this Set. * @param {Iterable.} coll the collection of items to check for. * @return {boolean} */ containsAll(coll: Iterable): boolean; /** * Returns true if any of the values of a given collection are in this Set. * @param {Iterable.} coll the collection of items to check for. * @return {boolean} */ containsAny(coll: Iterable): boolean; /** * Returns the first item in the collection, or null if there is none. * @return {T|null} This returns null if there are no items in the collection. */ first(): T | null; /** * This is true if any invocation of the given predicate on items in the collection is true. * * Call the given predicate on each item in the collection. * As soon as a call returns true, this returns true. * Otherwise this returns false. * For an empty collection this returns false. * @expose * @param {function(T):boolean} pred This function must not have any side-effects. * @return {boolean} True if any predicate call is true; false otherwise. * @since 1.4 */ any(pred: ((a: T) => boolean)): boolean; /** * This is true if all invocations of the given predicate on items in the collection are true. * * Call the given predicate on each item in the collection. * As soon as a call returns false, this returns false. * Otherwise this returns true. * For an empty collection this returns true. * @expose * @param {function(T):boolean} pred This function must not have any side-effects. * @return {boolean} True if all predicate calls are true; false otherwise. * @since 1.4 */ all(pred: ((a: T) => boolean)): boolean; /** * Call the given function on each item in the collection. * @expose * @param {function(T)} func This function must not modify the collection. * @return {Set.} This Set itself. * @since 1.4 */ each(func: ((a: T) => void)): Set; /** * Call the given function on each item in the collection and collect the results in a new Set. * * Unlike Iterator#map, this returns a Set, not an Iterator. * @expose * @param {function(T):*} func This function must not modify the collection. * @return {Set.} */ map(func: ((a: T) => S)): Set; /** * Call the given predicate on each item in the collection and for each item that it returns true, collect the item in a new Set. * * Unlike Iterator#filter, this returns a Set, not an Iterator. * @expose * @param {function(T):boolean} pred This function must not have any side-effects. * @return {Set.} */ filter(pred: ((a: T) => boolean)): Set; /** * Removes a value (if found) from the Set. * * Be careful not to call this method while iterating over the collection. * @param {T} val The value to remove. * @return {boolean} true if the value was found and removed, false otherwise. */ remove(val: T): boolean; /** * Removes a value (if found) from the Set. * * Be careful not to call this method while iterating over the collection. * @param {T} val The value to insert. * @return {boolean} true if the value was found and removed, false otherwise. */ delete(val: T): boolean; /** * Removes all of the values of a collection from this Set. * * Be careful not to call this method while iterating over the collection. * @param {Iterable.|Array.} coll the collection of items to remove. * @return {Set.} This modified Set. */ removeAll(coll: Iterable | Array): Set; /** * Removes from this Set all items that are not in the given collection. * * Be careful not to call this method while iterating over the collection. * @param {Iterable.} coll the collection of items that should be kept in this Set. * @return {Set.} This modified Set. */ retainAll(coll: Iterable): Set; /** * Clears the Set. * This sets the #count to zero. * * Be careful not to call this method while iterating over the collection. */ clear(): void; /** * Makes a shallow copy of this Set. * The values are not copied, * so if they are objects they may continue to be shared with the original Set. * @expose * @return {Set.} The new Set with the same elements. */ copy(): Set; /** * Produces a JavaScript Array from the contents of this Set. * @return {Array.} A copy of the Set in Array form. */ toArray(): Array; /** * Converts the Set to a List. * Because there is no ordering within a Set, * the values in the List may be in any order. * @return {List.} A copy of the contents of this Set in List form. */ toList(): List; /** * This read-only property is the number of elements in the Set. */ get count(): number; /** * This read-only property is the number of elements in the Set. */ get size(): number; /** * Gets an object that you can use for iterating over the Set. * The value will be a member of the Set. * Typical usage: * ```js * var it = aSet.iterator; * while (it.next()) { * . . . " value: " + it.value . . . * } * ``` */ get iterator(): Iterator; /** * (undocumented) * Set the unique hash ID for an object. * This should be called at the beginning of each constructor that does not inherit from another class. */ static uniqueHash(obj: ObjectData): void; /** * (undocumented) * Get the unique hash ID for an object, making it if necessary. */ static hashIdUnique(obj: ObjectData): number; /** * (undocumented) * Get the unique hash ID for an object; may return undefined. */ static hashId(obj: ObjectData): number | undefined; } /** * (undocumented) * @template K,V * @unrestricted */ export class KeyValuePair { /** * @param {K} k * @param {V} v */ constructor(k: K, v: V); /** * @return {string} */ toString(): string; /** * Gets a key for a value in a Map. * @return {K} the key uniquely identifying a #value in a Map. */ key: K; /** * Gets a value in a Map. * @return {V} a value in a Map corresponding to a #key. */ value: V; } /** * (undocumented) * Iterating over Maps is very similar to an Iterator>, * but not exactly, because the type of the value property is V, not KeyValuePair. */ export interface IMapIterator { /** @hidden */ iterator: IMapIterator; /** @hidden */ next(): boolean; /** @hidden */ hasNext(): boolean; /** @hidden */ first(): KeyValuePair | null; /** @hidden */ reset(): void; /** @hidden */ any(pred: (x: KeyValuePair) => boolean): boolean; /** @hidden */ all(pred: (x: KeyValuePair) => boolean): boolean; /** @hidden */ each(func: (x: KeyValuePair) => void): IMapIterator; /** @hidden */ map(func: (x: KeyValuePair) => S): Iterator; /** @hidden */ filter(pred: (x: KeyValuePair) => boolean): Iterator>; /** @hidden */ readonly key: K; /** @hidden */ readonly value: T; /** @hidden */ readonly count: number; } /** * NOTE: For 2.0 the #constructor arguments have changed. * Map now optionally accepts a collection, and only checks types in TypeScript. * * An unordered iterable collection of key/value pairs that cannot contain two instances of the same key. * In TypeScript it is a generic class that enforces at compile-time the type of the key and the type of the associated value. * * To create a Map: * ```js * var map = new go.Map(); // In TypeScript: new go.Map(); * map.add("one", 1); * map.add("two", 2); * map.add("three", 3); * // now map.count === 3 * // and map.getValue("two") === 2 * // and map.contains("zero") === false * ``` * * You can iterate over the key/value pairs in a Map: * ```js * var it = aMap.iterator; * while (it.next()) { * console.log(it.key + ": " + it.value); * } * ``` * Or: * ```js * aMap.each(kvp => { * console.log(kvp.key + ": " + kvp.value); * }); * ``` * But note that there is no guaranteed ordering amongst the key/value pairs. * * Call #toKeySet to get a read-only Set that holds all of the keys of a Map. * Iterating over that Set will produce values that are the keys in the Map. * * Although not precisely implementing the features and semantics of the EcmaScript 6 **Map** class, * this **GoJS** Map class has synonyms for the following methods and property: * - **get(key)**: #getValue, but returns null instead of undefined when key is not present * - **set(key,val)**: #add * - **has(key)**: #contains * - **delete(key)**: #remove * - **clear()**: #clear * - **size**: #count * * The constructor now takes an optional Iterable or Array argument that provides the initial entries for the new Map. * * Note that GoJS iteration is quite different than ES6 iteration, so that functionality has not been made somewhat compatible. * These collection classes were defined in GoJS before the ES6 collection classes were proposed. * @template K, V * @unrestricted * @category Collection */ export class Map { /** * There are two possible constructors: * * `new go.Map()`, for JavaScript * * `new go.Map()` for TypeScript * * In TypeScript, the two optional generic arguments describe the types of keys * and the types of values that this Map may hold. * * For example, the expression: * ```js * // TypeScript: * new go.Map() * ``` * produces a Map that has keys that must be strings and whose associated values * must be Points. * @param {Iterable.>|Array.>=} coll an optional collection of keys/values to add, or an Array of { key: ..., value: ... } objects. * Note that the key/value pairs are objects with "key" and "value" properties, not Arrays of length 2. */ constructor(coll?: Iterable> | Array> | Map); /** * @return {string} */ toString(): string; /** * Adds a key-value association to the Map, or replaces the value associated with the key * if the key was already present in the map. * * Be careful not to call this method while iterating over the collection. * @param {K} key The key or index for storing the value in the Map. * @param {V} val The value to add to the Map, associated with the key. * @return {Map.} This modified Map. */ add(key: K, val: V): Map; /** * Adds a key-value association to the Map, or replaces the value associated with the key * if the key was already present in the map. * * Be careful not to call this method while iterating over the collection. * @param {K} key The key or index for storing the value in the Map. * @param {V} val The value to add to the Map, associated with the key. * @return {Map.} This modified Map. */ set(key: K, val: V): Map; /** * Adds all of the key-value pairs of another Map to this Map. * If a key is already present in this Map, * its value is replaced with the corresponding value from the given map. * * Be careful not to call this method while iterating over the collection. * @param {Iterable.>|Array.>} coll the collection of keys/values to add, or an Array of { key: ..., value: ... } objects. * @return {Map.} This modified Map. */ addAll(coll: Iterable> | Array> | Map): Map; /** * Returns the first key/value pair in the collection, or null if there is none. * @return {KeyValuePair.} This returns null if there are no items in the collection. * @since 1.4 */ first(): KeyValuePair; /** * This is true if any invocation of the given predicate on items in the collection is true. * * Call the given predicate on each key/value pair in the collection. * As soon as a call returns true, this returns true. * Otherwise this returns false. * For an empty collection this returns false. * @expose * @param {function(KeyValuePair.):boolean} pred The argument to the predicate will be an object with both "key" and "value" properties. * This function must not have any side-effects. * @return {boolean} True if any predicate call is true; false otherwise. * @since 1.4 */ any(pred: ((a: KeyValuePair) => boolean)): boolean; /** * This is true if all invocations of the given predicate on items in the collection are true. * * Call the given predicate on each key/value pair in the collection. * As soon as a call returns false, this returns false. * Otherwise this returns true. * For an empty collection this returns true. * @expose * @param {function(KeyValuePair.):boolean} pred The argument to the predicate will be an object with both "key" and "value" properties. * This function must not have any side-effects. * @return {boolean} True if all predicate calls are true; false otherwise. * @since 1.4 */ all(pred: ((a: KeyValuePair) => boolean)): boolean; /** * Call the given function on each key/value pair in the collection. * @expose * @param {function(KeyValuePair.)} func The argument to the function will be an object with both "key" and "value" properties. * This function must not modify the collection. * @return {Map.} This Map itself * @since 1.4 */ each(func: ((a: KeyValuePair) => void)): Map; /** * Call the given function on each key-value pair in the collection and associate the key with the result of the function in a new Map. * * Unlike Iterator#map, this returns a Map, not an Iterator. * @expose * @param {function(KeyValuePair.):*} func The argument to the function will be an object with both "key" and "value" properties. * This function must not modify the collection. * @return {Map.} a new Map with the same keys but values produced by the function */ map(func: ((a: KeyValuePair) => S)): Map; /** * Call the given predicate on each key-value pair in the collection and for each pair that it returns true, add the key-value association in a new Map. * * Unlike Iterator#filter, this returns a Map, not an Iterator. * @expose * @param {function(KeyValuePair.):boolean} pred This function must not have any side-effects. * @return {Map.} */ filter(pred: ((a: KeyValuePair) => boolean)): Map; /** * Returns whether the given key is in this Map. * @param {K} key The key to look up in the Map. * @return {boolean} Whether or not the key is contained within the Map. */ contains(key: K): boolean; /** * Returns whether the given key is in this Map. * @param {K} key The key to look up in the Map. * @return {boolean} Whether or not the key is contained within the Map. */ has(key: K): boolean; /** * Returns the value associated with a key. * @param {K} key The key to look up in the Map. * @return {V|null} The value associated with the given key, or null if not present in the Map. */ getValue(key: K): V | null; /** * Returns the value associated with a key. * @param {K} key The key to look up in the Map. * @return {V|null} The value associated with the given key, or null if not present in the Map. */ get(key: K): V | null; /** * Removes a key (if found) from the Map. * * Be careful not to call this method while iterating over the collection. * @param {K} key The key to remove. * @return {boolean} true if the key was found and removed, false otherwise. */ remove(key: K): boolean; /** * Removes a key (if found) from the Map. * * Be careful not to call this method while iterating over the collection. * @param {K} key The key to insert. * @return {boolean} true if the key was found and removed, false otherwise. */ delete(key: K): boolean; /** * Clears the Map, removing all key-value associations. * This sets the #count to zero. * * Be careful not to call this method while iterating over the collection. */ clear(): void; /** * Makes a shallow copy of this Map. * The keys and their values are not copied, * so if they are objects they may continue to be shared with the original Map. * @expose * @return {Map.} The new Map with copies of the same entries. */ copy(): Map; /** * Produces a JavaScript Array of key/value pair objects from the contents of this Map. * @return {Array.>} A copy of the Map in Array form, * each element being an Object with 'key' and 'value' properties. */ toArray(): Array>; /** * Produces a Set that provides a read-only view onto the keys of this Map. * The collection of keys is not copied. * @return {Set.} */ toKeySet(): Set; /** * This read-only property is the number of associations in the Map. */ get count(): number; /** * This read-only property is the number of associations in the Map. */ get size(): number; /** * Gets an object that you can use for iterating over the key-value pairs of a Map. * Typical usage: * ```js * var it = aMap.iterator; * while (it.next()) { * console.log("the key: " + it.key + " has value: " + it.value); * } * ``` */ get iterator(): IMapIterator; /** * Gets an object that you can use for iterating over the keys of a Map. * Typical usage: * ```js * var it = aMap.iteratorKeys; * while (it.next()) { * console.log("key: " + it.value); * } * ``` * @since 1.4 */ get iteratorKeys(): Iterator; /** * Gets an object that you can use for iterating over the values of a Map. * Typical usage: * ```js * var it = aMap.iteratorValues; * while (it.next()) { * console.log("value: " + it.value); * } * ``` * @since 1.4 */ get iteratorValues(): Iterator; } /** * A Point represents an x- and y-coordinate pair in two-dimensional space. * * Use the static functions Point.parse and Point.stringify to convert to and from * a standard string representation that is independent of the current locale. * * When an instance of this class is the value of a property of a GraphObject class or Diagram * or CommandHandler or a Tool class, you should treat the object * as if it were frozen or read-only -- you cannot modify its properties. * This allows the property to return a value without allocating a new instance. * If you need to do your own calculations with the value, call #copy to make * a new instance with the same values that you can modify. * * Many methods modify the object's properties and then return a reference to "this" object. * The only instance method to allocate a new object is the #copy method. * The static Point.parse method also allocates a new object. * * The "Debug" implementation of this class is significantly slower than the "Release" implementation, * mostly due to additional error checking. * * You cannot inherit from this class. * @category Geometry */ export class Point { /** * The default constructor produces the Point(0,0). * This constructor may take either zero arguments or two arguments. * @param {number=} x The x value. * @param {number=} y The y value. */ constructor(x?: number, y?: number); /** * Modify this Point with new X and Y values. * @param {number} x * @param {number} y * @return {Point} this. */ setTo(x: number, y: number): Point; /** * Modify this Point so that its X and Y values are the same as the given Point. * @param {Point} p the given Point. * @return {Point} this. */ set(p: Point): Point; /** * Create a copy of this Point, with the same values. * @expose * @return {Point} */ copy(): Point; /** * This static function can be used to read in a Point from a string that was produced by Point.stringify. * * `go.Point.parse("1 2")` produces the Point `new go.Point(1, 2)`. * @param {string} str * @return {Point} */ static parse(str: string): Point; /** * This static function can be used to write out a Point as a string that can be read by Point.parse. * * `go.Point.stringify(new go.Point(1, 2))` produces the string "1 2". * @param {Point} val * @return {string} */ static stringify(val: Point): string; /** * Indicates whether the given Point is equal to this Point. * @param {Point} p The Point to compare to the current Point. * @return {boolean} True if the two Points have identical X and Y values, * false otherwise. * @see #equalTo */ equals(p: Point): boolean; /** * Indicates whether the given point (x, y) is equal to this Point. * @param {number} x * @param {number} y * @return {boolean} True if the two Points have identical X and Y values, * false otherwise. * @see #equals */ equalTo(x: number, y: number): boolean; /** * (undocumented) * True when the given Point is nearly equal to this Point. * @param {Point} p The Point to compare to the current Point. * @return {boolean} True if the two Points have X and Y values that * are equal with a tolerance of 0.5, false otherwise. */ equalsApprox(p: Point): boolean; /** * Modify this point so that is the sum of the current Point and the * x and y co-ordinates of the given Point. * @param {Point} p The Point to add to this Point. * @return {Point} this. * @see #offset * @see #subtract */ add(p: Point): Point; /** * Modify this point so that is the difference of this Point and the * x and y co-ordinates of the given Point. * @param {Point} p The Point to subtract from the current Point. * @return {Point} this. * @see #offset * @see #add */ subtract(p: Point): Point; /** * Modify this point by shifting its values with the given DX and DY offsets. * @param {number} dx * @param {number} dy * @return {Point} this. * @see #add * @see #subtract */ offset(dx: number, dy: number): Point; /** * Modify this Point so that has been rotated about the origin by the given angle. * @param {number} angle an angle in degrees. * @return {Point} this. */ rotate(angle: number): Point; /** * Modify this Point so that its X and Y values have been scaled by given factors along the X and Y axes. * @param {number} sx * @param {number} sy * @return {Point} this. */ scale(sx: number, sy: number): Point; /** * Returns the square of the distance from this Point to a given Point. * @param {Point} p the other Point to measure to. * @return {number} the square of the euclidean distance. * @see #distanceSquared */ distanceSquaredPoint(p: Point): number; /** * Returns the square of the distance from this point to a given point (px, py). * @param {number} px * @param {number} py * @return {number} the square of the euclidean distance. * @see #distanceSquaredPoint */ distanceSquared(px: number, py: number): number; /** * Modify this Point so that its X and Y values have been normalized to a unit length. * However, if this Point is the origin (zero, zero), its length remains zero. * @return {Point} this. */ normalize(): Point; /** * Compute the angle from this Point to a given Point. * However, if the given Point is the same as this Point, the direction is zero. * @param {Point} p the other Point to which to measure the relative angle. * @return {number} the angle, in degrees, of the line from this Point to the given point. * @see #direction */ directionPoint(p: Point): number; /** * Compute the angle from this Point to a given (px,py) point. * However, if the point is the same as this Point, the direction is zero. * @param {number} px * @param {number} py * @return {number} the angle, in degrees, of the line from this Point to the given point. * @see #directionPoint */ direction(px: number, py: number): number; /** * This static function compares a point with a finite line segment. * * If the point is on the finite line segment, this returns zero. * If the point is on the left side of the segment, this returns a positive number. * If the point is on the right side of the segment, this returns a negative number. * If the point is on the infinitely extended line but not within the segment, * then this returns a positive number if the point is beyond the end of the segment when going from A1 to A2, * or this returns a negative number if the point comes before the segment's start at A1. * @param {number} a1x * @param {number} a1y * @param {number} a2x * @param {number} a2y * @param {number} px * @param {number} py * @return {number} <0 if on the right side, or >0 if on the left side, or zero if exactly on the finite line segment * @since 2.2 */ static compareWithLineSegment(a1x: number, a1y: number, a2x: number, a2y: number, px: number, py: number): number; /** * Compare this point with a finite line segment given by two Points. * * This method compares this point with a finite line segment determined by the given two Points. * If the point is on the finite line segment, this returns zero. * If the point is on the left side of the segment, this returns a positive number. * If the point is on the right side of the segment, this returns a negative number. * If the point is on the infinitely extended line but not within the segment, * then this returns a positive number if the point is beyond the end of the segment when going from A1 to A2, * or this returns a negative number if the point comes before the segment's start at A1. * @param {Point} p the start of the finite line segment * @param {Point} q the end of the finite line segment * @return {number} <0 if this Point is on the right side of the line segment, or >0 if this Point is on the left side, or zero if exactly on the finite line segment * @since 2.2 */ compareWithLineSegmentPoint(p: Point, q: Point): number; /** * This static function is true if two finite straight line segments intersect each other. * @param {number} a1x * @param {number} a1y * @param {number} a2x * @param {number} a2y * @param {number} b1x * @param {number} b1y * @param {number} b2x * @param {number} b2y * @return {boolean} True if the two given finite line segments intersect with each other, false otherwise. * @since 2.2 */ static intersectingLineSegments(a1x: number, a1y: number, a2x: number, a2y: number, b1x: number, b1y: number, b2x: number, b2y: number): boolean; /** * Modify this point to be the closest point to this point that is on a finite line segment. * @param {number} px one end of the finite line segment * @param {number} py one end of the finite line segment * @param {number} qx the other end of the finite line segment * @param {number} qy the other end of the finite line segment * @return {Point} this modified Point * @since 1.3 */ projectOntoLineSegment(px: number, py: number, qx: number, qy: number): Point; /** * Modify this point to be the closest point to this point that is on a finite line segment. * @param {Point} p one end of the finite line segment * @param {Point} q the other end of the finite line segment * @return {Point} this modified Point * @since 1.3 */ projectOntoLineSegmentPoint(p: Point, q: Point): Point; /** * Modify this point to be at the nearest point on an infinite grid, * given the grid's origin and size of each grid cell. * @param {number} originx the top-left point of one of the grid cells * @param {number} originy the top-left point of one of the grid cells * @param {number} cellwidth the size of each grid cell -- must be a real number larger than zero * @param {number} cellheight the size of each grid cell -- must be a real number larger than zero * @return {Point} this modified Point * @since 1.3 */ snapToGrid(originx: number, originy: number, cellwidth: number, cellheight: number): Point; /** * Modify this point to be at the nearest point on an infinite grid, * given the grid's origin and size of each grid cell. * @param {Point} origin the top-left point of one of the grid cells * @param {Size} cellsize the size of each grid cell * @return {Point} this modified Point * @since 1.3 */ snapToGridPoint(origin: Point, cellsize: Size): Point; /** * Modify this Point so that its X and Y values correspond to a particular Spot * in a given Rect. * * The result is meaningless if Spot#isNoSpot is true for the given Spot. * @param {Rect} r the Rect for which we are finding the point. * @param {Spot} spot the Spot; Spot#isSpot must be true for this Spot. * @return {Point} this. * @see #setSpot */ setRectSpot(r: Rect, spot: Spot): Point; /** * Modify this Point so that its X and Y values correspond to a particular Spot * in a given rectangle. * * The result is meaningless if Spot#isNoSpot is true for the given Spot. * @param {number} x The X coordinate of the Rect for which we are finding the point. * @param {number} y The Y coordinate of the Rect for which we are finding the point. * @param {number} w The Width of the Rect for which we are finding the point. * @param {number} h The Height of the Rect for which we are finding the point. * @param {Spot} spot the Spot; Spot#isSpot must be true for this Spot. * @return {Point} this the point of the spot in the rectangle. * @see #setRectSpot */ setSpot(x: number, y: number, w: number, h: number, spot: Spot): Point; /** * This static function returns the square of the distance from the point P * to the finite line segment from point A to point B. * @param {number} px * @param {number} py * @param {number} ax * @param {number} ay * @param {number} bx * @param {number} by * @return {number} the euclidean distance. */ static distanceLineSegmentSquared(px: number, py: number, ax: number, ay: number, bx: number, by: number): number; /** * This static function returns the square of the distance from the point P to the point Q. * @param {number} px * @param {number} py * @param {number} qx * @param {number} qy * @return {number} */ static distanceSquared(px: number, py: number, qx: number, qy: number): number; /** * This static function returns the angle in degrees of the line from point P to point Q. * @param {number} px * @param {number} py * @param {number} qx * @param {number} qy * @return {number} */ static direction(px: number, py: number, qx: number, qy: number): number; /** * Gets or sets the x value of the Point. */ get x(): number; set x(value: number); /** * Gets or sets the y value of the Point. */ get y(): number; set y(value: number); /** * True if this Point has X and Y values that are real numbers and not infinity. * @return {boolean} */ isReal(): boolean; /** * @expose * @return {Point} */ static alloc(): Point; /** * @expose * @param {number} x * @param {number} y * @return {Point} */ static allocAt(x: number, y: number): Point; /** * @expose * @param {Point} temp */ static free(temp: Point): void; } /** * A Size describes a width and a height in two-dimensional coordinates. * The width and height must both be non-negative. * * Use the static functions Size.parse and Size.stringify to convert to and from * a standard string representation that is independent of the current locale. * * When an instance of this class is the value of a property of a GraphObject class or Diagram * or CommandHandler or a Tool class, you should treat the object * as if it were frozen or read-only -- you cannot modify its properties. * This allows the property to return a value without allocating a new instance. * If you need to do your own calculations with the value, call #copy to make * a new instance with the same values that you can modify. * * Many methods modify the object's properties and then return a reference to "this" object. * The only instance method to allocate a new object is the #copy method. * The static Size.parse method also allocates a new object. * * The "Debug" implementation of this class is significantly slower than the "Release" implementation, * mostly due to additional error checking. * * You cannot inherit from this class. * @category Geometry */ export class Size { /** * The default constructor produces the Size(0,0). * This constructor may take either zero arguments or two arguments. * @param {number=} w The initial width (must be non-negative). * @param {number=} h The initial height (must be non-negative). */ constructor(w?: number, h?: number); /** * Modify this Size with new Width and Height values. * @param {number} w the width. * @param {number} h the height. * @return {Size} this. */ setTo(w: number, h: number): Size; /** * Modify this Size so that its Width and Height values are the same as the given Size. * @param {Size} s the given Size. * @return {Size} this. */ set(s: Size): Size; /** * Create a copy of this Size, with the same values. * @expose * @return {Size} */ copy(): Size; /** * This static function can be used to read in a Size from a string that was produced by Size.stringify. * * `go.Size.parse("1 2")` produces the Size `new go.Size(1, 2)`. * @param {string} str * @return {Size} */ static parse(str: string): Size; /** * This static function can be used to write out a Size as a string that can be read by Size.parse. * * `go.Size.stringify(new go.Size(1, 2))` produces the string "1 2". * @param {Size} val * @return {string} */ static stringify(val: Size): string; /** * Indicates whether the given Size is equal to the current Size. * @param {Size} s The Size to compare to the current Size. * @return {boolean} True if the Sizes have the same width and height, * false otherwise. * @see #equalTo */ equals(s: Size): boolean; /** * Indicates whether the given size is equal to this Size. * @param {number} w the width. * @param {number} h the height. * @return {boolean} True if the Sizes have the same width and height, * false otherwise. * @see #equals */ equalTo(w: number, h: number): boolean; /** * (undocumented) * True when the given Size is nearly equal to this Size. * @param {Size} s The Size to compare to the current Size. * @return {boolean} True if the two Sizes have Width and Height values that * are equal with a tolerance of 0.5, false otherwise. */ equalsApprox(s: Size): boolean; /** * Modify this Size so that its width and height are changed by the given distances. * When the arguments are negative, this operation deflates this Size, but not beyond zero. * @param {number} w The additional width, which must be a real number; may be negative. * @param {number} h The additional height, which must be a real number; may be negative. * @return {Rect} this. */ inflate(w: number, h: number): Size; /** * Gets or sets the width value of the Size. * The value must not be negative. */ get width(): number; set width(value: number); /** * Gets or sets the height value of the Size. * The value must not be negative. */ get height(): number; set height(value: number); /** * True if this Size has Width and Height values that are real numbers and not infinity. * @return {boolean} */ isReal(): boolean; /** * @return {Size} */ static alloc(): Size; /** * @param {Size} temp */ static free(temp: Size): void; } /** * A Rect describes a rectangular two-dimensional area as a top-left point (x and y values) * and a size (width and height values). * * Use the static functions Rect.parse and Rect.stringify to convert to and from * a standard string representation that is independent of the current locale. * * When an instance of this class is the value of a property of a GraphObject class or Diagram * or CommandHandler or a Tool class, you should treat the object * as if it were frozen or read-only -- you cannot modify its properties. * This allows the property to return a value without allocating a new instance. * If you need to do your own calculations with the value, call #copy to make * a new instance with the same values that you can modify. * * Many methods modify the object's properties and then return a reference to "this" object. * The only instance method to allocate a new object is the #copy method. * The static Rect.parse method also allocates a new object. * The #center, #position, and #size properties all allocate and return a new object. * * The "Debug" implementation of this class is significantly slower than the "Release" implementation, * mostly due to additional error checking. * * You cannot inherit from this class. * @category Geometry */ export class Rect { /** * There are four constructors: (), (Point, Point), (Point, Size), * and four numbers for (x, y, width, height). * The default constructor (no argument) results in a Rect(0,0,0,0). * @param {Point|number=} x Top-left Point, or x value. * @param {Point|Size|number=} y Bottom-right Point or Size or y value. * @param {number=} w Width to be used if x,y are specified; * must be non-negative. * @param {number=} h Height to be used if x,y are specified; * must be non-negative. */ constructor(x?: Point | number, y?: Point | Size | number, w?: number, h?: number); /** * Modify this Rect with new X, Y, Width, and Height values. * @param {number} x * @param {number} y * @param {number} w the width. * @param {number} h the height. * @return {Rect} this. */ setTo(x: number, y: number, w: number, h: number): Rect; /** * Modify this Rect so that its X, Y, Width, and Height values are the same as the given Rect. * @param {Rect} r the given Rect. * @return {Rect} this. */ set(r: Rect): Rect; /** * Modify this Rect so that its X and Y values are the same as the given Point. * @param {Point} p the given Point. * @return {Rect} this. */ setPoint(p: Point): Rect; /** * Modify this Rect so that its Width and Height values are the same as the given Size. * @param {Size} s the given Size. * @return {Rect} this. */ setSize(s: Size): Rect; /** * Create a copy of this Rect, with the same values. * @expose * @return {Rect} */ copy(): Rect; /** * This static function can be used to read in a Rect from a string that was produced by Rect.stringify. * * `go.Rect.parse("1 2 3 4")` produces the Rect `new go.Rect(1, 2, 3, 4)`. * @param {string} str * @return {Rect} */ static parse(str: string): Rect; /** * This static function can be used to write out a Rect as a string that can be read by Rect.parse. * * `go.Rect.stringify(new go.Rect(1, 2, 3, 4))` produces the string "1 2 3 4". * @param {Rect} val * @return {string} */ static stringify(val: Rect): string; /** * Indicates whether the given Rect is equal to the current Rect. * @param {Rect} r The rectangle to compare to the current rectangle. * @return {boolean} True if the Rects are equivalent in x, y, width, * and height. * @see #equalTo */ equals(r: Rect): boolean; /** * Indicates whether the given Rect is equal to the current Rect. * @param {number} x * @param {number} y * @param {number} w the width. * @param {number} h the height. * @return {boolean} True if the Rects are equivalent in x, y, width, and height. * @see #equals */ equalTo(x: number, y: number, w: number, h: number): boolean; /** * (undocumented) * True when the given Rect is nearly equal to this Rect. * @param {Rect} r The Rect to compare to the current Rect. * @return {boolean} True if the two Rects have respective X, Y, Width, * and Height values within 0.5, false otherwise. */ equalsApprox(r: Rect): boolean; /** * Indicates whether this Rect contains the given Point. * @param {Point} p The Point to check. * @return {boolean} True if the Point is contained within this Rect, * false otherwise. * @see #containsRect * @see #contains */ containsPoint(p: Point): boolean; /** * Indicates whether this Rect contains the given Rect. * @param {Rect} r The Rect to check. * @return {boolean} True if the Rect is contained within this Rect, * false otherwise. * @see #containsPoint * @see #contains */ containsRect(r: Rect): boolean; /** * Indicates whether this Rect contains the given Point/Rect. * @param {number} x The X coordinate of the Point or Rect to include in the new bounds. * @param {number} y The Y coordinate of the Point or Rect to include in the new bounds. * @param {number=} w The Width of the Rect to include in the new bounds, defaults to zero. * @param {number=} h The Height of the Rect to include in the new bounds, defaults to zero. * @return {boolean} True if the Point/Rect is contained within this Rect, * false otherwise. * @see #containsRect * @see #containsPoint */ contains(x: number, y: number, w?: number, h?: number): boolean; /** * Modify this Rect by shifting its values with the given DX and DY offsets. * @param {number} dx * @param {number} dy * @return {Rect} this. */ offset(dx: number, dy: number): Rect; /** * Modify this Rect so that its width and height are changed on all four sides, * equally on the left and right sides, and equally on the top and bottom sides. * When the arguments are negative, this operation deflates this Rect, but not beyond zero. * @param {number} w The additional width on each side, left and right; may be negative. * @param {number} h The additional height on each side, top and bottom; may be negative. * @return {Rect} this. * @since 2.3 * @see #grow * @see #addMargin * @see #subtractMargin */ inflate(w: number, h: number): Rect; /** * Modify this Rect by adding the given Margin to each side of the Rect. * @param {Margin} m The Margin to add to the Rect. * @return {Rect} this bigger Rect. * @see #subtractMargin * @see #grow * @see #inflate */ addMargin(m: Margin): Rect; /** * Modify this Rect by subtracting the given Margin from each side of the Rect. * @param {Margin} m The Margin to subtract from the Rect. * @return {Rect} this smaller Rect. * @see #addMargin * @see #grow * @see #inflate */ subtractMargin(m: Margin): Rect; /** * Modifies this Rect by adding some distance to each side of the Rect. * @param {number} t the amount to move the top side upwards; may be negative. * @param {number} r the amount to move the right side rightwards; may be negative. * @param {number} b the amount to move the bottom side downwards; may be negative. * @param {number} l the amount to move the left side leftwards; may be negative. * @return {Rect} this modified Rect. * @see #inflate * @see #addMargin * @see #subtractMargin */ grow(t: number, r: number, b: number, l: number): Rect; /** * Modify this Rect so that it is the intersection of this Rect and the given Rect. * @param {Rect} r Rect to intersect with. * @return {Rect} this. * @see #intersect * @see #intersects */ intersectRect(r: Rect): Rect; /** * Modify this Rect so that it is the intersection of this Rect and the rectangle * defined by x, y, w, h. * @param {number} x * @param {number} y * @param {number} w * @param {number} h * @return {Rect} this. * @see #intersectRect * @see #intersects */ intersect(x: number, y: number, w: number, h: number): Rect; /** * Determine if a given Rect is partly or wholly inside of this Rect. * @param {Rect} r Rect to test intersection with. * @return {boolean} true if there is an intersection. * @see #intersects * @see #intersectRect */ intersectsRect(r: Rect): boolean; /** * Determine if this Rect partly or wholly overlaps the rectangle * defined by x, y, w, h. * @param {number} x * @param {number} y * @param {number} w * @param {number} h * @return {boolean} true if there is any overlap. * @see #intersectsRect * @see #intersect */ intersects(x: number, y: number, w: number, h: number): boolean; /** * Modify this Rect to be exactly big enough to contain both the original Rect and the given Point. * @param {Point} p The Point to include in the new bounds. * @return {Rect} this. * @see #unionRect * @see #union */ unionPoint(p: Point): Rect; /** * Modify this Rect to be exactly big enough to contain this Rect and the given Rect. * @param {Rect} r The Rect to include in the new bounds. * @return {Rect} this. * @see #unionPoint * @see #union */ unionRect(r: Rect): Rect; /** * Modify this Rect to be exactly big enough to contain both the original Rect and the given rectangular area. * @param {number} x The X coordinate of the Point or Rect to include in the new bounds. * @param {number} y The Y coordinate of the Point or Rect to include in the new bounds. * @param {number=} w The Width of the Rect to include in the new bounds, defaults to zero. * @param {number=} h The Height of the Rect to include in the new bounds, defaults to zero. * @return {Rect} this. * @see #unionRect * @see #unionPoint */ union(x: number, y: number, w?: number, h?: number): Rect; /** * Modify this Rect so that a given Spot is at a given (x,y) point using this Rect's size. * Return this rectangle for which the spot is at that point, without modifying the size. * * The result is meaningless if Spot#isNoSpot is true. * @param {number} x the point where the spot should be. * @param {number} y the point where the spot should be. * @param {Spot} spot a Spot; Spot#isSpot must be true. * @return {Rect} this. */ setSpot(x: number, y: number, spot: Spot): Rect; /** * This static function indicates whether a Rect contains the given Point/Rect. * @param {number} rx The X coordinate of a Rect. * @param {number} ry The Y coordinate of a Rect. * @param {number} rw The Width of a Rect. * @param {number} rh The Height of a Rect. * @param {number} x The X coordinate of the Point or Rect that might be in the bounds (RX, RY, RW, RH). * @param {number} y The Y coordinate of the Point or Rect that might be in the bounds (RX, RY, RW, RH). * @param {number=} w The Width of the Rect to include in the new bounds, defaults to zero. * @param {number=} h The Height of the Rect to include in the new bounds, defaults to zero. * @return {boolean} True if the Point/Rect is contained within this Rect, * false otherwise. */ static contains(rx: number, ry: number, rw: number, rh: number, x: number, y: number, w?: number, h?: number): boolean; /** * This static function indicates whether a Rect partly or wholly overlaps the given Rect. * @param {number} rx The X coordinate of a Rect. * @param {number} ry The Y coordinate of a Rect. * @param {number} rw The Width of a Rect. * @param {number} rh The Height of a Rect. * @param {number} x The X coordinate of the Point or Rect that might overlap the bounds (RX, RY, RW, RH). * @param {number} y The Y coordinate of the Point or Rect that might overlap the bounds (RX, RY, RW, RH). * @param {number} w * @param {number} h * @return {boolean} true if there is any overlap. */ static intersects(rx: number, ry: number, rw: number, rh: number, x: number, y: number, w: number, h: number): boolean; /** * This static function is true if a rectangular area is intersected by a finite straight line segment. * @param {number} x The X coordinate of the rectangle to check for intersection with the line segment. * @param {number} y The Y coordinate of the rectangle to check for intersection with the line segment. * @param {number} w The Width of the rectangle to check for intersection with the line segment. * @param {number} h The Height of the rectangle to check for intersection with the line segment. * @param {number} p1x The X coordinate of one end of the line segment. * @param {number} p1y The Y coordinate of one end of the line segment. * @param {number} p2x The X coordinate of other end of the line segment. * @param {number} p2y The Y coordinate of other end of the line segment. * @return {boolean} True if the given finite line segment intersects with the given rectangular area, false otherwise. * @since 2.2 */ static intersectsLineSegment(x: number, y: number, w: number, h: number, p1x: number, p1y: number, p2x: number, p2y: number): boolean; /** * Gets or sets the top-left x coordinate of the Rect. */ get x(): number; set x(value: number); /** * Gets or sets the top-left y coordinate of the Rect. */ get y(): number; set y(value: number); /** * Gets or sets the width of the Rect. * The value must not be negative. */ get width(): number; set width(value: number); /** * Gets or sets the height of the Rect. * The value must not be negative. */ get height(): number; set height(value: number); /** * Gets or sets the leftmost value of the Rect. * This is the same as the X value. */ get left(): number; set left(value: number); /** * Gets or sets the topmost value of the Rect. * This is the same as the Y value. */ get top(): number; set top(value: number); /** * Gets or sets the x-axis value of the right of the Rect. * This is equal to the sum of the x value and the width. */ get right(): number; set right(value: number); /** * Gets or sets the y-axis value of the bottom of the Rect. * This is equal to the sum of the y value and the height. */ get bottom(): number; set bottom(value: number); /** * Gets or sets the x- and y-axis position of the Rect as a Point. */ get position(): Point; set position(value: Point); /** * Gets or sets the width and height of the Rect as a Size. */ get size(): Size; set size(value: Size); /** * Gets or sets the Point at the center of this Rect. * Setting this property just shifts the X and Y values. */ get center(): Point; set center(value: Point); /** * Gets or sets the horizontal center X coordinate of the Rect. */ get centerX(): number; set centerX(value: number); /** * Gets or sets the vertical center Y coordinate of the Rect. */ get centerY(): number; set centerY(value: number); /** * True if this Rect has X, Y, Width, and Height values that are real numbers and not infinity. * @return {boolean} */ isReal(): boolean; /** * True if this Rect has a Width and Height of zero. * @return {boolean} */ isEmpty(): boolean; /** * @return {Rect} */ static alloc(): Rect; /** * @param {number} x * @param {number} y * @param {number} w * @param {number} h * @return {Rect} */ static allocAt(x: number, y: number, w: number, h: number): Rect; /** * @param {Rect} temp */ static free(temp: Rect): void; } /** * The MarginLike type is the same as `Margin | number`. * A number in place of a Margin object is treated as a uniform Margin with that thickness. * @category Type */ export type MarginLike = Margin | number; /** * A Margin represents a band of space outside or inside a rectangular area, * with possibly different values on each of the four sides. * * Example uses include GraphObject#margin, Panel#padding, and Diagram#padding. * * Use the static functions Margin.parse and Margin.stringify to convert to and from * a standard string representation that is independent of the current locale. * * When an instance of this class is the value of a property of a GraphObject class or Diagram * or CommandHandler or a Tool class, you should treat the object * as if it were frozen or read-only -- you cannot modify its properties. * This allows the property to return a value without allocating a new instance. * If you need to do your own calculations with the value, call #copy to make * a new instance with the same values that you can modify. * * Many methods modify the object's properties and then return a reference to "this" object. * The only instance method to allocate a new object is the #copy method. * The static Margin.parse method also allocates a new object. * * The "Debug" implementation of this class is significantly slower than the "Release" implementation, * mostly due to additional error checking. * * You cannot inherit from this class. * @category Geometry */ export class Margin { /** * If zero arguments are supplied, zero is used for all four sides. * If one argument is supplied, that number is used for all four sides. * If two arguments are supplied, the top and bottom sides get the first value, * and the left and right sides get the second value. * Otherwise there must be four arguments, in the order: top, right, bottom, left. * @param {number=} t the margin for the top side; * if not supplied, all sides are zero. * @param {number=} r the margin for the right side; * if not supplied, all sides have the value of the first argument. * @param {number=} b the margin for all bottom side; * if not supplied, the top and bottom get the value of the first argument, * and the right and left sides get the value of the second argument. * @param {number=} l the margin for the left side; * must be supplied if the third argument was supplied. */ constructor(t?: number, r?: number, b?: number, l?: number); /** * Modify this Margin with new Top, Right, Bottom, and Left values. * @param {number} t top. * @param {number} r right. * @param {number} b bottom. * @param {number} l left. * @return {Margin} this. */ setTo(t: number, r: number, b: number, l: number): Margin; /** * Modify this Margin so that its Top, Right, Bottom, and Left values * are the same as the given Margin. * @param {Margin} m the given Margin. * @return {Margin} this. */ set(m: Margin): Margin; /** * Create a copy of this Margin, with the same values. * @expose * @return {Margin} */ copy(): Margin; /** * This static function can be used to read in a Margin from a string that was produced by Margin.stringify. * * `go.Margin.parse("1 2 3 4")` produces the Margin `new go.Margin(1, 2, 3, 4)`. * @param {string} str * @return {Margin} */ static parse(str: string): Margin; /** * This static function can be used to write out a Margin as a string that can be read by Margin.parse. * * `go.Margin.stringify(new go.Margin(1, 2, 3, 4))` produces the string "1 2 3 4". * @param {Margin} val * @return {string} */ static stringify(val: Margin): string; /** * Indicates whether the given Margin is equal to this Margin. * @param {Margin} m The Margin to compare to this Margin. * @return {boolean} True if the two Margins have identical Top and Right and Bottom and Left values, * false otherwise. * @see #equalTo */ equals(m: Margin): boolean; /** * Indicates whether the given margin is equal to this Margin. * @param {number} t top. * @param {number} r right. * @param {number} b bottom. * @param {number} l left. * @return {boolean} True if the two Margins have identical Top and Right and Bottom and Left values, * false otherwise. * @see #equals */ equalTo(t: number, r: number, b: number, l: number): boolean; /** * (undocumented) * True when the given Margin is nearly equal to this Margin. * @param {Margin} m The Margin to compare to the current Margin. * @return {boolean} True if the two Margins have Top, Right, * Bottom and Left values within 0.5, false otherwise. */ equalsApprox(m: Margin): boolean; /** * Gets or sets the top value of this margin. Default is 0. */ get top(): number; set top(value: number); /** * Gets or sets the right value of this margin. Default is 0. */ get right(): number; set right(value: number); /** * Gets or sets the bottom value of this margin. Default is 0. */ get bottom(): number; set bottom(value: number); /** * Gets or sets the left value of this margin. Default is 0. */ get left(): number; set left(value: number); /** * True if this Margin has values that are real numbers and not infinity. * @return {boolean} */ isReal(): boolean; /** * @return {Margin} */ static alloc(): Margin; /** * @param {Margin} temp */ static free(temp: Margin): void; } /** * A Spot represents a relative point from (0,0) to (1,1) within the bounds of * a rectangular area plus an absolute offset. * * Use the static functions Spot.parse and Spot.stringify to convert to and from * a standard string representation that is independent of the current locale. * * When an instance of this class is the value of a property of a GraphObject class or Diagram * or CommandHandler or a Tool class, you should treat the object * as if it were frozen or read-only -- you cannot modify its properties. * This allows the property to return a value without allocating a new instance. * If you need to do your own calculations with the value, call #copy to make * a new instance with the same values that you can modify. * * Many methods modify the object's properties and then return a reference to "this" object. * The only instance method to allocate a new object is the #copy method. * The static Spot.parse method also allocates a new object. * * The "Debug" implementation of this class is significantly slower than the "Release" implementation, * mostly due to additional error checking. * * You cannot inherit from this class. * @category Geometry */ export class Spot { /** * The default constructor produces the Spot(0, 0, 0, 0), at the top-left corner. * @param {number=} x The x value of the Spot. Default is zero. * @param {number=} y The y value of the Spot. Default is zero. * @param {number=} offx (Optional) The absolute x offset. Default is zero. * @param {number=} offy (Optional) The absolute y offset. Default is zero. */ constructor(x?: number, y?: number, offx?: number, offy?: number); /** * Modify this Spot with new X, Y, OffsetX, and OffsetY values. * @param {number} x * @param {number} y * @param {number} offx * @param {number} offy * @return {Spot} this. */ setTo(x: number, y: number, offx: number, offy: number): Spot; /** * Modify this Spot so that its X, Y, OffsetX, and OffsetY values are the same as the given Spot. * @param {Spot} s the given Spot. * @return {Spot} this. */ set(s: Spot): Spot; /** * Create a copy of this Spot, with the same values. * @expose * @return {Spot} */ copy(): Spot; /** * This static function can be used to read in a Spot from a string that was produced by Spot.stringify. * * `go.Spot.parse("0 1 2 3")` produces the Spot `new go.Spot(0, 1, 2, 3)`. * @param {string} str * @return {Spot} */ static parse(str: string): Spot; /** * This static function can be used to write out a Spot as a string that can be read by Spot.parse. * * `go.Spot.stringify(new go.Spot(0, 1, 2, 3))` produces the string "0 1 2 3". * @param {Spot} val * @return {string} */ static stringify(val: Spot): string; /** * Two spots are equal if all four property values are the same. * @param {Spot} spot The Spot to compare to the current Spot. * @return {boolean} True if the two spots are equal, false otherwise. */ equals(spot: Spot): boolean; /** * Return a new spot that is opposite this spot. * The X and Y values will be an equal distance * away from the center on the other side of the center. * The OffsetX and OffsetY values are also negated. * * The result is meaningless if #isNoSpot is true. * @return {Spot} */ opposite(): Spot; /** * This predicate is true if this Spot is a side that * includes the side(s) given by the argument Spot. * @param {Spot} side * @return {boolean} false if either this Spot or the argument Spot is not a "Side"; * true if the side(s) that this Spot represents are a superset or the same set of * sides represented by the argument Spot. */ includesSide(side: Spot): boolean; /** * Gets or sets the x value of the Spot, a fractional value between zero and one. * * The Spot(0,0) of a rectangle is at the top-left corner. * This value is commonly available as Spot.TopLeft. * The Spot(0.5,1) would be at the middle of the bottom side. * That value is commonly available as Spot.MiddleBottom. */ get x(): number; set x(value: number); /** * Gets or sets the y value of the Spot, a fractional value between zero and one. * * The Spot(0,1) of a rectangle is at the bottom-left corner. * This value is commonly available as Spot.BottomLeft. * The Spot(1,0.5) would be at the middle of the right side. * That value is commonly available as Spot.MiddleRight. */ get y(): number; set y(value: number); /** * Gets or sets the offsetX value of the Spot. * The value may be negative. * If this represents a side value instead of a specific spot, this value is meaningless. * * A Spot(0,0,5,5) of a large rectangle is near the top-left corner, inside the rectangle. * A Spot(1,1,5,5) would be near the bottom-right corner, outside the rectangle. * A Spot(1,1,-5,-5) would also be near the bottom-right corner, but inside the rectangle. */ get offsetX(): number; set offsetX(value: number); /** * Gets or sets the offsetY value of the Spot. * The value may be negative. * If this represents a side value instead of a specific spot, this value is meaningless. * * A Spot(0,0,5,5) of a large rectangle is near the top-left corner, inside the rectangle. * A Spot(1,1,5,5) would be near the bottom-right corner, outside the rectangle. * A Spot(1,1,-5,-5) would also be near the bottom-right corner, but inside the rectangle. */ get offsetY(): number; set offsetY(value: number); /** * True if this is a specific spot, not a side nor Spot.None. * @return {boolean} */ isSpot(): boolean; /** * True if this is an unspecific special spot, such as Spot.None * or one of the sides. * @return {boolean} */ isNoSpot(): boolean; /** * True if this is a special spot referring to one (or more) of the sides. * This is false if the spot is Spot.None. * @return {boolean} */ isSide(): boolean; /** * True if this is a special spot referring to no particular spot or side. * @return {boolean} */ isNone(): boolean; /** * True if this is a special spot indicating that the real spot value will come from another source. * @return {boolean} */ isDefault(): boolean; /** * Use this Spot value to indicate no particular spot -- * code looking for a particular point on an element will need to do their * own calculations to determine the desired point depending on the * circumstances. * @constant */ static None: Spot; /** * Use this value to indicate that the real spot value is inherited from elsewhere. * @constant */ static Default: Spot; /** * The specific point at the top-left corner of the bounding rectangle. * @constant */ static TopLeft: Spot; /** * The specific point at the center of the top side of the bounding rectangle. * @constant */ static TopCenter: Spot; /** * The specific point at the top-right corner of the bounding rectangle. * @constant */ static TopRight: Spot; /** * The specific point at the middle of the left side of bounding rectangle. * @constant */ static LeftCenter: Spot; /** * The specific point at the very center of the bounding rectangle. * @constant */ static Center: Spot; /** * The specific point at the middle of the right side of bounding rectangle. * @constant */ static RightCenter: Spot; /** * The specific point at the bottom-left corner of the bounding rectangle. * @constant */ static BottomLeft: Spot; /** * The specific point at the middle of the bottom side of bounding rectangle. * @constant */ static BottomCenter: Spot; /** * The specific point at the bottom-right corner of the bounding rectangle. * @constant */ static BottomRight: Spot; /** * A synonym for Spot.TopCenter. * @constant */ static MiddleTop: Spot; /** * A synonym for Spot.LeftCenter. * @constant */ static MiddleLeft: Spot; /** * A synonym for Spot.RightCenter. * @constant */ static MiddleRight: Spot; /** * A synonym for Spot.BottomCenter. * @constant */ static MiddleBottom: Spot; /** * A synonym for Spot.TopCenter. * @constant */ static Top: Spot; /** * A synonym for Spot.LeftCenter. * @constant */ static Left: Spot; /** * A synonym for Spot.RightCenter. * @constant */ static Right: Spot; /** * A synonym for Spot.BottomCenter. * @constant */ static Bottom: Spot; /** * The set of points at the top side of the bounding rectangle. * @constant */ static TopSide: Spot; /** * The set of points at the left side of the bounding rectangle. * @constant */ static LeftSide: Spot; /** * The set of points at the right side of the bounding rectangle. * @constant */ static RightSide: Spot; /** * The set of points at the bottom side of the bounding rectangle. * @constant */ static BottomSide: Spot; /** * The set of points at the top or bottom sides of the bounding rectangle. * @constant */ static TopBottomSides: Spot; /** * The set of points at the left or right sides of the bounding rectangle. * @constant */ static LeftRightSides: Spot; /** * The set of points at the top or left sides of the bounding rectangle. * @constant */ static TopLeftSides: Spot; /** * The set of points at the top or right sides of the bounding rectangle. * @constant */ static TopRightSides: Spot; /** * The set of points at the left or bottom sides of the bounding rectangle. * @constant */ static BottomLeftSides: Spot; /** * The set of points at the right or bottom sides of the bounding rectangle. * @constant */ static BottomRightSides: Spot; /** * The set of points on all sides of the bounding rectangle except top side. * @constant */ static NotTopSide: Spot; /** * The set of points on all sides of the bounding rectangle except left side. * @constant */ static NotLeftSide: Spot; /** * The set of points on all sides of the bounding rectangle except right side. * @constant */ static NotRightSide: Spot; /** * The set of points on all sides of bounding rectangle except bottom side. * @constant */ static NotBottomSide: Spot; /** * The set of points on all sides of the bounding rectangle. * @constant */ static AllSides: Spot; /** * @return {Spot} */ static alloc(): Spot; /** * @param {Spot} temp */ static free(temp: Spot): void; } /** * The Geometry class is used to define the "shape" of a Shape. * A Geometry can be simple straight lines, rectangles, or ellipses. * A Geometry can also be an arbitrarily complex path, consisting of a list of PathFigures. * * A Geometry must not be modified once it has been used by a Shape. * However, a Geometry may be shared by multiple Shapes. * * It is commonplace to create Geometries using geometry path string syntax: * Geometry Path Strings. * However it is much more efficient to create Geometries programmatically. * One way to do that is illustrated by several of the samples that evaluate JavaScript such as: * ```js * new go.Geometry() * .add(new go.PathFigure(p.x, p.y) * .add(new go.PathSegment(go.PathSegment.Arc, -sweep/2, sweep, 0, 0, radius+layerThickness, radius+layerThickness)) * .add(new go.PathSegment(go.PathSegment.Line, q.x, q.y)) * .add(new go.PathSegment(go.PathSegment.Arc, sweep/2, -sweep, 0, 0, radius, radius).close())); * ``` * See samples that make use of Geometries in the samples index. * @unrestricted * @category Geometry */ export class Geometry { /** * @param {?=} type * Construct an empty Geometry. * The geometry type must be one of the following values: * Geometry.Line, Geometry.Ellipse, Geometry.Rectangle, Geometry.Path. * The default type is Geometry.Path. */ constructor(type?: EnumValue); /** * Create a copy of this Geometry, with the same values and figures. * @expose * @return {Geometry} */ copy(): Geometry; /** * For drawing a simple straight line; * a value for Geometry#type. * The line goes from the point * (#startX, #startY) to the point (#endX, #endY). * @constant */ static Line: EnumValue; /** * For drawing a rectangle; * a value for Geometry#type. * The rectangle goes from the point * (#startX, #startY) to the point (#endX, #endY). * @constant */ static Rectangle: EnumValue; /** * For drawing an ellipse fitting within a rectangle; * a value for Geometry#type. * The ellipse fits within the rectangle that goes from the point * (#startX, #startY) to the point (#endX, #endY). * @constant */ static Ellipse: EnumValue; /** * For drawing a complex path made of a list of PathFigures; * a value for Geometry#type. * @constant */ static Path: EnumValue; /** * (undocumented) * @param {Geometry} g * @return {boolean} */ equalsApprox(g: Geometry): boolean; /** * This static function can be used to write out a Geometry as a string * that can be read by Geometry.parse. * * The string produced by this method is a superset of the SVG path * string rules that contains some additional GoJS-specific tokens. * See the Introduction page on Geometry Parsing for more details. * @param {Geometry} val * @return {string} * @since 1.1 */ static stringify(val: Geometry): string; /** * Given a SVG or GoJS path string, returns a congruent path string with each pathfigure filled. * For instance, "M0 0 L22 22 L33 0" would become "F M0 0 L22 22 L33 0". * @param {string} str * @return {string} * @since 1.1 */ static fillPath(str: string): string; /** * Produce a Geometry from a string that uses an SVG-like compact path geometry syntax. * The syntax accepts all SVG Path Syntax (SVG Path Syntax (w3.org)), * as well as three GoJS-specific tokens. * Specifically, the following tokens are allowed: * - `M (x,y)+ ` - Move commands * - `L (x,y)+, H (x)+, V (y)+` Lines commands, including horizontal and vertical lines * - `C (x1 y1 x2 y2 x y)+, S (x2 y2 x y)+` Cubic bezier curves * - `Q (x1 y1 x y)+, T (x y)+` Quadratic bezier curves * - `A (rx ry x-axis-rotation large-arc-flag clockwise-flag x y)+` Arcs (following SVG arc conventions) * - `Z` Denotes that the previous subpath is closed * * Additionally there are some tokens specific to GoJS: * - `B (startAngle, sweepAngle, centerX, centerY, radius)+` Arcs following GoJS canvas arc conventions * - `X` Used before M-commands to denote separate PathFigures instead of a subpath * - `F` Denotes whether the current PathFigure is filled (true if F is present) * - `F0` (instead of `F`) Denotes that the PathFigure should use the even-odd fill rule instead of the nonzero winding number rule (setting PathFigure#isEvenOdd) * - `U` Denotes that the PathFigure is not shadowed * * See the Introduction page on Geometry Parsing for more details. * @param {string} str * @param {boolean=} filled whether figures should be filled. * If true, all PathFigures in the string will be filled regardless of the presence * of an "F" command or not. * If false, all PathFigures will determine their own filled state by the presence of an "F" command or not. * Default is false. * @return {Geometry} */ static parse(str: string, filled?: boolean): Geometry; /** * Computes the Geometry's bounds without adding an origin point, and returns those bounds as a rect. * This method does not modify the Geometry or its bounds. * @return {Rect} * @since 1.1 */ computeBoundsWithoutOrigin(): Rect; /** * Normalizes the Geometry points in place by ensuring the top-left bounds of the geometry lines up with (0, 0), * returning the Point (x, y) amount it was shifted. * After this method is called there will be no negative X or Y value for the Geometry's bounds, * and no empty space at the top-left of the Geometry. * @return {Point} * @since 1.1 */ normalize(): Point; /** * Offsets the Geometry in place by a given (x, y) amount * @param {number} x The x-axis offset factor. * @param {number} y The y-axis offset factor. * @return {Geometry} this * @since 1.1 */ offset(x: number, y: number): Geometry; /** * Scales the Geometry in place by a given (x, y) scale factor. * * If you want to flip a Geometry horizontally, call `geo.scale(-1, 1)`. * If you want to flip a Geometry vertically, call `geo.scale(1, -1)`. * @param {number} x The x-axis scale factor. * @param {number} y The y-axis scale factor. * @return {Geometry} this * @since 1.1 */ scale(x: number, y: number): Geometry; /** * Rotates the Geometry in place by a given angle, with optional x and y values to rotate the geometry about. * If no x and y value are given, (0, 0) is used as the rotation point. * @param {number} angle The angle to rotate by. * @param {number=} x The optional X point to rotate the geometry about. If no point is given, this value is 0. * @param {number=} y The optional Y point to rotate the geometry about. If no point is given, this value is 0. * @return {Geometry} this * @since 1.1 */ rotate(angle: number, x?: number, y?: number): Geometry; /** * Returns true if the Geometry contains the point. * @param {Point} p in local geometry coordinates * @param {number=} sw half the stroke width that a Shape has or that you want to pretend it has * @return {boolean} * @since 2.2 */ containsPoint(p: Point, sw?: number): boolean; /** * Returns the point at the fractional distance (0-1) along this Geometry's path. * @param {number} fraction A fractional amount between 0 and 1, inclusive. * @param {Point=} result an optional Point that is modified and returned; otherwise it allocates and returns a new Point. * @return {Point} the Point, in local coordinates, of the fractional distance along the path. * @since 2.1 */ getPointAlongPath(fraction: number, result?: Point): Point; /** * Returns the slope expressed as an angle at the fractional distance (0-1) along this Geometry's path, in local coordinates. * @param {number} fraction A fractional amount between 0 and 1, inclusive. * @return {number} * @since 2.1 */ getAngleAlongPath(fraction: number): number; /** * Returns the fractional distance (0-1) along this Geometry's path for a nearby point. * @param {Point} pt A Point, in local coordinates, near this Geometry. * @return {number} A fractional amount between 0 and 1, inclusive. * @since 2.1 */ getFractionForPoint(pt: Point): number; /** * (undocumented) * Flattened segments represents a series of points making up a Geometry. * The inner arrays consist of a sequence of PathSegment coordinates making up a PathFigure, * while the outer array represents the whole Geometry of these PathFigures. */ get flattenedSegments(): Array>; /** * (undocumented) * Flattened lengths represents a series of lengths of the paths making up a Geometry. * The inner arrays consist of a sequence of PathSegment lengths making up a PathFigure, * while the outer array represents the whole Geometry of these PathFigures. */ get flattenedLengths(): Array>; /** * (undocumented) * This read-only property returns the approximate length of the path. * This is the overall distance of all the PathSegments that make up the geometry. */ get flattenedTotalLength(): number; /** * Gets or sets the type of the Geometry. * The default type is Geometry.Path. * Other permissible values are Geometry.Line, Geometry.Ellipse, * or Geometry.Rectangle. */ get type(): EnumValue; set type(value: EnumValue); /** * Gets or sets the starting X coordinate of the Geometry if it is of type * Geometry.Line|Line, Geometry.Rectangle|Rectangle, or Geometry.Ellipse|Ellipse. * The initial value is zero. */ get startX(): number; set startX(value: number); /** * Gets or sets the starting Y coordinate of the Geometry if it is of type * Geometry.Line|Line, Geometry.Rectangle|Rectangle, or Geometry.Ellipse|Ellipse. * The initial value is zero. */ get startY(): number; set startY(value: number); /** * Gets or sets the ending X coordinate of the Geometry if it is of type * Geometry.Line|Line, Geometry.Rectangle|Rectangle, or Geometry.Ellipse|Ellipse. * The initial value is zero. */ get endX(): number; set endX(value: number); /** * Gets or sets the ending Y coordinate of the Geometry if it is of type * Geometry.Line|Line, Geometry.Rectangle|Rectangle, or Geometry.Ellipse|Ellipse. * The initial value is zero. */ get endY(): number; set endY(value: number); /** * Gets or sets the List of PathFigures * that describes the content of the * path for Geometries of type Geometry.Path|Path. */ get figures(): List; set figures(value: List); /** * Add a PathFigure to the #figures list. * @param {PathFigure} figure a newly allocated unshared PathFigure that will become owned by this Geometry * @return {Geometry} this * @since 1.5 */ add(figure: PathFigure): Geometry; /** * (undocumented) * Set #spot1 and #spot2 without allocating new Spots. * @param {number} f1x spot1.x * @param {number} f1y spot1.y * @param {number} f2x spot2.x * @param {number} f2y spot2.y * @param {number=} o1x offset1.x, default is zero * @param {number=} o1y offset1.y, default is zero * @param {number=} o2x offset2.x, default is zero * @param {number=} o2y offset2.y, default is zero * @return {Geometry} this */ setSpots(f1x: number, f1y: number, f2x: number, f2y: number, o1x?: number, o1y?: number, o2x?: number, o2y?: number): Geometry; /** * Gets or sets the spot an "Auto" Panel will use for the top-left corner of any panel content * when the Shape#spot1 value is Spot.Default. * The default value is Spot.TopLeft, at the top-left point of the bounds of the Shape. */ get spot1(): Spot; set spot1(value: Spot); /** * Gets or sets the spot an "Auto" Panel will use for the bottom-right corner of any panel content * when the Shape#spot2 value is Spot.Default. * The default value is Spot.BottomRight, at the bottom-right point of the bounds of the Shape. */ get spot2(): Spot; set spot2(value: Spot); /** * Gets or sets the Shape#geometryStretch value the Shape should use by default * when the Shape#geometryStretch value is GraphObject.None. * The default value is GraphObject.Fill. * Some figure generators return a Geometry with this property set to GraphObject.Uniform, * in order to preserve its aspect ratio when used by a Shape that may have different sizes. * @since 1.5 */ get defaultStretch(): EnumValue; set defaultStretch(value: EnumValue); /** * This read-only property returns a rectangle that contains all points within the Geometry. * The result will always contain the origin (0, 0). */ get bounds(): Rect; } /** * A PathFigure represents a section of a Geometry. * It is a single connected series of * two-dimensional geometric PathSegments. * * The Geometry#figures property is a list of PathFigures. * * PathFigures are drawn with the Shape#stroke and other stroke properties. * Filled PathFigures are painted with the Shape#fill. * * A PathFigure must not be modified once its containing Geometry * has been assigned to a Shape. * @unrestricted * @category Geometry */ export class PathFigure { /** * Constructs an empty figure. * The optional arguments specify the starting point of the figure. * You'll want to add a new instance of a PathFigure to the * Geometry#figures list of a Geometry. * @param {number=} sx optional: the X coordinate of the start point (default is zero). * @param {number=} sy optional: the Y coordinate of the start point (default is zero). * @param {boolean=} filled optional: whether the figure is filled (default is true). * @param {boolean=} shadowed optional: whether the figure may be drawn with a shadow (default is true). * @param {boolean=} isEvenOdd optional: whether uses the even-odd rule (true) or nonzero winding number rule (the default, false). */ constructor(sx?: number, sy?: number, filled?: boolean, shadowed?: boolean, isEvenOdd?: boolean); /** * Create a copy of this PathFigure, with the same values and segments. * @expose * @return {PathFigure} */ copy(): PathFigure; /** * (undocumented) * @param {PathFigure} f * @return {boolean} */ equalsApprox(f: PathFigure): boolean; /** * Gets or sets whether this PathFigure is drawn filled. * The default value is true. */ get isFilled(): boolean; set isFilled(value: boolean); /** * Gets or sets whether this PathFigure will render a shadow if one is defined. * This is used for turning off shadows on specific subpaths. * The default value is true. */ get isShadowed(): boolean; set isShadowed(value: boolean); /** * Gets or sets whether this PathFigure will render and hit-test with the even-odd fill rule * or nonzero winding number fill rule (false). * The default value is false, using the nonzero winding number rule. * * In Geometry Path Strings, this is set by using "F0" instead of "F" at the beginning of a figure. * @since 2.3 */ get isEvenOdd(): boolean; set isEvenOdd(value: boolean); /** * Gets or sets the starting point X coordinate of the PathFigure. * The default value is zero. */ get startX(): number; set startX(value: number); /** * Gets or sets the starting point Y coordinate of the PathFigure. * The default value is zero. */ get startY(): number; set startY(value: number); /** * Gets or sets the List of PathSegments that define this PathFigure. */ get segments(): List; set segments(value: List); /** * Add a PathSegment to the #segments list. * @param {PathSegment} segment a newly allocated unshared PathSegment that will become owned by this PathFigure * @return {PathFigure} * @since 1.5 */ add(segment: PathSegment): PathFigure; } /** * A PathSegment represents a straight line or curved segment of a path between * two or more points that are part of a PathFigure. * The very first point is given by the PathFigure#startX and PathFigure#startY properties. * After the first segment the beginning point of the next segment is the same as the end point of the previous segment. * For most types of PathSegments the end point of the segment is given by #endX and #endY. * * A PathSegment must not be modified once its containing PathFigure's * Geometry has been assigned to a Shape. * @unrestricted * @category Geometry */ export class PathSegment { /** * Constructs a segment that goes nowhere unless you specify some Points. * * The very first point of a path is specified in the containing PathFigure by * its PathFigure#startX and PathFigure#startY properties. * * The segment type must be one of the following values: * PathSegment.Line, PathSegment.Bezier, * PathSegment.QuadraticBezier, PathSegment.Arc, PathSegment.SvgArc. * You will want to add a new instance of a PathSegment to the * PathFigure#segments list of a PathFigure. * @param {EnumValue=} type if not supplied, the default PathSegment type is PathSegment.Line. * But if the type is supplied, one must also provide the endpoint X and Y values, * either as arguments in this constructor or by setting the #endX and #endY properties. * If the type is QuadraticBezier, the X1 and Y1 control point values must both be supplied. * If the type is Bezier, X1, Y1, X2, and Y2 control point values must all be supplied. * * If the type is PathSegment.Line|Line it needs the following arguments: * * `(go.PathSegment.Line, ex, ey)` * - **ex, ey** describe the end point * * If the type is PathSegment.QuadraticBezier|QuadraticBezier it needs the following arguments: * * `(go.PathSegment.QuadraticBezier, ex, ey, x1, y1)` * - **ex, ey** describe the end point * - **x1, y1** describe the only control point * * If the type is PathSegment.Bezier|Bezier it needs the following arguments: * * `(go.PathSegment.Bezier, ex, ey, x1, y1, x2, y2)` * - **ex, ey** describe the end point * - **x1, y1** describe the first control point * - **x2, y2** describe the second control point * * If the type is PathSegment.Arc|Arc it needs the following arguments: * * `(go.PathSegment.Arc, startAngle, sweepAngle, centerX, centerY, radiusX, radiusY)` * - **startAngle** describes the start angle, in degrees * - **sweepAngle** describes the sweep angle, in degrees * - **centerX, centerY** describe the center point * - **radiusX, radiusY** describe the radiusX and radiusY * * If the type is PathSegment.SvgArc|SvgArc it needs the following arguments: * * `(go.PathSegment.SvgArc, ex, ey, radiusX, radiusY, xAxisRotation, largeArcFlag, clockwiseFlag)` * * They are in the same order as arcs in SVG path strings, except the endpoint x and y values come first, not last. * - **ex, ey** describe the endpoint * - **radiusX, radiusY** describe the radius * - **xAxisRotation** describes the #xAxisRotation (number in degrees) * - **largeArcFlag** describes the #isLargeArc (true or false) * - **clockwiseFlag** describes the #isClockwiseArc (true or false). * * If the type is PathSegment.Move|Move it needs the following arguments: * * `(go.PathSegment.Move, ex, ey)` * - **ex, ey** describe the next starting point * * @param {number=} ex optional: the X coordinate of the end point, or the startAngle of an Arc. * @param {number=} ey optional: the Y coordinate of the end point, or the sweepAngle of an Arc. * @param {number=} x1 optional: the X coordinate of the first bezier control point, or the centerX of an Arc, or the radiusX of an SvgArc. * @param {number=} y1 optional: the Y coordinate of the first bezier control point, or the centerY of an Arc, or the radiusY of an SvgArc. * @param {number=} x2 optional: the X coordinate of the second cubic bezier control point, or the radiusX of an Arc, or the xAxisRotation of an SvgArc. * @param {number|boolean=} y2 optional: the Y coordinate of the second cubic bezier control point, or the radiusY of an Arc, or whether this is the larger arc of an SvgArc. * @param {boolean=} clockwise optional: whether an SvgArc goes clockwise or counterclockwise. */ constructor(type?: EnumValue, ex?: number, ey?: number, x1?: number, y1?: number, x2?: number, y2?: number | boolean, clockwise?: boolean); /** * Create a copy of this PathSegment, of the same type and with the same point values. * @expose * @return {PathSegment} */ copy(): PathSegment; /** * (undocumented) * @param {PathSegment} s * @return {boolean} */ equalsApprox(s: PathSegment): boolean; /** * For beginning a new subpath, a value for PathSegment#type. * @constant */ static Move: EnumValue; /** * For drawing a straight line segment, a value for PathSegment#type. * @constant */ static Line: EnumValue; /** * For drawing a cubic bezier segment, a value for PathSegment#type. * @constant */ static Bezier: EnumValue; /** * For drawing a quadratic bezier segment, a value for PathSegment#type. * @constant */ static QuadraticBezier: EnumValue; /** * For drawing an arc segment, a value for PathSegment#type. * @constant */ static Arc: EnumValue; /** * For drawing an SVG arc segment, a value for PathSegment#type. * * See: SVG Arc specification (w3.org) * @constant * @since 1.1 */ static SvgArc: EnumValue; /** * Closes the path after this PathSegment * @return {PathSegment} returns this PathSegment. */ close(): PathSegment; /** * Gets or sets whether the path is closed after this PathSegment. * Default value is false. */ get isClosed(): boolean; set isClosed(value: boolean); /** * Gets or sets the type of the PathSegment. * The value must be one of the following: * PathSegment.Line, PathSegment.Bezier, * PathSegment.QuadraticBezier, PathSegment.Arc, * PathSegment.Move, PathSegment.Arc, and PathSegment.SvgArc. */ get type(): EnumValue; set type(value: EnumValue); /** * Gets or sets the X coordinate of the end point for all types of PathSegment except PathSegment.Arc|Arc. * The default value is zero. */ get endX(): number; set endX(value: number); /** * Gets or sets the Y coordinate of the end point for all types of PathSegment except PathSegment.Arc|Arc. * The default value is zero. */ get endY(): number; set endY(value: number); /** * Gets or sets the X value of the first control point for a PathSegment * of type PathSegment.Bezier|Bezier or PathSegment.QuadraticBezier|QuadraticBezier. */ get point1X(): number; set point1X(value: number); /** * Gets or sets the Y value of the first control point for a PathSegment * of type PathSegment.Bezier|Bezier or PathSegment.QuadraticBezier|QuadraticBezier. */ get point1Y(): number; set point1Y(value: number); /** * Gets or sets the X value of the second control point for a PathSegment * of type cubic PathSegment.Bezier|Bezier. */ get point2X(): number; set point2X(value: number); /** * Gets or sets the Y value of the second control point for a PathSegment * of type cubic PathSegment.Bezier|Bezier. */ get point2Y(): number; set point2Y(value: number); /** * Gets or sets the center X value of the Arc for a PathSegment of type PathSegment.Arc|Arc. */ get centerX(): number; set centerX(value: number); /** * Gets or sets the center Y value of the Arc for a PathSegment of type PathSegment.Arc|Arc. */ get centerY(): number; set centerY(value: number); /** * Gets or sets the X value of the radius for a PathSegment of type PathSegment.Arc|Arc or PathSegment.SvgArc|SvgArc. * Value must be a positive number. */ get radiusX(): number; set radiusX(value: number); /** * Gets or sets the Y value of the radius for a PathSegment of type PathSegment.Arc|Arc or PathSegment.SvgArc|SvgArc. * Value must be a positive number. */ get radiusY(): number; set radiusY(value: number); /** * Gets or sets the starting angle for a PathSegment of type PathSegment.Arc|Arc. * Value must within the range: (0 <= value < 360). */ get startAngle(): number; set startAngle(value: number); /** * Gets or sets the length of angle in degrees, or amount of arc to "sweep" for a PathSegment of type PathSegment.Arc|Arc. * Must be between -360 and 360, inclusive. */ get sweepAngle(): number; set sweepAngle(value: number); /** * Gets or sets the clockwise-flag for a PathSegment of type PathSegment.SvgArc|SvgArc. * SVG Arcs specify a radius and an endpoint, and are always a portion of an ellipse. * The parameters allow for two potential ellipses and four potential arcs. * A clockwise-flag set to true will use one of the two possible positive-angle arcs, * and false will use one of the two negative-angle arcs. Which arc is chosen (small or large) * depends on the value of #isLargeArc. * For more information see the visual examples in the * SVG Arc specification (w3.org) */ get isClockwiseArc(): boolean; set isClockwiseArc(value: boolean); /** * Gets or sets the large-arc-flag for a PathSegment of type PathSegment.SvgArc|SvgArc. * SVG Arcs specify a radius and an endpoint, and are always a portion of an ellipse. * The parameters allow for two potential ellipses and four potential arcs. * A large-arc-flag set to true will choose the larger of the two arc sweeps. * Which way the arc sweeps (positive angle or negative angle) depends on the value of #isClockwiseArc * For more information see the visual examples in the * SVG Arc specification (w3.org) */ get isLargeArc(): boolean; set isLargeArc(value: boolean); /** * Gets or sets the X-axis rotation for a PathSegment of type PathSegment.SvgArc|SvgArc. * X-axis rotation is used to rotate the ellipse that the arc is created from, * and must be between 0 and 360 degrees. * Default is 0. */ get xAxisRotation(): number; set xAxisRotation(value: number); } /** * An InputEvent represents a mouse or keyboard or touch event. * The principal properties hold information about a particular input event. * These properties include the #documentPoint at which a mouse event * occurred in document coordinates, * the corresponding point in view/element coordinates, #viewPoint, * the #key for keyboard events, * and the #modifiers and #button at the time. * Additional descriptive properties include #clickCount, #delta, * #timestamp, and the source event #event (if available). * * Many of its properties are provided for convenient access to the state of the input event, * such as asking whether the #control key was held down at the time, * or the #targetObject (a GraphObject) that the mouse was over . * * When real events fire on the Diagram, InputEvents are created automatically set update the value of Diagram#lastInput. * These events set the value of #event with the backing browser-defined Event, * which may be a MouseEvent, KeyboardEvent, PointerEvent, and so on. * * InputEvents backed by MouseEvents set both #button, the button that caused the action, * and #buttons, the set of buttons currently pressed after the action has happened. * By default a user-created InputEvent sets #button and #buttons as if the event was a left-click. * * You can create InputEvents and set the value of Diagram#lastInput in order to simulate user actions in tools. * This can be useful for testing. See the Robot extension sample for * an example of creating InputEvents to simulate user input. * @unrestricted */ export class InputEvent { /** * The InputEvent class constructor produces an empty InputEvent. * You should never need to call this constructor. * But if you do, you must first set #diagram to the Diagram before any other use. */ constructor(); /** * Make a copy of this InputEvent. * @expose * @return {InputEvent} */ copy(): InputEvent; /** * Gets the source diagram associated with the event. */ get diagram(): Diagram; set diagram(value: Diagram); /** * Gets or sets the point at which this input event occurred. * The Point is in view coordinates within the viewport, not in document coordinates. * This should be valid for mouse events. * For keyboard events, this is the last available mouse point. * @see #documentPoint * @see Diagram#transformViewToDoc * @see Diagram#transformDocToView */ get viewPoint(): Point; set viewPoint(value: Point); /** * Gets or sets the point at which this input event occurred, in document coordinates. * The Point is in document coordinates, the same as the GraphObject#position * for Parts in the diagram. * This should be valid for mouse events. * For keyboard events, this is the last available mouse point. * @see #viewPoint * @see Diagram#transformViewToDoc * @see Diagram#transformDocToView */ get documentPoint(): Point; set documentPoint(value: Point); /** * Gets or sets the modifier keys that were used with the mouse or keyboard event. * The number will be a combination of flags representing Control, Shift, Alt or Meta. * @see #control * @see #shift * @see #alt * @see #meta */ get modifiers(): number; set modifiers(value: number); /** * Gets or sets the numerical value representing the mouse button that caused this event. * * Only one mouse button can cause an event at a time, * but the set of all buttons currently pressed is kept in #buttons. * * This property describes nothing during a `mousemove` event, * since no button press causes the event. Instead, use the convenience properties * #left, #middle, or #right, or use the value * of #buttons to determine which mouse buttons are * held during `mousemove` events. * * Common values for this property: * - 0: left mouse button * - 1: middle mouse button * - 2: right mouse button * * Other values are possible if the mouse has additional buttons. * * If there is no associated #event, setting this also * sets the #buttons flags to only this button. * * This property is valid if this is a mouse event. * @see #buttons * @see #left * @see #middle * @see #right */ get button(): number; set button(value: number); /** * Gets or sets the set of buttons that are currently being held down. * If this is a `mouseup` event, this set of buttons does not include * the button that was just released, which will be the value of #button. * * Common values for this property: * - 0: not holding down any button * - 1: left mouse button * - 2: right mouse button * - 3: both left and right mouse buttons * - 4: middle mouse button * - 5: middle and left mouse buttons * - 6: middle and right mouse buttons * - 7: all three common mouse buttons * * Other values are possible if the mouse has additional buttons. * * This property is valid if this is a mouse event. * @see #button * @see #left * @see #middle * @see #right */ get buttons(): number; set buttons(value: number); /** * Gets or sets the key pressed or released as this event. * This property is valid if this is a keyboard event. */ get key(): string; set key(value: string); /** * Gets or sets whether the InputEvent represents a mouse-down or a key-down event. * The default value is false. * @since 1.1 */ get down(): boolean; set down(value: boolean); /** * Gets or sets whether the InputEvent represents a mouse-up or a key-up event. * The default value is false. * @since 1.1 */ get up(): boolean; set up(value: boolean); /** * Gets or sets whether this event represents a click or a double-click. * It is zero if not a click; one if a single-click; two if a double-click. * This property is valid if this is a mouse event. */ get clickCount(): number; set clickCount(value: number); /** * Gets or sets the amount of change associated with a mouse-wheel rotation. * It is an abstract number, either positive or negative. * This property is valid if this is a mouse-wheel event. */ get delta(): number; set delta(value: number); /** * This property is true when the InputEvent is caused by a touch event that registered more than one touch. * @see #isTouchEvent * @since 1.5 */ get isMultiTouch(): boolean; set isMultiTouch(value: boolean); /** * Gets or sets whether an InputEvent that applies to a GraphObject and bubbles * up the chain of containing Panels is stopped from continuing up the chain. * * Some event handlers may set this to true to avoid getting any behavior from the containing Panels. * The default value is false. */ get handled(): boolean; set handled(value: boolean); /** * Gets or sets whether the underlying #event is prevented from bubbling up * the hierarchy of HTML elements outside of the Diagram and whether any default action is canceled. * Setting this is uncommon, but may be needed in some CommandHandler overrides in order to * pass along events, such as keystrokes, to parent elements of the Diagram. * * Some event handlers may set this to true if the event should continue beyond the diagram's DIV * and result in any default behaviors by the user-agent. * The default value is false. * @since 2.2 * @see #handled */ get bubbles(): boolean; set bubbles(value: boolean); /** * Gets or sets the platform's user-agent-supplied event for this event. * It may be null if no underlying event exists. * @see #timestamp */ get event(): Event | null; set event(value: Event | null); /** * This read-only property is true when the InputEvent is caused by a touch event. * @see #isMultiTouch * @since 1.5 */ get isTouchEvent(): boolean; /** * Gets or sets the time at which the event occurred, in milliseconds. */ get timestamp(): number; set timestamp(value: number); /** * Gets or sets the diagram associated with the canvas that the event is currently targeting. */ get targetDiagram(): Diagram | null; set targetDiagram(value: Diagram | null); /** * Gets or sets the GraphObject that is at the current mouse point, if any. * * For those events that are bubbled up the chain of parent Panels, * this property provides access to the original GraphObject where the input event occurred. * @see #handled */ get targetObject(): GraphObject | null; set targetObject(value: GraphObject | null); /** * Gets or sets whether the control key is being held down. * This is true if the key was pressed at the time of the event. * @see #modifiers * @see #shift * @see #alt * @see #meta */ get control(): boolean; set control(value: boolean); /** * Gets or sets whether the shift key is being held down. * This is true if the key was pressed at the time of the event. * @see #modifiers * @see #control * @see #alt * @see #meta */ get shift(): boolean; set shift(value: boolean); /** * Gets or sets whether the alt key is being held down. * This is true if the key was pressed at the time of the event. * @see #modifiers * @see #control * @see #shift * @see #meta */ get alt(): boolean; set alt(value: boolean); /** * Gets or sets whether the meta key is being held down. * This is true if the key was pressed at the time of the event. * @see #modifiers * @see #control * @see #shift * @see #alt */ get meta(): boolean; set meta(value: boolean); /** * Gets or sets whether the logical left mouse button is being held down. * This is true if the button was pressed at the time of the event. * * If this InputEvent has a #event of type `MouseEvent` with `e.type` of "mouseup" or "mousedown", * this property uses the value of #button. Otherwise, it uses the value of #buttons. * * When setting, this sets the value of #buttons. * @see #button * @see #middle * @see #right */ get left(): boolean; set left(value: boolean); /** * Gets or sets whether the logical right mouse button is being held down. * This is true if the button was pressed at the time of the event. * @see #button * @see #left * @see #middle */ get right(): boolean; set right(value: boolean); /** * Gets or sets whether the logical middle mouse button is being held down. * This is true if the button was pressed at the time of the event. * @see #button * @see #left * @see #right */ get middle(): boolean; set middle(value: boolean); } /** * A DiagramEvent represents a more abstract event than an InputEvent. * They are raised on the Diagram class. * One can receive such events by registering a DiagramEvent listener on a Diagram * by calling Diagram#addDiagramListener. * The listener function, when called, will be passed an instance of a DiagramEvent. * Use the #name property to decide what kind of diagram event it is. * The #diagram property refers to the Diagram, and you can get additional information * from that, such as the Diagram#lastInput, which in turn provides information * such as InputEvent#documentPoint that may be relevant for that kind of DiagramEvent. * * The #subject and #parameter properties optionally provide additional information * about the diagram event. The subject could be a collection of Parts or it could be * an individual object such as a Link or a GraphObject within a Node. * Everything depends on the kind of diagram event that it is. * * Some DiagramEvents such as "ObjectSingleClicked" or "BackgroundDoubleClicked" are normally * associated with InputEvents. * Some DiagramEvents such as "SelectionMoved" or "PartRotated" are associated with the * results of Tool-handled gestures or CommandHandler actions. * Some DiagramEvents are not necessarily associated with any input events at all, * such as "ViewportBoundsChanged", which can happen due to programmatic * changes to the Diagram#position and Diagram#scale properties. * * DiagramEvents that occur during a transaction may be called before the state of the whole diagram has settled down. * This often means that such events occur before a layout, so nodes may not have their final positions, * links may not have their final routes, and the Diagram#documentBounds and Diagram#viewportBounds * may not yet have been updated. * Such events may make additional changes to the diagram, which may in turn result in additional side-effects. * * DiagramEvents that occur outside of a transaction require you to start and commit a transaction around any side-effects that you want to do. * However, some DiagramEvents do not allow you to make any changes to the Diagram or Model. * * Currently defined diagram event names include: * - **"InitialAnimationStarting"**, the initial AnimationManager#defaultAnimation is about to start;
* this can be useful for customizing the initial animation, see AnimationManager#initialAnimationStyle. * - **"AnimationStarting"**, a AnimationManager#defaultAnimation is about to start;
* do not modify the Diagram or its Model in the event listener. * - **"AnimationFinished"**, a AnimationManager#defaultAnimation just completed;
* do not modify the Diagram or its Model in the event listener. * - **"BackgroundSingleClicked"**, a click that was not on any Part;
* if you make any changes, start and commit your own transaction. * - **"BackgroundDoubleClicked"**, a double-click that was not on any Part;
* if you make any changes, start and commit your own transaction. * - **"BackgroundContextClicked"**, a context-click that was not on any Part;
* if you make any changes, start and commit your own transaction. * - **"ChangingSelection"**, an operation is about to change the Diagram#selection collection,
* which is also the value of the DiagramEvent#subject;
* do not make any changes to the selection or the diagram in the event listener; * note that just setting Part#isSelected will not raise this event, but tools and commands will. * - **"ChangedSelection"**, an operation has just changed the Diagram#selection collection,
* which is also the value of the DiagramEvent#subject;
* do not make any changes to the selection or the diagram in the event listener; * note that just setting Part#isSelected will not raise this event, but tools and commands will. * - **"ClipboardChanged"**, Parts have been copied to the clipboard by CommandHandler#copySelection;
* the DiagramEvent#subject is the collection of Parts;
* if you make any changes, start and commit your own transaction. * - **"ClipboardPasted"**, Parts have been copied from the clipboard into the Diagram by CommandHandler#pasteSelection;
* the DiagramEvent#subject is the Diagram#selection,
* and this is called within a transaction. * - **"DocumentBoundsChanged"**, the area of the diagram's Parts, Diagram#documentBounds, has changed;
* the DiagramEvent#parameter is the old Rect * - **"ExternalObjectsDropped"**, Parts have been copied into the Diagram by drag-and-drop from outside of the Diagram;
* the DiagramEvent#subject is the set of Parts that were dropped (which is also the Diagram#selection), * the DiagramEvent#parameter is the source Diagram, * and this is called within a transaction. If you choose, you can cancel the drop by executing: * e.diagram.toolManager.draggingTool.transactionResult = null; * - **"GainedFocus"**, the diagram has gained keyboard focus, such as after a call to Diagram#focus. * - **"InitialLayoutCompleted"**, the whole diagram layout has updated for the first time since a major change to the Diagram, such as replacing the Model;
* if you make any changes, you do not need to perform a transaction. * - **"LayoutCompleted"**, the whole diagram layout has just been updated;
* if you make any changes, you do not need to perform a transaction. * - **"LinkDrawn"**, the user has just created a new Link using LinkingTool;
* the DiagramEvent#subject is the new Link,
* and this is called within a transaction. * - **"LinkRelinked"**, the user has just reconnected an existing Link using RelinkingTool or DraggingTool;
* the DiagramEvent#subject is the modified Link,
* the DiagramEvent#parameter is the GraphObject port that the link was disconnected from,
* and this is called within a transaction. * - **"LinkReshaped"**, the user has just rerouted an existing Link using LinkReshapingTool;
* the DiagramEvent#subject is the modified Link,
* the DiagramEvent#parameter is the List of Points of the link's original route, * and this is called within a transaction. * - **"LostFocus"**, the diagram has lost keyboard focus, a.k.a. "blur". * - **"Modified"**, the Diagram#isModified property has been set to a new value -- * useful for marking a window as having been modified since the last save;
* do not modify the Diagram or its Model in the event listener. * - **"ObjectSingleClicked"**, a click that occurred on a GraphObject;
* the DiagramEvent#subject is the GraphObject;
* if you make any changes, start and commit your own transaction. * - **"ObjectDoubleClicked"**, a double-click that occurred on a GraphObject;
* the DiagramEvent#subject is the GraphObject;
* if you make any changes, start and commit your own transaction. * - **"ObjectContextClicked"**, a context-click that occurred on a GraphObject;
* the DiagramEvent#subject is the GraphObject;
* if you make any changes, start and commit your own transaction. * - **"PartCreated"**, the user inserted a new Part by ClickCreatingTool;
* the DiagramEvent#subject is the new Part,
* and this is called within a transaction. * - **"PartResized"**, the user has changed the size of a GraphObject by ResizingTool;
* the DiagramEvent#subject is the GraphObject,
* the DiagramEvent#parameter is the original Size,
* and this is called within a transaction. * - **"PartRotated"**, the user has changed the angle of a GraphObject by RotatingTool;
* the DiagramEvent#subject is the GraphObject,
* the DiagramEvent#parameter is the original angle in degrees,
* and this is called within a transaction. * - **"SelectionMoved"**, the user has moved selected Parts by DraggingTool;
* the DiagramEvent#subject is a Set of the moved Parts,
* and this is called within a transaction. * - **"SelectionCopied"**, the user has copied selected Parts by DraggingTool;
* the DiagramEvent#subject is Set of the newly copied Parts,
* and this is called within a transaction. * - **"SelectionDeleted"**, the user has deleted selected Parts by CommandHandler#deleteSelection;
* the DiagramEvent#subject is the collection of Parts that were deleted,
* and this is called within a transaction. * - **"SelectionDeleting"**, the user is about to delete selected Parts by CommandHandler#deleteSelection;
* the DiagramEvent#subject is the Diagram#selection collection of Parts to be deleted,
* and this is called within a transaction. * - **"SelectionGrouped"**, the user has made a new Group out of the selected Parts by CommandHandler#groupSelection;
* the DiagramEvent#subject is the new Group,
* and this is called within a transaction. * - **"SelectionUngrouped"**, the user has removed a selected Group but kept its members by CommandHandler#ungroupSelection;
* the DiagramEvent#subject is the collection of Groups that were ungrouped,
* the DiagramEvent#parameter is the collection of former member Parts that were ungrouped,
* and this is called within a transaction. * - **"SubGraphCollapsed"**, the user has collapsed selected Groups by CommandHandler#collapseSubGraph;
* the DiagramEvent#subject is the collection of Groups that were collapsed,
* and this is called within a transaction. * - **"SubGraphExpanded"**, the user has expanded selected Groups by CommandHandler#expandSubGraph;
* the DiagramEvent#subject is the collection of Groups that were expanded,
* and this is called within a transaction. * - **"TextEdited"**, the user has changed the string value of a TextBlock by TextEditingTool;
* the DiagramEvent#subject is the edited TextBlock,
* the DiagramEvent#parameter is the original string,
* and this is called within a transaction. * - **"TreeCollapsed"**, the user has collapsed selected Nodes with subtrees by CommandHandler#collapseTree;
* the DiagramEvent#subject is the collection of Nodes that were collapsed,
* and this is called within a transaction. * - **"TreeExpanded"**, the user has expanded selected Nodes with subtrees by CommandHandler#expandTree;
* the DiagramEvent#subject is the collection of Nodes that were expanded,
* and this is called within a transaction. * - **"ViewportBoundsChanged"**, the visible area of the Diagram, Diagram#viewportBounds, has changed;
* the DiagramEvent#subject is an object whose "scale" property is the old Diagram#scale value, * whose "position" property is the old Diagram#position value, * whose "bounds" property is the old Diagram#viewportBounds value, * whose "canvasSize" property is the old size of the Diagram#div, and * whose "newCanvasSize" property is the new size of the Diagram#div, * the DiagramEvent#parameter is also the old viewportBounds Rect. * @unrestricted */ export class DiagramEvent { /** * The DiagramEvent class constructor produces an empty DiagramEvent. * You should never need to call this constructor. * But if you do, you must first set #diagram to the Diagram before any other use. */ constructor(); /** * Gets the diagram associated with the event. */ get diagram(): Diagram; set diagram(value: Diagram); /** * Gets or sets the name of the kind of diagram event that this represents. * This property should always be set to one of the recognized list of names, * as listed in the documentation for DiagramEvent. */ get name(): string; set name(value: string); /** * Gets or sets an optional object that is the subject of the diagram event. * This property defaults to null. */ get subject(): any; set subject(value: any); /** * Gets or sets an optional object that describes the change to the subject of the diagram event. * This property defaults to null. */ get parameter(): any; set parameter(value: any); } /** * The signature for a function acting as a handler for DiagramEvents. */ export type DiagramEventHandler = (e: DiagramEvent) => void; /** * A TypeScript type listing all of the supported DiagramEvent names. */ export type DiagramEventName = 'InitialAnimationStarting' | 'AnimationStarting' | 'AnimationFinished' | 'BackgroundSingleClicked' | 'BackgroundDoubleClicked' | 'BackgroundContextClicked' | 'ChangingSelection' | 'ChangedSelection' | 'ClipboardChanged' | 'ClipboardPasted' | 'DocumentBoundsChanged' | 'ExternalObjectsDropped' | 'GainedFocus' | 'InitialLayoutCompleted' | 'LayoutCompleted' | 'LinkDrawn' | 'LinkRelinked' | 'LinkReshaped' | 'LostFocus' | 'Modified' | 'ObjectSingleClicked' | 'ObjectDoubleClicked' | 'ObjectContextClicked' | 'PartCreated' | 'PartResized' | 'PartRotated' | 'SelectionMoved' | 'SelectionCopied' | 'SelectionDeleted' | 'SelectionDeleting' | 'SelectionGrouped' | 'SelectionUngrouped' | 'SubGraphCollapsed' | 'SubGraphExpanded' | 'TextEdited' | 'TreeCollapsed' | 'TreeExpanded' | 'ViewportBoundsChanged' | 'InvalidateDraw'; /** * A TypeScript type for helping to declare GraphObject.make. */ export interface DiagramEventsInterface { AnimationStarting?: DiagramEventHandler; AnimationFinished?: DiagramEventHandler; BackgroundSingleClicked?: DiagramEventHandler; BackgroundDoubleClicked?: DiagramEventHandler; BackgroundContextClicked?: DiagramEventHandler; ChangingSelection?: DiagramEventHandler; ChangedSelection?: DiagramEventHandler; ClipboardChanged?: DiagramEventHandler; ClipboardPasted?: DiagramEventHandler; DocumentBoundsChanged?: DiagramEventHandler; ExternalObjectsDropped?: DiagramEventHandler; GainedFocus?: DiagramEventHandler; InitialLayoutCompleted?: DiagramEventHandler; LayoutCompleted?: DiagramEventHandler; LinkDrawn?: DiagramEventHandler; LinkRelinked?: DiagramEventHandler; LinkReshaped?: DiagramEventHandler; LostFocus?: DiagramEventHandler; Modified?: DiagramEventHandler; ObjectSingleClicked?: DiagramEventHandler; ObjectDoubleClicked?: DiagramEventHandler; ObjectContextClicked?: DiagramEventHandler; PartCreated?: DiagramEventHandler; PartResized?: DiagramEventHandler; PartRotated?: DiagramEventHandler; SelectionMoved?: DiagramEventHandler; SelectionCopied?: DiagramEventHandler; SelectionDeleted?: DiagramEventHandler; SelectionDeleting?: DiagramEventHandler; SelectionGrouped?: DiagramEventHandler; SelectionUngrouped?: DiagramEventHandler; SubGraphCollapsed?: DiagramEventHandler; SubGraphExpanded?: DiagramEventHandler; TextEdited?: DiagramEventHandler; TreeCollapsed?: DiagramEventHandler; TreeExpanded?: DiagramEventHandler; ViewportBoundsChanged?: DiagramEventHandler; } /** * A ChangedEvent represents a change to an object, typically a GraphObject, * but also for model data, a Model, or a Diagram. * The most common case is for remembering the name of a property * and the before-and-after values for that property. * * You can listen for changed events on the model using Model#addChangedListener * or Diagram#addModelChangedListener, and on the Diagram using Diagram#addChangedListener. * * There are four kinds of changes, represented by enumerated values: * ChangedEvent.Property (the most common), ChangedEvent.Insert and ChangedEvent.Remove * (to represent inserting or removing objects from collections), * and ChangedEvent.Transaction (to notify about beginning or ending transactions or undo or redo). * * The most common kind of ChangedEvent is a Property change. * The name of the property is given by #propertyName. * The modified object is given by #object. * Use the #oldValue and #newValue properties for the before and after property values. * * For an Insert ChangedEvent, the modified collection (often an Array) is a property value on the #object. * The #propertyName helps distinguish between different collections on the object. * Use the #newValue property to indicate the value that was inserted. * Use the #newParam property to indicate where or how, such as an array index or dictionary key. * * For a Remove ChangedEvent, the modified collection is a property value on the #object. * The #propertyName helps distinguish between different collections on the object. * Use the #oldValue property to indicate the value that was removed. * Use the #oldParam property to indicate where or how, such as an array index or dictionary key. * * Transaction ChangedEvents are generated by the UndoManager. * The #propertyName names the nature of the ChangedEvent. * For the very first transaction, the property name is "StartingFirstTransaction". * This ChangedEvent precedes a ChangedEvent whose property name is "StartedTransaction", * which occurs for every top-level transaction. * * When ending a transaction, there is first a ChangedEvent whose name is "ComittingTransaction". * This is followed by one with either "CommittedTransaction" or "RolledBackTransaction", * depending on how the transaction is ending. * The #oldValue provides the transaction name and the #object is the Transaction being finished. * (Note that the Transaction value may be null if no Transaction is available at that time, * perhaps because there were no changes made during the transaction.) * That Transaction can be scanned to look for ChangedEvents that you may wish to record in a database, * all within a single database transaction. * * There are also Transaction ChangedEvents corresponding to "StartingUndo", "FinishedUndo", * "StartingRedo", and "FinishedRedo". * The #object property provides the Transaction that is about-to-be or just-was undone or redone. * * Non-Transaction ChangedEvents are remembered by the UndoManager, if UndoManager#isEnabled, * and held in the UndoManager#history as Transactions which hold lists of ChangedEvents. * That is why ChangedEvent implements #undo and #redo of the change that it remembers. * * When the ChangedEvent represents a change to a Model, the value of #model is non-null * and the value of #diagram is meaningless. * If the change is a structural change to the model, * the value of #modelChange indicates the kind of change. * Currently defined model changed event names include: * - **"nodeDataArray"**, after the model's Model#nodeDataArray is replaced, inserted into or removed from * (setting Model#nodeDataArray or calling Model#addNodeData or Model#removeNodeData) * - **"nodeKey"**, after changing a node data's unique key (Model#setKeyForNodeData) * - **"nodeCategory"**, after changing a node data's category (Model#setCategoryForNodeData) * - **"linkDataArray"**, after the model's GraphLinksModel#linkDataArray is replaced, inserted into or removed from * (setting GraphLinksModel#linkDataArray or calling GraphLinksModel#addLinkData * or GraphLinksModel#removeLinkData) * - **"linkKey"**, after changing a link data's unique key (GraphLinksModel#setKeyForLinkData) * - **"linkCategory"**, after changing a link data's category (GraphLinksModel#setCategoryForLinkData) * - **"linkFromKey"**, after changing a link data's "from" node key (GraphLinksModel#setFromKeyForLinkData) * - **"linkToKey"**, after changing a link data's "to" node key (GraphLinksModel#setToKeyForLinkData) * - **"linkFromPortId"**, after changing a link data's "from" port identifier string (GraphLinksModel#setFromPortIdForLinkData) * - **"linkToPortId"**, after changing a link data's "to" port identifier string (GraphLinksModel#setToPortIdForLinkData) * - **"linkLabelKeys"**, after replacing, inserting into, or removing from a link data's array of keys to label nodes * (calling GraphLinksModel#setLabelKeysForLinkData, GraphLinksModel#addLabelKeyForLinkData, * or GraphLinksModel#removeLabelKeyForLinkData) * - **"nodeGroupKey"**, after changing a node data's key for a containing group data (GraphLinksModel#setGroupKeyForNodeData) * - **"nodeParentKey"**, after changing a node data's "parent" node key (TreeModel#setParentKeyForNodeData) * - **"parentLinkCategory"**, after changing a node data's "parent" link's category(TreeModel#setParentLinkCategoryForNodeData) * - other names are for internal implementation use only, only on Transaction ChangedEvents * * The value of ChangedEvent#propertyName indicates the actual name of the property that was modified. * ChangedEvent#modelChange is a non-empty string only when there is a known structural change to the model, * not just the setting of some property on some object. * * When the ChangedEvent represents a change to a Diagram or a GraphObject within a diagram, * the value of #diagram is non-null and * the values of #model and #modelChange are meaningless. * * Please note that ChangedEvents can be raised for many different causes. * You may not be interested in changes to temporary objects -- in that case ignore the ChangedEvent when * Model#skipsUndoManager or Diagram#skipsUndoManager is true. * @unrestricted * @category Model */ export class ChangedEvent { /** * The ChangedEvent class constructor produces an empty ChangedEvent object. */ constructor(); /** * For informational events, such as transactions and undo/redo operations, * and used as the value for ChangedEvent#change. * The ChangedEvent#object refers to the Transaction affected, if any. * The ChangedEvent#propertyName distinguishes the different transaction or undo or redo stages. * The ChangedEvent#oldValue may provide the transaction name, if available, as given to UndoManager#commitTransaction. * @constant */ static Transaction: EnumValue; /** * For simple property changes, * and used as the value for ChangedEvent#change. * The name of the property is given by ChangedEvent#propertyName. * The modified object is given by ChangedEvent#object. * Use the ChangedEvent#oldValue and ChangedEvent#newValue properties for the previous and next property values. * * For model changes, the ChangedEvent#modelChange may be non-empty, indicating a structural change to the model. * @constant */ static Property: EnumValue; /** * For inserting into collections, * and used as the value for ChangedEvent#change. * The modified object is given by ChangedEvent#object. * Use the optional ChangedEvent#propertyName to distinguish between different collections on the object. * Use the ChangedEvent#newValue property to indicate the value that was inserted. * Use the optional ChangedEvent#newParam property to indicate where or how, such as an array index or dictionary key. * @constant */ static Insert: EnumValue; /** * For removing from collections, * and used as the value for ChangedEvent#change. * The modified object is given by ChangedEvent#object. * Use the optional ChangedEvent#propertyName to distinguish between different collections on the object. * Use the ChangedEvent#oldValue property to indicate the value that was removed. * Use the optional ChangedEvent#oldParam property to indicate where or how, such as an array index or dictionary key. * @constant */ static Remove: EnumValue; /** * Forget any object references that this ChangedEvent may have. */ clear(): void; /** * Make a copy of this ChangedEvent. * ChangedEvents are copied when the UndoManager adds to a Transaction. * @return {ChangedEvent} */ copy(): ChangedEvent; /** * This is a convenient method to get the right value, depending on the value of undo, * when implementing a state change as part of an undo or a redo. * @param {boolean} undo If true, returns the oldValue, otherwise returns the newValue. * @return {*} Either the oldValue or the newValue. */ getValue(undo: boolean): any; /** * This is a convenient method to get the right parameter value, depending on the value of undo, * when implementing a state change as part of an undo or a redo. * @param {boolean} undo If true, returns the oldParam, otherwise returns the newParam. * @return {*} Either the oldParam or the newParam. */ getParam(undo: boolean): any; /** * This predicate returns true if you can call undo(). * @return {boolean} True if ready for undo() to be called. */ canUndo(): boolean; /** * Reverse the effects of this object change. * canUndo() must be true for this method to have any effect. */ undo(): void; /** * This predicate returns true if you can call redo(). * @return {boolean} True if ready for redo() to be called. */ canRedo(): boolean; /** * Re-perform this object change after an undo(). * canRedo() must be true for this method to have any effect. */ redo(): void; /** * Gets or sets the Model or TreeModel or GraphLinksModel that was modified. * When this property is non-null, the #diagram property will be null. * However this property and the #diagram property may both be null simultaneously, * when no particular model or diagram applies. */ get model(): Model | null; set model(value: Model | null); /** * Gets or sets the Diagram that was modified. * When this property is non-null, the #model property will be null. * However this property and the #model property may both be null simultaneously, * when no particular model or diagram applies. */ get diagram(): Diagram | null; set diagram(value: Diagram | null); /** * Gets or sets the nature of change that occurred. * The default is ChangedEvent.Property. * Other values are ChangedEvent.Insert, ChangedEvent.Remove, * and ChangedEvent.Transaction. */ get change(): EnumValue; set change(value: EnumValue); /** * Gets or sets the name of the model change, reflecting a change to * model data in addition to a change to the model itself. * * The default is an empty string, which indicates that this is just * a regular change to some object's state, probably its property. * For a list of possible model change names, see the documentation for ChangedEvent. * The names are compared in a case-sensitive manner. */ get modelChange(): string; set modelChange(value: string); /** * Gets or sets the name of the property change. * The default is an empty string, which is not a valid property name. * This property can be useful even when the type of change is * not ChangedEvent.Property, because it can help identify * the collection in the #object that was modified * (for ChangedEvent.Insert or ChangedEvent.Remove) * or the stage of the current transaction (for ChangedEvent.Transaction). */ get propertyName(): string | ((a: ObjectData, b: any) => any); set propertyName(value: string | ((a: ObjectData, b: any) => any)); /** * This read-only property is true when this ChangedEvent is of type ChangedEvent.Transaction and represents the end of a transactional change. * It is implemented as: * ```js * return (this.change === ChangedEvent.Transaction && * (this.propertyName === "CommittedTransaction" || * this.propertyName === "FinishedUndo" || * this.propertyName === "FinishedRedo")); * ``` */ get isTransactionFinished(): boolean; /** * Gets or sets the Object that was modified. * The default is null. * * For ChangedEvent.Transaction changes, this may be the Transaction. */ get object(): ObjectData | null; set object(value: ObjectData | null); /** * Gets or sets the previous or old value that the property had. * The default is null. */ get oldValue(): any; set oldValue(value: any); /** * Gets or sets an optional value associated with the old value. * Most properties do not require any parameter to describe the change. * This is typically a value that helps distinguish the old value, such as an index into an array. * It is null if it is not used. * The default is null. */ get oldParam(): any; set oldParam(value: any); /** * Gets or sets the next or current value that the property has. * The default is null. */ get newValue(): any; set newValue(value: any); /** * Gets or sets an optional value associated with the new value. * Most properties do not require any parameter to describe the change. * This is typically a value that helps distinguish the new value, such as an index into an array. * It is null if it is not used. * The default is null. */ get newParam(): any; set newParam(value: any); } /** * The signature for a function acting as a handler for ChangedEvents. */ export type ChangedEventHandler = (e: ChangedEvent) => void; /** * A Transaction holds a list of ChangedEvents collected during a transaction, * as the value of the read-only #changes property. * * Start a transaction by calling UndoManager#startTransaction * (or Model#startTransaction or Diagram#startTransaction, which call that method). * Be sure to finish a transaction with a matching call to UndoManager#commitTransaction * (or Model#commitTransaction or Diagram#commitTransaction), * or a call to UndoManager#rollbackTransaction * (or the same named methods on Model or Diagram). * * If you are performing multiple or repeated changes to a model or diagram, * surround all of the code with calls to start and commit the transaction -- * do not perform repeated calls to start-commit-start-commit. * Typically each change caused by the user, such as a button click or a change of focus or a mouse drag, * should perform one transaction in which all changes are made. * All of the predefined commands and tools perform transactions. * * Undoing or redoing a transaction is done by calling UndoManager#undo or UndoManager#redo. * Those methods call the #undo or #redo methods here. * * The UndoManager holds a list of Transactions in its UndoManager#history. * @unrestricted * @category Model */ export class Transaction { /** * Construct an object holding an empty list of ChangedEvents * and no #name. */ constructor(); /** * Clear all of the saved changes. */ clear(): void; /** * This predicate returns true if you can call #undo, * namely when #isComplete is true. * @return {boolean} true if ready for #undo to be called. */ canUndo(): boolean; /** * Undo all of the changes, in reverse order. * This is normally called only by the UndoManager. * #canUndo must be true for this method to have any effect. */ undo(): void; /** * This predicate returns true if you can call #redo, * namely when #isComplete is true. * @return {boolean} true if ready for #redo to be called. */ canRedo(): boolean; /** * Re-perform these changes after an #undo. * This is normally called only by the UndoManager. * #canRedo must be true for this method to have any effect. */ redo(): void; /** * Remove all but the first and last Property ChangedEvents for each property for each object. * * This is now called by DraggingTool#stopTransaction in order to reduce the memory saved by each dragging transaction. * @since 2.2 */ optimize(): void; /** * This read-only property returns the list of ChangedEvents. * The changes are stored in order of occurrence. * * You should not modify this list. */ get changes(): List; /** * Gets or sets the transaction name for this collection of changes. * This is set by a top-level call to UndoManager#commitTransaction. */ get name(): string; set name(value: string); /** * Gets or sets whether we can add more ChangedEvents to this list of changes. * This is initially false. * It is set to true by UndoManager#commitTransaction and UndoManager#rollbackTransaction. */ get isComplete(): boolean; set isComplete(value: boolean); } /** * An UndoManager observes and records model and diagram changes in transactions and * supports undo/redo operations. * You will need to set the #isEnabled property to true in order for * the UndoManager to record changes and for users to perform an undo or a redo. * * Typically an operation will call #startTransaction, * make some changes to the Model and/or Diagram, * and then call #commitTransaction. * Any ChangedEvents that occur will be recorded in a * Transaction object. * If for some reason you do not wish to complete the transaction * successfully, you can call #rollbackTransaction instead * of #commitTransaction. * * For convenience the Diagram#commit and Model#commit methods * execute a function within a transaction and then perform a commit, * or else a rollback upon an error. * * The #history property is a list of Transactions. * #commitTransaction will add the #currentTransaction * to the #history list. * #rollbackTransaction will undo the changes remembered in the * #currentTransaction and then discard it, without changing the #history. * You can limit how many transactions are remembered in the history * by setting #maxHistoryLength. * * Transactions may be nested. * Be sure to call either #commitTransaction or #rollbackTransaction * for each call to #startTransaction. * Avoid repeated start-commit-start-commit calls as a result of a user's actions. * Instead, start, make all changes, and then commit. * * If you want to restore the diagram to the state before the latest complete * transaction, call #undo. * Call #redo to change the diagram to a later state. * If after some number of undo's you start a transaction, * all of the history after the current state is discarded, * and a new transaction may be recorded. * You cannot undo or redo during a transaction. * * Initially each Model has its own UndoManager. * UndoManagers may be shared by multiple Models by replacing * the standard Model#undoManager created by the model constructor. * * There are several informational properties: * - #isInTransaction is true when a top-level transaction has been started that has not yet been committed or rolled-back. * - #currentTransaction holds the flattened list of all ChangedEvents * that have happened within the current transaction. * - #transactionLevel indicates the current depth of nesting. * - #nestedTransactionNames holds the stack of transaction names supplied to * #startTransaction calls. * - #history holds only complete top-level transactions. * - #isUndoingRedoing is true during a call to #undo or #redo. * - #historyIndex indicates which Transaction in the #history is the next to be "undone"; * this is decremented by each undo and incremented by each redo. * - #transactionToUndo and #transactionToRedo indicate which Transaction may be undone or redone next, if any. * - #models returns an iterator over all of the Models that this UndoManager is handling. * * A transaction may not be ongoing when replacing a Diagram#model, * because it would not make sense to be replacing the UndoManager (the Model#undoManager) * while changes are being recorded. * * Replacing a Diagram#model copies certain properties from the old UndoManager to the new one, * including #isEnabled and #maxHistoryLength. * @unrestricted * @category Model */ export class UndoManager { /** * The constructor produces an empty UndoManager * with no transaction history. */ constructor(); /** * Clear all of the Transactions and clear all other state, * including any ongoing transaction without rolling back. * However, this maintains its references to its Models. * * You should not call this method during a transaction. */ clear(): void; /** * (undocumented) * Copy persistent properties from an old UndoManager to this new one. * This is called by the Diagram#model property setter. * @expose * @param old */ copyProperties(old: UndoManager): void; /** * Make sure this UndoManager knows about a Model for which * it may receive ChangedEvents when the given Model is changed. * The model will also receive notifications about transactions and undo or redo operations. * * You should not call this method during a transaction. * @param {Model} model A Model that this UndoManager is managing. * @see #models * @see #removeModel */ addModel(model: Model): void; /** * Inform this UndoManager that it will no longer be receiving ChangedEvents * when the given Model is changed. * The model will no longer receive notifications about transactions and undo or redo operations. * * You should not call this method during a transaction. * If you call this method between transactions when there is a transaction history, * you should be careful that there are no ChangedEvents referring to that model in any Transactions. * @param {Model} model A Model that this UndoManager should no longer manage. * @see #models * @see #addModel */ removeModel(model: Model): void; /** * Begin a transaction, where the changes are held by a Transaction object * as the value of #currentTransaction. * You must call either #commitTransaction or #rollbackTransaction afterwards. * * For convenience, this method is called by Model#startTransaction and Diagram#startTransaction. * * Transactions can be nested. * Starting or ending a nested transaction will return false. * Nested transactions will share the same Transaction list of ChangedEvents. * * Starting a transaction will not necessarily cause #currentTransaction to be non-null. * A Transaction object is usually only created by #handleChanged when a ChangedEvent first occurs. * @param {string=} tname a short string describing the transaction, pushed onto the #nestedTransactionNames stack. * @return {boolean} true if starting a top-level transaction. * @see #commitTransaction * @see #rollbackTransaction */ startTransaction(tname?: string): boolean; /** * Commit the current transaction started by a call to #startTransaction. * * For convenience, this method is called by Model#commitTransaction and Diagram#commitTransaction. * * If this call stops a top-level transaction, * we mark the #currentTransaction as complete (Transaction#isComplete), * we add the Transaction to the #history list, * and we return true. * Committing a transaction when there have been some undos without corresponding * redos will throw away the Transactions holding changes that happened * after the current state, before adding the new Transaction to the * #history list. * @param {string=} tname a short string describing the transaction; * this is recorded as the Transaction#name and need not be the same as the string passed to #startTransaction. * If the value is an empty string or not supplied, this will use the name given to #startTransaction. * @return {boolean} true if ending a top-level transaction. * @see #startTransaction * @see #rollbackTransaction */ commitTransaction(tname?: string): boolean; /** * Rollback the current transaction started by a call to #startTransaction, undoing any changes. * * For convenience, this method is called by Model#rollbackTransaction and Diagram#rollbackTransaction. * * This undoes and then discards the changes in the #currentTransaction. * You must have started a transaction previously. * @return {boolean} true if ending a top-level transaction. * @see #startTransaction * @see #commitTransaction */ rollbackTransaction(): boolean; /** * After an undo, call this to discard all of the transactions after * this point in the history, as indicated by the #historyIndex. * This method is called when a transaction occurs after some number of undo's * without the same number of redo's, in order to remove all of the transactions * that happened after the current history point, and then adding the new transaction. * * This modifies the #history but leaves #historyIndex unchanged. * After a successful discard, #canRedo will return false. * * This method does nothing if #canRedo returns false, * or if an undo or a redo is ongoing. * @since 2.4 */ discardHistoryAfterIndex(): void; /** * This predicate returns true if you can call #undo. * This will return false if #isEnabled is false (as it is by default), * if any transaction is ongoing, or * if there is no #transactionToUndo that can be undone. * @return {boolean} true if ready for #undo to be called. */ canUndo(): boolean; /** * Reverse the effects of the #transactionToUndo. * #canUndo must be true for this method to have any effect. * * This is called by CommandHandler#undo. * * This will raise a "StartingUndo" ChangedEvent of type ChangedEvent.Transaction, * perform the Transaction#undo on the #transactionToUndo, and then * raise a "FinishedUndo" ChangedEvent of type ChangedEvent.Transaction. * The two ChangedEvents are to let model listeners know that an undo is about to take place * and that it just finished. * #isUndoingRedoing will temporarily be set to true during this operation. */ undo(): void; /** * This predicate returns true if you can call #redo. * This will return false if #isEnabled is false (as it is by default), * if any transaction is ongoing, or * if there is no #transactionToRedo that can be redone. * @return {boolean} true if ready for #redo to be called. */ canRedo(): boolean; /** * After an #undo, re-perform the changes in #transactionToRedo. * #canRedo must be true for this method to have any effect. * * This is called by CommandHandler#redo. * * This will raise a "StartingRedo" ChangedEvent of type ChangedEvent.Transaction, * perform the Transaction#redo on the #transactionToRedo, and then * raise a "FinishedRedo" ChangedEvent of type ChangedEvent.Transaction. * The two ChangedEvents are to let model listeners know that a redo is about to take place * and that it just finished. * #isUndoingRedoing will temporarily be set to true during this operation. */ redo(): void; /** * Maybe record a ChangedEvent in the #currentTransaction. * This calls #skipsEvent to see if this should ignore the change. * If #skipsEvent returns false, this creates a copy of the ChangedEvent * and adds it to the #currentTransaction. * If there is no #currentTransaction, this first creates and remembers it. * * This method always ignores all changes while performing * an #undo or #redo. * This method is also a no-op if #isEnabled is false. * @param {ChangedEvent} e a ChangedEvent. */ handleChanged(e: ChangedEvent): void; /** * This predicate is called by #handleChanged to decide if a ChangedEvent * is not interesting enough to be remembered. * * Transactional events (of change type ChangedEvent.Transaction) are always skipped. * Changed events for GraphObjects that are in Layer#isTemporary layers are also skipped. * * Sometimes changed events do not even get to #handleChanged because * Model#skipsUndoManager or Diagram#skipsUndoManager is true. * @expose * @param {ChangedEvent} e the ChangedEvent received by #handleChanged. * @return {boolean} true to not record the change. */ skipsEvent(e: ChangedEvent): boolean; /** * This read-only property returns an iterator for all of the Models that this UndoManager is handling. * @see #addModel * @see #removeModel */ get models(): Iterator; /** * Gets or sets whether this UndoManager records any changes. * The default value is false -- you need to set this to true if * you want the user to be able to undo or redo. * * You can temporarily turn off recording by setting Diagram#skipsUndoManager * and Model#skipsUndoManager to true. */ get isEnabled(): boolean; set isEnabled(value: boolean); /** * This read-only property returns the Transaction in the #history to be undone next. * The value may be null if the UndoManager is not ready to perform an undo. * @see #transactionToRedo */ get transactionToUndo(): Transaction | null; /** * This read-only property returns the Transaction in the #history to be redone next. * The value may be null if the UndoManager is not ready to perform a redo. * @see #transactionToUndo */ get transactionToRedo(): Transaction | null; /** * This read-only property is true during a call to #undo or #redo. */ get isUndoingRedoing(): boolean; /** * This read-only property returns the whole history, a list of all of the Transactions, * each representing a transaction with some number of ChangedEvents. * * You should not modify this List. */ get history(): List; /** * Gets or sets the maximum number of transactions that this undo manager will remember. * When a transaction is committed and the number exceeds this value, * the UndoManager will discard the oldest transaction(s) in order to meet this limit. * The initial value is 999. * Any new value must be an integer. * A negative value is treated as if there were no limit. * A zero value will not remember any Transactions in the #history, * but will allow commits and rollbacks to occur normally, * including raising "Transaction" type ChangedEvents. * * This property is useful in helping limit the memory consumption of typical applications. * But this does not limit the number of ChangedEvents that are recorded, * because there may be an unlimited number of those within each Transaction. * Decreasing this value will not necessarily remove any existing Transactions * if there currently exist more in #history than the new value permits. */ get maxHistoryLength(): number; set maxHistoryLength(value: number); /** * This read-only property returns the index into #history for the current undoable Transaction. * The value is -1 if there is no undoable Transaction to be undone. */ get historyIndex(): number; /** * This read-only property returns the current Transaction for recording additional model change events. * This is initialized and augmented by #handleChanged * before it is added to #history by a top-level call * to #commitTransaction. * The value will be null between transactions. */ get currentTransaction(): Transaction | null; /** * This read-only property returns the current transaction level. * The value is zero when there is no ongoing transaction. * The initial value is zero. * #startTransaction will increment this value; * #commitTransaction or #rollbackTransaction will decrement it. * When this value is greater than zero, #canUndo * and #canRedo will be false, because * additional logically related model change events may occur. */ get transactionLevel(): number; /** * This read-only property is true after the first call to #startTransaction * and before a corresponding call to #commitTransaction or #rollbackTransaction. * * During a transaction #canUndo and #canRedo will be false. * #currentTransaction may be non-null if any ChangedEvents were recorded. */ get isInTransaction(): boolean; set checksTransactionLevel(value: boolean); /** * This read-only property returns a stack of ongoing transaction names. * The outermost transaction name will be the first item in the list. * The last one will be the name of the most recent (nested) call * to #startTransaction. * * You should not modify this List. */ get nestedTransactionNames(): List; } /** * Tools handle mouse, keyboard, and touch events. * The currently running tool, Diagram#currentTool, receives all input events from the Diagram * via canonicalized InputEvents. *

* For more discussion, see Introduction to Tools. * See samples that make use of tools in the samples index. * * Most tools are "mode-less" tools that are managed by the ToolManager, * which chooses the current tool based on the kind and position of the mouse event and the parts in the diagram. * The ToolManager has properties holding instances of most of the pre-defined Tool classes. * These classes include: * - In the ToolManager#mouseDownTools List: * - ActionTool * - RelinkingTool * - LinkReshapingTool * - RotatingTool * - ResizingTool * - In the ToolManager#mouseMoveTools List: * - LinkingTool * - DraggingTool * - DragSelectingTool * - PanningTool * - In the ToolManager#mouseUpTools List: * - ContextMenuTool * - TextEditingTool * - ClickCreatingTool * - ClickSelectingTool * * The ToolManager chooses a tool to run as the diagram's current tool by finding in its lists of tools the first tool * whose #canStart method returns true. The ToolManager then sets Diagram#currentTool to be that tool. * * A tool is in the "running" state when it is the value of Diagram#currentTool. * The Diagram#currentTool property setter will call #doStop on the old tool * and then call #doStart on the new tool. * * A tool can then go into the "active" state once it decides it can actually do something. * This happens with a call to #doActivate, normally called by the ToolManager. * Later it is deactivated (#doDeactivate) and then stopped. * #isActive should be true when the tool is "active". * Often tools should ignore certain common events, such as calls to #doMouseMove, * unless the tool #isActive. * * You can prevent a "mode-less" tool (i.e. one managed by the ToolManager) * from being started by the ToolManager by setting #isEnabled to false. * * You can also go into a particular "mode" by setting Diagram#currentTool explicitly, * thereby circumventing the normal operation of the ToolManager. * This ignores the #isEnabled property and does not call the #canStart predicate. * The behavior will depend on the tool -- not all of the predefined tools support operating as a "modal" tool. * * Tools cannot be shared amongst multiple Diagrams. * * If you define a Tool subclass, you may override any of the methods whose names start with "do" * and any other methods that are documented to be overridable, such as #canStart. * However you must seriously consider calling the base method in order to gets its default behavior. * There may be situations where not calling the base method may cause subtle bugs. * But that depends on the method and the tool. * Please read the Introduction page on Extensions for how to override methods and how to call the base method. * @unrestricted * @category Tool */ export abstract class Tool { /** * Don't construct this directly -- this is an abstract class. */ constructor(); /** * This read-only property returns the Diagram that owns this tool and * for which this tool is handling input events. */ get diagram(): Diagram; set diagram(val: Diagram); /** * The diagram asks each tool to update any adornments the tool might * use for a given part. * If the tool uses its own tool handles, * this should display them or hide them as appropriate. * Typically this should only show them if the part is selected. * * By default this method does nothing. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Part} part */ updateAdornments(part: Part): void; /** * This predicate is used by the ToolManager to decide if this tool can be started mode-lessly * by mouse and touch events. * Implementations of this method can look at Diagram#lastInput to get the mouse * event and input state. * * By default this method returns #isEnabled. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} true if #isEnabled is true and * if the Diagram#toolManager can make this tool the Diagram#currentTool and * then call the #doStart method. */ canStart(): boolean; /** * The Diagram calls this method when this tool becomes the current tool; you should not call this method. * Tool implementations should perform their per-use initialization here, such * as setting up internal data structures, or capturing the mouse. * Implementations of this method can look at Diagram#lastInput to get the mouse * event and input state. * * You should not call this method -- only the Diagram#currentTool property setter should call this method. * * By default this method does nothing. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * * If you override this method, it is commonplace to also override #doStop to clean up whatever you set up in this method. * @expose */ doStart(): void; /** * The Diagram calls this method after setting Diagram#currentTool, * to make the new tool active. * This should set #isActive to true. * Overrides of this method might call #startTransaction, * if this tool's activity involves modification of the model. * Implementations of this method can look at Diagram#lastInput to get the mouse * event and input state. * * You should call this method only after setting Diagram#currentTool to the Tool that you want to activate. * * By default this only sets #isActive to true. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * * If you override this method, it is commonplace to also override #doDeactivate to clean up whatever you set up in this method. * @expose */ doActivate(): void; /** * The Diagram calls this method on the old tool when * Diagram#currentTool is set to a new tool. * This needs to set #isActive to false. * Overrides of this method might call #stopTransaction, * if this tool's activity involves modification of the model. * * You should have no reason to call this method, because it is automatically called by the * Diagram#currentTool property setter on the old tool. * * By default this only sets #isActive to false. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * * It is commonplace to override this method in order to clean up whatever you have set up in an override of #doActivate. * @expose */ doDeactivate(): void; /** * The Diagram calls this method when this tool stops being the current tool; you should not call this method. * Tool implementations should perform their per-use cleanup here, * such as releasing mouse capture. * * You should not call this method -- only the Diagram#currentTool property setter should call this method. * If you want to stop a tool unexpectedly, you should call #doCancel. * If your implementation of a tool wants to stop itself, you should call #stopTool. * * By default this method does nothing. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * * It is commonplace to override this method in order to clean up whatever you have set up in an override of #doStart. * @expose */ doStop(): void; /** * The diagram will call this method when the user wishes to cancel the * current tool's operation. * Typically this is called when the user hits the ESCAPE key. * This should restore the original state of what was modified by this tool, and then it should call #stopTool. * This method is not responsible for cleaning up any side-effects that should be performed * by #doDeactivate and/or #doStop, which will always be called whether the tool stops normally or abnormally. * * By default this method just sets #transactionResult to null and calls #stopTool. * You will want to override this method even in tools that call #startTransaction and #stopTransaction, * because the UndoManager might not be enabled. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doCancel(): void; /** * If the Diagram#currentTool is this tool, * stop this tool and start the Diagram#defaultTool * by making it be the new current tool. * The implementation of various tool methods can call this method to stop the current tool. * This will call #doStop -- you should not call that method directly. * * If you want to stop the current tool and have it restore the original state, call #doCancel. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ stopTool(): void; /** * The diagram will call this method upon a mouse down event. * This is normally overridden for mouse-down tools; * it is not called for mouse-move or mouse-up tools. * However it may also be called when the tool is run in a modal fashion, * when code explicitly sets the diagram's Diagram#currentTool. * Implementations of this method can look at Diagram#lastInput to get the mouse * event and input state. * * By default this method checks #isActive; if that is false it calls #canStart. * If that in turn is true, this calls #doActivate. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doMouseDown(): void; /** * The diagram will call this method upon a mouse move event. * This is normally overridden for mouse-move tools; * it is not called for mouse-up tools. * However it may also be called when the tool is run in a modal fashion, * when code explicitly sets the diagram's Diagram#currentTool. * An override of this method usually does nothing when #isActive is false. * Implementations of this method can look at Diagram#lastInput to get the mouse * event and input state. * * By default this method does nothing. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doMouseMove(): void; /** * The diagram will call this method upon a mouse up event. * This is normally overridden for mouse-up tools. * An override of this method usually does nothing when #isActive is false, * except for calling #stopTool. * Tools normally stop upon a mouse up, by calling #stopTool. * If you want to handle multiple mouse down-up gestures in one tool activation, * you will need to override this method to only stop the tool when you want. * Implementations of this method can look at Diagram#lastInput to get the mouse * event and input state. * * By default this method just calls #stopTool. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doMouseUp(): void; /** * The diagram will call this method as the mouse wheel is rotated. * Implementations of this method can look at Diagram#lastInput to get the mouse * event and input state. * * By default this method does nothing. * (But the ToolManager#doMouseWheel override will call Tool#standardMouseWheel.) * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doMouseWheel(): void; /** * Called by ToolManager#doMouseDown and ToolManager#doMouseMove, * this method determines whether or not to allow pinch zooming from a multi-touch event. * By default this predicate just returns true. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} * @see #standardPinchZoomStart * @see #standardPinchZoomMove * @since 1.5 */ canStartMultiTouch(): boolean; /** * Initiates pinch-zooming on multi-touch devices. * * This is called by ToolManager#doMouseDown if the Diagram#lastInput has InputEvent#isMultiTouch * set to true and #canStartMultiTouch returns true. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @see #canStartMultiTouch * @see #standardPinchZoomMove * @since 1.5 */ standardPinchZoomStart(): void; /** * Continues pinch-zooming (started by #standardPinchZoomStart on multi-touch devices. * * This is called by ToolManager#doMouseMove if the Diagram#lastInput has InputEvent#isMultiTouch * set to true and #canStartMultiTouch returns true. * By default this calls #doCancel in order to cancel the regular tool behavior caused by the multitouch events. * This then calculates the appropriate zoom level and calls CommandHandler#canResetZoom to decide * whether to call CommandHandler#resetZoom to actually set Diagram#scale. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @see #canStartMultiTouch * @see #standardPinchZoomStart * @since 1.5 */ standardPinchZoomMove(): void; /** * The diagram will call this method upon a key down event. * By default this just calls #doCancel if the key is the ESCAPE key. * Implementations of this method can look at Diagram#lastInput to get the key. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doKeyDown(): void; /** * The diagram will call this method upon a key up event. * Implementations of this method can look at Diagram#lastInput to get the key. * * By default this method does nothing. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doKeyUp(): void; /** * Call Diagram#startTransaction with the given transaction name. * This always sets #transactionResult to null. * * This is normally called in an override of #doActivate, if the tool modifies the model, * along with a call to #stopTransaction in an override of #doDeactivate. * Alternatively, you can surround a block of code that sets the #transactionResult * with calls to startTransaction and stopTransaction. * @param {string=} tname a string describing the transaction. * @return {boolean} the value of the call to Diagram#startTransaction. */ startTransaction(tname?: string): boolean; /** * If #transactionResult is null, call Diagram#rollbackTransaction, * otherwise call Diagram#commitTransaction. * * This is normally called in an override of #doDeactivate, * if #startTransaction was called in #doActivate. * Alternatively, you can surround a block of code that sets the #transactionResult * with calls to `startTransaction` and `stopTransaction`. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} the result of the call to rollback or commit the transaction. */ stopTransaction(): boolean; /** * Implement the standard behavior for selecting parts with the mouse, * depending on the control and shift modifier keys. * * Control-clicking on a part will select it if it wasn't already, * and will deselect if it had been selected. * Shift-clicking on a part will add it to the selection (if it wasn't already). * Otherwise, clicking on a part will select it (if it wasn't already). * * Note that there are restrictions on selection. * For example, a part cannot be selected in this manner if Part#selectable is false, * or if Diagram#maxSelectionCount would be exceeded. * * A left click in the background of the diagram with no modifier keys clears the selection. * * This method does not implement any click event behavior -- that is implemented by #standardMouseClick. * * The ClickSelectingTool calls this method in its override of #doMouseUp in order to change the selection. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ standardMouseSelect(): void; /** * Implement the standard behavior for mouse clicks, * searching for and calling click handler functions on GraphObjects * or on Diagram, * and raising the corresponding DiagramEvent. * * A click on a GraphObject of the diagram will raise one of the following DiagramEvents: * "ObjectSingleClicked", "ObjectDoubleClicked", or "ObjectContextClicked". * This will also look at the corresponding click property: * GraphObject#click, GraphObject#doubleClick, or GraphObject#contextClick. * If the value is a function, this will call it, passing the current InputEvent * and the GraphObject. * If the value is null, it tries looking at the parent GraphObject#panel, * and so on, walking up the visual tree until it finds the appropriate function to call. * After calling the click function, if the value of InputEvent#handled is false, * this method will continue walking up the visual tree looking for more click functions * to call. * Once it has looked at the top-level object (a Part) * for a click function, this method stops. * * A click in the background of the diagram will raise one of the following DiagramEvents: * "BackgroundSingleClicked", "BackgroundDoubleClicked", or "BackgroundContextClicked". * This will also look at the corresponding click property: * Diagram#click, Diagram#doubleClick, or Diagram#contextClick. * If the value is a function, this will call it, passing the current InputEvent. * * This method is not responsible for selecting or deselecting any parts. * Call #standardMouseSelect for that functionality. * * Note that this calls GraphObject#isEnabledObject on the target object; * if it returns false, no click action will occur. * * The ClickSelectingTool calls this method in its override of #doMouseUp in order to raise "click" events. * Note that by default GraphObjects in Layers that are Layer#isTemporary will not be "clicked". * To change that behavior it is easiest to set GraphObject#isActionable to true on those objects for which you wish to handle "click" events. * Then the ActionTool's #doMouseUp override will raise the standard "click" events. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {function(GraphObject):GraphObject | null=} navig An optional custom navigation * function to find target objects. * @param {function(GraphObject):boolean | null=} pred An optional custom predicate * function to find target objects. No value means that only objects in layers holding permanent objects. * @return {boolean} true if InputEvent#handled had been set to true on the Diagram#lastInput. */ standardMouseClick(navig?: (a: GraphObject) => (T | null), pred?: (a: T) => boolean): boolean; /** * Implement the standard behavior for mouse enter, over, and leave events, * where the mouse is moving but no button is pressed. * This should be called by mouse move event handlers when wanting to * detect and invoke mouse enter/over/leave event handlers. * * The GraphObject#mouseEnter property provides a function to call * when the mouse first enters an object or any of its contained objects * (if the object is actually a Panel). * * The GraphObject#mouseLeave property provides a function to call * when the mouse leaves an object and all of its contained objects * (if the object is actually a Panel). * * The GraphObject#mouseOver property and Diagram#mouseOver * properties provide functions to call when the mouse moves but stays * within the same GraphObject or when the mouse moves in the * background of the Diagram. * * This method is also responsible for updating the Diagram#currentCursor * according to the value of GraphObject#cursor and Diagram#defaultCursor. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ standardMouseOver(): void; /** * Implement the standard behavior for mouse wheel events. * ToolManager#doMouseWheel calls this method. * * Turning the mouse wheel if Diagram#allowVerticalScroll is true * causes the diagram to scroll up or down. * If InputEvent#shift and Diagram#allowHorizontalScroll are true, * the diagram scrolls left or right. * * If InputEvent#control and Diagram#allowZoom are true, * turning the mouse wheel changes the diagram's scale, * zooming in or out while trying to keep the point in the model * at the same point as the mouse. * * The value of ToolManager#mouseWheelBehavior affects what operations might occur * upon mouse wheel events. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ standardMouseWheel(): void; /** * This is called to start a new timer to call #doWaitAfter after a given delay. * It first cancels any previously running "WaitAfter" timer, by calling #cancelWaitAfter. * * This is normally used to implement mouse hover and mouse hold events. * If the mouse has moved, it must not have moved beyond the distance as determined by * Tool#isBeyondDragSize for it be considered "stationary". * So the regular ToolManager#doMouseMove implementation only calls * this method when the mouse has moved beyond the drag size. * * This method is rarely overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {number} delay The delay, in milliseconds. * @param {InputEvent=} event An optional event that caused this timer. Defaults to Diagram#lastInput. * This gets passed on to #doWaitAfter. */ standardWaitAfter(delay: number, event?: InputEvent): void; /** * This is called to cancel any running "WaitAfter" timer. * * This is called when a tool is stopped. * * This method is rarely overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ cancelWaitAfter(): void; /** * This is called a certain delay after a call to #standardWaitAfter if there * has not been any call to #cancelWaitAfter. * The ToolManager overrides this method in order to implement support for mouse-hover behavior and tooltips. * * By default this does nothing. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {InputEvent} event The event that caused #standardWaitAfter. */ doWaitAfter(event: InputEvent): void; /** * This convenience function finds the front-most GraphObject * that is at a given point and that is an element of an Adornment * that is of a given category. * The tool handle must be an immediate element of the Adornment, * not a GraphObject that is nested within Panels within the Adornment. * * This method is very infrequently overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Point} p a Point in document coordinates. * @param {string} category the required Part#category of the Adornment. * @return {GraphObject} */ findToolHandleAt(p: Point, category: string): GraphObject | null; /** * Return true when the last mouse point is far enough away from the first mouse down point * to constitute a drag operation instead of just a potential click. * * This uses the value of ToolManager#dragSize. * On touch devices the value is automatically increased to accommodate the unavoidable movement of fingers. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Point=} first Point in view coordinates, defaults to Diagram#firstInput's InputEvent#viewPoint. * @param {Point=} last Point in view coordinates, defaults to Diagram#lastInput's InputEvent#viewPoint. * @return {boolean} */ isBeyondDragSize(first?: Point, last?: Point): boolean; /** * Gets or sets the name of this tool. * The default name is an empty string, * but the constructor for each instance of a subclass of Tool will initialize it appropriately. * For example, the name of the DragSelectingTool is "DragSelecting". * * This name is sometimes used by tools that use Adornments as the Part#category for their Adornments. * It is also sometimes used by tools that conduct transactions as the transaction name. */ get name(): string; set name(value: string); /** * Gets or sets whether this tool can be started by a mouse event. * * Set this to false to prevent #canStart from returning true. * Setting this property to false should prevent this tool from being used in a mode-less fashion * by the ToolManager with a mouse down/move/up event. * However, even when this property is false, this tool can still be used in a modal fashion: * it can still be started by explicitly setting the * Diagram#currentTool property to this tool. * * The default value is true. */ get isEnabled(): boolean; set isEnabled(value: boolean); /** * Gets or sets whether this tool is started and is actively doing something. * * You can set this to true after your tool is started (i.e. when it is the * Diagram#currentTool and #doStart * had been called), but when it is not yet in a state * that it is actually "doing" something, because it is waiting for the right * circumstances. This is typically only important when the tool is used in * a modal fashion. * * The default value is false. * This is normally set by #doActivate and #doDeactivate. */ get isActive(): boolean; set isActive(value: boolean); /** * Gets or sets the name of the transaction to be committed by #stopTransaction * * If null, the transaction will be rolled back. * * If this is non-null at the time of a call to #stopTransaction, * it calls Diagram#commitTransaction with this transaction name; * if this is null at that time, it calls Diagram#rollbackTransaction. * * The default value is null; #startTransaction will also set this to null. * Because a value of null when #stopTransaction is called will rollback the transaction, * it is important that your code sets this property to a non-null value when it thinks it has succeeded. * * This property exists so that no matter what execution path occurs to end the usage of a tool, * any ongoing transaction can be properly committed or rolled-back. * Many tools call #startTransaction and #stopTransaction; thus they set this property * for their transaction to be committed. * #doCancel also sets this property to null. */ get transactionResult(): string | null; set transactionResult(value: string | null); } /** * This special Tool is responsible for managing all of the Diagram's * mode-less tools, which you can access as the Diagram#toolManager. * * Mode-less tools are tools that are present in one of the following lists: * #mouseDownTools, #mouseMoveTools, or #mouseUpTools. * This ToolManager tool is normally the Diagram#defaultTool, * so it is also usually the Diagram#currentTool when the user is doing "nothing". * * When this tool is running as the current tool, it handles mouse-down, * mouse-move, and mouse-up events and the corresponding touch events. * For each event it iterates over each of the tools in the corresponding list, * calling the tool's Tool#canStart predicate. * If that predicate returns true, it starts that tool by making it the * diagram's current tool. * It then activates the tool and passes on the event to the tool by calling * the corresponding method (either Tool#doMouseDown, * Tool#doMouseMove, or Tool#doMouseUp). * * Because this tool is typically the one running as the diagram's current tool * when the user isn't "doing" anything, this tool can also handle other events, * such as mouse wheel events and keyboard commands. * * Keyboard events are just passed on to the Diagram#commandHandler's * CommandHandler#doKeyDown or CommandHandler#doKeyUp method. * * This tool also is responsible for showing tooltips. * Tooltip Adornments may be declared as any GraphObject#toolTip, * or as the Diagram#toolTip if the mouse or finger remains motionless in the background of the diagram. * You can set #toolTipDuration to control how long the tooltip remains visible after being motionless. * * This tool does not utilize any tool handles. * This tool does not conduct any transactions. * But of course some of the tools that the ToolManager starts can show tool handles and/or * conduct their own transactions. * @extends Tool * @unrestricted * @category Tool */ export class ToolManager extends Tool { /** * You do not normally need to create an instance of this tool * because one already exists as the Diagram#toolManager, which you can modify. * * The Tool#name of this tool is "ToolManager". * * The constructor produces a ToolManager that manages no tools. * Call #initializeStandardTools to create various tools, * initialize the tool properties such as #draggingTool, * and initialize the three mouse tool lists with those newly created tools. */ constructor(); /** * This default value for #mouseWheelBehavior indicates that mouse wheel events scroll the diagram. * @constant */ static WheelScroll: EnumValue; /** * This value for #mouseWheelBehavior indicates that the mouse wheel events change the scale of the diagram. * @constant */ static WheelZoom: EnumValue; /** * This value for #mouseWheelBehavior indicates that the mouse wheel events are ignored, * although scrolling or zooming by other means may still be allowed. * @constant * @since 1.2 */ static WheelNone: EnumValue; /** * This value for #gestureBehavior indicates that the pointer/touch pinch gestures * on the canvas intend to zoom the Diagram. * @constant * @since 1.5 */ static GestureZoom: EnumValue; /** * This value for #gestureBehavior indicates that the pointer/touch pinch gestures * on the canvas intend to have no effect on the Diagram, but also no effect on the page. * @constant * @since 1.5 */ static GestureCancel: EnumValue; /** * This value for #gestureBehavior indicates that the pointer/touch pinch gestures * on the canvas intend to have no effect on the Diagram, but will not be prevented, * and may bubble up the page to have other effects (such as zooming the page). * @constant * @since 1.5 */ static GestureNone: EnumValue; /** * Gets or sets the ToolManager's mouse wheel behavior. Allowed values are ToolManager.WheelScroll and * ToolManager.WheelZoom and ToolManager.WheelNone. * * The default value is ToolManager.WheelScroll. */ get mouseWheelBehavior(): EnumValue; set mouseWheelBehavior(value: EnumValue); /** * Gets or sets the ToolManager's touch pinching behavior. * Allowed values are ToolManager.GestureZoom and * ToolManager.GestureCancel and ToolManager.GestureNone. * The default value is ToolManager.GestureZoom. * * If you want to control whether a single finger touch movement * causes a pan (i.e. scroll) of the diagram's contents or scrolls the page, * consider either disabling the PanningTool by setting its property * Tool#isEnabled to false or by setting PanningTool#bubbles to true. * * @since 1.5 */ get gestureBehavior(): EnumValue; set gestureBehavior(value: EnumValue); /** * Initialize the three mouse tool lists with instances of the standard tools. * This adds new instances of tools to the following three mouse tool lists: * #mouseDownTools, #mouseMoveTools, or #mouseUpTools. * This also sets the various tool properties of this ToolManager * to those newly created tools. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ initializeStandardTools(): void; /** * Iterate over the #mouseDownTools list and start the first tool * for which its Tool#canStart predicate returns true. * * Starting a tool replaces the Diagram#currentTool with the new tool. * Successfully doing so also activates the new tool by calling Tool#doActivate * and passes on the mouse-down event to it by calling Tool#doMouseDown. * * Not finding any startable tools causes this tool manager to activate, * thereby enabling the mouse-move and mouse-up behaviors and starts * detection of a mouse-hold event after #holdDelay milliseconds. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doMouseDown(): void; /** * Iterate over the #mouseMoveTools list and start the first tool * for which its Tool#canStart predicate returns true. * * Starting a tool replaces the Diagram#currentTool with the new tool. * Successfully doing so also activates the new tool by calling Tool#doActivate * and passes on the mouse-move event to it by calling Tool#doMouseMove. * * If no tool is found and activated, this: * - Calls Tool#standardMouseOver to invoke any mouse-enter, mouse-over, or mouse-leave functions. * - if the mouse has moved sufficiently, such that Tool#isBeyondDragSize is true, * this also calls Tool#standardWaitAfter for a possible call to * #doWaitAfter after #hoverDelay milliseconds. * - Sets the Diagram#lastInput to bubble. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doMouseMove(): void; /** * Implement the standard behavior for when the mouse has not moved for a period of time. * This is due to an expired timer started by calling Tool#standardWaitAfter. * * This calls #doMouseHover and, if not mouse-down, #doToolTip. * Afterwards, if the event that called Tool#standardWaitAfter was a touch event, * this simulates a right click, enabling context menu functionality and other actions on touch devices. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {InputEvent} event The event that caused #standardWaitAfter. In this override, * if it is a touch event and the Diagram#lastInput event is not handled (InputEvent#handled set to false), * then this method will simulate a right click. */ doWaitAfter(event: InputEvent): void; /** * Implement the standard behavior for mouse hover and mouse hold events, * called by #doWaitAfter when the mouse has not moved for a period of time. * * If there has been no mouse down, the timer is set for #hoverDelay milliseconds. * If it executes, it calls any GraphObject#mouseHover function on the object * at the mouse or on any of its containing panels, * or it calls any Diagram#mouseHover function for a background mouse-hover event. * * If there had been a mouse down, the timer is set for #holdDelay milliseconds. * If it executes, it calls any GraphObject#mouseHold function on the object * at the mouse or on any of its containing panels, * or it calls any Diagram#mouseHold function for a background mouse-held-down event. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doMouseHover(): void; /** * Implement the standard behavior for tooltips, * called by #doWaitAfter when the mouse has not moved for a period of time. * * This looks for a GraphObject at the latest mouse point. * If it finds an object, it checks for a GraphObject#toolTip. * If it has none, this method searches up the visual tree for a containing * Panel that does have a tooltip. * * If it didn't find any object, this looks for a Diagram#toolTip. * * If it eventually finds a tooltip, this calls #showToolTip. * Otherwise this calls #hideToolTip. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doToolTip(): void; /** * Show a tooltip Adornment or HTMLInfo. * This is called by #doToolTip once that method has found a tooltip to display. * * This calls #positionToolTip to make it easier to customize how the tooltip * is positioned relative to the object with the tooltip. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Adornment|HTMLInfo} tooltip * @param {GraphObject} obj The GraphObject getting the tooltip; this is null if the tooltip is being shown for the diagram background. */ showToolTip(tooltip: Adornment | HTMLInfo, obj: GraphObject): void; /** * This is called by #showToolTip to position the part within the viewport. * It normally goes just below the cursor. * But if the mouse is too close to the right edge or the bottom edge of the viewport, * it is positioned left and/or above the cursor. * * This method only operates if the tooltip, an Adornment, does not have a Adornment#placeholder. * When there is a Placeholder in the tooltip, that Adornment is automatically positioned * so that the Placeholder is positioned at the adorned object, the second argument to this method. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * * If you override this method to position the tooltip, * the tooltip has already been measured but not arranged, * so you can use its GraphObject#measuredBounds width and height * but not its GraphObject#actualBounds. * @expose * @param {Adornment} tooltip * @param {GraphObject} obj The GraphObject getting the tooltip, * or null if the tooltip is for the diagram background. */ positionToolTip(tooltip: Adornment, obj: GraphObject): void; /** * Hide any tooltip. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ hideToolTip(): void; /** * This read-only property returns the currently showing tooltip, or null if there is none. */ get currentToolTip(): Adornment | HTMLInfo | null; set currentToolTip(value: Adornment | HTMLInfo | null); /** * Iterate over the #mouseUpTools list and start the first tool * for which its Tool#canStart predicate returns true. * * Starting a tool replaces the Diagram#currentTool with the new tool. * Successfully doing so also activates the new tool by calling Tool#doActivate * and passes on the mouse-up event to it by calling Tool#doMouseUp. * * If no startable tool is found it deactivates this tool manager, * to get ready for a mouse-down and ignore mouse-move and mouse-up events. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doMouseUp(): void; /** * The diagram will call this method as the mouse wheel is rotated. * * By default this just calls Tool#standardMouseWheel. * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doMouseWheel(): void; /** * This just calls CommandHandler#doKeyDown on the diagram's Diagram#commandHandler. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doKeyDown(): void; /** * This just calls CommandHandler#doKeyUp on the diagram's Diagram#commandHandler. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doKeyUp(): void; /** * Find a mouse tool of a given name. * This searches the #mouseDownTools, #mouseMoveTools, and #mouseUpTools lists. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {string} name the type of tool, such as "Dragging" or "ClickSelecting". * @return {Tool} a Tool whose Tool#name exactly matches the given name, * or null if no such tool is found in any of the three lists. */ findTool(name: string): Tool | null; /** * Replace a mouse tool of a given name with a new tool, or remove an existing tool (if the *newtool* is null). * This searches the #mouseDownTools, #mouseMoveTools, * and #mouseUpTools lists. * The new tool is inserted into the same list in which the same-named tool is found, * at the same position as the old tool. * However, if no existing tool with the given name is present, this does **not** add the new tool to any list, since it cannot know where it should be added. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {string} name the type of tool, such as "Dragging" or "ClickSelecting". * @param {Tool} newtool If null, any tool that the search finds will just be removed * from the list in which it was found. * @return {Tool} the old tool that was replaced by the new one; this is null if none was found and the new tool was not added to any mouse tool list */ replaceTool(name: string, newtool: Tool): Tool | null; /** * (undocumented) * @param {string} name * @param {Tool} newtool * @param {List.} list */ replaceStandardTool(name: string, newtool: Tool, list: List): void; /** * This read-only property returns the list of Tools that might be started upon a mouse or finger press event. * When the ToolManager handles a mouse-down or touch-down event in #doMouseDown, * it searches this list in order, starting the first tool for which * Tool#canStart returns true. * * This list may be modified, but it must not be modified while any tool * is handling events. * * #initializeStandardTools installs the following tools, in order: * - #actionTool, an ActionTool * - #relinkingTool, a RelinkingTool * - #linkReshapingTool, a LinkReshapingTool * - #rotatingTool, a RotatingTool * - #resizingTool, a ResizingTool */ get mouseDownTools(): List; /** * This read-only property returns the list of Tools that might be started upon a mouse or finger move event. * When the ToolManager handles a mouse-move or touch-move event in #doMouseMove, * it searches this list in order, starting the first tool for which * Tool#canStart returns true. * * This list may be modified, but it must not be modified while any tool * is handling events. * * #initializeStandardTools installs the following tools, in order: * - #linkingTool, a LinkingTool * - #draggingTool, a DraggingTool * - #dragSelectingTool, a DragSelectingTool * - #panningTool, a PanningTool */ get mouseMoveTools(): List; /** * This read-only property returns the list of Tools that might be started upon a mouse or finger up event. * When the ToolManager handles a mouse-up or touch-up event in #doMouseUp, * it searches this list in order, starting the first tool for which * Tool#canStart returns true. * * This list may be modified, but it must not be modified while any tool * is handling events. * * #initializeStandardTools installs the following tools, in order: * - #contextMenuTool, a ContextMenuTool * - #textEditingTool, a TextEditingTool * - #clickCreatingTool, a ClickCreatingTool * - #clickSelectingTool, a ClickSelectingTool */ get mouseUpTools(): List; /** * Gets or sets the time between when the mouse stops moving and a hover event, * in milliseconds. This value affects the delay before GraphObject#toolTips are shown. * The default value is 850 milliseconds. * * Set #toolTipDuration to control how long a tooltip will remain visible. */ get hoverDelay(): number; set hoverDelay(value: number); /** * Gets or sets the time between when the mouse stops moving and a hold event, * in milliseconds. * The default value is 850 milliseconds. */ get holdDelay(): number; set holdDelay(value: number); /** * Gets or sets the distance in view coordinates within which a mouse down-and-up is considered a click and beyond which a mouse movement is considered a drag. * The default value is 2 pixels horizontally and vertically for mouse events, and increases by 6 pixels for touch events. * This value is used by Tool#isBeyondDragSize. * @since 1.2 */ get dragSize(): Size; set dragSize(value: Size); /** * Gets or sets how long a tool tip is visible. * The default value is 5000 milliseconds. * * This is used by #showToolTip to determine how long to wait before calling #hideToolTip. * * Set #hoverDelay to control how long the mouse should stay stationary before it shows a tooltip. */ get toolTipDuration(): number; set toolTipDuration(value: number); /** * Gets or sets the mode-less ActionTool, normally one of the #mouseDownTools. * * You can disable this tool by setting its Tool#isEnabled property to false. */ get actionTool(): ActionTool; set actionTool(value: ActionTool); /** * Gets or sets the mode-less RelinkingTool, normally one of the #mouseDownTools. * * You can disable this tool by setting its Tool#isEnabled property to false. */ get relinkingTool(): RelinkingTool; set relinkingTool(value: RelinkingTool); /** * Gets or sets the mode-less LinkReshapingTool, normally one of the #mouseDownTools. * * You can disable this tool by setting its Tool#isEnabled property to false. */ get linkReshapingTool(): LinkReshapingTool; set linkReshapingTool(value: LinkReshapingTool); /** * Gets or sets the mode-less ResizingTool, normally one of the #mouseDownTools. * * You can disable this tool by setting its Tool#isEnabled property to false. */ get resizingTool(): ResizingTool; set resizingTool(value: ResizingTool); /** * Gets or sets the mode-less RotatingTool, normally one of the #mouseDownTools. * * You can disable this tool by setting its Tool#isEnabled property to false. */ get rotatingTool(): RotatingTool; set rotatingTool(value: RotatingTool); /** * Gets or sets the mode-less LinkingTool, normally one of the #mouseMoveTools. * * You can disable this tool by setting its Tool#isEnabled property to false. */ get linkingTool(): LinkingTool; set linkingTool(value: LinkingTool); /** * Gets or sets the mode-less DraggingTool, normally one of the #mouseMoveTools. * * You can disable this tool by setting its Tool#isEnabled property to false. */ get draggingTool(): DraggingTool; set draggingTool(value: DraggingTool); /** * Gets or sets the mode-less DragSelectingTool, normally one of the #mouseMoveTools. * * You can disable this tool by setting its Tool#isEnabled property to false. */ get dragSelectingTool(): DragSelectingTool; set dragSelectingTool(value: DragSelectingTool); /** * Gets or sets the mode-less PanningTool, normally one of the #mouseMoveTools. * * You can disable this tool by setting its Tool#isEnabled property to false. */ get panningTool(): PanningTool; set panningTool(value: PanningTool); /** * Gets or sets the mode-less ContextMenuTool, normally one of the #mouseUpTools. * * You can disable this tool by setting its Tool#isEnabled property to false. */ get contextMenuTool(): ContextMenuTool; set contextMenuTool(value: ContextMenuTool); /** * Gets or sets the mode-less TextEditingTool, normally one of the #mouseUpTools. * * You can disable this tool by setting its Tool#isEnabled property to false. */ get textEditingTool(): TextEditingTool; set textEditingTool(value: TextEditingTool); /** * Gets or sets the mode-less ClickCreatingTool, normally one of the #mouseUpTools. * * You can disable this tool by setting its Tool#isEnabled property to false. */ get clickCreatingTool(): ClickCreatingTool; set clickCreatingTool(value: ClickCreatingTool); /** * Gets or sets the mode-less ClickSelectingTool, normally one of the #mouseUpTools. * * You can disable this tool by setting its Tool#isEnabled property to false. */ get clickSelectingTool(): ClickSelectingTool; set clickSelectingTool(value: ClickSelectingTool); } /** * The DraggingTool is used to move or copy selected parts with the mouse. * This sets the Part#location property; you may want to save the location to the model * by using a TwoWay Binding on the "location" property in your Parts/Nodes/Groups templates. * * Dragging the selection moves parts for which Part#canMove is true. * If the user holds down the Control key (Option key on Mac), this tool will make a copy of the parts being dragged, * for those parts for which Part#canCopy is true. * * When the drag starts it calls #computeEffectiveCollection to find the actual collection * of Parts to be dragged. * Normally this collection includes not only the Diagram#selection, but also parts that belong * to those selected parts, such as members of groups. * If #dragsTree is true, the effective collection also includes all of the nodes and links that * constitute the subtree starting from selected nodes. * The result of #computeEffectiveCollection is not a Set but a Map * which remembers the original Part#location for all of the dragged parts. * This map is saved as the value of #draggedParts. * * During the drag if the user holds down the Control/Option key this tool makes a copy of the #draggedParts * and proceeds to drag it around. * (It only copies the Diagram#selection, not the whole effective collection, * if #copiesEffectiveCollection is false.) * The collection of copied parts is held by #copiedParts. * It too is a Map remembering the original locations of the parts. * #copiedParts will be null when this tool is moving (not copying) at the moment. * * Each Part's movement is limited by the Diagram#computeMove method. * By default it limits the Part#location to be within the bounds given by Part#minLocation and Part#maxLocation. * (Those default to minus Infinity to plus Infinity.) * As a further convenience, the value of NaN in minLocation and maxLocation cause Diagram#computeMove to use the * part's current location. * So, for example, an easy way to declare that the user may only drag a node horizontally is to just set: * ```js * $(go.Node, * . . . * { minLocation: new go.Point(-Infinity, NaN), maxLocation: new go.Point(Infinity, NaN) }, * . . . * ) * ``` * * If you set #isGridSnapEnabled to true, dragged or copied parts will be snapped to points on a grid. * The snapping occurs continuously during a drag unless you set #isGridSnapRealtime to false. * Normally the grid points come from the Diagram#grid, even if that grid is not GraphObject#visible. * However you can override those grid's properties for the snapping grid cell size and offset * by setting the properties here: #gridSnapCellSize and #gridSnapOrigin. * This computes the point to snap to for each dragged part. * The resulting point is used as the new Part#location. * * For the most general control over where a part may be dragged, either set the Part#dragComputation property * or override Diagram#computeMove. * For the common case of wanting to keep member nodes within the Group that they are members of, * you can do something like: * ```js * // this is a Part.dragComputation function for limiting where a Node may be dragged * function stayInGroup(part, pt, gridpt) { * // don't constrain top-level nodes * var grp = part.containingGroup; * if (grp === null) return pt; * // try to stay within the background Shape of the Group * var back = grp.resizeObject; * if (back === null) return pt; * // allow dragging a Node out of a Group if the Shift key is down * if (part.diagram.lastInput.shift) return pt; * var p1 = back.getDocumentPoint(go.Spot.TopLeft); * var p2 = back.getDocumentPoint(go.Spot.BottomRight); * var b = part.actualBounds; * var loc = part.location; * // find the padding inside the group's placeholder that is around the member parts * var m = grp.placeholder.padding; * // now limit the location appropriately, assuming no grid-snapping * var x = Math.max(p1.x + m.left, Math.min(pt.x, p2.x - m.right - b.width - 1)) + (loc.x-b.x); * var y = Math.max(p1.y + m.top, Math.min(pt.y, p2.y - m.bottom - b.height - 1)) + (loc.y-b.y); * return new go.Point(x, y); * } * ``` * Note that this expects there to be a "SHAPE" object within the Group's visual tree that delimits * where the part may be dragged within the group. * This also expects that Group#computesBoundsIncludingLinks is false. * Then in your node template(s), just set: * ```js * $(go.Node, * . . ., * { dragComputation: stayInGroup }, * . . . * ) * ``` * * This tool does not utilize any Adornments or tool handles. * If the drag is successful, it raises the "SelectionMoved" or "SelectionCopied" DiagramEvent * and produces a "Move" or a "Copy" transaction. * * If you want to programmatically start a new user's dragging of a particular existing node, * you can make sure that node is selected, set the #currentPart property, and then start and activate the tool. * ```js * var node = ...; * myDiagram.select(node); // in this case the only selected node * var tool = myDiagram.toolManager.draggingTool; * tool.currentPart = node; // the DraggingTool will not call standardMouseSelect * myDiagram.currentTool = tool; // starts the DraggingTool * tool.doActivate(); // activates the DraggingTool * ``` * @extends Tool * @unrestricted * @category Tool */ export class DraggingTool extends Tool { /** * You do not normally need to create an instance of this tool * because one already exists as the ToolManager#draggingTool, which you can modify. * * The Tool#name of this tool is "Dragging". */ constructor(); /** * Gets or sets whether for any internal copying operation is permitted by control-drag-and-drop. * This property affects the behavior of #mayCopy, * but does not affect whether copied objects may be dropped into this diagram from a different diagram. * * The default value is true. * Setting this property does not raise any events. * @since 1.4 */ get isCopyEnabled(): boolean; set isCopyEnabled(value: boolean); /** * Gets or sets whether for a copying operation the extended selection * is copied or only the selected parts. * The default value is true. * Setting this property does not raise any events. * * The CommandHandler#copiesConnectedLinks property serves a similar role for the CommandHandler#copySelection command, * when the user types control-C to copy the currently selected parts. */ get copiesEffectiveCollection(): boolean; set copiesEffectiveCollection(value: boolean); /** * Gets or sets the DraggingTool's DraggingOptions instance, which controls several dragging properties. * * Several DraggingTool properties are just convenience properties: * - #isGridSnapEnabled * - #isGridSnapRealtime * - #gridSnapCellSize * - #gridSnapCellSpot * - #gridSnapOrigin * - #dragsLink * - #dragsTree * * Setting any of these properties really sets the corresponding dragOptions property. * * Setting this property does not raise any events. * @since 2.0 */ get dragOptions(): DraggingOptions; set dragOptions(value: DraggingOptions); /** * Gets or sets whether the DraggingTool snaps objects to grid points. * Whether the snapping movement of the dragged parts occurs during the drag or only upon a drop * is determined by the value of #isGridSnapRealtime. * * This property does not affect dragging disconnected links, * but those links to respect the Part#dragComputation, which can be used to snap them. * * By default this property is false. * Setting this property does not raise any events. * * This property is a convenience getter/setter, and sets a value on #dragOptions. */ get isGridSnapEnabled(): boolean; set isGridSnapEnabled(value: boolean); /** * Gets or sets whether link routing takes some short-cuts during dragging. * When false Links whose routing is AvoidsNodes are not routed to avoid Nodes, in order to improve dragging performance. * The default value is true. * @since 1.4 */ get isComplexRoutingRealtime(): boolean; set isComplexRoutingRealtime(value: boolean); /** * Gets or sets whether the DraggingTool snaps objects to grid points during the drag. * This property is ignored unless #isGridSnapEnabled is true. * By default this property is true; when false parts are only snapped to grid locations upon the drop (i.e. mouse-up). * Setting this property does not raise any events. * * This property is a convenience getter/setter, and sets a value on #dragOptions. * @since 1.1 */ get isGridSnapRealtime(): boolean; set isGridSnapRealtime(value: boolean); /** * Gets or sets the size of the grid cell used when snapping during a drag * if the value of #isGridSnapEnabled is true. * By default this property is the Size(NaN, NaN), which causes this tool to use the Panel#gridCellSize value of the Diagram#grid. * Setting this property does not raise any events. * * This property is a convenience getter/setter, and sets a value on #dragOptions. */ get gridSnapCellSize(): Size; set gridSnapCellSize(value: Size); /** * Gets or sets the Spot that specifies what point in the grid cell dragged parts snap to, * if the value of #isGridSnapEnabled is true. * By default this property is Spot.TopLeft: * node locations will snap exactly to the grid point. * Setting this property does not raise any events. * * This property is a convenience getter/setter, and sets a value on #dragOptions. */ get gridSnapCellSpot(): Spot; set gridSnapCellSpot(value: Spot); /** * Gets or sets the snapping grid's origin point, in document coordinates, * if the value of #isGridSnapEnabled is true. * By default this property is the Point(NaN, NaN), * which causes this tool to use the Panel#gridOrigin value from the Diagram#grid. * Setting this property does not raise any events. * * This property is a convenience getter/setter, and sets a value on #dragOptions. */ get gridSnapOrigin(): Point; set gridSnapOrigin(value: Point); /** * Gets or sets whether the user can drag a single Link, * disconnecting it from its connected nodes and possibly connecting it * to valid ports when the link is dropped. * The default value is false. * Setting this property does not raise any events. * * In order to avoid too many cases of having both ends of a dragged Link connect to the same node (if allowed), * it is commonplace to decrease the LinkingBaseTool#portGravity to a smaller value such as 10 or 20. * * This property is a convenience getter/setter, and sets a value on #dragOptions. * @since 1.3 */ get dragsLink(): boolean; set dragsLink(value: boolean); /** * Gets or sets whether moving or copying a node also includes all of the * node's tree children and their descendants, along with the links to those additional nodes. * The default value is false. * Setting this property does not raise any events. * * The CommandHandler#copiesTree property serves a similar role for the CommandHandler#copySelection command, * when the user types control-C to copy the currently selected parts. * * This property is a convenience getter/setter, and sets a value on #dragOptions. */ get dragsTree(): boolean; set dragsTree(value: boolean); /** * The cursor to show when a drop is allowed and will result in a copy. * This defaults to 'copy'. * Read more about cursors at Diagram#currentCursor * @since 2.2 */ get copyCursor(): string; set copyCursor(c: string); /** * The cursor to show when a drop is allowed and will result in a move. * This defaults to the empty string, which refers to the Diagram#defaultCursor. * Read more about cursors at Diagram#currentCursor * @since 2.2 */ get moveCursor(): string; set moveCursor(c: string); /** * The cursor to show when a drop is not allowed. * This defaults to 'no-drop'. * Read more about cursors at Diagram#currentCursor * @since 2.2 */ get nodropCursor(): string; set nodropCursor(c: string); /** * Gets the Part found at the mouse point. * This is normally set by a call to #standardMouseSelect. */ get currentPart(): Part | null; set currentPart(value: Part | null); /** * Gets the collection of Parts that this tool has copied. * The value is a Map mapping Parts to DraggingInfo Objects * that have a "point" property remembering the original location of that Part. * The value is null when moving instead of copying. * * #draggedParts provides the map of Parts that are being moved and from which this collection was copied. */ get copiedParts(): Map | null; set copiedParts(value: Map | null); /** * Gets the collection of Parts being moved. * The value is a Map mapping Parts to DraggingInfo Objects * that have a "point" property remembering the original location of that Part. * * #copiedParts provides the map of Parts that have been copied during a copying operation, if any. */ get draggedParts(): Map | null; set draggedParts(value: Map | null); /** * (undocumented) * This read-only property returns a Set that holds all of the Parts that are currently being dragged for either copying or moving. * @return {Set.} Returns the Map#toKeySet of either #copiedParts or #draggedParts, or else an empty Set. */ get draggingParts(): Set; set draggedLink(value: Link | null); set isDragOutStarted(value: boolean); /** * Gets or sets the mouse point from which parts start to move. * The value is a Point in document coordinates. * This property is normally set to the diagram's mouse-down point in #doActivate, * but may be set to a different point if parts are being copied from a different control. * Setting this property does not raise any events. */ get startPoint(): Point; set startPoint(value: Point); /** * On touch gestures only, this property gets or sets the time in milliseconds * for which the mouse must be stationary before this tool can be started. * The default value is 100 milliseconds. * Setting this property does not raise any events. */ get delay(): number; set delay(value: number); /** * This tool can run if the diagram allows selection and moves/copies/dragging-out, * if the mouse has moved far enough away to be a drag and not a click, * and if #findDraggablePart has found a selectable part at the mouse-down point. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} */ canStart(): boolean; /** * Return the selectable and movable/copyable Part at the mouse-down point. * This is called by #canStart to decide if this tool is ready to run. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {Part} */ findDraggablePart(): Part | null; /** * This override prevents the Control modifier unselecting an already selected part. * This also remembers the selectable #currentPart at the current mouse point. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ standardMouseSelect(): void; /** * Start the dragging operation. * This calls #computeEffectiveCollection and saves the result as #draggedParts. * * This starts a "Drag" transaction. * Depending on what happens, the transaction may be finished as a "Move" or a "Copy" * transaction, or it may be rolled-back if the tool is cancelled. * * Normally when this method is called the value of #currentPart will be null, * in which case this will call Tool#standardMouseSelect which will set #currentPart. * But if when this method is called the value of #currentPart has already been set * because the programmer wants the user to start dragging that Part, * then this method will not need to call Tool#standardMouseSelect because * the Part(s) to be selected and dragged have already been determined by the caller. */ doActivate(): void; /** * This just calls CommandHandler#computeEffectiveCollection. The implementation of this method was moved to CommandHandler for 2.0. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Iterable.} parts A Set or List of Parts. * @param {DraggingOptions} options Potential options for the collection computation * @return {Map.} a Map mapping Parts to DraggingInfo Objects * that have a "point" property remembering the original location of that Part. */ computeEffectiveCollection(parts: Iterable, options: DraggingOptions): Map; /** * Stop the dragging operation by stopping the transaction and cleaning up any temporary state. */ doDeactivate(): void; /** * This calls the super Tool#stopTransaction method, and if the result is `true`, * attempts to optimize the transaction by removing all changes except the first and last * by calling Transaction#optimize. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} the result of the call to rollback or commit the transaction. */ stopTransaction(): boolean; /** * Abort any dragging operation. */ doCancel(): void; /** * Handle switching between copying and moving modes as the Control/Option key is pressed or released. */ doKeyDown(): void; /** * Handle switching between copying and moving modes as the Control/Option key is pressed or released. */ doKeyUp(): void; /** * Move a collection Map of Parts by a given offset. * * If *check* is true this respects the Part#canMove predicate for Nodes or simple Parts * when this is the Diagram#currentTool. * It also respects #isGridSnapEnabled in order to try to automatically snap part locations to a grid. * And it also uses the Part#dragComputation function, if any, to determine the new location for each part. * * The first argument is a Map as produced by #computeEffectiveCollection, * not a List or Set or Iterator of Parts. * Call Diagram#moveParts if you want to move a simple collection of Parts without having to create the argument Map. * @expose * @param {Map.} parts a Map mapping Parts to DraggingInfo Objects * that have a "point" property remembering the original location of that Part. * @param {Point} offset The offset, before snapping, to move parts. * This offset reflects the total amount moved during tool operation, * based on original Part locations remembered when the DraggingTool activated. * @param {boolean=} check Whether to check Part#canMove on each part. The default value is false. * @since 1.1 */ moveParts(parts: Map, offset: Point, check?: boolean): void; /** * (undocumented) * @expose * @param pt * @return {GraphObject|null} */ protected findDragOverObject(pt: Point): GraphObject | null; /** * Perform any additional side-effects during a drag, whether an internal move or copy or an external drag, * that may affect the existing non-moved object(s). * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Point} pt a Point in document coordinates. * @param {GraphObject} obj the GraphObject at the point, * excluding what is being dragged or temporary objects; * the argument may be null if the drag is occurring in the background of the diagram. * Use GraphObject#part to get the Node or Part at the root of * the visual tree of the stationary object. * @since 1.1 */ doDragOver(pt: Point, obj: GraphObject | null): void; /** * Perform any additional side-effects after a drop, whether an internal move or copy or an external drop, * that may affect the existing non-moved object(s). * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Point} pt a Point in document coordinates. * @param {GraphObject} obj the GraphObject where the drop occurred, * excluding what was dropped or temporary objects; * the argument may be null if the drop occurred in the background of the diagram. * Use GraphObject#part to get the Node or Part at the root of * the visual tree of the stationary object. * @since 1.1 */ doDropOnto(pt: Point, obj: GraphObject | null): void; /** * Move the #draggedParts (or if copying, the #copiedParts) to follow the current mouse point. * * If this creates any temporary parts, by default it adds them to the Tool layer. * * This calls #doDragOver for any side-effects on stationary parts. */ doMouseMove(): void; /** * On a mouse-up finish moving or copying the effective selection. * * This calls #doDropOnto for any side-effects on stationary parts. * * This also updates the diagram's bounds, * raises a "SelectionCopied" or "SelectionMoved" DiagramEvent, and stops this tool. * * This method also raises the "ChangingSelection" and "ChangedSelection" diagram events. * Changes are performed in a "Drag" transaction, but the "ChangedSelection" event is raised outside the transaction. */ doMouseUp(): void; /** * (undocumented) * @expose * @param {Event} e * @param {Point} modelpt * @param {Diagram} overdiag the diagram attached to the target of the mouse move event, if any. * @return {boolean} */ simulatedMouseMove(e: Event | Touch | null, modelpt: Point, overdiag: Diagram | null): boolean; /** * (undocumented) * @expose * @param {Event} e * @param {Point} modelpt * @param {Diagram} curdiag * @return {boolean} */ simulatedMouseUp(e: Event | Touch | null, modelpt: Point, curdiag: Diagram | null): boolean; /** * This predicate is true when the diagram allows objects to be copied and inserted, * and some object in the selection is copyable, * and the user is holding down the Control key (Option key on Mac). * * This method may be overridden, although in most cases it is easiest to set Part#copyable. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} */ mayCopy(): boolean; /** * This predicate is true when the diagram allows objects to be moved, * and some object in the selection is movable. * * This method may be overridden, although in most cases it is easiest to set Part#movable. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} */ mayMove(): boolean; /** * This method computes the new location for a Node or simple Part, * given a new desired location and an optional Map of dragged parts, * taking any grid-snapping into consideration, * any Part#dragComputation function, * and any Part#minLocation and Part#maxLocation. * * As of 2.0, this just calls Diagram#computeMove and remains for compatibility. * * This method may be overridden, but should usually be overridden on Diagram. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Part} n the Node or simple Part that is being moved * @param {Point} newloc the proposed new location * @param {Map.=} draggedparts an optional Map mapping Parts to DraggingInfo Objects * that have a "point" property remembering the original location of that Part. * @param {Point=} result an optional Point that is modified and returned * @return {Point} the possibly grid-snapped computed Point that is within the minimum and maximum permitted locations * @since 1.1 */ computeMove(n: Part, newloc: Point, draggedparts?: Map | null, result?: Point): Point; } /** * This abstract class is the base class for the LinkingTool and RelinkingTool classes. * * This class includes properties for defining and accessing any temporary nodes and temporary link * that are used during any linking operation, as well as access to the existing diagram's nodes and link * (if any) that are involved with the linking operation. *

* For a general discussion of link routing, see: * Introduction to Links, * Introduction to Link Labels, and * Introduction to Link Connection Points. * For customizing the linking tools, see Introduction to the Linking Tools. * For customizing the reshaping of Links, see Introduction to the LinkReshapingTool. * For a general discussion of validation, see Introduction to Validation. * @extends Tool * @unrestricted * @category Tool */ export abstract class LinkingBaseTool extends Tool { /** * Don't construct this directly -- this is an abstract class. */ constructor(); /** * Gets or sets the distance at which link snapping occurs. * The default value is 100.0. * The value must be non-negative. * Setting this property does not raise any events. */ get portGravity(): number; set portGravity(value: number); /** * Gets or sets whether it is valid to have partly or completely unconnected links. * * The default value is false -- the user cannot draw or reconnect a link to "nowhere". * Setting this property does not raise any events. * @since 1.3 */ get isUnconnectedLinkValid(): boolean; set isUnconnectedLinkValid(value: boolean); /** * Gets or sets the cursor used during the linking or relinking operation. * This defaults to 'pointer'. * Read more about cursors at Diagram#currentCursor * @since 2.2 */ get linkingCursor(): string; set linkingCursor(c: string); /** * Gets or sets the temporary Link that is shown while the user is drawing or reconnecting a link. * Setting this property does not raise any events. */ get temporaryLink(): Link; set temporaryLink(value: Link); /** * Gets or sets the temporary Node at the "from" end of the #temporaryLink * while the user is drawing or reconnecting a link. * Setting this property does not raise any events. */ get temporaryFromNode(): Node; set temporaryFromNode(value: Node); /** * Gets or sets the GraphObject that is the port at the "from" end of the #temporaryLink * while the user is drawing or reconnecting a link. * Setting this property does not raise any events. */ get temporaryFromPort(): GraphObject; set temporaryFromPort(value: GraphObject); /** * Gets or sets the temporary Node at the "to" end of the #temporaryLink * while the user is drawing or reconnecting a link. * Setting this property does not raise any events. */ get temporaryToNode(): Node; set temporaryToNode(value: Node); /** * Gets or sets the GraphObject that is the port at the "to" end of the #temporaryLink * while the user is drawing or reconnecting a link. * Setting this property does not raise any events. */ get temporaryToPort(): GraphObject; set temporaryToPort(value: GraphObject); /** * Gets or sets the original Link being reconnected by the RelinkingTool. * Setting this property does not raise any events. */ get originalLink(): Link | null; set originalLink(value: Link | null); /** * Gets or sets the original Node from which the new link is being drawn * or from which the #originalLink was connected when being relinked. * Setting this property does not raise any events. */ get originalFromNode(): Node | null; set originalFromNode(value: Node | null); /** * Gets or sets the GraphObject that is the port in the #originalFromNode. * Setting this property does not raise any events. */ get originalFromPort(): GraphObject | null; set originalFromPort(value: GraphObject | null); /** * Gets or sets the original Node to which the new link is being drawn * or to which the #originalLink was connected when being relinked. * Setting this property does not raise any events. */ get originalToNode(): Node | null; set originalToNode(value: Node | null); /** * Gets or sets the GraphObject that is the port in the #originalToNode. * Setting this property does not raise any events. */ get originalToPort(): GraphObject | null; set originalToPort(value: GraphObject | null); /** * Gets whether the linking operation is in the forwards direction, * connecting from the "From" port to the "To" port. */ get isForwards(): boolean; set isForwards(value: boolean); /** * Gets or sets a proposed GraphObject port for connecting a link. * Whether this is a "to" port or a "from" port depends on the direction * (#isForwards) in which the link is being drawn or reconnected. * * This is set when the mouse is being dragged and when a mouse-up event occurs * with the result of a call to #findTargetPort. * Setting this property does not raise any events. */ get targetPort(): GraphObject | null; set targetPort(value: GraphObject | null); /** * Make a temporary port look and act like a real one. * * This is called by #doMouseMove as the tool finds new valid target ports. * If #findTargetPort returns null, it calls #setNoTargetPortProperties instead. * * If the #portTargeted property is a function, that function is called. * It is easier to customize the behavior by setting that functional property than it is to override * this method and the #setNoTargetPortProperties method. * But you may want to call this method to get the standard behavior for dynamically adapting * the temporary node/port to "act like" the target port. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Node} realnode * @param {GraphObject} realport * @param {Node} tempnode * @param {GraphObject} tempport * @param {boolean} toend * @since 1.2 */ protected copyPortProperties(realnode: Node | null, realport: GraphObject | null, tempnode: Node, tempport: GraphObject, toend: boolean): void; /** * Reset a temporary port's properties to neutral values when there is no target port. * * This is called by #doMouseMove when the tool finds no new valid target port. * If #findTargetPort returns non-null, it calls #copyPortProperties instead. * * If the #portTargeted property is a function, that function is called with null values as the first two arguments. * It is easier to customize the behavior by setting that functional property than it is to override * this method and the #copyPortProperties method. * But you may want to call this method to get the standard behavior for dynamically adapting * the temporary node/port to "act like" it is not connecting with any target port. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Node} tempnode * @param {GraphObject} tempport * @param {boolean} toend * @since 1.2 */ protected setNoTargetPortProperties(tempnode: Node, tempport: GraphObject, toend: boolean): void; /** * Mouse movement results in a temporary node moving to where a valid target port is located, * or to where the mouse is if there is no valid target port nearby. * * This calls #findTargetPort to update the #targetPort * given the new mouse point. * If a valid target port is found this moves the temporary node/port and * makes them appear like the target node/port by calling #copyPortProperties. * If no valid target port is found, this moves the temporary node to * where the mouse currently is and removes any node/port appearance, * by calling #setNoTargetPortProperties. * * This method may be overridden, but we recommend that you call this base method. */ doMouseMove(): void; /** * Find a port with which the user could complete a valid link. * * This finds objects near to the current mouse point for which a valid link connection is possible. * * For each port element found, this calls #isValidLink to find out if a link between * the original node/port and the found node/port would be valid. * The result is saved in a cache for faster decisions later during operation of this tool. * The closest valid port is returned. * * This method may be overridden, but we recommend that you call this base method. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {boolean} toend true if looking for a "to" port. * @return {GraphObject} a valid port, or null if no such port is near the current mouse point * within the #portGravity distance. */ findTargetPort(toend: boolean): GraphObject | null; /** * This predicate is true if it is permissible to connect a link from a given node/port. * This is called by #isValidLink. *

* For a more general discussion of validation, see Introduction to Validation. * * This method may be overridden, but we recommend that you call this base method. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Node} fromnode * @param {GraphObject} fromport * @return {boolean} * False if the node is in a Layer that does not Layer#allowLink. * False if the port's GraphObject#fromLinkable is either false or null. * False if the number of links connected to the port would exceed the port's GraphObject#fromMaxLinks. * Otherwise true. */ isValidFrom(fromnode: Node | null, fromport: GraphObject | null): boolean; /** * This predicate is true if it is permissible to connect a link to a given node/port. * This is called by #isValidLink. *

* For a more general discussion of validation, see Introduction to Validation. * * This method may be overridden, but we recommend that you call this base method. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Node} tonode * @param {GraphObject} toport * @return {boolean} * False if the node is in a Layer that does not Layer#allowLink. * False if the port's GraphObject#toLinkable is either false or null. * False if the number of links connected from the port would exceed the port's GraphObject#toMaxLinks. * Otherwise true. */ isValidTo(tonode: Node | null, toport: GraphObject | null): boolean; /** * This predicate is true if both argument ports are in the same Node. * This is called by #isValidLink. * * This method may be overridden, but we recommend that you call this base method. * It is rare that you will want to override this method. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {GraphObject} fromport * @param {GraphObject} toport * @return {boolean} */ isInSameNode(fromport: GraphObject | null, toport: GraphObject | null): boolean; /** * This predicate is true if there is a link in the diagram going from the given port to the given port. * This is called by #isValidLink. * * This method may be overridden, but we recommend that you call this base method. * It is rare that you will want to override this method. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {GraphObject} fromport * @param {GraphObject} toport * @return {boolean} */ isLinked(fromport: GraphObject | null, toport: GraphObject | null): boolean; /** * This predicate should be true when it is logically valid to connect a new link from * one node/port to another node/port. * When this is called by the RelinkingTool, that tool sets #originalLink * to be the Link being reconnected. *

* For a more general discussion of validation, see Introduction to Validation. * * This method may be overridden, although it is usually much easier to just set #linkValidation * or Node#linkValidation in order to add some application-specific link validation. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Node} fromnode the "from" Node. * @param {GraphObject} fromport the "from" GraphObject port. * @param {Node} tonode the "to" Node. * @param {GraphObject} toport the "to" GraphObject port. * @return {boolean} * False if #isValidFrom is false for the "from" node/port. * False if #isValidTo is false for the "to" node/port. * False if #isInSameNode is true unless GraphObject#fromLinkableSelfNode * and GraphObject#toLinkableSelfNode are true for the two ports. * False if #isLinked is true unless GraphObject#fromLinkableDuplicates * and GraphObject#toLinkableDuplicates are true for the two ports. * False if trying to link to the link's own label node(s). * If Node#linkValidation is a predicate on either or both of the "from" node and the "to" node, * the predicate is called and if it returns false, this predicate returns false. * If #linkValidation is a predicate and if it returns false, this predicate returns false. * Otherwise this predicate is true. */ isValidLink(fromnode: Node | null, fromport: GraphObject | null, tonode: Node | null, toport: GraphObject | null): boolean; /** * Checks whether a proposed link would be valid according to Diagram#validCycle. * This does not distinguish between different ports on a node, so this method does not need to take port arguments. * This is called by #isValidLink. * * This method may be overridden, but we recommend that you call this base method. * It is rare that you will want to override this method. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Node} from * @param {Node} to * @param {Link} ignore may be null; this is useful during relinking to ignore the #originalLink * @return {boolean} * @since 1.5 */ isValidCycle(from: Node | null, to: Node | null, ignore?: Link | null): boolean; /** * Gets or sets a predicate that determines whether or not a new link between two ports would be valid. * This predicate is called in addition to the normal link checking performed by #isValidLink * and any Node#linkValidation predicates on the "from" and "to" nodes. * When relinking, the Link being considered for reconnection is passed as the fifth argument. * The default predicate is null, which is equivalent to simply returning true. *

* For a more general discussion of validation, see Introduction to Validation. * * The function, if supplied, must not have any side-effects. */ get linkValidation(): ((fromNode: Node, fromPort: GraphObject, toNode: Node, toPort: GraphObject, link: Link) => boolean) | null; set linkValidation(value: ((fromNode: Node, fromPort: GraphObject, toNode: Node, toPort: GraphObject, link: Link) => boolean) | null); /** * Gets or sets a function that is called as the tool targets the nearest valid port. * The first two arguments specify the port by providing the Node that it is in * and the GraphObject that is the actual port object. * The next two arguments are the temporary port that has been moved and styled to be like the valid port. * These values will be either the #temporaryToNode and #temporaryToPort * or the #temporaryFromNode and #temporaryFromPort, depending on * which end of the temporary link is being updated. * The fifth argument is true if the target port represents a potential "to" end of a link; * it is false if it is for the "from" end of a link. * * When there is no valid port within the #portGravity, the first two arguments are null. * * The function, if supplied, must not add or remove any links or nodes or port objects, * nor may it change the validity of any potential link connection. * @since 1.2 */ get portTargeted(): ((node: Node | null, port: GraphObject | null, tempNode: Node, tempPort: GraphObject, toEnd: boolean) => void) | null; set portTargeted(value: ((node: Node | null, port: GraphObject | null, tempNode: Node, tempPort: GraphObject, toEnd: boolean) => void) | null); } /** * The LinkingTool lets a user draw a new Link between two ports, * using a mouse-drag operation. * * By default an instance of this tool is installed as a mouse-move tool in the * Diagram#toolManager as the ToolManager#linkingTool. * However this tool may be used modally, as described below. * * #canStart calls #findLinkablePort to find a valid "port" element * from which (or to which) the user may interactively draw a new link. * #doActivate sets up a temporary link and two temporary nodes, * one at the start port and one following the mouse. *

* For a general discussion of validation, see Introduction to Validation. * * This tool does not utilize any Adornments or tool handles. * * This tool conducts a transaction while the tool is active. * A successful linking will result in a "LinkDrawn" DiagramEvent and a "Linking" transaction. * * If you want to programmatically start a new user mouse-gesture to draw a new link * from a given GraphObject that either is a "port" or may be within * the visual tree of a "port", set the #startObject property * to let #findLinkablePort find the real "port" element. * Then start and activate this tool: * ```js * var tool = myDiagram.toolManager.linkingTool; * tool.startObject = ...; * myDiagram.currentTool = tool; * tool.doActivate(); * ``` * @extends LinkingBaseTool * @unrestricted * @category Tool */ export class LinkingTool extends LinkingBaseTool { /** * You do not normally need to create an instance of this tool * because one already exists as the ToolManager#linkingTool, which you can modify. * * The Tool#name of this tool is "Linking". */ constructor(); /** * This value for LinkingTool#direction indicates that users may draw new links in either direction. * @constant */ static Either: EnumValue; /** * This value for LinkingTool#direction indicates that users may draw new links forwards only * (i.e. from "from" node to "to" node). * @constant */ static ForwardsOnly: EnumValue; /** * This value for LinkingTool#direction indicates that users may draw new links backwards only * (i.e. from "to" node to "from" node). * @constant */ static BackwardsOnly: EnumValue; /** * Gets or sets a data object that is copied by #insertLink * and added to the GraphLinksModel when creating a new Link. * The default value is an empty Object, which will be copied. * The value must be an Object for the linking operation to succeed. * A null value will cause #insertLink to fail. * * The copied link data's GraphLinksModel#linkFromKeyProperty * and GraphLinksModel#linkToKeyProperty properties are set to * the corresponding node's data's key values. * If the ports have GraphObject#portId values that are not null, * the link data's GraphLinksModel#linkFromPortIdProperty * and GraphLinksModel#linkToPortIdProperty properties are also set. * * Setting this property does not raise any events. * This property is ignored if the Diagram#model is not a GraphLinksModel. */ get archetypeLinkData(): ObjectData | null; set archetypeLinkData(value: ObjectData | null); /** * Gets or sets an optional node data object representing a link label, that is copied by #insertLink * and added to the GraphLinksModel when creating a new Link. * * The default value is null, which causes no such label node data to be added to the model * along with the new link data. * * #insertLink calls GraphLinksModel#addLabelKeyForLinkData * to associate the label node data with the link data. * * Setting this property does not raise any events. * This property is ignored if the Diagram#model is not a GraphLinksModel. */ get archetypeLabelNodeData(): ObjectData | null; set archetypeLabelNodeData(value: ObjectData | null); /** * Gets or sets the direction in which new links may be drawn. * Possible values are LinkingTool.ForwardsOnly, LinkingTool.BackwardsOnly, or LinkingTool.Either. * This defaults to LinkingTool.Either. * Setting this property does not raise any events. */ get direction(): EnumValue; set direction(value: EnumValue); /** * Gets or sets the GraphObject at which #findLinkablePort should start its search. * The default value is null. * Setting this property does not raise any events. * * If you want to explicitly start a new user mouse-gesture to draw a new link * from a given GraphObject that may be a "port" object or may be within * the visual tree of a "port" object, set this property to that object * to let #findLinkablePort find the real "port" object. * Then start and activate this tool: * ```js * var tool = myDiagram.toolManager.linkingTool; * tool.startObject = ...; * myDiagram.currentTool = tool; * tool.doActivate(); * ``` */ get startObject(): GraphObject | null; set startObject(value: GraphObject | null); /** * This tool can run when the diagram allows linking, the model is modifiable, * the left-button mouse drag has moved far enough away to not be a click, and * when #findLinkablePort has returned a valid port * or when #startObject is a valid port. * * This method may be overridden, but we recommend that you call this base method. * @return {boolean} */ canStart(): boolean; /** * Return the GraphObject at the mouse-down point, * if it is part of a node and if it is valid to link with it. * * This starts looking for a port at the #startObject if it is non-null, * otherwise it looks for an object at the Diagram#firstInput's InputEvent#documentPoint. * If it finds no object, or if the object it finds is not in a node, this method returns null. * If it does find a port, it should set #isForwards to declare which direction the new link is being drawn. * * This method may be overridden, but we recommend that you call this base method. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {GraphObject} * If the #direction is LinkingTool.Either or LinkingTool.ForwardsOnly, * this checks the element and its parent Node by calling LinkingBaseTool#isValidFrom. * If the #direction is LinkingTool.Either or LinkingTool.BackwardsOnly, * this checks the element and its parent Node by calling LinkingBaseTool#isValidTo. * In either case finding a matching port will return that port and set LinkingBaseTool#isForwards appropriately. * Otherwise this will return null. */ findLinkablePort(): GraphObject | null; /** * Start the linking operation. * * This calls #findLinkablePort to find the port from which to start drawing a new link. * If the #startObject is already set, it uses that object to find the starting port. * If it is not set, it looks for a linkable port at the Diagram#firstInput point. * If it finds one, it remembers it as the starting port, otherwise it stops this tool. * * It then starts a transaction, captures the mouse, and changes the cursor. * Next it initializes and adds the LinkingBaseTool#temporaryFromNode, * LinkingBaseTool#temporaryToNode, and LinkingBaseTool#temporaryLink to the diagram. * The temporary nodes that are positioned and sized to be like the real LinkingBaseTool#originalFromPort * and LinkingBaseTool#originalToPort ports. * The temporary link connects the two temporary ports, of course. * * This method may be overridden, but we recommend that you call this base method. */ doActivate(): void; /** * Finishing the linking operation stops the transaction, releases the mouse, and resets the cursor. * * This method may be overridden, but we recommend that you call this base method. */ doDeactivate(): void; /** * A mouse-up ends the linking operation; if there is a valid #targetPort nearby, * this adds a new Link by calling #insertLink. * * If there is a new link, it is selected and the "LinkDrawn" DiagramEvent is raised * with the new link as the DiagramEvent#subject. * If there is no new link, this calls #doNoLink. * In any case this stops the tool. * * This method also raises the "ChangingSelection" and "ChangedSelection" diagram events. * Changes are performed in a "Linking" transaction, but the "ChangedSelection" event is raised outside the transaction. * * This method may be overridden, but we recommend that you call this base method. * It is usually easier to override #insertLink or just set #archetypeLinkData. * It is also common to implement a "LinkDrawn" DiagramEvent listener on the Diagram. */ doMouseUp(): void; /** * Make a copy of the #archetypeLinkData, set its node and port properties, and add it to the GraphLinksModel. * If the model is a TreeModel, set the parent key of the child's node data object. * * For GraphLinksModels, if #archetypeLabelNodeData is non-null, this method also adds that node data as an initial label node * for the new link data. * * For TreeModels, if Diagram#isTreePathToChildren is false, the roles of the *fromnode* and *tonode* arguments are exchanged. * * This method may be overridden, but we recommend that you call this base method. * Usually though it is easiest to just set #archetypeLinkData to control what kind of link is created. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Node} fromnode * @param {GraphObject} fromport the from-port, or null to use the node itself * @param {Node} tonode * @param {GraphObject} toport the to-port, or null to use the node itself * @return {Link} the newly created Link, or null if it failed. * @see #doNoLink */ insertLink(fromnode: Node | null, fromport: GraphObject | null, tonode: Node | null, toport: GraphObject | null): Link | null; /** * This method is called upon a mouse up when no new link is drawn, * either because no valid LinkingBaseTool#targetPort was found or because * #insertLink returned null. * * This method may be overridden. By default this method does nothing. * If you want to successfully perform any side-effects, you will need to set Tool#transactionResult to a string; * otherwise this tool's transaction will be rolled-back. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Node} fromnode * @param {GraphObject} fromport the from-port, or null to use the node itself * @param {Node} tonode * @param {GraphObject} toport the to-port, or null to use the node itself * @since 1.7 */ doNoLink(fromnode: Node | null, fromport: GraphObject | null, tonode: Node | null, toport: GraphObject | null): void; } /** * The RelinkingTool allows the user to reconnect an existing Link * if the Link#relinkableTo and/or Link#relinkableFrom properties are true. *

* For a general discussion of validation, see Introduction to Validation. * * By default an instance of this tool is installed as a mouse-down tool in the * Diagram#toolManager as the ToolManager#relinkingTool. * * This tool makes use of two Adornments, * each including a relink handle (potentially one for each end of the link), * shown when a link is selected. * * This tool conducts a transaction while the tool is active. * A successful relinking will result in a "LinkRelinked" DiagramEvent and a "Relinking" transaction. * * If you want to programmatically start a new user's relinking of a Link, * you can set the #handle property to the specific "RelinkFrom" or "RelinkTo" handle and * then start and activate the tool. * ```js * var tool = myDiagram.toolManager.relinkingTool; * tool.originalLink = ...; // specify which Link to have the user reconnect * tool.isForwards = true; // specify which end of the Link to reconnect * myDiagram.currentTool = tool; // starts the RelinkingTool * tool.doActivate(); // activates the RelinkingTool * ``` * @extends LinkingBaseTool * @unrestricted * @category Tool */ export class RelinkingTool extends LinkingBaseTool { /** * You do not normally need to create an instance of this tool * because one already exists as the ToolManager#relinkingTool, which you can modify. * * The Tool#name of this tool is "Relinking". */ constructor(); /** * Show an Adornment for each end of the Link that the user may reconnect. * The Adornment may have a copy of #fromHandleArchetype and/or #toHandleArchetype. * * This method may be overridden. * @param {Part} part */ updateAdornments(part: Part): void; /** * (undocumented) * Create and return an Adornment that lets the user grab a handle to reconnect one end of the selected link. * * This method may be overridden, but we recommend that you call this base method. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {GraphObject} selelt the GraphObject of the Link being relinked. * @param {boolean} toend * @return {Adornment} */ makeAdornment(selelt: GraphObject, toend: boolean): Adornment | null; /** * Gets or sets a small GraphObject that is copied as a relinking handle for the selected link path * at the "from" end of the link. * By default this is a Shape that is a small blue diamond. * Setting this property does not raise any events. * * Here is an example of changing the default handle to be larger green triangles: * ```js * myDiagram.toolManager.relinkingTool.toHandleArchetype = * $(go.Shape, "Triangle", * { width: 10, height: 10, fill: "limegreen", segmentIndex: 0 }); * ``` * @see #toHandleArchetype */ get fromHandleArchetype(): GraphObject | null; set fromHandleArchetype(value: GraphObject | null); /** * Gets or sets a small GraphObject that is copied as a relinking handle for the selected link path * at the "to" end of the link. * By default this is a Shape that is a small blue diamond. * Setting this property does not raise any events. * * Here is an example of changing the default handle to be larger orange triangles: * ```js * myDiagram.toolManager.relinkingTool.toHandleArchetype = * $(go.Shape, "Triangle", * { width: 10, height: 10, fill: "orange", segmentIndex: -1 }); * ``` * @see #fromHandleArchetype */ get toHandleArchetype(): GraphObject | null; set toHandleArchetype(value: GraphObject | null); /** * Returns the GraphObject that is the tool handle being dragged by the user. * This will be contained by an Adornment whose category is "RelinkFrom" or "RelinkTo". * Its Adornment#adornedPart is the same as the #originalLink. * * This property is also settable, but should only be set either within an override of #doActivate * or prior to calling #doActivate. */ get handle(): GraphObject | null; set handle(value: GraphObject | null); /** * This tool can run when the diagram allows relinking, the model is modifiable, * and there is a relink handle at the mouse-down point. * * This method may be overridden, but we recommend that you call this base method. * @return {boolean} */ canStart(): boolean; /** * Start the relinking operation. * * Find the relink handle by calling Tool#findToolHandleAt * looking for either the "RelinkFrom" adornment or the "RelinkTo" adornment, * saving the result in #handle. * * Normally when this method is called the value of LinkingBaseTool#originalLink and #handle will be null, * resulting in a call to Tool#findToolHandleAt to find a "RelinkFrom" or "RelinkTo" tool handle, * which is then remembered as the value of #handle. * If when this method is called the value of #handle is already set, * then there is no need to call Tool#findToolHandleAt, * because the programmer has already set up which relinking handle they want the user to be relinking. * Finding a handle is not necessary if LinkingBaseTool#originalLink and * #isForwards have been set before calling this method. * * This starts a transaction, captures the mouse, and sets the cursor. * * If LinkingBaseTool#originalLink or #handle was not set beforehand, * the value of #isForwards is set depending on the category of the relink handle found. * The LinkingBaseTool#originalLink property and various * "Original..." port and node properties are set too. * The temporary nodes and temporary link are also initialized. * * This method may be overridden, but we recommend that you call this base method. */ doActivate(): void; /** * Make a temporary link look and act like the real Link being relinked. * By default this method copies many of the routing-oriented properties * from the LinkingBaseTool#originalLink to the LinkingBaseTool#temporaryLink. * * This method may be overridden, but we recommend that you call this base method. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Link} reallink * @param {Link} templink * @since 1.3 */ protected copyLinkProperties(reallink: Link | null, templink: Link): void; /** * Finishing the linking operation stops the transaction, releases the mouse, and resets the cursor. * * This method may be overridden, but we recommend that you call this base method. */ doDeactivate(): void; /** * A mouse-up ends the relinking operation; if there is a valid #targetPort nearby, * this modifies the old link to connect with the target port. * * A successful relinking calls #reconnectLink to actually change the link. * The "LinkRelinked" DiagramEvent is raised with the link as the DiagramEvent#subject * and with the now-disconnected original port as the DiagramEvent#parameter. * If the link was not reconnected, this calls #doNoRelink. * In any case this stops the tool. * * A failure to find a valid target port results in no changes and no DiagramEvent. * * This method may be overridden, but we recommend that you call this base method. * You might find it easier to override #reconnectLink. * It is actually most common to implement a "LinkRelinked" DiagramEvent listener on the Diagram. */ doMouseUp(): void; /** * Modify an existing Link to connect to a new node and port. * * This method may be overridden, but we recommend that you call this base method. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Link} existinglink * @param {Node} newnode the Node to connect to or from. * @param {GraphObject} newport the GraphObject port to connect to or from. * @param {boolean} toend If true, this modifies the link's "to" node and port; otherwise it modifies the "from" node and port. * @return {boolean} true if successful. * @see #doNoRelink */ reconnectLink(existinglink: Link, newnode: Node | null, newport: GraphObject | null, toend: boolean): boolean; /** * This method is called upon a mouse up when #reconnectLink is not called. * * This method may be overridden. By default this method does nothing. * If you want to successfully perform any side-effects, you will need to set Tool#transactionResult to a string; * otherwise this tool's transaction will be rolled-back. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Link} existinglink * @param {boolean} toend If true, the user was trying to modify the link's "to" node and port. * @since 1.7 */ doNoRelink(existinglink: Link, toend: boolean): void; } /** * The LinkReshapingTool is used to interactively change the route of a Link * by setting its Link#points list. * You may want to save the route to the model by using a TwoWay Binding on the "points" property of the Link. * * This tool makes use of an Adornment, shown when the adorned Link is selected, * that includes some number of reshape handles. * This tool conducts a transaction while the tool is active. * A successful reshaping will result in a "LinkReshaped" DiagramEvent and a "LinkReshaping" transaction. * *

* For a general discussion of link routing, see: * Introduction to Links, * Introduction to Link Labels, and * Introduction to Link Connection Points. * For customizing the linking tools, see Introduction to the Linking Tools. * For a general discussion of validation, see Introduction to Validation. * @extends Tool * @unrestricted * @category Tool */ export class LinkReshapingTool extends Tool { /** * You do not normally need to create an instance of this tool * because one already exists as the ToolManager#linkReshapingTool, which you can modify. * * The Tool#name of this tool is "LinkReshaping". */ constructor(); /** * Disallow dragging. * @constant */ static None: EnumValue; /** * Allow only horizontal (left-and-right) dragging. * @constant */ static Horizontal: EnumValue; /** * Allow only vertical (up-and-down) dragging. * @constant */ static Vertical: EnumValue; /** * Allow dragging in any direction. * @constant */ static All: EnumValue; /** * Get the permitted reshaping behavior for a particular reshape handle. * @param {GraphObject} obj a reshape handle in the "LinkReshaping" Adornment. * @return {EnumValue} one of LinkReshapingTool.All, .Vertical, .Horizontal, or .None * @since 1.3 */ protected getReshapingBehavior(obj: GraphObject): EnumValue; /** * Set the permitted reshaping behavior for a particular reshape handle. * @param {GraphObject} obj a reshape handle in the "LinkReshaping" Adornment. * @param {EnumValue} behavior one of LinkReshapingTool.All, .Vertical, .Horizontal, or .None * @since 1.3 */ protected setReshapingBehavior(obj: GraphObject, behavior: EnumValue): void; /** * Show an Adornment with reshape handles at each of the interesting points of the link's route, * if the link is selected and visible and if Part#canReshape is true. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Part} part */ updateAdornments(part: Part): void; /** * (undocumented) * @expose * @param {GraphObject} pathshape * @return {Adornment} */ makeAdornment(pathshape: GraphObject): Adornment | null; /** * (undocumented) * Create and return a GraphObject that the user can "grab" to relink the selected Link. * By default this returns a copy of #handleArchetype, a Shape that is a small blue rectangle. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {GraphObject} pathshape the GraphObject path of the link being reshaped. * @param {number} idx the index of the route point to be moved. * @return {GraphObject} */ makeHandle(pathshape: GraphObject, idx: number): GraphObject | null; /** * Gets or sets a small GraphObject that is copied as a reshape handle at each movable point in the selected link's route. * By default this is a Shape that is a small blue rectangle. * Setting this property does not raise any events. * * Here is an example of changing the default handles to be larger yellow circles: * ```js * myDiagram.toolManager.linkReshapingTool.handleArchetype = * $(go.Shape, "Circle", * { width: 10, height: 10, fill: "yellow" }); * ``` * @see #midHandleArchetype */ get handleArchetype(): GraphObject | null; set handleArchetype(value: GraphObject | null); /** * (undocumented) * Create and return a GraphObject that the user can "grab" to add a segment to the selected Link. * By default this returns a copy of #midHandleArchetype, a Shape that is a small blue diamond. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {GraphObject} pathshape the GraphObject path of the link being reshaped. * @param {number} idx the index of the route point to be moved. * @return {GraphObject} */ makeResegmentHandle(pathshape: GraphObject, idx: number): GraphObject | null; /** * Gets or sets a small GraphObject that is copied as a resegment handle at each mid-point in the selected Link's route. * By default this is a Shape that is a small blue diamond. * Setting this property does not raise any events. * * Here is an example of changing the default handle to be larger cyan triangles: * ```js * myDiagram.toolManager.linkReshapingTool.midHandleArchetype = * $(go.Shape, "Triangle", { width: 10, height: 10, fill: "cyan" }); * ``` * @see #handleArchetype * @since 1.2 */ get midHandleArchetype(): GraphObject | null; set midHandleArchetype(value: GraphObject | null); /** * Returns the GraphObject that is the tool handle being dragged by the user. * This will be contained by an Adornment whose category is "LinkReshaping". * Its Adornment#adornedPart is the same as the #adornedLink. * This is normally set by #doActivate, remembering the result of the call to Tool#findToolHandleAt. */ get handle(): GraphObject | null; set handle(value: GraphObject | null); /** * This read-only property returns the Link that is being routed manually. */ get adornedLink(): Link | null; /** * This tool may run when there is a mouse-down event on a reshape handle. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} */ canStart(): boolean; /** * Start reshaping, if #findToolHandleAt finds a reshape handle at the mouse down point. * * If successful this sets #handle to be the reshape handle that it finds * and #adornedLink to be the Link being routed. * It also remembers the original link route (a list of Points) in case this tool is cancelled. * And it starts a transaction. */ doActivate(): void; /** * This stops the current reshaping operation with the link route shaped the way it is. */ doDeactivate(): void; /** * This calls the super Tool#stopTransaction method, and if the result is `true`, * attempts to optimize the transaction by removing all changes except the first and last * by calling Transaction#optimize. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} the result of the call to rollback or commit the transaction. */ stopTransaction(): boolean; /** * Restore the link route to be the original points and stop this tool. */ doCancel(): void; /** * (undocumented) * If the handle clicked during activation was a resegment handle, return the point at which to start a new segment. * By default this returns the center of the handle that was clicked. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {Point} the point where resegmenting begins */ protected getResegmentingPoint(): Point; /** * Call #reshape with a new point determined by the mouse * to change the route of the #adornedLink. */ doMouseMove(): void; /** * Reshape the route with a point based on the most recent mouse point by calling #reshape, * and then raise a "LinkReshaped" DiagramEvent before stopping this tool. */ doMouseUp(): void; set resegmentingDistance(value: number); /** * Change the route of the #adornedLink by moving the point corresponding to the current * #handle to be at the given Point. * This is called by #doMouseMove and #doMouseUp with the result of calling * #computeReshape to constrain the input point. * * This method respects the orthogonality of the link, if necessary limiting movement along only one axis. * To maintain orthogonality it may need to modify more than one point in the route. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Point} newPoint the value of the call to #computeReshape. */ reshape(newPoint: Point): void; /** * This is called by #doMouseMove and #doMouseUp to limit the input point * before calling #reshape. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Point} p the point where the handle is being dragged. * @return {Point} Either the same Point p or one constrained by the reshape behavior to be moved * only vertically or only horizontally. */ computeReshape(p: Point): Point; /** * This read-only property returns the Point that was the original location of the handle that is being dragged to reshape the Link. * @since 1.1 */ get originalPoint(): Point; /** * This read-only property returns the List of Points that was the original route of the Link that is being reshaped. * This List should not be modified; its value is indeterminate until a reshaping has been activated. * @since 1.1 */ get originalPoints(): List; } /** * The ResizingTool is used to interactively change the size of a GraphObject * in the selected Part or Node by setting its GraphObject#desiredSize property. * You may want to save the size to the model by using a TwoWay Binding on the "desiredSize" property * of the GraphObject that is named by Part#resizeObjectName. * This tool does not operate on Links. * * You can limit the permitted minimum and maximum dimensions by setting * #minSize and #maxSize. * The resizing will also respect the GraphObject#minSize and * GraphObject#maxSize properties. * Width or height values that are NaN do not constrain the resizing. * Override #computeMinSize and/or #computeMaxSize to change this behavior. * * You can also limit the width and/or height to be multiples of a particular size by * setting Part#resizeCellSize. * If either or both of these values are NaN, as they are by default, * it will get the values from this tool's #cellSize. * Finally it will consider the Diagram#grid's Panel#gridCellSize * if #isGridSnapEnabled is true. * Override #computeCellSize to change this behavior. * * Pressing the Shift key or resizing a Shape with a Shape#geometryStretch of * GraphObject.Uniform will maintain the aspect ratio during the resize. * Override #computeReshape to change this behavior. * * This tool makes use of an Adornment, shown when the Part or Node is selected, * that includes some number of resize handles. * The resize handles are normally copies of ResizingTool#handleArchetype, * unless you specify a custom resize Adornment by setting Part#resizeAdornmentTemplate. * The resize Adornment is normally a "Spot" Panel with eight resize handles, * each with GraphObject#alignment set to one of the eight standard Spot values -- * the four corners and the four side middles. * The GraphObject#alignment is what identifies and distinguishes each of the handles and * the behavior when the user drags the handle. * * This tool conducts a transaction while the tool is active. * A successful resizing will result in a "PartResized" DiagramEvent and a "Resizing" transaction. *

* For a general discussion of the sizing of objects, see: Introduction to the sizing of GraphObjects. * For customizing the ResizingTool, see Introduction to the ResizingTool. * * If you want to programmatically start a user's resizing of the Part#resizeObject of an existing selected node, * you can set the #handle property to the specific resize handle and then start and activate the tool. * ```js * var node = ...; * myDiagram.select(node); * var adorn = node.findAdornment("Resizing"); * var tool = myDiagram.toolManager.resizingTool; * // specify which resize handle of the "Resizing" Adornment of the selected node * tool.handle = adorn.elt(...); * myDiagram.currentTool = tool; // starts the ResizingTool * tool.doActivate(); // activates the ResizingTool * ``` * @extends Tool * @unrestricted * @category Tool */ export class ResizingTool extends Tool { /** * You do not normally need to create an instance of this tool * because one already exists as the ToolManager#resizingTool, which you can modify. * * The Tool#name of this tool is "Resizing". */ constructor(); /** * Show an Adornment with the resize handles at points along the edge of the bounds of the * selected Part's Part#resizeObject. * * First this finds the object in the visual tree of the Part that should * get the resize adornment and that the user will be able to resize interactively. * It finds the object that has the Part#resizeObjectName property of the Part. * If the Part#resizeObjectName property is an empty string, as it is by default, * it uses the whole part. * * It then builds the adornment, associating it with the chosen resize object. * If Part#resizeAdornmentTemplate is non-null, it is copied. * Otherwise it constructs a new Adornment with a Placeholder and eight copies of #handleArchetype, * four at the corners and four at the middle of each side. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Part} part */ updateAdornments(part: Part): void; /** * (undocumented) * Create and return an Adornment that lets the user grab a handle to resize the selected part. * The Adornment will be a "Spot" Panel with a Placeholder and eight copies of #handleArchetype. * Each handle will have one of the standard Spots as their GraphObject#alignment. * * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {GraphObject} resizeObj the GraphObject being resized. * @return {Adornment} */ makeAdornment(resizeObj: GraphObject): Adornment | null; /** * (undocumented) * @expose * @param {GraphObject} elt * @param {number} angle */ updateResizeHandles(elt: GraphObject, angle: number): void; /** * Gets or sets a small GraphObject that is copied as a resizing handle for the selected part. * By default this is a Shape that is a small blue rectangle. * Setting this property does not raise any events. * * Here is an example of changing the default handle to be larger yellow circles: * ```js * myDiagram.toolManager.resizingTool.handleArchetype = * $(go.Shape, "Circle", * { width: 10, height: 10, fill: "yellow" }); * ``` * * This property is ignored when a custom resizing Adornment is specified as the Part#resizeAdornmentTemplate. * That property is normally null, in which case this tool will automatically construct Adornments * holding eight copies of this handle archetype, each with a GraphObject#alignment being one of the * standard eight Spots. */ get handleArchetype(): GraphObject | null; set handleArchetype(value: GraphObject | null); /** * Returns the GraphObject that is the tool handle being dragged by the user. * This will be contained by an Adornment whose category is "ResizingTool". * Its Adornment#adornedObject is the same as the #adornedObject. * This is normally set by #doActivate, remembering the result of the call to Tool#findToolHandleAt. * * This property is also settable, but should only be set either within an override of #doActivate * or prior to calling #doActivate. */ get handle(): GraphObject | null; set handle(value: GraphObject | null); /** * Gets the GraphObject that is being resized. * This may be the same object as the selected Part or it may be contained within that Part. * * This property is also settable, but should only be set when overriding functions * in ResizingTool, and not during normal operation. */ get adornedObject(): GraphObject | null; set adornedObject(value: GraphObject | null); /** * This tool may run when there is a mouse-down event on a resize handle, * the diagram is not read-only and it allows resizing, * the left mouse button is being used, * and this tool's adornment's resize handle is at the current mouse point. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} */ canStart(): boolean; /** * Find the #handle, remember the object's original bounds, * save the results of calling #computeMinSize, #computeMaxSize, and #computeCellSize, * capture the mouse, and start a transaction. * * Normally when this method is called the value of #handle will be null, * resulting in a call to Tool#findToolHandleAt to find a "Resizing" tool handle, * which is then remembered as the value of #handle. * If when this method is called the value of #handle is already set, * then there is no need to call Tool#findToolHandleAt, * because the programmer has already set up which resize handle they want the user to be resizing. */ doActivate(): void; /** * Stop the current transaction, forget the #handle and #adornedObject, and release the mouse. */ doDeactivate(): void; /** * This calls the super Tool#stopTransaction method, and if the result is `true`, * attempts to optimize the transaction by removing all changes except the first and last * by calling Transaction#optimize. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} the result of the call to rollback or commit the transaction. */ stopTransaction(): boolean; /** * Restore the original size of the GraphObject. */ doCancel(): void; /** * Call #resize with a new size determined by the current mouse point. * This determines the new bounds by calling #computeResize. * * When this calls #computeResize it passes as the reshape argument the result of calling #computeReshape. * The min, max, and cell arguments will be the saved results of #doActivate's calls to #computeMinSize, #computeMaxSize, and #computeCellSize. */ doMouseMove(): void; /** * Call #resize with the final bounds based on the most recent mouse point, * commit the transaction, and raise the "PartResized" DiagramEvent. * This determines the new bounds by calling #computeResize. * * When this calls #computeResize it passes as the reshape argument the result of calling #computeReshape. */ doMouseUp(): void; /** * Change the size of the selected part's Part#resizeObject to have the given bounds. * This modifies its GraphObject#desiredSize and maybe its Part#location. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Rect} newr a Rectangle in the #adornedObject's local coordinates, not in document coordinates */ resize(newr: Rect): void; /** * Given a Spot in the original bounds of the object being resized and a new Point, * compute the new Rect. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Point} newPoint a Point in local coordinates. * @param {Spot} spot the alignment spot of the handle being dragged. * @param {Size} min the result of the call to #computeMinSize. * @param {Size} max the result of the call to #computeMaxSize. * @param {Size} cell the result of the call to #computeCellSize. * @param {boolean} reshape true if the new size may change the aspect ratio from that of the natural bounds of the #adornedObject. * @return {Rect} a Rectangle in the #adornedObject's local coordinates, not in document coordinates */ computeResize(newPoint: Point, spot: Spot, min: Size, max: Size, cell: Size, reshape: boolean): Rect; /** * Decide whether to allow arbitrary reshaping or whether to keep the same aspect ratio of the object being resized. * If the #adornedObject is a Shape, * then if the Shape#geometryStretch is GraphObject.Uniform, * this method will return false to restrict reshaping to maintain the object's current ratio of height to width. * Also, if the user is holding down the Shift key, this method will return false. * * This is called on each mouse-move and on mouse-up; the result is passed to the call to #resize. * This permits the user to change the behavior dynamically during resizing. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * * For example, to always keep the object's original aspect ratio, override this method to return false. * When initializing a Diagram: * ```js * const diagram = new go.Diagram, "myDiagramDiv" * { * "resizingTool.computeReshape": function() { return false; }, * // ... rest of Diagram init * }) * ``` * Or when overriding the method dynamically: * ```js * myDiagram.toolManager.resizingTool.computeReshape = function() { return false; } * ``` * Your override might want to look at the `this.adornedObject.part.data` properties to decide whether to allow reshaping. * @expose * @return {boolean} true to allow any aspect ratio; false to preserve the #adornedObject's height/width ratio * @since 1.7 */ computeReshape(): boolean; /** * The effective minimum resizing size is the maximum of #minSize and the * #adornedObject's GraphObject#minSize. * * This is called once when the tool is activated. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {Size} */ computeMinSize(): Size; /** * The effective maximum resizing size is the minimum of the #maxSize and the * #adornedObject's GraphObject#maxSize. * * This is called once when the tool is activated. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {Size} */ computeMaxSize(): Size; /** * The size should be a multiple of the value returned by this method. * * This is called once when the tool is activated. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {Size} */ computeCellSize(): Size; /** * Gets or sets the minimum size to which the user can resize. * The effective minimum size is the maximum of this value and the GraphObject#minSize, * independently in each direction. * * The default value is `go.Size(1, 1)`. * Any new value must be of type Size; `NaN` width or height values are treated as zero. * Setting this property does not raise any events. */ get minSize(): Size; set minSize(value: Size); /** * Gets or sets the maximum size to which the user can resize. * The effective maximum size is the minimum of this value and the GraphObject#maxSize, * independently in each direction. * * The default value is `go.Size(9999, 9999)`. * Any new value must be of type Size; `NaN` width or height values are treated as Infinity. * Setting this property does not raise any events. */ get maxSize(): Size; set maxSize(value: Size); /** * Gets or sets the width and height multiples with which the user must resize. * The effective cell size is computed by first looking at the Adornment#adornedPart's Part#resizeCellSize. * If either or both of its width and height are `NaN`, it will use this property, `cellSize`. * If either or both of this property's width and height are `NaN`, it will * consider the Diagram#grid's Panel#gridCellSize. * * The default value is `go.Size(NaN, NaN)`. * Setting this property does not raise any events. */ get cellSize(): Size; set cellSize(value: Size); /** * Gets or sets whether the ResizingTool snaps object sizes to the diagram's background grid during the resize. * By default this property is false. * Setting this property does not raise any events. */ get isGridSnapEnabled(): boolean; set isGridSnapEnabled(value: boolean); /** * Gets or sets whether the ResizingTool moves the member Parts of a Group that has no Group#placeholder. * By default this property is true. * Setting this property does not raise any events. * @since 2.1.26 */ get dragsMembers(): boolean; set dragsMembers(value: boolean); /** * Gets the Point opposite to the chosen, dragged handle of the "Resizing" Adornment. * This property has no meaning until after #doActivate has been called. * @since 2.2 */ get oppositePoint(): Point; set oppositePoint(value: Point); /** * This read-only property returns the Size that was the original value of the GraphObject#desiredSize * of the element that is being resized. * @since 1.1 */ get originalDesiredSize(): Size; /** * This read-only property returns the Point that was the original value of the Part#location * of the Part that is being resized. * @since 1.1 */ get originalLocation(): Point; } /** * The RotatingTool is used to interactively change the GraphObject#angle of a GraphObject * by setting its GraphObject#angle property. * You may want to save the angle to the model by using a TwoWay Binding on the "angle" property * of the GraphObject that is named by Part#rotateObjectName. * * This tool allows the user to rotate the Part#rotateObject of the selected Part. * The Part must be Part#rotatable, which is false by default. * Normally this works with Parts or Nodes; it does not make sense for whole Links * or Link#paths, so if you want to rotate a label on a Link, make sure to name that label * and refer to it as the Part#rotateObjectName. * * You can control the point about which the object is rotated by setting Part#rotationSpot. * The rotation spot can be computed dynamically by overriding #computeRotationPoint. * The value of that method call is saved as #rotationPoint. * * You can limit the permitted angles by setting #snapAngleMultiple and #snapAngleEpsilon. * For example, if you want to permit only angles that are multiples of 90 degrees, * set #snapAngleMultiple to 90 and #snapAngleEpsilon to 45. * Pressing the Shift key during rotation ignores these two properties. * * This tool makes use of an Adornment that includes a rotation handle. * It is shown when the selected Part is Part#rotatable. * You can control its direction relative to the #rotationPoint * by setting #handleAngle to a multiple of 90 degrees, * and its distance from the rotation point by setting #handleDistance. * The rotate handle is normally a copy of RotatingTool#handleArchetype. * unless you specify a custom rotate Adornment by setting Part#rotateAdornmentTemplate. * * This tool conducts a transaction while the tool is active. * A successful rotation will result in a "PartRotated" DiagramEvent and a "Rotating" transaction. *

* For customizing the RotatingTool, see Introduction to the RotatingTool. * * If you want to programmatically start a user's rotating of the Part#rotateObject of an existing selected node, * you can set the #handle property to the rotate handle and then start and activate the tool. * ```js * var node = ...; * myDiagram.select(node); * var adorn = node.findAdornment("Rotating"); * var tool = myDiagram.toolManager.rotatingTool; * // specify the rotation handle of the "Rotating" Adornment of the selected node * tool.handle = adorn.elt(0); * myDiagram.currentTool = tool; // starts the RotatingTool * tool.doActivate(); // activates the RotatingTool * ``` * @extends Tool * @unrestricted * @category Tool */ export class RotatingTool extends Tool { /** * You do not normally need to create an instance of this tool * because one already exists as the ToolManager#rotatingTool, which you can modify. * * The Tool#name of this tool is "Rotating". */ constructor(); /** * Show an Adornment with a rotate handle at a point to the side of the adorned object * if the part is selected and visible and if Part#canRotate() is true. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Part} part the part. */ updateAdornments(part: Part): void; /** * (undocumented) * Create and return an Adornment that lets the user grab a handle to rotate an object in the selected part. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {GraphObject} rotateObj the GraphObject being rotated. * @return {Adornment} */ makeAdornment(rotateObj: GraphObject): Adornment | null; /** * Gets or sets a small GraphObject that is copied as a rotation handle for the selected part. * By default this is a Shape that is a small yellow circle. * Setting this property does not raise any events. * * Here is an example of changing the default handle to be green "X": * ```js * myDiagram.toolManager.rotatingTool.handleArchetype = * $(go.Shape, "XLine", * { width: 8, height: 8, stroke: "green", fill: "transparent" }); * ``` * * This property is ignored when a custom rotating Adornment is specified as the Part#rotateAdornmentTemplate. */ get handleArchetype(): GraphObject | null; set handleArchetype(value: GraphObject | null); /** * This read-only property returns the GraphObject that is the tool handle being dragged by the user. * This will be contained by an Adornment whose category is "RotatingTool". * Its Adornment#adornedObject is the same as the #adornedObject. * * This property is also settable, but should only be set either within an override of #doActivate * or prior to calling #doActivate. */ get handle(): GraphObject | null; set handle(value: GraphObject | null); /** * Gets the GraphObject that is being rotated. * This may be the same object as the selected Part or it may be contained within that Part. * * This property is also settable, but should only be set when overriding functions * in RotatingTool, and not during normal operation. */ get adornedObject(): GraphObject | null; set adornedObject(value: GraphObject | null); /** * This tool may run when there is a mouse-down event on a rotate handle, * the diagram is not read-only and it allows rotation, * the left mouse button is being used, * and this tool's adornment's rotate handle is at the current mouse point. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} */ canStart(): boolean; /** * Capture the mouse, remember the original GraphObject#angle, * and start a transaction. * * Normally when this method is called the value of #handle will be null, * resulting in a call to Tool#findToolHandleAt to find a "Rotating" tool handle, * which is then remembered as the value of #handle. * If when this method is called the value of #handle is already set, * then there is no need to call Tool#findToolHandleAt, * because the programmer has already set up which rotate handle they want the user to be rotating. */ doActivate(): void; /** * Compute the Point about which things should rotate. * This is called when this tool is activated and sometimes when updating the Adornment. * The value of the call is remembered as #rotationPoint. * @expose * @param {GraphObject} obj the Part#rotateObject * @return {Point} */ computeRotationPoint(obj: GraphObject): Point; /** * Stop the current transaction, forget the #handle and #adornedObject, and release the mouse. */ doDeactivate(): void; /** * This calls the super Tool#stopTransaction method, and if the result is `true`, * attempts to optimize the transaction by removing all changes except the first and last * by calling Transaction#optimize. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} the result of the call to rollback or commit the transaction. */ stopTransaction(): boolean; /** * Restore the original GraphObject#angle of the adorned object. */ doCancel(): void; /** * Call #rotate with a new angle determined by the current mouse point. * This determines the new angle by calling #computeRotate. */ doMouseMove(): void; /** * Call #rotate with an angle based on the most recent mouse point, * commit the transaction, and raise the "PartRotated" DiagramEvent. */ doMouseUp(): void; /** * Change the angle of the selected part's Part#rotateObject. * This modifies its GraphObject#angle. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {number} newangle in degrees. */ rotate(newangle: number): void; /** * Compute the new angle given a point. * If the Shift key is pressed, this method ignores the #snapAngleMultiple and #snapAngleEpsilon. * * If the angle is close (by #snapAngleEpsilon degrees) * to a multiple of #snapAngleMultiple degrees, * make it exactly that multiple. * * This method is called by both #doMouseMove and #doMouseUp. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Point} newPoint in document coordinates. * @return {number} the new angle, in degrees. */ computeRotate(newPoint: Point): number; /** * Gets or sets the preferred angles for the selected object. * * The default value is 45 degrees, meaning that angles that are multiples * of 45 degrees are automatically preferred, if the actual angle is * close to that multiple. * The closeness is determined by the #snapAngleEpsilon property. * A value of zero for #snapAngleMultiple results in no snapping at all. * Setting this property does not raise any events. */ get snapAngleMultiple(): number; set snapAngleMultiple(value: number); /** * Gets or sets the the closeness to a desired angle at which the angle is "snapped to". * * The default value is 2 degrees, meaning that any angle within 2 degrees * of a multiple of the #snapAngleMultiple automatically * snaps to that multiple. * Values are limited to half of the #snapAngleMultiple; * such values restrict user selected angles only to exact multiples of * #snapAngleMultiple -- no other angles between them. * Setting this property does not raise any events. */ get snapAngleEpsilon(): number; set snapAngleEpsilon(value: number); /** * This read-only property returns the angle that was the original value of the GraphObject#angle * of the GraphObject that is being rotated. * The value is invalid when this tool is not active. * @since 1.1 */ get originalAngle(): number; /** * Gets or sets the Point at which the axis of the rotation should be. * #doActivate saves here the value returned by the call to #computeRotationPoint. * The value is invalid when this tool is not active. * @since 2.0 */ get rotationPoint(): Point; set rotationPoint(value: Point); /** * Gets or sets the spot to locate the Adornment for the rotation handle when it does not have a Placeholder. * This assumes the Adornment's location will be at the center of the rotation handle. * * By default this is zero degrees, which locates the Adornment * so that it is placed to the right of an un-rotated object. * You can set this to a multiple of 90 degrees to position the rotation handle differently * with respect to the #rotationPoint. * @since 2.0 */ get handleAngle(): number; set handleAngle(value: number); /** * Gets or sets the spot to locate the Adornment at a particular distance from the #adornedObject. * This assumes the Adornment's location will be at the center of the rotation handle. * * By default this is 50, which locates the Adornment * so that it is placed to the right of an un-rotated object. * @since 2.0 */ get handleDistance(): number; set handleDistance(value: number); } /** * The ClickSelectingTool selects and deselects Parts when there is a click. * It does this by calling Tool#standardMouseSelect. * It is also responsible for handling and dispatching click events on GraphObjects * by calling Tool#standardMouseClick. * * Note that this tool avoids raising click events on objects that are in temporary layers. * This is to prevent parts such as selection adornments from interfering with clicking on selected nodes or links. * (Adornments are in the "Adornment" Layer, which Layer#isTemporary.) * However this means that if you add a GraphObject#click event handler on a GraphObject in an Adornment, * it will not be called. * You can get it to be called by setting GraphObject#isActionable to true on that object in the adornment. * * This tool is a standard mouse-up tool, the ToolManager#clickSelectingTool. * * This tool does not utilize any Adornments or tool handles. * This tool does not modify the model or conduct any transaction. * * An example customization of this tool is shown in the Tree Map sample, * where the Tool#standardMouseSelect method is overridden to permit the user to cycle through * the chain of containing groups, changing the selection on each click to the next containing group. * * If you want to programmatically select a Part, you can set Part#isSelected or call Diagram#select. * If you want to know which Part is at a particular point, you can call Diagram#findPartAt. * @extends Tool * @unrestricted * @category Tool */ export class ClickSelectingTool extends Tool { /** * You do not normally need to create an instance of this tool * because one already exists as the ToolManager#clickSelectingTool. * * The Tool#name of this tool is "ClickSelecting". */ constructor(); /** * This tool can run whenever a click occurs. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} */ canStart(): boolean; /** * Upon a click, this calls Tool#standardMouseSelect to change the Diagram#selection collection, * then calls Tool#standardMouseClick to perform the normal click behaviors, * and then stops this tool. */ doMouseUp(): void; } /** * The ActionTool is responsible for handling and dispatching mouse events on GraphObjects * that have GraphObject#isActionable set to true. * This is how one implements "controls", such as buttons or sliders or knobs, as GraphObjects * that can be inside Parts without interfering with the standard tool behaviors. * * This tool allows individual GraphObjects (usually Panels) to handle mouse-down-move-up events without * having to define new Tools. * It does this by calling GraphObject#actionDown, GraphObject#actionMove, GraphObject#actionUp, * and GraphObject#actionCancel on objects that have GraphObject#isActionable set to true. * * This tool is a standard mouse-down tool, the ToolManager#actionTool. * * This tool does not utilize any Adornments or tool handles. * This tool does not modify the model or conduct any transaction, although the actions that this invokes may do so. * * It would be very unusual to want to customize this tool. * @extends Tool * @unrestricted * @category Tool */ export class ActionTool extends Tool { /** * You do not normally need to create an instance of this tool * because one already exists as the ToolManager#actionTool. * * The Tool#name of this tool is "Action". */ constructor(); /** * This tool can run when there is a mouse-down on an object with GraphObject#isActionable true * or if the object is within a Panel that "isActionable". * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} */ canStart(): boolean; /** * If there is a GraphObject found with GraphObject#isActionable set to true, * call that object's GraphObject#actionDown event, if it exists. */ doMouseDown(): void; /** * If this tool is active call GraphObject#actionMove, if it exists, on the active object. */ doMouseMove(): void; /** * Calls the GraphObject#actionUp event if defined, then effectively calls * Tool#standardMouseClick to perform the normal click behaviors, * and then stops this tool. */ doMouseUp(): void; /** * Call the GraphObject#actionCancel event if defined on the current object. */ doCancel(): void; } /** * The ClickCreatingTool lets the user create a node by clicking where they want the new node to be. * By default a double-click is required to start this tool; * set #isDoubleClick to false if you want a single-click to create a node. * * This tool is a standard mouse-up tool, the ToolManager#clickCreatingTool. * However, it will not be able to start running unless you have set the * #archetypeNodeData property to an object that can be copied and added to the diagram's model. * * If you set #isGridSnapEnabled to true, newly created parts will be snapped to points on a grid. * * This tool does not utilize any Adornments or tool handles. * This tool does conduct a transaction when inserting the new node. * * If you want to programmatically create a Part, you can call #insertPart. * @extends Tool * @unrestricted * @category Tool */ export class ClickCreatingTool extends Tool { /** * You do not normally need to create an instance of this tool * because one already exists as the ToolManager#clickCreatingTool, which you can modify. * * The Tool#name of this tool is "ClickCreating". */ constructor(); /** * This tool can run when the diagram is not read-only and supports creating new nodes, * and when there has been a click (or double-click if #isDoubleClick is true) * in the background of the diagram (not on a Part), * and #archetypeNodeData is an object that can be copied and added to the model. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} */ canStart(): boolean; /** * Upon a click, call #insertPart and stop this tool. */ doMouseUp(): void; /** * Create a node by adding a copy of the #archetypeNodeData object * to the diagram's model, assign its Part#location * to be the given point, and select the new part. * * This starts and commits a transaction and also raises the "PartCreated" DiagramEvent. * The actual part that is added to the diagram may be a Part, a Node, * or even a Group, depending on the properties of the #archetypeNodeData * and the type of the template that is copied to create the part. * * This method also raises the "ChangingSelection" and "ChangedSelection" diagram events outside the transaction. * * This method may be overridden, although it is usually much easier to just set #archetypeNodeData. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Point} loc a Point in document coordinates. * @return {Part} the newly created Part, or null if it failed. */ insertPart(loc: Point): Part | null; /** * Gets or sets a data object that will be copied and added to the diagram's model each time this tool executes. * The default value is null. * The value must be non-null for this tool to be able to run. * Setting this property does not raise any events. */ get archetypeNodeData(): ObjectData | null; set archetypeNodeData(value: ObjectData | null); /** * Gets or sets whether a double click rather than a single-click is required * to insert a new Part at the mouse-up point. * The default value is true -- only a double-click will cause a node to be created. * Setting this property does not raise any events. */ get isDoubleClick(): boolean; set isDoubleClick(value: boolean); /** * Gets or sets whether the ClickCreatingTool snaps object sizes to the diagram's background grid during creation. * By default this property is false. * Setting this property does not raise any events. * * @since 2.0 */ get isGridSnapEnabled(): boolean; set isGridSnapEnabled(value: boolean); } /** * The DragSelectingTool lets the user select multiple parts within a rectangular area drawn by the user. * There is a temporary part, the #box, * that shows the current area encompassed between the mouse-down * point and the current mouse point. * The default drag selection box is a magenta rectangle. * You can change the #box to customize its appearance -- see its documentation for an example. * * This tool is a standard mouse-move tool, the ToolManager#dragSelectingTool. * However this cannot start running unless there has been a motionless delay * after the mouse-down event of at least #delay milliseconds. * * This tool does not utilize any Adornments or tool handles, * but it does temporarily add the #box part to the diagram. * This tool does not modify the model or conduct any transaction. * * Selection occurs on a mouse-up when it calls #selectInRect * with the value of #computeBoxBounds. * Selectable parts are selected when their bounds fall entirely within the rectangle, * unless #isPartialInclusion is set to true. *

* For customizing the DragSelectingTool, see Introduction to the DragSelectingTool. * * If you implement your own drag-in-the-background-to-do-something tool, you may need to disable * this tool or insert your new tool in the ToolManager#mouseMoveTools list before this tool, * in order for your tool to run. There are examples of such tools defined in the extensions directory: * Realtime Drag Selecting Tool, * Drag Creating Tool, and * Drag Zooming Tool. * * If you want to programmatically select some Parts in a rectangular area, * you can call #selectInRect. * @extends Tool * @unrestricted * @category Tool */ export class DragSelectingTool extends Tool { /** * You do not normally need to create an instance of this tool * because one already exists as the ToolManager#dragSelectingTool, which you can modify. * * The Tool#name of this tool is "DragSelecting". */ constructor(); /** * This tool can run when the diagram allows selection, * there has been delay of at least #delay milliseconds * after the mouse-down before a mouse-move, * there has been a mouse-drag far enough away not to be a click, * and there is no selectable part at the mouse-down point. * * The delay required to start this tool enables both this tool and * the ToolManager#panningTool to co-exist as mode-less mouse-move tools. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} */ canStart(): boolean; /** * Capture the mouse and show the #box. */ doActivate(): void; /** * Release the mouse and remove any #box. */ doDeactivate(): void; /** * Update the #box's position and size according to the value * of #computeBoxBounds. */ doMouseMove(): void; /** * Call #selectInRect with the value of a call to #computeBoxBounds. * * This method changes the cursor to "wait" and * raises the "ChangingSelection" DiagramEvent before calling #selectInRect, * and raises the "ChangedSelection" DiagramEvent afterward. */ doMouseUp(): void; /** * This just returns a Rect stretching from the mouse-down point to the current mouse point. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {Rect} a Rect in document coordinates. */ computeBoxBounds(): Rect; /** * This method is called to select some parts within the area of a given rectangle. * * The normal behavior is to set the diagram's selection collection to only those parts * in the given rectangle according to the #isPartialInclusion policy. * However, if the Shift key modifier is used, no parts are deselected -- * this adds to the selection the parts in the rectangle not already selected. * If the Control key (Command on Mac) modifier is used, this toggles the selectedness of the parts in the rectangle. * If the Control key (Command on Mac) and Shift key modifiers are both used, this deselects the parts in the rectangle. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Rect} r a rectangular bounds in document coordinates. */ selectInRect(r: Rect): void; /** * Gets or sets the time in milliseconds for which the mouse must be stationary * before this tool can be started. * The default value is 175 milliseconds. * Setting this property does not raise any events. */ get delay(): number; set delay(value: number); /** * Gets or sets whether a selectable Part may be only partly * or must be completely enclosed by the rectangle given to #selectInRect. * The default value is false: parts must be completely inside the rectangle. * Setting this property does not raise any events. */ get isPartialInclusion(): boolean; set isPartialInclusion(value: boolean); /** * Gets or sets the Part used as the "rubber-band selection box" * that is stretched to follow the mouse, as feedback for what area will * be passed to #selectInRect upon a mouse-up. * * Initially this is a Part containing only a simple magenta rectangular Shape. * The object to be resized during dragging should be named "SHAPE". * Setting this property does not raise any events. * * Here is an example of changing the selection box to be a thicker bright green rectangle: * ```js * myDiagram.toolManager.dragSelectingTool.box = * $(go.Part, * { layerName: "Tool", selectable: false }, * $(go.Shape, * { name: "SHAPE", fill: null, stroke: "chartreuse", strokeWidth: 3 })); * ``` * Note that the Part should be put into a Layer that Layer#isTemporary. * * Modifying this property while this tool Tool#isActive might have no effect. */ get box(): Part | null; set box(value: Part | null); } /** * The PanningTool supports manual panning, where the user can shift the * Diagram#position by dragging the mouse. * * This tool is a standard mouse-move tool, the ToolManager#panningTool. * Although the ToolManager#dragSelectingTool takes precedence over this tool, * the DragSelectingTool only starts if there is a delay after a mouse-down event. * If it does not start, then this PanningTool gets a chance to start. * * This tool does not utilize any Adornments or tool handles. * This tool does not modify the model or conduct any transaction. * * If you want to programmatically "pan" the diagram, you can just set Diagram#position * or call methods such as Diagram#scroll, Diagram#scrollToRect, or Diagram#centerRect. * @extends Tool * @unrestricted * @category Tool */ export class PanningTool extends Tool { /** * You do not normally need to create an instance of this tool * because one already exists as the ToolManager#panningTool. * * The Tool#name of this tool is "Panning". */ constructor(); /** * This tool can run when the diagram allows scrolling and * the mouse has been dragged with the left button far enough away * from the mouse-down point to avoid being a click. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} */ canStart(): boolean; /** * Capture the mouse, change the diagram cursor to "move", and remember the Diagram#position. */ doActivate(): void; /** * Release the mouse and restore the default diagram cursor. */ doDeactivate(): void; /** * Restore the Diagram#position to what it was when this tool activated. */ doCancel(): void; /** * Modify the Diagram#position according to how much the mouse has moved. */ doMouseMove(): void; /** * Modify the Diagram#position according to how much the mouse has moved. */ doMouseUp(): void; /** * Gets or sets whether panning actions will allow * events to bubble **instead** of panning in the diagram. * * Set this to true to allow mobile devices to scroll the page with panning gestures on the diagram. * Otherwise, the panning events will be captured and used to pan inside of the diagram. * * The default value is false. */ get bubbles(): boolean; set bubbles(value: boolean); /** * This read-only property returns the Point that was the original value of Diagram#position when the panning operation started. * @since 1.1 */ get originalPosition(): Point; } /** * HTMLInfo is used to show and hide custom HTML page elements, such as a context menu, tooltip, or text editor made of HTML. * * Properties that can be set to an HTMLInfo include: * - TextEditingTool#defaultTextEditor * - TextBlock#textEditor * - GraphObject#contextMenu * - Diagram#contextMenu * - GraphObject#toolTip * - Diagram#toolTip * * When a context menu is set to an instance of HTMLInfo, * ContextMenuTool#showContextMenu and ContextMenuTool#hideContextMenu * call #show and #hide respectively. You may define #mainElement * instead of #hide in order to automatically use a default hide method. * * When a tooltip is set to an instance of HTMLInfo, * ToolManager#showToolTip and ToolManager#hideToolTip * call #show and #hide respectively. * * When a text editor is set to an instance of HTMLInfo, * TextEditingTool#doActivate calls #show and TextEditingTool#doDeactivate calls #hide. * * For HTMLInfo to work, you must define #show * and either #hide or #mainElement. * Typical usage will also stop the ContextMenuTool once the desired context action occurs, * typically by calling `diagram.currentTool.stopTool();`. * * Example usage of HTMLInfo can be found in the * Custom Context Menu and * HTML LightBox Context Menu samples, the * Custom TextEditingTool sample, and the * Text Editor implementation extension. * * Here is the outline for typical usage of HTMLInfo as a context menu: * ```js * // Assign an HTMLInfo to the Diagram: * myDiagram.contextMenu = $(go.HTMLInfo, { * show: showContextMenu, * hide: hideContextMenu * }); * * function showContextMenu(obj, diagram, tool) { * // Show the context menu HTML element: * SomeDOMElement.style.display = "block"; * * // Also show relevant buttons given the current state * // and the GraphObject obj; if null, the context menu is for the whole Diagram * } * * function hideContextMenu() { * SomeDOMElement.style.display = "none"; * } * * function buttonClick() { * // do some action when a context menu button is clicked * * // then: * myDiagram.currentTool.stopTool(); * } * ``` * * By default, TextEditingTool#defaultTextEditor is an instance of HTMLInfo. * You can see its default implementation details here. * @unrestricted * @since 1.7 * @category Tool */ export class HTMLInfo { /** * A newly constructed HTMLInfo can be assigned as a value of TextEditingTool#defaultTextEditor, TextBlock#textEditor * GraphObject#contextMenu, Diagram#contextMenu, GraphObject#toolTip, or Diagram#toolTip. */ constructor(); /** * Gets or sets the primary HTML Element that represents this HTMLInfo. * In a context menu, this would be the outermost HTML element, the one which typically * shows and hides. If this is set and #hide is not, HTMLInfo will automatically execute: * ```js * tool.mainElement.style.display = "none"; * ``` * * when #hide would typically be called. * * This is set only for convenience; the default value for this property is null. * @see #hide */ get mainElement(): HTMLElement | null; set mainElement(value: HTMLElement | null); /** * Gets or sets the function to call when an HTMLInfo is to be shown, * such as when used as the GraphObject#contextMenu or Diagram#toolTip or TextBlock#textEditor. * * If this is called by: * - ContextMenuTool#showContextMenu, the first argument is the GraphObject for which the context menu is being shown, or null for the diagram background. * - ToolManager#showToolTip, the first argument is the GraphObject for which the tooltip is being shown, or null for the diagram background. * - TextEditingTool#doActivate, the first argument is the TextBlock for which the text editor is being shown. * * If you need access to any bound data for the first argument, if it is non-null, you can get it via: * `obj.part.data` * and then you can look at any of the properties you have put on that data. * * When used as a context menu, typically shown elements, such as buttons, should call * `diagram.currentTool.stopTool();` when their action is completed. */ get show(): ((a: GraphObject, b: Diagram, c: Tool) => void) | null; set show(value: ((a: GraphObject, b: Diagram, c: Tool) => void) | null); /** * Gets or sets the function to call when an HTMLInfo is to be hidden. * The function should "hide" the HTMLInfo, either by removing any traces of it or otherwise * returning the page state to one where the HTMLInfo content is no longer considered active. * * Setting this is not strictly necessary, if no action is to be taken when hiding the HTMLInfo. * * If this is called by: * - ContextMenuTool#hideContextMenu, the second argument is the ContextMenuTool. * - ToolManager#hideToolTip, the second argument is the ToolManager. * - TextEditingTool#doDeactivate, the second argument is the TextEditingTool. * * @see #mainElement */ get hide(): ((a: Diagram, b: Tool) => void) | null; set hide(value: ((a: Diagram, b: Tool) => void) | null); /** * Gets or sets a function that returns the primary value associated with this HTMLInfo, * such as the string value of a text editor, which would be solicited by the TextEditingTool. * * This typically returns a string. */ get valueFunction(): (() => any) | null; set valueFunction(value: (() => any) | null); } /** * The ContextMenuTool is used to create and show a context menu. * It automatically disables any browser context menu. * * Define context menus on individual GraphObjects by setting GraphObject#contextMenu. * Define a context menu for the diagram background by setting Diagram#contextMenu. * * This tool is a standard mouse-down tool, the ToolManager#contextMenuTool. * * This tool does not utilize any tool handles. * This tool does not modify the model or conduct any transaction, * although any code invoked by context menu commands might do so. * * There are examples of customizing this tool in the * Custom Context Menu and * HTML LightBox Context Menu samples. * * If you want to programmatically show a context menu for a particular GraphObject or for the * whole diagram, call CommandHandler#showContextMenu. * That command method is also invoked by the Menu key on the keyboard. * * Normally this shows a context menu (if available) on a right-mouse-up event. * If you want it to happen on a right-mouse-down event, you'll need to move this tool * from the ToolManager#mouseUpTools list to the ToolManager#mouseDownTools list: * ```js * myDiagram.toolManager.mouseDownTools.add(myDiagram.toolManager.replaceTool("ContextMenu", null)); * ``` * @extends Tool * @unrestricted * @category Tool */ export class ContextMenuTool extends Tool { /** * You do not normally need to create an instance of this tool * because one already exists as the ToolManager#contextMenuTool, which you can modify. * * The Tool#name of this tool is "ContextMenu". */ constructor(); /** * Return true if it's a single mouse right click that hasn't moved Tool#isBeyondDragSize * and that is on a GraphObject with a GraphObject#contextMenu. * This is also true if the mouse right click is in the diagram background * and the diagram's Diagram#contextMenu is non-null. * * On touch devices, a special default context menu will appear even if no object with a context menu is found. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} */ canStart(): boolean; /** * Find a GraphObject at the current mouse point with a GraphObject#contextMenu, * or return the Diagram if there is a Diagram#contextMenu. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {GraphObject|Diagram=} obj Optional GraphObject with which to start searching for a context menu. * If null, the Diagram will be used. If no argument is specified, this method will look for an object at the current mouse point. * @return {GraphObject|Diagram|null} something with a `contextMenu`, * or null if nothing can be found with a context menu at the current mouse point. */ findObjectWithContextMenu(obj?: GraphObject | Diagram): GraphObject | Diagram | null; /** * Do nothing, activation is special and relies on doMouseUp */ doActivate(): void; /** * Activate this but also execute the normal behavior that would happen on a mouse-up * if this tool is in the ToolManager#mouseDownTools list. * Perform ActionTool#doMouseDown if a ContextMenuButton was hit. */ doMouseDown(): void; /** * If there is something found by #findObjectWithContextMenu, * call #showContextMenu with that object's GraphObject#contextMenu * or the Diagram#contextMenu. * * Once a context menu is being shown, * if a click occurs on a part of the context menu, call Tool#standardMouseClick. * Otherwise if the click occurs elsewhere, just stop this tool. * Unlike most tools, the first mouse-up should not stop this tool. */ doMouseUp(): void; /** * Consider calling Tool#stopTool. * @expose * @param currobj */ maybeStopTool(currobj: GraphObject): void; /** * Handle mouse-enter, mouse-over, and mouse-leave events, as well as tooltips. */ doMouseMove(): void; /** * Show an Adornment or HTMLInfo as a context menu. * * This method is called by the context click (Tool#doMouseDown) and CommandHandler#showContextMenu. * If you want to programmatically show a context menu for a particular GraphObject or for the * whole diagram, do not call this method, which only does one small piece of the process of * bringing up a context menu. * Instead call CommandHandler#showContextMenu, which will start this tool * and eventually call this method and handle additional input events. * * For Adornment context menus: If the object's containing Part is data-bound, * this sets the contextmenu's `Part.data` to the same value. * The Adornment#adornedObject property is set to the GraphObject for which the menu is being shown. * * This method sets the #currentContextMenu. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Adornment|HTMLInfo} contextmenu * @param {GraphObject} obj the GraphObject for which the context menu is being shown; * this is null if the contextmenu is being shown for the diagram background. */ showContextMenu(contextmenu: Adornment | HTMLInfo, obj: GraphObject | null): void; /** * This is called by #showContextMenu to position the context menu within the viewport. * It normally goes just below the cursor. * But if the mouse is too close to the right edge or the bottom edge of the viewport, * it is positioned left and/or above the cursor. * * This method only operates if the context menu, an Adornment, does not have a Adornment#placeholder. * When there is a Placeholder in the context menu, that Adornment is automatically positioned * so that the Placeholder is positioned at the adorned object, the second argument to this method. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * * If you override this method to position the context menu, * the context menu has already been measured but not arranged, * so you can use its GraphObject#measuredBounds width and height * but not its GraphObject#actualBounds. * @expose * @param {Adornment} contextmenu * @param {GraphObject} obj The GraphObject getting the context menu, * or null if the context menu is for the diagram background. */ positionContextMenu(contextmenu: Adornment, obj: GraphObject | null): void; /** * Hide any context menu. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ hideContextMenu(): void; /** * This is the HTMLInfo#show method for the #defaultTouchContextMenu. * * If the object's containing Part is data-bound, * set the contextmenu's `Part.data` to the same value. * The Adornment#adornedObject property is set to the GraphObject * for which the menu is being shown. * * The menu carries some default CSS styling and uses the following CSS classes: * * * `goCXforeground` for the DIV containing the buttons * * `goCXbackground` for the darker DIV behind the context menu * * `goCXul` for the HTML `ul` items * * `goCXli` for the HTML `li` tag items * * `goCXa` for the HTML `a` tag items * * This method may be overridden. * Please read the Introduction page on Extensions * for how to override methods and how to call this base method. * @expose */ showDefaultContextMenu(): void; /** * This is the HTMLInfo#hide method for the #defaultTouchContextMenu. * * This method may be overridden. * Please read the Introduction page on Extensions * for how to override methods and how to call this base method. * @expose */ hideDefaultContextMenu(): void; /** * Gets or sets the currently showing context menu, or null if there is none. * This is typically only set in #showContextMenu and not by the user. * It is also typically set to null in #hideContextMenu. */ get currentContextMenu(): Adornment | HTMLInfo | null; set currentContextMenu(value: Adornment | HTMLInfo | null); /** * Gets or sets the HTMLInfo or Adornment that acts as the default touch context menu. * On touch devices, this context menu will appear even there is no context menu defined. * * You can disable this functionality by setting this property to null. * * By default shows a set of HTML elements acting as a context menu. * @since 1.7 */ get defaultTouchContextMenu(): Adornment | HTMLInfo | null; set defaultTouchContextMenu(value: Adornment | HTMLInfo | null); /** * Gets or sets the GraphObject found at the mouse point that has a context menu. * This property remembers the result returned by #findObjectWithContextMenu if it is a GraphObject. * This value is passed to #showContextMenu as the second argument. * The value will be null if the context menu is for the diagram rather than for a particular GraphObject. * @since 1.4 */ get currentObject(): GraphObject | null; set currentObject(value: GraphObject | null); /** * This read-only property returns the original mouse-down point in document coordinates. */ get mouseDownPoint(): Point; } /** * The TextEditingTool is used to let the user interactively edit text in place. * This sets the TextBlock#text property; you may want to save the changed text to the model * by using a TwoWay Binding on the "text" property of editable TextBlocks. * * Typically this is used by setting the TextBlock#editable property to true * on a particular TextBlock in a part. * When the part is selected and the user clicks on the TextBlock * or invokes the CommandHandler#editTextBlock command, * this tool is started and it uses an HTMLTextArea to perform in-place text editing. * (For more details see the description for TextEditingTool#doActivate.) * * The TextBlock is accessible as the TextEditingTool#textBlock property. * The text editor is accessible as the TextEditingTool#currentTextEditor property. * From the text editor control one can access the TextBlock being edited via the * 'textEditingTool' property to get to this tool, from which one can use * the TextEditingTool#textBlock property. * * You can disable mouse clicking from starting this text editing tool * by setting Tool#isEnabled to false. * You can disable the F2 key from starting this text editing tool * by making sure Part#canEdit returns false, * by either setting Diagram#allowTextEdit to false * or by setting Part#textEditable to false. * * If you want to programmatically start the user editing a particular TextBlock, * call CommandHandler#editTextBlock. * That command method is also invoked by the F2 key on the keyboard. *

* For a general discussion of text editing validation, see: Introduction to Text Validation. * For customizing the TextEditingTool, read about HTMLInfo and see Introduction to Text Editors. * @extends Tool * @unrestricted * @category Tool */ export class TextEditingTool extends Tool { /** * You do not normally need to create an instance of this tool * because one already exists as the ToolManager#textEditingTool, which you can modify. * * The Tool#name of this tool is "TextEditing". */ constructor(); /** * A possible value for TextEditingTool#acceptText, the text editing control has lost focus. * @constant */ static LostFocus: EnumValue; /** * A possible value for TextEditingTool#acceptText, the user has clicked somewhere else in the diagram. * @constant */ static MouseDown: EnumValue; /** * A possible value for TextEditingTool#acceptText, the user has typed TAB. * @constant */ static Tab: EnumValue; /** * A possible value for TextEditingTool#acceptText, the user has typed ENTER. * @constant */ static Enter: EnumValue; /** * A possible value for TextEditingTool#starting, * A single click on a TextBlock with TextBlock#editable property set to true * will start in-place editing. * @constant */ static SingleClick: EnumValue; /** * A possible value for TextEditingTool#starting, * A single click on a TextBlock with TextBlock#editable property set to true * will start in-place editing, but only if the Part that the TextBlock is in is already selected. * @constant */ static SingleClickSelected: EnumValue; /** * A possible value for TextEditingTool#starting, * A double click on a TextBlock with TextBlock#editable property set to true * will start in-place editing. * @constant */ static DoubleClick: EnumValue; /** * A possible value for #state, * this is the starting value before the tool is activated. * @constant */ static StateNone: EnumValue; /** * A possible value for #state, * TextEditingTool#doActivate sets the value of #state to this. * @constant */ static StateActive: EnumValue; /** * A possible value for #state, * The default text editor receiving focus sets the value of #state to this. * @constant */ static StateEditing: EnumValue; /** * A possible value for #state, * TextEditingTool.acceptText sets the value of #state to this. * @constant */ static StateValidating: EnumValue; /** * A possible value for #state, * If validation fails, TextEditingTool.acceptText sets the value of #state to this. * @constant */ static StateInvalid: EnumValue; /** * A possible value for #state, * Once accepted and the tool begins the "TextEditing" transaction, the value of #state is set to this. * @constant */ static StateValidated: EnumValue; /** * Gets or sets the TextBlock that is being edited. * This property is initially null and is set in TextEditingTool#doActivate * as the TextBlock at the mouse click point. * However, if you set this property beforehand, TextEditingTool#doActivate * will not set it, and this tool will edit the given TextBlock. */ get textBlock(): TextBlock | null; set textBlock(value: TextBlock | null); /** * Gets or sets the HTMLInfo that is editing the text. */ get currentTextEditor(): HTMLInfo | null; set currentTextEditor(value: HTMLInfo | null); /** * Gets or sets the default HTMLInfo that edits the text. * * When TextEditingTool#doActivate is called, the #currentTextEditor is set to this value by default. * If a TextBlock#textEditor is specified on the TextBlock, that editor is used instead. * * This tool will call HTMLInfo#show during #doActivate, * and HTMLInfo#hide during #doDeactivate. * * By default the value is an HTMLInfo, and the HTMLInfo#mainElement is an `HTMLTextArea`. * You can see the default implementation details here. * * For typical operation, HTMLInfo implementations should have a way of calling TextEditingTool#acceptText. */ get defaultTextEditor(): HTMLInfo; set defaultTextEditor(value: HTMLInfo); /** * Gets or sets how user gestures can start in-place editing of text. * * Possible values are TextEditingTool.SingleClickSelected, TextEditingTool.SingleClick, and TextEditingTool.DoubleClick. * * The default is TextEditingTool.SingleClickSelected */ get starting(): EnumValue; set starting(value: EnumValue); /** * This may run when there is a mouse-click on a TextBlock for which the * TextBlock#editable property is true in a Part * that Part#isSelected. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} */ canStart(): boolean; /** * This calls TextEditingTool#doActivate if there is a * #textBlock set. #doActivate attempts to set #textBlock if it is null. */ doStart(): void; /** * Start editing the text for a #textBlock. * * If TextEditingTool#textBlock is not already specified, this looks for one at the current * mouse point. If none is found, this method does nothing. * * This method sets #currentTextEditor. * If TextBlock#textEditor is defined on the TextBlock it will use that as the value. * By default, it uses the value of #defaultTextEditor, which is an HTMLInfo * showing an HTML textarea, with the CSS class `goTXarea`. * * If the #currentTextEditor is an HTMLInfo, this method calls HTMLInfo#show on that instance. * * This sets Tool#isActive to true. * Custom text editors should call TextEditingTool#acceptText to finish the edit * by modifying the TextBlock and committing the edit transaction. * Or call TextEditingTool#doCancel to abort the edit. */ doActivate(): void; /** * Abort any text editing operation. */ doCancel(): void; /** * A click (mouse up) calls TextEditingTool#doActivate if this tool is not already active * and if TextEditingTool#canStart returns true. */ doMouseUp(): void; /** * This calls #acceptText with the reason TextEditingTool.MouseDown, * if this tool Tool#isActive. */ doMouseDown(): void; /** * Finish editing by trying to accept the new text. * * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {EnumValue} reason The reason must be either TextEditingTool.LostFocus, * TextEditingTool.MouseDown, TextEditingTool.Tab, or TextEditingTool.Enter. */ acceptText(reason: EnumValue): void; /** * Call the #textBlock's TextBlock#errorFunction, if there is one, * and then show the text editor again. * This is called only when the #isValidText method returned false. * The value of #state will be StateInvalid. * This method may be overridden. * You may wish to override this method in order to not continue showing the editor. * @expose * @param oldstring * @param newstring * @since 2.1 */ doError(oldstring: string, newstring: string): void; /** * Call the #textBlock's TextBlock#textEdited event handler, if there is one. * This is called just after the TextBlock#text has been set to the new string value. * When this method returns, this tool raises the "TextEdited" DiagramEvent * and commits the transaction. * This method may be overridden. * @expose * @param oldstring * @param newstring * @since 2.1 */ doSuccess(oldstring: string, newstring: string): void; /** * Release the mouse. * * If the #currentTextEditor is an HTMLInfo, this calls HTMLInfo#hide. */ doDeactivate(): void; /** * This predicate checks any TextBlock#textValidation predicate and * this tool's #textValidation predicate to make sure the TextBlock#text * property may be set to the new string. * * This method may be overridden, although usually it is sufficient to set #textValidation. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {TextBlock} textblock the TextBlock that is being edited. * @param {string} oldstr the previous string value. * @param {string} newstr the proposed new string value. * @return {boolean} true if the new string is valid for the given TextBlock. */ isValidText(textblock: TextBlock, oldstr: string, newstr: string): boolean; /** * Gets or sets the predicate that determines whether or not a string of text is valid. * If this is non-null, this predicate is called in addition to any TextBlock#textValidation predicate. * See #isValidText for more details. * The default predicate is null, which is equivalent to simply returning true. * * The function, if supplied, must not have any side-effects. */ get textValidation(): ((aTextBlock: TextBlock, oldString: string, newString: string) => boolean) | null; set textValidation(value: ((aTextBlock: TextBlock, oldString: string, newString: string) => boolean) | null); set minimumEditorScale(value: number); /** * Gets or sets whether to select (highlight) the editable text when the TextEditingTool is activated. * The default is true. * @since 1.5 */ get selectsTextOnActivate(): boolean; set selectsTextOnActivate(value: boolean); /** * Gets or sets the state of the TextEditingTool. * The only accepted values are listed as constant properties of TextEditingTool, including: * - TextEditingTool.StateNone * - TextEditingTool.StateActive * - TextEditingTool.StateEditing * - TextEditingTool.StateValidating * - TextEditingTool.StateValidated * * The starting value value is TextEditingTool.StateNone, * TextEditingTool#doActivate sets the value to TextEditingTool.StateActive. * The default text editor receiving focus sets the value to TextEditingTool.StateEditing. * TextEditingTool#acceptText sets the value to TextEditingTool.StateValidating. * Once accepted and the tool begins the "TextEditing" transaction, the value is set to TextEditingTool.StateValidated. * @since 1.7 */ get state(): EnumValue; set state(value: EnumValue); /** * This method returns a temporary TextBlock used for measuring text during editing. * The TextBlock.text is set to the parameter's value, * and the TextBlock is measured with the last available width of the #textBlock. * * Text editors can use the GraphObject#measuredBounds and TextBlock#lineCount * to determine a reasonable size for their text areas. * @param {string} text the text to measure * @return {TextBlock} * @since 1.7 */ measureTemporaryTextBlock(text: string): TextBlock; } /** * An EasingFunction describes how much to modify a scalar value based on * the current time, the start value, the change in value, and the duration. * @category Type */ export type EasingFunction = ((currentTime: number, startValue: number, byValue: number, duration: number) => number); /** * AnimationManager handles animations in a Diagram. Each Diagram has one, Diagram#animationManager. * Setting the Model, performing a Layout, Group expansion and Tree expansion automatically start animations through * the #defaultAnimation. Animations can be manually started by creating Animations, which are associated with an * AnimationManager. * * Animation is enabled by default, setting the #isEnabled property to false will turn off animations for a Diagram. * * When the #defaultAnimation begins it raises the `"AnimationStarting"` Diagram event, * upon completion it raises the `"AnimationFinished"` Diagram event. * * The #defaultAnimation, if running, will stop if a new transaction is started, if an undo or redo is called, * if a layout is invalidated, or if a model is replaced. * When an Animation is stopped, the Diagram immediately finishes the animation and draws the final state. * Animations can be stopped programmatically with the methods AnimationManager#stopAnimation or Animation#stop. * @since 1.4 * @unrestricted */ export class AnimationManager { /** * You do not normally need to create an instance of this class because one already exists as the Diagram#animationManager, which you can modify. * @param {Partial=} init Optional initialization properties. * This is typically only used in the Diagram constructor to set properties on the Diagram#animationManager. */ constructor(init?: Partial); /** * This method is passed the reason a default animation is to begin, * and must return true or false based on whether or not the animation is to be allowed. * Returning true means the animation will occur, returning false will stop the animation's setup. * * By default, this method always returns true. * Setting this to a function that always returns false will disable all default animations, * but allow other animations, such as AnimationTriggers, to run. * * These are the possible reasons GoJS will begin an animation: * * **Called by CommandHandler:** * - "Collapse SubGraph" * - "Expand SubGraph" * - "Collapse Tree" * - "Expand Tree" * - "Scroll To Part" * - "Zoom To Fit" * **Called by Diagram:** * - "Model" * - "Layout" * **Called by AnimationTriggers:** * - "Trigger" * * Example usage: * * ```js * // disallow expand/collapse animations, but allow all other default animations: * myDiagram.animationManager.canStart = function(reason) { * if (reason === "Expand Tree") return false; * return true; * } * * // disallow all default animations: * myDiagram.animationManager.canStart = function(reason) { * return false; * } * ``` * @param {string} reason Reason for starting the animation * @return {boolean} * @since 2.1 */ canStart(reason: string): boolean; /** * Stops the #defaultAnimation and updates the Diagram to its final state. * * If the argument is true, this stops all running animations. * If an Animation was about to begin, it will be cancelled. * * If the AnimationManager#defaultAnimation is running, this will raise the `"AnimationFinished"` Diagram event. * @param {boolean=} stopsAllAnimations Whether to stop all animations, instead of just the #defaultAnimation. Default false. */ stopAnimation(stopsAllAnimations?: boolean): void; /** * Gets or sets whether this AnimationManager operates. * * The default value is `true`. * Setting this to `false` does not stop an animation, it only stops future animations. * To stop any ongoing animation, use #stopAnimation. * To disable only the default animations, set #canStart to a function that always returns `false`. * * If any indefinite animations (animations with Animation#runCount set to `Infinity`) were running * when this is set to `false`, they will be resumed when this is set to `true`. * * Setting this property does not raise any events. * @see #canStart */ get isEnabled(): boolean; set isEnabled(value: boolean); /** * Gets or sets the default duration, in milliseconds, used as the duration for the #defaultAnimation * and for animations that have their Animation#duration set to `NaN`. * * Typically these values are short. The default value is 600 milliseconds. * The value must be a number greater than or equal to 1. * Setting this property does not raise any events. * * @see Animation#duration */ get duration(): number; set duration(value: number); /** * This read-only property is true when the animation manager is currently animating any animation, * including the #defaultAnimation. * * This value cannot be set, but animation can be stopped by calling #stopAnimation, * and it can be prevented by setting #isEnabled. */ get isAnimating(): boolean; /** * This read-only property is true when the animation manager is in the middle of an animation tick. * Animation only operates on GraphObjects during ticks, but code outside of AnimationManager's control may execute between ticks. * * `isTicking` can only be true when #isAnimating is also true. */ get isTicking(): boolean; /** * Gets or sets whether a default animation is performed on an initial layout. * * The default value is true. * Changing the value does not affect any ongoing animation. * Setting this property does not raise any events. * @since 1.6 */ get isInitial(): boolean; set isInitial(value: boolean); /** * This read-only property gets the Animation that carries out the default built-in GoJS animations. * This animation is usually only referenced to modify default animation properties, * such as the Animation#easing or Animation#duration. * * You should not add anything to or start the default animation, GoJS does so automatically, internally. * When the default animation begins it raises the `"AnimationStarting"` Diagram event, * upon completion it raises the `"AnimationFinished"` Diagram event. * You should not modify the properties Animation#runCount or Animation#reversible on the default animation. * * See the Introduction Page on Animations for more detail. * @since 2.1 */ get defaultAnimation(): Animation; /** * Gets the set of currently animating Animations being managed by this AnimationManager, including any running #defaultAnimation. * @since 2.1 */ get activeAnimations(): Set; /** * Gets or sets the initial animation style that is set up by the #defaultAnimation. * This can be AnimationManager.Default, AnimationManager.AnimateLocations, or AnimationManager.None. * - If set to AnimationManager.Default, the initial animation will "fade up" * the Diagram's contents by animating the Diagram#position and Diagram#opacity. * - If set to AnimationManager.AnimateLocations, the initial animation will animate Part locations from `(0, 0)` to their values, as GoJS 2.0 and prior do. * - If set to AnimationManager.None, no initial animation will happen by default, * which this allows you to specify your own initial animation by defining a `"InitialAnimationStarting"` DiagramEvent listener with Diagram#addDiagramListener. * * An example custom initial animation, which zooms the Diagram into view: * * ```js * myDiagram.animationManager.initialAnimationStyle = go.AnimationManager.None; * myDiagram.addDiagramListener('InitialAnimationStarting', e => { * var animation = e.subject.defaultAnimation; * animation.easing = go.Animation.EaseOutExpo; * animation.duration = 900; * animation.add(e.diagram, 'scale', 0.1, 1); * animation.add(e.diagram, 'opacity', 0, 1); * }); * ``` * * * @since 2.1 */ get initialAnimationStyle(): EnumValue; set initialAnimationStyle(value: EnumValue); /** * Defines a new named effect to be used in animation, along with a function that tells the AnimationManager how to modify that property. * * Effect names do not need to reflect GraphObject properties, and you can define an effect with a function that modifies several properties for convenience. * * For example, one could define an animation effect named `"moveAndSpin"` which modifies the object's `position` and `angle`. * * Most commonly, an effect is defined with one GraphObject property in mind to be animated, * and the function uses the start and end values, an easing function, and the times to determine a new value for each tick of animation. * Here is an example for animating the fill of GraphObjects: * * ```js * // This presumes the object to be animated is a Shape * go.AnimationManager.defineAnimationEffect('fill', (obj, startValue, endValue, easing, currentTime, duration, animation) => { * var hueValue = easing(currentTime, startValue, endValue - startValue, duration); * obj.fill = 'hsl(' + hueValue + ', 100%, 80%)'; * }); * ``` * * @param {string} effectName Named effect to animate * @param {Function} animationFunction Function * that transforms the property values. It takes the animated object, start value, end value, * easing function (the Animation#easing), current time, duration, and animation state. It should modify one or more properties on the object. * @since 2.1 */ static defineAnimationEffect(effectName: string, animationFunction: (obj: Diagram | GraphObject, startValue: any, endValue: any, easing: EasingFunction, currentTime: number, duration: number, animation: Animation) => void): void; /** * Used as the default value for #initialAnimationStyle. * The default initial animation style will "fade up" and in the Diagram's contents by animating the Diagram#position and Diagram#opacity. * To make the default initial animation behave like GoJS 2.0, set #initialAnimationStyle to AnimationManager.AnimateLocations. * To customize the default initial animation, set #initialAnimationStyle to AnimationManager.None * and define a `"InitialAnimationStarting"` DiagramEvent listener with Diagram#addDiagramListener. * See #initialAnimationStyle for details and examples. * @constant * @since 2.1 */ static Default: EnumValue; /** * Used as a value for #initialAnimationStyle. * This value will cause initial animations to capture Part locations and animate them from `(0, 0)` to those location values. * This was the default initial animation behavior in GoJS 2.0 and prior. * See #initialAnimationStyle for details and examples. * @constant * @since 2.1 */ static AnimateLocations: EnumValue; /** * Used as a value for #initialAnimationStyle. * This will turn off the initial animation, but also allows for customizing the initial animation by adding your own properties * if you define a `"InitialAnimationStarting"` listener with Diagram#addDiagramListener. * See #initialAnimationStyle for details and examples. * @constant * @since 2.1 */ static None: EnumValue; } /** * Animations are used to animate GraphObject and Diagram properties. * * This class is useful for creating manual animations. * If you wish to animate particular properties on a GraphObject every time their value changes, * you may want to use AnimationTriggers instead, which automatically create and start Animations. * * The AnimationManager#defaultAnimation is an instance of this class, and carries out the * default animations in GoJS: Model load, layout, expand and collapse, and so on. * See the Introduction Page on Animations for more detail on the different kinds of animations. * * Manual animations are set up by creating an instance of this class, and calling #add at least once, then calling #start. * The method #add specifies which objects and which animation effects/properties to animate, plus start and end values for the property. * As objects are added to an Animation, the Animation infers which Diagram and AnimationManager is relevant. * * Animations are started by calling #start, and stopped when the #duration is reached, or when #stop is called, * or stopped when AnimationManager#stopAnimation is called with `true` as its argument. * * Animations can continue indefinitely if #runCount is set to `Infinity`. * Animations can act upon temporary copies of an object that will get destroyed by calling #addTemporaryPart. * This is useful when crafting cosmetic animations of parts that are about to be deleted: * Since the part will no longer exist, you can instead animate a temporary part disappearing. * * A simple example usage is this: * ```js * var node = myDiagram.nodes.first(); * var shape = part.findObject("SHAPE"); // assumes this Node contains a go.Shape with .name = "SHAPE" * var animation = new go.Animation(); * // Animate this Node from its current position to (400, 500) * animation.add(node, "position", node.position, new go.Point(400, 500)); * // Animate the fill of the Shape within the Node, from its current color to blue * animation.add(shape, "fill", shape.fill, "blue"); * // Both of these effects will animate simultaneously when start() is called: * animation.start(); * ``` * * See the Introduction Page on Animations and the Custom Animations sample * for more example usage of the Animation class. * * Unlike the AnimationManager#defaultAnimation, Animations can be started any time, * and do not stop automatically when a new transaction begins. * * * @since 2.1 * @unrestricted */ export class Animation { /** * The constructor creates an Animation. * A single Animation can animate multiple objects via multiple calls to #add. * When you are ready to begin the animation, call #start. * @param {Partial=} init Optional properties to initialize. */ constructor(init?: Partial); /** * @expose * (undocumented) Debug only. */ suspend(): void; /** * @expose * (undocumented) Debug only. */ advanceTo(duration: number, resume?: boolean): void; /** * Start this animation. * * This adds the Animation to its AnimationManager's list of active animations. * The AnimationManager is inferred from the list of objects to be animated, by inspecting their Diagram. * * This does nothing if there are no objects to animate. * @return {Animation} this Animation */ start(): this; /** * Add a temporary Part to this animation. * This part will be added to the Diagram when the animation is started, * and removed from the Diagram when the animation completes. * This is intended to be used with #add, to animate properties of this Part or its elements. * * The temporary part added is typically either a GraphObject#copy of an existing Part, * which is to be deleted and requires a copy for animated effects, or else a wholly new temporary Part, * constructed in memory for the purpose of creating some effect. * @param {Part} part A part to add to the Diagram at the start of the animation and remove at the end. * This is typically either a copied Part already in the Diagram, to animate its deletion, * or a Part created programmatically to be used for some effect. * @param {Diagram=} diagram The Diagram to add the temporary part to, and remove it from, at the start and end of animation, respectively. * @return {Animation} this Animation */ addTemporaryPart(part: Part, diagram: Diagram): this; /** * Add an object (GraphObject or Diagram) and effect name, with specified start and end values, to this Animation. * * @param {GraphObject|Diagram} obj GraphObject or Diagram to animate. * @param {string} effectName Animation effect name, such as `"scale"` to change GraphObject.scale. * By default the supported properties are, for GraphObjects: * * `"position"` * * `"location"` (on Parts) * * `"scale"` * * `"opacity"` * * `"angle"` * * `"desiredSize"` * * `"width"` * * `"height"` * * `"background"` * * `"fill"` (on Shapes) * * `"strokeWidth"` (on Shapes) * * `"strokeDashOffset"` (on Shapes) * * `"stroke"` (on Shapes, TextBlocks) * * For Diagrams: * * `"position"` * * `"scale"` * * `"opacity"` * * More properties can be supported by defining new effects with AnimationManager.defineAnimationEffect. * @param {*} startValue The starting value for the animated property. Often this is the current value of the property. * @param {*} endValue The ending value for the animated property. Even if the animation is just cosmetic, this must be a valid value for the property. * For instance, for GraphObject#scale, you cannot animate to 0, as this is an invalid scale value. * Instead you would animate to a very small (but still valid) value, such as 0.001. * @param {boolean=} cosmetic Determines if the animation should revert the property value to the start value at the end of animation. * Default false. This is commonly used when animating opacity or scale of "disappearing" nodes during collapse. * Even though the node may appear to go to scale 0.001, the programmer usually wants the scale to reflect its prior value, once hidden. * @return {Animation} this Animation */ add(obj: GraphObject | Diagram, effectName: string, startValue: any, endValue: any, cosmetic?: boolean): this; /** * Stops a running Animation and updates the animating objects to their final state. * * If an animation was about to begin, it is cancelled. * @return {Animation} this Animation */ stop(): this; /** * Gets or sets the duration for animations, in milliseconds. * * The default value is `NaN`, which means it inherits the default value from the AnimationManager#duration, * which defaults to 600 milliseconds. * * The value must be a number greater than or equal to 1, or `NaN`. * Setting this property does not raise any events. */ get duration(): number; set duration(value: number); /** * Gets or sets whether this Animation will repeat its animation in reverse at the end of the duration. Default false. * * A reversible Animation, if stopped early, will end at its original state. * Setting this to true doubles the effective #duration of the Animation. * * This property should not be set on the AnimationManager#defaultAnimation */ get reversible(): boolean; set reversible(value: boolean); /** * Gets or sets whether this Animation should be repeat, and how many times. The default is 1, which means the animation does not repeat. * * This can be set to any non-zero positive integer, or `Infinity`. Setting this to `Infinity` will repeat an animation forever. * * This property should not be set on the AnimationManager#defaultAnimation * * @see #reversible */ get runCount(): number; set runCount(value: number); /** * Gets or sets the function to execute when the user Animation finishes. * * By default this property is null. */ get finished(): ((animation: Animation) => void) | null; set finished(value: ((animation: Animation) => void) | null); /** * Gets or sets the easing function this Animation will use to modify default properties. * * Pre-defined animatable values are processed by passing scalars into this easing function. * * The default value is Animation.EaseInOutQuad. * * * The value can be an arbitrary easing function, or one of the six provided: * Animation.EaseLinear, Animation.EaseInOutQuad, Animation.EaseInQuad, * Animation.EaseOutQuad, Animation.EaseInExpo, Animation.EaseOutExpo. * */ get easing(): EasingFunction; set easing(value: EasingFunction); /** * Gets or sets whether this Animation should allow an unconstrained viewport during the runtime of the animation. * This temporarily sets the Diagram#scrollMode to Diagram.InfiniteScroll, and restores the value at the end of the animation. * This is done so that animating objects can move out of the viewport temporarily during the animation and not trigger scrollbars. * * This may be useful to set for animations that have objects or the Diagram bounds animate from outside the viewport into the view. * The default value is true. */ get isViewportUnconstrained(): boolean; set isViewportUnconstrained(value: boolean); /** * This read-only property is true when the Animation is currently running. * * This value cannot be set, but Animation can be stopped by calling #stop. */ get isAnimating(): boolean; /** * Gets the ObjectData associated with this GraphObject or Diagram. * If no state exists, this creates and returns a new ObjectData. * * This can be used to store temporary information per animated object during the course of an animation. * This state is cleared at the end of an animation. */ getTemporaryState(obj: GraphObject | Diagram): ObjectData; /** * Built-in static function for computing interpolated values. Can be used as a value for Animation#easing. * @constant */ static EaseLinear: EasingFunction; /** * Built-in static function for computing interpolated values. Can be used as a value for Animation#easing. * This is the default value for Animation#easing. * @constant */ static EaseInOutQuad: EasingFunction; /** * Built-in static function for computing interpolated values. Can be used as a value for Animation#easing. * @constant */ static EaseInQuad: EasingFunction; /** * Built-in static function for computing interpolated values. Can be used as a value for Animation#easing. * @constant */ static EaseOutQuad: EasingFunction; /** * Built-in static function for computing interpolated values. Can be used as a value for Animation#easing. * @constant */ static EaseInExpo: EasingFunction; /** * Built-in static function for computing interpolated values. Can be used as a value for Animation#easing. * @constant */ static EaseOutExpo: EasingFunction; } /** * An AnimationTrigger describes how to automatically animate a property on a GraphObject * when it changes value. * The target property name is a string, and all name matching is case-sensitive. * * Triggers will be shared by all copies of the template's GraphObjects. * You can include AnimationTriggers in your templates just like Bindings are included: * * ```js * $(go.Panel, "Vertical", * // This trigger uses the default value of AnimationTrigger.startCondition: * // If a transaction is ongoing and Panel.position is changed, this trigger will animate * // all changes to Panel.position at the end of the next transaction, in one bundled Animation. * // If no transaction is ongoing, then it will animate this value immediately. * new go.AnimationTrigger("position"), * { * // ... Panel properties * }, * $(go.Shape, * // Animate all changes to Shape.opacity immediately * new go.AnimationTrigger("opacity", null, go.AnimationTrigger.Immediate), * { * // ... Shape properties * } * ) * ``` * When the #startCondition is AnimationTrigger.Default, * GoJS will attempt to AnimationTrigger.Bundled or AnimationTrigger.Immediate based on the state of the transaction. * If no transaction is ongoing, this trigger will treat the default as using AnimationTrigger.Immediate. * Otherwise it will work as AnimationTrigger.Bundled. * * When the #startCondition is AnimationTrigger.Bundled, * the AnimationManager will use the default animation to prepare a single Animation that begins when the current transaction has ended. * This animation may be canceled if a new transaction is started. * * When the #startCondition is AnimationTrigger.Immediate, * a new animation will be created for every instance of the property changed, and started immediately, * and run until completion. This may be useful for cosmetic changes, such as animating * the opacity or color of an object on mouseEnter or mouseLeave. * * You can only specify properties that exist on the GraphObject, and are also registered with AnimationManager.defineAnimationEffect. * By default these properties are: * * * `"position"` * * `"location"` (on Parts) * * `"scale"` * * `"opacity"` * * `"angle"` * * `"desiredSize"` * * `"width"` * * `"height"` * * `"background"` * * `"fill"` (on Shapes) * * `"strokeWidth"` (on Shapes) * * `"strokeDashOffset"` (on Shapes) * * `"stroke"` (on Shapes, TextBlocks) * * Examples of defining additional animation properties are given in the Introduction Page on Animations. * * @since 2.1 * @unrestricted */ export class AnimationTrigger { /** * This constructor creates an AnimationTrigger. These are typically constructed within Part templates. * Using GraphObject.make it might look like: * * ```js * var $ = go.GraphObject.make; * * // ... * $(go.Shape, * // Animate all changes to Shape.opacity immediately * new go.AnimationTrigger("opacity", null, go.AnimationTrigger.Immediate), * { * // ... * } * ) * ``` * @param {string} propertyName A string naming the target property to animate. * This should not be the empty string. * @param {Object=} animationSettings An optional Object describing properties to set on animations created by this AnimationTrigger. * See the #animationSettings property for detail. * If specified, this also sets the #startCondition to AnimationTrigger.Immediate. * @param {EnumValue=} startCondition An optional EnumValue to set the #startCondition property. */ constructor(propertyName: string, animationSettings?: { duration?: number; finished?: (animation: Animation) => void; easing?: EasingFunction; }, startCondition?: EnumValue); /** * Create a copy of this AnimationTrigger, with the same property values. * @expose * @return {AnimationTrigger} */ copy(): AnimationTrigger; /** * Gets or sets the name of the property to animate on the target GraphObject. * The default value is set during constructor initialization. * * You can only specify properties that exist on the GraphObject, and are also registered with AnimationManager.defineAnimationEffect. * By default these properties are the same as the list of possible Animation effects: * * * `"position"` * * `"location"` (on Parts) * * `"scale"` * * `"opacity"` * * `"angle"` * * `"desiredSize"` * * `"width"` * * `"height"` * * `"background"` * * `"fill"` (on Shapes) * * `"strokeWidth"` (on Shapes) * * `"strokeDashOffset"` (on Shapes) * * `"stroke"` (on Shapes, TextBlocks) * * Examples of defining additional properties by adding animation effects are given in the Introduction Page on Animations. */ get propertyName(): string; set propertyName(value: string); /** * These settings are only used if the #startCondition is AnimationTrigger.Immediate. * Creating a new AnimationTrigger with animationSettings in the constructor automatically sets #startCondition to AnimationTrigger.Immediate * * This gets or sets the settings for any Animations this trigger creates. * Immediate triggers create a new Animation with each triggering, and apply these settings to that Animation. * * This can be set to an object with a subset of possible Animation settings. The default value is `null`, which keeps default Animation settings. * * Since a #startCondition of AnimationTrigger.Bundled uses the default animation, * you must set the properties of AnimationManager#defaultAnimation, and not this property, to modify the animation settings. * * To set default settings for *all* created Animations, you can modify the settings on AnimationManager instead, such as AnimationManager#duration. * * Possible properties to set in this object are: * * * **duration**: a `number`, corresponding to Animation#duration. * * **finished**: a `Function`, corresponding to Animation#finished. * * **easing**: an `EasingFunction`, corresponding to Animation#easing. */ get animationSettings(): { duration?: number; finished?: (animation: Animation) => void; easing?: EasingFunction; }; set animationSettings(value: { duration?: number; finished?: (animation: Animation) => void; easing?: EasingFunction; }); /** * Gets or sets the starting condition for this trigger. * * AnimationTriggers can invoke an animation immediately, * starting a new animation with each property of each GraphObject that has been modified, * or they can (more efficiently) be bundled together into the default animation (AnimationManager#defaultAnimation) * and begin only one animation, at the end of the next transaction. * * It is useful for the startCondition to be AnimationTrigger.Immediate when changing GraphObject properties * on GraphObject#mouseEnter or GraphObject#mouseLeave. * It is useful for the startCondition to be AnimationTrigger.Bundled when changing several GraphObject properties together, * such as when highlighting multiple parts, on selection changes, and during transactions, or when performance is a consideration. * * These behaviors can be set with the values AnimationTrigger.Immediate and AnimationTrigger.Bundled, respectively. * The default value, AnimationTrigger.Default, attempts to infer which is best: * It will start immediately if there is no ongoing transaction * or if Diagram#skipsUndoManager is true, and otherwise bundle them. */ get startCondition(): EnumValue; set startCondition(value: EnumValue); /** * Used as a value for #startCondition. * GoJS will attempt to AnimationTrigger.Bundled or AnimationTrigger.Immediate based on the state of the transaction. * If no transaction is ongoing, this trigger will be treated as using AnimationTrigger.Immediate, * otherwise it will work as AnimationTrigger.Bundled. * @constant */ static Default: EnumValue; /** * Used as a value for #startCondition. * A new animation will be created for every instance of the property changed, and started immediately, * and run until completion. This may be useful for cosmetic changes, such as animating * the opacity or color of an object on mouseEnter or mouseLeave. * However, using AnimationTrigger.Bundled may be more efficient, as it will create fewer * @constant */ static Immediate: EnumValue; /** * Used as a value for #startCondition. * The AnimationManager will use the default animation to prepare a single Animation that begins when the current transaction has ended. * This animation may be canceled if a new transaction is started. * @constant */ static Bundled: EnumValue; } /** * Layers are how named collections of Parts are drawn in front or behind other collections of Parts in a Diagram. * Layers can only contain Parts, such as Nodes and Links. They cannot hold GraphObjects directly. * * You put a Part into a Layer by assigning Part#layerName with the name of the Layer. * You can use data binding to initialize and remember a Part's layer's name. * You can change a Part's layer by modifying its Part#layerName, which changes its Part#layer. * * Each Diagram starts off with the following list of Layers: * "Grid", "Background", "" (the default layer), "Foreground", "Adornment", "Tool". * Parts are normally put in the default layer. * The "Grid", "Adornment", and "Tool" layers are considered #isTemporary. * Changes to objects in temporary layers are not recorded by the UndoManager. * Parts in temporary layers are not selected and are not considered to be part of the document. * Objects in temporary layers do not receive click events unless you set their GraphObject#isActionable to true. * The "Grid" layer is the furthest back; it also contains "temporary" parts that cannot be selected. * Furthermore the "Grid" layer has #pickable set to false so that mouse or touch events * and calls to the "find..." methods do not even consider any parts in that layer. * * Layers have many properties that control what actions users are permitted to perform involving the parts in the layer. * These properties are very much like the similarly named properties on Diagram. *

Z-ordering

* * Layers are drawn and presented in order. * You can add your own layers by calling Diagram#addLayerBefore or Diagram#addLayerAfter * to insert a new layer at a particular place in the Z-order, or to re-order existing layers. * Use Diagram#findLayer to get the Layer with a particular name. * Parts can be individually z-ordered within a layer by setting Part#zOrder. * @unrestricted */ export class Layer { /** * This constructs an empty Layer; you should set the #name before adding the Layer to a Diagram. * @param {Partial=} init Optional properties to initialize. */ constructor(init?: Partial); /** * Find the front-most GraphObject in this layer * at the given point in document coordinates. * * If #visible is false, this method will not find any objects in this layer. * However, #opacity does not affect this method. * @param {Point} p A Point in document coordinates. * @param {function(GraphObject):GraphObject | null=} navig A function taking a GraphObject and * returning a GraphObject, defaulting to the identity. * @param {function(GraphObject):boolean | null=} pred A function taking the GraphObject * returned by navig and returning true if that object should be returned, * defaulting to a predicate that always returns true. * @return {GraphObject} The first GraphObject in the Z-order, or else null. */ findObjectAt(p: Point, navig?: ((a: GraphObject) => (T | null)) | null, pred?: ((a: T) => boolean) | null): (T | null); /** * Return a collection of the GraphObjects of this layer * at the given point in document coordinates. * * If #visible is false, this method will not find any objects in this layer. * However, #opacity does not affect this method. * @param {Point} p A Point in document coordinates. * @param {function(GraphObject):GraphObject | null=} navig A function taking a GraphObject and * returning a GraphObject, defaulting to the identity. * If this function returns null, the given GraphObject will not be included in the results. * @param {function(GraphObject):boolean | null=} pred A function taking the GraphObject * returned by navig and returning true if that object should be returned, * defaulting to a predicate that always returns true. * @param {List.|Set.=} coll An optional collection (List or Set) to add the results to. * @return {Iterable.} a collection of GraphObjects that will contain all GraphObjects * located at Point p, or else an empty collection. * If a List or Set was passed in, it is returned. */ findObjectsAt | Set = Set>(p: Point, navig?: ((a: GraphObject) => (T | null)) | null, pred?: ((a: T) => boolean) | null, coll?: S): S; /** * Returns a collection of all GraphObjects that are inside or that intersect * a given Rect in document coordinates. * * If #visible is false, this method will not find any objects in this layer. * However, #opacity does not affect this method. * @param {Rect} r A Rect in document coordinates. * @param {function(GraphObject):GraphObject | null=} navig A function taking a GraphObject and * returning a GraphObject, defaulting to the identity. * If this function returns null, the given GraphObject will not be included in the results. * @param {function(GraphObject):boolean | null=} pred A function taking the GraphObject * returned by navig and returning true if that object should be returned, * defaulting to a predicate that always returns true. * @param {boolean=} partialInclusion Whether an object can match if it merely intersects the rectangular area (true) or * if it must be entirely inside the rectangular area (false). The default value is false. * @param {List.|Set.=} coll An optional collection (List or Set) to add the results to. * @return {Iterable.} a collection of GraphObjects that will contain all GraphObjects * located in or near Rect r, or else an empty collection. * If a List or Set was passed in, it is returned. */ findObjectsIn | Set = Set>(r: Rect, navig?: ((a: GraphObject) => (T | null)) | null, pred?: ((a: T) => boolean) | null, partialInclusion?: boolean, coll?: S): S; /** * Returns a collection of all GraphObjects that are within a certain distance * of a given point in document coordinates. * * If #visible is false, this method will not find any objects in this layer. * However, #opacity does not affect this method. * @param {Point} p A Point in document coordinates. * @param {number} dist The distance from the point. * @param {function(GraphObject):GraphObject | null=} navig A function taking a GraphObject and * returning a GraphObject, defaulting to the identity. * If this function returns null, the given GraphObject will not be included in the results. * @param {function(GraphObject):boolean | null=} pred A function taking the GraphObject * returned by navig and returning true if that object should be returned, * defaulting to a predicate that always returns true. * @param {*=} partialInclusion Whether an object can match if it merely intersects the circular area (true) or * if it must be entirely inside the circular area (false). The default value is true. * @param {List.|Set.=} coll An optional collection (List or Set) to add the results to. * @return {Iterable.} a collection of GraphObjects that will contain all GraphObjects * located at Point p, or else an empty collection. * If a List or Set was passed in, it is returned. */ findObjectsNear | Set = Set>(p: Point, dist: number, navig?: ((a: GraphObject) => (T | null)) | null, pred?: ((a: T) => boolean) | null, partialInclusion?: boolean | S, coll?: S): S; /** * This read-only property returns an iterator for this Layer's Parts. * The Parts can be Nodes, Links, Groups, Adornments, or simple Parts. */ get parts(): Iterator; /** * This read-only property returns a backwards iterator for this Layer's Parts, * for iterating over the parts in reverse order. * The Parts can be Nodes, Links, Groups, Adornments, or simple Parts. */ get partsBackwards(): Iterator; /** * This read-only property returns the Diagram that is using this Layer. */ get diagram(): Diagram | null; /** * Gets or sets the name for this layer. * The initial value is an empty string, which is also the name of the default layer. * The name should be unique among the diagram's Diagram#layers. */ get name(): string; set name(value: string); /** * Gets or sets the opacity for all parts in this layer. * The value must be between 0.0 (fully transparent) and 1.0 (no additional transparency). * This value is multiplicative with any existing transparency, * for instance from a Brush or image transparency. * The default value is 1. * * This property, unlike #visible, does not change whether any objects are found by the "find..." methods. * @since 1.1 * @see GraphObject#opacity * @see Diagram#opacity */ get opacity(): number; set opacity(value: number); /** * Gets or sets whether the objects in this layer are considered temporary. * * Parts in temporary layers are not selectable, * and changes to Parts in temporary layers are not recorded in the UndoManager. * Objects in temporary layers do not receive click events unless you set their GraphObject#isActionable to true. * * Temporary layers are excluded from bounds calculations, with the exception of the "Tool" layer, * so that temporary objects created while dragging are included in the bounds. * * Default value is false. * * When this is set to true, #isInDocumentBounds on this layer is set to false. * You can override this behavior by setting #isInDocumentBounds after setting this property. * * @see #isInDocumentBounds */ get isTemporary(): boolean; set isTemporary(value: boolean); /** * Gets or sets whether the user may view any of the objects in this layer. * * The default value is true -- all visible Parts are drawn. * When this property is false, all of the "find..." methods will fail to find parts that are in this layer. * @see GraphObject#visible */ get visible(): boolean; set visible(value: boolean); /** * Gets or sets whether methods such as #findObjectAt find any of the objects in this layer. * * The default value is true. * When this property is false, all of the "find..." methods will fail to find parts that are in this layer. * * Note that setting pickable to false does not prevent users from selecting nodes. * It does prevent them from selecting nodes by clicking on them, * but does not prevent selection through other mechanisms such as the DragSelectingTool or * CommandHandler#selectAll or calls to Diagram#select. * * You can control whether individual GraphObjects are "hittable" by setting GraphObject#pickable. * @since 1.2 * @see GraphObject#pickable */ get pickable(): boolean; set pickable(value: boolean); /** * Gets or sets whether or not a layer is included in the documentBounds computation. * Default value is `true`. However, setting #isTemporary to `true` also sets this property to `false` before version 3. * @since 2.2 * @see #isTemporary */ get isInDocumentBounds(): boolean; set isInDocumentBounds(value: boolean); /** * Gets or sets whether the user may copy objects in this layer. * The initial value is true. */ get allowCopy(): boolean; set allowCopy(value: boolean); /** * Gets or sets whether the user may delete objects in this layer. * The initial value is true. */ get allowDelete(): boolean; set allowDelete(value: boolean); /** * Gets or sets whether the user may do in-place text editing in this layer. * The initial value is true. */ get allowTextEdit(): boolean; set allowTextEdit(value: boolean); /** * Gets or sets whether the user may group parts together in this layer. * The initial value is true. */ get allowGroup(): boolean; set allowGroup(value: boolean); /** * Gets or sets whether the user may ungroup existing groups in this layer. * The initial value is true. */ get allowUngroup(): boolean; set allowUngroup(value: boolean); /** * Gets or sets whether the user may draw new links in this layer. * The initial value is true. */ get allowLink(): boolean; set allowLink(value: boolean); /** * Gets or sets whether the user may reconnect existing links in this layer. * The initial value is true. */ get allowRelink(): boolean; set allowRelink(value: boolean); /** * Gets or sets whether the user may move objects in this layer. * The initial value is true. */ get allowMove(): boolean; set allowMove(value: boolean); /** * Gets or sets whether the user may reshape parts in this layer. * The initial value is true. */ get allowReshape(): boolean; set allowReshape(value: boolean); /** * Gets or sets whether the user may resize parts in this layer. * The initial value is true. */ get allowResize(): boolean; set allowResize(value: boolean); /** * Gets or sets whether the user may rotate parts in this layer. * The initial value is true. */ get allowRotate(): boolean; set allowRotate(value: boolean); /** * Gets or sets whether the user may select objects in this layer. * The initial value is true. */ get allowSelect(): boolean; set allowSelect(value: boolean); } /** * DiagramInitOptions are used in the Diagram constructor to concisely initialize a Diagram by settings its properties, * and also set properties on its Tools, CommandHandler, AnimationManager, and set DiagramEvents. * * @category Type */ export type DiagramInitOptions = Partial void); } | DiagramInitStrings>; /** */ export type DiagramEvents = { [P in DiagramEventName]?: ((e: DiagramEvent) => void); }; interface DiagramInitStrings { [index: string]: any; 'grid.visible': boolean; 'grid.gridCellSize': Size; 'grid.gridOrigin': Point; 'toolManager.mouseWheelBehavior'?: EnumValue; 'toolManager.gestureBehavior'?: EnumValue; 'toolManager.currentToolTip'?: Adornment | HTMLInfo | null; 'toolManager.hoverDelay'?: number; 'toolManager.holdDelay'?: number; 'toolManager.dragSize'?: Size; 'toolManager.toolTipDuration'?: number; 'commandHandler.copiesClipboardData'?: boolean; 'commandHandler.copiesConnectedLinks'?: boolean; 'commandHandler.deletesConnectedLinks'?: boolean; 'commandHandler.copiesTree'?: boolean; 'commandHandler.deletesTree'?: boolean; 'commandHandler.copiesParentKey'?: boolean; 'commandHandler.copiesGroupKey'?: boolean; 'commandHandler.archetypeGroupData'?: ObjectData; 'commandHandler.memberValidation'?: ((aGroup: Group, somePart: Part) => boolean) | null; 'commandHandler.defaultScale'?: number; 'commandHandler.zoomFactor'?: number; 'commandHandler.isZoomToFitRestoreEnabled'?: boolean; 'commandHandler.scrollToPartPause'?: number; 'animationManager.isEnabled'?: boolean; 'animationManager.duration'?: number; 'animationManager.isInitial'?: boolean; 'animationManager.initialAnimationStyle'?: EnumValue; 'draggingTool.isCopyEnabled'?: boolean; 'draggingTool.copiesEffectiveCollection'?: boolean; 'draggingTool.dragOptions'?: DraggingOptions; 'draggingTool.isGridSnapEnabled'?: boolean; 'draggingTool.isComplexRoutingRealtime'?: boolean; 'draggingTool.isGridSnapRealtime'?: boolean; 'draggingTool.gridSnapCellSize'?: Size; 'draggingTool.gridSnapCellSpot'?: Spot; 'draggingTool.gridSnapOrigin'?: Point; 'draggingTool.dragsLink'?: boolean; 'draggingTool.dragsTree'?: boolean; 'draggingTool.copyCursor'?: string; 'draggingTool.moveCursor'?: string; 'draggingTool.nodropCursor'?: string; 'draggingTool.currentPart'?: Part | null; 'draggingTool.copiedParts'?: Map | null; 'draggingTool.draggedParts'?: Map | null; 'draggingTool.draggedLink'?: Link; 'draggingTool.isDragOutStarted'?: boolean; 'draggingTool.startPoint'?: Point; 'draggingTool.delay'?: number; 'undoManager.isEnabled'?: boolean; } /** * A Diagram is associated with an HTML DIV element. Constructing a Diagram creates * an HTML Canvas element which it places inside of the given DIV element, in addition to several helper DIVs. * **GoJS** will manage the contents of this DIV -- you should not modify the contents of the DIV, * although you may style the given DIV (background, border, etc) and position and size it as needed. * * Minimal Diagram construction looks like this. HTML: * ```html *
* ``` * * JavaScript: * ```js * * myDiagram = new go.Diagram("myDiagramDiv", // create a Diagram for the DIV HTML element * { * "undoManager.isEnabled": true // enable undo & redo * }); * ``` * * The diagram will draw onto an HTML Canvas element, created inside the Diagram DIV. * * Each Diagram holds a set of Layers each of which holds some number of Parts * such as Nodes and Links. * Each Part consists of GraphObjects such as TextBlocks and Shapes * and Panels holding yet more GraphObjects. * * A Diagram and its Parts provide the visual representation of a Model that holds JavaScript * data objects for the nodes and the links. * The model provides the way to recognize the relationships between the data. *

* Two Diagrams can display and manipulate the same Model. (Example) * * A diagram will automatically create Nodes and Links corresponding to the model data. * The diagram has a number of named templates it uses to create the actual parts: * #nodeTemplateMap, #groupTemplateMap, and #linkTemplateMap. * Each template may have some data Bindings that set the part's GraphObjects' properties * based on the value of properties of the data. * * A simple Node template and Model data (both nodes and links) may look like this: * * ```js * var $ = go.GraphObject.make; // for conciseness * * // define a simple Node template * myDiagram.nodeTemplate = * $(go.Node, "Auto", // the Shape will go around the TextBlock * $(go.Shape, "RoundedRectangle", * // Shape.fill is bound to Node.data.color * new go.Binding("fill", "color")), * $(go.TextBlock, * { margin: 3 }, // some room around the text * // TextBlock.text is bound to Node.data.key * new go.Binding("text", "key")) * ); * * // create the model data that will be represented by Nodes and Links * myDiagram.model = new go.GraphLinksModel( * [ * { key: "Alpha", color: "lightblue" }, * { key: "Beta", color: "orange" }, * { key: "Gamma", color: "lightgreen" }, * { key: "Delta", color: "pink" } * ], * [ * { from: "Alpha", to: "Beta" }, * { from: "Alpha", to: "Gamma" }, * { from: "Beta", to: "Beta" }, * { from: "Gamma", to: "Delta" }, * { from: "Delta", to: "Alpha" } * ]); * ``` *

* The above code is used to make the Minimal sample, a simple example of * creating a Diagram and setting its model. *

* Read about models on the Using Models page in the introduction. * A diagram is responsible for scrolling (#position) and zooming (#scale) all of the parts that it shows. * Each Part occupies some area given by its GraphObject#actualBounds. * * The union of all of the parts' bounds constitutes the #documentBounds. * The document bounds determines the area that the diagram can be scrolled to. * There are several properties that you can set, such as #initialContentAlignment, * that control the initial size and position of the diagram contents. * * At any later time you can also explicitly set the #position and/or #scale to * get the appearance that you want. But you may find it easier to call methods to get the desired effect. * For example, if you want to make a particular Node be centered in the viewport, * call either #centerRect or #scrollToRect with the Node's GraphObject#actualBounds, * depending on whether or not you want the view to be scrolled if the node is already in view. *

* Read in the Introduction about Viewports * and the Initial Viewport. * You can have the diagram perform automatic layouts of its nodes and links by setting * #layout to an instance of the Layout subclass of your choice. * The default #layout is an instance of the Layout base class that ignores links and * only positions Nodes that do not have a location. * This default layout will allow you to programmatically position nodes (including by loading * from a database) and will also allow the user to manually position nodes using the DraggingTool. * * If you do supply a particular layout as the #layout, you can control which Parts it operates * on by setting Part#isLayoutPositioned. * Normally, of course, it works on all top-level nodes and links. * The layout is performed both after the model is first loaded as well as after any part is added or removed * or changes visibility or size. * You can disable the initial layout by setting Layout#isInitial to false. * You can disable later automatic layouts by setting Layout#isOngoing to false. *

* See the Layouts page in the Introduction for a summary of layout behavior. * * A diagram maintains a collection of selected parts, the Diagram#selection. * To select a Part you set its Part#isSelected property to true. * * There are many properties, named "allow...", that control what operations the user * may perform on the parts in the diagram. These correspond to the same named * properties on Layer that govern the behavior for those parts in a particular layer. * Furthermore for some of these properties there are corresponding properties on * Part, named "...able", that govern the behavior for that individual part. * For example, the #allowCopy property corresponds to Layer#allowCopy and * to the property Part#copyable. * The Part#canCopy predicate is false if any of these properties is false. *

* See the Permissions page for a more thorough discussion. * * The #commandHandler implements various standard commands, * such as the CommandHandler#deleteSelection method and the * CommandHandler#canDeleteSelection predicate. *

* See the Commands page for a listing of keyboard commands and * the use of commands in general. * * The diagram supports modular behavior for mouse events by implementing "tools". * All mouse and keyboard events are represented by InputEvents and redirected * to the #currentTool. * The default tool is an instance of ToolManager which keeps three lists of mode-less tools: * ToolManager#mouseDownTools, ToolManager#mouseMoveTools, and ToolManager#mouseUpTools. * The ToolManager searches these lists when a mouse event happens to find the first tool that can run. * It then makes that tool the new #currentTool, where it can continue to process input events. * When the tool is done, it stops itself, causing the #defaultTool to be the new #currentTool. * * Mouse-down tools include: * - ToolManager#actionTool, to support objects like "buttons" * - ToolManager#relinkingTool, to reconnect an existing link * - ToolManager#linkReshapingTool, to modify the route of an existing link * - ToolManager#rotatingTool, to change the angle of an object * - ToolManager#resizingTool, to change the size of an object * * Mouse-move tools include: * - ToolManager#linkingTool, to draw a new link * - ToolManager#draggingTool, to move or copy the selection * - ToolManager#dragSelectingTool, to select parts within a rectangular area * - ToolManager#panningTool, to pan the diagram * * Mouse-up tools include: * - ToolManager#contextMenuTool, to manage context menus * - ToolManager#textEditingTool, to support in-place text editing * - ToolManager#clickCreatingTool, to create new parts where the user clicks * - ToolManager#clickSelectingTool, to select parts * * You can also run a tool in a modal fashion by explicitly setting #currentTool. * That tool will keep running until some code replaces the #currentTool. * This normally happens when the current tool calls Tool#stopTool, such as on a mouse-up event. *

* See the Tools page for a listing of predefined tools and how they operate. * * A diagram raises various DiagramEvents when interesting things happen that may have affected the whole diagram. * See the documentation for DiagramEvent for a complete listing. * * When you need to display multiple Models, but not at the same time, you can do so by using only one Diagram and setting the #model to a different one. * You can also have two Diagrams share a DIV by swapping the #div to `null` on one Diagram and setting it on the other. * When permanently removing a Diagram,t o clear any memory used, * set the #div to `null` and remove all references to the Diagram. These scenarios are discussed more on the * Replacing Diagrams and Models intro page. * @unrestricted * @category Diagram */ export class Diagram { /** * Construct an empty Diagram for a particular DIV HTML element. * * You will normally initialize properties of the Diagram that control its appearance and behavior. * These properties include: * - templates (such as #nodeTemplate or #linkSelectionAdornmentTemplate), * - an automatic layout (if desired, #layout), * - positioning or scaling (such as #initialContentAlignment or #initialAutoScale), * - permissions (such as #isReadOnly or #allowDelete), or * - Tool or CommandHandler customization (such as CommandHandler#archetypeGroupData or * Tool#isEnabled): `diagram.toolManager.dragSelectingTool.isEnabled = false;`. * * Then you will need to construct a Model (usually a GraphLinksModel) for the Diagram, * initialize its data by setting its Model#nodeDataArray and other properties, * and then set the diagram's #model. * * Finally, if you want to disassociate the Diagram from the HTML Div element, set Diagram#div to null. * If you remove a part of the HTML DOM containing a Div with a Diagram, you will need to * set #div to null in order for the page to recover the memory. * * Unlike GraphObject, the Diagram constructor passes its init options to GraphObject.make. * This allows you to quickly set sub-properties when initializing a Diagram, such as setting properties * on the Diagram's #undoManager or #commandHandler. For example: * * ```js * var diagram = new go.Diagram("myDiagramDiv", * { * allowZoom: false, * "animationManager.isEnabled": false, // turn off automatic animations * "grid.visible": true, // display a background grid for the whole diagram * "grid.gridCellSize": new go.Size(20, 20), * // allow double-click in background to create a new node * "clickCreatingTool.archetypeNodeData": { text: "Node" }, * // allow Ctrl-G to call the groupSelection command * "commandHandler.archetypeGroupData": * { text: "Group", isGroup: true, color: "blue" }, * "commandHandler.copiesTree": true, // for the copy command * "commandHandler.deletesTree": true, // for the delete command * "toolManager.hoverDelay": 100, // how quickly tooltips are shown * // mouse wheel zooms instead of scrolls * "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom, * "draggingTool.dragsTree": true, // dragging for both move and copy * "draggingTool.isGridSnapEnabled": true, * layout: new go.TreeLayout( * { angle: 90, sorting: go.TreeLayout.SortingAscending }), * "undoManager.isEnabled": true, // enable undo & redo * // a Changed listener on the Diagram.model * "ModelChanged": e => { if (e.isTransactionFinished) saveModel(); } * }); * ``` * @param {Element|string=} div A reference to a DIV HTML element or its ID as a string. * If no DIV is supplied, a Diagram will be created in memory. The Diagram's Diagram#div property * can then be set later on. * @param {DiagramInitOptions=} init A JavaScript object specifying optional initialization properties object. * Can specify Diagram properties, Diagram sub-properties such as `"undoManager.isEnabled": true`, * and DiagramEvent listeners. Example: * ```js * { * allowZoom: false, * "animationManager.isEnabled": false, * "ModelChanged": e => { if (e.isTransactionFinished) saveModel(); } * } * ``` */ constructor(div?: Element | string, init?: DiagramInitOptions); /** * * @param {DiagramInitOptions=} init A JavaScript object specifying optional initialization properties object. * Can specify Diagram properties, Diagram sub-properties such as `"undoManager.isEnabled": true`, * and DiagramEvent listeners. Example: * ```js * { * allowZoom: false, * "animationManager.isEnabled": false, * "ModelChanged": e => { if (e.isTransactionFinished) saveModel(); } * } * ``` */ constructor(init?: DiagramInitOptions); /** * Gets or sets the rendering context type. Values are `'default'`, which uses the HTML Canvas, * or `'svg'`, which builds and updates an SVG DOM. * * Setting this value dynamically is uncommon, typically a render is chosen only once, * when the Diagram is initially created. Using the SVG rendering context is also uncommon, * because the default canvas context has considerably greater performance. * * For more information, see the intro page on the * SVG drawing context. * * @since 2.3 */ get renderer(): 'default' | 'svg' | 'canvas'; set renderer(value: 'default' | 'svg' | 'canvas'); /** * This static function returns `true` if GoJS detects a DOM. * In browser environments this is expected to be `true`, in Node-like environments, `false`. * Specifically, this will be `false` if there is no root `document` in the JavaScript context, * or if the DOM was disabled explicitly by calling Diagram.useDOM. * * Incomplete or mock implementations of a DOM may make this return true when * it is more appropriate that it returns false. If that is the case, set it to false by calling * Diagram.useDOM. * @since 2.2 */ static isUsingDOM(): boolean; /** * This static function sets whether or not GoJS should use a DOM, if one exists. * This can be set to `false` to simulate a DOM-less environment. * It is uncommon to set this, but may be required in some testing environments. * @param {boolean} value * @since 2.2 */ static useDOM(value: boolean): void; /** * Removes all Parts from the Diagram, including unbound Parts except for the background grid, * and also clears out the Model and UndoManager and clipboard. * This operation is not undoable. * * Alternative actions are to replace the #model with a new Model * (probably a GraphLinksModel or a TreeModel), * or to set Model#nodeDataArray with an empty JavaScript Array * (and GraphLinksModel#linkDataArray). * * This does not remove any listeners from the diagram. */ clear(): void; /** * (undocumented) * Call #clear and also restore the templates, layers, layout and various Diagram properties to their original state. * @expose */ reset(): void; /** * @expose * (undocumented) * Used in Diagram constructor setup, this computes the pixel width of the scrollbars * @param {HTMLElement=} elem */ setRTL(elem?: HTMLElement): void; /** * (undocumented) * Computes the pixel width of the scrollbars * @expose * @param {HTMLElement=} elem */ setScrollWidth(elem?: HTMLElement): void; /** * This static function gets the Diagram that is attached to an HTML DIV element. * @param {Element|string} div * @return {Diagram} null if there is no Diagram associated with the given DIV, * or if the argument is not a DIV element nor a string naming such a DIV element in the HTML document. */ static fromDiv(div: Element | string): Diagram | null; /** * Gets or sets the Diagram's HTMLDivElement, via an HTML Element ID. * This is typically set automatically when a Div is supplied as an argument to Diagram's constructor. * * Setting this property to a new value will clobber any HTML and * inner DOM elements inside of both the new and the old divs. * It will then populate the Div with the elements * (inner Divs, Canvases) needed for the Diagram to function. * * If you want to disassociate the Diagram from the HTML Div element, set Diagram#div to null. * If you remove a part of the HTML DOM containing a Div with a Diagram, you will need to * set #div to null in order for the page to recover the memory. * * You should not attempt to manually modify the contents of this Div. * Changing this property value does not raise a Changed event. */ get div(): HTMLDivElement | null; set div(value: HTMLDivElement | null); /** * (undocumented), but may be useful for change detection calls in Angular. * @expose */ addEventListener(DOMElement: Element | Window | Document, name: string, listener: any, capture: boolean): void; /** * (undocumented), but may be useful for change detection calls in Angular. * @expose */ removeEventListener(DOMElement: Element | Window | Document, name: string, listener: any, capture: boolean): void; /** * (undocumented) * Computes the device pixel ratio divided by the backing store pixel ratio * Used to set this._pixelRatio to a value other than 1. * @expose * @return {number} */ computePixelRatio(): number; /** * (undocumented) * Focus the Diagram's canvas, allowing it to receive keyboard events. * This is called upon activation of mouseDown or mouseMove tools, or on any mouseUp. * * This is normally implemented as a simple call to #focus. * Override this if you do not wish to focus the canvas under certain circumstances. * However the method should call #focus most of the time in order to get the normal behaviors. * * #lastInput can be used to inspect the mouseDown event that calls this method. * @expose */ doFocus(): void; /** * Explicitly bring HTML focus to the Diagram's canvas. * This is called by tools that may create other HTML elements such as TextEditingTool. * * If #scrollsPageOnFocus is false, this tries to keep the page at the same scroll position * that it had before calling #focus. * This method is not overridable. */ focus(): void; /** * This is called during a Diagram update to determine a new value for #documentBounds. * By default this computes the union of the bounds of all the visible * GraphObjects in this Diagram, unless Diagram#fixedBounds is set. * This ignores parts for which Part#isVisible is false and * ignores those for which Part#isInDocumentBounds is false. * The returned value includes the addition of the #padding margin. * * To compute the bounds of a collection of Parts, call #computePartsBounds. * @expose * @param {Rect=} rect An optional Rect to modify and return, instead of returning a new Rect * @return {Rect} a Rect in document coordinates. If the argument rect was specified, it returns that modified rect. */ protected computeBounds(rect?: Rect): Rect; /** * Find the union of the GraphObject#actualBounds of all of the Parts in the given collection, * excluding Links unless the second argument is true. * * Unlike #computeBounds, this ignores the visibility of each Part and does not add any padding to the result. * @expose * @param {Iterable.|Array.} coll an iterable collection or Array of Parts. * @param {boolean=} includeLinks defaults to false * @return {Rect} This returns the bounding area of the given Parts; * if there are no Parts in the collection, this returns a Rect with zero width and height and an X and Y that are NaN. * @since 1.1 */ computePartsBounds(coll: Iterable | Array, includeLinks?: boolean): Rect; /** * Scales the Diagram to uniformly fit into the viewport. To have this done automatically, * set the Diagram's #autoScale to Diagram.Uniform. * * Note that depending on the values of #maxScale and #minScale, the actual value for #scale * might be limited. * * The scale will not be increased past the value of #defaultScale, which is normally 1.0, * so as to prevent a single node from appearing to fill up the whole viewport. * * To Animate zoomToFit, use CommandHandler#zoomToFit. * @see CommandHandler#zoomToFit */ zoomToFit(): void; /** * Modifies the #scale and #position of the Diagram * so that the viewport displays a given document-coordinates rectangle. * @param {Rect} r rectangular bounds in document coordinates. * @param {EnumValue=} scaling an optional value of either Diagram.Uniform (the default) or Diagram.UniformToFill. * @since 1.1 */ zoomToRect(r: Rect, scaling?: EnumValue): void; /** * Aligns the Diagram's #position based on a desired document Spot and viewport Spot. * @param {Spot} documentspot * @param {Spot} viewportspot */ alignDocument(documentspot: Spot, viewportspot: Spot): void; /** * (undocumented) * Sets the GraphObject on which to focus the viewport. * @param {GraphObject | null} obj * @since 2.1 */ focusObject(obj: GraphObject | null): void; /** * This convenience function finds the front-most Part * that is at a given point that might be selectable and that is not in a temporary layer. * * This just calls #findObjectAt with appropriate arguments, * but ignoring Layers that are Layer#isTemporary. * @param {Point} p a Point in document coordinates. * @param {boolean=} selectable Whether to only consider parts that are Part#selectable. The default is true. * @return {Part} * @see #findObjectAt * @see #findObjectsAt * @see #findObjectsIn * @see #findObjectsNear * @see #findPartsAt * @see #findPartsIn * @see #findPartsNear */ findPartAt(p: Point, selectable?: boolean): Part | null; /** * Find the front-most GraphObject at the given point in document coordinates. * * If Layer#visible is false, this method will not find any objects in that layer. * However, Layer#opacity does not affect this method. * * Example usage: * ```js * // Returns the top-most object that is a selectable Part, or null if there isn't one * myDiagram.findObjectAt( * myDiagram.lastInput.documentPoint, * // Navigation function * x => x.part, * // Because of the navigation function, x will always be a Part. * x => x.canSelect() * ); * ``` * @param {Point} p A Point in document coordinates. * @param {function(GraphObject):GraphObject | null=} navig A function taking a GraphObject and * returning a GraphObject, defaulting to the identity. * @param {function(GraphObject):boolean | null=} pred A function taking the GraphObject * returned by navig and returning true if that object should be returned, * defaulting to a predicate that always returns true. * @return {GraphObject} The first GraphObject returned by the *navig* function * and satisfying the *pred* function that is at the point *p*, in Z-order from front to back, * or else null if nothing is found. * @see #findObjectsAt * @see #findObjectsIn * @see #findObjectsNear * @see #findPartAt */ findObjectAt(p: Point, navig?: ((a: GraphObject) => (T | null)) | null, pred?: ((a: T) => boolean) | null): (T | null); /** * This convenience function finds all Parts that are at a point in document coordinates * and that are not in temporary layers. * * @param {Point} p A Point in document coordinates. * @param {boolean=} selectable Whether to only consider parts that are Part#selectable. The default is true. * @param {List.|Set.=} coll An optional collection (List or Set) to add the results to. * @return {Iterable.} * @see #findPartAt * @see #findPartsIn * @see #findPartsNear * @see #findObjectsAt * @since 2.0 */ findPartsAt | Set = Set>(p: Point, selectable?: boolean, coll?: S): S; /** * Return a collection of the GraphObjects at the given point in document coordinates. * * If Layer#visible is false, this method will not find any objects in that layer. * However, Layer#opacity does not affect this method. * * Example usage: * ```js * // Returns the Nodes that are at a given point, overlapping each other * myDiagram.findObjectsAt(somePoint, * // Navigation function -- only return Nodes * x => { const p = x.part; return (p instanceof go.Node) ? p : null; } * ); * ``` * @param {Point} p A Point in document coordinates. * @param {function(GraphObject):GraphObject | null=} navig A function taking a GraphObject and * returning a GraphObject, defaulting to the identity. * If this function returns null, the given GraphObject will not be included in the results. * @param {function(GraphObject):boolean | null=} pred A function taking the GraphObject * returned by navig and returning true if that object should be returned, * defaulting to a predicate that always returns true. * @param {List.|Set.=} coll An optional collection (List or Set) to add the results to. * @return {Iterable.} a collection of GraphObjects returned by the *navig* function * and satisfying the *pred* that are located at the point *p*, or else an empty collection. * If a List or Set was passed in, it is returned. * @see #findObjectAt * @see #findObjectsIn * @see #findObjectsNear * @see #findPartsAt */ findObjectsAt | Set = Set>(p: Point, navig?: ((a: GraphObject) => (T | null)) | null, pred?: ((a: T) => boolean) | null, coll?: S): S; /** * This convenience function finds Parts that are inside or that intersect * a given Rect in document coordinates. * * This just calls #findObjectsIn with appropriate arguments, * but ignoring Layers that are Layer#isTemporary. * @param {Rect} r a Rect in document coordinates. * @param {boolean=} partialInclusion Whether a Part can match if it merely intersects the rectangular area (true) or * if it must be entirely inside the rectangular area (false). The default value is false. * @param {boolean=} selectable Whether to only consider parts that are Part#selectable. The default is true. * @param {List.|Set.=} coll An optional collection (List or Set) to add the results to. * @return {Iterable.} * @see #findPartAt * @see #findPartsAt * @see #findPartsNear * @see #findObjectsIn * @since 2.0 */ findPartsIn | Set = Set>(r: Rect, partialInclusion?: boolean, selectable?: boolean, coll?: S): S; /** * Returns a collection of all GraphObjects that are inside or that intersect * a given Rect in document coordinates. * * If Layer#visible is false, this method will not find any objects in that layer. * However, Layer#opacity does not affect this method. * * Example usage: * ```js * // Returns the Links that intersect a given rectangle and have a certain data property * myDiagram.findObjectsIn(someRect, * // Navigation function -- only return Links * x => { const p = x.part; return (p instanceof go.Link) ? p : null; }, * // Predicate that always receives a Link, due to above navigation function * link => link.data.someProp > 17, * // the links may only partly overlap the given rectangle * true * ); * ``` * @param {Rect} r A Rect in document coordinates. * @param {function(GraphObject):GraphObject | null=} navig A function taking a GraphObject and * returning a GraphObject, defaulting to the identity. * If this function returns null, the given GraphObject will not be included in the results. * @param {function(GraphObject):boolean | null=} pred A function taking the GraphObject * returned by navig and returning true if that object should be returned, * defaulting to a predicate that always returns true. * @param {boolean=} partialInclusion Whether an object can match if it merely intersects the rectangular area (true) or * if it must be entirely inside the rectangular area (false). The default value is false. * @param {List.|Set.=} coll An optional collection (List or Set) to add the results to. * @return {Iterable.} a collection of GraphObjects returned by the *navig* function * and satisfying the *pred* function that are within the rectangle *r*, or else an empty collection. * If a List or Set was passed in, it is returned. * @see #findObjectAt * @see #findObjectsAt * @see #findObjectsNear * @see #findPartsIn */ findObjectsIn | Set = Set>(r: Rect, navig?: ((a: GraphObject) => (T | null)) | null, pred?: ((a: T) => boolean) | null, partialInclusion?: boolean, coll?: S): S; /** * This convenience function finds Parts that are within a certain distance * of a given point in document coordinates. * * This just calls #findObjectsNear with appropriate arguments, * but ignoring Layers that are Layer#isTemporary. * @param {Point} p A Point in document coordinates. * @param {number} dist The distance from the point. * @param {boolean=} partialInclusion Whether an object can match if it merely intersects the circular area (true) or * if it must be entirely inside the circular area (false). The default is true. * @param {boolean=} selectable Whether to only consider parts that are Part#selectable. The default is true. * @param {List.|Set.=} coll An optional collection (List or Set) to add the results to. * @return {Iterable.} * @see #findPartAt * @see #findPartsAt * @see #findPartsIn * @see #findObjectsNear * @since 2.0 */ findPartsNear | Set = Set>(p: Point, dist: number, partialInclusion?: boolean, selectable?: boolean, coll?: S): S; /** * Returns a collection of all GraphObjects that are within a certain distance * of a given point in document coordinates. * * If Layer#visible is false, this method will not find any objects in that layer. * However, Layer#opacity does not affect this method. * * Example usage: * ```js * // Returns the Nodes that intersect a given circular area and have a certain data property * myDiagram.findObjectsNear(somePoint, * // The circular area is centered at somePoint and has radius 100 * 100, * // Navigation function -- only return Nodes * x => { const p = x.part; return (p instanceof go.Node) ? p : null; }, * // Predicate that always receives a Node, due to above navigation function * node => node.data.someProp > 17, * // the nodes may only partly overlap the given circular area * true * ); * ``` * @param {Point} p A Point in document coordinates. * @param {number} dist The distance from the point. * @param {function(GraphObject):GraphObject | null=} navig A function taking a GraphObject and * returning a GraphObject, defaulting to the identity. * If this function returns null, the given GraphObject will not be included in the results. * @param {function(GraphObject):boolean | null=} pred A function taking the GraphObject * returned by navig and returning true if that object should be returned, * defaulting to a predicate that always returns true. * @param {*=} partialInclusion Whether an object can match if it merely intersects the circular area (true) or * if it must be entirely inside the circular area (false). The default value is true. * The default is true. * @param {List.|Set.=} coll An optional collection (List or Set) to add the results to. * @return {Iterable.} a collection of GraphObjects returned by the *navig* function * and satisfying the *pred* that are located near the point *p*, or else an empty collection. * If a List or Set was passed in, it is returned. * @see #findObjectAt * @see #findObjectsAt * @see #findObjectsIn * @see #findPartsNear */ findObjectsNear | Set = Set>(p: Point, dist: number, navig?: ((a: GraphObject) => (T | null)) | null, pred?: ((a: T) => boolean) | null, partialInclusion?: boolean | S, coll?: S): S; /** * (undocumented) * Requests that the Diagram updates its #documentBounds in the near-future. */ invalidateDocumentBounds(): void; /** * (undocumented) * Invalidates all non-layout diagram state and forces an immediate redraw. * Because this can be very inefficient, to discourage its use it remains an undocumented part of the API. * @expose */ redraw(): void; /** * Updates the diagram immediately, then resets initialization flags so that * actions taken in the argument function will be considered part of Diagram initialization, * and will participate in initial layouts, #initialAutoScale, #initialContentAlignment, etc. * * This is useful in situations where you do not wish for the first content added to the diagram to be considered * the "initial" content, such as with a Node that represents a "Loading" bar. * @param {function(Diagram)|null=} func an optional function of actions to perform as part of another diagram initialization. * @since 1.1 */ delayInitialization(func?: ((diag: Diagram) => void) | null): void; /** * Usage of this method is uncommon and may affect performance, * for efficiency do not call this method unless you have a well-defined need. * Normally, GoJS updates the diagram automatically, and completeing a transaction ensures an immediate update. * * The most common reason to call this method when the HTML Div has changed size but the window has not changed size, * and the Diagram needs to be notified of this DOM change. See an example of resizing diagrams * here. * * Requests that in the near-future the diagram makes sure all GraphObjects are arranged, * recomputes the document bounds, updates the scrollbars, and redraws the viewport. * * @param {boolean=} alwaysQueueUpdate If true the Diagram will queue another update, * even if an update is already occurring. The default value is false. * Side effects in an "InitialLayoutCompleted" DiagramEvent listener might necessitate setting this parameter. * @since 1.6 */ requestUpdate(alwaysQueueUpdate?: boolean): void; /** * (undocumented) * The use of this method at the wrong time may have some unexpected side-effects. */ maybeUpdate(): void; /** * (undocumented) * Get value of a given rendering hint. * @param {string} name * @return {*} */ getRenderingHint(name: string): any; /** * (undocumented) * Set a rendering hint and draw immediately. * @param {string} name * @param {*} val */ setRenderingHint(name: string, val: any): void; /** * (undocumented) * Get value of a given input option * @param {string} name * @return {*} */ getInputOption(name: string): any; /** * (undocumented) * Set value of a given input option * @param {string} name * @param {*} val */ setInputOption(name: string, val: any): void; /** * Set any number of properties on this Diagram. This is common in initialization. * This method can only be used to set existing properties on this object. To attach new properties, * or to set properties of sub-objects such as the Diagram#toolManager, Diagram#animationManager, * or Diagram#commandHandler, use Diagram#attach. * * This method uses TypeScript compile-time type checking, but does no runtime type checking. * * * @since 2.2 * @param {Partial} config * @return {Diagram} this Diagram * @see #setProperties */ set(config: Partial): this; /** * This method sets a collection of properties according to the property/value pairs that have been set on the given Object, * in the same manner as GraphObject.make does when constructing a Diagram with an argument that is a simple JavaScript Object. * * This method does not use TypeScript compile-time type checking like Diagram#set does, * but is considerably more flexible in allowing you to set sub-properties and DiagramEvents by quoted string names. * * You can set properties on an object that is the value of a property of the Diagram, * or on the Diagram#toolManager, Diagram#animationManager, or Diagram#commandHandler * by using a `"subpropname.property"` syntax for the property name. * At the current time only a single dot is permitted in the property "name". * * The property name may also be the name of a DiagramEvent, in which case this calls #addDiagramListener with that DiagramEvent name. * ```js * aDiagram.attach({ * allowDelete: false, * "animationManager.isEnabled": false, // turn off automatic animations * // specify a group membership validation predicate * "commandHandler.memberValidation": (group, part) => ..., * "commandHandler.copiesTree": true, // for the copy command * // mouse wheel zooms instead of scrolls * "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom, * "draggingTool.dragsTree": true, // dragging for both move and copy * "draggingTool.isGridSnapEnabled": true, * layout: $(go.TreeLayout), * // add a DiagramEvent listener * "ExternalObjectsDropped": e => { e.subject.each(part => { ... }); } * }); * ``` * @param {Object} props a plain JavaScript object with various property values to be set on this Diagram or on a part of this Diagram. * @since 2.2 * @return {Diagram} this Diagram * @see #setProperties a synonym of this method * @see #set a type-safe method to set a collection of properties */ attach(props: ObjectData): this; /** * This method sets a collection of properties according to the property/value pairs that have been set on the given Object, * in the same manner as GraphObject.make does when constructing a Diagram with an argument that is a simple JavaScript Object. * * This method does not use TypeScript compile-time type checking like Diagram#set does, * but is considerably more flexible in allowing you to set sub-properties and DiagramEvents by quoted string names. * * You can set properties on an object that is the value of a property of the Diagram, * or on the Diagram#toolManager, Diagram#animationManager, or Diagram#commandHandler * by using a `"subpropname.property"` syntax for the property name. * At the current time only a single dot is permitted in the property "name". * * The property name may also be the name of a DiagramEvent, in which case this calls #addDiagramListener with that DiagramEvent name. * ```js * aDiagram.attach({ * allowDelete: false, * "animationManager.isEnabled": false, // turn off automatic animations * // specify a group membership validation predicate * "commandHandler.memberValidation": (group, part) => return ..., * "commandHandler.copiesTree": true, // for the copy command * // mouse wheel zooms instead of scrolls * "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom, * "draggingTool.dragsTree": true, // dragging for both move and copy * "draggingTool.isGridSnapEnabled": true, * layout: $(go.TreeLayout), * // add a DiagramEvent listener * "ExternalObjectsDropped": e => e.subject.each(part => { ... }) * }); * ``` * @param {Object} props a plain JavaScript object with various property values to be set on this Diagram or on a part of this Diagram. * @since 1.5 * @return {Diagram} this Diagram * @see #attach a synonym of this method * @see #set a type-safe method to set a collection of properties */ setProperties(props: ObjectData): this; /** * Adds a Part to the Layer that matches the Part's Part#layerName, * or else the default layer, which is named with the empty string. * * Normally parts added to a diagram are top-level parts. * If you want nodes to be members of a Group, in addition to calling this method * call Group#addMembers or set each Part#containingGroup. * @param {Part} part * @see #remove */ add(part: Part): void; /** * Removes a Part from its Layer, provided the Layer is in this Diagram. * Removing a Node will also remove any Links that are connected with it. * Removing a Group will also remove all of its members. * Removing a Link will also remove all of its label Nodes, if it has any. * @param {Part} part * @see #add */ remove(part: Part): void; /** * This method removes from this Diagram all of the Parts in a collection. * Removing a Node will also remove any Links that are connected with it. * Removing a Group will also remove all of its members. * Removing a Link will also remove all of its label Nodes, if it has any. * * This does not perform a transaction nor does it raise a DiagramEvent. * Call CommandHandler#deleteSelection, which calls this method, * if you want to delete all selected Parts. * The CommandHandler#deleteSelection command may delete other Parts as well, depending on CommandHandler#deletesTree. * * At this time there is no "addParts" method -- just call Diagram#add on each Part. * @param {Iterable.|Array.} coll A List or Set or Iterator or Array of Parts. * @param {boolean=} check Whether to check Part#canDelete on each part; default value is false. * @since 1.3 */ removeParts(coll: Iterable | Array, check?: boolean): void; /** * Make a copy of a collection of Parts and return them in a Map mapping each original Part to its copy. * It may optionally add them to a given Diagram. * Copying a Group will also copy its member Nodes and Links. * Copying a Link will also copy any label Nodes that it owns. * * This does not perform a transaction nor does it raise a DiagramEvent. * Call CommandHandler#copySelection, which calls this method, * if you want to copy all selected Parts into the clipboard. * The CommandHandler#copySelection command may also copy additional Parts as well, depending on CommandHandler#copiesTree. * @param {Iterable.|Array.} coll A List or a Set or Iterator of Parts, or an Array of Parts. * @param {Diagram} diagram The destination diagram; if null, the copied parts are not added to this diagram. * @param {boolean=} check Whether to check Part#canCopy on each part. The default value is false. * @return {Map.} * @since 1.3 */ copyParts(coll: Iterable | Array, diagram: Diagram | null, check?: boolean): Map; /** * Move a collection of Parts in this Diagram by a given offset. * Moving a Group will also move its member Nodes and Links. * Moving with a zero X and a zero Y offset is potentially useful in order to snap Parts to the grid if DraggingTool#isGridSnapEnabled is true. * * This does not perform a transaction nor does it raise a DiagramEvent. * * @param {Iterable.|Array.} coll A List or a Set or Iterator of Parts, or an Array of Parts, * or null to move all of the Parts in this Diagram. * @param {Point} offset the amount to move each Part, in document coordinates. * @param {boolean=} check Whether to check Part#canMove on each part. The default value is false. * @param {DraggingOptions=} dragOptions Optional dragging options. By default this uses the settings from the Diagram's DraggingTool. * @since 1.3 */ moveParts(coll: Iterable | Array, offset: Point, check?: boolean, dragOptions?: DraggingOptions): void; /** * This method computes the new location for a Node or simple Part, * given a new desired location, * taking any grid-snapping into consideration, * any Part#dragComputation function, * and any Part#minLocation and Part#maxLocation. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Part} n the Node or simple Part that is being moved * @param {Point} newloc the proposed new location * @param {DraggingOptions} dragOptions the dragging options * @param {Point=} result an optional Point that is modified and returned * @return {Point} the possibly grid-snapped computed Point that is within the minimum and maximum permitted locations * @since 2.0 */ computeMove(n: Part, newloc: Point, dragOptions: DraggingOptions, result?: Point): Point; set draggedLink(value: Link | null); /** * Adds a new Layer to the list of layers. * If Layer#isTemporary is false, the layer is added after all existing non-temporary layers. * If Layer#isTemporary is true, the layer is added as the very last layer. * @param {Layer} layer The new Layer to add. It is an error if the Layer already belongs to a Diagram. * @see #addLayerBefore * @see #addLayerAfter * @see #removeLayer * @see #findLayer * @return {Diagram} this Diagram */ addLayer(layer: Layer): this; /** * Adds a layer to the list of layers before a specified layer. * This method can also re-order layers. * @param {Layer} layer the new Layer to add or existing Layer to move in Z-order. * @param {Layer} existingLayer the other Layer in this Diagram which should come just after the new or moved layer. * @see #addLayer * @see #addLayerAfter * @see #removeLayer * @return {Diagram} this Diagram */ addLayerBefore(layer: Layer, existingLayer: Layer): this; /** * Adds a layer to the list of layers after a specified layer. * This method can also re-order layers. * @param {Layer} layer the new Layer to add or existing Layer to move in Z-order. * @param {Layer} existingLayer the other Layer in this Diagram which should come just before the new or moved layer. * @see #addLayer * @see #addLayerBefore * @see #removeLayer * @return {Diagram} this Diagram */ addLayerAfter(layer: Layer, existingLayer: Layer): this; /** * Removes the given layer from the list of layers. * * Removing a layer does not remove the Parts in the layer. Instead, those Parts are placed into the default layer. * To remove all Parts in a layer you can call Diagram#removeParts with Layer#parts as the argument. * * You cannot remove the default layer, the one named with the empty string. * @param {Layer} layer * @see #addLayer * @see #addLayerBefore * @see #addLayerAfter * @see #findLayer */ removeLayer(layer: Layer): void; /** * Finds a layer with a given name. * @param {string} name * @return {Layer} a Layer with the given name, or null if no such layer was found. * @see #addLayerBefore * @see #addLayerAfter * @see #removeLayer */ findLayer(name: string): Layer | null; /** * Register an event handler on this Diagram's Diagram#model that is called when there is a ChangedEvent * on the Model, not in this diagram. * Be sure to call #removeModelChangedListener when you are done with the diagram. * * This is convenient when the Diagram#model may be replaced. * Using this method to register a Model Changed listener is more convenient than calling Model#addChangedListener directly * because when this diagram's Model is replaced, one does not need to call Model#removeChangedListener on the old Model * and then Model#addChangedListener again on the new Model. * * You can establish Model Changed listeners when you create a Diagram. * The Diagram init options are passed to GraphObject.make, which accepts "ModelChanged" as a shorthand. * For example: * ```js * new go.Diagram("myDiagramDiv", * { * "ModelChanged": e => { if (e.isTransactionFinished) saveModel(e.model); } * // ... other Diagram properties * }) * ``` * * This is equivalent to: * * ```js * new go.Diagram("myDiagramDiv", * { * // ... Diagram properties * }) * .addModelChangedListener(e => { if (e.isTransactionFinished) saveModel(e.model); }) * ``` * * Do not add or remove Changed listeners during the execution of a Changed listener. * @param {function(ChangedEvent)} listener a function that takes a ChangedEvent as its argument. * @see #removeModelChangedListener * @since 1.6 * @return {Diagram} this Diagram */ addModelChangedListener(listener: ((e: ChangedEvent) => void)): this; /** * Unregister a ChangedEvent handler from this Diagram's Diagram#model. * The function argument must be the same reference as was passed to #addChangedListener. * @param {function(ChangedEvent)} listener a function that takes a ChangedEvent as its argument. * @see #addModelChangedListener * @since 1.6 */ removeModelChangedListener(listener: ((e: ChangedEvent) => void)): void; /** * Register an event handler that is called when there is a ChangedEvent because this Diagram * or one of its Parts has changed, but not because the Model or any model data has changed. * * It is unusual to listen for Diagram ChangedEvents -- * it is far more common to listen for specific DiagramEvents by calling #addDiagramListener, * or to listen for Model ChangedEvents (i.e. changes to the model) by calling #addModelChangedListener. * * Do not add or remove Changed listeners during the execution of a Changed listener. * @param {function(ChangedEvent)} listener a function that takes a ChangedEvent as its argument. * @see #removeChangedListener * @return {Diagram} this Diagram */ addChangedListener(listener: ((e: ChangedEvent) => void)): this; /** * Unregister a ChangedEvent handler. * The function argument must be the same reference as was passed to #addChangedListener. * @param {function(ChangedEvent)} listener a function that takes a ChangedEvent as its argument. * @see #addChangedListener */ removeChangedListener(listener: ((e: ChangedEvent) => void)): void; /** * This read-only property returns the AnimationManager for this Diagram. * @since 1.4 */ get animationManager(): AnimationManager; /** * This read-only property returns the UndoManager for this Diagram, which actually belongs to the #model. * * The default UndoManager has its UndoManager#isEnabled property set to false. * If you want users to undo and redo, you should set that property to true once you have initialized the Diagram or its Model. * * Note that the UndoManager might be shared with other Diagrams that are showing the same Model. * The UndoManager might also be shared with other Models too. */ get undoManager(): UndoManager; /** * Gets or sets whether ChangedEvents are not recorded by the UndoManager. * The initial and normal value is false. * WARNING: while this property is true do not perform any changes that cause any previous transactions * to become impossible to undo. * * While this property is true, changing the Diagram or any GraphObject does not call UndoManager#handleChanged. * Even when this property is true, * transactions (such as calls to #startTransaction) and * undo/redo (such as calls to CommandHandler#undo) * are still delegated to the #undoManager. * * You should set this to true only temporarily, and you should remember its previous value * before setting this to true. * When finishing the period for which you want the UndoManager to be disabled, * you should set this back to the remembered value it had before it was set to true. * * For more permanent disabling of the UndoManager, set UndoManager#isEnabled to false. * * Setting this property also sets Model#skipsUndoManager to the same value. * Setting this property does not notify about any changed event. */ get skipsUndoManager(): boolean; set skipsUndoManager(value: boolean); /** * (undocumented) * When set to true Diagram layouts will not get invalidated. * Used by some tools stop real-time layouts from occuring during their operation. */ get delaysLayout(): boolean; set delaysLayout(value: boolean); /** * Begin a transaction, where the changes are held by a Transaction object * in the UndoManager. * This just calls UndoManager#startTransaction. * @param {string=} tname a descriptive name for the transaction. * @return {boolean} the value returned by UndoManager#startTransaction. * @see #commit */ startTransaction(tname?: string): boolean; /** * Commit the changes of the current transaction. * This just calls UndoManager#commitTransaction. * @param {string=} tname a descriptive name for the transaction. * @return {boolean} the value returned by UndoManager#commitTransaction. */ commitTransaction(tname?: string): boolean; /** * Rollback the current transaction, undoing any recorded changes. * This just calls UndoManager#rollbackTransaction. * @return {boolean} the value returned by UndoManager#rollbackTransaction. */ rollbackTransaction(): boolean; /** * Starts a new transaction, calls the provided function, and commits the transaction. * Code is called within a try-finally statement. * If the function does not return normally, this rolls back the transaction rather than committing it. * Example usage: * ```js * myDiagram.commit(d => d.remove(somePart), "Remove Part"); * ``` * Note: passing null as the second argument will temporarily set Diagram#skipsUndoManager to true. * It is commonplace to call this method with no second argument, which would commit a transaction with * a transaction name that is the empty string. * @param {Function} func the function to call as the transaction body * @param {(string|null)=} tname a descriptive name for the transaction, or null to temporarily set #skipsUndoManager to true; * if no string transaction name is given, an empty string is used as the transaction name * @since 1.8 */ commit(func: (d: Diagram) => void, tname?: string | null): void; /** * Update all of the data-bound properties of Nodes and Links in this diagram, * without having to call Model#setDataProperty. * This copies/converts model data properties to set properties on Parts. * This method does not conduct a transaction, so you need to start and commit one yourself. * * It is better to call Model#setDataProperty to modify data properties, * because that will both record changes for undo/redo and will update all bindings * that make depend on that property. * Simply modifying the data and calling an "update..." method will not be able to record * the previous value(s) of properties in the model data to support undo. * * If you know which model data objects have been modified, * it will be more efficient to update only the Parts that need it * by calling Panel#updateTargetBindings. * * To update relationships between nodes, call #updateAllRelationshipsFromData. * @param {string=} srcprop An optional source data property name: * when provided, only evaluates those Bindings that use that particular property; * when not provided or when it is the empty string, all bindings are evaluated. * @see #updateAllRelationshipsFromData */ updateAllTargetBindings(srcprop?: string): void; /** * Add or remove any nodes or links according to additional or missing data objects in the model * and update all of the references to nodes, in case they had been modified in the model without * properly notifying the model by calling Model#addNodeData or * GraphLinksModel#removeLinkData or * GraphLinksModel#setGroupKeyForNodeData or * GraphLinksModel#setToKeyForLinkData or other similar methods. * This method does not conduct a transaction, so you need to start and commit one yourself. * * It is better to call Model#addNodeData, Model#removeNodeData, * GraphLinksModel#addLinkData, GraphLinksModel#removeLinkData, * Model#setDataProperty, and other model methods to add/remove/modify data, * because those methods will both record changes for undo/redo and will update all bindings * that make depend on that property. * Simply modifying the data and calling an "update..." method will not be able to record * the previous value(s) of properties in the model data to support undo. * * This only adds, removes, or updates the relationships between nodes and links, * to have them reflect what is now declared in the model data. * If you know which model data objects have been modified, * it will be more efficient to update only the Parts that need it * by calling Part#updateRelationshipsFromData. * * To update GraphObject properties that are data bound, call #updateAllTargetBindings. * @see #updateAllTargetBindings * @since 1.5 */ updateAllRelationshipsFromData(): void; /** * Deselect all selected Parts. * This removes all parts from the #selection collection. * * This method raises the "ChangingSelection" and "ChangedSelection" DiagramEvents. * @expose * @param {boolean=} skipsEvents if true, do not raise the DiagramEvents "ChangingSelection" and "ChangedSelection"; if not supplied the value is assumed to be false. * @see #select * @see #selectCollection * @see #clearHighlighteds */ clearSelection(skipsEvents?: boolean): void; /** * Make the given object the only selected object. * Afterwards the #selection collection will have only the given part in it. * * This method raises the "ChangingSelection" and "ChangedSelection" DiagramEvents. * @param {Part} part a Part that is already in a layer of this Diagram. * If the value is null, this does nothing. * @see #selectCollection * @see #clearSelection * @see #highlight */ select(part: Part | null): void; /** * Select all of the Parts supplied in the given collection, and deselect all other Parts. * * This method raises the "ChangingSelection" and "ChangedSelection" DiagramEvents. * @param {Iterable.|Array.} coll a List or Set or Iterator or Array, of Parts to be selected. * @see #select * @see #clearSelection * @see #highlightCollection */ selectCollection(coll: Iterable | Array): void; /** * Remove highlights from all Parts. * This removes all parts from the #highlighteds collection. * * Note that no predefined command or tool operates on the #highlighteds collection, * and there is no predefined visual rendering when a part becomes Part#isHighlighted. * @expose * @see #highlight * @see #highlightCollection * @see Part#isHighlighted * @see #clearSelection * @since 1.4 */ clearHighlighteds(): void; /** * Make the given part the only highlighted part. * Afterwards the #highlighteds collection will have only the given part in it. * * Note that no predefined command or tool operates on the #highlighteds collection, * and there is no predefined visual rendering when a part becomes Part#isHighlighted. * @param {Part} part a Part that is already in a layer of this Diagram. * If the value is null, this does nothing. * @see Part#isHighlighted * @see #highlightCollection * @see #clearHighlighteds * @see #select * @since 1.4 */ highlight(part: Part | null): void; /** * Highlight all of the Parts supplied in the given collection, and unhighlight all other highlighted Parts. * * Note that no predefined command or tool operates on the #highlighteds collection, * and there is no predefined visual rendering when a part becomes Part#isHighlighted. * @param {Iterable.|Array.} coll a List or Set or Iterator or Array, of Parts to be highlighted. * @see Part#isHighlighted * @see #highlight * @see #clearHighlighteds * @see #selectCollection * @since 1.4 */ highlightCollection(coll: Iterable | Array): void; /** * Scrolling function used by primarily by #commandHandler's CommandHandler#doKeyDown. * @param {string} unit A string representing the unit of the scroll operation. Can only be 'pixel', 'line', 'page', or 'document'. * @param {string} dir The direction of the scroll operation. Can only be 'up', 'down', 'left', or 'right'. * @param {number=} dist An optional distance multiplier, for multiple pixels, lines, or pages. The default value is 1. * This argument is ignored when the unit is 'document'. * @see #scrollToRect * @see #centerRect */ scroll(unit: ('pixel' | 'line' | 'page' | 'document'), dir: ('up' | 'down' | 'left' | 'right'), dist?: number): void; /** * Modifies the #position to show a given Rect of the Diagram by centering the * viewport on that Rect. Does nothing if the Rect is already entirely in view. * * See also #centerRect * @param {Rect} r * @see #centerRect * @see #scroll * @see CommandHandler#scrollToPart */ scrollToRect(r: Rect): void; /** * Modifies the #position to show a given Rect of the Diagram by centering the * viewport on that Rect. * * If the rect is near the #documentBounds and if the * #scrollMargin is small, it might not be possible to scroll far enough to * actually put the Rect area in the center of the viewport. * @param {Rect} r * @see #scrollToRect * @see #scroll */ centerRect(r: Rect): void; /** * Given a Point in document coordinates, return a new Point in viewport coordinates. * @param {Point} p * @return {Point} The given Point converted into View coordinates. * @see #transformViewToDoc * @see GraphObject#getDocumentPoint */ transformDocToView(p: Point): Point; /** * Given a point in viewport coordinates, return a new Point in document coordinates. * @param {Point} p * @return {Point} The given point converted into Document coordinates. * @see #transformDocToView * @see GraphObject#getDocumentPoint */ transformViewToDoc(p: Point): Point; /** * The default autoScale type, used as the value of Diagram#autoScale: * The Diagram does not attempt to scale so that its documentBounds would fit the view. * @constant */ static None: EnumValue; /** * Diagrams with this autoScale type, used as the value of Diagram#autoScale, * are scaled uniformly until the whole documentBounds fits in the view. * @constant */ static Uniform: EnumValue; /** * Diagrams with this autoScale type, used as the value of Diagram#autoScale, * are scaled until the documentBounds fits in the view in one direction while * a scrollbar is still needed in the other direction. * @constant */ static UniformToFill: EnumValue; /** * This value for Diagram#validCycle states that * there are no restrictions on making cycles of links. * @constant */ static CycleAll: EnumValue; /** * This value for Diagram#validCycle states that * a valid link from a node will not produce a directed cycle in the graph. * @constant */ static CycleNotDirected: EnumValue; /** * This value for Diagram#validCycle states that * a valid link from a node will not produce an undirected cycle in the graph. * @constant */ static CycleNotUndirected: EnumValue; /** * This value for Diagram#validCycle states that * any number of destination links may go out of a node, but at most one * source link may come into a node, and there are no directed cycles. * * This value assumes that the graph does not already have any cycles in it, * or else the behavior may be indeterminate. * @constant */ static CycleDestinationTree: EnumValue; /** * This value for Diagram#validCycle states that * any number of source links may come into a node, but at most one * destination link may go out of a node, and there are no directed cycles. * * This value assumes that the graph does not already have any cycles in it, * or else the behavior may be indeterminate. * @constant */ static CycleSourceTree: EnumValue; /** * This value for Diagram#scrollMode states that * the viewport constrains scrolling to the Diagram document bounds. * @constant */ static DocumentScroll: EnumValue; /** * This value for Diagram#scrollMode states that * the viewport does not constrain scrolling to the Diagram document bounds. * @constant */ static InfiniteScroll: EnumValue; /** * Gets or sets the opacity for all parts in this diagram. * The value must be between 0.0 (fully transparent) and 1.0 (no additional transparency). * This value is multiplicative with any existing transparency, * for instance from a Brush or image transparency. * The default value is 1. * @since 2.1 * @see Layer#opacity * @see GraphObject#opacity */ get opacity(): number; set opacity(value: number); /** * Gets or sets what kinds of graphs this diagram allows the user to draw. * By default this property is Diagram.CycleAll -- all kinds of cycles are permitted. * Common values include Diagram.CycleDestinationTree and Diagram.CycleNotDirected. */ get validCycle(): EnumValue; set validCycle(value: EnumValue); /** * This read-only property returns an iterator for this Diagram's Layers. * @see #addLayer * @see #removeLayer */ get layers(): Iterator; /** * Gets or sets whether the Diagram's Diagram#model is Model#isReadOnly. * @see #isReadOnly * @see #isEnabled */ get isModelReadOnly(): boolean; set isModelReadOnly(value: boolean); /** * Gets or sets whether the Diagram may be modified by the user, * while still allowing the user to scroll, zoom, and select. * The initial value is false. * @see #isModelReadOnly * @see #isEnabled */ get isReadOnly(): boolean; set isReadOnly(value: boolean); /** * Gets or sets whether the user may interact with the Diagram. * @see #isReadOnly * @see #isModelReadOnly */ get isEnabled(): boolean; set isEnabled(value: boolean); /** * Gets or sets whether the user may copy to or paste parts from the internal clipboard. * This allows use of CommandHandler#cutSelection, * CommandHandler#copySelection and CommandHandler#pasteSelection. * The initial value is true. */ get allowClipboard(): boolean; set allowClipboard(value: boolean); /** * Gets or sets whether the user may copy objects. * The initial value is true. */ get allowCopy(): boolean; set allowCopy(value: boolean); /** * Gets or sets whether the user may delete objects from the Diagram. * The initial value is true. */ get allowDelete(): boolean; set allowDelete(value: boolean); /** * Gets or sets whether the user may start a drag-and-drop in this Diagram, * possibly dropping in a different element. * The initial value is false. */ get allowDragOut(): boolean; set allowDragOut(value: boolean); /** * Gets or sets whether the user may end a drag-and-drop operation in this Diagram. * This is typically set to true when a Diagram is used with a Palette. * * The initial value is true. */ get allowDrop(): boolean; set allowDrop(value: boolean); /** * Gets or sets whether the user may do in-place text editing. * The initial value is true. */ get allowTextEdit(): boolean; set allowTextEdit(value: boolean); /** * Gets or sets whether the user may group parts together. * The initial value is true. */ get allowGroup(): boolean; set allowGroup(value: boolean); /** * Gets or sets whether the user may ungroup existing groups. * The initial value is true. */ get allowUngroup(): boolean; set allowUngroup(value: boolean); /** * Gets or sets whether the user may add parts to the Diagram. * The initial value is true. */ get allowInsert(): boolean; set allowInsert(value: boolean); /** * Gets or sets whether the user may draw new links. * The initial value is true. */ get allowLink(): boolean; set allowLink(value: boolean); /** * Gets or sets whether the user may reconnect existing links. * The initial value is true. */ get allowRelink(): boolean; set allowRelink(value: boolean); /** * Gets or sets whether the user may move objects. * The initial value is true. */ get allowMove(): boolean; set allowMove(value: boolean); /** * Gets or sets whether the user may reshape parts. * The initial value is true. */ get allowReshape(): boolean; set allowReshape(value: boolean); /** * Gets or sets whether the user may resize parts. * The initial value is true. */ get allowResize(): boolean; set allowResize(value: boolean); /** * Gets or sets whether the user may rotate parts. * The initial value is true. */ get allowRotate(): boolean; set allowRotate(value: boolean); /** * Gets or sets whether the user may select objects. * The initial value is true. */ get allowSelect(): boolean; set allowSelect(value: boolean); /** * Gets or sets whether the user may undo or redo any changes. * The initial value is true. */ get allowUndo(): boolean; set allowUndo(value: boolean); /** * Gets or sets whether the user may zoom into or out of the Diagram. * The initial value is true. */ get allowZoom(): boolean; set allowZoom(value: boolean); /** * Gets or sets whether the Diagram has a vertical Scrollbar. * * To enable or disable scrolling itself, use #allowHorizontalScroll and #allowVerticalScroll. * * Adding or removing a scrollbar modifies the diagram's viewport. * * The initial value is true. * @see #allowVerticalScroll * @see #hasHorizontalScrollbar */ get hasVerticalScrollbar(): boolean; set hasVerticalScrollbar(value: boolean); /** * Gets or sets whether the Diagram has a horizontal Scrollbar. * * To enable or disable scrolling itself, use #allowHorizontalScroll and #allowVerticalScroll. * * Adding or removing a scrollbar modifies the diagram's viewport. * * The initial value is true. * @see #allowHorizontalScroll * @see #hasVerticalScrollbar */ get hasHorizontalScrollbar(): boolean; set hasHorizontalScrollbar(value: boolean); /** * Gets or sets whether the user is allowed to use the horizontal scrollbar. * The initial value is true. * @see #hasHorizontalScrollbar * @see #allowVerticalScroll */ get allowHorizontalScroll(): boolean; set allowHorizontalScroll(value: boolean); /** * Gets or sets whether the user is allowed to use the vertical scrollbar. * The initial value is true. * @see #hasVerticalScrollbar * @see #allowHorizontalScroll */ get allowVerticalScroll(): boolean; set allowVerticalScroll(value: boolean); /** * Gets or sets the distance in screen pixels that the horizontal scrollbar will scroll * when scrolling by a line. * * The default value is 16. * @see #scrollVerticalLineChange */ get scrollHorizontalLineChange(): number; set scrollHorizontalLineChange(value: number); /** * Gets or sets the distance in screen pixels that the vertical scrollbar will scroll * when scrolling by a line. * * The default value is 16. * @see #scrollHorizontalLineChange */ get scrollVerticalLineChange(): number; set scrollVerticalLineChange(value: number); /** * Gets or sets the last InputEvent that occurred. * * This property is useful in tools and real-time operations for determining * where the mouse pointer was most recently located. * * Setting this property does not notify about any changed event. * @see #firstInput */ get lastInput(): InputEvent; set lastInput(value: InputEvent); set previousInput(value: InputEvent); /** * Gets or sets the most recent mouse-down InputEvent that occurred. * * Setting this property does not notify about any changed event. * @see #lastInput */ get firstInput(): InputEvent; set firstInput(value: InputEvent); /** * Gets or sets the current cursor for the Diagram, overriding the #defaultCursor. * * Valid CSS cursors are accepted, * such as "auto", "default", "none", "context-menu", "help", "pointer", "progress", "wait", etc. * * It is possible to use custom cursors with the syntax "url(path_to_image), default". * A fallback (like default here) is necessary for a custom cursor to work. * * To read more about cursor syntax, go to: * CSS cursors (mozilla.org). * * If the specified cursor is not accepted by the platform, this property setter will try prepending * `-webkit-` and `-moz-` prefixes when assigning the "cursor" CSS style property. * * Setting this property does not notify about any changed event. * Setting this value to the empty string ('') returns the Diagram's cursor to the #defaultCursor. * @see #defaultCursor * @see GraphObject#cursor */ get currentCursor(): string; set currentCursor(value: string); /** * Gets or sets the cursor to be used for the Diagram * when no GraphObject specifies a different cursor. * * Valid CSS cursors are accepted, * such as "auto", "default", "none", "context-menu", "help", "pointer", "progress", "wait", etc. * * It is possible to use custom cursors with the syntax "url(path_to_image), default". * A fallback (like default here) is necessary for a custom cursor to work. * * To read more about cursor syntax, go to: * CSS cursors (mozilla.org). * The default value is "auto". * @see #currentCursor * @see GraphObject#cursor */ get defaultCursor(): string; set defaultCursor(value: string); /** * Gets or sets the function to execute when the user single-primary-clicks * on the background of the Diagram. * This typically involves a mouse-down followed by a prompt mouse-up * at approximately the same position using the left (primary) mouse button. * This property is used by the ClickSelectingTool * when the user clicks on no object. * The function is called in addition to the DiagramEvent * that is raised with the name "BackgroundSingleClicked". * * If this property value is a function, it is called with an InputEvent. * By default this property is null. * * If you do provide a function that makes changes to the diagram or to its model, * you should do so within a transaction -- call #startTransaction and #commitTransaction, * or call #commit. * @see #doubleClick * @see #contextClick * @see GraphObject#click */ get click(): ((e: InputEvent) => void) | null; set click(value: ((e: InputEvent) => void) | null); /** * Gets or sets the function to execute when the user double-primary-clicks * on the background of the Diagram. * This typically involves a mouse-down/up/down/up in rapid succession * at approximately the same position using the left (primary) mouse button. * This property is used by the ClickSelectingTool * when the user clicks on no object. * The function is called in addition to the DiagramEvent * that is raised with the name "BackgroundDoubleClicked". * * If this property value is a function, it is called with an InputEvent. * By default this property is null. * * If you do provide a function that makes changes to the diagram or to its model, * you should do so within a transaction -- call #startTransaction and #commitTransaction, * or call #commit. * @see #click * @see #contextClick * @see GraphObject#doubleClick */ get doubleClick(): ((e: InputEvent) => void) | null; set doubleClick(value: ((e: InputEvent) => void) | null); /** * Gets or sets the function to execute when the user single-secondary-clicks * on the background of the Diagram. * This typically involves a mouse-down followed by a prompt mouse-up * at approximately the same position using the right (secondary) mouse button. * This property is used by the ClickSelectingTool * when the user clicks on no object. * The function is called in addition to the DiagramEvent * that is raised with the name "BackgroundContextClicked". * * If this property value is a function, it is called with an InputEvent. * By default this property is null. * * If you do provide a function that makes changes to the diagram or to its model, * you should do so within a transaction -- call #startTransaction and #commitTransaction, * or call #commit. * @see #click * @see #doubleClick * @see GraphObject#contextClick */ get contextClick(): ((e: InputEvent) => void) | null; set contextClick(value: ((e: InputEvent) => void) | null); /** * Gets or sets the function to execute when the user moves the mouse (pointer) in * the background of the Diagram without holding down any buttons, * not over any GraphObjects. * This property is used by the ToolManager. * * If this property value is a function, it is called with an InputEvent. * By default this property is null. * * This function is called with Diagram#skipsUndoManager temporarily set to true, * so that any changes to GraphObjects are not recorded in the UndoManager. * You do not need to start and commit any transaction in this function. * After calling this function the diagram will be updated immediately. * @see #mouseHover * @see GraphObject#mouseOver */ get mouseOver(): ((e: InputEvent) => void) | null; set mouseOver(value: ((e: InputEvent) => void) | null); /** * Gets or sets the function to execute when the user holds the mouse (pointer) stationary in * the background of the Diagram without holding down any buttons, * not over any GraphObjects. * This property is used by the ToolManager. * * If this property value is a function, it is called with an InputEvent. * By default this property is null. * * If you do provide a function that makes changes to the diagram or to its model, * you should do so within a transaction -- call #startTransaction and #commitTransaction, * or call #commit. * @see #mouseOver * @see GraphObject#mouseHover * @see ToolManager#doMouseHover */ get mouseHover(): ((e: InputEvent) => void) | null; set mouseHover(value: ((e: InputEvent) => void) | null); /** * Gets or sets the function to execute when the user holds the mouse (pointer) stationary in * the background of the Diagram while holding down a button, * not over any GraphObjects. * This property is used by the ToolManager. * * If this property value is a function, it is called with an InputEvent. * By default this property is null. * * If you do provide a function that makes changes to the diagram or to its model, * you should do so within a transaction -- call #startTransaction and #commitTransaction, * or call #commit. * @see GraphObject#mouseHold * @see ToolManager#doMouseHover */ get mouseHold(): ((e: InputEvent) => void) | null; set mouseHold(value: ((e: InputEvent) => void) | null); /** * Gets or sets the function to execute when the user is dragging the selection in * the background of the Diagram during a DraggingTool drag-and-drop, * not over any GraphObjects. * * If this property value is a function, it is called with an InputEvent. * It is called within the transaction performed by the DraggingTool. * By default this property is null. * * Note that for a drag-and-drop that originates in a different diagram, the target diagram's * selection collection will not be the parts that are being dragged. * Instead the temporary parts being dragged can be found as the source diagram's DraggingTool#copiedParts. * * This function is called with Diagram#skipsUndoManager temporarily set to true, * so that any changes to GraphObjects are not recorded in the UndoManager. * You do not need to start and commit any transaction in this function. * After calling this function the diagram will be updated immediately. * * For example, if you want to prevent the user from dropping Parts into the background of the diagram, * and want to provide feedback about that during a drag: * ```js * myDiagram.mouseDragOver = e => { * myDiagram.currentCursor = "no-drop"; * } * ``` * @see #mouseDrop * @see GraphObject#mouseDragEnter * @see GraphObject#mouseDragLeave */ get mouseDragOver(): ((e: InputEvent) => void) | null; set mouseDragOver(value: ((e: InputEvent) => void) | null); /** * Gets or sets the function to execute when the user drops the selection in * the background of the Diagram at the end of a DraggingTool drag-and-drop, * not onto any GraphObjects. * * If this property value is a function, it is called with an InputEvent. * It is called within the transaction performed by the DraggingTool. * By default this property is null. * * For example, if you want to prevent the user from dropping Parts into the background of the diagram: * ```js * myDiagram.mouseDrop = e => { * myDiagram.currentTool.doCancel(); * } * ``` * @see #mouseDragOver * @see GraphObject#mouseDrop */ get mouseDrop(): ((e: InputEvent) => void) | null; set mouseDrop(value: ((e: InputEvent) => void) | null); /** * Gets or sets whether drag-and-drop events may be bubbled up to the diagram if not handled by a part. * The default value is false -- each Node or Link that in the diagram needs to define * its own GraphObject#mouseDragEnter, GraphObject#mouseDragLeave, and GraphObject#mouseDrop * event handlers if you want dragging/dropping on a part to act as if the user were acting on the diagram. * * If set to true, this will call Diagram#mouseDragOver during a drag, even while dragging over top-level parts, * and Diagram#mouseDrop will be called even when dropping onto parts. * * This property will have no impact while dropping on a Group. * The Group's mouseDrop and Group#handlesDragDropForMembers should be set if desired. * * GraphObjects do not have a mouseDragOver property, so if this is set to true, the Diagram's mouseDragOver will * always be called, even when dragging over a part. * @see #mouseDragOver * @see #mouseDrop * @see Group#handlesDragDropForMembers * @see GraphObject#mouseDrop * @since 2.0 */ get handlesDragDropForTopLevelParts(): boolean; set handlesDragDropForTopLevelParts(value: boolean); /** * Gets or sets the function to execute when the mouse (pointer) enters the Diagram. * (When the browser's mouseEnter event fires on the Diagram canvas.) * * If this property value is a function, it is called with an InputEvent. * By default this property is null. * * If you do provide a function that makes changes to the diagram or to its model, * you should do so within a transaction -- call #startTransaction and #commitTransaction, * or call #commit. * @see #mouseLeave * @see GraphObject#mouseEnter * @since 2.0 */ get mouseEnter(): ((e: InputEvent) => void) | null; set mouseEnter(value: ((e: InputEvent) => void) | null); /** * Gets or sets the function to execute when the mouse (pointer) leaves the Diagram. * * If this property value is a function, it is called with an InputEvent. * By default this property is null. * * If you do provide a function that makes changes to the diagram or to its model, * you should do so within a transaction -- call #startTransaction and #commitTransaction, * or call #commit. * @see #mouseEnter * @see GraphObject#mouseLeave * @since 2.0 */ get mouseLeave(): ((e: InputEvent) => void) | null; set mouseLeave(value: ((e: InputEvent) => void) | null); /** * This Adornment or HTMLInfo is shown when the mouse (pointer) stays motionless in the background. * The default value is null, which means no tooltip is shown. * * Here is a simple example: * ```js * diagram.toolTip = * $(go.Adornment, "Auto", * $(go.Shape, { fill: "#CCFFCC" }), * $(go.TextBlock, { margin: 4 }, * "This diagram lets you control the world.") * ); * ``` * @see GraphObject#toolTip * @see ToolManager#doToolTip */ get toolTip(): Adornment | HTMLInfo | null; set toolTip(value: Adornment | HTMLInfo | null); /** * This Adornment or HTMLInfo is shown when the use context clicks in the background. * The default value is null, which means no context menu is shown. * On touch devices, a special default context menu will appear even there is no context menu defined. * See ContextMenuTool#defaultTouchContextMenu for details. * * ```js * diagram.contextMenu = * $("ContextMenu", * $("ContextMenuButton", * $(go.TextBlock, "Undo"), * { click: (e, obj) => e.diagram.commandHandler.undo() }, * new go.Binding("visible", "", o => o.diagram.commandHandler.canUndo()).ofObject()), * $("ContextMenuButton", * $(go.TextBlock, "Redo"), * { click: (e, obj) => e.diagram.commandHandler.redo() }, * new go.Binding("visible", "", o => o.diagram.commandHandler.canRedo()).ofObject()) * ); * ``` * @see GraphObject#contextMenu * @see ContextMenuTool */ get contextMenu(): Adornment | HTMLInfo | null; set contextMenu(value: Adornment | HTMLInfo | null); /** * Gets or sets the CommandHandler for this Diagram. * * This is set to a new instance of CommandHandler on Diagram instantiation. * * Setting this property does not notify about any changed event. * The value cannot be null and must not be shared with other Diagrams. */ get commandHandler(): CommandHandler; set commandHandler(value: CommandHandler); /** * Gets or sets the ToolManager for this Diagram. * This tool is used for mode-less operation. * It is responsible for choosing a particular tool to run as the #currentTool. * * This tool is normally also the #defaultTool. * If you don't want the ToolManager to run at all, * replace the #defaultTool with your own tool. * * Setting this property does not notify about any changed event. * The value cannot be null and must not be shared with other Diagrams. * If you set this property, you will probably also want to set #defaultTool. * @see #defaultTool */ get toolManager(): ToolManager; set toolManager(value: ToolManager); /** * Gets or sets the default tool for this Diagram that becomes the current tool when the current tool stops. * Initially this value is the same tool as #toolManager, which is an instance of ToolManager. * * Setting this property also sets the #currentTool if the old default tool is the currently running tool. * * Setting this property does not notify about any changed event. * The value cannot be null and must not be shared with other Diagrams. * @see #currentTool * @see #toolManager */ get defaultTool(): Tool; set defaultTool(value: Tool); /** * Gets or sets the current tool for this Diagram that handles all input events. * This value is frequently replaced by the #toolManager as different tools run. * * Each Diagram has a number of tools that define its behavior when responding to mouse events. * These include ClickSelectingTool, DraggingTool, DragSelectingTool, LinkingTool, and ResizingTool, among others. * * Initially this is set to the value of #defaultTool. * Setting this to a null value is treated as if it were set to the #defaultTool, * because there should always be a currently running tool, except when the diagram is being initialized. * * A ToolManager is the default tool used by a Diagram - it chooses to run one of the other tools * depending on the circumstances. * * Setting this property to a new tool stops the previous current tool * * Setting this property does not notify about any changed event. * @see #defaultTool * @see #toolManager */ get currentTool(): Tool; set currentTool(value: Tool); /** * This read-only property returns the read-only collection of selected objects. * Most commands and many tools operate on this collection. * * Do not modify this collection. * If you want to select or deselect a particular object in a Diagram, * set the Part#isSelected property. * If you want to select a collection of Parts, call #selectCollection. * If you want to deselect all objects, call #clearSelection. * If you want to deselect all objects and select a single object, call #select. * * You can limit how many objects the user can select by setting #maxSelectionCount. * * There are also DiagramEvents for "ChangingSelection" and "ChangedSelection", * which are raised by commands and tools before and after changes to this selection collection. * * Note that selection collection and Part#isSelected property are completely independent * of the #highlighteds collection and the Part#isHighlighted property. */ get selection(): Set; /** * Gets or sets the maximum number of selected objects. * The default value is a large positive integer. * Values must be non-negative. * Decreasing this value may cause objects to be removed from #selection * in order to meet the new lower limit. */ get maxSelectionCount(): number; set maxSelectionCount(value: number); /** * Gets or sets the default selection Adornment template, used to adorn selected Parts other than Groups or Links. * * Each Node or simple Part can have its own Part#selectionAdornmentTemplate, * which if non-null will take precedence over this Diagram property. * * This Adornment must not be in the visual tree of any Diagram. */ get nodeSelectionAdornmentTemplate(): Adornment; set nodeSelectionAdornmentTemplate(value: Adornment); /** * Gets or sets the default selection Adornment template, used to adorn selected Groups. * * Each Group can have its own Part#selectionAdornmentTemplate, which if non-null will take precedence over this Diagram property. * * This Adornment must not be in the visual tree of any Diagram. */ get groupSelectionAdornmentTemplate(): Adornment; set groupSelectionAdornmentTemplate(value: Adornment); /** * Gets or sets the default selection Adornment template, used to adorn selected Links. * * Each Link can have its own Part#selectionAdornmentTemplate, which if non-null will take precedence over this Diagram property. * * This Adornment must not be in the visual tree of any Diagram. */ get linkSelectionAdornmentTemplate(): Adornment; set linkSelectionAdornmentTemplate(value: Adornment); /** * This read-only property returns the read-only collection of highlighted parts. * * Do not modify this collection. * If you want to highlight or remove the highlight for a particular Part in a Diagram, * set the Part#isHighlighted property. * If you want to highlight a collection of Parts, call #highlightCollection. * If you want to remove all highlights and highlight a single object, call #highlight. * If you want to remove all highlights, call #clearHighlighteds. * * Note that highlighteds collection and Part#isHighlighted property are completely independent * of the #selection collection and the Part#isSelected property. * No predefined command or tool operates on this highlighteds collection. */ get highlighteds(): Set; /** * Gets or sets whether this Diagram's state has been modified. * Setting this property does not notify about any changed event, * but it does raise the "Modified" DiagramEvent, * although perhaps not immediately. * * Returns true if the Diagram has been changed, * if the #undoManager has recorded any changes, or * if an undo has been performed without a corresponding redo. * * Replacing the #model automatically sets this property to false after the initial layout has completed. * The "Modified" DiagramEvent is also raised when an undo or a redo has finished. * A "Modified" DiagramEvent listener must not modify this Diagram or its Model. */ get isModified(): boolean; set isModified(value: boolean); /** * Gets or sets the Model holding data corresponding to the * data-bound nodes and links of this Diagram. * * Replacing this value causes all of the bound Nodes and Links to be deleted and re-created * from the new model data. * * Models may be shared by multiple Diagrams. One common approach is to have two * Diagrams displaying the same Model but using different templates * (see #nodeTemplate, #nodeTemplateMap, and the associated link and group properties) and sometimes even different Layouts. * * Setting this property does not notify about any changed event; the new value must not be null. * Typically a new Model will have its own UndoManager, thereby replacing the Diagram's * current UndoManager. * * Replacing or re-setting the model will re-initialize the Diagram, taking in to account * #initialPosition, #initialScale, #initialAutoScale, and #initialContentAlignment. * It will also set #isModified to false. * * The default behavior when replacing the model is to copy a few UndoManager properties to the * new UndoManager, including UndoManager#isEnabled and UndoManager#maxHistoryLength. * * It is an error to replace the Diagram.model while a transaction is in progress. */ get model(): Model; set model(value: Model); /** * Gets or sets the license key. * @since 2.0 */ static get licenseKey(): string; static set licenseKey(value: string); /** * Gets the current GoJS version. * @since 2.0 */ static get version(): string; set skipsModelSourceBindings(value: boolean); /** * Remove all of the Parts created from model data * and then create them again. * This must be called after modifying or replacing any of the template maps * such as #nodeTemplateMap. * This re-selects all of the new Parts that were created from data of the original selected Parts. * * If you modify a template Map, there is no notification that the map has changed. * You will need to call rebuildParts explicitly. * If you are replacing the #nodeTemplate or the #nodeTemplateMap or * the corresponding properties for Groups or Links, * the Diagram property setters will automatically call rebuildParts. * * It is extremely wasteful to call this method after making some model data changes that you want to * be reflected in the diagram. Instead, it is better call Model#setDataProperty, * Model#addNodeData, Model#removeNodeData, or other model methods. * Not only do those methods update efficiently, they also preserve unbound state and support undo/redo. */ rebuildParts(): void; /** * Look for a Part or Node or Group corresponding to a model's data object's unique key. * This will find a Link if the model is a GraphLinksModel that is maintaining a key on the link data objects. * @param {(string|number|undefined)} key a string or number. * @return {Part} null if a data with that key cannot be found in the model, * or if a corresponding Part cannot be found in the Diagram. * This will not return a Link unless the model is a GraphLinksModel and * GraphLinksModel#linkKeyProperty has been set. * If the same key is used for both a node data object and a link data object, this will return a Node. */ findPartForKey(key: Key): Part | null; /** * Look for a Node or Group corresponding to a model's node data object's unique key. * @param {(string|number|undefined)} key a string or number. * @return {Node} null if a node data with that key cannot be found in the model, * or if a corresponding Node or Group cannot be found in the Diagram, * or if what is found is just a Part. */ findNodeForKey(key: Key): Node | null; /** * Look for a Link corresponding to a model's link data object's unique key. * @param {(string|number|undefined)} key a string or number. * @return {Link} null if a link data with that key cannot be found in the model, * or if a corresponding Link cannot be found in the Diagram, * or if the model is a GraphLinksModel without GraphLinksModel#linkKeyProperty set to a non-empty string. * @since 2.1 */ findLinkForKey(key: Key): Link | null; /** * Look for a Part, Node, Group, or Link corresponding to a Model's data object. * We recommend that you call #findNodeForData or #findLinkForData if you are looking for a Node or a Link. * @param {Object} data a JavaScript object matched by reference identity * @return {Part} an existing Part in this Diagram that was * created because its `Part.data` was the data in the Diagram's Model. */ findPartForData(data: ObjectData): Part | null; /** * Look for a Node or Group corresponding to a model's node data object. * @param {Object} nodedata a JavaScript object matched by reference identity; * use #findNodesByExample if you want to find those Nodes whose data matches an example data object * @return {Node} an existing Node or Group in this Diagram that was * created because its `Part.data` was the node data in the Diagram's Model. * This will be null if there is no such part or if it's just a Part or Link. */ findNodeForData(nodedata: ObjectData): Node | null; /** * Look for a Link corresponding to a GraphLinksModel's link data object. * @param {Object} linkdata a JavaScript object matched by reference identity; * use #findLinksByExample if you want to find those Links whose data matches an example data object * @return {Link} an existing Link in this Diagram that was * created because its `Part.data` was the link data in the Diagram's Model. */ findLinkForData(linkdata: ObjectData): Link | null; /** * Search for Nodes or Groups by matching the Node data with example data holding values, RegExps, or predicates. * * For example, calling this method with an argument object: * `{ sex: "M", name: /^Alex/i, age: n => n >= 18 }` * will return an iterator of Nodes whose `Node.data` is a JavaScript object whose: * - sex is "M" (a case-sensitive string comparison), and * - name starts with the string "Alex" (using a case-insensitive match), and * - age is greater than or equal to 18 * * Here is how an example value can match the corresponding data value: * - A string, number, or boolean is compared with the === operator. * - A function is treated as a predicate and applied to the data value. * - A regular expression (RexExp) is matched against the toString() of the data value. * Common expressions include: * - `/abc/` matches any string that includes exactly the substring "abc" * - `/abc/i` matches any string that includes the substring "abc", but uses a case-insensitive comparison * - `/^no/i` matches any string that starts with "no", ignoring case * - `/ism$` matches any string that ends with "ism" exactly * - `/(green|red) apple/` matches any string that includes either "green apple" or "red apple" * * For more details read Regular Expressions (mozilla.org). * - An Array requires the data value to also be an Array of equal or greater length. * Each example array item that is not undefined is matched with the corresponding data array item. * - An Object is recursively matched with the data value, which must also be an Object. * * All properties given by the argument example data must be present on the node data, * unless the example property value is undefined. * All other data properties are ignored when matching. * * When multiple argument objects are given, if any of the objects match the node's data, * the node is included in the results. * @param {...Object} examples one or more JavaScript Objects whose properties are either predicates to be * applied or RegExps to be tested or values to be compared to the corresponding data property value * @return {Iterator.} * @see #findLinksByExample * @since 1.5 */ findNodesByExample(...examples: Array): Iterator; /** * Search for Links by matching the Link data with example data holding values, RegExps, or predicates. * * See the documentation of #findNodesByExample for how the example * data can match data of bound Parts. * @param {...Object} examples one or more JavaScript Objects whose properties are either predicates to be * applied or RegExps to be tested or values to be compared to the corresponding data property value * @return {Iterator.} * @see #findNodesByExample * @since 1.5 */ findLinksByExample(...examples: Array): Iterator; /** * Gets or sets the default Node template used as the archetype * for node data that is added to the #model. * Setting this property just modifies the #nodeTemplateMap * by replacing the entry named with the empty string. * * The value must not be null. * The template may be either a Node or a simple Part, * but not a Link or a Group. * * This Part must not be in the visual tree of any Diagram. */ get nodeTemplate(): Part; set nodeTemplate(value: Part); /** * Gets or sets a Map mapping template names to Parts. * These nodes are copied for each node data that is added to the #model. * * The new value must not be null and must contain Nodes or simple Parts. * These Parts must not be in the visual tree of any Diagram. * Replacing this Map will automatically call #rebuildParts. * * If you modify this Map, by replacing a Node or by adding or * removing a map entry, you need to explicitly call #rebuildParts afterwards. * Any new map values must not be Links or Groups. * * If you want to create Groups, use #groupTemplateMap instead. */ get nodeTemplateMap(): Map; set nodeTemplateMap(value: Map); /** * Gets or sets the default Group template used as the archetype * for group data that is added to the #model. * * Setting this property just modifies the #groupTemplateMap * by replacing the entry named with the empty string. * The value must not be null and must be a Group, not a Node or simple Part. * This Part must not be in the visual tree of any Diagram. */ get groupTemplate(): Group; set groupTemplate(value: Group); /** * Gets or sets a Map mapping template names to Groups. * These groups are copied for each group data that is added to the #model. * * The new value must not be null, nor may it contain a Node or Link or simple Part. * The Links must not be in the visual tree of any Diagram. * Replacing this Map will automatically call #rebuildParts. * * If you modify this Map, by replacing a Group in it or by adding or * removing a map entry, you need to explicitly call #rebuildParts afterwards. */ get groupTemplateMap(): Map; set groupTemplateMap(value: Map); /** * Gets or sets the default Link template used as the archetype * for link data that is added to the #model. * * Setting this property just modifies the #linkTemplateMap * by replacing the entry named with the empty string. * The value must not be null and must be a Link, not a Node or simple Part. * This Link must not be in the visual tree of any Diagram. */ get linkTemplate(): Link; set linkTemplate(value: Link); /** * Gets or sets a Map mapping template names to Links. * These links are copied for each link data that is added to the #model. * * The new value must not be null and must contain only Links, not Nodes or simple Parts. * The Links must not be in the visual tree of any Diagram. * Replacing this Map will automatically call #rebuildParts. * * If you modify this Map, by replacing a Link in it or by adding or * removing a map entry, you need to explicitly call #rebuildParts afterwards. */ get linkTemplateMap(): Map; set linkTemplateMap(value: Map); /** * Gets or sets whether mouse events initiated within the Diagram will be captured. * The initial value is true. * Setting this property does not notify about any changed event. */ get isMouseCaptured(): boolean; set isMouseCaptured(value: boolean); /** * Gets or sets the coordinates of this Diagram in the viewport. * Value must be of type Point in document coordinates. * The default is Point(NaN, NaN), but is typically set to a real value when a Diagram is initialized. * * Scrolling and panning the Diagram modify the Diagram's position. * * Setting this property does not notify about any changed event. * However you can listen with #addDiagramListener for a DiagramEvent * with the name "ViewportBoundsChanged". * * The #viewportBounds x and y values are always the same as the Diagram's position values. * * If you set this property any replacement of the #model will result in a layout * and a computation of new #documentBounds, which in turn may cause the diagram to be scrolled * and zoomed, depending on various Diagram properties named "initial...". * You may want to set #initialPosition instead of setting this property around the time * that you are loading a model. */ get position(): Point; set position(value: Point); /** * Gets or sets the initial coordinates of this Diagram in the viewport, eventually setting the #position. * This value is relevant on initialization of a #model or if #delayInitialization is called. * Value must be of type Point in document coordinates. * The default is Point(NaN, NaN). * * Setting this property has the same effect as implementing * an "InitialLayoutCompleted" DiagramEvent listener that sets #position. * * Setting this property does not notify about any changed event. * @see #initialDocumentSpot * @see #initialViewportSpot * @since 1.1 */ get initialPosition(): Point; set initialPosition(value: Point); /** * Gets or sets the initial scale of this Diagram in the viewport, eventually setting the #scale. * This value is relevant on initialization of a #model or if #delayInitialization is called. * The default is NaN. * * Setting this property has the same effect as implementing * an "InitialLayoutCompleted" DiagramEvent listener that sets #scale. * @since 1.1 */ get initialScale(): number; set initialScale(value: number); /** * Gets or sets a Panel of type Panel.Grid acting as the background grid * extending across the whole viewport of this diagram. */ get grid(): Panel; set grid(value: Panel); /** * This read-only property returns the bounds of the portion of the Diagram in document coordinates that is viewable from its HTML Canvas. * Typically when the viewport bounds are smaller than the #documentBounds, the user can scroll or pan the view. * * The x and y coordinates are equal to the #position of the Diagram, * and the width and height are equal to the Diagram's canvas width and height, * divided by the #scale. */ get viewportBounds(): Rect; /** * Gets or sets a fixed size in document coordinates to be returned by #viewportBounds. This is typically only set when the Diagram's #div is `null`. * This property is intended to be used in DOM-less environments where there is no Diagram #div expected, to simulate the size of the DIV. * Normally, the #viewportBounds is sized by the DIV instead. * * By default this is `Size(NaN, NaN)`. * If this property is set, its size will always be used to compute the #viewportBounds, even if * a #div is also set. It is uncommon to set both this property and a Diagram DIV. * * See the intro page on GoJS within Node.js for a usage example. * * @see #viewportBounds * @since 2.0 */ get viewSize(): Size; set viewSize(value: Size); /** * Gets or sets a fixed bounding rectangle to be returned by #documentBounds * and #computeBounds. * By default this has NaN values, meaning that #computeBounds * will compute the union of all of the parts in the Diagram to determine the #documentBounds. * If all x/y/width/height values are real numbers, this value is used as the #documentBounds. */ get fixedBounds(): Rect; set fixedBounds(value: Rect); /** * Gets or sets a scrollable area in document coordinates that surrounds the document bounds, allowing the user to scroll into empty space. * * The margin is only effective in each direction when the document bounds plus margin is greater than the viewport bounds. * * The default value is a margin of 0, all around the edge of the document. * @since 1.5 */ get scrollMargin(): MarginLike; set scrollMargin(value: MarginLike); /** * Gets or sets the scrollMode of the Diagram, allowing the user to either * scroll to document bound borders with Diagram.DocumentScroll, * or scroll endlessly with Diagram.InfiniteScroll. * * The default value is Diagram.DocumentScroll. * Changing this property value does not raise a Changed event. * @since 1.5 */ get scrollMode(): EnumValue; set scrollMode(value: EnumValue); /** * Gets or sets whether the page may be scrolled when the diagram receives focus. * This happens in some browsers when the top-left corner of the diagram's HTMLDivElement * is scrolled out of view, the diagram does not have focus, and the user clicks in the diagram. * * The default value is false. * @since 1.8 */ get scrollsPageOnFocus(): boolean; set scrollsPageOnFocus(value: boolean); /** * Gets or sets the function used to determine the position that this Diagram can be scrolled or moved to. * * By default this function is null and the Diagram's position is bound only by the document bounds. * * When this property is set the function is given a reference to the diagram and the proposed new position Point. * The function must return a new point. * * An example that disallows decimal position values: * ```js * function computeIntegralPosition(diagram, pt) { * return new go.Point(Math.floor(pt.x), Math.floor(pt.y)); * } * ``` * * The function, if supplied, must not have any side-effects. * @since 1.5 */ get positionComputation(): ((thisDiagram: Diagram, newPosition: Point) => Point) | null; set positionComputation(value: ((thisDiagram: Diagram, newPosition: Point) => Point) | null); /** * Gets or sets the function used to determine valid scale values for this Diagram. * @since 1.5 */ get scaleComputation(): ((thisDiagram: Diagram, newScale: number) => number) | null; set scaleComputation(value: ((thisDiagram: Diagram, newScale: number) => number) | null); /** * This read-only property returns the bounds of the diagram's contents, in document coordinates. * * This is normally computed and set by #computeBounds during Diagram updates * that can occur for any number of relevant reasons, such as a Part changing size. * * The Diagram's documentBounds can have an unvarying specific value * by setting the #fixedBounds property. * * If the documentBounds are larger than the #viewportBounds, * scrollbars will appear on desktop browsers. You can disable scrolling with the * #allowHorizontalScroll and #allowVerticalScroll properties, and * you can disable scrollbars themselves with the #hasHorizontalScrollbar * and #hasVerticalScrollbar properties. */ get documentBounds(): Rect; /** * Ensures that the #documentBounds are up to date. * This is sometimes necessary when operations need updated document bounds immediately. * * It is uncommon to call this method outside of customization. * For efficiency, do not call this method unnecessarily. * @since 2.1.30 * @see Part#ensureBounds */ ensureBounds(): void; /** * (undocumented) */ get isVirtualized(): boolean; set isVirtualized(value: boolean); /** * Gets or sets the scale transform of this Diagram. * Value must be a positive number. * The default value is 1. * Any new value will be coerced to be between #minScale and #maxScale. * * Scale can automatically be set by the #autoScale property. * There are also #initialScale and #initialAutoScale for * setting the scale on (re)initialization of a Diagram. * * Setting this property does not notify about any changed event. * However you can listen with #addDiagramListener for a DiagramEvent * with the name "ViewportBoundsChanged". * * If you set this property any replacement of the #model will result in a layout * and a computation of new #documentBounds, which in turn may cause the diagram to be scrolled * and zoomed, depending on various Diagram properties named "initial...". * You may want to set #initialScale instead of setting this property around the time * that you are loading a model. * * @see #minScale * @see #maxScale * @see #initialScale * @see #defaultScale */ get scale(): number; set scale(value: number); /** * Gets or sets the Diagram#scale set by CommandHandler#resetZoom * and when computing stretch values, such as when #autoScale or * #initialAutoScale are set, or when #zoomToFit is called. * * The default value is 1.0. * The value must be a number larger than 0. * Setting this property does not raise any events. * @since 2.0 */ get defaultScale(): number; set defaultScale(value: number); /** * Gets or sets the autoScale behavior of the Diagram, controlling whether or not the * Diagram's bounds automatically scale to fit the view. * * The only accepted values are the constant properties of Diagram, * Diagram.None, Diagram.Uniform, or Diagram.UniformToFill. * Setting this will change the Diagram's Diagram#scale and Diagram#position, if appropriate. * * The default value is Diagram.None - the scale and position are not automatically adjusted * according to the area covered by the document. * When the value is not None, any value for #initialAutoScale or #initialScale is ignored. *

* When autoScale is set to a non-Diagram.None value, * the user will not be able to zoom, and setting #scale will do nothing. * If you only want to scale automatically on initialization, use #initialAutoScale. * * Setting this property to Diagram.Uniform is basically the same as calling #zoomToFit * all the time, or just disabling interactive zooming. * * Note that depending on the values of #maxScale and #minScale, the actual value for #scale * might be limited. * * The scale will not be increased past the value of #defaultScale, which is normally 1.0, * so as to prevent a single node from appearing to fill up the whole viewport. * * @see #initialAutoScale */ get autoScale(): EnumValue; set autoScale(value: EnumValue); /** * Gets or sets how the scale of the diagram is automatically * set at the time of the "InitialLayoutCompleted" DiagramEvent, after the model has been replaced. * * The only accepted values are listed as constant properties of Diagram, * such as Diagram.None, Diagram.Uniform, or Diagram.UniformToFill. * Setting this will change the Diagram's Diagram#scale and Diagram#position, if appropriate. * * If you want to always automatically scale the Diagram, set #autoScale instead. * If you want to set the scale to a specific value on initialization (each time the model is replaced), * set #initialScale. * * The default value is Diagram.None -- the scale and position are not automatically adjusted * according to the area covered by the document. * * Setting this property to Diagram.Uniform is basically the same as calling #zoomToFit * in an "InitialLayoutCompleted" DiagramEvent listener. * * Note that depending on the values of #maxScale and #minScale, the actual value for #scale * might be limited. * * The scale will not be increased past the value of #defaultScale, which is normally 1.0, * so as to prevent a single node from appearing to fill up the whole viewport. * * @see #autoScale */ get initialAutoScale(): EnumValue; set initialAutoScale(value: EnumValue); /** * Gets or sets the spot in the viewport that should be coincident with the * #initialDocumentSpot of the document when the document is first initialized. * The default value is Spot.TopLeft. * * If you set this, often you will also want to set #initialDocumentSpot. * If you set #initialPosition, it will take precedence over this property. * * Setting this property and #initialDocumentSpot has the same effect as implementing * an "InitialLayoutCompleted" DiagramEvent listener that calls #alignDocument. * * @see #initialDocumentSpot * @see #initialContentAlignment */ get initialViewportSpot(): Spot; set initialViewportSpot(value: Spot); /** * Gets or sets the spot in the document's area that should be coincident with the * #initialViewportSpot of the viewport when the document is first initialized. * The default value is Spot.TopLeft. * * If you set this, often you will also want to set #initialViewportSpot. * If you set #initialPosition, it will take precedence over this property. * * Setting this property and #initialViewportSpot has the same effect as implementing * an "InitialLayoutCompleted" DiagramEvent listener that calls #alignDocument. * * @see #initialViewportSpot * @see #initialPosition * @see #initialContentAlignment */ get initialDocumentSpot(): Spot; set initialDocumentSpot(value: Spot); /** * Gets or sets the smallest value greater than zero that #scale may take. * This property is only used to limit the range of new values of #scale. * * The default value is 0.0001. * Values must be larger than zero and not greater than one. * Setting this to a value that is greater than the current #scale * will cause the current diagram scale to be set to this new value. */ get minScale(): number; set minScale(value: number); /** * Gets or sets the largest value that #scale may take. * This property is only used to limit the range of new values of #scale. * * The default value is 100.0. * Values must be no less than one. * Setting this to a value that is less than the current #scale * will cause the current diagram scale to be set to this new value. */ get maxScale(): number; set maxScale(value: number); /** * Gets or sets the zoom point of this Diagram, in viewport coordinates. * This is used by Tool#standardMouseWheel and scale-setting commands to control where to zoom in or out. * * Typical usage is to remember the value of this property and * to set this property to some point within the viewport (between zero and the canvas width and height). * This is commonly accomplished by using the InputEvent#viewPoint of Diagram#lastInput. * Then one changes the #scale somehow, perhaps by executing one of the CommandHandler commands, * or by rotating the mouse wheel, or just by setting the Diagram#scale property. * Finally one restores the original value of this property. * * The default value is Point(NaN, NaN). * Value must be of type Point, in element coordinates, not in document coordinates. * Setting this property does not notify about any changed event. * @since 1.2 */ get zoomPoint(): Point; set zoomPoint(value: Point); /** * Gets or sets the content alignment Spot of this Diagram, to be used in determining * how parts are positioned when the #viewportBounds width or height is larger than the #documentBounds. * * For instance a spot of Spot.Center would ensure that the Diagram's * contents are always centered in the viewport. * * If you want the content to be aligned only initially, use #initialContentAlignment instead. * * The default value is Spot.Default, which causes no automatic scrolling or positioning. * When the value is not Default, any value for #initialContentAlignment or #initialPosition is ignored. * * Setting this property has the same effect as implementing * a "LayoutCompleted" DiagramEvent listener that scrolls the viewport to align the content. * */ get contentAlignment(): Spot; set contentAlignment(value: Spot); /** * Gets or sets the initial content alignment Spot of this Diagram, to be used in determining * how parts are positioned initially relative to the viewport, when the #viewportBounds width or height is larger than the #documentBounds. * * For instance a spot of Spot.Center would ensure that the Diagram's contents are initially centered in the viewport. * * To initially align the document when the documentBounds are larger than the viewport, use #initialDocumentSpot and #initialViewportSpot. * * If you want the content to be constantly aligned with a spot, use #contentAlignment instead. * * The default value is Spot.Default, which causes no automatic scrolling or positioning. * * Setting this property has the same effect as implementing * an "InitialLayoutCompleted" DiagramEvent listener that scrolls the viewport to align the content. * * @see #initialDocumentSpot * @see #initialViewportSpot */ get initialContentAlignment(): Spot; set initialContentAlignment(value: Spot); /** * Gets or sets the Margin that describes the Diagram's padding, * which controls how much extra space in document coordinates there is around the area occupied by the document. * This keeps nodes from butting up against the side of the diagram (unless scrolled). * * The default value is a margin of 5, all around the edge of the document. */ get padding(): MarginLike; set padding(value: MarginLike); /** * This read-only property returns an iterator of all Nodes and Groups in the Diagram. * * This includes both data-bound and unbound nodes, * and both top-level nodes and nodes inside Groups. * All of the simple Parts are accessible via the #parts property. * @see #findTopLevelGroups * @see #findTreeRoots */ get nodes(): Iterator; /** * This read-only property returns an iterator of all Links in the Diagram. * * This includes both data-bound and unbound links, * and both top-level links and links inside Groups. */ get links(): Iterator; /** * This read-only property returns an iterator of all Parts in the Diagram * that are not Nodes or Links or Adornments. * * This includes both data-bound and unbound parts, * and both top-level parts and parts inside Groups. * Use the #nodes or #links properties for getting the * collection of all Nodes or Links in the diagram. */ get parts(): Iterator; /** * Returns an iterator of all Groups that are at top-level, * in other words that are not themselves inside other Groups. * * This is useful for when you want to traverse the diagram's graph by recursing into Groups. * @return {Iterator.} * @since 1.2 */ findTopLevelGroups(): Iterator; /** * Gets or sets the Layout used to position all of the top-level nodes and links in this Diagram. * By default this property is an instance of a simple Layout * that assigns positions to all parts that need it. * The value cannot be null and must not be shared with other Diagrams. */ get layout(): Layout; set layout(value: Layout); /** * Perform all invalid layouts. * If the optional argument is true, * this will perform all of the layouts (Diagram#layout and all Group#layouts), * not just the invalid ones. * * Under normal circumstances you should not need to call this method, * because layouts will be performed automatically after they become invalid. * However you may have disabled automatic layouts by setting Layout#isInitial * and/or Layout#isOngoing to false, or by restricting a Part's Part#layoutConditions. * If that is the case you might call this method * (perhaps due to a user command) to perform the layout at a time of your choosing. * @param {boolean=} invalidateAll If true, this will explicitly set Layout#isValidLayout to false on each Layout in the diagram. */ layoutDiagram(invalidateAll?: boolean): void; /** * Gets or sets whether the Diagram tree structure is defined by * links going from the parent node to their children, or vice-versa. * By default this property is true: links go from the parent node to the child node. */ get isTreePathToChildren(): boolean; set isTreePathToChildren(value: boolean); /** * Returns an iterator of all top-level Nodes that have no tree parents. * * This is useful for when you want to traverse the diagram's graph by starting at the root of each tree, * assuming that the diagram consists of one tree or a forest of trees. * @return {Iterator.} * @since 1.2 */ findTreeRoots(): Iterator; /** * (undocumented) * Gets or sets the conditions under which "child" nodes become not visible. * By default this property is Diagram.TreeParentCollapsed: only the true tree parent node's * Node#isTreeExpanded property controls the visibility of a child node. * * You can set this to Diagram.AllParentsCollapsed, to require all of a node's * "parents" to be collapsed in order for the node to become hidden. * Caution: cycles in the graph structure may cause all of the nodes in the cycle to become hidden. */ get treeCollapsePolicy(): EnumValue; set treeCollapsePolicy(value: EnumValue); /** * Register an event handler that is called when there is a DiagramEvent of a given name. * * See the DiagramEvent documentation for a complete listing of diagram event names and their purposes. * @param {string} name the name is normally capitalized, but this method uses case-insensitive comparison. * @param {function(DiagramEvent)} listener a function that takes a DiagramEvent as its argument. * @return {Diagram} this Diagram * @see #removeDiagramListener */ addDiagramListener(name: DiagramEventName, listener: ((e: DiagramEvent) => void)): this; /** * Unregister a DiagramEvent handler. * * See the documentation for DiagramEvent for a complete listing of diagram event names and their purposes. * @param {string} name the name is normally capitalized, but this method uses case-insensitive comparison. * @param {function(DiagramEvent)} listener a function that takes a DiagramEvent as its argument. * @see #addDiagramListener */ removeDiagramListener(name: DiagramEventName, listener: ((e: DiagramEvent) => void)): void; /** * (undocumented) * Notify any DiagramEvent listeners by calling all event handlers registered by #addDiagramListener. * @param {string} name the name is normally capitalized, but this method uses case-insensitive comparison. * @param {Object=} obj an optional subject of the event. * @param {*=} param an optional parameter describing the change to the subject of the event. * @see #addDiagramListener * @see #removeDiagramListener */ raiseDiagramEvent(name: DiagramEventName, obj?: ObjectData, param?: any): void; /** * (undocumented) */ get avoidanceCellSize(): Size; set avoidanceCellSize(value: Size); /** * (undocumented) */ get avoidanceLimit(): number; set avoidanceLimit(value: number); /** * Gets or sets number of milliseconds between autoscroll events. * The default value is 250. * @since 2.2 */ get autoScrollInterval(): number; set autoScrollInterval(value: number); /** * Gets or sets the Margin that describes the area along the inside edges of the viewport, * in viewport coordinates, where autoscrolling will occur while the mouse (pointer) is held there * during dragging or linking or drag-selecting. * * The default value is a Margin of 16 on all sides. * Increase this value in order to make it easier for the user to autoscroll by having * a larger area in which to hold the mouse (pointer) down during a dragging operation. * * When the mouse (pointer) drag point is within this region on the left or right sides, * the view will automatically scroll horizontally in that direction. * When the point is within the region on the top or bottom, the view will automatically scroll * vertically in that direction. * You can specify a Margin side of zero to disable autoscrolling in a particular direction; * a value of Margin(0,0,0,0) turns off autoscrolling in all four directions. */ get autoScrollRegion(): MarginLike; set autoScrollRegion(value: MarginLike); /** * (undocumented) * Called by DraggingTool and LinkingTool to implement auto-scrolling. * @param {Point} viewPt */ doAutoScroll(viewPt: Point): void; /** * (undocumented) * Stop any ongoing auto-scroll action. */ stopAutoScroll(): void; /** * (undocumented) * @expose * @param {Point} viewPnt in viewport coordinates * @return {Point} in document coordinates */ computeAutoScrollPosition(viewPnt: Point): Point; /** * Create an SVGElement that contains a SVG rendering of the current Diagram. * * By default this method returns a snapshot of the visible diagram, but optional arguments give more options. *

* See the page on Making SVG for usage examples. * See the Minimal SVG Download sample, * which also demonstrates downloading an SVG file without involving a web server. * * See #makeImageData for an explanation of possible options that are shared by both methods. * Additional SVG-specific options for this method: * - **elementFinished:** * A function with two arguments, GraphObject and SVGElement. * As the SVG elements are created representing each graph object, this function is called on them, * allowing you to modify the SVG as it is being built, to assign stylesheets, IDs, etc. Example: * ```js * elementFinished: (graphObject, SVGElement) => { * // set something on every SVG element that represents a GoJS TextBlock * if (graphObject instanceof go.TextBlock) SVGElement.setAttribute(...); * } * ``` * * Note that the resulting SVG DOM is not interactive -- it is a snapshot of this diagram at this time. * * At the current time methods such as Diagram#makeImage, * Diagram#makeImageData and Diagram#makeSvg do not work on Overviews. * * For the rendering to work, the diagram must have an HTML Div element as the #div. * @param {any=} options a JavaScript object detailing optional arguments for SVG creation. * @return {SVGElement} * @see #makeImage */ makeSvg(options?: SvgRendererOptions): SVGElement | null; /** * (undocumented) * Add a renderer to the Diagram. This property is only used when building GoJS from source. * * When building from source, to include SVG rendering functionality for Diagram#makeSvg, * you must add the SVGSurface renderer with the name 'SVG': `myDiagram.addRenderer('SVG', new SVGSurface(myDiagram, document));` * * @param {string} name Name of the renderer * @param {ISurface} surface Rendering class, either SVGSurface or CanvasSurface. */ addRenderer(name: string, surface: ISurface): void; /** * (undocumented) * Start or stop caching Group.findExternalLinksConnected */ cacheGroupExternalLinks(start: boolean): void; /** * * Create an HTMLImageElement that contains a bitmap of the current Diagram. * This method is just a convenience function that creates an image, * sets its source to the returned string of #makeImageData, * and returns a reference to that Image. * * See #makeImageData for a complete explanation of possible options. * * By default this method returns a snapshot of the visible diagram, but optional arguments give more options. * * Note that a returned HTMLImageElement, either returned directly or passed to the callback function, * might not yet have the complete property set to true. * So if you need to draw the image immediately, you should check that property first. * If it is false, add a "load" listener to the HTMLImageElement that does the drawing you want. * * At the current time methods such as Diagram#makeImage, * Diagram#makeImageData and Diagram#makeSvg do not work on Overviews. * * For the rendering to work, the diagram must have an HTML Div element as the #div. * @param {any=} options a JavaScript object detailing optional arguments for image creation, to be passed to #makeImageData. * @return {HTMLImageElement | null} An HTML Image element, or null if a callback is specified, or null if there is no DOM. * @see #makeImageData * @see #makeSvg */ makeImage(options?: ImageRendererOptions): HTMLImageElement | null; /** * Create a bitmap of the current Diagram encoded as a base64 string, or returned as an ImageData object. * This method uses the toDataURL method of the HTMLCanvasElement to create the data URL, * or the getImageData method of the Canvas Context. * Unlike toDataURL, this method will not throw an error if cross-domain images * were drawn on the canvas, instead it will return a data URL of a bitmap with those images omitted. * * A simple example: * ```js * myDiagram.makeImageData({ * scale: 1.5, * size: new go.Size(100,100) * }); * ``` *

* See the page on Making Images for more usage examples. * * Note that a returned HTMLImageElement, either returned directly or passed to the callback function, * might not yet have the complete property set to true. * So if you need to draw the image immediately, you should check that property first. * If it is false, add a "load" listener to the HTMLImageElement that does the drawing you want. * * At the current time methods such as Diagram#makeImage, * Diagram#makeImageData and Diagram#makeSvg do not work on Overviews. * * For the rendering to work, the diagram must have an HTML Div element as the #div. * @param {any=} options a JavaScript object detailing optional arguments for image creation. * Rendering options for both images and SVG: * - **size:** * The size of the created image, as a Size, limited by the **maxSize** property. * If no **scale** or **position** is specified then the diagram will be scaled to fit the given size. * If you set a size, you should also set a **position**. If you are scaling the diagram, you may also want to scale the size. * - **scale:** * The scale of the diagram. If **scale** is specified and **size** is not, the resulting image will be sized to uniformly * fit the space needed for the given scale. * Can be constrained by the **maxSize** property. A scale value of `NaN` will * automatically scale to fit within the maxSize, but may be smaller, with a maximum computed scale of 1. * - **maxSize:** * The maximum size of the created image, as a Size. * The default value is `(Infinity, Infinity)` for SVG and `(2000, 2000)` for images. * This is typically used when **scale** is specified and helps prevent accidental excessive memory usage, * which is especially needed in limited-memory environments. * You cannot use Infinity when providing a maximum size for an image -- consider calling #makeSvg instead. * - **position:** * The position of the diagram, as a Point. * By default this is the position of Diagram#documentBounds with the Diagram#padding removed. * If a specific parts collection is used, by default this is the top-left diagram position of their collective bounds. * If you set a `position`, you should also set a `size`. * - **parts:** * An iterator of GraphObjects, typically Parts, such as one from Diagram#selection or Layer#parts. * If GraphObjects are specified their containing Part will be drawn. By default all Parts are drawn except temporary parts (see **showTemporary**). * - **padding:** * A Margin (or number) to pad the image with. If a size is specified, * the padding will not increase the image size, it will only offset the Diagram contents within the image. * The default value is a padding of `1`. * - **background:** * A valid CSS color to replace the default (transparent) canvas background. Any padding area is also colored. * - **showTemporary:** * A boolean value, defaulting to false, * that determines whether or not temporary objects such as adornments are included in the image. * - **showGrid:** * A boolean value, defaulting to the value of **showTemporary**, * that determines whether or not the Grid Layer (containing Diagram#grid) is included in the image * regardless of the value of **showTemporary**. * This is useful if you want to include the grid but not adornments, or vice versa. * - **document:** * An HTML Document, defaulting to `window.document` (or the root object in other contexts) * This may be useful to set if you intend your Image or SVG to be opened in a new window. * - **callback:** * The function to call when an image is finished creation. * It has one argument, which is of the type specified by the value of the **returnType** or SVG DOM. * If provided, call the callback when finished instead of returning immediately. This can be useful if you need to wait for image assets to load. * This also respects the **callbackTimeout**. * This argument is necessary if the **returnType** is `"blob"`, however a callback can be used with any **returnType**. * See the Minimal Image Blob Download sample for an example usage, * which also demonstrates downloading an image file without involving a web server. * - **callbackTimeout:** * If a **callback** is specified, the additional amount of time in milliseconds a call will wait before completeing. Right now, it will only wait if * image assets in the Diagram are not yet loaded. Default is 300 (milliseconds). * * Additional image-specific arguments (not for SVG): * - **type:** * The optional MIME type of the image. Valid values are typically `"image/png"` and `"image/jpeg"`. * Some browsers allow `"image/webp"`. The default value is `"image/png"`, and unrecognized values will defer to the default. * - **returnType:** * The optional return type of the image data. Valid values are `"ImageData"`, `"Image"`, `"string"`, and `"blob"`. * The `"string"` option returns a base64 string representation of the image. * The `"ImageData"` option returns an `ImageData` object representation of the image. * The `"Image"` option returns an `HTMLImageElement` using `ImageData` as the `HTMLImageElement.src`. * The `"blob"` option requires that the **callback** property is also defined. * The default value is `"string"`, and unrecognized values will return a string. * - **details:** * The optional details to pass to the HTMLCanvasElement's toDataURL function. * If the type is `"image/jpeg"` then this can be a number from `0` to `1`, inclusive, describing the desired jpeg quality. * * @return {ImageData|string|null} An ImageData, or a base64-encoded string describing an image, or an HTMLImageElement, or null if a callback is specified. * @see #makeImage */ makeImageData(options?: ImageRendererOptions): HTMLImageElement | ImageData | string | null; /** * This static function declares that a class (constructor function) derives from another class -- * **_but please note that most classes do not support inheritance_**. * Do not call this function when your class is defined using an ES2015 or TypeScript "class" declaration. * * Because you must not modify the prototypes for the **GoJS** classes, * in order to override methods you need to define a new class that inherits from a predefined class. * You can then modify the prototype of your derived class. * * Typical usage is: * ```js * function BaseClass() { * this._total = 0; * } * * public increment(x) { * this._total += x; * } * * function DerivedClass() { * this._anotherProperty = ""; * } * go.Diagram.inherit(DerivedClass, BaseClass); * * DerivedClass.prototype.someMethod = ...; * ``` * * **_Note that most classes do not support inheritance._** * Currently you can only inherit from Layout, Tool, CommandHandler, and Link or their subclasses. * When you override a method, you must strongly consider calling the base method. * Please read the Introduction page on Extensions for how to override methods and how to call a base method. * * The call to `Diagram.inherit` should be made immediately after defining the subclass constructor function * and before defining any new methods or overriding any base class methods. * You must not call this static function more than once on a derived class, or at all on a class defined using an ES2015 or TypeScript class declaration. * * The need for subclassing is greatly diminished by the presence of a number of properties that have functional values. * Setting such a property to a function will cause that function to be called as if it were * an event handler for that particular object. * Example properties include: GraphObject#click, GraphObject#mouseEnter, Part#layerChanged, * Node#treeExpandedChanged, LinkingBaseTool#linkValidation, CommandHandler#memberValidation, * TextEditingTool#textValidation. * @param {Function} derivedclass * @param {Function} baseclass */ static inherit(derivedclass: Function, baseclass: Function): void; } /** * This is used in dragging methods to remember initial locations, for relative positioning and for cancellation. * You do not typically need to create these unless you are overriding tools. * * CommandHandler#computeEffectiveCollection returns a Map of Parts and DraggingInfo, * which is used as an argument for methods like Diagram#computeMove. * * Diagram#moveParts constructs a Map of Parts and DraggingInfo to record each Part's location offset during moves. * * @unrestricted * @since 2.0 */ export class DraggingInfo { /** * Optionally takes a Point that sets #point. * @param {Point=} pt */ constructor(pt?: Point); /** * Gets or sets the initial location for a dragged object. * This is most commonly the Part.location of the dragged object, or a rounded Part.location if snapping. */ get point(): Point; set point(value: Point); set shifted(value: Point); } /** * New in 2.0, this class contains options for dragging and moving parts. * * This is used by Diagram#moveParts, Diagram#computeMove, and DraggingTool#computeMove. * * Both the Diagram and its DraggingTool have a DraggingOptions instance. * Typically, only the DraggingTool one is used, unless the Diagram has no DraggingTool defined. * * In typical DraggingTool operation you do not need to create or modify a DraggingOptions instance. * Setting properties on the DraggingTool such as DraggingTool#isGridSnapEnabled * sets the value on the DraggingTool#dragOptions instance for you. * * @unrestricted * @see DraggingTool#dragOptions * @since 2.0 */ export class DraggingOptions { /** * Whether or not the dragged parts snap to the Diagram#grid. * By default this property is false. * * In typical DraggingTool operation this is set via DraggingTool#isGridSnapEnabled. */ isGridSnapEnabled: boolean; /** * If dragging with the DraggingTool, whether or not Parts snap to a grid (if applicable) in real-time, * or only at the end of the dragging transaction. * By default this property is true. * * In typical DraggingTool operation this is set via DraggingTool#isGridSnapRealtime. */ isGridSnapRealtime: boolean; /** * Gets or sets the size of the grid cell used when snapping during a drag. * By default this property is the Size(NaN, NaN), which causes this tool to use the Panel#gridCellSize value of the Diagram#grid. * * In typical DraggingTool operation this is set via DraggingTool#gridSnapCellSize. */ gridSnapCellSize: Size; /** * Gets or sets the Spot that specifies what point in the grid cell dragged parts snap to, * if the value of #isGridSnapEnabled is true. By default this property is Spot.TopLeft. * * In typical DraggingTool operation this is set via DraggingTool#gridSnapCellSpot. */ gridSnapCellSpot: Spot; /** * Gets or sets the snapping grid's origin point, in document coordinates, * if the value of #isGridSnapEnabled is true. By default this property is the Point(NaN, NaN). * * In typical DraggingTool operation this is set via DraggingTool#gridSnapOrigin. */ gridSnapOrigin: Point; /** * Gets or sets whether the user can move a single Link, * disconnecting it from connected nodes and possibly connecting it to valid ports. * By default this property is false. * * In typical DraggingTool operation this is set via DraggingTool#dragsLink. */ dragsLink: boolean; /** * Gets or sets whether moving or copying a node also includes all of the * node's tree children and their descendants, along with the links to those additional nodes. * By default this property is false. * * In typical DraggingTool operation this is set via DraggingTool#dragsTree. */ dragsTree: boolean; /** * Determines whether or not Groups will snap their member Parts in addition to themselves when moving. * By default this property is false. */ groupsSnapMembers: boolean; /** * Determines whether or not Groups will ensure their member Parts always move, * even if those member parts have Part#copyable and Part#movable set to false. * By default this property is true. */ groupsAlwaysMove: boolean; /** * Determines whether dragging a Group also drags its member Parts if there is no Group.placeholder. * By default this property is true. */ dragsMembers: boolean; constructor(); } /** * Used for the options arguments to Diagram.makeImage, Diagram.makeImageData, and Diagram.makeSvg. */ export interface DiagramRendererOptions { size?: Size; scale?: number; maxSize?: Size; position?: Point; parts?: Iterable; padding?: MarginLike; background?: BrushLike; showTemporary?: boolean; showGrid?: boolean; document?: HTMLDocument; } /** * Used for the options argument to Diagram.makeSvg. */ export interface SvgRendererOptions extends DiagramRendererOptions { elementFinished?: ((graphobj: GraphObject, svgelt: SVGElement) => void) | null; } /** * Used for the options argument to Diagram.makeImage and Diagram.makeImageData. */ export interface ImageRendererOptions extends DiagramRendererOptions { type?: string; returnType?: string; callback?: ((result: any) => void) | null; callbackTimeout?: number; details?: ObjectData; } /** * Palette extends the Diagram class to allow objects to be dragged and placed onto other Diagrams. * Its Diagram#layout is a GridLayout. * The Palette is Diagram#isReadOnly but to support drag-and-drop its Diagram#allowDragOut is true. *

* For more discussion, see Introduction to Palettes. * See samples that make use of Palettes in the samples index. * * You can control the order of Parts in the palette in several manners: * - If you want to keep the order given by `myPalette.model.nodeDataArray`, * just set `myPalette.layout.sorting = go.GridLayout.Forward` (GridLayout#sorting). * - If you want to sort based on some text string associated with each Part, just bind Part#text. * - If you want to sort more generally, set `myPalette.layout.comparer` (GridLayout#comparer). * @extends Diagram * @unrestricted */ export class Palette extends Diagram { /** * @param {Element|string=} div A reference to a DIV HTML element or its ID as a string. * If no DIV is supplied, a Palette will be created in memory. The Palette's Diagram#div property * can then be set later on. * @param {DiagramInitOptions=} init A JavaScript object specifying optional initialization properties object. * Can specify Palette properties, and Palette sub-properties such as `"undoManager.isEnabled": true`, * Example: * ```js * { * allowZoom: false, * "animationManager.isEnabled": false * } * ``` */ constructor(div?: Element | string, init?: Partial); /** * @param {DiagramInitOptions=} init A JavaScript object specifying optional initialization properties object. * Can specify Palette properties, and Palette sub-properties such as `"undoManager.isEnabled": true` * Example: * ```js * { * allowZoom: false, * "animationManager.isEnabled": false * } * ``` */ constructor(init?: Partial); } /** * An Overview is a Diagram that displays all of a different diagram, * with a rectangular box showing the viewport displayed by that other diagram. *

* For more discussion, see Introduction to Overviews. * See samples that make use of Overviews in the samples index. * * All you need to do is set Overview#observed. * For example: * * ```js * var myDiagram = new go.Diagram("myDiagramDIV"); * . . . other initialization . . . * * // create and initialize the Overview: * new go.Overview("myOverviewDIV").observed = myDiagram; * ``` * * The Overview draws what the observed Diagram is displaying, * so setting or modifying any diagram templates or template Maps has no effect. * * Animations are not shown in an Overview. * * At the current time methods such as Diagram#makeImage, * Diagram#makeImageData and Diagram#makeSvg do not work on Overviews. * @extends Diagram * @unrestricted */ export class Overview extends Diagram { /** * @param {Element|string=} div A reference to a DIV HTML element or its ID as a string. * If no DIV is supplied, an Overview will be created in memory. The Overviews's Diagram#div property * can then be set later on. * @param {Partial=} init Optional initialization properties. */ constructor(div?: Element | string, init?: Partial); /** * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * Gets or sets the Diagram for which this Overview is * displaying a model and showing its viewport into that model. * * The value must be null or another Diagram, but may not be an Overview. */ get observed(): Diagram | null; set observed(value: Diagram | null); /** * Gets or sets the rectangular Part that represents the * viewport of the #observed Diagram. * By default the part contains only a magenta Shape. * The box's Part#selectionObject is what is resized by the Overview to the apparent size of the observed diagram's viewport. */ get box(): Part; set box(value: Part); /** * Gets or sets whether this overview draws the temporary layers of the observed Diagram. * The default value is true. * Setting this property to false may improve drawing performance, * especially if the Diagram#grid is visible. * * Setting this property does not notify about any changed event. * @since 1.2 */ get drawsTemporaryLayers(): boolean; set drawsTemporaryLayers(value: boolean); /** * Gets or sets whether this overview draws the Diagram#grid of the observed Diagram, * if it is visible. The default value is true. * * This property is only considered when #drawsTemporaryLayers is true. * Setting this to false may help improve drawing performance. * * Setting this property does not notify about any changed event. * @since 2.2 */ get drawsGrid(): boolean; set drawsGrid(value: boolean); /** * Gets or sets how long it waits before updating, in milliseconds. * The default value is zero. * Any new value must be a non-negative number. * * Setting this property does not notify about any changed event. * @since 2.2 */ get updateDelay(): number; set updateDelay(value: number); } /** * The Diagram#commandHandler implements various * commands such as CommandHandler#deleteSelection or CommandHandler#redo. * The CommandHandler includes keyboard event handling to interpret * key presses as commands. * * CommandHandlers cannot be shared amongst multiple Diagrams. * * You may define a CommandHandler subclass and override methods. * However you must seriously consider calling the base method in order to get its default behavior. * There may be situations where not calling the base method may cause subtle bugs, * but that depends on the method. * Please read the Introduction page on Extensions for how to override methods and how to call a base method. * * There is an example custom CommandHandler in the extensions directory: DrawCommandHandler.js, * which provides alignment commands and additional behaviors for the arrow keys. *

* For additional discussion, please read the Introduction page on Commands. *

Keyboard Shortcuts

* * The CommandHandler implements the following command bindings for keyboard input in #doKeyDown: * - `Ctrl-X` & `Shift-Del` invoke #cutSelection * - `Ctrl-C` & `Ctrl-Insert` invoke #copySelection * - `Ctrl-V` & `Shift-Insert` invoke #pasteSelection * - `Del` & `Backspace` invoke #deleteSelection * - `Ctrl-A` invokes #selectAll * - `Ctrl-Z` & `Alt-Backspace` invoke #undo * - `Ctrl-Y` & `Alt-Shift-Backspace` invoke #redo * - `Up` & `Down` & `Left` & `Right` (arrow keys) call Diagram#scroll * - `PageUp` & `PageDown` call Diagram#scroll * - `Home` & `End` call Diagram#scroll * - `Space` invokes #scrollToPart * - `Ctrl-- & Keypad--` (minus) invoke #decreaseZoom * - `Ctrl-+ & Keypad-+` (plus) invoke #increaseZoom * - `Ctrl-0` invokes #resetZoom * - `Shift-Z` invokes #zoomToFit; repeat to return to the original scale and position * - `Ctrl-G` invokes #groupSelection * - `Ctrl-Shift-G` invokes #ungroupSelection * - `F2` invokes #editTextBlock * - `Menu Key` invokes #showContextMenu * - `Esc` invokes #stopCommand * * On a Macintosh the Command key is used as the modifier instead of the Control key. * * On touch devices there is a default context menu that shows many commonly-used commands * when you hold a finger down on the diagram. * @unrestricted */ export class CommandHandler { /** * The constructor produces a CommandHandler with the default key bindings. */ constructor(); /** * This read-only property returns the Diagram that is using this CommandHandler, * after Diagram#commandHandler has been set to this object. */ get diagram(): Diagram; /** * This is called by tools to handle keyboard commands. * For most commands, this calls the "can..." predicate; if that returns true it calls the command method. * If GoJS handles a key-down event as a keyboard command, the underlying event will not bubble. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * * There is an example custom CommandHandler in the extensions directory: DrawCommandHandler.js, * which implements additional behaviors for the arrow keys by overriding this method. * For additional discussion, please read the Introduction page on Commands. * @expose */ doKeyDown(): void; /** * This is called by tools to handle keyboard commands. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ doKeyUp(): void; /** * This command cancels the operation of the current tool. * This is typically called when the user presses ESCAPE. * * If the current tool is a ToolManager, this clears the diagram's selection. * This then calls Tool#doCancel on the current tool. * @expose * @see #canStopCommand */ stopCommand(): void; /** * This predicate controls whether the user may stop the current tool. * This just returns true. * * This method may be overridden, but probably should not be overridden. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} true. * @see #stopCommand */ canStopCommand(): boolean; /** * This command selects all of the selectable Parts in the diagram by setting Part#isSelected to true on each one. * This is normally invoked by the `Ctrl-A` keyboard shortcut. * * This method raises the "ChangingSelection" and "ChangedSelection" diagram events. * This ignores all parts in temporary layers. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @see #canSelectAll */ selectAll(): void; /** * This predicate controls whether or not the user can invoke the #selectAll command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} This returns true if Diagram#allowSelect is true. * @see #selectAll */ canSelectAll(): boolean; /** * This command deletes the currently selected parts from the diagram. * This is normally invoked by the `Del` keyboard shortcut. * * This will first start a "Delete" transaction, then * raise the "SelectionDeleting" DiagramEvent, * call Diagram#removeParts on a perhaps extended collection of selected Parts, * raise the "SelectionDeleted" diagram event, * and finally commit the transaction. * * Because this command changes the selection, * this method also raises the "ChangingSelection" and "ChangedSelection" diagram events. * Changes are performed within a transaction, but the selection events are raised outside the transaction. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @see #canDeleteSelection */ deleteSelection(): void; /** * This predicate controls whether or not the user can invoke the #deleteSelection command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} This returns true: * if the diagram is not Diagram#isReadOnly, * if Diagram#allowDelete is true, and * if there are some selected Parts. * @see #deleteSelection */ canDeleteSelection(): boolean; /** * This command copies the currently selected parts, Diagram#selection, from the Diagram into the clipboard. * This is normally invoked by the `Ctrl-C` keyboard shortcut. * * This makes a copy of the current selection by calling #copyToClipboard. * This also raises the "ClipboardChanged" diagram event. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @see #canCopySelection */ copySelection(): void; /** * This predicate controls whether or not the user can invoke the #copySelection command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} * This returns true: * if Diagram#allowCopy is true, * if Diagram#allowClipboard is true, and * if there are some selected Parts. * @see #copySelection */ canCopySelection(): boolean; /** * This command executes a #copySelection followed by a #deleteSelection. * This is normally invoked by the `Ctrl-X` keyboard shortcut. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @see #canCutSelection */ cutSelection(): void; /** * This predicate controls whether or not the user can invoke the #cutSelection command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} * This returns true: * if the diagram is not Diagram#isReadOnly, * if Diagram#allowCopy is true, * if Diagram#allowDelete is true, * if Diagram#allowClipboard is true, and * if there are some selected Parts. * @see #cutSelection */ canCutSelection(): boolean; /** * Make a copy of the given collection of Parts * and stores it in a static variable acting as the clipboard. * * The clipboard is initially null. * It can hold a collection of copied Parts. * It also remembers the Model#dataFormat of the diagram * from which the parts were copied. * * This calls Diagram#copyParts in order to make a copy of the Parts for the clipboard. * The values of #copiesParentKey and #copiesGroupKey affect whether * a copied node data remembers its tree parent node (if in a TreeModel) or * its containing group (if in a GraphLinksModel). * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Iterable.} coll A collection of Parts. * If the value is null, the clipboard is cleared of all data. * @see #pasteFromClipboard */ copyToClipboard(coll: Iterable | null): void; /** * If the clipboard holds a collection of Parts, * and if the Model#dataFormat matches that stored in the clipboard, * this makes a copy of the clipboard's parts and adds the copies to this Diagram. * * This calls Diagram#copyParts in order to make a copy of the Parts in the clipboard and add them to this diagram. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {Set.} a collection of the newly pasted Parts, * or an empty Set if there was no data in the clipboard. * @see #copyToClipboard */ pasteFromClipboard(): Set; /** * This command copies the contents of the clipboard into this diagram and makes those new parts the new selection. * This is normally invoked by the `Ctrl-V` keyboard shortcut. * * This calls #pasteFromClipboard to add copies of Parts * into this diagram, and then selects all of the newly created parts. * This also raises the "ClipboardPasted" diagram event. * This method raises the "ChangingSelection" and "ChangedSelection" diagram events. * Changes are performed in a transaction, but the selection events are raised outside the transaction. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Point=} pos Point at which to center the newly pasted parts; if not present the parts are not moved. * @see #canPasteSelection */ pasteSelection(pos?: Point): void; /** * This predicate controls whether or not the user can invoke the #pasteSelection command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Point=} pos Point at which to center the newly pasted parts; if not present the parts would not be moved. * @return {boolean} * This returns true: * if the diagram is not Diagram#isReadOnly, * if Diagram#allowInsert is true, * if Diagram#allowClipboard is true, and * if the clipboard has parts in it. * @see #pasteSelection */ canPasteSelection(pos?: Point): boolean; /** * This command calls UndoManager#undo. * This is normally invoked by the `Ctrl-Z` keyboard shortcut. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @see #canUndo */ undo(): void; /** * This predicate controls whether or not the user can invoke the #undo command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} * This returns true: * if the diagram is not Diagram#isReadOnly, * if Diagram#allowUndo is true, and * if the UndoManager#canUndo predicate returns true. * @see #undo */ canUndo(): boolean; /** * This command calls UndoManager#redo. * This is normally invoked by the `Ctrl-Y` keyboard shortcut. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @see #canRedo */ redo(): void; /** * This predicate controls whether or not the user can invoke the #redo command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} * This returns true: * if the diagram is not Diagram#isReadOnly, * if Diagram#allowUndo is true, and * if the UndoManager#canRedo predicate returns true. * @see #redo */ canRedo(): boolean; /** * This command decreases the Diagram#scale by a given factor. * This is normally invoked by the `Ctrl--` and `Keypad--` keyboard shortcuts. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {number=} factor This defaults to 1/#zoomFactor. The value should be less than one and greater than zero. * @see #canDecreaseZoom */ decreaseZoom(factor?: number): void; /** * This predicate controls whether or not the user can invoke the #decreaseZoom command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {number=} factor This defaults to 1/#zoomFactor. The value should be less than one and greater than zero. * @return {boolean} * This returns true if Diagram#allowZoom is true * and if the new scale is within the range of Diagram#minScale and Diagram#maxScale. * @see #decreaseZoom */ canDecreaseZoom(factor?: number): boolean; /** * This command increases the Diagram#scale by a given factor. * This is normally invoked by the `Ctrl-+` and `Keypad-+` keyboard shortcuts. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {number=} factor This defaults to #zoomFactor. The value should be greater than one. * @see #canIncreaseZoom */ increaseZoom(factor?: number): void; /** * This predicate controls whether or not the user can invoke the #increaseZoom command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {number=} factor This defaults to #zoomFactor. The value should be greater than one. * @return {boolean} * This returns true if Diagram#allowZoom is true * and if the new scale is within the range of Diagram#minScale and Diagram#maxScale. * @see #increaseZoom */ canIncreaseZoom(factor?: number): boolean; /** * This command sets the Diagram#scale to a new scale value, by default 1. * This is normally invoked by the `Ctrl-0` keyboard shortcut. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {number=} newscale This defaults to Diagram#defaultScale, which is normally 1.0. The value should be greater than zero. * @see #canResetZoom */ resetZoom(newscale?: number): void; /** * This predicate controls whether or not the user can invoke the #resetZoom command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {number=} newscale This defaults to Diagram#defaultScale, which is normally 1.0. The value should be greater than zero. * @return {boolean} * This returns true if Diagram#allowZoom is true. * and if the new scale is within the range of Diagram#minScale and Diagram#maxScale. * @see #resetZoom */ canResetZoom(newscale?: number): boolean; /** * This command changes the Diagram#scale so that the Diagram#documentBounds fits within the viewport. * If this command had been called before without any other zooming since then, * the original Diagram scale and position are restored. * This is normally invoked by the `Shift-Z` keyboard shortcut. * If you do not want the behavior where this command might restore the original diagram scale and position on a subsequent call, * set #isZoomToFitRestoreEnabled to false. * * As of 2.1, this animates zooming by default. Diagram#zoomToFit does not animate. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @see #canZoomToFit * @see #isZoomToFitRestoreEnabled * @see Diagram#zoomToFit * @since 1.1 */ zoomToFit(): void; /** * This predicate controls whether or not the user can invoke the #zoomToFit command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} * This returns true if Diagram#allowZoom is true. * @see #zoomToFit * @since 1.1 */ canZoomToFit(): boolean; /** * This command scrolls the diagram to make a highlighted or selected Part visible in the viewport. * Call this command repeatedly to cycle through the Diagram#highlighteds collection, * if there are any Parts in that collection, or else in the Diagram#selection collection, * scrolling to each one in turn by calling Diagram#centerRect. * * This method animates to the scrolled part, and Diagram#scrollToRect does not. * * This is normally invoked by the `Space` keyboard shortcut. * If there is no argument and there is no highlighted or selected Part, this command does nothing. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * * @expose * @param {Part=} part This defaults to the first highlighted Part of Diagram#highlighteds, * or, if there are no highlighted Parts, the first selected Part. * @see #canScrollToPart * @see Diagram#scrollToRect * @since 1.6 */ scrollToPart(part?: Part): void; /** * This predicate controls whether or not the user can invoke the #scrollToPart command. * This returns false if there is no argument Part and there are no selected Parts. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Part=} part This defaults to the first selected Part of Diagram#selection * @return {boolean} * This returns true if Diagram#allowHorizontalScroll and Diagram#allowVerticalScroll are true. * @see #scrollToPart * @since 1.6 */ canScrollToPart(part?: Part): boolean; /** * This command collapses all expanded selected Nodes. * This operation is performed within a "Collapse Tree" transaction. * Just before the end of the transaction this raises the "TreeCollapsed" DiagramEvent, * with a collection of collapsed Nodes as the subject. * This currently has no default keyboard shortcut. * * This calls Node#collapseTree to perform the collapse, which will set Node#isTreeExpanded to false. * You may want to save the collapsed/expanded state to the model by using a TwoWay Binding on the "isTreeExpanded" property of your Nodes, * and perhaps also on the Node#wasTreeExpanded property. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Node=} node if supplied, ignore the selection and collapse this particular Node subtree. * @see #canCollapseTree */ collapseTree(node?: Node): void; /** * This predicate controls whether the user can collapse expanded subtrees of Nodes. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Node=} node if supplied, ignore the selection and consider collapsing this particular Node. * @return {boolean} * @see #collapseTree */ canCollapseTree(node?: Node): boolean; /** * This command expands all collapsed selected Nodes. * This operation is performed within an "Expand Tree" transaction. * Just before the end of the transaction this raises the "TreeExpanded" DiagramEvent, * with a collection of expanded Nodes as the subject. * This currently has no default keyboard shortcut. * * This calls Node#expandTree to perform the expand, which will set Node#isTreeExpanded to true. * You may want to save the collapsed/expanded state to the model by using a TwoWay Binding on the "isTreeExpanded" property of your Nodes, * and perhaps also on the Node#wasTreeExpanded property. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Node=} node if supplied, ignore the selection and collapse this particular Node subtree. * @see #canExpandTree */ expandTree(node?: Node): void; /** * This predicate controls whether the user can expand collapsed subtrees of Nodes. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Node=} node if supplied, ignore the selection and consider expanding this particular Node. * @return {boolean} * @see #expandTree */ canExpandTree(node?: Node): boolean; /** * This command adds a copy of #archetypeGroupData to the diagram's model * to create a new Group and then adds the selected Parts to that new group. * This is normally invoked by the `Ctrl-G` keyboard shortcut. * * This creates a new Group by adding a copy of the #archetypeGroupData to the model. * Each of the selected parts for which Part#canGroup is true * and for which #isValidMember is true * is made a member of that new group. * If all of the selected groupable parts were members of a pre-existing group, * the new group also becomes a member of that pre-existing group, * if #isValidMember is true for that existing group with the new group. * The new group becomes the only selected part. * This raises the "SelectionGrouped" diagram event. * This method also raises the "ChangingSelection" and "ChangedSelection" diagram events. * Changes are performed in a "Group" transaction, but the selection events are raised outside the transaction. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @see #canGroupSelection */ groupSelection(): void; /** * This predicate controls whether or not the user can invoke the #groupSelection command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} * This returns true: * if the #archetypeGroupData is not null, * if the diagram is not Diagram#isReadOnly, * if Diagram#allowInsert is true, * if Diagram#allowGroup is true, * if Diagram#model is a GraphLinksModel, and * if there is any selected Part that can be Part#canGrouped. * @see #groupSelection */ canGroupSelection(): boolean; /** * This predicate is called to determine whether a Node may be added as a member of a Group. * This always checks to make sure no group might become a member of itself, either directly or indirectly. * If the Group has a Group#memberValidation predicate and if it returns false, this method returns false. * If this CommandHandler has a #memberValidation predicate and if it returns false, this method returns false. * Otherwise this will return true. *

* For a more general discussion of validation, see Introduction to Validation. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Group} group this may be null if the node is being added as a top-level node. * @param {Part} part a Part, usually a Node, possibly another Group, but not a Link or an Adornment. * @return {boolean} true if OK to add the node to the group. */ isValidMember(group: Group, part: Part): boolean; /** * This command removes selected groups from the diagram without removing their members from the diagram. * This is normally invoked by the `Ctrl-Shift-G` keyboard shortcut. * * For the given group, or if not supplied, each selected Group that is Group#ungroupable, * expand the subgraph and change all of its member parts to be members of the group that the selected group node is in. * (If the selected group is a top-level node, i.e. not a member of any group node, its members become top-level parts too.) * All of those selected groups are deleted. * All of the reparented member parts are selected. * * This raises the "SelectionUngrouped" diagram event. * This method also raises the "ChangingSelection" and "ChangedSelection" diagram events. * Changes are performed in an "Ungroup" transaction, but the selection events are raised outside the transaction. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Group=} group if supplied, ignore the selection and consider ungrouping this particular Group. * @see #canUngroupSelection */ ungroupSelection(group?: Group): void; /** * This predicate controls whether or not the user can invoke the #ungroupSelection command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Group=} group if supplied, ignore the selection and consider ungrouping this particular Group. * @return {boolean} * This returns true: * if the diagram is not Diagram#isReadOnly, * if Diagram#allowDelete is true, * if Diagram#allowUngroup is true, * if Diagram#model is a GraphLinksModel, and * if there are any selected Groups that are Group#ungroupable. * @see #ungroupSelection */ canUngroupSelection(group?: Group): boolean; /** * Make sure all of the unnested Parts in the given collection * are removed from any containing Groups. * * This sets Part#containingGroup to null on each Part that is * not a member of another Part in the argument collection. * If the check argument to this method is supplied and true, * this will call #isValidMember on each part, passing null as the first argument. * * This functionality is similar to #ungroupSelection, * except that this is not a command (there is no transaction and this does not raise a DiagramEvent) * and the parts are necessarily becoming top-level parts * (whereas ungrouping would add them to the Group containing the Group being ungrouped). * * This function is typically called in a Diagram#mouseDrop event handler * in order to remove the selected Parts from whatever Group they had been in. * * If you want to add Parts to be members of a Group, call Group#addMembers. * If you want to remove Parts completely from a Diagram, call Diagram#removeParts. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Iterable.} coll a collection of Parts. * @param {boolean=} check whether to call #isValidMember to confirm that changing the Part to be a top-level Part is valid. * @return {boolean} true if all non-Links were changed to be top-level Parts in this Diagram; false if some Parts or Nodes were not able to be added. */ addTopLevelParts(coll: Iterable, check?: boolean): boolean; /** * This command collapses all expanded selected Groups. * This operation is performed within a "Collapse SubGraph" transaction. * Just before the end of the transaction this raises the "SubGraphCollapsed" DiagramEvent, * with a collection of collapsed Groups as the subject. * This currently has no default keyboard shortcut. * * This calls Group#collapseSubGraph to perform the collapse, which will set Group#isSubGraphExpanded to false. * You may want to save the collapsed/expanded state to the model by using a TwoWay Binding on the "isSubGraphExpanded" property of your Groups, * and perhaps also on the Group#wasSubGraphExpanded property. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Group=} group if supplied, ignore the selection and collapse this particular Group. * @see #canCollapseSubGraph */ collapseSubGraph(group?: Group): void; /** * This predicate controls whether the user can collapse expanded Groups. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Group=} group if supplied, ignore the selection and consider collapsing this particular Group. * @return {boolean} * @see #collapseSubGraph */ canCollapseSubGraph(group?: Group): boolean; /** * This command expands all collapsed selected Groups. * This operation is performed within an "Expand SubGraph" transaction. * Just before the end of the transaction this raises the "SubGraphExpanded" DiagramEvent, * with a collection of expanded Groups as the subject. * This currently has no default keyboard shortcut. * * This calls Group#expandSubGraph to perform the collapse, which will set Group#isSubGraphExpanded to true. * You may want to save the collapsed/expanded state to the model by using a TwoWay Binding on the "isSubGraphExpanded" property of your Groups, * and perhaps also on the Group#wasSubGraphExpanded property. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Group=} group if supplied, ignore the selection and expand this particular Group. * @see #canExpandSubGraph */ expandSubGraph(group?: Group): void; /** * This predicate controls whether the user can expand collapsed Groups. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Group=} group if supplied, ignore the selection and consider expanding this particular Group. * @return {boolean} * @see #expandSubGraph */ canExpandSubGraph(group?: Group): boolean; /** * This command starts in-place editing of a TextBlock in the selected Part. * This is normally invoked by the `F2` keyboard shortcut. * * This starts the TextEditingTool to have the user enter or modify the text string and finally set the TextBlock#text. * You may want to save the new string to the model by using a TwoWay Binding on the "text" property of your TextBlock. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {TextBlock=} textblock the TextBlock to start editing. * @see #canEditTextBlock */ editTextBlock(textblock?: TextBlock): void; /** * This predicate controls whether or not the user can invoke the #editTextBlock command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {TextBlock=} textblock the TextBlock to consider editing. * @return {boolean} * This returns true: * if the diagram is not Diagram#isReadOnly, * if Diagram#allowTextEdit is true, * if there is a ToolManager#textEditingTool, and * if there is any selected Part for which Part#canEdit is true. * @see #editTextBlock */ canEditTextBlock(textblock?: TextBlock): boolean; /** * This command opens the context menu for a selected Part or given GraphObject, or else for the whole Diagram. * This is normally invoked by the `Menu` keyboard shortcut. * * The given GraphObject must have a GraphObject#contextMenu * defined in order to show anything. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {GraphObject|Diagram=} obj a GraphObject or Diagram with a contextMenu defined. * If none is given, this method will use the first selected object, or else the Diagram. * The method will simulate a right-button click at the middle of the GraphObject or, * if a Diagram, at the current mouse position if it is in the viewport. * @see #canShowContextMenu */ showContextMenu(obj?: GraphObject | Diagram): void; /** * This predicate controls whether or not the user can invoke the #showContextMenu command. * * This method may be overridden, but you should consider calling this base method in order to get all of its functionality. * This method must not have any side-effects. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {GraphObject|Diagram=} obj a GraphObject or Diagram with a contextMenu defined. * If none is given, this method will use the first selected object, or else the Diagram. * @return {boolean} * @see #showContextMenu */ canShowContextMenu(obj?: GraphObject | Diagram): boolean; set copiesClipboardData(value: boolean); /** * Gets or sets whether #copySelection should also copy Links that connect with selected Nodes. * The default value is true. * Setting this property does not raise any events. * * The DraggingTool#copiesEffectiveCollection property serves a similar role for the DraggingTool * when the user holds down the control key to modify the drag into a copy operation. * @since 1.5 */ get copiesConnectedLinks(): boolean; set copiesConnectedLinks(value: boolean); /** * Gets or sets whether #deleteSelection should also delete links that are connected to nodes that are deleted. * The default value is true. * Setting this property does not raise any events. * @since 1.6 */ get deletesConnectedLinks(): boolean; set deletesConnectedLinks(value: boolean); /** * Gets or sets whether #copySelection should also copy subtrees. * The default value is false. * Setting this property does not raise any events. * * The DraggingTool#dragsTree property serves a similar role for the DraggingTool * for both moving and copying operations. */ get copiesTree(): boolean; set copiesTree(value: boolean); /** * Gets or sets whether #deleteSelection should also delete subtrees. * The default value is false. * Setting this property does not raise any events. */ get deletesTree(): boolean; set deletesTree(value: boolean); /** * Gets or sets whether #copySelection and #copyToClipboard copy the node data property * whose value is the tree-parent node data's key. * * Set this property to true if you want a copy/paste of a node to automatically have the new node be a tree-child of the original tree-parent node. * Caution: this only has an effect if the Diagram's Diagram#model is a TreeModel. * * The default value is false. * @since 1.3 */ get copiesParentKey(): boolean; set copiesParentKey(value: boolean); /** * Gets or sets whether #copySelection and #copyToClipboard copy the node data property * whose value is the containing group data's key. * * Set this property to true if you want a copy/paste of a node to automatically have the new node be a member of the original group. * Caution: this only has an effect if the Diagram's Diagram#model is a GraphLinksModel. * * The default value is false. * @since 1.3 */ get copiesGroupKey(): boolean; set copiesGroupKey(value: boolean); /** * Gets or sets a data object that is copied by #groupSelection * when creating a new Group. * * The default value is null. * If you set this to an Object, be sure that GraphLinksModel#isGroupForNodeData is true for that object. * Setting this property does not raise any events. */ get archetypeGroupData(): ObjectData; set archetypeGroupData(value: ObjectData); /** * Gets or sets the predicate that determines whether or not a node may become a member of a group. * This predicate is called in addition to any existing group's Group#memberValidation predicate. * The default predicate is null, which is equivalent to simply returning true. * The predicate may be called passing null as the first argument (the Group) -- * this asks whether it is OK to make the second argument (the Part, but not a Link) a top-level Part of the diagram. *

* For a more general discussion of validation, see Introduction to Validation. * * The function, if supplied, must not have any side-effects. */ get memberValidation(): ((aGroup: Group, somePart: Part) => boolean) | null; set memberValidation(value: ((aGroup: Group, somePart: Part) => boolean) | null); /** * (undocumented) * Deprecated in favor of Diagram#defaultScale. */ get defaultScale(): number; set defaultScale(value: number); /** * Gets or sets the amount by which #decreaseZoom and #increaseZoom change * the Diagram#scale. * * The default value is 1.05 (5%). * The value must be a number larger than 1.0. * Setting this property does not raise any events. * @since 1.1 */ get zoomFactor(): number; set zoomFactor(value: number); /** * Gets or sets whether the #zoomToFit command ever restores the previous * Diagram scale and position. * When this property is false, this command always calls Diagram#zoomToFit. * * The default value is true. * Setting this property does not raise any events. * @since 2.2 */ get isZoomToFitRestoreEnabled(): boolean; set isZoomToFitRestoreEnabled(value: boolean); set scrollToPartPause(value: number); /** * Find the actual collection of nodes and links to be moved or copied, * given an initial collection. * This includes links that connected at both ends to nodes being moved or copied, * members of Groups, and if DraggingTool#dragsTree is true, * this includes nodes and links that are "tree" descendants from selected nodes. * * Note that this does not return a simple collection of Parts, * but a Map associating a chosen Part * with an Object holding its original location Points as the value of the "point" property. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * * This was moved to CommandHandler from DraggingTool in 2.0. * @expose * @param {Iterable.} parts A Set or List of Parts. * @param {DraggingOptions=} options Potential options for the collection computation. If not specified, this uses the DraggingTool's drag options. * @return {Map.} a Map mapping Parts to DraggingInfo Objects * that have a "point" property remembering the original location of that Part. * @since 2.0 */ computeEffectiveCollection(parts: Iterable, options?: DraggingOptions): Map; } /** * A type that describes a constructor. Used in the declaration of GraphObject.make. */ export type ConstructorType) => InstanceType> = new (...args: Array) => InstanceType; /** * A type that declares which types may be passed as arguments, depending on the type of instance being built. * Used in the declaration of GraphObject.make. */ export type MakeAllow, C, E> = (InstanceType extends C ? E : never); /** * This is the abstract base class for all graphical objects. * Classes inheriting from GraphObject include: * Shape, TextBlock, Picture, and Panel. * From the Panel class the Part class is derived, from which the * Node and Link classes derive. * * It is very common to make use of the static function GraphObject.make in order to build up * a visual tree of GraphObjects. You can see many examples of this throughout the * Introduction, starting at Building Objects, * and the Samples, starting with Minimal Sample. * * Since GraphObject is an abstract class, programmers do not create GraphObjects themselves, * but this class defines many properties used by all kinds of GraphObjects. * * The only visual property on GraphObject is #background. * However one can control whether the GraphObject is drawn at all by setting #visible, * or by setting #opacity to zero if you still want the GraphObject to occupy space. * Call the #isVisibleObject predicate to determine whether the object is visible and * all of its containing panels are visible. * Also, if you want to control whether any mouse or touch events "see" the GraphObject, * you can set #pickable to false. * * For more information about specifying how things get drawn, see the properties on the * Shape, TextBlock, and Picture classes. *

GraphObject Sizing

* * GraphObject defines most of the properties that cause objects to size themselves differently. * The most prominent ones include: * - The #desiredSize, #minSize, and #maxSize properties are used to * explicitly set or limit the size of visual elements. #width and #height are * convenience properties that set the #desiredSize width and height, respectively. * - The #angle and #scale properties are used to transform visual elements. * - The #stretch property determines how a GraphObject will fill its visual space, * contextually granted to it by its containing Panel. Top-level (Part) * GraphObjects are not affected by this property because they are always granted infinite space. * * All GraphObjects in a Diagram are measured and then arranged by their containing Panels in a tree-like fashion. * After measuring and arranging, a GraphObject will have valid values for the read-only * properties #naturalBounds, #measuredBounds, and #actualBounds. * * - The #naturalBounds of a GraphObject describe its local size, * without any transformations (#scale, #angle) affecting it. * - The #measuredBounds of a GraphObject describe its size within its containing Panel. * - The #actualBounds of a GraphObject describe its position and given size inside of its panel. * This size may be smaller than #measuredBounds, for instance if a GraphObject with a large #desiredSize * is placed in a Panel of a smaller #desiredSize. Smaller #actualBounds than #measuredBounds * typically means an object will be cropped. * *

* See the Introduction page on sizing * for usage information and examples. *

GraphObject Size and Position within Panel

* Several GraphObject properties guide the containing Panel for how to size and position the object within the panel. * * - The #alignment specifies where the object should be relative to some area of the panel. * For example, an alignment value of Spot.BottomRight means that the GraphObject should be at the bottom-right corner of the panel. * - The #alignmentFocus specifies precisely which point of the GraphObject should be aligned at the #alignment spot. * - The #column and #row properties are only used by Panel.Table panels, to indicate where the GraphObject should be. * - The #columnSpan and #rowSpan properties tell the Panel.Table panel how large the GraphObject should be. * - The #isPanelMain property indicates to some kinds of Panels that the GraphObject is the "primary" object * that other panel children should be measured with or positioned in. * - The #margin property tells the containing Panel how much extra space to put around this GraphObject. * - The #position property is used to determine the relative position of GraphObjects when they are elements of a Panel.Position panel. * *

* See the Introduction page on Panels * and Table Panels for an overview of the capabilities. *

Top-level GraphObjects are Parts

* * A Part is a derived class of GraphObject representing a top-level object. * All top-level GraphObjects must be Parts, and Node, Link, Group, and Adornment derive from Part. * The position of a Part determines the point of the Part's top-left corner in document coordinates. * See also Part#location, which supports an way to specify the position based on a different * spot of a different element within the Part. * * There are several read-only properties that help navigate up the visual tree. * - #panel returns the Panel that directly contains this GraphObject * - #part returns the Part that this GraphObject is in, perhaps via intervening Panels; * this is frequently used in order to get to the model data, Panel#data * - #layer returns the Layer that this GraphObject's Part is in * - #diagram returns the Diagram that this GraphObject's Part's Layer is in * *

* See the Visual Tree sample * for a diagram displaying the visual tree of a simple diagram. *

User Interaction

* * GraphObjects have several properties enabling dynamic customizable interaction. * There are several definable functions that execute on input events: #mouseDragEnter, * #mouseDragLeave, #mouseDrop, #mouseEnter, #mouseHold, * #mouseHover, #mouseLeave, and #mouseOver. * For example, you could define mouse enter-and-leave event handlers to modify the appearance of a link * as the mouse passes over it: * ```js * myDiagram.linkTemplate = * $(go.Link, * $(go.Shape, * { strokeWidth: 2, stroke: "gray" }, // default color is "gray" * { // here E is the InputEvent and OBJ is this Shape * mouseEnter: (e, obj) => { obj.strokeWidth = 4; obj.stroke = "dodgerblue"; }, * mouseLeave: (e, obj) => { obj.strokeWidth = 2; obj.stroke = "gray"; } * })); * ``` * * There are #click, #doubleClick, and #contextClick functions * that execute when a user appropriately clicks the GraphObject. * These click functions are called with the InputEvent as the first argument * and this GraphObject as the second argument. * For example, you could define a click event handler on a Node that goes to another page: * ```js * myDiagram.nodeTemplate = * $(go.Node, "Auto", * $(go.Shape, "RoundedRectangle", * new go.Binding("fill", "color")), * $(go.TextBlock, * { name: "TB", margin: 3 }, * new go.Binding("text", "key")), * { // second arg will be this GraphObject, which in this case is the Node itself: * click: (e, node) => { * window.open("https://en.wikipedia.org/Wiki/" + node.data.key); * } * }); * ``` * * Note: you may prefer defining DiagramEvent listeners on the Diagram * rather than on individual GraphObjects. DiagramEvents also include more general events that * do not necessarily correspond to input events. * * The properties #actionCancel, #actionDown, #actionMove, * and #actionUp define functions to execute when the GraphObject's #isActionable property * is set to true (default false). See the ActionTool for more detail. *

* See the Introduction page on Events for a more general discussion. *

GraphObjects as Ports

* * In GoJS, Links can only connect to elements within a Node * that are specified as "ports", and by default the only port is the Node itself. * Setting the #portId of a GraphObject inside a Node allows that object to act as a port. * Note: the only kind of model that can save which port a link is connected with, i.e. portIds that are not an empty string, * is a GraphLinksModel whose GraphLinksModel#linkFromPortIdProperty and * GraphLinksModel#linkToPortIdProperty have been set to name properties on the link data objects. * * GraphObjects have several properties that are only relevant when they are acting as ports. * These port-related properties are: * - #portId, which must be set to a string that is unique within the Node, * in order for this GraphObject to be treated as a "port", rather than the whole node * - #fromSpot and #toSpot, where a link should connect with this port * - #fromEndSegmentLength and #toEndSegmentLength, the length of the link segment adjacent to this port * - #fromShortLength and #toShortLength, the distance the link should terminate before touching this port * - #fromLinkable and #toLinkable, whether the user may draw links connecting with this port * - #fromLinkableDuplicates and #toLinkableDuplicates, whether the user may draw multiple links between the same pair of ports * - #fromLinkableSelfNode and #toLinkableSelfNode, whether the user may draw a link between ports on the same node * - #fromMaxLinks and #toMaxLinks, to limit the number of links connecting with this port in a particular direction * *

* See the Introduction page on ports * and link routing * and link connection points * for port usage information and examples. *

GraphObjects as labels on a Link

* * GraphObjects can also be used as "labels" on a Link. * In addition to the #alignmentFocus property, these properties direct a Link Panel * to position a "label" at a particular point along the route of the link, in a particular manner: * - #segmentIndex, which segment the label should be on * - #segmentFraction, how far along the segment the label should be * - #segmentOffset, where the label should be positioned relative to the segment * - #segmentOrientation, how the label should be rotated relative to the angle of the segment * *

* See the Introduction page on link labels * for examples of how to make use of labels on Links. *

Interactive Behavior

* * There are several properties that specify fairly high-level interactive behavior: * - #cursor, a CSS string specifying a cursor * - #contextMenu, an Adornment * - #toolTip, an Adornment * *

* For more information, please read the Introduction page about Context Menus * and the page about ToolTips. *

* Also see the Basic sample * for examples of how to show context menus and tooltips. * @unrestricted */ export abstract class GraphObject { /** * This is an abstract class, so you should not use this constructor. */ constructor(); /** * Copies properties from this object to the given object, which must be of the same class. * This is called by #copy. * This method may be overridden. * * For every property that you add to a subclass of a GraphObject-inheriting class, * in this method you should assign its value to the copied object. * For performance reasons you should set all of the same properties to this * that the constructor does, and in the same order. * * For example, let us define a custom Link class and add two properties: * * ```js * function CustomLink() { * go.Link.call(this); * this._someNewProperty = 17; * this._someNewProperty2 = []; // an Array * } * go.Diagram.inherit(CustomLink, go.Link); * * CustomLink.prototype.cloneProtected = function() { * // Always call the base method in an override * // In TypeScript you would use: super.cloneProtected(copy); * go.Link.prototype.cloneProtected.call(this, copy); * // assign every new property to the copy: * copy._someNewProperty = this._someNewProperty; * copy._someNewProperty2 = this._someNewProperty2.slice(0); // make a copy of the Array * } * ``` * * This ensures that copies of GraphObjects and their subclasses are faithful reproductions. * Consider for properties that are references to objects whether the reference should be shared * or whether that object value should be copied as well, resulting in a less shallow copy. * This is demonstrated above by making a copy of the property value that is an Array, * so that modifications to the Array will not be shared by copies of the CustomLink. * Further copies of the Array items might be warranted, depending on their purpose. * * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {GraphObject} copy */ protected cloneProtected(copy: this): void; /** * Creates a deep copy of this GraphObject and returns it. * This method is the same as a clone for simple GraphObjects * such as Shape, TextBlock, and Picture. * For Panel this method copies the visual tree of GraphObjects that it contains. * @expose * @return {GraphObject} */ copy(): this; /** * GraphObjects with this enumeration as the value of GraphObject#stretch * are not automatically scaled to fit in the given bounds; * there may be clipping in one or both directions if the available dimensions are too small. * @constant */ static None: EnumValue; /** * GraphObjects with this enumeration as the value of GraphObject#stretch * are stretched depending on the context they are used. For instance a 'Circle' figure might * be uniformly stretched whereas an 'Ellipse' figure might be non-uniformly stretched. * @constant */ static Default: EnumValue; /** * GraphObjects with this enumeration as the value of GraphObject#stretch * are scaled as much as possible in the y-axis. In another context, can be used as a value of PanelLayout, so type is "any". * @constant */ static Vertical: any; /** * GraphObjects with this enumeration as the value of GraphObject#stretch * are scaled as much as possible in the x-axis. In another context, can be used as a value of PanelLayout, so type is "any". * @constant */ static Horizontal: any; /** * GraphObjects with this enumeration as the value of GraphObject#stretch * are scaled in both directions so as to fit exactly in the given bounds; * there is no clipping but the aspect ratio may change, causing the object to appear stretched. * @constant */ static Fill: EnumValue; /** * Pictures with this enumeration as the value of Picture#imageStretch are drawn with equal * scale in both directions to fit the larger side of the image bounds; * Panels of type Viewbox with this as the value of Panel#viewboxStretch * scale the contained element equally in both directions to fit the larger side * of the element's bounds in the given bounds. * @constant */ static Uniform: EnumValue; /** * Pictures with this enumeration as the value of Picture#imageStretch are drawn with equal * scale in both directions to fit the arranged (actual) bounds; * Panels of type Viewbox with this as the value of Panel#viewboxStretch * scale the contained element equally in both directions to fit the smaller side * of the element's bounds in the given bounds. * There may be clipping in one dimension. * @constant */ static UniformToFill: EnumValue; /** * GraphObjects with this enumeration as the value of Picture#flip or TextBlock#flip * are drawn upside-down, with Y coordinate points increasing upwards. * @constant * @since 2.0 */ static FlipVertical: EnumValue; /** * GraphObjects with this enumeration as the value of Picture#flip or TextBlock#flip * are drawn mirror-image, with X coordinate points increasing towards the left. * @constant * @since 2.0 */ static FlipHorizontal: EnumValue; /** * GraphObjects with this enumeration as the value of Picture#flip or TextBlock#flip * are drawn with both X and Y coordinates reversed. * @constant * @since 2.0 */ static FlipBoth: EnumValue; /** * Returns the Point in document coordinates for a given Spot in this object's bounds * or for a Point in local coordinates. * * For example, for an instance of a Node like this: * ```js * myDiagram.nodeTemplate = * $(go.Node, "Auto", * $(go.Shape, "RoundedRectangle", * new go.Binding("fill", "color")), * $(go.TextBlock, * { name: "TB", margin: 3 }, * new go.Binding("text", "key"))); * ``` * where the Node is positioned at `100, 200`, * ```js * node.findObject("TB").getDocumentPoint(go.Spot.Center) * ``` * could return a Point that is approximately at `122, 213`. * @param {Spot|Point} local a real Spot describing a relative location in or near this GraphObject, or a real Point in local coordinates. * @param {Point=} result an optional Point that is modified and returned. * @return {Point} in document coordinates. * @see #getDocumentBounds * @see #getLocalPoint */ getDocumentPoint(local: Spot | Point, result?: Point): Point; /** * Returns the Rect in document coordinates for this object's bounds. * If this GraphObject is a Part, the rect will be identical to its #actualBounds. * @param {Rect=} result an optional Rect that is modified and returned. * @return {Rect} in document coordinates. * @see #getDocumentPoint * @since 2.0 */ getDocumentBounds(result?: Rect): Rect; /** * Returns the effective angle that the object is drawn at, in document coordinates, normalized to between 0 and 360. * * Basically this adds together all of the rotation declared by this #angle and the angles of all of its containing Panels, including the Part. * @return {number} */ getDocumentAngle(): number; /** * Returns the total scale that the object is drawn at, in document coordinates. * * Basically this multiplies together this #scale with the scales of all of its containing Panels, including the Part. * @return {number} */ getDocumentScale(): number; /** * Given a Point in document coordinates, returns a new Point in local coordinates. * * For example, if you have a mouse event whose InputEvent#documentPoint is at `122, 213`, * and if you have a Node whose #position is at `100, 200`, * `node.getLocalPoint(e.documentPoint)` could return a Point that is at `22, 13`. * For a GraphObject within the Node named "TB", * ```js * node.findObject("TB").getLocalPoint(e.documentPoint) * ``` * could return a Point that is at `15.7, 6.7`, * if that "TB" object is positioned somewhat inside the bounds of the Node. * @param {Point} p a real Point in document coordinates. * @param {Point=} result an optional Point that is modified and returned. * @return {Point} The corresponding Point in local coordinates. * @see #getDocumentPoint */ getLocalPoint(p: Point, result?: Point): Point; /** * Gets or sets whether or not this GraphObject will be shadowed inside a Part that has Part#isShadowed set to true. * * The default is null, which means this GraphObject will obey the default shadow rules (see Part#isShadowed). * * A value of true or false will ensure that this part is shadowed or not regardless of the default shadow rules, * but this GraphObject's shadowed status will not affect other GraphObjects in the Part. * * Typically this property does not need to be set, but you may need to set this value to false * on GraphObjects inside a Part that you do not wish to be shadowed. * @see Part#isShadowed * @since 1.6 */ get shadowVisible(): boolean | null; set shadowVisible(value: boolean | null); /** * This predicate is true if this object is an element, perhaps indirectly, * of the given panel. * * For example, if this GraphObject is inside a Part but is not itself the Part, * `obj.isContainedBy(obj.part)` should be true. * @param {GraphObject} panel * @return {boolean} true if this object is contained by the given panel, * or if it is contained by another panel that is contained by the given panel, * to any depth; false if the argument is null or is not a Panel. */ isContainedBy(panel: GraphObject): boolean; /** * This predicate is true if this object is #visible * and each of its visual containing panels is also visible. * This ignores the actual location or appearance (except visibility) * of the panel that this object is part of, as well as ignoring all * properties of the Layer or Diagram. * * For Parts, you can call the Part#isVisible predicate to determine * if not only the Part is visible but also any containing Group or Link or Layer. * @return {boolean} */ isVisibleObject(): boolean; /** * This predicate is false if this object is inside any Panel that is not Panel#isEnabled, * or if this is itself a disabled panel. * This ignores the #visible and #pickable properties. * @return {boolean} * @see #enabledChanged * @see Panel#isEnabled * @since 1.7 */ isEnabledObject(): boolean; /** * Gets or sets the function to execute when some containing Panel changes the value of Panel#isEnabled. * It is typically used to modify the appearance of the object. * This function must not change the value of any panel Panel#isEnabled. * * If this property value is a function, it is called with two arguments, * this GraphObject and the new value. * By default this property is null -- no function is called. * @see #isEnabledObject * @see Panel#isEnabled * @since 1.7 */ get enabledChanged(): ((thisObj: GraphObject, enabled: boolean) => void) | null; set enabledChanged(value: ((thisObj: GraphObject, enabled: boolean) => void) | null); /** * Gets or sets the orientation of a GraphObject that is in a Link or Panel.Graduated. * This controls the automatic rotation of the object by the Link Panel or Graduated Panel. * The only accepted values are the Link "Orient..." values of Link * and the default value: Link.None. * * When the value is Link.None, the #angle of this object is unchanged as the link is routed. * Setting this to a value of Link.OrientAlong will cause routing to set the #angle * to be the angle of the segment that this object is on. * Other values compute the angle somewhat differently. * If the value is changed back to Link.None, the #angle of this object is set to zero. * * Note that when this property is not Link.None, this property takes precedence * over any setting or binding of the #angle property. * Changes to the angle caused by orientation might not result in Changed events, * and any original value for the angle may be lost. * * In the case of Graduated Panels, if this value is Link.None, Link.OrientAlong, or Link.OrientUpright, * any TextBlock label #angle will be respected. Depending on this value, the effective TextBlock angle will be either * fixed or relative to the slope of the path where it is rendered. * * For examples of how to use this property, see Link Labels. * @see #segmentFraction * @see #segmentIndex * @see #segmentOffset */ get segmentOrientation(): EnumValue; set segmentOrientation(value: EnumValue); /** * Gets or sets the segment index of a GraphObject that is in a Link. * Non-negative numbers count up from zero, which is the first segment, at the "from" end of the Link. * Negative numbers count segments from the "to" end of the Link, where -1 means the last segment * and -2 means the next-to-last segment. * The default value is -Infinity. The value should be an integer or NaN. * * Setting this value to NaN means #segmentFraction's fractional distance will be calculated along the entire link route. * A NaN value also means the Link#midPoint and Link#midAngle will not be used when determining label positions. * * If you do not set this property, the Link will choose a place that is approximately at the * mid-point of the link's route. * * For examples of how to use this property, see Link Labels. * @see #segmentFraction * @see #segmentOffset * @see #segmentOrientation */ get segmentIndex(): number; set segmentIndex(value: number); /** * Gets or sets the fractional distance along a segment of a GraphObject that is in a Link. * The value should be between zero and one, where zero is at the point at the start of the segment, * and where one is at the point at the end of the segment. * The default value is zero. * * If #segmentIndex is set to NaN, the fractional distance will be calculated along the entire link route. * * For examples of how to use this property, see Link Labels. * @see #segmentIndex * @see #segmentOffset * @see #segmentOrientation */ get segmentFraction(): number; set segmentFraction(value: number); /** * Gets or sets the offset of a GraphObject that is in a Link from a point on a segment * or in a Panel.Graduated from a point along the main element. * The X component of the Point indicates the distance along the route, * with positive values going further toward the "to" end of the link or panel. * The Y component of the Point indicates the distance away from the route, * with positive values towards the right as seen when facing further towards the "to" end of the link or panel. * The value defaults to the Point (0, 0). * You cannot modify the x or y of the value of this property -- * if you want to change the segmentOffset you must set this property to a different Point. * * For labels that are near either end of a link, it may be convenient to set the segmentOffset * to Point(NaN, NaN). This causes the offset to be half the width and half the height of the label object. * * For examples of how to use this property, see Link Labels. * @see #segmentFraction * @see #segmentIndex * @see #segmentOrientation */ get segmentOffset(): Point; set segmentOffset(value: Point); /** * Gets or sets the stretch of the GraphObject. * This controls whether the width and/or height of this object automatically adjusts to fill * the area allotted by the containing Panel. * * The only accepted values are listed as constant properties of GraphObject, * such as GraphObject.None, GraphObject.Fill, GraphObject.Horizontal, or GraphObject.Vertical. * The default value is GraphObject.Default, which allows the Panel to decide how to treat this object, depending on the type of Panel. * * Objects with an #angle that are stretched may look incorrect unless the angle is a multiple of 90. * * Stretch will have have different effects based upon the Panel containing this object. Elements of: * - Auto panels will not stretch, except the main element growing to fill the panel or being made uniform * - Horizontal panels will only stretch vertically * - Vertical panels will only stretch horizontally * - Spot panels will stretch to the size of the main element * - Table panels will stretch to the size of their cell, defined by their row and column, which is usually determined by other GraphObjects in that cell that are not stretching * - Grid panels, Link panels, and Graduated panels will not stretch * @see Panel#defaultStretch * @see #desiredSize * @see #minSize * @see #maxSize * @see #measuredBounds * @see #actualBounds * @see #scale * @see Picture#imageStretch */ get stretch(): EnumValue; set stretch(value: EnumValue); /** * Gets or sets the name for this object. * The default value is the empty string. * The name should be unique within a Panel, although if it isn't, * it reduces the usefulness of methods such as Panel#findObject. * * You must not modify the name of a GraphObject once it is in the visual tree of a Part. * * This is frequently needed to identify a particular GraphObject in the visual tree of a Part, * for example as the value of the Part#locationObjectName or * Part#selectionObjectName properties. */ get name(): string; set name(value: string); /** * Gets or sets the multiplicative opacity for this GraphObject and (if a Panel) all elements. * The value must be between 0.0 (fully transparent) and 1.0 (no additional transparency). * * Unlike #visible, Opacity only affects drawing, it does not cause objects to be resized or remeasured. * Opacity settings do not change the shape of the object or exclude it from object-picking * (does not change whether any objects are found by the "find..." methods). * * This value is multiplicative with any existing transparency, * for instance from Layer#opacity or a GraphObject's opacity higher in the visual tree, * or from a Brush or image transparency. * The default value is 1. * @see #visible * @see #pickable * @see Layer#opacity * @see Diagram#opacity * @since 1.4 */ get opacity(): number; set opacity(value: number); /** * Undocumented. May not work in Safari. */ get filter(): string; /** * Undocumented. May not work in Safari. */ set filter(value: string); /** * Gets or sets whether a GraphObject is visible. * The default value is true. * A not visible object takes no space in the Panel that it is in. * Toggling visibility may cause elements in the visual tree to re-measure and re-arrange. * Making a Panel not visible causes all of its elements not to be seen or receive input events. * Changing a Panel to become visible causes all of its elements to be seen and be active, * unless those elements are themselves not visible. * * This object does not get any mouse/touch events if it is not #visible * or if it is not #pickable. * * One can have a visible Shape that is not drawn by setting its Shape#fill * and Shape#stroke to null or to `"transparent"`. * Similarly, one can set TextBlock#stroke to null or to `"transparent"`. * It is also possible make a GraphObjects transparent by setting GraphObject#opacity to 0. * Finally, one can make a whole Layer-full of Parts invisible by setting Layer#visible to false. * * Use the #isVisibleObject predicate to see if this GraphObject is visible and is inside a Panel * that is #isVisibleObject, and so forth up the chain of panels until reaching the Part. * * For Parts, you can call the Part#isVisible predicate to determine * if not only the Part is visible but also any containing Group or Link, * and whether the Layer it is in is visible. * @see #opacity * @see #pickable * @see Layer#visible */ get visible(): boolean; set visible(value: boolean); /** * Gets or sets whether or not this GraphObject can be chosen by visual "find" or "hit-test" methods such * as Diagram#findObjectAt. * * This object does not get any mouse/touch events if it is not #visible * or if it is not #pickable. * * The default value is true -- mouse events on this object will be noticed. * If this value is false and this object is a Panel, not only is this Panel not "hittable", * but all of the elements inside the Panel will be ignored. * @see #visible * @see #opacity * @see Layer#pickable * @see Panel#isEnabled * @since 1.2 */ get pickable(): boolean; set pickable(value: boolean); /** * Gets or sets whether the user may draw duplicate Links from this port. * This property is used by LinkingBaseTool#isValidLink. * The default value is false. * * You must set this property on a GraphObject whose #portId is non-null, * unless the whole Node is acting as a single port, * in which case this property should be set on the Node. * @see #fromLinkable * @see #fromLinkableSelfNode * @see #toLinkableDuplicates */ get fromLinkableDuplicates(): boolean; set fromLinkableDuplicates(value: boolean); /** * Gets or sets whether the user may draw Links that connect from this port's Node. * This property is used by LinkingBaseTool#isValidLink. * The default value is false. * * You must set this property on a GraphObject whose #portId is non-null, * unless the whole Node is acting as a single port, * in which case this property should be set on the Node. * @see #fromLinkable * @see #fromLinkableDuplicates * @see #toLinkableSelfNode */ get fromLinkableSelfNode(): boolean; set fromLinkableSelfNode(value: boolean); /** * Gets or sets whether the user may draw duplicate Links to this port. * This property is used by LinkingBaseTool#isValidLink. * The default value is false. * * You must set this property on a GraphObject whose #portId is non-null, * unless the whole Node is acting as a single port, * in which case this property should be set on the Node. * @see #toLinkable * @see #toLinkableSelfNode * @see #fromLinkableDuplicates */ get toLinkableDuplicates(): boolean; set toLinkableDuplicates(value: boolean); /** * Gets or sets whether the user may draw Links that connect to this port's Node. * This property is used by LinkingBaseTool#isValidLink. * The default value is false. * * You must set this property on a GraphObject whose #portId is non-null, * unless the whole Node is acting as a single port, * in which case this property should be set on the Node. * @see #toLinkable * @see #toLinkableDuplicates * @see #fromLinkableSelfNode */ get toLinkableSelfNode(): boolean; set toLinkableSelfNode(value: boolean); /** * Gets or sets whether a GraphObject is the "main" object for some types of Panel. * Panels that use a "main" object include Panel.Auto, Panel.Spot, and Panel.Link. * * Panels that use a "main" object will use the first object that has this property set to true, * or else just the first object, if none have the property set. * * Do not modify this property once this object is an element of a panel. */ get isPanelMain(): boolean; set isPanelMain(value: boolean); /** * This property determines whether or not this GraphObject's events occur * before all other events, including selection. This enables the #actionDown, * #actionMove, #actionUp, and #actionCancel events, * which are all handled by the ActionTool. * * This object does not get any mouse/touch events if it is not #visible * or if it is not #pickable. * * This property is infrequently used -- typically only when implementing objects * that act as buttons or knobs or sliders. * The default value is false. * @see #actionDown * @see #actionMove * @see #actionUp * @see #actionCancel * @see #pickable * @see Panel#isEnabled */ get isActionable(): boolean; set isActionable(value: boolean); /** * Gets or sets the areaBackground Brush of this GraphObject. * The areaBackground fills the rectangle described by this GraphObject's containing panel's coordinates. * If the object is rotated, the area background will expand to fill the entire measured bounds of the object, * without rotating the brush. * * The value may be either a Brush object or a string that is a CSS color. * The default value is null -- no area background is drawn. * More information about the syntax of CSS color strings is available at: * CSS colors (mozilla.org). * @see #background * @see Shape#fill */ get areaBackground(): BrushLike; set areaBackground(value: BrushLike); /** * Gets or sets the background Brush of this GraphObject, * filling the rectangle of this object's local coordinate space. * If the object is rotated, the background will rotate with it. * * The value may be either a Brush object or a string that is a CSS color. * The default value is null -- no background is drawn. * More information about the syntax of CSS color strings is available at: * CSS colors (mozilla.org). * @see Shape#fill */ get background(): BrushLike; set background(value: BrushLike); /** * This read-only property returns the Part containing this object, if any. * The Part will be the root GraphObject in this GraphObject's visual tree. * * It is common to refer to the containing Part of a GraphObject * in order to refer to the Panel#data to which it is bound. * * This property is not settable. * If you want this GraphObject to belong to a Part, you will need to add it to a Part, * or else add it to some visual tree structure that is added to a Part using Panel#add. * * Note that for objects such as buttons that are in Adornments such as tooltips or context menus, * this property will return that Adornment, not the Node or Link that is adorned. * * If you want to find a Group that contains a Part, use the Part#containingGroup property: * `someObj.part.containingGroup` */ get part(): Part | null; set svg(value: SVGElement); /** * This read-only property returns the GraphObject's containing Panel, or null if this object is not in a Panel. * * Although Part inherits from this class, a Part will never belong to a Panel, * so this property will always be null for every Node or Link. * * This property is not settable. * Instead, call Panel#add in order to put a GraphObject in a Panel. */ get panel(): Panel | null; /** * This read-only property returns the GraphObject's containing Layer, if there is any. * A plain GraphObject cannot belong directly to a Layer -- only a Part can belong directly to a Layer. * * This property is not settable. * Normally one changes which Layer that a GraphObject is in by setting Part#layerName. * Adding a Part to a Diagram will automatically add that Part to a Layer in that Diagram based on the layerName. */ get layer(): Layer | null; /** * This read-only property returns the Diagram that this GraphObject is in, if it is. * * This property is not settable. * Although you cannot add any plain GraphObject to a Diagram, you can call Diagram#add * to add a Part to a Diagram. */ get diagram(): Diagram | null; /** * Gets or sets the position of this GraphObject in container coordinates * (either a Panel or the document). * Value must be of type Point. * You cannot modify the x or y of the value of this property -- * if you want to change the position you must set this property to a different Point. * Default is `Point(NaN, NaN)`. * * For Parts, see also Part#location. */ get position(): Point; set position(value: Point); /** * This read-only property returns the bounds of this GraphObject in container coordinates. This means that * the actualBounds are in the coordinate space of the GraphObject's Panel, * unless this is a Part, in which case they are in * the Diagram's coordinate system. * * You must not modify any of the properties of the Rect that is the value of this property. * * If this GraphObject is a Part, * then the x and y values of the actualBounds are identical to that Part's #position, * and the width and height values of the actualBounds represent the rectangular space occupied * by the Part in Diagram#documentBounds coordinates. * * If this GraphObject is not a top-level object (not a Part), then the actualBounds * x and y values represent that GraphObject's position within its Panel. In a Panel of type Panel.Position * this is identical to the GraphObject's #position, but in other cases it is dependent on * the unique workings of each Panel type. The actualBounds width and height * of a GraphObject are the final size after the #scale and #angle are applied. * * It is possible for a GraphObject (be it an GraphObject or a Panel containing several more GraphObjects) * to have no containing Part, in which case these GraphObjects cannot possibly be in a Diagram. * These GraphObjects are unlikely to have real-number values for their actualBounds, as they may * never have had the chance to be measured and arranged. * * As with all read-only properties, using this property as a binding source is unlikely to be useful. * @see #measuredBounds * @see #desiredSize */ get actualBounds(): Rect; /** * Gets or sets the scale transform of this GraphObject. * Value must be a number; larger values will make this object appear bigger. * Default is 1. * @see #angle * @see #stretch */ get scale(): number; set scale(value: number); /** * Gets or sets the angle transform, in degrees, of this GraphObject. * Value must be a number. If the value is not between (0 <= value < 360), * it will be normalized to be in that range. * Zero is along the positive X-axis (rightwards); 90 is along the positive Y-axis (downwards). * Default is 0. * * When set on a Graduated Panel's TextBlock label, this value will be be ignored if #segmentOrientation is not * Link.None, Link.OrientAlong, or Link.OrientUpright. OrientAlong and OrientUpright will use this angle * relative to the slope of the main path. * * When set on a Link label, this value will be be ignored if #segmentOrientation is not Link.None. * @see #scale * @see #stretch */ get angle(): number; set angle(value: number); /** * Gets or sets the desired size of this GraphObject in local coordinates. * Value must be of type Size. * Default is Size(NaN, NaN). * You cannot modify the width or height of the value of this property -- * if you want to change the desiredSize you must set this property to a different Size. * * Getting or setting #width or #height is equivalent to getting or setting the * width or height of this property. * * The size does not include any transformation due to #scale or #angle, * nor any pen thickness due to Shape#strokeWidth if this is a Shape. * If there is a containing Panel the Panel will determine the actual size. * If the desiredSize is greater than the allowed size that the GraphObject's Panel determines, * then the GraphObject may be visually clipped. If the desiredSize does not meet the constraints * of #minSize and #maxSize, the GraphObject will be resized to meet them. * @see #minSize * @see #maxSize * @see #naturalBounds * @see #measuredBounds * @see #actualBounds */ get desiredSize(): Size; set desiredSize(value: Size); /** * Gets or sets the desired width of this GraphObject in local coordinates. * This just gets or sets the width component of the #desiredSize. * Default is NaN. * * Size can also be constrained by setting #minSize and #maxSize. * * The width does not include any transformation due to #scale or #angle, * nor any pen thickness due to Shape#strokeWidth if this is a Shape. * If there is a containing Panel the Panel will determine the actual size. */ get width(): number; set width(value: number); /** * Gets or sets the desired height of this GraphObject in local coordinates. * This just gets or sets the height component of the #desiredSize. * Default is NaN. * * Size can also be constrained by setting #minSize and #maxSize. * * The height does not include any transformation due to #scale or #angle, * nor any pen thickness due to Shape#strokeWidth if this is a Shape. * If there is a containing Panel the Panel will determine the actual size. */ get height(): number; set height(value: number); /** * Gets or sets the minimum size of this GraphObject in container coordinates * (either a Panel or the document). * Any new value must be of type Size; NaN values are treated as 0. * * You cannot modify the width or height of the value of this property -- * if you want to change the minSize you must set this property to a different Size. * The default value is zero by zero. * A containing Panel will determine the actual size of this object. * @see #maxSize * @see #desiredSize */ get minSize(): Size; set minSize(value: Size); /** * Gets or sets the maximum size of this GraphObject in container coordinates * (either a Panel or the document). * Any new value must be of type Size; NaN values are treated as Infinity. If you want no maximum width or height, use NaN or Infinity. * * You cannot modify the width or height of the value of this property -- * if you want to change the maxSize you must set this property to a different Size. * The default value is Infinity by Infinity. * A containing Panel will determine the actual size of this object. * @see #minSize * @see #desiredSize */ get maxSize(): Size; set maxSize(value: Size); /** * This read-only property returns the measuredBounds of the GraphObject in container coordinates * (either a Panel or the document). * This describes the transformed bounds with margins excluded. * * You must not modify any of the properties of the Rect that is the value of this property. * * As with all read-only properties, using this property as a binding source is unlikely to be useful. * @see #naturalBounds * @see #desiredSize * @see #actualBounds */ get measuredBounds(): Rect; /** * This read-only property returns the natural bounding rectangle of this GraphObject in local coordinates, * before any transformation by #scale or #angle. * Defaults to unknown (NaN,NaN). * * You must not modify any of the properties of the Rect that is the value of this property. * * The value can only be changed by changing properties of the particular GraphObject, * such as GraphObject#desiredSize, Shape#geometry, or TextBlock#font. * * As with all read-only properties, using this property as a binding source is unlikely to be useful. * @see #desiredSize * @see #measuredBounds * @see #actualBounds */ get naturalBounds(): Rect; /** * Gets or sets the size of empty area around this GraphObject, as a Margin, * in the containing Panel coordinates. * * Negative values are permitted but may cause overlaps with adjacent * objects in a Panel. * You cannot modify the top or left or right or bottom of the value of this property -- * if you want to change the margin you must set this property to a different Margin. * Default margin is `Margin(0,0,0,0)`. * * For most uses, increasing a margin will increase the space this GraphObject takes in its containing panel. * When an object has a GraphObject#stretch value applied, margins may decrease the size of that object. * * The property setter accepts a number instead of a Margin object: providing a * number `N` will result in using a `Margin(N, N, N, N)`. * The property getter will always return a Margin. * @see #desiredSize * @see #measuredBounds * @see #actualBounds * @see Panel#padding */ get margin(): MarginLike; set margin(value: MarginLike); /********************************************************** Panel-specific properties: ***********************************************************/ /** * Gets or sets the alignment Spot of this GraphObject used in Panel layouts, * to determine where in the area allocated by the panel this object should be placed. * * The default value is Spot.Default, which lets the Panel determine the Spot using * Panel#defaultAlignment. If that property is also Spot.Default, * then the alignment spot will be different depending on the Panel type. * * The #alignmentFocus is often used along with this property to specify * where this object should be positioned in a Panel. * * A Spot.Default is equivalent to Spot.Center in Spot, Auto, Horizontal, and Vertical panels. * For examples of alignments in different panels, see the Introduction page on Panels. * * @see #alignmentFocus * @see Panel#defaultAlignment */ get alignment(): Spot; set alignment(value: Spot); /** * Gets or sets the column of this GraphObject if it is in a Table Panel. * The value must be a small non-negative integer. The default is 0. */ get column(): number; set column(value: number); /** * Gets or sets the number of columns spanned by this GraphObject if it is in a Table Panel. * The value must be a small positive integer. The default is 1. */ get columnSpan(): number; set columnSpan(value: number); /** * Gets or sets the row of this GraphObject if it is in a Table Panel. * The value must be a small non-negative integer. The default is 0. */ get row(): number; set row(value: number); /** * Gets or sets the number of rows spanned by this GraphObject if it is in a Table Panel. * The value must be a small positive integer. The default is 1. */ get rowSpan(): number; set rowSpan(value: number); /** * (undocumented) */ get spanAllocation(): ((a: GraphObject, b: RowColumnDefinition, c: number) => number) | null; set spanAllocation(value: ((a: GraphObject, b: RowColumnDefinition, c: number) => number) | null); /** * Gets or sets the spot on this GraphObject to be used as the alignment point * in Spot and Fixed Panels. * Value must be of the Spot. * * The default value is Spot.Default, which means that the Panel type can decide the effective alignment spot. * * The #alignment is often used along with this property to specify * where this object should be positioned in a Panel. * * For Panel.Graduated, the alignmentFocus spot determines the spot on a child element to be aligned with some * point along the main element. * * When you want a link label Node to be positioned by its location spot rather than by this alignmentFocus spot, * you can set this property to Spot.None, only on Nodes. * * For examples of alignments in different panels, see the Introduction page on Panels. * * WARNING: Since 2.0, for Spot Panels, the offsetX/offsetY of #alignmentFocus has been reversed. * The offsetX/Y now describes offset distance from the alignmentFocus point to the alignment point, rather than the opposite. * This is what it has always described when using #alignmentFocus with Link Labels. * @see Panel#alignmentFocusName */ get alignmentFocus(): Spot; set alignmentFocus(value: Spot); /********************************************************** Port-specific properties: ***********************************************************/ /** * Gets or sets an identifier for an object acting as a port on a Node. * The default value is null -- this object is not a port. * * A value that is the empty string is used by convention to mean the primary * (and usually only) port of the node. * * If a Node has no named ports, then the Node itself is the sole port. * * Note: the only kind of model that can save port information, i.e. portIds that are not an empty string, * for links is a GraphLinksModel whose GraphLinksModel#linkFromPortIdProperty and * GraphLinksModel#linkToPortIdProperty have been set to name properties on the link data objects. * * The value should be unique within the Node. * You must not modify this property once this GraphObject is in the visual tree of a Node. *

* See the Introduction page on ports * for usage information and examples. * @see #fromLinkable * @see #toLinkable * @see #fromSpot * @see #toSpot * @see Link#fromSpot * @see Link#toSpot */ get portId(): string; set portId(value: string); /** * Gets or sets where a link should connect to this port. * The default value is Spot.None, meaning that the link routing * must consider the shape of the port and connect to the closest point. * * The value of Link#toSpot, if not Spot.Default, takes precedence over the value at this port * when determining the route of the link. * A number of the predefined Layouts automatically set Link#fromSpot and Link#toSpot, * thereby causing this property and #fromSpot on the port element to be ignored. * Depending on the layout, you may be able to disable that behavior, such as by setting ForceDirectedLayout#setsPortSpots, * TreeLayout#setsPortSpot, TreeLayout#setsChildPortSpot, or LayeredDigraphLayout#setsPortSpots to false. * * For examples of how to use this property, see Link Connection Points. * * You must set this property on a GraphObject whose #portId is non-null, * unless the whole Node is acting as a single port, * in which case this property should be set on the Node. * @see Link#toSpot * @see Link#computeSpot * @see #fromSpot * @see #portId */ get toSpot(): Spot; set toSpot(value: Spot); /** * Gets or sets the length of the last segment of a link going to this port. * This value is used when the computed "to spot" is not Spot.None. * The default value is 10. * * The value of Link#toEndSegmentLength, if not NaN, takes precedence over the value at this port * when determining the route of the link. * This value also limits how short the Link#toShortLength may be drawn. * * For examples of how to use this property, see Link End Segment Lengths. * * You must set this property on a GraphObject whose #portId is non-null, * unless the whole Node is acting as a single port, * in which case this property should be set on the Node. * @see Link#toEndSegmentLength * @see Link#computeEndSegmentLength * @see #fromEndSegmentLength * @see #portId */ get toEndSegmentLength(): number; set toEndSegmentLength(value: number); /** * Gets or sets how far the end segment of a link going to this port stops short of the actual port. * Positive values are limited by the #toEndSegmentLength or Link#toEndSegmentLength. * Negative values cause the link to extend into the port. * The default value is zero. * * This property is useful when you have a thick link and a pointy arrowhead. * Normally the link Shape extends all the way to the end of the arrowhead. * If the link Shape is wide, its edges will be seen behind the arrowhead. * By setting this property to a small positive value, the link Shape can end within the * body of the arrowhead, leaving only the point of the arrowhead visible at the end of the link. * * A negative value for this property can also be useful when you want the link Shape to continue * into the port, perhaps because a portion of the port is transparent and you want the link to * appear to connect visually with a different point on the node. * * The value of Link#toShortLength, if not NaN, takes precedence over the value at this port * when determining the route of the link. * * For examples of how to use this property, see Link Connection Points. * * You must set this property on a GraphObject whose #portId is non-null, * unless the whole Node is acting as a single port, * in which case this property should be set on the Node. * @see #fromShortLength * @see Link#toShortLength * @see #portId */ get toShortLength(): number; set toShortLength(value: number); /** * Gets or sets whether the user may draw Links to this port. * This property is used by LinkingBaseTool#isValidTo. * * The default value is null, which indicates that the real value is inherited from * the parent Panel, or false if there is no containing panel. * * You must set this property on a GraphObject whose #portId is non-null, * unless the whole Node is acting as a single port, * in which case this property should be set on the Node, * or unless you are disabling the "linkability" of a particular GraphObject * inside a Panel whose toLinkable has been set or bound to true. * @see #fromLinkable * @see #toMaxLinks * @see #portId * @see #cursor */ get toLinkable(): boolean | null; set toLinkable(value: boolean | null); /** * Gets or sets the maximum number of links that may go into this port. * This property is used by LinkingBaseTool#isValidTo. * * The value must be non-negative. * The default value is Infinity. * * You must set this property on a GraphObject whose #portId is non-null, * unless the whole Node is acting as a single port, * in which case this property should be set on the Node. * @see #toLinkable * @see #fromMaxLinks * @see #portId */ get toMaxLinks(): number; set toMaxLinks(value: number); /** * Gets or sets where a link should connect from this port. * The default value is Spot.None, meaning that the link routing * must consider the shape of the port and connect at the closest point. * * The value of Link#fromSpot, if not Spot.Default, takes precedence over the value at this port * when determining the route of the link. * A number of the predefined Layouts automatically set Link#fromSpot and Link#toSpot, * thereby causing this property and #toSpot on the port element to be ignored. * Depending on the layout, you may be able to disable that behavior, such as by setting ForceDirectedLayout#setsPortSpots, * TreeLayout#setsPortSpot, TreeLayout#setsChildPortSpot, or LayeredDigraphLayout#setsPortSpots to false. * * For examples of how to use this property, see Link Connection Points. * * You must set this property on a GraphObject whose #portId is non-null, * unless the whole Node is acting as a single port, * in which case this property should be set on the Node. * @see Link#fromSpot * @see Link#computeSpot * @see #toSpot * @see #portId */ get fromSpot(): Spot; set fromSpot(value: Spot); /** * Gets or sets the length of the first segment of a link coming from this port. * This value is used when the computed "from spot" is not Spot.None. * The default value is 10. * This value also limits how short the Link#fromShortLength may be drawn. * * The value of Link#fromEndSegmentLength, if not NaN, takes precedence over the value at this port * when determining the route of the link. * * For examples of how to use this property, see Link End Segment Lengths. * * You must set this property on a GraphObject whose #portId is non-null, * unless the whole Node is acting as a single port, * in which case this property should be set on the Node. * @see Link#fromEndSegmentLength * @see Link#computeEndSegmentLength * @see #toEndSegmentLength * @see #portId */ get fromEndSegmentLength(): number; set fromEndSegmentLength(value: number); /** * Gets or sets how far the end segment of a link coming from this port stops short of the actual port. * Positive values are limited by the #fromEndSegmentLength or Link#fromEndSegmentLength. * Negative values cause the link to extend into the port. * The default value is zero. * * This property is useful when you have a thick link and a pointy arrowhead. * Normally the link Shape extends all the way to the end of the arrowhead. * If the link Shape is wide, its edges will be seen behind the arrowhead. * By setting this property to a small positive value, the link Shape can end within the * body of the arrowhead, leaving only the point of the arrowhead visible at the end of the link. * * A negative value for this property can also be useful when you want the link Shape to continue * into the port, perhaps because a portion of the port is transparent and you want the link to * appear to connect visually with a different point on the node. * * The value of Link#fromShortLength, if not NaN, takes precedence over the value at this port * when determining the route of the link. * * For examples of how to use this property, see Link Connection Points. * * You must set this property on a GraphObject whose #portId is non-null, * unless the whole Node is acting as a single port, * in which case this property should be set on the Node. * @see #toShortLength * @see Link#fromShortLength * @see #portId */ get fromShortLength(): number; set fromShortLength(value: number); /** * Gets or sets whether the user may draw Links from this port. * This property is used by LinkingBaseTool#isValidFrom. * * The default value is null, which indicates that the real value is inherited from * the parent Panel, or false if there is no containing panel. * * You must set this property on a GraphObject whose #portId is non-null, * unless the whole Node is acting as a single port, * in which case this property should be set on the Node, * or unless you are disabling the "linkability" of a particular GraphObject * inside a Panel whose fromLinkable has been set or bound to true. * @see #toLinkable * @see #fromMaxLinks * @see #portId * @see #cursor */ get fromLinkable(): boolean | null; set fromLinkable(value: boolean | null); /** * Gets or sets the maximum number of links that may come out of this port. * This property is used by LinkingBaseTool#isValidFrom. * * The value must be non-negative. * The default value is Infinity. * * You must set this property on a GraphObject whose #portId is non-null, * unless the whole Node is acting as a single port, * in which case this property should be set on the Node. * @see #fromLinkable * @see #toMaxLinks * @see #portId */ get fromMaxLinks(): number; set fromMaxLinks(value: number); /********************************************************** Event Handling: ***********************************************************/ /** * Gets or sets the mouse cursor to use when the mouse is over this object with no mouse buttons pressed. * The value is null when no particular cursor is specified for this object; * the actual cursor is determined by any containing Panel. * * The default value is the empty string, which means the * current mouse cursor is determined by the Diagram. * Other strings should be valid CSS strings that specify a cursor. * This provides some more information about cursor syntax: * CSS cursors (mozilla.org). * * Read more about cursors at Diagram#currentCursor * @see Diagram#defaultCursor * @see Diagram#currentCursor */ get cursor(): string; set cursor(value: string); /** * Gets or sets the function to execute when the user single-primary-clicks on this object. * This typically involves a mouse-down followed by a prompt mouse-up * at approximately the same position using the left (primary) mouse button. * This property is used by the ClickSelectingTool * when the user clicks on a GraphObject. * The function is called in addition to the DiagramEvent * that is raised with the name `"ObjectSingleClicked"`. * * If this property value is a function, it is called with an InputEvent * and this GraphObject. * The InputEvent#targetObject provides the GraphObject that was found * at the mouse point before looking up the visual tree of GraphObject#panels * to get to this object. * * From the second argument, *obj*, you can get to the Node or Link via the #part property. * From there you can access the bound data via the Panel#data property. * So from an event handler you can get the bound data by `obj.part.data`. * * By default this property is null. * * Objects in Layers that are Layer#isTemporary do not receive click events. * If you do want such objects to respond to clicks, set #isActionable to true. * * If you do provide a function that makes changes to the diagram or to its model, * you should do so within a transaction -- call Diagram#startTransaction and * Diagram#commitTransaction. *

* An example of a click event handler is shown in the * Arrowheads sample. * @see #doubleClick * @see #contextClick * @see Diagram#click */ get click(): ((e: InputEvent, thisObj: GraphObject) => void) | null; set click(value: ((e: InputEvent, thisObj: GraphObject) => void) | null); /** * Gets or sets the function to execute when the user double-primary-clicks on this object. * This typically involves a mouse-down/up/down/up in rapid succession * at approximately the same position using the left (primary) mouse button. * This property is used by the ClickSelectingTool * when the user clicks on a GraphObject. * The function is called in addition to the DiagramEvent * that is raised with the name `"ObjectDoubleClicked"`. * * If this property value is a function, it is called with an InputEvent * and this GraphObject. * The InputEvent#targetObject provides the GraphObject that was found * at the mouse point before looking up the visual tree of GraphObject#panels * to get to this object. * * From the second argument, *obj*, you can get to the Node or Link via the #part property. * From there you can access the bound data via the Panel#data property. * So from an event handler you can get the bound data by `obj.part.data`. * * By default this property is null. * * Objects in Layers that are Layer#isTemporary do not receive click events. * If you do want such objects to respond to clicks, set #isActionable to true. * * If you do provide a function that makes changes to the diagram or to its model, * you should do so within a transaction -- call Diagram#startTransaction and * Diagram#commitTransaction. * * The Class Hierarchy sample * demonstrates the definition of a double-click event handler that opens up * a web page with the documentation for that class: * ```js * diagram.nodeTemplate = * $(go.Node, . . ., * { * doubleClick: // here the second argument is this object, which is this Node * (e, node) => { window.open("../api/symbols/" + node.data.key + ".html"); } * }, * . . . * ); * ``` * @see #click * @see #contextClick * @see Diagram#doubleClick */ get doubleClick(): ((e: InputEvent, thisObj: GraphObject) => void) | null; set doubleClick(value: ((e: InputEvent, thisObj: GraphObject) => void) | null); /** * Gets or sets the function to execute when the user single-secondary-clicks on this object. * This typically involves a mouse-down followed by a prompt mouse-up * at approximately the same position using the right (secondary) mouse button. * This property is used by the ClickSelectingTool * when the user clicks on a GraphObject. * The function is called in addition to the DiagramEvent * that is raised with the name `"ObjectContextClicked"`. * * If this property value is a function, it is called with an InputEvent * and this GraphObject. * The InputEvent#targetObject provides the GraphObject that was found * at the mouse point before looking up the visual tree of GraphObject#panels * to get to this object. * * From the second argument, *obj*, you can get to the Node or Link via the #part property. * From there you can access the bound data via the Panel#data property. * So from an event handler you can get the bound data by `obj.part.data`. * * By default this property is null. * * Objects in Layers that are Layer#isTemporary do not receive click events. * If you do want such objects to respond to clicks, set #isActionable to true. * * If you do provide a function that makes changes to the diagram or to its model, * you should do so within a transaction -- call Diagram#startTransaction and * Diagram#commitTransaction. * @see #click * @see #doubleClick * @see Diagram#contextClick */ get contextClick(): ((e: InputEvent, thisObj: GraphObject) => void) | null; set contextClick(value: ((e: InputEvent, thisObj: GraphObject) => void) | null); /** * Gets or sets the function to execute when the user moves the mouse * into this object without holding down any buttons. * This property is used by the ToolManager. * * If this property value is a function, it is called with an InputEvent, * this GraphObject that the mouse is now in, * and any previous GraphObject that the mouse was in. * The InputEvent#targetObject provides the GraphObject that was found * at the mouse point before looking up the visual tree of GraphObject#panels * to get to this object. * By default this property is null. * * This function is called with Diagram#skipsUndoManager temporarily set to true, * so that any changes to GraphObjects are not recorded in the UndoManager. * You do not need to start and commit any transaction in this function. * After calling this function the diagram will be updated immediately. * * For example, consider the situation where one wants to display buttons that the user can click * whenever the user passes the mouse over a node, and the buttons automatically disappear when the * mouse leaves the node. This can be implemented by showing an Adornment holding the buttons. * ```js * var nodeContextMenu = * $(go.Adornment, "Spot", * { background: "transparent" }, // to help detect when the mouse leaves the area * $(go.Placeholder), * $(go.Panel, "Vertical", * { alignment: go.Spot.Right, alignmentFocus: go.Spot.Left }, * $("Button", * $(go.TextBlock, "Command 1"), * { * click: (e, obj) => { * var node = obj.part.adornedPart; * alert("Command 1 on " + node.data.text); * node.removeAdornment("ContextMenuOver"); * } * }), * $("Button", * $(go.TextBlock, "Command 2"), * { * click: (e, obj) => { * var node = obj.part.adornedPart; * alert("Command 2 on " + node.data.text); * node.removeAdornment("ContextMenuOver"); * } * }) * )); * ``` * Then in the definition of the Node we can implement a mouseEnter event handler: * ```js * myDiagram.nodeTemplate = * $(go.Node, * . . . * { * mouseEnter: (e, node) => { * nodeContextMenu.adornedObject = node; * nodeContextMenu.mouseLeave = (ev, cm) => { * node.removeAdornment("ContextMenuOver"); * } * node.addAdornment("ContextMenuOver", nodeContextMenu); * } * }); * ``` * Note how it automatically defines a #mouseLeave event handler too. * The context menu Adornment is removed either when the mouse leaves the area of the Adornment * or when the user executes a button click event handler. * @see #mouseLeave * @see #mouseOver * @see #mouseHover * @see #mouseDragEnter */ get mouseEnter(): ((e: InputEvent, thisObj: GraphObject, prevObj: GraphObject) => void) | null; set mouseEnter(value: ((e: InputEvent, thisObj: GraphObject, prevObj: GraphObject) => void) | null); /** * Gets or sets the function to execute when the user moves the mouse * out of this object without holding down any buttons. * This property is used by the ToolManager. * * If this property value is a function, it is called with an InputEvent, * this GraphObject that the mouse has left, * and any next GraphObject that the mouse is now in. * The InputEvent#targetObject provides the GraphObject that was found * at the mouse point before looking up the visual tree of GraphObject#panels * to get to this object. * By default this property is null. * * This function is called with Diagram#skipsUndoManager temporarily set to true, * so that any changes to GraphObjects are not recorded in the UndoManager. * You do not need to start and commit any transaction in this function. * After calling this function the diagram will be updated immediately. * * For example, the Flow Chart sample * automatically shows and hides the ports as the mouse passes over a node. * The node template includes the following settings: * ```js * myDiagram.nodeTemplate = * $(go.Node, * . . . * { * . . . * // handle mouse enter/leave events to show/hide the ports * mouseEnter: (e, obj) => showPorts(obj.part, true), * mouseLeave: (e, obj) => showPorts(obj.part, false) * . . . * }); * ``` * where the `showPorts` function is defined to set the #visible * property of each of the port elements of the node. * @see #mouseEnter * @see #mouseOver * @see #mouseHover * @see #mouseDragLeave */ get mouseLeave(): ((e: InputEvent, thisObj: GraphObject, nextObj: GraphObject) => void) | null; set mouseLeave(value: ((e: InputEvent, thisObj: GraphObject, nextObj: GraphObject) => void) | null); /** * Gets or sets the function to execute when the user moves the mouse * over this object without holding down any buttons. * This property is used by the ToolManager. * This property is infrequently used -- it is more common to implement #mouseEnter * and #mouseLeave functions. * * If this property value is a function, it is called with an InputEvent * and this GraphObject. * The InputEvent#targetObject provides the GraphObject that was found * at the mouse point before looking up the visual tree of GraphObject#panels * to get to this object. * By default this property is null. * * This function is called with Diagram#skipsUndoManager temporarily set to true, * so that any changes to GraphObjects are not recorded in the UndoManager. * You do not need to start and commit any transaction in this function. * After calling this function the diagram will be updated immediately. * @see #mouseHover * @see #mouseEnter * @see #mouseLeave */ get mouseOver(): ((e: InputEvent, thisObj: GraphObject) => void) | null; set mouseOver(value: ((e: InputEvent, thisObj: GraphObject) => void) | null); /** * Gets or sets the function to execute when the user holds the mouse still for a while * over this object without holding down any buttons. * This property is used by the ToolManager. * * If this property value is a function, it is called with an InputEvent. * By default this property is null. * * If you do provide a function that makes changes to the diagram or to its model, * you should do so within a transaction -- call Diagram#startTransaction and * Diagram#commitTransaction. * * You can control how long the user must wait with a motionless mouse before * a "mouse hover" event occurs, by setting ToolManager#hoverDelay. * For example: * ```js * myDiagram = new go.Diagram("myDiagramDiv", * { "toolManager.hoverDelay": 500 }); // 500 milliseconds * ``` * or: * ```js * myDiagram.toolManager.hoverDelay = 500; // 500 milliseconds * ``` * @see #mouseOver * @see #mouseEnter * @see #mouseLeave */ get mouseHover(): ((e: InputEvent, thisObj: GraphObject) => void) | null; set mouseHover(value: ((e: InputEvent, thisObj: GraphObject) => void) | null); /** * Gets or sets the function to execute when the user holds the mouse still for a while * over this object while holding down a button. * This property is used by the ToolManager. * * If this property value is a function, it is called with an InputEvent. * By default this property is null. * * If you do provide a function that makes changes to the diagram or to its model, * you should do so within a transaction -- call Diagram#startTransaction and * Diagram#commitTransaction. * * You can control how long the user must wait during a drag with a motionless mouse before * a "mouse hold" event occurs, by setting ToolManager#holdDelay. * For example: * ```js * myDiagram = new go.Diagram("myDiagramDiv", * { "toolManager.holdDelay": 500 }); // 500 milliseconds * ``` * or: * ```js * myDiagram.toolManager.holdDelay = 500; // 500 milliseconds * ``` * @see #mouseDragEnter * @see #mouseDragLeave * @see #mouseHover */ get mouseHold(): ((e: InputEvent, thisObj: GraphObject) => void) | null; set mouseHold(value: ((e: InputEvent, thisObj: GraphObject) => void) | null); /** * Gets or sets the function to execute when the user moves the mouse * into this stationary object during a DraggingTool drag; * this allows you to provide feedback during a drag based on where it might drop. * * If this property value is a function, it is called with an InputEvent, * this GraphObject, and any previous GraphObject. * The InputEvent#targetObject provides the GraphObject that was found * at the mouse point before looking up the visual tree of GraphObject#panels * to get to this object. * By default this property is null. * * Note that for a drag-and-drop that originates in a different diagram, the target diagram's * selection collection will not be the parts that are being dragged. * Instead the temporary parts being dragged can be found as the source diagram's DraggingTool#copiedParts. * * This function is called with Diagram#skipsUndoManager temporarily set to true, * so that any changes to GraphObjects are not recorded in the UndoManager. * You do not need to start and commit any transaction in this function, * because the DraggingTool will be conducting one already. * After calling this function the diagram will be updated immediately. * * For an example of a mouseDragEnter event handler, see the node template in the * Org Chart Editor sample. * @see #mouseDragLeave * @see #mouseHold * @see #mouseDrop * @see #mouseEnter * @see Group#handlesDragDropForMembers */ get mouseDragEnter(): ((e: InputEvent, thisObj: GraphObject, prevObj: GraphObject) => void) | null; set mouseDragEnter(value: ((e: InputEvent, thisObj: GraphObject, prevObj: GraphObject) => void) | null); /** * Gets or sets the function to execute when the user moves the mouse * out of this stationary object during a DraggingTool drag; * this allows you to provide feedback during a drag based on where it might drop. * * If this property value is a function, it is called with an InputEvent, * this GraphObject, and any new GraphObject that the mouse is in. * The InputEvent#targetObject provides the GraphObject that was found * at the mouse point before looking up the visual tree of GraphObject#panels * to get to this object. * By default this property is null. * * Note that for a drag-and-drop that originates in a different diagram, the target diagram's * selection collection will not be the parts that are being dragged. * Instead the temporary parts being dragged can be found as the source diagram's DraggingTool#copiedParts. * * This function is called with Diagram#skipsUndoManager temporarily set to true, * so that any changes to GraphObjects are not recorded in the UndoManager. * You do not need to start and commit any transaction in this function, * because the DraggingTool will be conducting one already. * After calling this function the diagram will be updated immediately. * * For an example of a mouseDragLeave event handler, see the node template in the * Org Chart Editor sample. * @see #mouseDragEnter * @see #mouseHold * @see #mouseDrop * @see #mouseLeave * @see Group#handlesDragDropForMembers */ get mouseDragLeave(): ((e: InputEvent, thisObj: GraphObject, nextObj: GraphObject) => void) | null; set mouseDragLeave(value: ((e: InputEvent, thisObj: GraphObject, nextObj: GraphObject) => void) | null); /** * Gets or sets the function to execute when a user drops the selection on this object * at the end of a DraggingTool drag; * this allows you to customize the behavior when a drop occurs on an object. * * If this property value is a function, it is called with an InputEvent, * this GraphObject. * The InputEvent#targetObject provides the GraphObject that was found * at the mouse point before looking up the visual tree of GraphObject#panels * to get to this object. * The function is called within the transaction performed by the DraggingTool, * so you do not need to conduct one. * By default this property is null. * * For an example of a mouseDrop event handler, see the node template in the * Org Chart Editor sample. * @see #mouseDragEnter * @see #mouseDragLeave * @see #mouseHold * @see Group#handlesDragDropForMembers */ get mouseDrop(): ((e: InputEvent, thisObj: GraphObject) => void) | null; set mouseDrop(value: ((e: InputEvent, thisObj: GraphObject) => void) | null); /** * Gets or sets the function to execute on a mouse-down event when this GraphObject's #isActionable * is set to true. * This property is infrequently set. * By default this property is null. * * This functional property is only set on objects such as buttons, knobs, or sliders that want to handle all events, * in conjunction with ActionTool, pre-empting the normal tool mechanisms. * * The ActionTool does not conduct any transaction, so if this property has a value, * the function will not be called within a transaction. * @see #actionMove * @see #actionUp * @see #actionCancel */ get actionDown(): ((e: InputEvent, thisObj: GraphObject) => void) | null; set actionDown(value: ((e: InputEvent, thisObj: GraphObject) => void) | null); /** * Gets or sets the function to execute on a mouse-move event when this GraphObject's #isActionable * is set to true. * This property is infrequently set. * By default this property is null. * * This functional property is only set on objects such as buttons, knobs, or sliders that want to handle all events, * in conjunction with ActionTool, pre-empting the normal tool mechanisms. * * The ActionTool does not conduct any transaction, so if this property has a value, * the function will not be called within a transaction. * @see #actionDown * @see #actionUp * @see #actionCancel */ get actionMove(): ((e: InputEvent, thisObj: GraphObject) => void) | null; set actionMove(value: ((e: InputEvent, thisObj: GraphObject) => void) | null); /** * Gets or sets the function to execute on a mouse-up event when this GraphObject's #isActionable * is set to true. * This property is infrequently set. * By default this property is null. * * This functional property is only set on objects such as buttons, knobs, or sliders that want to handle all events, * in conjunction with ActionTool, pre-empting the normal tool mechanisms. * * The ActionTool does not conduct any transaction, so if this property has a value, * the function will not be called within a transaction. * If you do provide a function that makes changes to the diagram or to its model, * you should do so within a transaction -- call Diagram#startTransaction and * Diagram#commitTransaction. * @see #actionDown * @see #actionMove * @see #actionCancel */ get actionUp(): ((e: InputEvent, thisObj: GraphObject) => void) | null; set actionUp(value: ((e: InputEvent, thisObj: GraphObject) => void) | null); /** * Gets or sets the function to execute when the ActionTool is cancelled and this GraphObject's #isActionable * is set to true. * This property is infrequently set. * By default this property is null. * * This functional property is only set on objects such as buttons, knobs, or sliders that want to handle all events, * in conjunction with ActionTool, pre-empting the normal tool mechanisms. * * The ActionTool does not conduct any transaction, so if this property has a value, * the function will not be called within a transaction. * @see #actionDown * @see #actionMove * @see #actionUp */ get actionCancel(): ((e: InputEvent, thisObj: GraphObject) => void) | null; set actionCancel(value: ((e: InputEvent, thisObj: GraphObject) => void) | null); /** * This Adornment or HTMLInfo is shown when the mouse hovers over this object. * The default value is null, which means no tooltip is shown. * * A typical tooltip is defined in the following manner, as taken from * the Kitten Monitor sample: * ```js * myDiagram.nodeTemplate = * $(go.Node, * . . . * { // this tooltip shows the name and picture of the kitten * toolTip: * $("ToolTip", * $(go.Panel, "Vertical", * $(go.Picture, * new go.Binding("source", "src", s => return "images/" + s + ".png")), * $(go.TextBlock, { margin: 3 }, * new go.Binding("text", "key")))) * }); * ``` * Note that this Adornment depends on having the same data binding as the adorned Part * (i.e. the same value for Panel#data). * * Tooltips are not copied by #copy, so that tooltips may be shared by all instances of a template. * * Tooltips are shown after a timed delay given by the ToolManager#hoverDelay. * You can change the delay time by: * ```js * myDiagram = new go.Diagram("myDiagramDiv", * { "toolManager.hoverDelay": 500 }); // 500 milliseconds * ``` * or: * ```js * myDiagram.toolManager.hoverDelay = 500; // 500 milliseconds * ``` * * Tooltips are normally positioned by ToolManager#positionToolTip. * However, if there is a Placeholder in the tooltip, the tooltip (i.e. an Adornment) * will be positioned so that the Placeholder is at the same position as this adorned GraphObject. * * Replacing this value will not modify or remove any existing tooltip that is being shown for this object. * * Read more about tooltips at ToolTips. */ get toolTip(): Adornment | HTMLInfo | null; set toolTip(value: Adornment | HTMLInfo | null); /** * This Adornment or HTMLInfo is shown upon a context click on this object. * The default value is null, which means no context menu is shown. * * Changing this value will not modify or remove any existing menu that is being shown for this object. * * Context menus may also depend on having the same data binding as the adorned Part * (i.e. the same value for Panel#data). * * Context menus are not copied by #copy, so that context menus may be shared by all instances of a template. * * A typical context menu is implemented as an Adornment with several buttons in it. * For example, this context menu is defined in the * Dynamic Port sample: * ```js * var nodeMenu = // context menu for each Node * $("ContextMenu", * $("ContextMenuButton", * $(go.TextBlock, "Add top port"), * { click: (e, obj) => addPort("top") }), * $("ContextMenuButton", * $(go.TextBlock, "Add left port"), * { click: (e, obj) => addPort("left") }), * $("ContextMenuButton", * $(go.TextBlock, "Add right port"), * { click: (e, obj) => addPort("right") }), * $("ContextMenuButton", * $(go.TextBlock, "Add bottom port"), * { click: (e, obj) => addPort("bottom") })); * ``` * and is used in the node template: * ```js * myDiagram.nodeTemplate = * $(go.Node, "Table", * { . . . * contextMenu: nodeMenu * }, * . . .); * ``` * * Context menus are normally positioned by ContextMenuTool#positionContextMenu. * However, if there is a Placeholder in the context menu, the context menu (i.e. an Adornment) * will be positioned so that the Placeholder is at the same position as this adorned GraphObject. * * The Basic sample also shows how * to make context menu items invisible when the command is disabled. * * Replacing this value will not modify or remove any existing context menu that is being shown for this object. * * Read more about context menus at Context Menus. */ get contextMenu(): Adornment | HTMLInfo | null; set contextMenu(value: Adornment | HTMLInfo | null); /** * Add a data-binding to this GraphObject for the given property names and optional conversion function. * * Do not add, modify, or remove any Bindings after this object has been copied. * * An example using `.bind` with the shorthand arguments: * * ```js * myDiagram.nodeTemplate = * new go.Node("Horizontal") * .bind("location", "loc") * // ... rest of Node template * ``` * * An example using both shorthand and a new go.Binding with `.bind`: * * ```js * new go.Shape({ * // ... shape properties * }) * // Shape.fill is bound to Node.data.color * .bind("fill", "color") * // Shape.stroke is red when Node.isHighlighted is true, black otherwise * .bind(new go.Binding("stroke", "isHighlighted", * h => return h ? "red" : "black").ofObject()) * ``` * * If you need to call Binding#makeTwoWay or Binding#ofObject, you will have to use a `new go.Binding()` as * the argument to this method. * * Read more about Bindings at the Introduction page about Data Bindings. * * @param {string=} targetprop A string naming the target property on the target object. * This should not be the empty string. * @param {string=} sourceprop A string naming the source property on the bound data object. * If this is the empty string, the whole Panel#data object is used. * If this argument is not supplied, the source property is assumed to be the same as the target property. * @param {TargetConversion} conv An optional side-effect-free function converting the data property value to the value to set the target property. * If the function is null or not supplied, no conversion takes place. * @param {BackConversion} backconv An optional conversion function to convert property values back to data values. * Specifying this modifies the binding to set its Binding#mode to be Binding.TwoWay. * If you want a two-way binding without a back-conversion function, call this method with the new Binding * argument instead, and call Binding#makeTwoWay on it: `.bind(new go.Binding(...).makeTwoWay())` * @return {GraphObject} this GraphObject * @since 2.2 */ bind(targetprop?: string, sourceprop?: string, conv?: TargetConversion, backconv?: BackConversion): this; /** * Add a data-binding of a property on this GraphObject to a property on a data object. * * Do not add, modify, or remove any Bindings after this object has been copied. * * An example using `.bind` with the Binding argument: * * ```js * myDiagram.nodeTemplate = * new go.Part("Horizontal") * .bind(new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify)) * // ... * ``` * * Read more about Bindings at the Introduction page about Data Bindings. * @param {Binding} binding * @return {GraphObject} this GraphObject */ bind(binding: Binding): this; /** * @undocumented */ bindTwoWay(targetprop: string | Binding, sourceprop?: string, conv?: TargetConversion, backconv?: BackConversion): this; /** * @undocumented */ bindObject(targetprop: string | Binding, sourceprop?: string, conv?: TargetConversion, backconv?: BackConversion, objectSrcname?: string): this; /** * @undocumented */ bindModel(targetprop: string | Binding, sourceprop?: string, conv?: TargetConversion, backconv?: BackConversion): this; /** * Set any number of properties on this GraphObject. This is common in initialization. * This method can only be used to set existing properties on this object. To attach new properties, * or to set properties of elements, use GraphObject#setProperties. * * This method uses TypeScript compile-time type checking, but does no runtime type checking. * If you need to set properties without type checking, or attach new properties, use GraphObject#attach. * * * ```js * // Common init for use in many different shapes: * var shapeStyle = (() => { return { background: 'red', strokeWidth: 0 }; }) * * // Constructor init is equivalent to "set" * // But if you use common init (eg, shapeStyle()) * // You may wish to set additional properties via "set" * new go.Shape(shapeStyle()) * .bind("fill", "color") * .bind("strokeWidth", "width") * .set({ // more init via set * figure: "RoundedRectangle" * }) * ``` * * @since 2.2 * @param {Partial} config * @return {GraphObject} this GraphObject * @see #setProperties */ set(config: Partial): this; /** * This method sets a collection of properties according to the property/value pairs on the given Object, or array of Objects, * in the same manner as GraphObject.make does when constructing a GraphObject. * * This method is used in initialization, but typically you should use #set instead, * unless you need to attach new properties that do not exist on the GraphObject, or to set sub-properties. * Calling this method is much less efficient than setting properties directly, and does not do compile-time type checking. * * ```js * new go.Shape() * .bind("fill", "color") * .bind("strokeWidth", "width") * .attach({ // use .attach for untyped property attachments * "_color": "Red" * }) * ``` * * @since 2.2 * @param {any} config a JavaScript object containing properties to attach, or an array of such objects. * @return {GraphObject} this GraphObject * @see #setProperties a synonym of this method * @see #set a type-safe method to set a collection of properties */ attach(config: any): this; /** * This method takes a function that can be used to apply multiple settings, bindings, * or Panel#add calls, to different GraphObjects. This is common in initialization. * If you are just adding settings, bindings, or GraphObjects to a single GraphObject, * you do not need to use this, you can just chain calls to #set, #bind, * and Panel#add instead. This method is mostly useful when setting the same values * across multiple GraphObjects. * * For example: * * ```js * // This can be used by several node templates * // to set multiple properties and bindings on each * function nodeStyle(node) { * node * .set({ background: 'red' }) * .bind("location") * .bind("desiredSize", "size", go.Size.parse) * } * * // ... in a Node template: * new go.Node("Auto") * .apply(nodeStyle) * .add(new go.Shape( ... )) * .add(new go.Panel( ... )) * // ...rest of Node template * * // ... in another Node template: * new go.Node("Vertical", { padding: 5 }) * .apply(nodeStyle) * // ...rest of Node template * ``` * * @since 2.2 * @param {((thisObject: this) => void)} func a function that takes this GraphObject * @return {GraphObject} this GraphObject * @see #set a type-safe method to set a collection of properties */ apply(func: ((thisObject: this) => void)): this; /** * This method sets a collection of properties according to the property/value pairs on the given Object, * in the same manner as GraphObject.make does when constructing a GraphObject with an argument that is a simple JavaScript Object. * * This method is common in initialization, but typically you should use #set instead, * unless you need to attach new properties, or set sub-properties. * Calling this method is much less efficient than setting properties directly, and does not do compile-time type checking. * * If this is a Panel, you can set properties on named elements within the panel by using a *name.property* syntax for the property name. * For example, if a Node has a Picture that is named "ICON" (because its #name property has been set to "ICON") * and a TextBlock whose name is "TB", one could set properties on the Node and on each of those named elements by: * ```js * aNode.setProperties({ * background: "red", * "ICON.source": "https://www.example.com/images/alert.jpg", * "TB.font": "bold 12pt sans-serif" * }); * ``` * * At the current time only a single dot is permitted in the property "name". * Note that the use of all-upper-case object names is simply a convention. * * @param {Object} props a plain JavaScript object with various property values to be set on this GraphObject. * @since 1.5 * @return {GraphObject} this GraphObject * @see #attach a synonym of this method * @see #set a type-safe method to set a collection of properties */ setProperties(props: ObjectData): this; /** * This static function creates an instance that was defined with GraphObject.defineBuilder. * Once this is called one can use the name as the first argument for GraphObject.make. * Names are case sensitive. * * The second is an optional settings configuration object, equivalent to calling GraphObject#set * on the new object. * * Predefined builder names include: `"Button"`, `"TreeExpanderButton"`, `"SubGraphExpanderButton"`, * `"PanelExpanderButton"`, and `"ContextMenuButton"`. * The implementation of these builders is provided by Buttons.js * in the Extensions directory. * * @param {string} name a capitalized name; must not be `""` or `"None"` * @param {Partial=} config a plain JavaScript object with various property values to be set on this GraphObject. * @param {...any} args If defined in the builder, the additional arguments that would be passed to GraphObject.takeBuilderArgument * @since 2.2 */ static build(name: string, config?: Partial, ...args: Array): T; /** * (undocumented) * This never-documented method has been renamed #findBindingPanel for v2.2 and will be removed in v3.0. * @return {Panel} */ findTemplateBinder(): Panel | null; /** * Walks up the visual tree and returns the first Panel whose Panel.data is bound to data. * This can be useful when you need to inspect Panel#data objects. * @since 2.2 * @return {Panel} */ findBindingPanel(): Panel | null; /** * Adds an AnimationTrigger to this GraphObject. * @since 2.2 * @param {AnimationTrigger} trigger an AnimationTrigger * @return {Panel} */ trigger(trigger: AnimationTrigger): this; /** * This static function builds an object given its class and additional arguments * providing initial properties or GraphObjects that become Panel elements. * * The first argument must be the class type or the name of a class or the name of a predefined kind of Panel. * This function will construct a new instance of that type and use the rest of the arguments to initialize the object. * The first argument cannot be a regular Object (such as a GraphObject) that you are trying to initialize; * for that you can call #setProperties or Diagram#setProperties, although that would * be less efficient than setting properties directly. * * If an initializer argument is an enumerated value, this tries to set the property that seems most appropriate. * * If an initializer argument is a string, this sets a particular property depending on the type of object being built. * - If the object is a TextBlock, it sets TextBlock#text. * - If the object is a Shape, it sets Shape#figure. * - If the object is a Picture, it sets Picture#source. * - If the object is a Panel (including Part, Node, or Group), it sets Panel#type. * * If an initializer argument is a particular kind of object, this can add that object to the object being built. * - GraphObjects and RowColumnDefinitions can only be added as elements of Panels. * - Bindings can only be applied to GraphObjects and RowColumnDefinitions. * - PathFigures can only be added to Geometry objects. * - PathSegments can only be added to PathFigure objects. * - Regular JavaScript Arrays provide a sequence of initializer arguments. * - Regular JavaScript objects provide property/value pairs that are set on the object being built. * * When the initializer argument is a plain JavaScript Object, there are several ways that that object's properties are applied. * If the property name is a string with a period inside it, this has a special meaning if the object is a Panel or a Diagram. * At the current time only a single period separator is valid syntax for a property string, and it is valid only on Panels and Diagrams. * * For Panels, the substring before the period is used as the name passed to Panel#findObject * to get the actual object on which to set the property, which is the substring after the period. * This is normally useful only on the predefined Panels: * - a **"Button"** has a Shape named "ButtonBorder" surrounding the content of the Panel. * - a **"TreeExpanderButton"** has a "ButtonBorder" Shape and a "ButtonIcon" Shape that is the plus-or-minus sign. * - a **"SubGraphExpanderButton"** has a "ButtonBorder" Shape and a "ButtonIcon" Shape that is the plus-or-minus sign. * - a **"ContextMenuButton"** has a Shape named "ButtonBorder" surrounding the content of the Panel. * * But you can define your own names that GraphObject.make can build by calling the static function GraphObject.defineBuilder. * * For Diagrams, the substring before the period is used as the name of a property on the Diagram itself * to get the actual object on which to set the property. * As a special case, if such a property value does not exist on the Diagram, it looks on the Diagram#toolManager. * See some examples below. * * Also for Diagrams, and only for Diagrams, if the property name is the name of a DiagramEvent, * the property value must be a DiagramEvent listener function, and Diagram#addDiagramListener is called * using that DiagramEvent name and that function. * Note that all DiagramEvent names are capitalized and do not contain any periods, * so there cannot be any name conflicts with any properties on Diagram or ToolManager. * Although you can register multiple listeners for the same DiagramEvent names, due to JavaScript limitations * those need to be declared using separate JavaScript objects, because JavaScript does not permit duplicate property names * in an Object literal. * * Furthermore for Diagrams, if the property name is `"Changed"` or `"ModelChanged"`, * the property value must be a ChangedEvent listener function, which is called with a ChangedEvent argument. * When the property name is `"Changed"`, it calls Diagram#addChangedListener, * notifying about changes to the Diagram or its Layers or GraphObjects. * When the property name is `"ModelChanged"`, it calls Model#addChangedListener on the Diagram#model, * resulting in notifications about changes to the Model or its data. * This is handy because the Diagram#model property setter will automatically call * Model#removeChangedListener on the old model, thereby avoiding any overhead if there are any * more changes to the old model and also avoiding a reference to the listener which might cause garbage collection retention. * It also will call Model#addChangedListener on the new model, helping implement the same behavior with the new model. * * If the property name is a number and if the object being constructed is a Brush, * the number and value are added to the Brush by calling Brush#addColorStop. * * Otherwise the property name is used as a regular property name on the object being built. * This tries to do some property name and value checking: * when a property is not defined on the object being built, it will signal an error. * Many typos can be found this way that would be ignored by JavaScript code. * * If the property name begins with an underscore, this will not complain about the property being undefined. * Not only is that underscore property set on the object being built, but calls to #copy * will also copy the values of such named properties to the new objects. * * In the samples and in the intro pages this function is called using the alias `$`. * You can use a different short name if you would like to preserve the use of `$` for another JavaScript library. * ```js * var $ = go.GraphObject.make; * * var diagram = * $(go.Diagram, "myDiagramDiv", * { * // don't initialize some properties until after a new model has been loaded * "InitialLayoutCompleted": loadDiagramProperties, * allowZoom: false, // don't allow the user to change the diagram's scale * "grid.visible": true, // display a background grid for the whole diagram * "grid.gridCellSize": new go.Size(20, 20), * // allow double-click in background to create a new node * "clickCreatingTool.archetypeNodeData": { text: "Node" }, * // allow Ctrl-G to call the groupSelection command * "commandHandler.archetypeGroupData": * { text: "Group", isGroup: true, color: "blue" }, * "toolManager.hoverDelay": 100, // how quickly tooltips are shown * // mouse wheel zooms instead of scrolls * "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom, * "commandHandler.copiesTree": true, // for the copy command * "commandHandler.deletesTree": true, // for the delete command * "draggingTool.dragsTree": true, // dragging for both move and copy * "draggingTool.isGridSnapEnabled": true, * layout: $(go.TreeLayout, * { angle: 90, sorting: go.TreeLayout.SortingAscending }) * }); * * diagram.nodeTemplate = * $(go.Node, "Auto", // or go.Panel.Auto * new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), * $(go.Shape, "RoundedRectangle", * { * fill: $(go.Brush, "Linear", { 0: "#FEC901", 1: "#FEA200" }), * stroke: "gray", * strokeWidth: 2, * strokeDashArray: [3, 3] * }), * $(go.TextBlock, * { margin: 5, font: "bold 12pt sans-serif" }, * new go.Binding("text", "key")) * ); * ``` *

* See the Introduction page on building objects * for usage information and examples of GraphObject.make. * @param {Function|string} type a class function or the name of a class in the `go` namespace, * or one of several predefined kinds of Panels: `"Button"`, `"TreeExpanderButton"`, * `"SubGraphExpanderButton"`, or `"ContextMenuButton"`. * @param {...*} initializers zero or more values that initialize the new object, * typically an Object with properties whose values are set on the new object, * or a JavaScript Array with additional initializer arguments, * or a GraphObject that is added to a Panel, * or a Binding for one of the new object's properties, * or a constant value as the initial value of a single property of the new object that * is recognized to take that value, * or a string that is used as the value of a commonly set property. * @return {Object} */ static make(// for specific named builders cls: ('ToolTip' | 'ContextMenu'), ...initializers: Array & { [p: string]: any; }) | Binding | AnimationTrigger | EnumValue | RowColumnDefinition | PanelLayout | Array & { [p: string]: any; }) | Binding | AnimationTrigger | EnumValue | RowColumnDefinition | PanelLayout>>): T; static make(// for specific named Panel builders cls: ('Button' | 'TreeExpanderButton' | 'SubGraphExpanderButton' | 'ContextMenuButton' | 'PanelExpanderButton' | 'CheckBoxButton' | 'CheckBox'), ...initializers: Array & { [p: string]: any; }) | Binding | AnimationTrigger | EnumValue | RowColumnDefinition | PanelLayout | Array & { [p: string]: any; }) | Binding | AnimationTrigger | EnumValue | RowColumnDefinition | PanelLayout>>): T; static make(cls: string, // for named Panel builders ...initializers: Array & { [p: string]: any; }) | Binding | AnimationTrigger | EnumValue | RowColumnDefinition | PanelLayout | Array & { [p: string]: any; }) | Binding | AnimationTrigger | EnumValue | RowColumnDefinition | PanelLayout>>): T; static make>(cls: CT, ...initializers: Array> & { [p: string]: any; } & (InstanceType extends Diagram ? DiagramEventsInterface & { Changed?: ChangedEventHandler; ModelChanged?: ChangedEventHandler; } : unknown)) | MakeAllow | MakeAllow | MakeAllow | MakeAllow | MakeAllow | MakeAllow | MakeAllow | MakeAllow | EnumValue | HTMLDivElement | Array> & { [p: string]: any; } & (InstanceType extends Diagram ? DiagramEventsInterface & { Changed?: ChangedEventHandler; ModelChanged?: ChangedEventHandler; } : unknown)) | MakeAllow | MakeAllow | MakeAllow | MakeAllow | MakeAllow | MakeAllow | MakeAllow | MakeAllow | EnumValue>>): InstanceType; /** * This static function defines a named function that GraphObject.make or GraphObject.build can use to build objects. * Once this is called one can use the name as the first argument for GraphObject.make or GraphObject.build. * Names are case sensitive. * * The second argument must be a function that returns a newly created object, typically a GraphObject. * It is commonplace for that object to be a Panel holding a newly created visual tree of GraphObjects. * The function receives as its only argument an Array that is holds all of the arguments that are being * passed to GraphObject.make, which it may modify in order to change the arguments that GraphObject.make receives. * * Predefined builder names include: `"Button"`, `"TreeExpanderButton"`, `"SubGraphExpanderButton"`, * `"PanelExpanderButton"`, and `"ContextMenuButton"`. * The implementation of these builders is provided by Buttons.js * in the Extensions directory. * @param {string} name a capitalized name; must not be `""` or `"None"` * @param {function(Array.<*>):Object} func that takes an Array of `GraphObject.make` arguments and returns a new object * @since 1.5 */ static defineBuilder(name: string, func: ((a: Array) => ObjectData)): void; /** * This static function returns the first argument from the arguments array passed * to a GraphObject.defineBuilder function by GraphObject.make. * By default this requires the first argument to be a string, * but you can provide a predicate to determine whether the argument is suitable. * @param {Array.<*>} args the arguments Array passed to the builder function; * this may be modified if an acceptable argument is found and returned * @param {*=} defval the default value to return if the argument is optional and not present as the first argument; * otherwise throw an error when the argument is not there * @param {function(*):boolean|null=} pred a predicate to determine the acceptability of the argument; * the default predicate checks whether the argument is a string * @return {*} * @since 1.5 */ static takeBuilderArgument(args: Array, defval?: any, pred?: ((a: any) => boolean) | null): any; } /** * @unrestricted */ export class SGradient { /** * @param {string} aType */ constructor(aType: string); } /** * The BrushLike type is the same as `Brush | string | null`. * A string in place of a Brush object is treated as a Solid Brush of that color. * @category Type */ export type BrushLike = Brush | string | null; /** * A Brush holds color information and describes how to draw the inside * of a Shape or the stroke of a shape or a TextBlock or the * background of any GraphObject. * * A Brush must not be modified once it has been assigned to a GraphObject, * such as the Shape#fill or TextBlock#stroke * or GraphObject#background. * However, a Brush may be shared by multiple GraphObjects. * @unrestricted * @category Geometry */ export class Brush { /** * Construct a Brush class that holds the given color information. * @param {EnumValue|string=} type Optional, one of the values Brush.Solid, Brush.Linear, Brush.Radial, Brush.Pattern, * or a well-formed CSS string describing a solid color brush. No parameter * defaults to a Brush.Solid with a color description of 'black'. * @param {Partial=} init Optional initialization properties. */ constructor(type?: EnumValue | string, init?: Partial); /** * Create a copy of this Brush with the same values. * @return {Brush} */ copy(): Brush; /** * Specify a particular color at a particular fraction of the distance. * If the #type is Brush.Solid, change the type to Brush.Linear. * You should not have duplicate color stop values at the same fractional distance. * @param {number} loc A number between 0 and 1 (inclusive). * @param {string} color A valid CSS color string. * @return {Brush} this Brush */ addColorStop(loc: number, color: string): Brush; /** * Gets or sets the type of brush. * The default value is Brush.Solid. * The value must be one of: Brush.Solid, Brush.Linear, Brush.Radial, Brush.Pattern. * If the new value is a linear or radial brush type, * and if the #start or #end spots are not specific spots, * they are changed to be specific spots, depending on the type of brush. */ get type(): EnumValue; set type(value: EnumValue); /** * Gets or sets the color of a solid Brush. * The default value is 'black'. * The value must be a valid CSS color string. */ get color(): string; set color(value: string); /** * Gets or sets the starting location for a linear or radial gradient. * A Spot value specifies a relative point in the object's GraphObject#naturalBounds. * The default value is Spot.TopCenter for linear gradients and Spot.Center for radial gradients. */ get start(): Spot; set start(value: Spot); /** * Gets or sets the ending location for a linear or radial gradient. * A Spot value specifies a relative point in the object's GraphObject#naturalBounds. * The default value is Spot.BottomCenter for linear gradients and Spot.Center for radial gradients. */ get end(): Spot; set end(value: Spot); /** * Gets or sets the radius of a radial brush at the start location. * The default value is 0. */ get startRadius(): number; set startRadius(value: number); /** * Gets or sets the radius of a radial brush at the end location. * The default value is NaN. */ get endRadius(): number; set endRadius(value: number); /** * Gets or sets a Map holding all of the color stops used in this gradient, * where the key is a number, the fractional distance between 0 and 1 (inclusive), * and where the corresponding value is a color string. * * Call #addColorStop in order to add color stops to this brush. * This property value may be null if no gradient stops have been defined. */ get colorStops(): Map | null; set colorStops(value: Map | null); /** * Gets or sets the pattern of a brush of type Brush.Pattern. */ get pattern(): HTMLCanvasElement | HTMLImageElement | null; set pattern(value: HTMLCanvasElement | HTMLImageElement | null); /** * This static function can be used to generate a random color. * @param {number=} min A number between 0 and 255, defaults to 128. * @param {number=} max A number between 0 and 255, defaults to 255. * @return {string} A color value in # hexadecimal format. */ static randomColor(min?: number, max?: number): string; /** * This static function returns true if a given color string is well-formed for drawing. * @param {string} color A color string to validate. * @return {boolean} * @since 1.7 */ static isValidColor(color: string): boolean; /** * This static function takes a color and lightens it by 20% in the Lab color space. * This is a convenience function which calls Brush.lightenBy. * @param {string} color A valid CSS color string. * @return {string} A CSS string for the lightened color in RGBA. * @since 1.7 */ static lighten(color: string): string; /** * Modifies all colors within this Brush, lightening them by some fraction. * @param {number=} fraction Fraction to lighten the colors by. Defaults to 0.2, must be between 0 and 1 (inclusive). * @param {EnumValue=} mode Color space to use for adjusting. Must be Brush.Lab or Brush.HSL, defaults to Brush.Lab. * @return {Brush} This Brush with modified color values. * @since 1.7 */ lightenBy(fraction?: number, mode?: EnumValue): Brush; /** * This static function takes a color and lightens it. * @param {string} color A valid CSS color string. * @param {number=} fraction Fraction to lighten the colors by. Defaults to 0.2, must be between 0 and 1 (inclusive). * @param {EnumValue=} mode Color space to use for adjusting. Must be Brush.Lab or Brush.HSL, defaults to Brush.Lab. * @return {string} A CSS string for the lightened color in RGBA or HSLA. * @since 1.7 */ static lightenBy(color: string, fraction?: number, mode?: EnumValue): string; /** * This static function takes a color and darkens it by 20% in the Lab color space. * This is a convenience function which calls Brush.darkenBy. * @param {string} color A valid CSS color string. * @return {string} A CSS string for the darkened color in RGBA. * @since 1.7 */ static darken(color: string): string; /** * Modifies all colors within this Brush, darkening them by some fraction. * @param {number=} fraction Fraction to darken the colors by. Defaults to 0.2, must be between 0 and 1 (inclusive). * @param {EnumValue=} mode Color space to use for adjusting. Must be Brush.Lab or Brush.HSL, defaults to Brush.Lab. * @return {Brush} This Brush with modified color values. * @since 1.7 */ darkenBy(fraction?: number, mode?: EnumValue): Brush; /** * This static function takes a color and darkens it. * @param {string} color A valid CSS color string * @param {number=} fraction Fraction to darken the color by. Defaults to 0.2, must be between 0 and 1 (inclusive). * @param {EnumValue=} mode Color space to use for adjusting. Must be Brush.Lab or Brush.HSL, defaults to Brush.Lab. * @return {string} A CSS string for the darkened color in RGBA or HSLA. * @since 1.7 */ static darkenBy(color: string, fraction?: number, mode?: EnumValue): string; /** * This static function takes two colors and mixes them together, using the (optionally) specified amount of the second color. * @param {string} color1 A valid CSS color string. * @param {string} color2 Another valid CSS color string to mix. * @param {number=} fraction Fraction specifying how much color2 to mix into color1. Defaults to .5, must be between 0 and 1 (inclusive). * @return {boolean} * @since 2.0 */ static mix(color1: string, color2: string, fraction?: number): string; /** * This function determines whether this Brush is "dark." * @return {boolean} * @since 2.0 */ isDark(): boolean; /** * This static function takes a color and determines whether it is "dark." Does not account for transparency. * * Example usage: * ```js * myDiagram.nodeTemplate = * $(go.Node, "Auto", * $(go.Shape, "RoundedRectangle", { strokeWidth: 0 }, * new go.Binding("fill", "color")), * $(go.TextBlock, * { margin: 8 }, * new go.Binding("stroke", "color", function (c) { * // Dark nodes use white text, light nodes use black text * return go.Brush.isDark(c) ? "white" : "black"; * }), * new go.Binding("text", "key") * ) * ); * ``` * @param {Brush|string} color A valid CSS color string or a Brush. * @return {boolean} * @since 2.0 */ static isDark(color: BrushLike): boolean; /** * For simple, solid color brushes, used as the value for Brush#type. * @constant */ static Solid: EnumValue; /** * For linear gradient brushes, used as the value for Brush#type. * @constant */ static Linear: EnumValue; /** * For radial gradient brushes, used as the value for Brush#type. * @constant */ static Radial: EnumValue; /** * For pattern brushes, used as the value for Brush#type. * @constant */ static Pattern: EnumValue; /** * For lightening and darkening, used as a color-space value. * @constant */ static Lab: EnumValue; /** * For lightening and darkening, used as a color-space value. * @constant */ static HSL: EnumValue; } /** * This is the abstract base class for all Panel Layouts, which inform the possible Panel types. * It is possible to create your own Panel type by creating a subclass of PanelLayout, * though this is not common and not recommended for beginners. * * By default, GoJS has 12 Panel types, each corresponding to a PanelLayout subclass: * - 'Position', `PanelLayoutPosition` * - 'Horizontal', `PanelLayoutHorizontal` * - 'Vertical', `PanelLayoutVertical` * - 'Spot', `PanelLayoutSpot` * - 'Auto', `PanelLayoutAuto` * - 'Table', `PanelLayoutTable` * - 'Viewbox', `PanelLayoutViewbox` * - 'TableRow', `PanelLayoutTableRow` * - 'TableColumn', `PanelLayoutTableColumn` * - 'Link', `PanelLayoutLink` * - 'Grid', `PanelLayoutGrid` * - 'Graduated', `PanelLayoutGraduated` * * None of these predefined panel layout classes have their own documentation pages. * * These panel layouts are included by default in builds of `go.js` and `go-module.js` and their respective debug versions. * When building from source, you can optionally exclude all of them except `Position`, * `Vertical`, `Auto`, `Link`, and `Grid`. * This is demonstrated in `minimalSource` and `maximalSource`, in the `/projects` folder. * * Registering a new PanelLayout is done by calling the static function, Panel.definePanelLayout: * * ```js * Panel.definePanelLayout('Table', new PanelLayoutCustom()); * ``` * * Each PanelLayout must define a #measure and #arrange method. * The measure method must call #measureElement with each element of the Panel, * which sets each element's GraphObject#measuredBounds. These bounds can be used to determine object layout. * The arrange method must call #arrangeElement with each element of the Panel to position the objects relative to the Panel. * Remember that each Panel defines its own coordinate system, which is used for sizing and positioning of the panel's elements. * * An instance of a PanelLayout is shared by all copies of a Panel that uses it. * * There is an example PanelLayout in the PanelLayout sample. * There is a Flow PanelLayout extension at #PanelLayoutFlow, demonstrated at * Flow PanelLayout sample. * @since 2.0 * @unrestricted */ export abstract class PanelLayout { /** * Gets or sets the name of this instance of a particular panel layout. */ get name(): string; set name(value: string); /** * This class is abstract. Define your own subclass if you want to implement a custom panel layout. */ constructor(); /** * (undocumented) */ get classType(): Function; /** * Given the available size, measure the Panel and * determine its expected drawing size. * * This must call #measureElement with each Panel element, which will set the * GraphObject#measuredBounds of those elements. Depending on how the Panel intends to lay out its elements, * the programmer must construction the `union` by setting `union.width` and `union.height` of the supplied argument. * For example PanelLayoutHorizontal measures its elements and sums their widths to set its `union.width`, * and takes the maximum of their heights to set its `union.height`. * * This union must reflect the measured size of the Panel. After measure is called, the Panel class will modify this union Rect, * constraining its size by the Panel's GraphObject#desiredSize, GraphObject#minSize, and GraphObject#maxSize, * before passing it to #arrange. * * @expose * @param {Panel} panel Panel which called this layout * @param {number} width expected width of the Panel, informed by any containing Panel and by the Panel's own * GraphObject#desiredSize, GraphObject#minSize, and GraphObject#maxSize. * Often Infinity. * @param {number} height expected height of the Panel. * @param {Array.} elements Array of Panel elements * @param {Rect} union rectangle to be modified to contain the expected union bounds of every element in the Panel, * to be potentially used in #arrange. * @param {number} minw expected minimum width of the Panel, informed by any containing Panel. Often zero. * @param {number} minh expected minimum height of the Panel. */ measure(panel: Panel, width: number, height: number, elements: Array, union: Rect, minw: number, minh: number): void; /** * Given the available size, measure one element of the Panel and * determine its expected drawing size. This sets the GraphObject#measuredBounds of the object, * which can then be used to determine the arrangement of objects in the PanelLayout. * * @param {GraphObject} obj Panel which called this layout * @param {number} width expected width of the GraphObject * @param {number} height expected height of the GraphObject * @param {number} minw minimum width of the GraphObject * @param {number} minh minimum height of the GraphObject */ protected measureElement(obj: GraphObject, width: number, height: number, minw: number, minh: number): void; /** * After measuring, a Panel must arrange each element, giving the elements a position and size in the Panel's coordinate system. * This must call #arrangeElement with each Panel element, which will set that element's GraphObject#actualBounds. * * For arranging some elements, it is useful to know the total unioned area of every element, which is given as the `union` argument. * This Rect can be used to right-align or center-align, etc, elements within an area. * * For example, PanelLayoutHorizontal arranges each element sequentially, starting with an `x` value of `0`, * and increasing it by each previous element's GraphObject#measuredBounds `width`. * The horizontal Panel arranges each element with a `y` value determined by the `union` argument's `height` * considering the GraphObject#alignment of the element, and the GraphObject's own `measuredBounds.height`. * * * @expose * @param {Panel} panel Panel which called this layout * @param {Array.} elements Array of Panel elements * @param {Rect} union rectangle, if properly constructed in #measure, that contains the expected union bounds of every element in the Panel. */ arrange(panel: Panel, elements: Array, union: Rect): void; /** * Arranges the GraphObject onto its parent Panel. * The passed-in numbers typically account for GraphObject#margin and other offsets. * The `x` and `y` coordinates are where GraphObjects will be placed within the Panel's own coordinates * (from the Panel's top-left corner). The `width` and `height` are the size it will take up within the Panel's coordinates. * * This sets the GraphObject#actualBounds of the `obj`. * * @param {GraphObject} obj GraphObject to be arranged. * @param {number} x The final x value of actualBounds that the Panel computes for the GraphObject. * @param {number} y The final y value of actualBounds that the Panel computes for the GraphObject. * @param {number} width The final width value of actualBounds that the Panel computes for the GraphObject. * @param {number} height The final height value of actualBounds that the Panel computes for the GraphObject. * @param {Rect=} clipRect an optional area to constrain this actualBounds to when picking and drawing. * By default, this is only used with Table Panel elements, which are clipped to their cell sizes. */ protected arrangeElement(obj: GraphObject, x: number, y: number, width: number, height: number, clipRect?: Rect): void; /** * Uncommon: Force a given GraphObject to remeasure in the near future. * If a PanelLayout is not just measuring elements, but must also modify some of its elements, * this must be called on those elements before modifications are made. * This prevents the elements from potentially remeasuring * the entire visual tree, which would cause an infinite loop. * * Normally, panels do not modify the dimensions of their elements. In other words, a Panel * would not normally set a property like GraphObject#desiredSize or TextBlock#text * or Shape#geometry on any of its elements. Some custom panels may wish to do this, * especially if the programmer knows it will not affect the size of any containing Panel. * * Calling this method before changing a property preempts the remeasuring of any containing Panels, * ensuring only the GraphObject and its own child elements will be remeasured. * * This is used in PanelLayout "Viewbox" on its one element. * It modifies that element's GraphObject#scale and is certain that will not * affect Panels up the visual tree. * @since 2.2 * @param {GraphObject} obj GraphObject to be invalidated. */ remeasureObject(obj: GraphObject): void; } /** * A Panel is a GraphObject that holds other GraphObjects as its elements. * A Panel is responsible for sizing and positioning its elements. * The elements of a panel are drawn in the order in which they appear in the #elements collection. * * The Part class inherits from Panel; Part in turn is the base class of Node and Link. * * Every Panel has a #type and establishes its own coordinate system. The type of a Panel * determines how it will size and arrange its elements: * - Panel.Position is used to arrange elements based on their absolute positions within the Panel's local coordinate system. * - Panel.Vertical and Panel.Horizontal are used to create linear "stacks" of elements. * - Panel.Auto is used to size the main element to fit around other elements in the Panel -- this creates borders. * - Panel.Spot is used to arrange elements based on the Spot properties GraphObject#alignment * and GraphObject#alignmentFocus, relative to a main element of the panel. * Spot panels can align relative to other elements by using Panel#alignmentFocusName. * - Panel.Table is used to arrange elements into rows and columns, typically employing the different * elements' GraphObject#row, GraphObject#rowSpan, GraphObject#column, * and GraphObject#columnSpan properties. This Panel type also makes use of RowColumnDefinition. * - Panel.TableRow and Panel.TableColumn can only be used immediately within a Panel.Table Panel * to organize a collection of elements as a row or as a column in a table. * - Panel.Viewbox is used to automatically resize a single element to fit inside the panel's available area. * - Panel.Grid is not used to house typical elements, but is used only to draw regular patterns of lines. * The elements must be Shapes used to describe the repeating lines. * - Panel.Link is only used by Link parts and Link Adornments. * - Panel.Graduated is used to draw regular tick marks and text along the main Shape element. * * Using GraphObject.make, the second argument can be used to declare the Panel type. * The second argument may also be an instance of PanelLayout, if you want to use a custom panel layout. * ```js * // Either: * new go.Panel(go.Panel.Horizontal, ... * // Or: * new go.Panel("Horizontal", ... * * // Full example: * p = new go.Panel("Horizontal", * { width: 60, height: 60 }) // panel properties * // elements in the panel: * .add(new go.Shape("Rectangle", { stroke: "lime" })) * .add(new go.TextBlock("Some Text")) * ``` * *

* For an overview of most Panel types, please read the Introduction page on Panels. * * Panel.Vertical and Panel.Horizontal panels are frequently used to position two or more GraphObjects * vertically above each other or horizontally next to each other. Use the GraphObject#alignment or * GraphObject#stretch properties on the individual elements to control their position and size. * Set #isOpposite to true if you want the elements arranged from right-to-left in Horizontal Panels * or from bottom-to-top in Vertical Panels. * * Panel.Spot and Panel.Auto panels have a "main" element, signified by the Panel's first element * with GraphObject#isPanelMain set to true. If there is no such element, it uses the first element as the "main" one. * Use the GraphObject#alignment property to position elements with respect to the main element. * Use the GraphObject#alignmentFocus property to further specify the position within Spot Panels. * "Spot" and "Auto" Panels should have two or more elements in them. * * In Panel.Table panels you will want to set the GraphObject#row and GraphObject#column * properties on each element. The GraphObject#alignment and GraphObject#stretch properties are also * useful when an element's table cell is larger than that element. *

Please read the Introduction page on Table Panels * for more examples and explanation. * * Panel.TableRow and Panel.TableColumn panels can only be used as elements within a Panel.Table Panel. * They are typically only used in item templates, e.g. for automatically creating rows in a Table Panel based on model data * provided in an #itemArray. You will still need to specify properties on the individual elements within a TableRow * or TableColumn as if they were immediate elements of the containing Table panel. *

For an example that uses TableRow Panels, see Records sample. * * Panel.Grid panels are often used for the Diagram's Diagram#grid. * ```js * const diagram = new go.Diagram("myDiagramDiv", * // Diagram options: * { . . . * grid: new go.Panel("Grid", * { gridCellSize: new go.Size(40, 40) }) * .add(new go.Shape("LineH", { stroke: "lightgray" })) * .add(new go.Shape("LineV", { stroke: "lightgray" })), * . . . * }); * ``` * Or to get a green bar effect: * ```js * const diagram = new go.Diagram("myDiagramDiv", * { . . . * grid: new go.Panel("Grid", * { gridCellSize: new go.Size(100, 100) }) * .add(new go.Shape("BarH", { fill: "lightgreen", height: 50 })), * . . . * }); * ``` * But Grid Panels can also be stand alone objects: * ```js * new go.Node("Grid", * { gridCellSize: new go.Size(6, 6), width: 60, height: 60 }) * .add(new go.Shape("LineH", { stroke: "gray" })) * .add(new go.Shape("LineV", { stroke: "gray" })) * ``` * * A Grid Panel's elements do not participate in object picking. *

Please read the Introduction page on Grid Patterns * for more examples and explanation. * * Panel.Graduated panels, like Spot and Auto Panels have a "main" element. The other elements within a Graduated Panel * are used to define ticks and labels to draw along the main shape's path. * ```js * new go.Part("Graduated") * .add(new go.Shape({ geometryString: "M0 0 H400" })) * .add(new go.Shape({ geometryString: "M0 0 V10" })) * // offset to display below ticks * .add(new go.TextBlock({ segmentOffset: new go.Point(0, 12) })); * ``` * * Only the main shape of a Graduated Panel participates in object picking, but a `background` * can be set if the entire panel needs to be pickable. * You cannot set or bind the Panel#itemArray of a Graduated Panel. * Events on the tick Shapes and TextBlock labels of a Graduated Panel will be ignored. * Graduated Panel TextBlock labels cannot be edited. * * Rotating the main shape will not rotate the ticks, just as rotating a Spot Panel's main element * won't rotate its children. Rotation should generally be done at the Panel level. Another similarity * to Spot Panels is that resizing of a Graduated Panel should generally be done on the main shape. *

Please read the Introduction page on Graduated Panels * for more examples and explanation. * *

Changing and accessing elements of a Panel

* * You can change the collection of #elements by calling #add, #insertAt, #remove, or #removeAt. * You can get direct access to a particular element by calling #elt. * * Alternatively you can control the number and order of elements that are copies of an item template by setting or binding the * #itemArray property. This is discussed below. * * You can search the visual tree of a Panel for GraphObjects that given a GraphObject#name using #findObject. * *

Panel Size and Appearance

* * Panels typically compute their own size based on their elements and Panel #type, * but can also be sized by setting GraphObject#desiredSize, GraphObject#minSize, and GraphObject#maxSize. * Setting an explicit size on a Panel may cause nested elements of that panel to size themselves differently, * especially in the cases of nested elements having a GraphObject#stretch value or TextBlock's having word wrap. * * Panels have no visual components of their own unless a GraphObject#background is specified * or separators are specified either as defaults for the whole Table Panel or on individual RowColumnDefinitions. * Panels can specify #padding, to make the Panel larger including its background. Setting a padding * when the Panel is constrained in size will reduce the total area that it has to arrange its elements. Setting a #margin * will not do this -- instead the Panel will expand in size. * * In addition to the GraphObject properties on elements that are only used by certain types of panels, * several Panel properties only apply to specific Panel types. * - Panels of #type Panel.Table use the #rowCount, #rowSizing, #columnCount, * #columnSizing, #leftIndex, #topIndex, and all of the "default" separator properties. * - Panels of #type Panel.TableRow and Panel.TableColumn do not act like regular GraphObjects, * instead they are only to be used immediately within a Panel.Table. They are pass-through containers * that hold elements for their parent table, and ignore their own scale and angle. * - Panels of #type Panel.Grid use the #gridCellSize and #gridOrigin properties. * - Panels of #type Panel.Viewbox use the #viewboxStretch property. * - Panels of #type Panel.Graduated use the #graduatedMin, #graduatedMax, * #graduatedTickUnit, and #graduatedTickBase properties. * *

* For live examples of all Panel types, see the Introduction page on Panels. * *

Data Binding

* * Panels also provide fundamental support for data binding. * When a diagram gets a new model or when a diagram's model is augmented with additional data, * the diagram automatically creates a new Node or Link whose #data property refers to the corresponding * node data or link data object. *

* For more discussion of data binding, please read the Introduction page on Models * and Data Binding. * * Panels provide support for automatically creating elements within the Panel based on items in a JavaScript Array. * This is achieved by setting or binding the #itemArray property, which acts in a manner similar * to the Model#nodeDataArray property. * You can supply an #itemTemplate, which must itself be a simple Panel, which is copied to create the element * in this container Panel corresponding to an item in the itemArray. * This property is analogous to the Diagram#nodeTemplate property, although for the diagram the * template must be a Node, Group, or simple Part. * * Much like the Diagram#nodeTemplateMap, Panel's #itemTemplateMap supports having multiple templates, * so that the actual structure of the element created for a data item can be chosen dynamically. * Just as the Model#nodeCategoryProperty determines which template in the Diagram#nodeTemplateMap * is copied to create a Node, the #itemCategoryProperty names the data property whose value * chooses the Panel in the itemTemplateMap to copy for the item. * * When binding the #itemArray property, it is commonplace to set Model#copiesArrays and * Model#copiesArrayObjects properties to true, so that when a node is copied, the item Array and its * contents are copied, not shared. Or more generally, to customize the model's copying processes, you * can supply a custom Model#copyNodeDataFunction. *

* For more discussion and examples of item arrays, please read the Introduction page on Item Arrays. * @extends GraphObject * @unrestricted */ export class Panel extends GraphObject { /** * Constructs an empty Panel of the given #type. Default type is Panel.Position. * The panel type must be one of the enumerated values defined on the Panel class, including: * Panel.Position, Panel.Vertical, Panel.Horizontal, Panel.Table, * Panel.Auto, Panel.Spot, or Panel.Viewbox. The string value such as "Auto" may also be used. * * Usage example: * *```js * const p = new go.Panel("Auto", { * margin: 5, * background: "red" * }); * ``` * * @param {string=} type Panel Type as either a string or PanelLayout. such as "Vertical", "Auto", or Panel.Vertical, Panel.Auto, are accepted. * If not supplied, the default Panel type is "Position". * @param {Partial=} init Optional initialization properties. */ constructor(type?: PanelLayout | string, init?: Partial); /** * Constructs an empty Panel. Default type is Panel.Position. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * Creates a deep copy of this Panel and returns it. * @return {Panel} */ copy(): this; /** * Gets or sets the type of the Panel, which controls how the Panel's elements are measured and arranged. * The value must be an instance of PanelLayout. * The only predefined values are listed as constant properties of Panel, including: * - Panel.Position * - Panel.Vertical * - Panel.Horizontal * - Panel.Auto * - Panel.Spot * - Panel.Table * - Panel.Viewbox * - Panel.Link (see also Links, which are all Panels of type Link) * - Panel.TableRow * - Panel.TableColumn * - Panel.Grid * - Panel.Graduated * * The default value is Panel.Position. * * You must not modify this property once the Panel has been measured or the Panel has been added to another Panel. */ get type(): PanelLayout; set type(value: PanelLayout); /** * This read-only property returns an iterator over the collection of the GraphObjects that this panel manages. * * You can change the collection by calling #add, #insertAt, #remove, or #removeAt. * * You can also get direct access to individual elements by calling #elt. */ get elements(): Iterator; /** * Gets or sets the space between this Panel's border and its content. * Unlike GraphObject#margin, padding expands the area inside of the Panel's border. * If this Panel's size is unconstrained, this will increase the size of the panel. * If this Panel's size is constrained, this will decrease the total area * for the Panel elements to arrange themselves. * * Unlike margin, increases in size due to padding are visually covered by the GraphObject#background. * * Padding cannot contain negative numbers. * The default value is a Margin of zero. * @see GraphObject#margin */ get padding(): MarginLike; set padding(value: MarginLike); /** * Gets or sets the default alignment spot of this Panel, used as * the alignment for an element when its GraphObject#alignment value is Spot.Default. * The default value is Spot.Default, which is interpreted by the Panel in whatever manner seems reasonable, * depending on the Panel type. */ get defaultAlignment(): Spot; set defaultAlignment(value: Spot); /** * Gets or sets the default stretch of this Panel, used as * the stretch for an element when its GraphObject#stretch value is GraphObject.Default. * The default value is GraphObject.Default, which typically resolves to GraphObject.None. */ get defaultStretch(): EnumValue; set defaultStretch(value: EnumValue); /** * For Panel.Table|Table Panels: Gets or sets the additional padding for rows and columns. * Padding is applied both before and after a row or column's contents. * @see RowColumnDefinition#separatorPadding * @see #defaultColumnSeparatorStrokeWidth * @see #defaultRowSeparatorStrokeWidth * @since 1.2 */ get defaultSeparatorPadding(): MarginLike; set defaultSeparatorPadding(value: MarginLike); /** * For Panel.Table|Table Panels: Gets or sets the default stroke (color) for rows * provided a given row has a nonzero RowColumnDefinition#separatorStrokeWidth. * RowColumnDefinition#separatorStroke can override this default value. * The default value is null -- no line is drawn. * @TablePanel * @see #defaultRowSeparatorStrokeWidth * @see #defaultRowSeparatorDashArray * @see RowColumnDefinition#separatorStroke * @see #defaultColumnSeparatorStroke * @since 1.2 */ get defaultRowSeparatorStroke(): BrushLike; set defaultRowSeparatorStroke(value: BrushLike); /** * For Panel.Table|Table Panels: Gets or sets the default stroke width for a row's separator. * RowColumnDefinition#separatorStrokeWidth can override this default value. * The default value is 1. Any new value must be a real, non-negative number. * @see RowColumnDefinition#separatorStrokeWidth * @see #defaultColumnSeparatorStrokeWidth * @since 1.2 */ get defaultRowSeparatorStrokeWidth(): number; set defaultRowSeparatorStrokeWidth(value: number); /** * For Panel.Table|Table Panels: Gets or sets the default dash array for a row's separator. * RowColumnDefinition#separatorDashArray can override this default value. * * Must be an array of positive numbers and zeroes, * or else null to indicate a solid line. * * For example, the array [5, 10] would create dashes of 5 pixels and spaces of 10 pixels. * * Setting an array with all zeroes will set the value to null. * * Default is null. * @see RowColumnDefinition#separatorDashArray * @see #defaultColumnSeparatorDashArray * @since 1.2 */ get defaultRowSeparatorDashArray(): Array | null; set defaultRowSeparatorDashArray(value: Array | null); /** * For Panel.Table|Table Panels: Gets or sets the default stroke (color) for columns * provided a given column has a nonzero RowColumnDefinition#separatorStrokeWidth. * RowColumnDefinition#separatorDashArray can override this default value. * The default value is null -- no line is drawn. * @see #defaultColumnSeparatorStrokeWidth * @see #defaultColumnSeparatorDashArray * @see RowColumnDefinition#separatorStroke * @see #defaultRowSeparatorStroke * @since 1.2 */ get defaultColumnSeparatorStroke(): BrushLike; set defaultColumnSeparatorStroke(value: BrushLike); /** * For Panel.Table|Table Panels: Gets or sets the default stroke width for a column's separator. * RowColumnDefinition#separatorStrokeWidth can override this default value. * The default value is 1. Any new value must be a real, non-negative number. * @see RowColumnDefinition#separatorStrokeWidth * @see #defaultRowSeparatorStrokeWidth * @since 1.2 */ get defaultColumnSeparatorStrokeWidth(): number; set defaultColumnSeparatorStrokeWidth(value: number); /** * For Panel.Table|Table Panels: Gets or sets the default dash array for a column's separator. * RowColumnDefinition#separatorStrokeWidth can override this default value. * * Must be an array of positive numbers and zeroes, * or else null to indicate a solid line. * * For example, the array [5, 10] would create dashes of 5 pixels and spaces of 10 pixels. * * Setting an array with all zeroes will set the value to null. * * Default is null. * @see RowColumnDefinition#separatorDashArray * @see #defaultRowSeparatorDashArray * @since 1.2 */ get defaultColumnSeparatorDashArray(): Array | null; set defaultColumnSeparatorDashArray(value: Array | null); /** * For Panel.Viewbox|Viewbox Panels: Gets or sets how the panel will resize its content. * * Possible values are GraphObject.Uniform and GraphObject.UniformToFill. * The default is GraphObject.Uniform. */ get viewboxStretch(): EnumValue; set viewboxStretch(value: EnumValue); /** * For Panel.Grid|Grid Panels: Gets or sets the distance between lines. * The units are in local coordinates. * The default is 10x10. Any new width or height must be a positive real number. */ get gridCellSize(): Size; set gridCellSize(value: Size); /** * For Panel.Grid|Grid Panels: Gets or sets an origin point for the grid cells. * The units are in local coordinates. * The default is (0,0). Any new value must use real numbers. */ get gridOrigin(): Point; set gridOrigin(value: Point); /** * For Panel.Graduated|Graduated Panels: Gets or sets the minimum value represented. * Must be less than #graduatedMax. The default is 0. * @since 1.7 */ get graduatedMin(): number; set graduatedMin(value: number); /** * For Panel.Graduated|Graduated Panels: Gets or sets the maximum value represented. * Must be greater than #graduatedMin. The default is 100. * @since 1.7 */ get graduatedMax(): number; set graduatedMax(value: number); /** * For Panel.Graduated|Graduated Panels: This read-only property returns the range of values represented by the Panel. * * For example, a #graduatedMin of 25 and #graduatedMax of 75 would return 50. * @since 1.7 */ get graduatedRange(): number; /** * For Panel.Graduated|Graduated Panels: Gets or sets the difference between two consecutive values marked by ticks. * Must be positive. The default is 10. * @since 1.7 */ get graduatedTickUnit(): number; set graduatedTickUnit(value: number); /** * For Panel.Graduated|Graduated Panels: Gets or sets the base value which is marked with a tick. * The default is 0. * @since 1.7 */ get graduatedTickBase(): number; set graduatedTickBase(value: number); /** * Return an immediate child element whose GraphObject#isPanelMain is true, * or else just return the first child element. * @return {GraphObject} this may return null if there are no child elements * @since 1.5 */ findMainElement(): GraphObject | null; /** * Undocumented state for PanelLayouts */ get panelLayoutState(): any | null; /** * Undocumented state for PanelLayouts */ set panelLayoutState(value: any | null); /** * Search the visual tree starting at this Panel for a GraphObject * whose GraphObject#name is the given name. * * This does not recurse into the elements inside a Panel that holds elements for an #itemArray. * @param {string} name The name to search for, using a case-sensitive string comparison. * @return {GraphObject} If no such named object can be found, this returns null. */ findObject(name: string): GraphObject | null; /** * Adds a number of GraphObjects to the end of this Panel's list of elements, visually in front of all of the other elements. * * If the element to be added is already in this Panel's list of elements, * the object is moved to the end of the list. * You cannot add a GraphObject to a Panel if that GraphObject is already in a different Panel. * @return {Panel} this Panel * @param {...GraphObject} elements Any number of GraphObjects. */ add(...elements: Array): this; /** * Returns the GraphObject in this Panel's list of elements at the specified index. * @param {number} idx * @return {GraphObject} */ elt(idx: number): GraphObject; /** * Adds a GraphObject to the Panel's list of elements at the specified index. * * If the element to be added is already in this Panel's list of elements, * the object is moved to the specified index. * You cannot add a GraphObject to a Panel that if that GraphObject is already in a different Panel. * @param {number} index * @param {GraphObject} element A GraphObject. */ insertAt(index: number, element: GraphObject): void; /** * Removes a GraphObject from this Panel's list of elements. * @param {GraphObject} element A GraphObject. */ remove(element: GraphObject): void; /** * Removes an GraphObject from this Panel's list of elements at the specified index. * @param {number} idx */ removeAt(idx: number): void; /** * For Panel.Table|Table Panels: This read-only property returns the number of rows. * This value is only valid after the Panel has been measured. */ get rowCount(): number; /** * For Panel.Table|Table Panels: Gets the RowColumnDefinition for a particular row. * If you ask for the definition of a row at or beyond the #rowCount, * it will automatically create one and return it. * * If this Panel is not a Table Panel, this method returns null. * @param {number} idx the non-negative zero-based integer row index. * @return {RowColumnDefinition} */ getRowDefinition(idx: number): RowColumnDefinition; /** * For Panel.Table|Table Panels: Removes the RowColumnDefinition for a particular row. * * If this Panel is not a Table Panel, this method does nothing. * @param {number} idx the non-negative zero-based integer row index. */ removeRowDefinition(idx: number): void; /** * For Panel.Table|Table Panels: This read-only property returns the number of columns. * This value is only valid after the Panel has been measured. */ get columnCount(): number; /** * For Panel.Table|Table Panels: Gets the RowColumnDefinition for a particular column. * If you ask for the definition of a column at or beyond the #columnCount, * it will automatically create one and return it. * * If this Panel is not a Table Panel, this method returns null. * @param {number} idx the non-negative zero-based integer column index. * @return {RowColumnDefinition} */ getColumnDefinition(idx: number): RowColumnDefinition; /** * For Panel.Table|Table Panels: Removes the RowColumnDefinition for a particular row. * * If this Panel is not a Table Panel, this method does nothing. * @param {number} idx the non-negative zero-based integer row index. */ removeColumnDefinition(idx: number): void; /** * For Panel.Table|Table Panels: Sets the given RowColumnDefinition. * If the row or column definition does not exist on the Panel, this will create it. * If it already exists on the Panel, this will copy the properties of the given RowColumnDefinition * onto that RowColumnDefinition. * @since 2.3 * @param {RowColumnDefinition} rowOrColumnDef the non-negative zero-based integer column index. * @return {Panel} this Panel * @see #addRowDefinition * @see #addColumnDefinition */ addRowColumnDefinition(rowOrColumnDef: RowColumnDefinition): this; /** * For Panel.Table|Table Panels: Sets the row RowColumnDefinition given by the index. * If the row definition does not exist on the Panel, this will create it. * If it already exists on the Panel, this will copy the properties of the given RowColumnDefinition options * onto that definition. * * This is a convenience method for #addRowColumnDefinition. Instead of writing: * ```js * .addRowColumnDefinition(new go.RowColumnDefinition({ row: 2, height: 60 })) * ``` * * You can write: * * ```js * .addRowDefinition(2, { height: 60 }) * ``` * * @since 2.3 * @param {RowColumnDefinition} rowIndex the non-negative zero-based integer row index. * @param {Partial} options the initialization options passed to the RowColumnDefinition constructor. * @return {Panel} this Panel * @see #addColumnDefinition * @see #addRowColumnDefinition */ addRowDefinition(rowIndex: number, options: Partial): Panel; /** * For Panel.Table|Table Panels: Sets the column RowColumnDefinition given by the index. * If the column definition does not exist on the Panel, this will create it. * If it already exists on the Panel, this will copy the properties of the given RowColumnDefinition options * onto that definition. * * This is a convenience method for #addRowColumnDefinition. Instead of writing: * ```js * .addRowColumnDefinition(new go.RowColumnDefinition({ column: 2, width: 60 })) * ``` * * You can write: * * ```js * .addColumnDefinition(2, { width: 60 }) * ``` * * @since 2.3 * @param {RowColumnDefinition} colIndex the non-negative zero-based integer column index. * @param {Partial} options the initialization options passed to the RowColumnDefinition constructor. * @return {Panel} this Panel * @see #addRowDefinition * @see #addRowColumnDefinition */ addColumnDefinition(colIndex: number, options: Partial): Panel; /** * For Panel.Table|Table Panels: Gets or sets how this Panel's rows deal with extra space. * Valid values are RowColumnDefinition.ProportionalExtra and RowColumnDefinition.None. * The default is RowColumnDefinition.ProportionalExtra. * @see RowColumnDefinition#sizing */ get rowSizing(): EnumValue; set rowSizing(value: EnumValue); /** * For Panel.Table|Table Panels: Gets or sets how this Panel's columns deal with extra space. * Valid values are RowColumnDefinition.ProportionalExtra and RowColumnDefinition.None. * The default is RowColumnDefinition.ProportionalExtra. * @see RowColumnDefinition#sizing * @see #rowSizing */ get columnSizing(): EnumValue; set columnSizing(value: EnumValue); /** * For Panel.Table|Table Panels: Gets or sets the first row that this Panel displays. * The default value is 0. * @see #leftIndex */ get topIndex(): number; set topIndex(value: number); /** * For Panel.Table|Table Panels: Gets or sets the first column that this Panel displays. * The default value is 0. * @see #topIndex */ get leftIndex(): number; set leftIndex(value: number); /** * For Panel.Table|Table Panels: Returns the row at a given y-coordinate in local coordinates, * or -1 if there are no RowColumnDefinitions for this Table Panel or if the argument is negative. * Call GraphObject#getLocalPoint to convert a Point in document coordinates into * a Point in local coordinates. * * @param {number} y * @return {number} a zero-based integer * @see #findColumnForLocalX * @since 1.2 */ findRowForLocalY(y: number): number; /** * For Panel.Table|Table Panels: Returns the cell at a given x-coordinate in local coordinates, * or -1 if there are no RowColumnDefinitions for this Table Panel or if the argument is negative. * Call GraphObject#getLocalPoint to convert a Point in document coordinates into * a Point in local coordinates. * * @param {number} x * @return {number} a zero-based integer * @see #findRowForLocalY * @since 1.2 */ findColumnForLocalX(x: number): number; /** * For Panel.Graduated|Graduated Panels: Returns the point that corresponds with a value, in the panel's coordinates. * * If the value provided is not within the #graduatedMin and #graduatedMax, * it will be constrained to within those values. * * If this Panel is not a Graduated Panel, this method returns Point(NaN, NaN). * @param {number} val a value between #graduatedMin and #graduatedMax * @param {Point=} result an optional Point that is modified and returned * @return {Point} * @see #graduatedValueForPoint * @since 1.7 */ graduatedPointForValue(val: number, result?: Point): Point; /** * For Panel.Graduated|Graduated Panels: Returns the value that corresponds with the given Point. * The Point must be in the panel's coordinates. * The value returned will be in the Graduated Panel's range. * * If this Panel is not a Graduated Panel, this method returns NaN. * @param {Point} pt a Point in the Graduated Panel's coordinates * @return {number} * @see #graduatedPointForValue * @since 1.7 */ graduatedValueForPoint(pt: Point): number; /** * Gets or sets the optional model data to which this panel is data-bound. * The data must be a JavaScript Object if this is a Part. * The data can be any JavaScript value if this is a Panel created for * an item in an Array that was data-bound by the #itemArray property. * The default value is null. * * Setting it to a new value automatically calls #updateTargetBindings * in order to assign new values to all of the data-bound GraphObject properties. * * Once you set this property you cannot add, remove, or modify any data bindings * on any of the GraphObjects in the visual tree of this Panel, including on * this panel itself. * * You should not modify this property on a Part that is created automatically * to represent model data, nor on a Panel that is created automatically for a data item * in the containing Panel's Panel#itemArray. * Call Model#removeNodeData and Model#addNodeData if you want to replace * this Part with another one, or call Model#removeArrayItem and Model#insertArrayItem * if you want to replace this Panel with another one. * * Although you might not be able to replace this data value if this Part was created * automatically by the Diagram, you can still modify that data object's properties. * Call the appropriate Model method for changing properties that affect the structure of the diagram. * Call Model#setDataProperty for changing other properties that may be the sources * of Bindings on GraphObject properties that are in the visual tree of this panel/part. */ get data(): any | null; set data(value: any | null); /** * Gets the index of this Panel's data if it was created to represent an item in its containing Panel's Panel#itemArray. * The default value is NaN. * * This is only set internally by code such as #rebuildItemElements or Model#insertArrayItem * when building or shifting Panel representing items * in the Panel whose Panel#itemArray was set or bound to an Array of value. * * This property can be used in data bindings within the item template to produce values * that depend on its position in the item Array. * For example: * ```js * $(go.Panel, // the item Panel * . . ., * new go.Binding("itemArray", "someProperty"), * { * itemTemplate: * $(go.Panel, * // set Panel.background to a color based on the Panel.itemIndex * new go.Binding("background", "itemIndex", * // using this conversion function * i => return (i%2 === 0) ? "lightgreen" : "lightyellow") * // bound to this Panel itself, not to the Panel.data item * .ofObject(), * $(go.TextBlock, // a trivial item template, just showing some text * new go.Binding("text")) // sets TextBlock.text = data.text * ) * } * ) * ``` * * The main element of a Spot or Auto or Link Panel, or the first TableRow or TableColumn element of a Table Panel * whose #isPanelMain property is true, will not have this property set to a number, * because it will not have been created by #rebuildItemElements. * @since 1.4 */ get itemIndex(): number; set itemIndex(value: number); /** * Make a deep copy of this Panel and allow it to be used as a template. * This makes copies of Bindings, unlike the regular `copy()` method. * Pass true as the argument in order to freeze the Bindings, * allowing it to operate efficiently as a template. * A false value (which is the default) allows further additions/modifications * of the bindings in the copied Panel. * @since 2.2 * @param {boolean=} freeze whether to freeze the Bindings in the copy; default is false * @return {Panel} */ copyTemplate(freeze?: boolean): Panel; /** * Re-evaluate all data bindings on this panel, * in order to assign new property values to the GraphObjects in this visual tree * based on this object's #data property values. * * It is better to call Model#setDataProperty to modify data properties, * because that will both record changes for undo/redo and will update all bindings * that may depend on that property. * * This method does nothing if #data is null. * @param {string=} srcprop An optional source data property name: * when provided, only evaluates those Bindings that use that particular property; * when not provided or when it is the empty string, all bindings are evaluated. * @see Model#updateTargetBindings */ updateTargetBindings(srcprop?: string): void; /** * Gets or sets a JavaScript Array of values or objects, each of which will be represented * by a Panel as elements in this Panel. * Replacing this array results all of this panel's child objects being replaced with * a copy of the Panel found in #itemTemplateMap for each particular * item in the Array. * * Because the software does not receive any notifications when an Array is modified, * any insertions or removals or replacements of data in the Array will not be noticed * unless you call Model#insertArrayItem or Model#removeArrayItem. * You may also reset this property to its current value (the modified Array) or * call #updateTargetBindings, if there is a Binding whose target is this property. * * When binding this property, it is commonplace to set Model#copiesArrays and * Model#copiesArrayObjects properties to true, so that when a node is copied, * the item Array and its contents are copied, not shared. * Or more generally, to customize the model's copying processes, you can supply a custom * Model#copyNodeDataFunction and perhaps a GraphLinksModel#copyLinkDataFunction. * * Any JavaScript Object that is in this Array must only appear once in the array * and must not appear in any other Panel#itemArrays. * Use #findItemPanelForData to find the data-bound Panel created for an Object in this panel's item Array. * * Non-Object values in an item Array may appear multiple times. * An item Array may be shared by multiple Panels. * * Item Arrays should not be used with Grid Panels or Graduated Panels as they may not have nested Panels. */ get itemArray(): Array | null; set itemArray(value: Array | null); /** * Return the Panel that was made for a particular data object in this panel's #itemArray. * If this returns a Panel, its #data property will be the argument data object, * and its containing GraphObject#panel will be this panel. * @param {Object} data must be an Object, not a string or a number or a boolean or a function * @return {Panel} or null if not found * @since 1.6 */ findItemPanelForData(data: ObjectData): Panel | null; /** * Create and add new GraphObjects corresponding to and bound to the data in the #itemArray, * after removing all existing elements from this Panel. * This method is automatically called when replacing the #itemArray value, * or when changing the value of #itemTemplate or #itemTemplateMap. * * This uses #itemCategoryProperty to determine the category for an item data. * That string is used to look up a template in #itemTemplateMap. * The resulting template (which is also a Panel) is copied, added to this panel, * and its #itemIndex is set to its index in that Array. * That new child Panel is then data-bound to that Array item by setting its #data. * * If #itemArray is null, this method just removes all elements from this panel. * Actually, if this Panel #type is "Spot", "Auto", or "Link", the very first element * is always kept by this method. * Also, if this Panel type is "Table", and if the first element is a "TableRow" or "TableColumn" Panel * whose #isPanelMain property is set to true, that first element will be kept too. * That is useful for defining literal TableRow headers in Table panels, when the header information * is not kept as the first item in the itemArray. * * It is wasteful to call this method after making some model data changes. * It is better to call Model#setDataProperty, Model#addArrayItem, * Model#insertArrayItem, or Model#removeArrayItem, or other model methods. * Not only do those methods update efficiently, they also preserve unbound state and support undo/redo. */ rebuildItemElements(): void; /** * Gets or sets the default Panel template used as the archetype * for item data that are in #itemArray. * * Setting this property just modifies the #itemTemplateMap * by replacing the entry named with the empty string. * Any new value must be a Panel but not a Part. * By default this property is null. * * GraphObject#copy when copying a panel will share the #itemTemplateMap * between the original panel and the copied panel. */ get itemTemplate(): Panel; set itemTemplate(value: Panel); /** * Gets or sets a Map mapping template names to Panels. * One of these Panels is copied for each item data that is in the #itemArray. * Replacing this map will automatically rebuild all of the elements in this Panel. * * By default this property is null. * All values in the Map must be Panels but not Parts. * * If you modify this Map, by replacing a Panel or by adding or * removing a map entry, you need to explicitly call #rebuildItemElements afterwards. * * GraphObject#copy when copying a panel will share the #itemTemplateMap * between the original panel and the copied panel. */ get itemTemplateMap(): Map | null; set itemTemplateMap(value: Map | null); /** * Gets or sets the name of the item data property that returns a string describing that data's category, * or a function that takes an item data object and returns that string; * the default value is the name 'category'. * This is used to distinguish between different * kinds of items in the #itemArray. * * The name must not be null. * If the value is an empty string, the category is assumed to be an empty string, * the default category name, for all item data objects. * You must not change this property when the #itemArray already has a value. */ get itemCategoryProperty(): string | ((a: any) => string); set itemCategoryProperty(value: string | ((a: any) => string)); set isAtomic(value: boolean); /** * For Spot Panels: Gets or sets whether this Panel's main element clips instead of fills. * The main element will not paint its stroke, if it has any. * This assumes that the main element is a Shape. * * Since 2.2: For Groups: Gets or sets whether this Group's Part#resizeObject clips its member nodes. * For compatibility, if the Group is a Spot Panel, it will not clip its members. * * When this property is `true`, the Spot panel will size itself to be the *intersection* of the main element bounds and * all other elements' bounds, rather than the union of these bounds. * @since 1.7 */ get isClipping(): boolean; set isClipping(value: boolean); /** * For Panel.Horizontal|Horizontal and Panel.Vertical|Vertical Panels: gets or sets whether this Panel arranges its contents from the * typical side (left and top, respectively), or the opposite side (right and bottom, respectively). * * The default value is false. * @since 1.7 */ get isOpposite(): boolean; set isOpposite(value: boolean); /** * Gets or sets whether this Panel or any GraphObject inside the panel actually responds to user click events. * It may be used as a Binding target. * See how this property is used in Buttons.js. * * This property does not have any effect on picking ("hit-testing") -- that behavior is implemented * by the GraphObject#pickable property. * When this property is false, non-click events may still occur on this panel or on objects within this panel. * This property is normally only used for Panels that are GraphObject#isActionable. * * Call GraphObject#isEnabledObject to decide whether a particular object can be clicked. * @see GraphObject#isEnabledObject * @see GraphObject#enabledChanged * @see GraphObject#isActionable * @see GraphObject#pickable * @since 1.7 */ get isEnabled(): boolean; set isEnabled(value: boolean); /** * For Panels which are elements of Spot Panels: Gets or sets the name * of this Panel's element that should be used as the alignment object instead of this Panel. * * This allows Spot Panels to align objects that are nested in the element tree of its own elements. * @since 1.7 */ get alignmentFocusName(): string; set alignmentFocusName(value: string); /** * Register a PanelLayout. This is called when making new Panel types. * See the PanelLayout sample for an example. * @param {string} layoutName Panel name * @param {PanelLayout} layout instance of the PanelLayout * @since 2.0 */ static definePanelLayout(layoutName: string, layout: PanelLayout): void; /** * The default #type, arranges each element according to their GraphObject#position. * @constant */ static get Position(): PanelLayout; /** * This value for #type lays out the elements horizontally with * their GraphObject#alignment property dictating their alignment on the Y-axis. * @constant */ static get Horizontal(): PanelLayout; /** * This value for #type lays out the elements vertically with * their GraphObject#alignment property dictating their alignment on the X-axis. * @constant */ static get Vertical(): PanelLayout; /** * This value for #type arranges GraphObjects about a main element using the * GraphObject#alignment and GraphObject#alignmentFocus properties; * the main element is the first GraphObject with GraphObject#isPanelMain set to true, * or else the first GraphObject if none have that property set to true. * @constant */ static get Spot(): PanelLayout; /** * This value for #type resizes the main element to fit around the other elements; * the main element is the first GraphObject with GraphObject#isPanelMain set to true, * or else the first GraphObject if none have that property set to true. * @constant */ static get Auto(): PanelLayout; /** * This value for #type arranges GraphObjects into rows and columns; * set the GraphObject#row and GraphObject#column properties on each element. * @constant */ static get Table(): PanelLayout; /** * This value for #type rescales a single GraphObject to fit inside the panel * depending on the panel's Panel#viewboxStretch property. * @constant */ static get Viewbox(): PanelLayout; /** * Organizational Panel type that is only valid inside of a Table panel; * This Panel ignores its angle and scale, and does not have a meaningful size on its own, * it is only an organizational container for other elements of a Panel. * @constant * @since 1.1 */ static get TableRow(): PanelLayout; /** * Organizational Panel type that is only valid inside of a Table panel; * This Panel ignores its angle and scale, and does not have a meaningful size on its own, * it is only an organizational container for other elements of a Panel. * @constant * @since 1.1 */ static get TableColumn(): PanelLayout; /** * This value for #type is used for Links and adornments that act as Links. * @constant */ static get Link(): PanelLayout; /** * This value for #type is used to draw regular patterns of lines. * @constant */ static get Grid(): PanelLayout; /** * This value for #type is used to draw regular tick marks and labels along some shape. * The main element is the first GraphObject with GraphObject#isPanelMain set to true, * or else the first GraphObject if none have that property set to true. * @constant * @since 1.7 */ static get Graduated(): PanelLayout; } /** * The RowColumnDefinition class describes constraints on a row or a column * in a Panel of type Panel.Table. * It also provides information about the actual layout after the * Table Panel has been arranged. * @unrestricted */ export class RowColumnDefinition { /** * You can use this constructor with Panel#addRowColumnDefinition to add * RowColumnDefinitions to Table Panels. * * Calls to Panel#getRowDefinition or Panel#getColumnDefinition * will automatically create and remember a RowColumnDefinition for you. * @param {Partial=} init Optional * initialization properties. These can include `row` or `column` index numbers as a convenience * instead of setting #isRow and #index. */ constructor(init?: Partial); /** * The default #sizing, which resolves to RowColumnDefinition.None or else * the Table Panel's rowSizing and columnSizing if present. * @constant */ static Default: EnumValue; /** * The default #sizing if none is specified on the Table Panel's rowSizing and columnSizing. * @constant */ static None: EnumValue; /** * If a Table Panel is larger than all the rows then this #sizing * grants this row and any others with the same value the extra space, apportioned proportionally between them * @constant */ static ProportionalExtra: EnumValue; /** * (undocumented) * Get the spacing at the top or left of the row or column. * @param {number} first the first row or column with an element in it * @return {number} * @see #computeEffectiveSpacing */ computeEffectiveSpacingTop(first: number): number; /** * (undocumented) * Get the total spacing for a row or column. * * For a row, this would be the value of Panel#defaultRowSeparatorStrokeWidth or RowColumnDefinition#separatorStrokeWidth, * plus the top and bottom values of Panel#defaultSeparatorPadding or RowColumnDefinition#separatorPadding. * @return {number} */ computeEffectiveSpacing(): number; /** * This read-only property returns the Panel that this row or column definition is in. */ get panel(): Panel | null; /** * This read-only property is true when this describes a row instead of a column in the #panel. * When this is true, the #height, #minimum, and #maximum * all describe the row height. * Otherwise #width and the other two properties describe the column width. */ get isRow(): boolean; set isRow(value: boolean); /** * This read-only property returns which row or column this RowColumnDefinition describes in the #panel. * The value is a zero-based integer. * @see Panel#findColumnForLocalX * @see Panel#findRowForLocalY * @see Panel#leftIndex * @see Panel#topIndex * @see #position */ get index(): number; set index(value: number); /** * Gets or sets the row height, in local coordinates. * This describes the row height if #isRow is true; * otherwise this property is meaningless. * The value must be non-negative and finite. * * The default value is NaN, which means this row will get a height * that is just big enough to hold all of the objects in the row. * * Setting this value to a number will mean that all of the objects * of this Panel in this row will be allocated that * amount of row height. * Whether an object in the row is actually arranged to have that height * depends on whether the GraphObject#stretch stretches vertically. * @see #width * @see #minimum * @see #maximum * @see #sizing */ get height(): number; set height(value: number); /** * Gets or sets the column width, in local coordinates. * The size describes the column width if #isRow is false; * otherwise this property is meaningless. * The value must be non-negative and finite. * * The default value is NaN, which means this column will get a width * that is just big enough to hold all of the objects in the column. * * Setting this value to a number will mean that all of the objects * of this Panel in this column will be allocated that * amount of column width. * Whether an object in the column is actually arranged to have that width * depends on whether the GraphObject#stretch stretches horizontally. * @see #height * @see #minimum * @see #maximum * @see #sizing */ get width(): number; set width(value: number); /** * Gets or sets the minimum row height or column width, in local coordinates. * The minimum describes the row height if #isRow is true; * otherwise this describes the column width. * * The value must be non-negative and finite. * The default value is zero. * The arranged height of all objects in this row, * or the arranged width of all objects in this column, * will be no less than this value. * @see #width * @see #height * @see #maximum * @see #sizing */ get minimum(): number; set minimum(value: number); /** * Gets or sets the maximum row height or column width, in local coordinates. * The maximum describes the row height if #isRow is true; * otherwise this describes the column width. * * The value must be non-negative. * The default value is Infinity. * The arranged height of all objects in this row, * or the arranged width of all objects in this column, * will be no greater than this value. * @see #width * @see #height * @see #minimum * @see #sizing */ get maximum(): number; set maximum(value: number); /** * Gets or sets a default alignment for elements that are in this row or column. * The value must be a Spot. * The default value is Spot.Default, so that this RowColumnDefinition * does not supply any alignment information for the row or column. * * When an element's GraphObject#alignment property is Spot.Default, * it gets the horizontal alignment from the element's column's RowColumnDefinition * and the vertical alignment from the element's row's RowColumnDefinition. * When that RowColumnDefinition#alignment property is also Default, * it takes the value from the table panel's Panel#defaultAlignment property. * @see GraphObject#alignment * @see Panel#defaultAlignment */ get alignment(): Spot; set alignment(value: Spot); /** * Gets or sets the default stretch for elements that are in this row or column. * The only accepted values are listed as constant properties of GraphObject: * GraphObject.None, GraphObject.Fill, GraphObject.Horizontal, GraphObject.Vertical, or GraphObject.Default. * The default value is GraphObject.Default, so that this RowColumnDefinition * does not supply any stretch information for the row or column. * * When an element's GraphObject#stretch property is GraphObject.Default, * it gets the horizontal stretch from the element's column's RowColumnDefinition * and the vertical stretch from the element's row's RowColumnDefinition. * When that RowColumnDefinition#stretch property is also Default, * it takes the value from the table panel's Panel#defaultStretch property. * @see GraphObject#stretch * @see Panel#defaultStretch * @see #sizing * @see #width * @see #height */ get stretch(): EnumValue; set stretch(value: EnumValue); /** * Gets or sets the additional padding for a particular row or column, in local coordinates. * Padding is applied on two sides - before and after a row or column's contents. * The #separatorStrokeWidth comes before any padding Margin#top or Margin#left. * * The default value is null, so that this RowColumnDefinition * does not supply any padding information for the row or column. * There may still be some padding between rows and/or columns if Panel#defaultSeparatorPadding is non-zero. * @see Panel#defaultSeparatorPadding * @see #separatorStroke * @see #separatorStrokeWidth * @see #separatorDashArray * @see #background * @since 1.2 */ get separatorPadding(): MarginLike; set separatorPadding(value: MarginLike); /** * Gets or sets the stroke (color) for the separator line that is drawn before a particular row or column, * provided that row or column has a nonzero #separatorStrokeWidth. * * The default value is null, so that this RowColumnDefinition * does not specify any brush for the separator line to draw before the row or column. * The line may still be drawn if the value of Panel#defaultRowSeparatorStroke or * Panel#defaultColumnSeparatorStroke is non-null. * * However, if no stroke color is specified, then no stroke width will be drawn, * even if the #separatorStrokeWidth value is non-zero. * @see Panel#defaultColumnSeparatorStroke * @see Panel#defaultRowSeparatorStroke * @see #separatorPadding * @see #separatorStrokeWidth * @see #separatorDashArray * @see #background * @since 1.2 */ get separatorStroke(): BrushLike; set separatorStroke(value: BrushLike); /** * Gets or sets the stroke width for a particular row or column's separator line, in local coordinates. * * The default value is NaN, so that this RowColumnDefinition * does not supply any stroke width information for what is drawn before the row or column. * The separator line may still be drawn if Panel#defaultRowSeparatorStroke * or Panel#defaultColumnSeparatorStroke is a real number (they default to 1). * @see Panel#defaultColumnSeparatorStrokeWidth * @see Panel#defaultRowSeparatorStrokeWidth * @see #separatorPadding * @see #separatorStroke * @see #separatorDashArray * @see #background * @since 1.2 */ get separatorStrokeWidth(): number; set separatorStrokeWidth(value: number); /** * Gets or sets the dash array for dashing the separator line, provided this * row or column has a nonzero RowColumnDefinition#separatorStrokeWidth and non-null RowColumnDefinition#separatorStroke. * * Must be an array of positive numbers and zeroes, * or else null to indicate a solid line. * * For example, the array [5, 10] would create dashes of 5 pixels and spaces of 10 pixels. * * Setting an array with all zeroes will set the value to null. * * Default is null, so that this RowColumnDefinition * does not supply any stroke dash array information for what is drawn before the row or column. * The separator line may still be drawn using dashes if Panel#defaultRowSeparatorDashArray * or Panel#defaultColumnSeparatorDashArray is non-null. * @see Panel#defaultColumnSeparatorDashArray * @see Panel#defaultRowSeparatorDashArray * @see #separatorPadding * @see #separatorStroke * @see #separatorStrokeWidth * @see #background * @since 1.2 */ get separatorDashArray(): Array | null; set separatorDashArray(value: Array | null); /** * Gets or sets the background color for a particular row or column, * which fills the entire span of the row or column, including any separatorPadding. * * The default value is null, which means nothing is drawn in the background of the row or column. * @see GraphObject#background * @since 1.2 */ get background(): BrushLike; set background(value: BrushLike); /** * Determines whether or not the #background, if there is one, is in front of or behind the separators. * * The default value is false -- any background is drawn behind any separator lines. * @since 1.2 */ get coversSeparators(): boolean; set coversSeparators(value: boolean); /** * Gets or sets how this row or column deals with a Table Panel's extra space. * The value must be one of: RowColumnDefinition.None, RowColumnDefinition.ProportionalExtra, * or RowColumnDefinition.Default. * The default value is RowColumnDefinition.Default. * @see Panel#columnSizing * @see Panel#rowSizing * @see #actual * @see #total * @see #height * @see #width */ get sizing(): EnumValue; set sizing(value: EnumValue); /** * This read-only property returns the usable row height or column width, after arrangement, in local coordinates, * that objects in this row or column can be arranged within. * This does not include #separatorPadding or #separatorStrokeWidth, as #total does. * * This value gives the row height if #isRow is true; * otherwise this gives the column width. * The value is meaningless until after the Table Panel using this * RowColumnDefinition has been arranged. * @see #total * @see #height * @see #width * @see #sizing */ get actual(): number; set actual(value: number); /** * (undocumented) */ get measured(): number; set measured(value: number); /** * This read-only property returns the total arranged row height or column width, after arrangement, in local coordinates. * This value gives the #actual size plus the #separatorPadding and #separatorStrokeWidth. * * This value gives the vertical space occupied by the row if #isRow is true; * otherwise this gives the horizontal space occupied by the column. * The value is meaningless until after the Table Panel using this * RowColumnDefinition has been arranged. * @see #actual * @see #height * @see #width * @see #sizing * @since 1.2 */ get total(): number; /** * This read-only property returns the actual arranged row or column starting position, after arrangement, in local coordinates. * This value gives the Y position if #isRow is true; * otherwise this gives the X position. * The value is meaningless until after the Table Panel using this * RowColumnDefinition has been arranged. * @see Panel#findColumnForLocalX * @see Panel#findRowForLocalY * @see Panel#leftIndex * @see Panel#topIndex * @see #index */ get position(): number; set position(value: number); /** * Add a data-binding to this RowColumnDefinition for the given property names and optional conversion function. * You can pass in the arguments to a new Binding: `.bind(a, b)` instead of calling `.bind(new go.Binding(a, b)`. * * @param {string=} targetprop A string naming the target property on the target object. * This should not be the empty string. * @param {string=} sourceprop A string naming the source property on the bound data object. * If this is the empty string, the whole Panel#data object is used. * If this argument is not supplied, the source property is assumed to be the same as the target property. * @param {TargetConversion=} conv An optional side-effect-free function converting the data property value to the value to set the target property. * If the function is null or not supplied, no conversion takes place. * @param {BackConversion=} backconv An optional conversion function to convert property values back to data values. * Specifying this modifies the binding to set its Binding#mode to be Binding.TwoWay. * If you want a two-way binding without a back-conversion function, call this method with the new Binding * argument instead, and call Binding#makeTwoWay on it: `.bind(new go.Binding(...).makeTwoWay())` * @return {RowColumnDefinition} this RowColumnDefinition * @since 2.2 */ bind(targetprop?: string, sourceprop?: string, conv?: TargetConversion, backconv?: BackConversion): this; /** * Add a data-binding of a property on this RowColumnDefinition to a property on a data object. * You can pass in the arguments to a new Binding: `.bind(a, b)` instead of calling `.bind(new go.Binding(a, b)`. * * Read more about Bindings at the Introduction page about Data Bindings. * @param {Binding} binding * @return {RowColumnDefinition} this RowColumnDefinition */ bind(binding: Binding): this; } /** * A Shape is a GraphObject that shows a geometric figure. * The Geometry determines what is drawn; * the properties #fill and #stroke * (and other stroke properties) determine how it is drawn. * * There are generally two types of shapes: Those that use a custom Geometry by setting * Shape#geometry, and those that receive an automatically generated Geometry using the value of * #figure, #toArrow, or #fromArrow. An explicitly set Geometry always supersedes * the figure and arrowhead properties. * * Some created Shapes: * ```js * // A shape with the figure set to RoundedRectangle: * new go.Shape({ figure: "RoundedRectangle", fill: "lightgreen" }) * // Alternatively: * new go.Shape("RoundedRectangle" { fill: "lightgreen" }) * * // A shape with a custom geometry: * new go.Shape( * { geometry: go.Geometry.parse("M120 0 L80 80 0 50z") }) * * // A shape with a custom geometry, using geometryString: * new go.Shape( * { geometryString: "F M120 0 L80 80 0 50z", * fill: "lightgreen" }) * * // A common link template, using two shapes, * // the first for the link path and the second for the arrowhead * // The first shape in a link is special, its geometry is set by the Link's routing, * // so it does not need a geometry or figure set manually * myDiagram.linkTemplate = * new go.Link() * .add(new go.Shape( * { strokeWidth: 2, stroke: 'gray' })) * .add(new go.Shape( * { toArrow: "Standard", fill: 'gray', stroke: null })) * ``` *

* You can see more custom geometry examples and read about geometryString * on the Geometry Path Strings Introduction page. * * When automatically generating a Shape Geometry, the value of #toArrow takes precedence, * then #fromArrow, then #figure. If the value of #toArrow or #fromArrow is "None" * then it is ignored, and the "None" value of #figure is identical to "Rectangle". * * All of the predefined figures are shown in the Shapes sample. * You can define your own named figures by calling the static function Shape.defineFigureGenerator. * Get a Map of named figures by calling the static function Shape.getFigureGenerators. * * All of the predefined arrowheads are shown in the Arrowheads sample. * You can define your own named arrowheads by calling the static function Shape.defineArrowheadGeometry. * Get a Map of named arrowheads by calling the static function Shape.getArrowheadGeometries. * * You can see a copy of all of the built-in arrowhead definitions in this file: Arrowheads.js. * * The Shape properties #parameter1, and #parameter2 determine details of the * construction of some #figure geometries. * Specifically, they often set the #spot1, #spot2 for the Shape. * These spots determine the "inner area" of an Auto panel when a Shape is the main object. * See the Auto Panels section of the Panels Introduction page for more details. * * Shapes use their geometric bounds when determining hit testing, * but use rectangular bounds when participating in (panel) layouts. * @extends GraphObject * @unrestricted */ export class Shape extends GraphObject { /** * A newly constructed Shape has a default #figure of "None", * which constructs a rectangular geometry, and is filled and stroked with a black brush. * * Common usage: * ```js * new go.Shape("RoundedRectangle", { * strokeWidth: 2, * stroke: "red", * fill: "yellow" * }) * ``` * * Or when using a custom #geometryString instead of a #figure: * * ```js * new go.Shape({ * fill: "red", * stroke: null, * width: 100, * height: 100, * // This SVG-style path creates a thick "+" figure: * geometryString: "F M2 1 h1 v1 h1 v1 h-1 v1 h-1 v-1 h-1 v-1 h1 z" * }) * ``` * * Also common is to set some or all of the Shape properties dynamically, * in the Node data, by way of bindings: * * ```js * // A Node used as the node template, holding a single shape * // The shape has many bindings * myDiagram.nodeTemplate = * new go.Node("Horizontal") * .add( * new go.Shape() * .bind("width") * .bind("height") * .bind("fill", "color") // binds the data.color to shape.fill * .bind("figure")); * * // It could be used with model data like this: * myDiagram.model = new go.GraphLinksModel( * [ * { key: "1", width: 150, height: 150, color: "red", figure: "Triangle" }, * { key: "2", width: 24, height: 24, color: "blue", figure: "Roundedrectangle" } * ]); * ``` * * @param {string=} figure The shape's figure, a predefined geometry. * If no geometry is set then shapes will use the default figure of "None", a rectangle. * Common values are "Rectangle", "Ellipse", "RoundedRectangle". * @param {Partial=} init Optional initialization properties. */ constructor(figure?: string, init?: Partial); /** * A newly constructed Shape has a default #figure of "None", * which constructs a rectangular geometry, and is filled and stroked with a black brush. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * Gets or sets the Shape's Geometry that defines the Shape's figure. * Setting a geometry is not necessary if a #figure is specified, * as that will construct a geometry instead. * * Setting this geometry property will freeze the supplied Geometry. * * Setting this geometry property always overrides any set figure. * The default value is null. * @see #geometryString */ get geometry(): Geometry | null; set geometry(value: Geometry | null); /** * When set, creates a Geometry and normalizes it from a given path string, * then sets the #geometry property on this Shape and * set the GraphObject#position to the amount computed by normalization. * The property getter simply returns the toString value of the #geometry, * or the empty string if there is no Geometry value. * * See the Geometry Path Strings Introduction page for examples. * @since 1.1 */ get geometryString(): string; set geometryString(value: string); /** * Gets or sets the whether the GraphObject#position of this shape denotes * the top-left corner of this shape in panel coordinates or the origin of this geometry's coordinate system. * Basically, this determines whether the #strokeWidth affects the rendered location. * A true value allows multiple shapes to be positioned precisely in a "Position" Panel independent of the stroke width. * The default is false. * @since 1.1 */ get isGeometryPositioned(): boolean; set isGeometryPositioned(value: boolean); /** * Gets or sets the Brush or string that describes how the geometry is filled when drawn. * * The default value is "black", causing the shape to be filled with solid black. * Any valid CSS string can specify a solid color, and the Brush * class can be used to specify a gradient or pattern. * A null fill will mean no fill is drawn and the filled portion * of the Shape will not be pickable. * A "transparent" fill is useful when wanting to allow a shape to be pickable * without obscuring any other objects behind it. * More information about the syntax of CSS color strings is available at: * CSS colors (mozilla.org). * * The geometry is filled before the #stroke is drawn. */ get fill(): BrushLike; set fill(value: BrushLike); /** * Gets or sets the Brush or string that describes how the geometry is drawn as if by a pen. * * The default value is "black", causing the shape to be outlined in black. * Any valid CSS string can specify a solid color, and the Brush * class can be used to specify a gradient or pattern. * A null stroke will mean no stroke is drawn. * A "transparent" stroke is useful when wanting to allow a shape to be pickable * without obscuring any other objects behind it. * More information about the syntax of CSS color strings is available at: * CSS colors (mozilla.org). * * The stroke is drawn after the geometry is filled with the #fill Brush. */ get stroke(): BrushLike; set stroke(value: BrushLike); /** * Gets or sets the thickness of the stroke's pen. * * Value must be a real number greater than or equal to zero. * The default value is 1.0. * * A value of zero will cause the stroke not to be drawn. * However, Main Shapes of Link Selection Adornments with a strokeWidth of 0 * will inherit the strokeWidth from the Link's main Shape. * * The stroke width will affect the GraphObject#measuredBounds and GraphObject#actualBounds of this shape. * The stroke is drawn centered on the path of the geometry. */ get strokeWidth(): number; set strokeWidth(value: number); /** * Gets or sets the style for how the ends of the stroke's line are drawn. * The value must be one of "butt", "round", or "square". The default is "butt". * * For more information, see Stroke Line Cap (w3.org). */ get strokeCap(): ('butt' | 'round' | 'square'); set strokeCap(value: ('butt' | 'round' | 'square')); /** * Gets or sets the type of corner that will be drawn for a stroke at the intersection of two straight segments of the geometry. * The value must be one of "miter", "bevel", or "round". The default is "miter". * * For more information, see Stroke Line Join (w3.org). */ get strokeJoin(): ('miter' | 'bevel' | 'round'); set strokeJoin(value: ('miter' | 'bevel' | 'round')); /** * Gets or sets the style for the stroke's mitre limit ratio. * The value must be a real number greater than or equal to one. * The default is 10.0. * * For more information, see Stroke Miter Limit (w3.org). */ get strokeMiterLimit(): number; set strokeMiterLimit(value: number); /** * Gets or sets the dash array for creating dashed or dotted lines. * The value must be an array of positive numbers and zeroes, * or else null to indicate a solid line. * For example, the array [5, 10] would create dashes of 5 pixels and spaces of 10 pixels. * For more information, see Stroke Line Dash Array (w3.org). * * The default value is null, resulting in a line without dashes or dots. * Setting an array with all zeroes will set the value to null. * @since 1.1 */ get strokeDashArray(): Array | null; set strokeDashArray(value: Array | null); /** * Gets or sets the offset for dashed lines, used to start the drawing of the dash pattern with some space. * The value must be a real non-negative number. The default is zero. * * For more information, see Stroke Line Dash Offset (w3.org). * @since 1.1 */ get strokeDashOffset(): number; set strokeDashOffset(value: number); /** * Gets or sets the figure name, used to construct a Geometry. * The value must be a string. The default value is "None". * * The name can be any case but will always be canonicalized when set. For instance, * setting "roundedrectangle" will set the value of figure to "RoundedRectangle". * All of the predefined figures are shown in the Shapes sample. * * At most one of the following three properties may be set to a non-"None" value at the same time on the same shape: * #figure, #toArrow, #fromArrow. * * You can define your own named figures by calling the static function Shape.defineFigureGenerator. */ get figure(): string; set figure(value: string); /** * Gets or sets the name of the kind of arrowhead that this shape should take * when this shape is an element of a Link. * Value must be a string. * * The default is "None", which means that this Shape is not an arrowhead, causing it to be the default Shape, a large filled Rectangle. * If you want to have an arrowhead Shape but sometimes not show an arrowhead, you can set or bind * the GraphObject#visible property, or you can set or bind this "toArrow" property to * be the empty string. * The arrowhead named "", an empty string, will display as nothing. * * The name can be any case but will always be canonicalized when set. For instance, * setting "opentriangle" will set the value of the arrowhead to "OpenTriangle". * All of the predefined arrowheads are shown in the Arrowheads sample. * * Setting this property may also set the GraphObject#segmentIndex, * GraphObject#segmentOrientation, and GraphObject#alignmentFocus properties. * This shape should be an element of a Link. * * At most one of the following three properties may be set to a non-"None" value at the same time on the same shape: * #figure, #toArrow, #fromArrow. * * You can define your own named arrowheads by calling the static function Shape.defineArrowheadGeometry. * * You can see a copy of all of the built-in arrowhead definitions in this file: Arrowheads.js. */ get toArrow(): string; set toArrow(value: string); /** * Gets or sets the name of the kind of arrowhead that this shape should take * when this shape is an element of a Link. * Value must be a string. * For bi-directional links the arrowhead name often starts with "Backward...". * * The default is "None", which means that this Shape is not an arrowhead, causing it to be the default Shape, a large filled Rectangle. * If you want to have an arrowhead Shape but sometimes not show an arrowhead, you can set or bind * the GraphObject#visible property, or you can set or bind this "toArrow" property to * be the empty string. * The arrowhead named "", an empty string, will display as nothing. * * The name can be any case but will always be canonicalized when set. For instance, * setting "opentriangle" will set the value of the arrowhead to "OpenTriangle". * All of the predefined arrowheads are shown in the Arrowheads sample. * * Setting this property may also set the GraphObject#segmentIndex, * GraphObject#segmentOrientation, and GraphObject#alignmentFocus properties. * This shape should be an element of a Link. * * At most one of the following three properties may be set to a non-"None" value at the same time on the same shape: * #figure, #toArrow, #fromArrow. * * You can define your own named arrowheads by calling the static function Shape.defineArrowheadGeometry. * * You can see a copy of all of the built-in arrowhead definitions in this file: Arrowheads.js. */ get fromArrow(): string; set fromArrow(value: string); /** * Gets or sets the top-left Spot used by some Panels for determining where in the shape other objects may be placed. * The value is normally Spot.Default, but you may want to set it to override the value that many #figures use. */ get spot1(): Spot; set spot1(value: Spot); /** * Gets or sets the bottom-right Spot used by some Panels for determining where in the shape other objects may be placed. * The value is normally Spot.Default, but you may want to set it to override the value that many #figures use. */ get spot2(): Spot; set spot2(value: Spot); /** * Gets or sets a property for parameterizing the construction of a Geometry from a figure. * The meaning of this property depends on the particular figure. * The value must be a number; the default value is NaN. */ get parameter1(): number; set parameter1(value: number); /** * Gets or sets a property for parameterizing the construction of a Geometry from a figure. * The meaning of this property depends on the particular figure. * The value must be a number; the default value is NaN. */ get parameter2(): number; set parameter2(value: number); /** * This read-only property returns the natural bounds of this Shape as determined by its #geometry's bounds. * The bounds will always include the (0,0) point. * If the #desiredSize is set, it returns a Rect with the #desiredSize. If no geometry is available, * and no #desiredSize is set, this may have NaN values for the width and height. */ get naturalBounds(): Rect; /** * Gets or sets a GraphObject that is drawn repeatedly along the path of the stroke of this shape. * This property may be set to a shared GraphObject; the GraphObject should not belong to any Panel. * Note that data bindings do not work in such shared GraphObjects, because they are not part of the visual tree. * The default value is null, causing no object to be drawn repeatedly. * * Typically the object is a small Shape or a Picture. * The larger the object is the worse the results will be, especially if the stroke has short segments or sharp curves. * The pathPattern object is not part of the measured bounds of the Shape, it is a cosmetic element only. * * The stroke is always drawn normally -- having a value for this property will draw the value along the stroke as well, * so it is commonplace to set the #stroke to "transparent" and the #strokeWidth to be as wide as * the height of the GraphObject being drawn along the stroke. * * Examples of path patterns can be seen in the Relationships sample. * * This property is ignored by the Shapes in "Grid" or "Graduated" Panels. * @since 1.6 */ get pathPattern(): GraphObject | null; set pathPattern(value: GraphObject | null); /** * Gets or sets how the shape's geometry is proportionally created given its computed size. * Possible values are GraphObject.None, GraphObject.Fill, GraphObject.Uniform, and GraphObject.Default. * The default is GraphObject.Default, which resolves to GraphObject.Fill for most figures, though * some regular figures such as "Circle" and "Square" default to GraphObject.Uniform. */ get geometryStretch(): EnumValue; set geometryStretch(value: EnumValue); /** * Gets or sets how frequently this shape should be drawn within a "Grid" or "Graduated" Panel, * in multiples of the Panel#gridCellSize or Panel#graduatedTickUnit. * The default is 1. Any new value must be a positive integer. */ get interval(): number; set interval(value: number); /** * Gets or sets the fractional distance along the main shape of a "Graduated" Panel at which this kind of tick should start. * The default is 0. Any new value should range from 0 to 1. * @since 1.7 */ get graduatedStart(): number; set graduatedStart(value: number); /** * Gets or sets the fractional distance along the main shape of a "Graduated" Panel at which this kind of tick should end. * The default is 1. Any new value should range from 0 to 1. * @since 1.7 */ get graduatedEnd(): number; set graduatedEnd(value: number); /** * Gets or sets the function to determine which values along a "Graduated" Panel will be skipped. * The default is null and doesn't skip any ticks. * * The function takes a number argument, a value between Panel#graduatedMin and Panel#graduatedMax, * and this Shape. * The function will return a boolean, whether the tick will be skipped at the value of the argument. * * Note that the second argument is the Shape, *not* a particular tick that would be rendered at the given value. * The function, if supplied, must not have any side-effects. * @since 2.0 */ get graduatedSkip(): ((val: number, shape: Shape) => boolean) | null; set graduatedSkip(value: ((val: number, shape: Shape) => boolean) | null); /** * This static function returns a read-only Map of named geometry generators. * The keys are figure names. * The values are either string synonyms for other figure names, or functions * that take a Shape and a width and a height and return a Geometry. * * The predefined shape figures can be seen in the Shapes sample. * @return {Map.} * @since 1.5 */ static getFigureGenerators(): Map Geometry)>; /** * This static function defines a named figure geometry generator for Shapes. * Once this is called one can use the name as a value for Shape#figure. * * The first argument is the new figure name and must be a non-empty string that starts with a capital letter and that is not "None". * * If the second argument is a string this call defines a synonym for an existing figure generator. * Do not define cycles of synonyms -- the behavior will be undefined. * * If the second argument is a function, * the Geometry generator function's first argument is the Shape for which the function is producing a Geometry. * But this Shape argument may be null in some circumstances. * The second and third arguments are the desired width and height. * These will always be finite non-negative numbers. * The function may look at the Shape#parameter1 and Shape#parameter2 properties, which may be NaN, * to decide what geometry to create for the figure given its intended width and height. * * The function must return a Geometry; you may want to set Geometry#spot1 and Geometry#spot2 on it * to indicate where content should be placed within the figure when using an "Auto" Panel. * For some figures you may also want to set Geometry#defaultStretch to GraphObject.Uniform * in order to maintain the geometry's aspect ratio within the Shape. * * Generated figures must create a Geometry that is not larger than the supplied with and height. Doing so will signal an error. * @param {string} name a capitalized figure name ("RoundedRectangle"); must not be "" or "None" * @param {string|function(Shape,number,number):Geometry} func A function that takes (Shape,width,height) and returns a Geometry, * or an existing figure generator name for which the new name will be a synonym. * @since 1.5 */ static defineFigureGenerator(name: string, func: string | ((shape: Shape, width: number, height: number) => Geometry)): void; /** * This static function returns a read-only Map of named arrowhead geometries. * The keys are arrowhead names. * The values are Geometry objects. * * The predefined arrowheads can be seen in the Arrowheads sample. * @return {Map.} * @since 1.5 */ static getArrowheadGeometries(): Map; /** * This static function defines a named arrowhead geometry. * Once this is called one can use the name as a value for Shape#toArrow or Shape#fromArrow. * * The first argument is the new arrowhead name and must be a non-empty string that starts with a capital letter and that is not "None". * * If the second argument is a string, it is converted into a Geometry by calling * `go.Geometry.parse(pathstr, false)`, * which may throw an error if there are problems with the syntax of the string. * @param {string} name a capitalized arrowhead name ("OpenTriangle"); must not be "" or "None" * @param {Geometry|string} pathstr a Geometry or a Geometry path string, e.g. "m 0,0 l 8,4 -8,4" * @since 1.5 */ static defineArrowheadGeometry(name: string, pathstr: Geometry | string): void; } /** * A TextBlock is a GraphObject that displays a #text string in a given #font. * * The size and appearance of the text is specified by #font, * which takes a well-formed CSS string as its value. * The order of the CSS properties given is important for cross-browser compatibility, * and should be given in this order: * * "font-style font-variant font-weight font-size font-family" * * For example, "Italic small-caps bold 32px Georgia, Serif" is a valid font string * using every CSS font property. Note that not all browsers may support every property. * * Text is drawn using the #stroke brush, which may be any CSS color string or a Brush. * * Some created TextBlocks: * ```js * // A TextBlock with text and stroke properties set: * new go.TextBlock({ text: "Hello World", stroke: "gray" }) * // Alternatively: * new go.TextBlock("Hello World", { stroke: "gray" }) * ``` * * TextBlocks typically receive a natural size based on their text and font strings, * but often a width is given in order to cause the text to wrap at a certain place. * In order for wrapping to occur, the #wrap property must not be TextBlock.None. * * TextBlocks can be edited by users using the TextEditingTool. * The HTMLInfo that a given TextBlock uses as its text editor can be customized * by setting the #textEditor property. For an example of custom text editing tool use, * see the Custom TextEditingTool Sample. *

* For examples of TextBlock possibilities and functionality, * see the Introduction page on TextBlocks. * @extends GraphObject * @unrestricted */ export class TextBlock extends GraphObject { /** * Constructs a TextBlock, which by default has no string to show; if it did, * it would draw the text, wrapping if needed, in the default font using a black stroke. * * Typical usage: * * ```js * new go.TextBlock("Hello World", { font: "12px sans-serif", stroke: "gray" }) * ``` * * It is common to data-bind the #text: * * ```js * // A Node used as the node template, holding a single TextBlock * myDiagram.nodeTemplate = * new go.Node() * .add( * new go.TextBlock({ font: "12px sans-serif", stroke: "darkgray" }) * .bind("text")); * * // It could be used with model data like this: * myDiagram.model = new go.GraphLinksModel( * [ * { key: "1", text: "First TextBlock" }, * { key: "2", text: "Second TextBlock" } * ]); * ``` * * @param {string=} text The textblock's text. * @param {Partial=} init Optional initialization properties. */ constructor(text?: string, init?: Partial); /** * A newly constructed TextBlock has no string to show; if it did, * it would draw the text, wrapping if needed, in the default font using a black stroke. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * (undocumented) * This static function gets the current ellipsis character or string for * TextBlocks that have TextBlock#overflow set to TextBlock.Ellipsis. */ static getEllipsis(): string; /** * (undocumented) * This static function sets the ellipsis character or string for all * TextBlocks that have TextBlock#overflow set to TextBlock.Ellipsis. * * The default is `"..."`, which works with all fonts. * * Note when using the ellipsis character, "…", you will need to specify a compatible * character set for your page, like UTF-8. * * Modifying the ellipsis character does not cause any TextBlocks to be remeasured or redrawn. * @param {string} val */ static setEllipsis(val: string): void; /** * Gets the function that, given the TextBlock and numerical text height, computes the position to draw the baseline of a line of text in all TextBlocks. * By default this is null and default behavior returns `(textHeight * 0.75)`. * * This computation affects drawing only, and does not change TextBlock measurement calculations. * @return {(textBlock: TextBlock, textHeight: number) => number | null} * @since 2.0 */ static getBaseline(): ((textBlock: TextBlock, textHeight: number) => number) | null; /** * Sets the function that, given the TextBlock and numerical text height, computes the position to draw the baseline of a line of text in all TextBlocks. * * This computation affects drawing only, and does not change TextBlock measurement calculations. * It is expected this method will be called before or during initialization of any Diagram. * Diagrams will not redraw when this method has been called, * and you should call `Diagram.redraw()` if you are calling this method outside of your initialization. * * @param {(textBlock: TextBlock, textHeight: number) => number | null} value * @since 2.0 */ static setBaseline(value: ((textBlock: TextBlock, textHeight: number) => number) | null): void; /** * Gets the function that, given the TextBlock and numerical text height, computes the position to draw the underline of a line of text in all TextBlocks. * By default this is null and default behavior returns `(textHeight * 0.75)`. * * This computation affects drawing only, and does not change TextBlock measurement calculations. * @return {(textBlock: TextBlock, textHeight: number) => number | null} * @since 2.0 */ static getUnderline(): ((textBlock: TextBlock, textHeight: number) => number) | null; /** * Sets the function that, given the TextBlock and numerical text height, computes the position to draw the underline of a line of text in all TextBlocks. * * This computation affects drawing only, and does not change TextBlock measurement calculations. * It is expected this method will be called before or during initialization of any Diagram. * Diagrams will not redraw when this method has been called, * and you should call `Diagram.redraw()` if you are calling this method outside of your initialization. * * @param {(textBlock: TextBlock, textHeight: number) => number | null} value * @since 2.0 */ static setUnderline(value: ((textBlock: TextBlock, textHeight: number) => number) | null): void; /** * Used as a value for TextBlock#wrap, the TextBlock will not wrap its text. * @constant */ static None: EnumValue; /** * Used as a value for TextBlock#wrap, the TextBlock will wrap text, making the width of * the TextBlock equal to the width of the longest line. * @constant */ static WrapFit: EnumValue; /** * Used as the default value for TextBlock#wrap, the TextBlock will wrap text and the width of * the TextBlock will be the desiredSize's width, if any. * @constant */ static WrapDesiredSize: EnumValue; /** * Used a a value for TextBlock#wrap, the TextBlock will attempt to wrap at each character, allowing * breaks within "words." * @since 2.0 * @constant */ static WrapBreakAll: EnumValue; /** * Used as the default value for TextBlock#overflow: if the width is too small to display all text, * the TextBlock will clip. * @constant * @since 1.4 */ static OverflowClip: EnumValue; /** * Used as a value for TextBlock#overflow: if the width is too small to display all text, * the TextBlock will display an ellipsis. * @constant * @since 1.4 */ static OverflowEllipsis: EnumValue; /** * Used as the default value for TextBlock#formatting: the TextBlock will automatically trim any whitespace at the start * or end of each line of text. * @constant * @since 2.2 */ static FormatTrim: EnumValue; /** * Used as a value for TextBlock#formatting: the TextBlock will *not* trim any whitespace at the start * or end of each line of text. This can be useful if your text is preformatted. * @constant * @since 2.2 */ static FormatNone: EnumValue; /** * Gets or sets the current font settings. * The font property must be a valid CSS string describing a font. * The font string can accept several CSS properties but they must be * in a specific order in order to render correctly across all browsers: * * `"font-style font-variant font-weight font-size font-family"` * * For example, `"Italic small-caps bold 32px Georgia, Serif"` is a valid font string * using every CSS font property. Not every browser can render every font option. * For more information about CSS font syntax, see CSS fonts (mozilla.org). * * If your Node sizes depend on TextBlocks, it is best to ensure any custom fonts you are using are finished loading before you load your Diagram. * This will ensure nodes are sized appropriately for the initial Diagram layout. * * The default font is "13px sans-serif". */ get font(): string; set font(value: string); /** * (undocumented) * This static predicate returns true if the given font is a valid font. * @param {string} font * @return {boolean} */ static isValidFont(font: string): boolean; /** * Gets or sets the TextBlock's text string. The default is an empty string. * The text of a TextBlock, along with the values of #font, #wrap, * #isMultiline and sizing restrictions are what naturally determine * the size of the TextBlock. * * The text in textblocks can include manual line-breaks by using the character escape, `\n`. * * Leading and trailing whitespace is eliminated in each line of TextBlock text. * * If #editable is set to true, users can edit textblocks with the TextEditingTool. */ get text(): string; set text(value: string); /** * Gets or sets the alignment location in the TextBlock's given space. * The only possible values are `"start"`, `"end"`, `"left"`, `"right"`, and `"center"`. * Any other value is invalid. * * This property is most pertinent when the TextBlock has multiple lines of text, * or when the TextBlock is given a size that differs from the text's natural size (such as with #desiredSize). * * In left-to-right writing systems, `"start"` and `"left"` are synonymous, as are `"end"` and `"right"`. * * The default is `"start"`. * @see #verticalAlignment */ get textAlign(): ('start' | 'end' | 'left' | 'right' | 'center'); set textAlign(value: ('start' | 'end' | 'left' | 'right' | 'center')); /** * Gets or sets how the TextBlock is displayed: Either normally or with a Horizontal or Vertical flip or both. * * Possible values are GraphObject.None, GraphObject.FlipHorizontal, GraphObject.FlipVertical, or GraphObject.FlipBoth. * The default is GraphObject.None. * @since 2.0 */ get flip(): EnumValue; set flip(value: EnumValue); /** * Gets or sets the vertical alignment Spot of this TextBlock, used when * the TextBlock has more available vertical space than it needs to draw all lines. * * The default value is Spot.Top, which aligns the TextBlock to the top of its available space. * * The #textAlign is often used along with this property to specify * where the should be positioned in its available space. * * This does not affect TextBlock coordinates or bounds, it only affects where text is drawn within the given area. * @see #textAlign * @since 1.7 */ get verticalAlignment(): Spot; set verticalAlignment(value: Spot); /** * This read-only property returns the natural bounds of this TextBlock in local coordinates, * as determined by its #font and #text string, and optionally its #desiredSize. */ get naturalBounds(): Rect; /** * Gets or sets whether or not the text displays multiple lines or embedded newlines. * If this is false, all characters including and after the first newline will be omitted. * The default is true. * @see #maxLines */ get isMultiline(): boolean; set isMultiline(value: boolean); /** * Gets or sets whether or not the text is underlined. * The default is false. * @see #isStrikethrough * @since 1.2 */ get isUnderline(): boolean; set isUnderline(value: boolean); /** * Gets or sets whether or not the text has a strikethrough line (line-through). * The default is false. * @see #isUnderline * @since 1.2 */ get isStrikethrough(): boolean; set isStrikethrough(value: boolean); /** * Gets or sets whether the text should be wrapped if it is too long to fit on one line. * * Possible values are TextBlock.WrapDesiredSize, TextBlock.WrapFit, TextBlock.WrapBreakAll, * and TextBlock.None. * * The default value is TextBlock.WrapDesiredSize. * @see #overflow */ get wrap(): EnumValue; set wrap(value: EnumValue); /** * Gets or sets how text that is too long to display should be handled. * * Possible values are TextBlock.OverflowClip and TextBlock.OverflowEllipsis. * For OverflowEllipsis to work, you must constrain the available size of the TextBlock in some way, * such as setting #wrap to TextBlock.None, * or limiting the number of lines with #maxLines or a height constraint. * * The default value is TextBlock.OverflowClip. * @see #wrap * @since 1.4 */ get overflow(): EnumValue; set overflow(value: EnumValue); /** * Gets whether the TextBlock text is truncated (overflowed) or not. * This value is set during a TextBlock's measurement. * * As with all read-only properties, using this property as a binding source is unlikely to be useful. * @since 2.3 * @see #overflow */ get isOverflowed(): boolean; /** * Gets or sets the Brush or string that describes the stroke (color) of the text that is drawn. * * The default value is `"black"`. * Any valid CSS string can specify a solid color, and the Brush * class can be used to specify a gradient or pattern. * More information about the syntax of CSS color strings is available at: * CSS colors (mozilla.org). */ get stroke(): BrushLike; set stroke(value: BrushLike); /** * This read-only property returns the computed number of lines in this TextBlock, including lines created * from embedded newlines (`\n`), #wrapping, and #maxLines. * * This value may be meaningless before the TextBlock is measured. * @see #lineHeight */ get lineCount(): number; /** * This read-only property returns the height of a line of text in this TextBlock, not including any #spacingAbove or #spacingBelow. * * This value may be meaningless before the TextBlock is measured. * @since 2.2 * @see #lineCount */ get lineHeight(): number; /** * Gets or sets whether or not this TextBlock allows in-place editing of the #text * string by the user with the help of the TextEditingTool. * The default is false. * * See also Part#textEditable. */ get editable(): boolean; set editable(value: boolean); /** * Gets or sets the HTMLInfo that this TextBlock uses as its text editor in the TextEditingTool. * If null, the TextBlock will use the default text editor of the TextEditingTool. * The default is null. * The value should be set to an instance of HTMLInfo. * Setting this property might not affect any ongoing text editing operation. * * As of 2.0 setting this to an HTML Element is no longer supported. * * For example usage, see the Custom TextEditingTool Sample. */ get textEditor(): HTMLInfo | null; set textEditor(value: HTMLInfo | null); /** * Gets or sets the function to call if a text edit made with the TextEditingTool is invalid. * The default is null. */ get errorFunction(): ((tool: TextEditingTool, oldString: string, newString: string) => void) | null; set errorFunction(value: ((tool: TextEditingTool, oldString: string, newString: string) => void) | null); /** * Gets or sets how frequently this text should be drawn within a "Graduated" Panel, * in multiples of the Panel#graduatedTickUnit. * The default is 1. Any new value must be a positive integer. * @since 1.7 */ get interval(): number; set interval(value: number); /** * Gets or sets the fractional distance along the main shape of a "Graduated" Panel at which this text should start. * The default is 0; the value should range from 0 to 1. * @since 1.7 */ get graduatedStart(): number; set graduatedStart(value: number); /** * Gets or sets the fractional distance along the main shape of a "Graduated" Panel at which this kind of tick text should end. * The default is 1; the value should range from 0 to 1. * @since 1.7 */ get graduatedEnd(): number; set graduatedEnd(value: number); /** * Gets or sets the function to convert from a value along a "Graduated" Panel to a string. * The default returns a string representing the value rounded to at most 2 decimals. * * The function takes a number argument, a value between Panel#graduatedMin and Panel#graduatedMax, * and this TextBlock. * The function will return a string, the text that will appear at the value of the argument. * * Note that the second argument is the TextBlock, *not* a particular label that would be rendered at the given value. * The function, if supplied, must not have any side-effects. * @since 1.7 */ get graduatedFunction(): ((val: number, tb: TextBlock) => string) | null; set graduatedFunction(value: ((val: number, tb: TextBlock) => string) | null); /** * Gets or sets the function to determine which values along a "Graduated" Panel will be skipped. * The default is null and doesn't skip any text labels. * * The function takes a number argument, a value between Panel#graduatedMin and Panel#graduatedMax, * and this TextBlock. * The function will return a boolean, whether the text label will be skipped at the value of the argument. * * Note that the second argument is the TextBlock, *not* a particular label that would be rendered at the given value. * The function, if supplied, must not have any side-effects. * @since 2.0 */ get graduatedSkip(): ((val: number, tb: TextBlock) => boolean) | null; set graduatedSkip(value: ((val: number, tb: TextBlock) => boolean) | null); /** * Gets or sets the predicate that determines whether or not a user-edited string of text is valid. * If this is non-null, the predicate is called in addition to any TextEditingTool#textValidation predicate. * See TextEditingTool#isValidText for more details. * * ```js * function(textBlock, oldString, newString) * ``` * * The default predicate is null, which is equivalent to simply returning true. * * The function, if supplied, must not have any side-effects, and must return true or false. * @see TextEditingTool#textValidation */ get textValidation(): ((thisTextBlock: TextBlock, oldString: string, newString: string) => boolean) | null; set textValidation(value: ((thisTextBlock: TextBlock, oldString: string, newString: string) => boolean) | null); /** * Gets or sets the function that is called after the TextBlock's text has been edited by the TextEditingTool. * - The first argument is a reference to this TextBlock. * - The second argument is the previous text, before editing. * - The third argument is the current text, which is also TextBlock.text. * * ```js * function(textBlock, previousText, currentText) * ``` * * The default value is null -- no function is called. * @since 1.7 */ get textEdited(): ((thisTextBlock: TextBlock, oldString: string, newString: string) => void) | null; set textEdited(value: ((thisTextBlock: TextBlock, oldString: string, newString: string) => void) | null); /** * Gets or sets additional spacing above each line of text. * The default is zero. The value may be negative. * * This can be useful when you need to adjust the font spacing on * custom fonts or monospace fonts to suit your needs. * * @since 2.2 */ get spacingAbove(): number; set spacingAbove(value: number); /** * Gets or sets additional spacing below each line of text. * The default is zero. The value may be negative. * * This can be useful when you need to adjust the font spacing on * custom fonts or monospace fonts to suit your needs. * * @since 2.2 */ get spacingBelow(): number; set spacingBelow(value: number); /** * Gets or sets the policy for trimming whitespace on each line of text. * * Possible values are TextBlock#FormatTrim, which trims whitespace before and after every line of text, * or TextBlock#FormatNone, which will not trim any whitespace and may be useful for preformatted text. * The default is TextBlock#FormatTrim. * @since 2.2 */ get formatting(): EnumValue; set formatting(value: EnumValue); /** * Gets or sets the maximum number of lines that this TextBlock can display. * Value must be a greater than zero whole number or `Infinity`. * The default is `Infinity`. * * Modifying this value may modify the computed height of the TextBlock. * If maxLines is set, the value of #lineCount will never be larger than maxLines. * @see #isMultiline * @since 1.5 */ get maxLines(): number; set maxLines(value: number); /** * Gets or sets the an array of possible choices for a custom TextEditingTool. * The value must be an array of strings. * * The default value is null. * For example usage, see the Custom TextEditingTool Sample. * @since 1.7 */ get choices(): Array | null; set choices(value: Array | null); } /** * A Picture is a GraphObject that shows an image, video-frame, or Canvas element. * * You can specify what to show by either setting the #source URL property * to a URL string or the #element property to an HTMLImageElement, * HTMLCanvasElement, or HTMLVideoElement. * * If a #source URL is set, the Picture will automatically create a corresponding * HTMLImageElement and retain a reference to it in memory. If multiple Pictures specify * the same #source URL then they will all refer to the same HTMLImageElement. * * Some created Pictures: * ```js * var $ = go.GraphObject.make; // for conciseness in defining GraphObjects * * // A picture with the source set to "example.png". It will show a gray area until the image is loaded: * $(go.Picture, { source: "example.png", background: "gray", width: 50, height: 50 }) * // Alternatively: * $(go.Picture, "example.png", { background: "gray", width: 50, height: 50 }) * ``` * * If an element is not completely loaded during Diagram initialization, a redraw may occur, * and if an image's size is not known before loading, the containing Part of this Picture * may be resized, causing side effects such as layouts. * This can be avoided by knowing the size of the image beforehand, * and setting the Picture's GraphObject#desiredSize. * * With some images (notably sprite sheets) only a portion of the image is expected to be drawn. * The #sourceRect property allows the programmer to specify a rectangular area of * the source image that the Picture should display. * * The #imageStretch property allows an image to be resized inside of its bounding box. * This property does not change the size of the Picture element, it only resizes or re-scales * the image to fit (or not) in its bounds. *

* For examples of sizing and #imageStretch, * see the Introduction page on Pictures. * * The #errorFunction property allows one to set a function to call when a source fails to load. * This is useful in instances where images cannot be guaranteed to work, such as with * user specified input. The error function can set the #source to a known good value, * but care should be taken to avoid error infinite loops when doing so. * @extends GraphObject * @unrestricted */ export class Picture extends GraphObject { /** * The constructor creates a Picture that shows nothing until the * #source or #element is specified. It is also common to specify the * GraphObject#desiredSize to make sure that the picture's size is known * before the image is loaded asynchronously, so that layouts do not need to be recomputed. * * Common usage: * ```js * new go.Picture("example_image_url.png", { * width: 100, * height: 50 * }) * ``` * * Or: * * ```js * // specify a different source for each node in the node data * new go.Picture({ * width: 100, * height: 50 * }).bind("source") * ``` * * @param {string=} source Optionally set the Pictures's #source. * @param {Partial=} init Optional properties to initialize. */ constructor(source?: string, init?: Partial); /** * The constructor creates a Picture that shows nothing until the * #source or #element is specified. It is also common to specify the * GraphObject#desiredSize to make sure that the picture's size is known * before the image is loaded asynchronously, so that layouts do not need to be recomputed. * @param {Partial=} init Optional properties to initialize. */ constructor(init?: Partial); /** * (undocumented) * This static function clears the cache of loaded images, or removes the cached image for a particular URL. * * When an image is loaded by GoJS when specifying a Picture.source URL, * GoJS creates an Image element using that source and caches it. * That way, when many Picture elements refer to the same source, * they can refer to the same single object in memory. * @param {string=} url optional, clear only a specified URL from the image cache. If relative urls are used as Picture sources, this must be in the same format. */ static clearCache(url?: string): void; /** * Gets or sets the Picture's HTML element that provides some kind of visual image. * * The default value is null. * This can be a HTMLImageElement, HTMLVideoElement, or HTMLCanvasElement. * If an image, this element must have its source (src) attribute defined. * Setting this does not set the Picture#source attribute and that attribute may be unknowable. * * If this property is set to an HTMLImageElement, and that element is not yet loaded before it is used, * the Diagrams using that Element will not redraw on their own. * You must call #redraw after the image is finished loading if you wish for the Diagram to be updated immediately. */ get element(): HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | null; set element(value: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | null); /** * Gets or sets the Picture's source URL, which can be any valid image (png, jpg, gif, etc) URL. * * The default value is the empty string, which specifies no image source. * Setting this attribute creates an HTMLImageElement and sets the Picture#element * attribute to that element. When the element loads, this Picture may remeasure if no GraphObject#desiredSize was set, * and Diagrams using the picture will redraw. * * To avoid remeasuring and rearranging Parts as images load asynchronously, * be sure to set the GraphObject#desiredSize * (or GraphObject#width and GraphObject#height) to fixed values. * * Setting the source of multiple Pictures to the same URL will cause only one HTMLImageElement * to be created and shared. Setting the source to the empty string will set Picture#element to null. * It is commonplace to either specify a constant URL or to data bind this property to some data property, * perhaps using a conversion function in order to produce a proper URL. * * For cross-browser support of SVG sources additional care is needed. * See the final section of the Introduction page on Pictures. */ get source(): string; set source(value: string); /** * Attempts to reload a Picture#source image. This can be useful if the content on a server has changed, or was missing before. * If a new image is loaded, this Picture may remeasure and/or redraw. * * Because of browsers caching assets, you may additionally need to force a re-fetch of the Picture's source URL * with a `fetch` call such as: * * ```js * fetch(thisPicture.source, { cache: 'reload', mode: 'no-cors' }); * ``` * * This should normally be called within a transaction. * @since 2.1 */ reloadSource(): void; /** * Redraws a Picture, which can be useful if the backing #element is an HTML Canvas or HTML Video that has changed. * This will not attempt to *reload* any image. If you need to do that, call #reloadSource. * * This does not need to be called within a transaction, and will not re-measure anything. * @since 2.1 */ redraw(): void; /** * Gets or sets a function that returns a value for image.crossOrigin. * * The default value is null, which will not set a value for image.crossOrigin. * Set this property to a function that returns "anonymous" or "use-credentials" * if you want images to complete a cross-origin request. * Example: * ```js * $(go.Picture, * { width: 64, height: 64 }, * { sourceCrossOrigin: pict => "use-credentials" }, * new go.Binding("source", "path")) * ``` * @since 1.5 */ get sourceCrossOrigin(): ((a: Picture) => string) | null; set sourceCrossOrigin(value: ((a: Picture) => string) | null); /** * Gets or sets the rectangular area of the source image that this picture should display. * This is only common with sprite maps and image tables. * * The value must be of type Rect. * The default value is Rect(NaN, NaN, NaN, NaN), which means the whole source image should be used. */ get sourceRect(): Rect; set sourceRect(value: Rect); /** * Gets or sets how the Picture's image is stretched within its bounding box. * Some images will be a different aspect ratio than their given size or #desiredSize. * This property will never change the size of the Picture itself, * only the size of the image that is drawn in the Picture's #actualBounds. * * Possible values are GraphObject.Fill, GraphObject.Uniform, * GraphObject.UniformToFill, and GraphObject.None. * The default is GraphObject.Fill. * @see #imageAlignment */ get imageStretch(): EnumValue; set imageStretch(value: EnumValue); /** * Gets or sets how the Picture is displayed: Either normally or with a Horizontal or Vertical flip or both. * * Possible values are GraphObject.None, GraphObject.FlipHorizontal, GraphObject.FlipVertical, or GraphObject.FlipBoth. * The default is GraphObject.None. * @since 2.0 */ get flip(): EnumValue; set flip(value: EnumValue); /** * Gets or sets the Spot to align the source image to, when the source image * is smaller than the Picture. This is only relevant when * the #imageStretch property value is not go.GraphObject.Fill. * * This does not affect Picture coordinates or bounds, it only affects what is drawn within the given area. * The default value is Spot.Center. * @see #imageStretch * @since 1.7 */ get imageAlignment(): Spot; set imageAlignment(value: Spot); /** * Gets or sets the function to call if an image set by #source fails to load. * The arguments to this function are this Picture and the HTMLImageElement's "error" Event. * * This is called once per Picture, for every Picture that is using the same #source that failed to load. * This will never be called if the #source is never set, and is not called with Pictures that use #element instead. * * The default value is null, meaning that no specific action occurs when there is an error loading an image. * @see #successFunction */ get errorFunction(): ((a: Picture, b: Event) => void) | null; set errorFunction(value: ((a: Picture, b: Event) => void) | null); /** * Gets or sets the function to call when an image set by #source loads successfully. * The arguments to this function are this Picture and the HTMLImageElement's "load" Event. * * This is called once per Picture, for every Picture that is using the same #source that loaded successfully. * This will never be called if the #source is never set, and is not called with Pictures that use #element instead. * It is even called for a Picture source that has already loaded, so that creating copies of a Picture with this property set will * call it once for each newly created Picture. * * The default value is null, meaning that no specific action occurs when an image finishes loading. * @see #errorFunction * @since 1.7 */ get successFunction(): ((a: Picture, b: Event) => void) | null; set successFunction(value: ((a: Picture, b: Event) => void) | null); /** * This read-only property returns the natural size of this picture as determined by its source's width and height. * The value is initially NaN x NaN until the picture has been measured. * It will use the #element's `naturalWidth` and `naturalHeight` if available. */ get naturalBounds(): Rect; } /** * This is the base class for all user-manipulated top-level objects. * Because it inherits from Panel, it is automatically a visual container * of other GraphObjects. * Because it thus also inherits from GraphObject, it also has properties such as * GraphObject#actualBounds, GraphObject#contextMenu, and GraphObject#visible. * * If you just want an object that users can select and manipulate, * you can create an instance of this class. * * If you want an object that also supports being connected by links to other objects, * use the Node class, which inherits from Part. * Create those connections by using instances of the Link class. * * If you want a node that logically contains a subgraph of nodes and links, * use the Group class, which inherits from Node. * * If you want an object that decorates another Part, without having to modify that Part, * use the Adornment class. * Adornments do not support linking or grouping or being selected. * * You can construct a Part, add GraphObjects to it programmatically, * and then add the part to a diagram by calling Diagram#add. * However it is commonplace to add data to a model by setting its Model#nodeDataArray or calling Model#addNodeData, * or for Links, setting the GraphLinksModel#linkDataArray or calling GraphLinksModel#addLinkData. * Such actions will cause a diagram that is displaying the model to copy a template, * which is a Part that may have data Bindings, and add the new part to the diagram. * The Panel#data property will refer to that data object in the model. * * Some examples of adding Parts to a Diagram: * ```js * // A simple Part template * myDiagram.nodeTemplate = * new go.Part("Horizontal") * .add(new go.Shape("Circle", { width: 20, height: 20 })) * .add(new go.TextBlock("Hello World")) * // Node templates can be either Nodes, or simple Parts * // (But not Groups, Adornments, or Links) * * // Adds copies of the nodeTemplate bound to the specified node data: * myDiagram.model.nodeDataArray = * [ * { key: "Alpha" }, * { key: "Beta" } * ]; * * // Adds one copy of the nodeTemplate bound to the given node data: * myDiagram.model.addNodeData( { key: "Gamma" } ); * ``` *

* See the Introduction on using Models * for examples and more information. *

Layers and Z-ordering

* * Parts added to a Diagram exist in one of the Diagram's Layers. * You can specify which layer the part should be in by setting #layerName. * Parts cannot be nested in the visual tree -- they cannot be added to other Parts of Panels. * * Parts can be individually z-ordered within a layer by setting #zOrder. * Parts within the same layer that have a higher zOrder number will be drawn above parts with a lower number. *

Size and Position

* * The size and position of a part are given by its GraphObject#actualBounds. * The size is determined by the GraphObjects that are elements inside this part. * You can change the position by setting GraphObject#position or Part#location. * * The "location" of a part is commonly the same as its "position". * The "position" is always the point that is at the top-left corner of the area occupied by the part. * But the "location" may be different from the "position" if you want to think of the part as being "at" a different spot in the part. * For example, you might want the "location" to be at the center of a Picture that has a TextBlock title of arbitrary size. * In this case you would set the #locationSpot to be Spot.Center and the #locationObjectName * to be the name of the Picture element in your Part. * * A part may be selected or de-selected by setting its #isSelected property. * This may also happen due to a call to Diagram#select or other operations that change the selection. * The user may change this property as part of the operation of the ClickSelectingTool, * due to the user's mouse click, if the part is #selectable. *

Ability Properties (Permissions)

* * There are many properties named "...able", that control what operations the user may perform on this part. * These properties correspond to the similarly named properties on Diagram and Layer that govern the * behavior for all parts in all layers or for all parts in the given layer. * For example, the Part#copyable property corresponds to the properties Diagram#allowCopy and Layer#allowCopy. * * For each of these "ability" properties there is a corresponding "can..." predicate. * For example, the Part#canCopy predicate is false if any of the three previously named properties is false. * Commands and tools will normally call these predicates rather than just looking at Part properties. *

* For more discussion about permissions, please read: Permissions. * * As previously mentioned, each Diagram supports the notion of selected parts. * One way of displaying that a part is selected is by modifying the part. * You can set the #selectionChanged property to be a function that is called when the value of #isSelected has changed; * it is passed the Part as the first argument. * The function can modify the color of one or more GraphObjects in the visual tree of that Part. * Or perhaps it could toggle the GraphObject#visible property of an object that is normally hidden when the part is not selected. * * The Part class also supports showing separate visual objects for a part when it gets selected. * These visuals are typically used to show that the part is selected ("selection handles") * or are used to allow the user to manipulate or modify the part with a tool ("tool handles"). * These handles are instances of Adornments. * The #updateAdornments method is responsible for showing or hiding adornments, * normally depending on whether the part is selected. * * When the #selectionAdorned property is true, a selected part automatically gets an Adornment created for it. * By default the selection adornment is just a simple blue box around the Part, and a blue shape following the route of a selected Link. * However you can set the #selectionAdornmentTemplate to an arbitrarily complex Adornment. * This way it can show more information or buttons for executing various commands when the user selects a Part. * * Tool handles are shown for those mode-less mouse-down tools that need it. * The process of updating adornments for a part will call Tool#updateAdornments on each tool in ToolManager#mouseDownTools. * Most tools might not need special tool handles. * But, for example, ResizingTool naturally will want to create an adornment with eight resize handles * positioned at the corners and at the middles of the sides of the selected node's visual element, * if the node has its #canResize function returning true. * * One may not always want the whole Part to get the selection handle or all tool handles. * Sometimes one wants to emphasize selection by highlighting a particular element within the part's visual tree. * This can be achieved by setting the #selectionObjectName property, * and making sure the desired element has the same GraphObject#name property value. *

* For more discussion about selection, see Selection. * * Similarly the #resizeObjectName and #rotateObjectName properties direct the * corresponding ResizingTool and RotatingTool to operate on the particular GraphObject * in the Part's visual tree with the given name. * That includes both providing tool handles and actually modifying properties on that object. * * Parts are not resizable or rotatable by default: you need to set #resizable and/or #rotatable to true. *

* For more discussion about tools, see Tools. * * A Part may be positioned (or a Link may be routed) by a Layout. * This will happen automatically if Diagram#layout or Group#layout are set. * The default Diagram#layout will position any nodes that were not given explicit positions or location. * * If you set #isLayoutPositioned to false, this part will not participate in any of the standard layouts, * so it will not be moved by a layout or affect other parts in a layout. * In order for the part to get a #location or position you will need to supply it explicitly. * * As parts are added to or removed from a diagram, the Layout responsible for positioning the part is invalidated. * This will cause the layout to be performed again in the near future, at the end of the transaction. * This automatic layout invalidation also occurs as parts change their visibility (GraphObject#visible) * or their size (GraphObject#actualBounds). * If you do want there to be a Diagram#layout but you do not want an automatic layout to happen * after removing parts (for example), you can set #layoutConditions not to include the Part.LayoutRemoved flag. * In this particular case, you could set #layoutConditions to: * `go.Part.LayoutStandard & ~go.Part.LayoutRemoved`. * It may also reasonable for your application to set it to Part.LayoutNone. * Do not forget to consider applying the same conditions to links as well as to nodes and groups. * * If you want to save the locations/positions of the parts in a diagram, it is commonplace to * data bind the #location to a property on your node data with a TwoWay Binding * (call Binding#makeTwoWay). For example: * ```js * new go.Part("Horizontal") * .bind(new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify)) * // ... * ``` * * Then as the nodes are moved, whether manually by the user or automatically by a Layout, * the model data is automatically updated with the location. *

* For more discussion about related topics, see Selection, * Tools, and * Permissions. * * Parts that are templates should have no relationships with other Parts. * Only real Parts that are in a Diagram can belong to Groups or have any Adornments. * Only real Nodes in a Diagram can be connected with Links. * @extends Panel * @unrestricted */ export class Part extends Panel { /** * Constructs an empty Part of the given #type. Default type is Panel.Position. * The panel type must be one of the enumerated values defined on the Panel class, including: * Panel.Position, Panel.Vertical, Panel.Horizontal, Panel.Table, * Panel.Auto, Panel.Spot, or Panel.Viewbox. The string value such as "Auto" may also be used. * * Usage example: * *```js * // Constructs a Part, sets properties on it, * // adds a data binding to it, * // and adds two GraphObjects to the Part: * const p = new go.Part("Auto", { * margin: 5, * background: "red" * }) * .bind("location", "loc") * .add(new go.Shape("RoundedRectangle")) * .add(new go.TextBlock("Some Text")) * ``` * * @param {string=} type Panel Type as either a string or PanelLayout. such as "Vertical", "Auto", or Panel.Vertical, Panel.Auto, are accepted. * If not supplied, the default Panel type is "Position". * @param {Partial=} init Optional initialization properties. */ constructor(type?: PanelLayout | string, init?: Partial); /** * Constructs an empty Panel. Default type is Panel.Position. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * This value may be used as the value of the Part#layoutConditions property to indicate that * no operation on this Part causes invalidation of the Layout responsible for this Part. * @constant */ static LayoutNone: number; /** * This flag may be combined with other "Layout" flags as the value of the Part#layoutConditions property to indicate that * when a Part is added to a Diagram or Group, it invalidates the Layout responsible for the Part. * @constant */ static LayoutAdded: number; /** * This flag may be combined with other "Layout" flags as the value of the Part#layoutConditions property to indicate that * when a Part is removed from a Diagram or Group, it invalidates the Layout responsible for the Part. * @constant */ static LayoutRemoved: number; /** * This flag may be combined with other "Layout" flags as the value of the Part#layoutConditions property to indicate that * when a Part's GraphObject#visible becomes true, it invalidates the Layout responsible for the Part. * @constant */ static LayoutShown: number; /** * This flag may be combined with other "Layout" flags as the value of the Part#layoutConditions property to indicate that * when a Part's GraphObject#visible becomes false, it invalidates the Layout responsible for the Part. * @constant */ static LayoutHidden: number; /** * This flag may be combined with other "Layout" flags as the value of the Part#layoutConditions property to indicate that * when a Node or simple Part's GraphObject#actualBounds changes size, it invalidates the Layout responsible for the Part; * this flag is ignored for Parts that are Links. * @constant */ static LayoutNodeSized: number; /** * This flag may be combined with other "Layout" flags as the value of the Part#layoutConditions property to indicate that * when a Group has been laid out, it invalidates the Layout responsible for that Group; * this flag is ignored for Parts that are not Groups. * @constant */ static LayoutGroupLayout: number; /** * This flag may be combined with other "Layout" flags as the value of the Part#layoutConditions property to indicate that * when a Node or simple Part's #category changes, it invalidates the Layout responsible for the Part; * this flag is ignored for Parts that are Links. * @constant */ static LayoutNodeReplaced: number; /** * This is the default value for the Part#layoutConditions property, basically a combination of all of the conditions: * the Layout responsible for the Part is invalidated when the Part is added or removed or replaced * from the Diagram or Group, or when it changes visibility or size, or when a Group's layout has been performed. * @constant */ static LayoutStandard: number; /** * Re-evaluate all data bindings in this Part, * in order to assign new property values to the GraphObjects in this visual tree * based on this this object's #data property values. * This method does nothing if #data is null. * * It is better to call Model#setDataProperty to modify data properties, * because that will both record changes for undo/redo and will update all bindings * that make depend on that property. * * To update relationships between nodes, call #updateRelationshipsFromData. * @param {string=} srcprop An optional source data property name: * when provided, only evaluates those Bindings that use that particular property; * when not provided or when it is the empty string, all bindings are evaluated. * @see #updateRelationshipsFromData */ updateTargetBindings(srcprop?: string): void; /** * Update all of the references to nodes in case they had been modified in the model without * properly notifying the model by calling GraphLinksModel#setGroupKeyForNodeData or * GraphLinksModel#setToKeyForLinkData or other similar methods. * This method does not conduct a transaction, so you need to start and commit one yourself. * * This only updates the relationships between nodes, to have them reflect what is now declared in the model data. * For example, in a GraphLinksModel if code has changed the value of the "to" property of a link data, * calling this method on the corresponding Link would cause the link to connect with * the Node whose data has the new key. * * To update GraphObject properties that are data bound, call #updateTargetBindings. * @expose * @see #updateTargetBindings * @since 1.5 */ updateRelationshipsFromData(): void; /** * This read-only property returns the Part's Model data key if it is in a Diagram and is backed by Model data. * Otherwise this returns undefined. * @since 1.8 * @see Model#getKeyForNodeData */ get key(): Key; /** * This read-only property returns an iterator over all of the Adornments associated with this part. * After each call to the iterator's next() method that returns true, * the iterator's key will be the category and the iterator's value will * be an Adornment. * * Templates should not have any adornments. */ get adornments(): Iterator; /** * Find an Adornment of a given category associated with this Part. * * Templates should not have any adornments. * @param {string} category * @return {Adornment} Returns null if no such Adornment was found. */ findAdornment(category: string): Adornment | null; /** * Associate an Adornment with this Part, perhaps replacing any existing adornment of the same category. * Don't forget to set Adornment#adornedObject before calling this method. * This adds the Adornment to the Layer named by #layerName, normally "Adornment". * * Adornments are also data bound to the same data that this Part has, if any. * If the Adornment was already associated with a Part, it is unassociated with that old Part. * * This method should not be called on templates. * @param {string} category a string identifying the kind or role of the given adornment for this Part. * @param {Adornment} ad the new Adornment. */ addAdornment(category: string, ad: Adornment): void; /** * Remove any Adornment of the given category that may be associated with this Part. * @param {string} category a string identifying the kind or role of the given adornment for this Part. */ removeAdornment(category: string): void; /** * Remove all adornments associated with this part. */ clearAdornments(): void; /** * This is responsible for creating any selection Adornment (if this Part #isSelected) and * any tool adornments for this part. * @expose */ updateAdornments(): void; /** * (undocumented) */ invalidateAdornments(): void; /** * This read-only property returns the Layer that this Part is in. * The value is the Layer that is named with the value of #layerName. * If you want to change what Layer this Part is in, change the value of #layerName to refer to a different Layer. * * This will be null if it has not yet been added to a Diagram, * or if it has already been removed from a Diagram. * @see #layerName */ get layer(): Layer | null; /** * This read-only property returns the Diagram that this Part is in. * * This will be null if it is not in a Layer. */ get diagram(): Diagram | null; /** * Gets or sets the layer name for this part. * The initial value is an empty string, which is the name of the default layer. * The value of this property determines the value of #layer. * * If this part is not yet in a Diagram, * this value is used by Diagram#add * to determine which Layer this part should go in. * If no layer can be found with this name, it uses the default layer. * * Changing the value of this property while it is already in a layer * causes it to change layers if needed. * @see #layerChanged */ get layerName(): string; set layerName(value: string); /** * Gets or sets the function to execute when this part changes layers. * It is typically used to modify the appearance of the part. * This function must not change the layer of this part by setting #layerName. * * If this property value is a function, it is called with three arguments, * this Part, the old Layer (may be null), and the new Layer (may be null). * By default this property is null -- no function is called. * @see #layerName */ get layerChanged(): ((thisPart: Part, oldLayer: Layer | null, newLayer: Layer | null) => void) | null; set layerChanged(value: ((thisPart: Part, oldLayer: Layer | null, newLayer: Layer | null) => void) | null); /** * Gets or sets the Z-ordering position of this Part within its Layer. * * Within the same layer, nodes with larger zOrder values are placed in front of nodes with smaller zOrder values. * When the value is NaN the ordering is not specified. * The default value is NaN. * * When a Group has a zOrder value of NaN, it is automatically placed behind its member nodes and links * that also have no zOrder. * Such automatic ordering is not guaranteed if any nodes including the groups have a numeric zOrder. * If you do want to specify the zOrder of nodes, you should also specify the zOrder of their containing groups * unless those groups are in different layers. * @since 1.6 */ get zOrder(): number; set zOrder(value: number); /** * This read-only property returns the GraphObject that determines the location of this Part. * The value will be in the visual tree of this Part and is usually named with * the value of #locationObjectName. */ get locationObject(): GraphObject; /** * Gets or sets the minimum location of this Part to which the user may drag using the DraggingTool. * * Value must be of type Point. * The initial value is (-Infinity, -Infinity), which imposes no position constraint. * A X value of NaN causes Diagram#computeMove to use the part's current location's X value as the minimum, * and similarly for NaN as the Y value. * @see #location * @see #maxLocation * @see #dragComputation * @see #movable */ get minLocation(): Point; set minLocation(value: Point); /** * Gets or sets the maximum location of this Part to which the user may drag using the DraggingTool. * * Value must be of type Point. * The initial value is (Infinity, Infinity), which imposes no position constraint. * A X value of NaN causes Diagram#computeMove to use the part's current location's X value as the maximum, * and similarly for NaN as the Y value. * @see #location * @see #minLocation * @see #dragComputation * @see #movable */ get maxLocation(): Point; set maxLocation(value: Point); /** * Gets or sets the name of the GraphObject that provides the location of this Part. * This name determines the value of #locationObject. * The actual #location also depends on the #locationSpot. * * The initial value is an empty string, meaning the whole Part itself determines the location. * If you want to use a particular GraphObject in the visual tree of this Part, * set this property to be the GraphObject#name of the element that you want to be the #locationObject. * @see #location * @see #locationSpot */ get locationObjectName(): string; set locationObjectName(value: string); /** * Gets or sets the location Spot of this Node, the spot on the #locationObject * that is used in positioning this part in the diagram. * * Value must be of the type Spot. * The initial value is `Spot.TopLeft`. * The value must be a specific spot -- i.e. one for which Spot#isSpot is true. * * It is commonplace to set this property to `Spot.Center`, so that the #location * has a value corresponding to the point at the center of this Part's #locationObject element. * But the GraphObject#position of a Part is always at the top-left corner * point of the GraphObject#actualBounds. * @see #location * @see #locationObjectName */ get locationSpot(): Spot; set locationSpot(value: Spot); /** * Move this part and any parts that are owned by this part to a new position. * * If this part is a Group, it also moves all of its members, recursively. * If this part is a Link, it also moves all of its label nodes. * * This method does not perform a transaction or start any animation. * @expose * @param {Point} newpos a new Point in document coordinates. * @param {boolean=} useLocation true if you want to set the #location instead of the position. False by default. */ move(newpos: Point, useLocation?: boolean): void; /** * Move this part and any parts that are owned by this part to a new position. * This just calls #move without the caller having to allocate a new Point. * @param {number} newx a new X value in document coordinates. * @param {number} newy a new Y value in document coordinates. * @param {boolean=} useLocation true if you want to set the #location instead of the position. False by default. * @since 1.4 */ moveTo(newx: number, newy: number, useLocation?: boolean): void; /** * This predicate is true if this Part can be seen. * Parts that can be seen can be manipulated by the user, can take space in the document, or can take part in a layout, * among many possibilities. * Note that the value of this predicate can often be false even while GraphObject#visible is true. * * A Part is not seen if it is not GraphObject#visible or if it is in a Layer that is not Layer#visible. * * If a Part is a member of a Group and the Group is not Group#isSubGraphExpanded, the part is not seen. * (The containing Group might still be visible.) * * If a Node is a "tree child" of a Node that is not Node#isTreeExpanded, the node is not seen. * (The parent Node might still be visible.) * * If a Link is connected to or from a Node that is not `isVisible()` * and is not a member of a Group that `isVisible()`, the link is not seen. * * If a Node is a "link label" of a Link and that Link is not `isVisible()`, the node is not seen. * * This is different from GraphObject#isVisibleObject, * which ignores whether the Layer is visible and just checks GraphObject#visible * up the chain of containing Panels. * * If you want to know whether a Part is in the Diagram's viewport, try: * ```js * diagram.viewportBounds.containsRect(part.actualBounds); * ``` * * or: * ```js * diagram.viewportBounds.intersectsRect(part.actualBounds); * ``` * @expose * @return {boolean} true if GraphObject#visible is true and if Layer#visible is true. */ isVisible(): boolean; /** * Returns the Rect in document coordinates for this object's bounds. * If this GraphObject is a Part, the rect will be identical to its #actualBounds. * @param {Rect=} result an optional Rect that is modified and returned. * @return {Rect} in document coordinates. * @see #getDocumentPoint * @since 2.0 */ getDocumentBounds(result?: Rect): Rect; /** * Measures if needed to make sure the GraphObject#measuredBounds and GraphObject#naturalBounds are all real numbers, * primarily to get the actual width and height. * GraphObject#actualBounds will get a real width and height, but the x and y values may continue to be `NaN` * if they were that way beforehand. * * This is sometimes necessary to call when defining custom layouts or implementing virtualization, * so that it can work with the actual size of the nodes. * * For efficiency, do not call this method unnecessarily. * @since 1.6 * @see Diagram#ensureBounds */ ensureBounds(): void; /** * Gets or sets the position of this part in document coordinates, * based on the #locationSpot in this part's #locationObject. * * Value must be of type Point. * The initial value is Point(NaN, NaN). * It is commonplace to data bind this property to some property on your model node data. * * The value is related to the GraphObject#position. * For Parts, both are in document coordinates; setting one property will set the other property. * By default both will have the same value. * However, by setting either or both of #locationSpot and #locationObjectName, * the location will be determined by a spot in the #locationObject, * a GraphObject that is in the visual tree of this Part. * The GraphObject#position will always refer to the point at the top-left corner of the whole part. * * The #minLocation and #maxLocation limit the location of a part, not its position. * Grid snapping will normally locate the location to be on grid points. * @see #locationObjectName * @see #locationSpot * @see #movable * @see #maxLocation * @see #minLocation * @see #dragComputation */ get location(): Point; set location(value: Point); /** * Gets or sets the category of this part, * typically used to distinguish different kinds of nodes or links. * * The initial value is an empty string, which is the default category. * Any new value must be a string. * This should not be set in templates. * * When building Parts for node data or link data in a model, * the Diagram will call Model#getCategoryForNodeData or * GraphLinksModel#getCategoryForLinkData to get the category string for the data object. * The diagram uses this value to look up a template in Diagram#nodeTemplateMap, * Diagram#linkTemplateMap or Diagram#groupTemplateMap. * That template is copied to create the actual Part that is added to the diagram. * The diagram will set this property to remember the category it used. * * Note that the class of the new Part must be the same as the class of the original Part. * For example, a Node cannot be replaced by a simple Part or vice-versa. * Nor can a Link be replaced by a subclass of Link or vice-versa. * * To change the category for a Part created for model data, call Model#setCategoryForNodeData or * GraphLinksModel#setCategoryForLinkData. * * This property is also used to distinguish Adornments on a Part. * In this scenario you create the Adornment, often indirectly by specifying a template, * and set this property explicitly. * For example, ResizingTool#updateAdornments creates a resizing Adornment from the * Part#resizeAdornmentTemplate and sets its category to be "Resizing". * Changing the category of an existing Adornment will update any adorned part's association. */ get category(): string; set category(value: string); set self(clone: Part); /** * This predicate returns true if #copyable is true, * if the layer's Layer#allowCopy is true, and * if the diagram's Diagram#allowCopy is true. * * This does not check Diagram#isReadOnly or Model#isReadOnly, * but commands and tools should check those properties. * @expose * @return {boolean} true if the user may copy this part. */ canCopy(): boolean; /** * This predicate returns true if #deletable is true, * if the layer's Layer#allowDelete is true, and * if the diagram's Diagram#allowDelete is true. * * This does not check Diagram#isReadOnly or Model#isReadOnly, * but commands and tools should check those properties. * @expose * @return {boolean} true if the user may delete this part. */ canDelete(): boolean; /** * This predicate returns true if #textEditable is true, * if the layer's Layer#allowTextEdit is true, and * if the diagram's Diagram#allowTextEdit is true. * * This does not check Diagram#isReadOnly or Model#isReadOnly, * but commands and tools should check those properties. * @expose * @return {boolean} true if the user may edit this part. */ canEdit(): boolean; /** * This predicate returns true if #groupable is true, * if the layer's Layer#allowGroup is true, and * if the diagram's Diagram#allowGroup is true. * * This does not check Diagram#isReadOnly or Model#isReadOnly, * but commands and tools should check those properties. * @expose * @return {boolean} true if the user may group this part. */ canGroup(): boolean; /** * This predicate returns true if #movable is true, * if the layer's Layer#allowMove is true, and * if the diagram's Diagram#allowMove is true. * * This does not check Diagram#isReadOnly or Model#isReadOnly, * but commands and tools should check those properties. * @expose * @return {boolean} true if the user may move this part. */ canMove(): boolean; /** * This predicate returns true if #reshapable is true, * if the layer's Layer#allowReshape is true, and * if the diagram's Diagram#allowReshape is true. * * This does not check Diagram#isReadOnly or Model#isReadOnly, * but commands and tools should check those properties. * @expose * @return {boolean} true if the user may reshape this part. */ canReshape(): boolean; /** * This predicate returns true if #resizable is true, * if the layer's Layer#allowResize is true, and * if the diagram's Diagram#allowResize is true. * * This does not check Diagram#isReadOnly or Model#isReadOnly, * but commands and tools should check those properties. * @expose * @return {boolean} true if the user may resize this part. */ canResize(): boolean; /** * This predicate returns true if #rotatable is true, * if the layer's Layer#allowRotate is true, and * if the diagram's Diagram#allowRotate is true. * * This does not check Diagram#isReadOnly or Model#isReadOnly, * but commands and tools should check those properties. * @expose * @return {boolean} true if the user may rotate this part. */ canRotate(): boolean; /** * This predicate returns true if #selectable is true, * if the layer's Layer#allowSelect is true, and * if the diagram's Diagram#allowSelect is true. * * This does not check Diagram#isReadOnly or Model#isReadOnly, * but commands and tools should check those properties. * @expose * @return {boolean} true if the user may select this part. */ canSelect(): boolean; /** * Gets or sets whether the user may copy this part. * The initial value is true. * @see #canCopy */ get copyable(): boolean; set copyable(value: boolean); /** * Gets or sets whether the user may delete this part. * The initial value is true. * @see #canDelete */ get deletable(): boolean; set deletable(value: boolean); /** * Gets or sets whether the user may do in-place text editing on TextBlocks in this part * that have TextBlock#editable set to true. * The initial value is true. * @see #canEdit * @see TextBlock#editable */ get textEditable(): boolean; set textEditable(value: boolean); /** * Gets or sets whether the user may group this part to be a member of a new Group. * The initial value is true. * * The grouping command is implemented by CommandHandler#groupSelection * and depends on CommandHandler#archetypeGroupData having been set to a node data object. * A Group can be ungrouped by the user if you set Group#ungroupable to true. * @see #canGroup */ get groupable(): boolean; set groupable(value: boolean); /** * Gets or sets whether the user may move this part. * The initial value is true. * @see #canMove * @see #dragComputation * @see #maxLocation * @see #minLocation */ get movable(): boolean; set movable(value: boolean); /** * Gets or sets whether a selection adornment is shown for this part when it is selected. * The initial value is true. * @see #selectionChanged * @see #selectionAdornmentTemplate */ get selectionAdorned(): boolean; set selectionAdorned(value: boolean); /** * Gets or sets whether this Part is part of the document bounds. * * The initial value is true. * A value of false causes Diagram#computeBounds to ignore this part. * If the value is false, it is possible that user will not be able to scroll far enough to see this part, * if the part's GraphObject#actualBounds are outside of the Diagram#documentBounds. */ get isInDocumentBounds(): boolean; set isInDocumentBounds(value: boolean); /** * Gets or sets whether a Layout positions this Node or routes this Link. * This property affects the value of #canLayout. * * The initial value is true, meaning that this part is laid out by the layout responsible for this Part. * If this part is a member of a Group, it is the Group#layout, * otherwise it is the Diagram#layout. * * A value of false means that this part is not affected by and does not affect any automatic layout, * so the #layoutConditions property is ignored. * You will need to make sure that it has a real #location or GraphObject#position value, * or else the Part might not be visible anywhere in the diagram. * * Another way of controlling when layouts are invalidated is by setting * Part#layoutConditions or Layout#isInitial or Layout#isOngoing. */ get isLayoutPositioned(): boolean; set isLayoutPositioned(value: boolean); /** * Gets or sets whether the user may select this part. * The initial value is true. * * If you set this to true you may also want to set #selectionObjectName * to the GraphObject#named element that you want to be adorned * when the Part is selected. * @see #canSelect * @see #isSelected * @see #selectionAdorned * @see #selectionObjectName * @see #selectionAdornmentTemplate * @see #selectionChanged */ get selectable(): boolean; set selectable(value: boolean); /** * Gets or sets whether the user may reshape this part. * The initial value is false. * @see #canReshape * @see LinkReshapingTool */ get reshapable(): boolean; set reshapable(value: boolean); /** * Gets or sets whether the user may resize this part. * The initial value is false. * * If you set this to true you may also want to set #resizeObjectName * to the GraphObject#named element that you want the user to resize. * It is also commonplace to add a TwoWay Binding of that named element's * GraphObject#desiredSize in order to save to the model data the value that the user * set via the ResizingTool. * @see #canResize * @see #resizeObjectName * @see #resizeCellSize * @see #resizeAdornmentTemplate */ get resizable(): boolean; set resizable(value: boolean); /** * Gets or sets whether the user may rotate this part. * The initial value is false. * * If you set this to true you may also want to set #rotateObjectName * to the GraphObject#named element that you want the user to rotate. * It is also commonplace to add a TwoWay Binding of that named element's * GraphObject#angle in order to save to the model data the value that the user * set via the RotatingTool. * @see #canRotate * @see #rotateObjectName * @see #rotateAdornmentTemplate */ get rotatable(): boolean; set rotatable(value: boolean); /** * Gets or sets whether this Part is selected. * The initial value is false. * * Selected parts typically are shown either with an Adornment * or with a different appearance by changing the brush or visibility of one or * more of the GraphObjects within the part. * * Changing this value does not by itself raise any "ChangingSelection" and "ChangedSelection" DiagramEvents. * Tools and the CommandHandler and methods such as Diagram#select do raise those DiagramEvents * because they want to surround changes to this property with a single "ChangingSelection" DiagramEvent beforehand and a single "ChangedSelection" afterwards. * @see #selectable * @see #selectionAdorned * @see #selectionChanged * @see #selectionObjectName * @see #selectionAdornmentTemplate */ get isSelected(): boolean; set isSelected(value: boolean); /** * Gets or sets whether this Part is highlighted. * The initial value is false. * * Highlighted parts may be shown with a different appearance by changing the brush or visibility of one or * more of the GraphObjects within the part. * One way of doing that is by using binding. * Consider part of the definition of a Node template: * ```js * new go.Shape({ * // ... shape properties * }) * // Shape.fill is bound to Node.data.color * .bind("fill", "color") * // Shape.stroke is red when Node.isHighlighted is true, black otherwise * .bind(new go.Binding("stroke", "isHighlighted", * h => h ? "red" : "black").ofObject()) * ``` * @see #highlightedChanged * @see Diagram#highlighteds * @see Diagram#highlight * @see Diagram#highlightCollection * @see Diagram#clearHighlighteds * @since 1.4 */ get isHighlighted(): boolean; set isHighlighted(value: boolean); /** * Gets or sets whether this part will draw shadows. * The initial value is false. * * By default, setting this property to true will attempt to draw shadows only * on the GraphObjects in this Part that appear to act as background objects, and * not on GraphObjects that appear to be in front of other GraphObjects in the Part. * * To finely control shadows, you may need to set GraphObject#shadowVisible on * elements of this Part, so that they explicitly do or do not get shadowed accordingly. * * The color of the shadow is determined by #shadowColor. * The opacity of the shadow color is multiplied by the opacity of the shadowed object's brush. * So, for example, if you have a Panel with a GraphObject#background * that is "transparent", the shadow that is drawn for the panel will also be transparent. * * The direction of the shadow that is cast is controlled by #shadowOffset, * and is independent of the Diagram#scale. * The sharpness of the shadow is controlled by #shadowBlur. * @see #shadowOffset * @see #shadowColor * @see #shadowBlur * @see GraphObject#shadowVisible */ get isShadowed(): boolean; set isShadowed(value: boolean); /** * Gets or sets whether this part may be animated. * The initial value is true. * @since 1.4 */ get isAnimated(): boolean; set isAnimated(value: boolean); /** * Gets or sets the function to execute when this #isHighlighted changes. * It is typically used to modify the appearance of the part. * This function must not highlight or unhighlight any parts. * * If this property value is a function, it is called with one argument, * this Part that whose #isHighlighted value changed. * By default this property is null. * @see #isHighlighted * @since 1.7 */ get highlightedChanged(): ((thisPart: Part) => void) | null; set highlightedChanged(value: ((thisPart: Part) => void) | null); /** * Gets or sets the name of the GraphObject that should get a selection handle * when this part is selected. * The value of this property affects the value of #selectionObject. * The initial value is an empty string, meaning the whole Part itself gets any selection handle. * * If no GraphObject has a GraphObject#name that is this name, #selectionObject returns the whole Part. * @see #selectable * @see #selectionObject */ get selectionObjectName(): string; set selectionObjectName(value: string); /** * Gets or sets the Adornment template used to create a selection handle for this Part. * * If this is null, depending on the class of this Part, the value of Diagram#nodeSelectionAdornmentTemplate, Diagram#groupSelectionAdornmentTemplate, * or Diagram#linkSelectionAdornmentTemplate is used instead. * * It is commonplace to make use of a Placeholder in an Adornment for a Node, Group, or simple Part. * The Placeholder represents the Adornment#adornedObject of the adorned Part. * For Links, the Adornment must be of Panel#type Panel.Link. * @see #selectable * @see #selectionObjectName */ get selectionAdornmentTemplate(): Adornment | null; set selectionAdornmentTemplate(value: Adornment | null); /** * This read-only property returns the GraphObject that should get a selection handle when this part is selected. * The value will be in the visual tree of this Part and is usually named with * the value of #selectionObjectName. * When the #selectionObjectName is unspecified, this whole Part is used as the "selection object". * @see #selectable * @see #selectionObjectName */ get selectionObject(): GraphObject; /** * Gets or sets the function to execute when this part is selected or deselected. * It is typically used to modify the appearance of the part. * This function must not select or deselect any parts. * * If this property value is a function, it is called with one argument, * this Part that was selected or that became unselected. * When it is called, the value of Diagram#skipsUndoManager is temporarily set to true. * By default this property is null. * * This function is called with Diagram#skipsUndoManager temporarily set to true, * so that any changes to GraphObjects are not recorded in the UndoManager. * You do not need to start and commit any transaction in this function. * @see #isSelected * @see #selectionAdorned * @see #selectionAdornmentTemplate */ get selectionChanged(): ((thisPart: Part) => void) | null; set selectionChanged(value: ((thisPart: Part) => void) | null); /** * Gets or sets the adornment template used to create a resize handle Adornment for this part. * This is used by the ResizingTool, ToolManager#resizingTool. * * If an Adornment is supplied, it is normally a Panel.Spot panel that contains a Placeholder * with some number of resize handles at the four corners or at the four side midpoints. * @see #resizable * @see #resizeObjectName * @see ResizingTool */ get resizeAdornmentTemplate(): Adornment | null; set resizeAdornmentTemplate(value: Adornment | null); /** * Gets or sets the name of the GraphObject that should get a resize handle * when this part is selected. * The value of this property affects the value of #resizeObject. * The initial value is an empty string, meaning the whole Part itself gets any resize handle. * @see #resizable * @see #resizeObject * @see ResizingTool */ get resizeObjectName(): string; set resizeObjectName(value: string); /** * This read-only property returns the GraphObject that should get resize handles when this part is selected. * The value will be in the visual tree of this Part and is usually named with * the value of #resizeObjectName. * @see #resizable * @see #resizeObjectName * @see ResizingTool */ get resizeObject(): GraphObject; /** * Gets or sets the width and height multiples used when resizing. * By default this property is the Size(NaN, NaN). * @see #resizable * @see #resizeObjectName * @see ResizingTool */ get resizeCellSize(): Size; set resizeCellSize(value: Size); /** * Gets or sets the adornment template used to create a rotation handle Adornment for this part. * This is used by the RotatingTool, ToolManager#rotatingTool. * * This Adornment should not have a Placeholder in it, because the RotatingTool will position it away from the * #rotateObject at its GraphObject#angle. * @see #rotatable * @see #rotateObjectName * @see RotatingTool */ get rotateAdornmentTemplate(): Adornment | null; set rotateAdornmentTemplate(value: Adornment | null); /** * Gets or sets the name of the GraphObject that should get a rotate handle * when this part is selected. * The value of this property affects the value of #rotateObject. * The initial value is an empty string, meaning the whole Part itself gets any rotate handle. * @see #rotatable * @see #rotateObject * @see RotatingTool */ get rotateObjectName(): string; set rotateObjectName(value: string); /** * This read-only property returns the GraphObject that should get rotate handles when this part is selected. * The value will be in the visual tree of this Part and is usually named with * the value of #rotateObjectName. * @see #rotatable * @see #rotateObjectName * @see RotatingTool */ get rotateObject(): GraphObject; /** * Gets or sets the spot on the #rotateObject * that is used in rotating this part with the RotatingTool. * * Value must be of the type Spot. * The value must be a specific spot -- i.e. one for which Spot#isSpot is true, or else `Spot.Default`. * * If the value is `Spot.Default`, the RotatingTool uses * the locationSpot if the #rotateObject is equal to the #locationObject, otherwise * it uses `Spot.Center`. * * The initial value is `Spot.Default`. * * @see #rotateObjectName * @since 2.0 */ get rotationSpot(): Spot; set rotationSpot(value: Spot); /** * Gets or sets a text string that is associated with this part. * * The initial value is an empty string. * This value is often used for sorting. */ get text(): string; set text(value: string); /** * Gets or sets the Group of which this Part or Node is a member. * This will be null if this is a top-level part. * * You cannot set this property on a Link; it is set for you automatically * based on the group memberships of the connected nodes. * You cannot set this property on an Adornment at all. * * A template should not be a member of any group. * @see Group#memberParts * @see #findTopLevelPart * @see #isTopLevel */ get containingGroup(): Group | null; set containingGroup(value: Group | null); /** * Gets or sets the function that is called after this Part has changed which Group it belongs to, if any. * It is typically used to modify the appearance of the part. * The first argument will be this Part. * The second argument will be the old Group, or null if it had been a top-level part. * The third argument will be the new Group, or null if it is now a top-level part. * * If the value is a function, that function must not modify the part's containing Group. * The containing Group has already been changed -- trying to change it again may produce undefined behavior. * * The initial value is null -- no function is called. */ get containingGroupChanged(): ((thisPart: Part, oldGroup: Group | null, newGroup: Group | null) => void) | null; set containingGroupChanged(value: ((thisPart: Part, oldGroup: Group | null, newGroup: Group | null) => void) | null); /** * Return how deep this part is in the hierarchy of nested Groups. * For parts that have no #containingGroup this returns zero. * * If you want to know how deep a Node is in a tree structure, call Node#findTreeLevel. * @return {number} * @since 1.5 */ findSubGraphLevel(): number; /** * Gets the top-level Part for this part, which is itself when #isTopLevel is true. * If this Part is a member of a Group, this returns the top-level Part for that Group. * If this is a Node that is a label node for a labeled Link, this returns the top-level Part for that Link. * * If this is a Node and you are searching for the root of the tree that this node is in, use Node#findTreeRoot. * @return {Part} This will not return null. * @since 1.1 */ findTopLevelPart(): Part; /** * This read-only property is true when this part is not member of any Group node * nor is it a label node for a Link. * @see #containingGroup * @see Node#labeledLink */ get isTopLevel(): boolean; /** * This predicate is true if this part is a member of the given Part, perhaps indirectly. * * If the given part is a Group and this part is a member of the given group, this returns true. * If this part is a Node and it is a label node for a link that is a member of the given group, this returns true. * Otherwise this searches recursively any Part#containingGroup of the given part. * * A part cannot be contained by itself. * A template should not be a member of any group. * * If this is a Node and you want to find whether it is in a subtree whose root is a given Node, use Node#isInTreeOf. * @param {Part} part * @return {boolean} */ isMemberOf(part: Part): boolean; /** * Find the Group that perhaps indirectly contains both this part and another one. * If this is a Group and it contains the OTHER Part, return this. * If the OTHER Part is a Group and it contains this Part, return that OTHER Part. * * This returns null if the two parts are unrelated in the hierarchy of part membership. * If non-null, the result is a Group. * * If you want to find the Node that is the tree parent of two Nodes, * call Node#findCommonTreeParent. * @param {Part} other * @return {Group} may be null */ findCommonContainingGroup(other: Part): Group | null; /** * Gets or sets flags that control when the Layout that is responsible for this Part is invalidated. * The initial value is Part.LayoutStandard, * which causes the layout for this part to be invalidated when the part is added or removed or changes visibility or size. * * Individual layout conditions include: Part.LayoutAdded, Part.LayoutRemoved, * Part.LayoutShown, Part.LayoutHidden, and Part.LayoutNodeSized. * * This property is ignored when #isLayoutPositioned is false -- no operation on this Part * will by itself cause the responsible Layout to be invalidated. * * You can also control when layouts are invalidated is by setting Layout#isInitial or Layout#isOngoing. */ get layoutConditions(): number; set layoutConditions(value: number); /** * This predicate is called by Layout implementations to decide whether this Part * should be positioned and might affect the positioning of other Parts. * * This is false if #isLayoutPositioned is false, if #isVisible returns false, * or if the part is in a temporary Layer. * * This does not check Diagram#isReadOnly or Model#isReadOnly, * but commands and tools should check those properties. * @expose * @return {boolean} */ canLayout(): boolean; /** * Invalidate the Layout that is responsible for positioning this Part. * If this part is in a Group, invalidate its Group#layout, if it has one. * Otherwise invalidate the Diagram#layout. * * But note that if #isLayoutPositioned is false, or if it is in a temporary Layer, * or if it is not in a diagram or group, no layout is invalidated. * @param {number=} condition the reason that the layout should be invalidated; * if this argument is not supplied, any value of #layoutConditions other than Part.LayoutNone * will allow the layout to be invalidated. */ invalidateLayout(condition?: number): void; /** * Gets or sets the function used to determine the location that this Part can be dragged to. * The first argument is a reference to the Part being dragged, the second argument is a Point describing * the proposed location, and the third argument is a snapped location, if one was determined during dragging. * It should return a Point that is the proposed new location. * * By default this function is null and the DraggingTool uses the snapped location, * if one was determined and if DraggingTool#isGridSnapEnabled is true, * or the proposed location (the second argument) if not snapping to a grid. * * In either case the DraggingTool will limit the proposed new location by #minLocation and #maxLocation. * * The function, if supplied, must not have any side-effects. * * An example that limits moving a Node to the current viewport: * ```js * function stayInViewport(part, pt, gridpt) { * var diagram = part.diagram; * if (diagram === null) return pt; * // compute the area inside the viewport * var v = diagram.viewportBounds.copy(); * v.subtractMargin(diagram.padding); * // get the bounds of the part being dragged * var bnd = part.actualBounds; * var loc = part.location; * // now limit the location appropriately * var l = v.x + (loc.x - bnd.x); * var r = v.right - (bnd.right - loc.x); * var t = v.y + (loc.y - bnd.y); * var b = v.bottom - (bnd.bottom - loc.y); * if (l <= gridpt.x && gridpt.x <= r && t <= gridpt.y && gridpt.y <= b) return gridpt; * var p = gridpt.copy(); * if (diagram.toolManager.draggingTool.isGridSnapEnabled) { * // find a location that is inside V but also keeps the part's bounds within V * var cw = diagram.grid.gridCellSize.width; * if (cw > 0) { * while (p.x > r) p.x -= cw; * while (p.x < l) p.x += cw; * } * var ch = diagram.grid.gridCellSize.height; * if (ch > 0) { * while (p.y > b) p.y -= ch; * while (p.y < t) p.y += ch; * } * return p; * } else { * p.x = Math.max(l, Math.min(p.x, r)); * p.y = Math.max(t, Math.min(p.y, b)); * return p; * } * } * ``` * Note that for this functionality you will also probably want to set Diagram#autoScrollRegion to be a zero margin. * ```js * myDiagram.nodeTemplate = * new go.Node(. . ., * { dragComputation: stayInViewport }, * . . . * ) * ``` * @see #maxLocation * @see #minLocation */ get dragComputation(): ((thisPart: Part, newLoc: Point, snappedLoc: Point) => Point) | null; set dragComputation(value: ((thisPart: Part, newLoc: Point, snappedLoc: Point) => Point) | null); /** * Gets or sets the X and Y offset of this part's shadow. This is only relevant if #isShadowed is true. * The initial value is (6, 6). * @see #isShadowed * @see #shadowColor * @see #shadowBlur */ get shadowOffset(): Point; set shadowOffset(value: Point); /** * Gets or sets the CSS string that describes a shadow color. Default is 'gray'. * Brushes cannot be used for this property -- only strings. * * The opacity of the shadow color is multiplied by the opacity of the shadowed object's brush. * So, for example, if you have a Panel with a GraphObject#background * that is "transparent", the shadow that is drawn for the panel will also be transparent. * @see #isShadowed * @see #shadowOffset * @see #shadowBlur */ get shadowColor(): string; set shadowColor(value: string); /** * Gets or sets the numerical value that describes the shadow's blur. Number must be non-negative and non-infinity. * A value of 0 would mean the shadow does not blur and larger numbers represent increasingly more blur. * The total blur area is independent of the Part's area and can become quite large as this number is increased. * * This value is not affected by scale. Default value is 4. * @see #isShadowed * @see #shadowOffset * @see #shadowColor */ get shadowBlur(): number; set shadowBlur(value: number); } /** * An Adornment is a special kind of Part that is associated with another Part, * the Adornment#adornedPart. * * Adornments are normally associated with a particular GraphObject in the adorned Part -- * that is the value of #adornedObject. * However, the #adornedObject may be null, in which case the #adornedPart will also be null. * * The area occupied by the adorned object is represented in the Adornment's visual tree by a Placeholder. * The placeholder is always the Part#locationObject, * although you may specify any Spot as the Part#locationSpot. * An adornment need not have a placeholder, but it may have at most one. * * Adornments can be distinguished by their Part#category. * This property can be an arbitrary string value determined by the code creating the adornment, * typically a tool that wants to be able to tell various adornments apart from each other. * Use the Part#findAdornment method to find an adornment for a part of a given category. * * For example, one of the Adornments created by Part#updateAdornments when the part * Part#isSelected has the Part#category of "Selection". * Those created by ResizingTool#updateAdornments have a category of "Resize" * and normally contain eight resize handles. * * Besides the selection Adornment and tool Adornments, Adornments are also used for * context menus and tooltips. * The #adornedObject in such cases refers to the GraphObject to which the * the context menu or tooltip applies. * * There cannot be any links connected to an Adornment, * nor can an Adornment have members or be a member of a group. * * An Adornment cannot have its own Adornments. * An Adornment cannot be selected. * * Adornments are not positioned by a Layout because they are normally positioned * according to the Part that they adorn. * * For more discussion and examples, see Selection, * ToolTips, * Context Menus, and * Tools. * @extends Part * @unrestricted */ export class Adornment extends Part { /** * Constructs an empty Adornment of the given #type. Default type is Panel.Position. * The panel type must be one of the enumerated values defined on the Panel class, including: * Panel.Position, Panel.Vertical, Panel.Horizontal, Panel.Table, * Panel.Auto, Panel.Spot, or Panel.Viewbox. The string value such as "Auto" may also be used. * * Usage example: * *```js * // Constructs an Adornment, sets properties on it, * // adds a data binding to it, * // and adds two GraphObjects to the Adornment: * const a = new go.Adornment("Auto", { * margin: 5, * background: "red" * }) * .add(new go.Shape("RoundedRectangle")) * .add(new go.TextBlock("Some Text")) * ``` * * @param {string=} type Panel Type as either a string or PanelLayout. such as "Vertical", "Auto", or Panel.Vertical, Panel.Auto, are accepted. * If not supplied, the default Panel type is "Position". * @param {Partial=} init Optional initialization properties. */ constructor(type?: PanelLayout | string, init?: Partial); /** * Constructs an empty Panel. Default type is Panel.Position. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * This read-only property returns a Placeholder that this Adornment may contain in its visual tree. * This may be null if there is no such placeholder object. */ get placeholder(): Placeholder | null; /** * Gets or sets the GraphObject that is adorned. * Setting this property updates the adorned object's Part by calling Part#addAdornment. * This may be null if the Adornment does not adorn a particular object. */ get adornedObject(): GraphObject | null; set adornedObject(value: GraphObject | null); /** * This read-only property returns the Part that contains the adorned object. * This will be null if the #adornedObject is null. */ get adornedPart(): Part | null; } /** * A Node is a Part that may connect to other nodes with Links, * or that may be a member of a Group. * * Group inherits from Node, * enabling nodes to logically contain other nodes and links. *

* For a more general discussion of how to define nodes, see Introduction to Nodes. * * Although you can create a Node and Diagram#add it to a Diagram, this does not update the Model. * It is more common to create a node by adding a node data object to the model * by calling Model#addNodeData. For example: * ```js * myDiagram.startTransaction("make new node"); * myDiagram.model.addNodeData({ key: "Omega" }); * myDiagram.commitTransaction("make new node"); * ``` * * This will cause a Node or simple Part to be created (copying the template found in Diagram#nodeTemplateMap), * added to the Diagram in some Layer (based on Part#layerName), and bound to the node data * (resulting in Panel#data referring to that node data object). * If you do not keep a reference to that JavaScript object, as the above code does not, * you can retrieve it later by calling Model#findNodeDataForKey. * * It is very common to initialize a Diagram by setting Model#nodeDataArray to a JavaScript Array * of JavaScript objects holding the properties that you need in your model. * Nearly all of the samples do this kind of initialization. * * You can delete a Node by either calling Diagram#remove or by calling Model#removeNodeData. * The latter obviously will modify the Model; the former does so if the Node was created from model data. * Commands such as CommandHandler#deleteSelection call these methods within a transaction. * * You can find all of the Links that are connected with a Node by calling #findLinksConnected. * Because links normally have a direction, you can find all of the links that have their Link#toNode * be a given Node by calling #findLinksInto. * Similarly, you can call #findLinksOutOf to find all of the links coming out from a node; * such links have their Link#fromNode be that node. * For tree-structured graphs, use #findTreeChildrenLinks or #findTreeParentLink. * * If you are not so interested in the links but are interested in the nodes at the other end of the links * connecting with a node, there are other methods that you can call. * #findNodesConnected returns all of the nodes that are at the other end of the links that * connect with a given node. * #findNodesInto and #findNodesOutOf return the subsets of those nodes considering * only those links that go into or come out of the given node. * For tree-structured graphs, use #findTreeChildrenNodes or #findTreeParentNode. * * For example, to operate on the data of all of the destination nodes: * ```js * var it = somenode.findNodesOutOf(); * while (it.next()) { * var child = it.value; * if (child.data.text.indexOf("special") >= 0) { ... } * } * ``` * * You can link two nodes by creating a new Link, setting its Link#toNode and Link#fromNode * (in either order), and Diagram#adding it to the diagram. * But it is more common to add a link data object to the Diagram#model by calling GraphLinksModel#addLinkData. * Just creating and adding a Link will not update the model. * * Thus to add a link when using a GraphLinksModel you should do something like: * ```js * myDiagram.startTransaction("make new link"); * myDiagram.model.addLinkData({ from: "Alpha", to: "Beta" }); * myDiagram.commitTransaction("make new link"); * ``` * * Where you would substitute the keys of the actual nodes that you want to connect with a link. * If you are using a TreeModel, there are no link data objects, so you just need to call * TreeModel#setParentKeyForNodeData to specify the "parent" node's key for a "child" node data. * * To find a Link given a link data object in the GraphLinksModel, * call Diagram#findLinkForData. When using a TreeModel, call either Diagram#findNodeForData * or Diagram#findNodeForKey to get a Node, and then call #findTreeParentLink to get the Link, if any exists. * * To find a link that connects two nodes, call #findLinksTo or #findLinksBetween. * With the former method, the direction matters; with the latter method it returns links in either direction. * * As links connect with a node or are disconnected, you may want to update the appearance of the node. * You can set the #linkConnected and #linkDisconnected properties to be functions that are called. * These functions must not modify any link relationships -- the properties just exist to update the appearance of the node. * A typical usage would be to change the color or figure of a shape. * * You can control whether the user may draw a new link or reconnect a link between a pair of Nodes * by affecting the result of LinkingBaseTool#isValidLink. * You can override that predicate on LinkingTool and RelinkingTool, * but it is easier to set the #linkValidation or * LinkingBaseTool#linkValidation functional property. *

* For a more general discussion of validation, see Introduction to Validation. * * Nodes also support the ability to provide logical and physical distinctions in the connection points * that links use at a node. These connection objects are called "ports". * By default the port object will be the whole Node. * However, you can set the GraphObject#portId property on any GraphObject in the visual tree of a node * to cause that element to be treated as a "port". * The "port id" is just a string that ought to be unique amongst all of the port elements in the node. * * In the case of a node only having a single port, you should set the GraphObject#portId as an empty string. * When there is no such element declared as the default port, it uses the whole node. * You can use the #port property to get the only port element. * * When a node should have multiple ports, * i.e. multiple GraphObjects acting as separate connection points for links, * you should set each port's GraphObject#portId to a string value that is unique for the node. * When there may be multiple ports on a node, you can get a collection of elements representing ports * by using the #ports property. * Use the #findPort method to find a particular port element by name. * * Note: the only kind of model that can save port information, i.e. portIds that are not an empty string, * for links is a GraphLinksModel whose GraphLinksModel#linkFromPortIdProperty and * GraphLinksModel#linkToPortIdProperty have been set to name properties on the link data objects. *

* For a more general discussion of ports, see Introduction to Ports. * * All of the "findLinks..." and "findNodes..." methods mentioned above take an optional port id argument. * When no argument is passed, these methods consider all links connecting with the node. * When a port id argument is provided, these methods only consider links that connect with that port * in the given node. * Thus when navigating through the diagram, you can easily look at all of the nodes that links coming out of * a given node go to. Or you can just look at those nodes at the ends of links coming out of a particular port. * * You can also control the default connecting behavior of Links at each port. * Because a port can be any GraphObject, they are all properties on GraphObject. * The properties are duplicated so that you can guide the "from" ends of links differently from the "to" ends of links. * The properties include: * - GraphObject#fromSpot, GraphObject#toSpot * - GraphObject#fromEndSegmentLength, GraphObject#toEndSegmentLength * - GraphObject#fromShortLength, GraphObject#toShortLength * - GraphObject#fromLinkable, GraphObject#toLinkable * - GraphObject#fromLinkableDuplicates, GraphObject#toLinkableDuplicates * - GraphObject#fromLinkableSelfNode, GraphObject#toLinkableSelfNode * - GraphObject#fromMaxLinks, GraphObject#toMaxLinks * * The "...Spot" and "...Length" properties control the position and routing of links at a port. * The "...Linkable..." and "...MaxLinks" properties control whether or not users can draw a new link * or reconnect an existing link from or to a port. * (The "...Spot" and "...Length" properties also exist on Link, to override for a particular * link the default values that come from a port element.) *

* For a more general discussion of link points, see Introduction to Link Connection Points. * * When the graph is tree-structured, you can use several functions for traversing the tree: * - #findTreeParentNode * - #findTreeChildrenNodes * - #findTreeParentLink * - #findTreeChildrenLinks * - #findTreeRoot * - #findTreeParentChain * - #findTreeParts * - #findCommonTreeParent * - #isInTreeOf * - #findTreeLevel * * Determining whether a tree grows from the root via links that go out to the children or vice-versa * is controlled for the whole diagram by the Diagram#isTreePathToChildren property. * However an individual link will be ignored by the above functions if Link#isTreeLink is false. * * The Node class also supports the notion of expanding and collapsing a subtree of nodes and links, * causing those nodes and links to be shown or hidden. * Principally this is a matter of setting Node#isTreeExpanded. * Of course if the diagram's graph is not tree-structured, these concepts and properties might not apply. * * If you want to change the appearance of the node you can do so in a function that you assign to * the #treeExpandedChanged property. * This function must not modify any link relationships or expand or collapse any subtrees -- the property just exists * to update the appearance of the node. * * There is an option for link routing to try to avoid crossing over nodes: * Link#routing = Link.AvoidsNodes. * You can control whether such links should avoid or ignore a node by setting #avoidable. * Set #avoidableMargin to control the area beyond the GraphObject#actualBounds * where AvoidsNodes links should not go. *

* For more discussion and examples, see Nodes, * Ports, and * Link Points. *

* For more about trees, see Trees, and * SubTrees. *

* To customize user-resizing behavior, please read * Introduction to the ResizingTool. * To customize user-rotating behavior, please read * Introduction to the RotatingTool. * * Only Nodes that are in Diagrams can have connections via Links. * Templates should not be connected with Links, be labels of Links, be members of Groups, or have any Adornments. * @extends Part * @unrestricted */ export class Node extends Part { /** * Constructs an empty Node of the given #type. Default type is Panel.Position. * The panel type must be one of the enumerated values defined on the Panel class, including: * Panel.Position, Panel.Vertical, Panel.Horizontal, Panel.Table, * Panel.Auto, Panel.Spot, or Panel.Viewbox. The string value such as "Auto" may also be used. * * Usage example: * *```js * // Constructs a Node, sets properties on it, * // adds a data binding to it, * // and adds two GraphObjects to the Node: * const n = new go.Node("Auto", { * margin: 5, * background: "red" * }) * .bind("location", "loc") * .add(new go.Shape("RoundedRectangle")) * .add(new go.TextBlock("Some Text")) * ``` * * @param {string=} type Panel Type as either a string or PanelLayout. such as "Vertical", "Auto", or Panel.Vertical, Panel.Auto, are accepted. * If not supplied, the default Panel type is "Position". * @param {Partial=} init Optional initialization properties. */ constructor(type?: PanelLayout | string, init?: Partial); /** * Constructs an empty Panel. Default type is Panel.Position. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * This value for Node#portSpreading indicates that links connecting with a port * should all connect at a single point on the side(s) indicated by a Spot that is Spot#isSide. * @constant */ static SpreadingNone: EnumValue; /** * This default value for Node#portSpreading indicates that links connecting with a port * should be distributed evenly along the side(s) indicated by a Spot that is Spot#isSide. * @constant */ static SpreadingEvenly: EnumValue; /** * This value for Node#portSpreading indicates that links connecting with a port * should packed together based on the link's shape's width * on the side(s) indicated by a Spot that is Spot#isSide. * @constant */ static SpreadingPacked: EnumValue; /** * (undocumented) * @param {Node} other * @param {string=} thisportid * @param {string=} otherportid */ invalidateLinkBundle(other: Node, thisportid?: string, otherportid?: string): void; /** * (undocumented) * This invalidates the routes of all links connected to this node. * Basically this calls Link#invalidateRoute on all connected links * and invalidates any cached side-connection information. * @param {Set.=} ignore An optional set of Links to ignore. */ invalidateConnectedLinks(ignore?: Set): void; /** * Gets or sets how link points are computed when the port spot is a "side" spot. * The value must be one of Node.SpreadingNone|SpreadingNone, * Node.SpreadingEvenly|SpreadingEvenly, Node.SpreadingPacked|SpreadingPacked. * The default value is Node.SpreadingEvenly. * @since 1.5 */ get portSpreading(): EnumValue; set portSpreading(value: EnumValue); /** * Gets or sets whether this Node is to be avoided by Links * whose Link#routing is Link.AvoidsNodes. * * The default value is true. */ get avoidable(): boolean; set avoidable(value: boolean); /** * Gets or sets the margin around this Node in which avoidable links will not be routed. * * You may need to increase the #fromEndSegmentLength and #toEndSegmentLength in * order to prevent link routes from turning within the avoidable area around the Node. * * Value must be of type Margin. * The default margin is Margin(2,2,2,2) */ get avoidableMargin(): MarginLike; set avoidableMargin(value: MarginLike); /** * Return the area to be avoided for this node -- the node's GraphObject#actualBounds * plus the Node#avoidableMargin. * @expose * @param {Rect} result a Rect to be modified and returned. * @return {Rect} the area in document coordinates. * @since 2.2 */ getAvoidableRect(result: Rect): Rect; /** * Starting with this node, walk up the chain of containingGroups to find a node that is visible. * This can be overridden to find a tree-parent/ancestor if the reason that this node * is not visible is because of a collapsed tree rather than a collapsed group. * @expose * @since 2.2 * @return {Node} */ findVisibleNode(): Node | null; /** * This read-only property returns an iterator over all of the Links that are connected with this node. * This includes both links that are coming out of this node as well as links that are going into this node. * Setting Link#fromNode or Link#toNode to refer to this Node * will add that Link to this collection. * * Use the #findLinksConnected, #findLinksOutOf, or #findLinksInto methods * to get different subsets of the links, depending on direction or depending on connecting to a particular port. * * A template should not have any links connected with it. */ get linksConnected(): Iterator; /** * Return a collection of Links that connect with this Node or any in its subtree, excluding any isTreeLink Links. * For trees this is the analog of Group#findExternalLinksConnected for Groups. * @return {Iterator.} * @since 2.2 */ findExternalTreeLinksConnected(): Iterator; /** * Returns an iterator over all of the Links that connect with this node in either direction, * perhaps limited to the given port id on this node. * @expose * @param {string|null=} pid A port identifier string; if null the link's portId is ignored and all links are included in the search. * @return {Iterator.} */ findLinksConnected(pid?: string | null): Iterator; /** * Returns an iterator over all of the Links that come out of this node, * perhaps limited to the given port id on this node. * @param {string|null=} pid A port identifier string; if null the link's portId is ignored and all links are included in the search. * @return {Iterator.} */ findLinksOutOf(pid?: string | null): Iterator; /** * Returns an iterator over all of the Links that go into this node, * perhaps limited to the given port id on this node. * @param {string|null=} pid A port identifier string; if null the link's portId is ignored and all links are included in the search. * @return {Iterator.} */ findLinksInto(pid?: string | null): Iterator; /** * Returns an iterator over the Nodes that are connected with this node * in either direction, perhaps limited to the given port id on this node. * * The results may include this node itself if there is a reflexive link connecting this node with itself. * @param {string|null=} pid A port identifier string; if null the link's portId is ignored and all links are included in the search. * @return {Iterator.} */ findNodesConnected(pid?: string | null): Iterator; /** * Returns an iterator over the Nodes that are connected with this node * by links coming out of this node, perhaps limited to the given port id on this node. * @param {string|null=} pid A port identifier string; if null the link's portId is ignored and all links are included in the search. * @return {Iterator.} */ findNodesOutOf(pid?: string | null): Iterator; /** * Returns an iterator over the Nodes that are connected with this node * by links going into this node, perhaps limited to the given port id on this node. * @param {string|null=} pid A port identifier string; if null the link's portId is ignored and all links are included in the search. * @return {Iterator.} */ findNodesInto(pid?: string | null): Iterator; /** * Returns an iterator over all of the Links that go from this node to another node or vice-versa, * perhaps limited to a given port id on this node and a port id on the other node. * * If you want all of the links between two nodes in just one direction, use #findLinksTo. * @param {Node} othernode * @param {string|null=} pid A port identifier string; if null the link's portId is ignored and all links are included in the search. * @param {string|null=} otherpid A port identifier string; if null the link's portId is ignored and all links are included in the search. * @return {Iterator.} * @since 1.2 */ findLinksBetween(othernode: Node, pid?: string | null, otherpid?: string | null): Iterator; /** * Returns an iterator over all of the Links that go from this node to another node, * perhaps limited to a given port id on this node and a port id on the other node. * * If you want all of the links between two nodes in both directions, use #findLinksBetween. * @param {Node} othernode * @param {string|null=} pid A port identifier string; if null the link's portId is ignored and all links are included in the search. * @param {string|null=} otherpid A port identifier string; if null the link's portId is ignored and all links are included in the search. * @return {Iterator.} * @since 1.2 */ findLinksTo(othernode: Node, pid?: string | null, otherpid?: string | null): Iterator; /** * Gets or sets the function that is called after a Link has been connected with this Node. * It is typically used to modify the appearance of the node. * The first argument will be this Node. * The second argument will be a Link that is now connected with this node. * The third argument will be a GraphObject port indicating which port the link was connected with. * * If the value is a function, that function must not modify what this Node is connected with. * The Link has already been added -- trying to remove it or another link may produce undefined behavior. * However, the other end of the link may not yet have been connected with a node (and might never be), * so you cannot depend on looking at what the link connects with. * * The default value is null -- no function is called. */ get linkConnected(): ((thisNode: Node, newLink: Link, thisPort: GraphObject) => void) | null; set linkConnected(value: ((thisNode: Node, newLink: Link, thisPort: GraphObject) => void) | null); /** * Gets or sets the function that is called after a Link has been disconnected from this Node. * It is typically used to modify the appearance of the node. * The first argument will be this Node. * The second argument will be a Link that had been connected with this node. * The third argument will be a GraphObject port indicating which port the link had been connected with. * * If the value is a function, that function must not modify what this Node is connected with. * The Link has already been removed -- trying to add it or another link may produce undefined behavior. * The other end of the link may not yet have been disconnected from a node (and might never be), * so you cannot depend on looking at what the link connects with. * * The default value is null -- no function is called. */ get linkDisconnected(): ((thisNode: Node, oldLink: Link, thisPort: GraphObject) => void) | null; set linkDisconnected(value: ((thisNode: Node, oldLink: Link, thisPort: GraphObject) => void) | null); /** * Gets or sets a predicate that determines whether or not a Link may be connected with this node. * If this is non-null, the predicate is called in addition to the predicate that is LinkingBaseTool#linkValidation * on the LinkingTool and RelinkingTool. * See LinkingBaseTool#isValidLink for more details. * * The default predicate is null, which is equivalent to simply returning true. * The first argument will be the proposed "from" Node (may be null). * The second argument will be the proposed "from" GraphObject port (may be null). * The third argument will be the proposed "to" Node (may be null). * The fourth argument will be the proposed "to" GraphObject port (may be null). * The fifth argument may be null when asking about creating a new link, * or may be a Link when asking about reconnecting an existing link. * * The function, if supplied, must not have any side-effects. * @since 1.3 */ get linkValidation(): ((fromNode: Node, fromPort: GraphObject, toNode: Node, toPort: GraphObject, link: Link) => boolean) | null; set linkValidation(value: ((fromNode: Node, fromPort: GraphObject, toNode: Node, toPort: GraphObject, link: Link) => boolean) | null); /** * This read-only property is true when this Node is a label node for a Link. * * If this is true, then `n.labeledLink` will be a Link and `n.labeledLink.isLabeledLink` will be true. * @see #labeledLink */ get isLinkLabel(): boolean; /** * Gets or sets the Link for which this Node is acting as a smart label. * Most nodes do not act as link labels, so this property will be null. * * A template should not be a label node for a link. * @see #isLinkLabel */ get labeledLink(): Link | null; set labeledLink(value: Link | null); /** * Find a GraphObject with a given GraphObject#portId. * If no such GraphObject is found, search for one with the empty string as its port identifier. * Finally, when failing to find a port with either the given name or the empty string, * this method returns this whole node itself. * @param {string} pid * @return {GraphObject} */ findPort(pid: string): GraphObject; /** * This read-only property returns the primary GraphObject representing a port in this node. * If there is a GraphObject whose GraphObject#portId is the empty string, return it. * If there is no such element, just return this whole Node. */ get port(): GraphObject; /** * This read-only property returns an iterator over all of the GraphObjects in this node that act as ports. */ get ports(): Iterator; /** * This predicate is true if this node is a child of the given Node, perhaps indirectly as a descendant. * * If this node is a child of the given node according to Diagram#isTreePathToChildren, this returns true. * Otherwise this searches recursively the chain of tree parents of this node, * ignoring links for which Link#isTreeLink is false. * A node cannot be in its own subtree. * * If you what to find out whether this Node is (perhaps indirectly) contained by a Group, use Part#isMemberOf. * @param {Node} node the Node that might be a parent or ancestor of this node. * @return {boolean} true if the given node is an ancestor of this node, but false otherwise, including false if it is the same node. * @see #findTreeRoot * @see #findTreeParentChain */ isInTreeOf(node: Node): boolean; /** * Return the Node that is at the root of the tree that this node is in, perhaps this node itself. * * This node will be #isInTreeOf the resulting node, unless the resulting node is this node itself. * The graph traversal will ignore links for which Link#isTreeLink is false. * * If you want to search up the containment hierarchy of Groups, use Part#findTopLevelPart. * @return {Node} If this Node has no "tree parent", this returns itself. * @see Diagram#isTreePathToChildren * @see #findTreeParentChain * @since 1.2 */ findTreeRoot(): Node; /** * Find the Node that is the perhaps indirect tree parent of both this node and another one, * or this node if it is an ancestor of the other node, or vice-versa. * * If you want to find the Group that contains two Parts, call Part#findCommonContainingGroup. * @param {Node} other * @return {Node} may be null if in different trees, * or may be itself if the OTHER argument is THIS node, * or may be itself if the OTHER node is a descendant of THIS node, * or may be the OTHER node if THIS node is in the tree of the OTHER node. * @see #findTreeRoot * @see #findTreeParentChain * @since 1.5 */ findCommonTreeParent(other: Node): Node | null; /** * Returns the Link that connects with the tree parent Node of this node if the graph is tree-structured, * if there is such a link and Link#isTreeLink is true. * @return {Link} The Link to the parent Node, or null if there is no parent node. * @see #findTreeParentNode * @see #findTreeChildrenLinks * @see Diagram#isTreePathToChildren * @see #findTreeRoot * @see #findTreeParentChain * @since 1.1 */ findTreeParentLink(): Link | null; /** * Returns the Node that is the tree parent of this node if the graph is tree-structured, if there is a parent. * Links for which Link#isTreeLink is false are ignored. * @return {Node} The parent Node, or null if there is no parent node. * @see #findTreeParentLink * @see #findTreeChildrenNodes * @see Diagram#isTreePathToChildren * @see #findTreeRoot * @see #findTreeParentChain * @since 1.1 */ findTreeParentNode(): Node | null; /** * Return a collection of Parts including this Node, * its tree parent link and node, and so on up the chain to the root node. * * This calls #findTreeParentLink and #findTreeParentNode. * Links for which Link#isTreeLink is false are ignored. * * This may result in undefined behavior if there are cycles of Links that are Link#isTreeLink. * * The result will include this node and the "root" node and all nodes and links in between. * The root node is also accessible directly via #findTreeRoot. * If any of the nodes are Groups, their member parts are not included. * @return {Set.} A Set of Nodes and Links. * @see #findTreeRoot * @see #findTreeParts * @since 1.7 */ findTreeParentChain(): Set; /** * Return how deep this node is in a tree structure. * For tree root nodes, this returns zero. * This calls #findTreeParentNode to find any tree parent node, * so this respects Diagram#isTreePathToChildren and Link#isTreeLink * to know which way to traverse links and to know to ignore non-tree links. * * This may result in undefined behavior if there are cycles of Links that are Link#isTreeLink. * * If you want to know how deep a Part is nested inside Groups, call Part#findSubGraphLevel. * @return {number} * @see #findTreeRoot * @see #findTreeParentChain * @since 1.5 */ findTreeLevel(): number; /** * Returns an Iterator for the collection of Links that connect with the immediate tree children of this node. * Links for which Link#isTreeLink is false are ignored. * * This basically returns either #findLinksOutOf or #findLinksInto, * depending on Diagram#isTreePathToChildren, * but the results excludes links for which Link#isTreeLink is false. * @return {Iterator.} * @see #findTreeParentLink * @see #findTreeChildrenNodes * @see #findTreeParts * @since 1.1 */ findTreeChildrenLinks(): Iterator; /** * Returns an Iterator for the collection of Nodes that are the immediate tree children of this node. * Nodes only connected by links for which Link#isTreeLink is false are ignored. * * This basically returns either #findNodesOutOf or #findNodesInto, * depending on Diagram#isTreePathToChildren. * @return {Iterator.} * @see #findTreeParentNode * @see #findTreeChildrenLinks * @see #findTreeParts * @since 1.1 */ findTreeChildrenNodes(): Iterator; /** * Return a collection of Parts including this Node, * all of the Links going to child Nodes, and all of their * tree child nodes and links. * Links for which Link#isTreeLink is false are ignored. * * Whether child nodes are found for a parent node by following links out of the parent node or * by links coming into the parent node is determined by the value of Diagram#isTreePathToChildren. * * The result will include this, the "root" node. * If any of the nodes are Groups, their member parts are not included. * * If you want to find the collection of Parts that are contained by a Group, use Group#findSubGraphParts. * @param {number=} level How many levels of the tree, starting at this node, to include; * the default is Infinity, including all tree children of this node. Values less than 1 are treated as 1. * @return {Set.} A Set of Nodes and Links. * @see #findTreeChildrenNodes * @see #findTreeChildrenLinks * @see #findTreeParentChain */ findTreeParts(level?: number): Set; /** * Hide each child node and the connecting link, * and recursively collapse each child node. * This changes the value of Part#isVisible of the whole subtree and the parts owned by * those nodes and links. * However, this root node's visibility is unchanged. * * Links are assumed to go from the parent node to the children nodes, * unless Diagram#isTreePathToChildren is false. * Links for which Link#isTreeLink is false are ignored. * * This sets #isTreeExpanded to false on this node and on all of the children nodes. * For those child nodes that were expanded when they were collapsed, * #wasTreeExpanded is set to true. * * You can also pass in a number of levels to hide nodes beyond a certain level starting at this node. * If you want to make sure that all nodes are expanded up to a particular level, call #expandTree. * If you want to do both, call `expandTree` before calling `collapseTree` to * collapse nodes expanded due to the #wasTreeExpanded flag. * * This method does not perform a transaction or start any animation. * You may want to call the CommandHandler#collapseTree command, which does perform a transaction * and raise a DiagramEvent. * * To collapse a Group's subgraph of Nodes and Links, use Group#collapseSubGraph. * @param {number=} level How many levels of the tree, starting at this node, to keep expanded if already expanded; * the default is 1, hiding all tree children of this node. Values less than 1 are treated as 1. * @see #expandTree * @see #findTreeParts */ collapseTree(level?: number): void; /** * Show each child node and the connecting link, * and perhaps recursively expand their child nodes. * This may change the value of Part#isVisible of the whole subtree and the parts owned by * those nodes and links. * However, this root node's visibility is unchanged. * * This sets #isTreeExpanded to true on this node and on all of the children nodes. * Links are assumed to go from the parent node to the children nodes, * unless Diagram#isTreePathToChildren is false. * Links for which Link#isTreeLink is false are ignored. * * This will expand a tree child node only if its #wasTreeExpanded property was true. * * You can also pass in a number of levels in order to be sure that all nodes * starting at this node and up through that number of levels are visible. * If you want to make sure that there are no nodes expanded after a particular level, call #collapseTree. * If you want to do both, call `expandTree` before calling `collapseTree` to * collapse nodes expanded due to the #wasTreeExpanded flag. * * This method does not perform a transaction or start any animation. * You may want to call the CommandHandler#expandTree command, which does perform a transaction * and raise a DiagramEvent. * * To expand a Group's subgraph of Nodes and Links, use Group#expandSubGraph. * @param {number=} level How many levels of the tree should be expanded; * the default is 2, showing all tree children of this node and potentially more. * Values less than 2 are treated as 2. * @see #collapseTree * @see #findTreeParts */ expandTree(level?: number): void; /** * Gets or sets whether the subtree graph starting at this node is expanded. * Changing this property's value will call #collapseTree or #expandTree, * and also will call the value of #treeExpandedChanged if it is a function. * * The initial value is true -- "tree-child" nodes, and the links to them, are shown. * * There is an analogous property for expanded/collapsed Groups: Group#isSubGraphExpanded. */ get isTreeExpanded(): boolean; set isTreeExpanded(value: boolean); /** * Gets or sets whether the subtree graph starting at this node * had been collapsed by a call to #expandTree on the parent node. * The initial value is false. * @see #isTreeExpanded */ get wasTreeExpanded(): boolean; set wasTreeExpanded(value: boolean); /** * Gets or sets the function that is called when #isTreeExpanded has changed value. * The argument to that function will be this Node. * * If the value is a function, that function must not expand or collapse any trees of nodes and links. * The Node has already been expanded or collapsed -- trying to change it again may produce undefined behavior. * * The default value is null -- no function is called. */ get treeExpandedChanged(): ((thisNode: Node) => void) | null; set treeExpandedChanged(value: ((thisNode: Node) => void) | null); /** * Gets whether this node has no tree children. * * The initial value is true, meaning that there are no links connected with child nodes * in the direction given by Diagram#isTreePathToChildren. * This value changes automatically as link connections are added to or removed from this node. * Links for which Link#isTreeLink is false are ignored. */ get isTreeLeaf(): boolean; set isTreeLeaf(value: boolean); } /** * A Group is a Node that can contain a subgraph of Nodes and Links, * which are members of the group. *

* For more discussion, see Introduction to Groups. * See samples that make use of Groups in the samples index. * * Although you can create a Group and Diagram#add it to a Diagram, this does not update the Model. * It is more common to create a group by adding a node data object to the model * by calling Model#addNodeData. For example: * ```js * myDiagram.startTransaction("make new group"); * myDiagram.model.addNodeData({ key: "Omega", isGroup: true }); * myDiagram.commitTransaction("make new group"); * ``` * * This will cause a Group to be created (copying the template found in Diagram#groupTemplateMap), * added to the Diagram in some Layer (based on Part#layerName), and bound to the group data * (resulting in Panel#data referring to that group data object). * Note that the JavaScript object includes setting `isGroup` to true, * to indicate that the object represents a Group rather than a regular Node or simple Part. * * The member Parts of a Group, which you can access as the #memberParts collection, * belong to the group but are not in the visual tree of the group. * All Parts are directly in Layers -- they cannot be inside a Panel. * This allows group member parts to be in layers different from the group's layer. * * You can change the membership of a Node or a simple Part in a Group by setting * its Part#containingGroup property. * This is done automatically for you by the diagram if you initialize the `group` property on the node data * in the model to be the key of the containing group node data. * Thus you should do something like: * ```js * myDiagram.startTransaction("add new member"); * myDiagram.model.addNodeData({ group: someExistingGroupKey, ... }); * myDiagram.commitTransaction("add new member"); * ``` * * where you would make sure the node data object included all of the properties you need. * You can also change the relationship dynamically by calling GraphLinksModel#setGroupKeyForNodeData. * * The membership of Links is computed automatically for you by the diagram based on the membership of * the connected Nodes. * For example, if the Link#fromNode is a top-level node but the Link#toNode is a member of a group, * the link is a top-level link. * If the two connected nodes both belong to the same group, the link is a member of that group. * If the two connected nodes belong to different groups, the link belongs to the common container group, if there is any. * Note that if a link connects a member of a group with the group itself, the link is a member of that group. * * All of the group-member relationships effectively form a tree structure. * These properties and methods are useful in navigating these relationships: * - Part#containingGroup * - Part#isTopLevel * - Part#findTopLevelPart * - Part#findSubGraphLevel * - Part#findCommonContainingGroup * - #memberParts * - #findSubGraphParts * - #findExternalLinksConnected * - #findExternalNodesConnected * * As the membership of a group changes, you may want to update the appearance of the group. * You can set the #memberAdded and #memberRemoved properties to be functions that are called. * These functions must not modify any membership relationships -- these function properties just exist to update the appearance of the Group. * * You can control whether certain Nodes are added to a Group by CommandHandler#groupSelection or * #addMembers or CommandHandler#addTopLevelParts by affecting the result of CommandHandler#isValidMember, * which is responsible for deciding whether it is OK to add a Node to a Group or to remove a Node from a Group to be a top-level node. * You can override that predicate on CommandHandler, but it is easier to set the #memberValidation or * CommandHandler#memberValidation functional property. *

* For a more general discussion of validation, see Introduction to Validation. * * The area occupied by the subgraph is represented in the group's visual tree by a Placeholder. * As the group #placeholder grows and shrinks based on the sizes and positions of the member nodes and links, * the group will grow and shrink accordingly. * The placeholder is always the Part#locationObject, * although you may specify any Spot as the Part#locationSpot. * A Group need not have a placeholder, but it may have at most one. * * A group has its own #layout property that is used to position the member nodes and route the member links. * * The Group class also supports the notion of expanding and collapsing the subgraph, * causing the member nodes and links to be shown or hidden. * Principally this is a matter of setting #isSubGraphExpanded. * Changes to this property will result in calls to #collapseSubGraph or #expandSubGraph, as appropriate. * * If you want to change the appearance of the group you can do so in a function that you assign to * the #subGraphExpandedChanged property. * This function must not modify any member relationships or expand or collapse any groups -- the functional property just exists * to update the appearance of the Group. *

* For more discussion and examples, see SubGraphs. * * If you want the user to be able to create a Group out of the currently * selected Parts using the CommandHandler#groupSelection command, * you need to first set the CommandHandler#archetypeGroupData property * to a data object with `isGroup` set to true. * If you want the user to be able to ungroup a Group, * using the CommandHandler#ungroupSelection command, * you need to set #ungroupable to true. *

* For more discussion and examples, see Groups, * SubGraphs, and * Sized Groups. * * Only Groups that are in Diagrams can have member Parts or connections via Links. * Templates should not be connected with Links, be labels of Links, be members of Groups, have any member Parts, or have any Adornments. * @extends Node * @unrestricted */ export class Group extends Node { /** * Constructs an empty Group with no visual elements and no member parts; * typically a Group will have some visual elements surrounding a Placeholder. * * The panel type must be one of the enumerated values defined on the Panel class, including: * Panel.Position, Panel.Vertical, Panel.Horizontal, Panel.Table, * Panel.Auto, Panel.Spot, or Panel.Viewbox. The string value such as "Auto" may also be used. * * Usage example: * *```js * // Constructs a Group, sets properties on it, * // adds a data binding to it, * // and adds two GraphObjects to the Group: * const g = new go.Group("Auto", { * margin: 5, * background: "red" * }) * .add(new go.Shape("RoundedRectangle")) * .add(new go.TextBlock("Some Text")) * ``` * * @param {string=} type Panel Type as either a string or PanelLayout. such as "Vertical", "Auto", or Panel.Vertical, Panel.Auto, are accepted. * If not supplied, the default Panel type is "Position". * @param {Partial=} init Optional initialization properties. */ constructor(type?: PanelLayout | string, init?: Partial); /** * Constructs an empty Panel. Default type is Panel.Position. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * This read-only property returns a Placeholder that this group may contain in its visual tree. */ get placeholder(): Placeholder | null; /** * Gets or sets whether the size of the area of the Group's #placeholder * should remain the same during a DraggingTool move until a drop occurs. * Groups within temporary layers (such as new Groups during a drag-copy) are unaffected by this property. * * In other words, when the value is true, re-computing the bounds of the * members is suspended until a drop occurs, at which time the border is recomputed, * perhaps not including some members that had been dragged out and reparented. * The initial value is false. */ get computesBoundsAfterDrag(): boolean; set computesBoundsAfterDrag(value: boolean); /** * Gets or sets whether a #placeholder's bounds includes the bounds of member Links. * The default value is true. * If this is false, only non-Link member Parts are used to compute the Placeholder's bounds in document coordinates. */ get computesBoundsIncludingLinks(): boolean; set computesBoundsIncludingLinks(value: boolean); /** * Gets or sets whether a #placeholder's bounds includes the previous Group.location. * The default value is false. */ get computesBoundsIncludingLocation(): boolean; set computesBoundsIncludingLocation(value: boolean); /** * Gets or sets whether drag-and-drop events may be bubbled up to this Group if not handled by member Parts. * The default value is false -- each Node or Link that is a member of the Group needs to define * its own GraphObject#mouseDragEnter, GraphObject#mouseDragLeave, and GraphObject#mouseDrop * event handlers if you want dragging/dropping on a member part to act as if the user were acting on the group. * * This is currently restricted to only call the mouseDragEnter, mouseDragLeave, and mouseDrop event handlers * defined on the whole Group, not on any element inside the Group's visual tree. * @since 1.5 */ get handlesDragDropForMembers(): boolean; set handlesDragDropForMembers(value: boolean); /** * (undocumented) */ get avoidableMembers(): boolean; /** * (undocumented) */ set avoidableMembers(value: boolean); /** * This read-only property returns an iterator over the member Parts of this Group. * Setting Part#containingGroup to refer to this Group * will add that part to this collection. * The Parts can be Nodes, Links, Groups, or simple Parts. * * A template should not have any member parts. */ get memberParts(): Iterator; /** * Gets or sets the Layout used to position all of the immediate member nodes and links in this group. * By default this property is an instance of Layout -- no special layout is used, which just makes * sure each member node has a valid location. * * A group layout must not be shared with any Diagram#layout. */ get layout(): Layout | null; set layout(value: Layout | null); /** * Gets or sets the function that is called after a member Part has been added to this Group. * It is typically used to modify the appearance of the group. * The first argument will be this Group. * The second argument will be a Part, typically a Node, but may be a simple Part or a Link. * * If the value is a function, that function must not modify any membership relationships. * The member Part has already been added -- trying to remove it or adding or removing another member or the Group itself may produce undefined behavior. * * The default value is null -- no function is called. */ get memberAdded(): ((thisGroup: Group, newPart: Part) => void) | null; set memberAdded(value: ((thisGroup: Group, newPart: Part) => void) | null); /** * Gets or sets the function that is called after a member Part has been removed from this Group. * It is typically used to modify the appearance of the group. * The first argument will be this Group. * The second argument will be a Part, typically a Node, but may be a simple Part or a Link. * * If the value is a function, that function must not modify any membership relationships. * The member Part has already been removed -- trying to add it or adding or removing another member or the Group itself may produce undefined behavior. * * The default value is null -- no function is called. */ get memberRemoved(): ((thisGroup: Group, oldPart: Part) => void) | null; set memberRemoved(value: ((thisGroup: Group, oldPart: Part) => void) | null); /** * Gets or sets the predicate that determines whether or not a Part may become a member of this group. * If this is non-null, the predicate is called in addition to any CommandHandler#memberValidation predicate. * * The default predicate is null, which is equivalent to simply returning true. * The first argument will be this Group. * The second argument will be a Part, typically a Node, but will not be a Link or an Adornment. * * The function, if supplied, must not have any side-effects. */ get memberValidation(): ((thisGroup: Group, part: Part) => boolean) | null; set memberValidation(value: ((thisGroup: Group, part: Part) => boolean) | null); /** * See if the given collection of Parts contains non-Links all for which * CommandHandler#isValidMember returns true. * * The CommandHandler predicate will use CommandHandler#memberValidation * and #memberValidation, if either or both are defined. * * This does not check Diagram#isReadOnly or Model#isReadOnly, * but commands and tools should check those properties. * @expose * @param {Iterable.} coll * @return {boolean} true. */ canAddMembers(coll: Iterable): boolean; /** * Add the Parts in the given collection as members of this Group * for those Parts for which CommandHandler#isValidMember returns true. * If the check argument to this method is not supplied or false, * this will set Part#containingGroup on each part unconditionally, not calling CommandHandler#isValidMember. * * The CommandHandler predicate will use CommandHandler#memberValidation * and #memberValidation, if either or both are defined. * * At this time there is no "removeMembers" method. * If you want to make a collection of Parts to be top-level parts, not members of any Group but still in the Diagram, call CommandHandler#addTopLevelParts. * If you want to remove a collection of Parts not only from a Group but from the whole Diagram, call Diagram#removeParts. * @expose * @param {Iterable.} coll * @param {boolean=} check whether to call CommandHandler#isValidMember to confirm that it is valid to add the Part to be a member of this Group. * @return {boolean} true if all non-Links were added to this Group; false if some Parts or Nodes were not able to be added. */ addMembers(coll: Iterable, check?: boolean): boolean; /** * Gets or sets whether the user may ungroup this group. * The initial value is false. * @see #canUngroup */ get ungroupable(): boolean; set ungroupable(value: boolean); /** * This predicate returns true if #ungroupable is true, * if the layer's Layer#allowUngroup is true, and * if the diagram's Diagram#allowUngroup is true. * * This does not check Diagram#isReadOnly or Model#isReadOnly, * but commands and tools should check those properties. * @expose * @return {boolean} true if the user may ungroup this object. */ canUngroup(): boolean; /** * Returns an iterator over all of the Links that connect with this group or any node contained by this group, * in either direction, but that are not internal to this group. * * Links that are contained by this group (even in nested groups) are not included in the result collection. * @return {Iterator.} * @see Node#findLinksConnected * @since 1.3 */ findExternalLinksConnected(): Iterator; /** * Returns an iterator over all of the Nodes that are connected with this group or any node contained by this group, * by a link in either direction, but that are not internal to this group. * * Nodes that are contained by this group (even in nested groups) are not included in the result collection. * However this group itself might be in the results if there is a reflexive link connected to this group. * @return {Iterator.} * @see Node#findNodesConnected * @since 1.3 */ findExternalNodesConnected(): Iterator; /** * Return a collection of Parts that are all of the nodes and links * that are members of this group, including inside nested groups and label nodes, * but excluding this group itself. * * For member nodes that are Groups, this will include its members recursively. * * If you want only the immediate members of this group, use the #memberParts property. * * If you want to find the collection of Nodes and Links that are in the subtree of a given Node, use Node#findTreeParts. * @return {Set.} */ findSubGraphParts(): Set; /** * Hide each of the member nodes and links of this group, * and recursively collapse any member groups. * This changes the value of Part#isVisible of the whole subgraph and the parts owned by * those member nodes and links. * However, this group's visibility is unchanged. * * This sets #isSubGraphExpanded to false on this group and on all of the nested Groups. * For those nested Groups that were expanded, * #wasSubGraphExpanded is set to true. * * This method does not perform a transaction or start any animation. * * To collapse trees made of Nodes and Links, use Node#collapseTree. */ collapseSubGraph(): void; /** * Show each member node and link, * and perhaps recursively expand nested subgraphs. * This may change the value of Part#isVisible of the whole subgraph and the parts owned by * those member nodes and links. * However, this group's visibility is unchanged. * * This sets #isSubGraphExpanded to true on this group and on all of the nested Groups. * This will expand a nested group only if its #wasSubGraphExpanded property was true. * * This method does not perform a transaction or start any animation. * * To expand trees made of Nodes and Links, use Node#expandTree. */ expandSubGraph(): void; /** * Gets or sets whether the subgraph contained by this group is expanded. * Changing this property's value will call #collapseSubGraph or #expandSubGraph, * and also will call the value of #subGraphExpandedChanged if it is a function. * * The initial value is true -- this group's member parts are shown. * * There is an analogous property for expanded/collapsed trees of Nodes and Links: Node#isTreeExpanded. */ get isSubGraphExpanded(): boolean; set isSubGraphExpanded(value: boolean); /** * Gets or sets whether the subgraph starting at this group * had been collapsed by a call to #expandSubGraph on the containing Group. * The initial value is false. * @see #isSubGraphExpanded */ get wasSubGraphExpanded(): boolean; set wasSubGraphExpanded(value: boolean); /** * Gets or sets the function that is called when #isSubGraphExpanded has changed value. * The argument to that function will be this Group. * * If the value is a function, that function must not expand or collapse any groups. * The Group has already been expanded or collapsed -- trying to change it again may produce undefined behavior. * * The default value is null -- no function is called. */ get subGraphExpandedChanged(): ((thisGroup: Group) => void) | null; set subGraphExpandedChanged(value: ((thisGroup: Group) => void) | null); /** * Move this Group and all of its member parts, recursively. * * This method does not perform a transaction or start any animation. * @param {Point} newpos a new Point in document coordinates. * @param {boolean=} useLocation true if you want to set the #location instead of the position. False by default. */ move(newpos: Point, useLocation?: boolean): void; } /** * If a Placeholder is in the visual tree of a Group, it represents the area of all of the member Parts of that Group. * If a Placeholder is in the visual tree of an Adornment, it represents the area of the Adornment#adornedObject. * Unlike other GraphObjects, the Placeholder measures itself based on these criteria, and not on its own #desiredSize or #scale. * It will set its own natural bounds and scale, and in the case of Groups will set the Group's location. * * It can only be used in the visual tree of a Group node or an Adornment. * There can be at most one Placeholder in a Group or an Adornment. * * See the documentation for Group and Adornment for descriptions of the Placeholder roles in each. * @extends GraphObject * @unrestricted */ export class Placeholder extends GraphObject { /** * This normally does not need any initialization, * except for maybe setting #padding. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * (undocumented) * This is only called when the Placeholder is inside a Group. * Normally this just returns the result of #computeMemberBounds expanded by the #padding. * However, if Group#computesBoundsAfterDrag is true, * and if the Diagram#currentTool is the DraggingTool, * and if this Group is not being dragged, * this method returns the last value of #computeBorder before dragging began. * @expose * @param {Rect} result * @return {Rect} in document coordinates. */ protected computeBorder(result: Rect): Rect; /** * (undocumented) * Compute the union of the Bounds of this Placeholder's parent's Group.memberParts. * If there are no members, this returns a Rect with Width and Height of zero * and an X and Y that are this panel's original location in document coordinates. * This is only called when the Placeholder is inside a Group. * @expose * @param {Rect} result * @return {Rect} in document coordinates. */ protected computeMemberBounds(result: Rect): Rect; /** * Gets or sets the padding around the members of the Group or around the Adornment#adornedObject GraphObject. * The initial value is a Margin of zero on all sides. */ get padding(): MarginLike; set padding(value: MarginLike); } /** * A Link is a Part that connects Nodes. * The link relationship is directional, going from Link#fromNode to Link#toNode. * A link can connect to a specific port element in a node, as named by the Link#fromPortId * and Link#toPortId properties. *

* For more discussion, see Introduction to Links. * * To add a Link to a Diagram when using a GraphLinksModel you should do something like: * ```js * myDiagram.startTransaction("make new link"); * myDiagram.model.addLinkData({ from: "Alpha", to: "Beta" }); * myDiagram.commitTransaction("make new link"); * ``` * * where you would substitute the keys of the actual nodes that you want to connect with a link. * This will cause a Link to be created (copying the template found in Diagram#linkTemplateMap), * added to the Diagram in some Layer (based on Part#layerName), and bound to the link data * (resulting in Panel#data referring to that link data object). * Note that link data objects, unlike Node data, do not have their own unique keys or identifiers, * because other Parts do not refer to them. * * If you are using a TreeModel, there are no link data objects, so you just need to call * TreeModel#setParentKeyForNodeData to specify the "parent" node's key for a "child" node data. * * To find a Link given a link data object in the GraphLinksModel, * call Diagram#findLinkForData. When using a TreeModel, call either Diagram#findNodeForData * or Diagram#findNodeForKey to get a Node, and then call Node#findTreeParentLink to get the Link, if any exists. * * To find a link that connects two nodes, call Node#findLinksTo or Node#findLinksBetween. * With the former method, the direction matters; with the latter method it returns links in either direction. * * A link's position and size are determined by the two nodes that it connects. * Normally there should be a Shape as the main element in this Link. * This shape is what users will see as the "line" or "wire" -- * you can set its Shape#stroke and other "stroke..." properties to control its appearance. * * The link will compute a route (a sequence of points) going from the #fromNode's port element * to the #toNode's port element. * That route is used to generate the path of the main shape. * Properties that affect the nature of the route and the geometry of the path include: * - #curve * - #curviness * - #corner * - #routing * - #smoothness * - #adjusting * *

* For more discussion and examples, see Links. * * There are additional properties that affect how the end of the link connects to a port element of a node. * There are duplicate properties, ones for the "to" end and ones for the "from" end: * - #fromSpot, #toSpot * - #fromEndSegmentLength, #toEndSegmentLength * - #fromShortLength, #toShortLength * * These properties normally have "default" values, causing the link's routing and path-geometry generating * to get the corresponding values from the connected port element. * This scheme permits an individual link to have its own specific connection to a port, * taking precedence over how the port normally expects links to connect to it. * For example, several of the Layout classes sets these properties on each Link * as part of their route computation for links. *

* For more discussion and examples, see Link Points. * * Elements other than the main Shape in the Link may act as decorations on the link, including arrowheads and labels. * You can control where they are located along the link route and how they are oriented. * Because these decorations may be any GraphObject, they are all properties of that class. * The properties include: * - GraphObject#segmentIndex * - GraphObject#segmentFraction * - GraphObject#segmentOffset * - GraphObject#segmentOrientation * * If you do not set the GraphObject#segmentIndex property, the object is positioned * to be at the middle of the link. *

* For more discussion and examples, see Link Labels. * * **GoJS** makes it easy to add arrowheads to your link template. * Just add a Shape with the appearance properties that you want, * and also set the Shape#toArrow or Shape#fromArrow property * to the name of the kind of arrowhead that you want. * Doing so automatically sets the "segment..." properties that are appropriate for the chosen arrowhead. * * More than one shape may automatically get the route geometry. * This is useful when you want to have multiple link shapes with different thicknesses * to create a gradient effect across the path of the link or to produce parallel lines along the path. * Just set GraphObject#isPanelMain to true on each such Shape. * * If you want the user to be able to reconnect a link, using the RelinkingTool, * you need to set one or both of #relinkableFrom and #relinkableTo to true. * The RelinkingTool shows a RelinkingTool#fromHandleArchetype and/or a * RelinkingTool#toHandleArchetype when the link is selected. * Such a relink handle can be dragged by the user to start a relinking operation. * * If you want the user to be able to change the path of the link, using the LinkReshapingTool, * set Part#reshapable to true. * The LinkReshapingTool shows reshape handles that the user can drag to shift the position * of a point in the link's route. * The LinkReshapingTool#handleArchetype is copied for each reshape handle. * * Often if a Link is reshapable, you will want to save the route in the model so that it can be restored * upon load. To save the route automatically, add a TwoWay Binding on the #points property: * `new go.Binding("points").makeTwoWay()`. Model#toJson will automatically * convert the List of Points into an Array of numbers in the JSON representation, * if the property is named "points". * * If a Link is Part#reshapable, it is also possible to allow the user to add and remove segments * from the link's route by setting #resegmentable to true. * This causes the LinkReshapingTool to add resegmenting handles at the midpoints of each segment. * The LinkReshapingTool#midHandleArchetype is copied for each resegment handle. * When the user drags such a resegmenting handle, a new segment is inserted into the route. * Also, when the user drags a reshape handle such that two adjacent segments end up in a straight line, * a segment is removed from the route. *

* For more discussion and examples, see Links, * Link Labels, and * Link Points. *

* To control what links a user may draw or reconnect, please read about * Validation. *

* To customize linking and relinking behavior, please read * Introduction to the Linking Tools * and Introduction to the RelinkingTool. * For customizing the reshaping of Links, * see Introduction to the LinkReshapingTool. * * Only Links that are in Diagrams can have connections with Nodes. * Templates should not be connected with Nodes, be members of Groups, or have any Adornments. * @extends Part * @unrestricted */ export class Link extends Part { /** * Constructs an empty link that does not connect any nodes. * If you want the link to be seen, you must provide a Shape as an element * to be used as the visual path for the link. * * Usage example: * *```js * // Constructs a Link, sets properties on it, * // adds a data binding to it, * // and adds two Shapes to the Link: * const l = new go.Link({ * routing: go.Link.Orthogonal * }) * .add(new go.Shape({ strokeWidth: 2 })) * .add(new go.Shape({ toArrow: "Standard" })) * ``` * * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * Used as the default value for Link#routing: * the route goes fairly straight between ports. * @constant */ static Normal: EnumValue; /** * Used as a value for Link#routing: * each segment is horizontal or vertical. * @constant */ static Orthogonal: EnumValue; /** * Used as a value for Link#routing: * each segment is horizontal or vertical, but the route tries to avoid crossing over nodes. * @constant */ static AvoidsNodes: EnumValue; /** * This is the default value for Link#curve and Link#adjusting, * to indicate that the path geometry consists of straight line segments and * to indicate that the link route computation does not depend on any previous route points; * this can also be used as a value for GraphObject#segmentOrientation * to indicate that the object is never rotated along the link route -- its angle is unchanged. * @constant */ static None: EnumValue; /** * Used as a value for Link#curve, to indicate that * the link path uses Bezier curve segments. * @constant */ static Bezier: EnumValue; /** * Used as a value for Link#curve, to indicate that * orthogonal link segments will be discontinuous where they cross over * other orthogonal link segments that have a Link#curve of JumpOver or JumpGap. * @constant */ static JumpGap: EnumValue; /** * Used as a value for Link#curve, to indicate that * orthogonal link segments will veer around where they cross over * other orthogonal link segments that have a Link#curve of JumpOver or JumpGap. * @constant */ static JumpOver: EnumValue; /** * Used as a value for Link#adjusting, * to indicate that the link route computation should keep the * intermediate points of the previous route, just modifying the first and/or last points; * if the routing is orthogonal, it will only modify the first two and/or last two points. * @constant */ static End: EnumValue; /** * Used as a value for Link#adjusting, * to indicate that the link route computation should scale and rotate the intermediate points * so that the link's shape looks approximately the same; * if the routing is orthogonal, this value is treated as if it were Link.End. * @constant */ static Scale: EnumValue; /** * Used as a value for Link#adjusting, * to indicate that the link route computation should linearly interpolate the intermediate points * so that the link's shape looks stretched; * if the routing is orthogonal, this value is treated as if it were Link.End. * @constant */ static Stretch: EnumValue; /** * This value for GraphObject#segmentOrientation results in * the GraphObject turned to have the same angle as the route: * the GraphObject's angle is always the same as the angle of the link's route * at the segment where the GraphObject is attached; * use this orientation for arrow heads. * @constant */ static OrientAlong: EnumValue; /** * This value for GraphObject#segmentOrientation results in * the GraphObject is turned clockwise to be perpendicular to the route: * the GraphObject's angle is always 90 degrees more than the angle of the link's route * at the segment where the GraphObject is attached. * @constant */ static OrientPlus90: EnumValue; /** * This value for GraphObject#segmentOrientation results in * the GraphObject being turned counter-clockwise to be perpendicular to the route: * the GraphObject's angle is always 90 degrees less than the angle of the link's route * at the segment where the GraphObject is attached. * @constant */ static OrientMinus90: EnumValue; /** * This value for GraphObject#segmentOrientation results in * the GraphObject's angle always being 180 degrees opposite from the angle of the link's route * at the segment where the GraphObject is attached. * @constant */ static OrientOpposite: EnumValue; /** * This value for GraphObject#segmentOrientation results in * the GraphObject turned to have the same angle as the route, just like Link.OrientAlong, but is never upside down: * the GraphObject's angle always following the angle of the link's route * at the segment where the GraphObject is attached; * this is typically only used for TextBlocks or Panels that contain text. * @constant */ static OrientUpright: EnumValue; /** * This value for GraphObject#segmentOrientation results in * the GraphObject turned clockwise to be perpendicular to the route, just like Link.OrientPlus90, but is never upside down: * the GraphObject's angle always being 90 degrees more than the angle of the link's route * at the segment where the GraphObject is attached; * this is typically only used for TextBlocks or Panels that contain text. * @constant */ static OrientPlus90Upright: EnumValue; /** * This value for GraphObject#segmentOrientation results in * the GraphObject turned counter-clockwise to be perpendicular to the route, just like Link.OrientMinus90, but is never upside down: * the GraphObject's angle always being 90 degrees less than the angle of the link's route * at the segment where the GraphObject is attached; * this is typically only used for TextBlocks or Panels that contain text. * @constant */ static OrientMinus90Upright: EnumValue; /** * This value for GraphObject#segmentOrientation results in * the GraphObject's angle always following the angle of the link's route * at the segment where the GraphObject is attached, but never upside down * and never angled more than +/- 45 degrees: * when the route's angle is within 45 degrees of vertical (90 or 270 degrees), * the GraphObject's angle is set to zero; * this is typically only used for TextBlocks or Panels that contain text. * @constant */ static OrientUpright45: EnumValue; /** * Gets or sets the Node that this link comes from. * The #fromPortId specifies which port the link comes from. * The default value is null -- this link is not coming from any node. * * A template should not be connected with any node. */ get fromNode(): Node | null; set fromNode(value: Node | null); /** * Gets or sets the identifier of the port that this link comes from. * The default value is the empty string. */ get fromPortId(): string; set fromPortId(value: string); /** * This read-only property returns a GraphObject that is the "from" port that this link is connected from. * The #fromNode provides the node that the link is coming from. * The #fromPortId provides the identifier for which port this link is coming from; * you can set that property in order to change the value of this property. * This method may return null. */ get fromPort(): GraphObject | null; /** * Gets or sets the function that is called after this Link changes which Node or port it connects from. * The first argument will be this Link. * The second argument will be the old GraphObject port. * The third argument will be the new GraphObject port. * * If the value is a function, that function must not modify which nodes or links this link connects with. * The "from" node and/or port has already been changed -- trying to change it again may produce undefined behavior. * * The default value is null -- no function is called. */ get fromPortChanged(): ((thisLink: Link, oldPort: GraphObject | null, newPort: GraphObject | null) => void) | null; set fromPortChanged(value: ((thisLink: Link, oldPort: GraphObject | null, newPort: GraphObject | null) => void) | null); /** * Gets or sets the Node that this link goes to. * The #toPortId specifies which port the link goes to. * The default value is null -- this link is not going to any node. * * A template should not be connected with any node. */ get toNode(): Node | null; set toNode(value: Node | null); /** * Gets or sets the identifier of the port that this link goes to. * The default value is the empty string. */ get toPortId(): string; set toPortId(value: string); /** * This read-only property returns a GraphObject that is the "to" port that this link is connected to. * The #toNode provides the node that the link is going to. * The #toPortId provides the identifier for which port this link is going to; * you can set that property in order to change the value of this property. * This method may return null. */ get toPort(): GraphObject | null; /** * Gets or sets the function that is called after this Link changes which Node or port it connects to. * The first argument will be this Link. * The second argument will be the old GraphObject port. * The third argument will be the new GraphObject port. * * If the value is a function, that function must not modify which nodes or links this link connects with. * The "to" node and/or port has already been changed -- trying to change it again may produce undefined behavior. * * The default value is null -- no function is called. */ get toPortChanged(): ((thisLink: Link, oldPort: GraphObject | null, newPort: GraphObject) => void) | null; set toPortChanged(value: ((thisLink: Link, oldPort: GraphObject | null, newPort: GraphObject) => void) | null); /** * Gets or sets where this link should connect at the #fromPort. * The default value is Spot.Default, meaning that the value * actually comes from the GraphObject#fromSpot property of the #fromPort. * * This property is set by some layouts, if ForceDirectedLayout#setsPortSpots or * LayeredDigraphLayout#setsPortSpots or TreeLayout#setsPortSpot or * TreeLayout#setsChildPortSpot is true. * * For examples of how to use this property, see Link Connection Points. * @see #toSpot * @see GraphObject#fromSpot * @see #computeSpot */ get fromSpot(): Spot; set fromSpot(value: Spot); /** * Gets or sets the length of the first segment, when the computed "from spot" at the #fromPort is not Spot.None. * The default value is NaN, meaning that the value * actually comes from the GraphObject#fromEndSegmentLength property of the #fromPort. * This value also limits how short the #fromShortLength may be drawn. * * For examples of how to use this property, see Link Connection Points. * @see #toEndSegmentLength * @see #computeEndSegmentLength * @see GraphObject#fromEndSegmentLength * @see #fromShortLength */ get fromEndSegmentLength(): number; set fromEndSegmentLength(value: number); /** * Gets or sets how far the end segment stops short of the actual port. * Positive values are limited by the #fromEndSegmentLength or GraphObject#fromEndSegmentLength. * Negative values cause the link to extend into the port. * The default value is NaN -- the value actually comes from the * GraphObject#fromShortLength property of the #fromPort. * * For examples of how to use this property, see Link Connection Points. * If you want to move an arrowhead away from the start of the link route, * set the arrowhead Shape's GraphObject#segmentOffset. * @see #toShortLength * @see GraphObject#fromShortLength * @see #fromEndSegmentLength */ get fromShortLength(): number; set fromShortLength(value: number); /** * Gets or sets where this link should connect at the #toPort. * The default value is Spot.Default, meaning that the value * actually comes from the GraphObject#toSpot property of the #toPort. * * This property is set by some layouts, if ForceDirectedLayout#setsPortSpots or * LayeredDigraphLayout#setsPortSpots or TreeLayout#setsPortSpot or * TreeLayout#setsChildPortSpot is true. * * For examples of how to use this property, see Link Connection Points. * @see #fromSpot * @see GraphObject#toSpot * @see #computeSpot */ get toSpot(): Spot; set toSpot(value: Spot); /** * Gets or sets the length of the last segment. * The default value is NaN, meaning that the value * actually comes from the GraphObject#toEndSegmentLength property of the #toPort. * This value also limits how short the #toShortLength may be drawn. * * For examples of how to use this property, see Link Connection Points. * @see #fromEndSegmentLength * @see #computeEndSegmentLength * @see GraphObject#toEndSegmentLength * @see #toShortLength */ get toEndSegmentLength(): number; set toEndSegmentLength(value: number); /** * Gets or sets how far the end segment stops short of the actual port. * Positive values are limited by the #toEndSegmentLength or GraphObject#toEndSegmentLength. * Negative values cause the link to extend into the port. * The default value is NaN -- the value actually comes from the * GraphObject#toShortLength property of the #toPort. * * For examples of how to use this property, see Link Connection Points. * If you want to move an arrowhead away from the end of the link route, * set the arrowhead Shape's GraphObject#segmentOffset. * @see #fromShortLength * @see GraphObject#toShortLength * @see #toEndSegmentLength */ get toShortLength(): number; set toShortLength(value: number); /** * Given a Node, return the node at the other end of this link. * @param {Node} node * @return {Node} This may return the same node, if the link is reflexive. */ getOtherNode(node: Node): Node | null; /** * Given a GraphObject that is a "port", return the port at the other end of this link. * @param {GraphObject} port * @return {GraphObject} This may return the same object, if the link is reflexive. */ getOtherPort(port: GraphObject): GraphObject | null; /** * This read-only property is true when this Link has any label Nodes, Nodes that are owned by this Link * and are arranged along its path in the same manner as elements of the Link Panel. * @see #labelNodes * @since 1.1 */ get isLabeledLink(): boolean; /** * This read-only property returns an iterator over the Nodes that act as labels on this Link. * Setting Node#labeledLink to refer to this Link * will add that Node to this collection. * * Do not confuse these Nodes with the GraphObjects that * are part of this Link Panel. * Those objects can also be used as "labels", but not as objects to which * there can be link connections, because those panel elements cannot be Nodes. * Those panel objects can be used for other purposes too, such as arrowheads. * * A template should not have any label nodes. * @see #isLabeledLink */ get labelNodes(): Iterator; /** * Move this link to a new position. * This also shifts all of the Points in the route accordingly. * This also moves any #labelNodes. * @param {Point} newpos a new Point in document coordinates. * @param {boolean=} useLocation true if you want to set the #location instead of the position. False by default. */ move(newpos: Point, useLocation?: boolean): void; /** * Gets or sets whether the user may reconnect an existing link at the "from" end. * This affects the behavior of the RelinkingTool. * * The initial value is false. */ get relinkableFrom(): boolean; set relinkableFrom(value: boolean); /** * Gets or sets whether the user may reconnect an existing link at the "to" end. * This affects the behavior of the RelinkingTool. * * The initial value is false. */ get relinkableTo(): boolean; set relinkableTo(value: boolean); /** * This predicate returns true if #relinkableFrom is true, * if the layer's Layer#allowRelink is true, and * if the diagram's Diagram#allowRelink is true. * * This does not check Diagram#isReadOnly or Model#isReadOnly, * but commands and tools should check those properties. * @expose * @return {boolean} true if the user may relink the From end of this link. */ canRelinkFrom(): boolean; /** * This predicate returns true if #relinkableTo is true, * if the layer's Layer#allowRelink is true, and * if the diagram's Diagram#allowRelink is true. * * This does not check Diagram#isReadOnly or Model#isReadOnly, * but commands and tools should check those properties. * @expose * @return {boolean} true if the user may relink the To end of this link. */ canRelinkTo(): boolean; /** * Gets or sets whether the user may change the number of segments in this Link, * if the link has straight segments. * This affects the behavior of the LinkReshapingTool when #curve is not Link.Bezier. * * The initial value is false. * @since 1.2 */ get resegmentable(): boolean; set resegmentable(value: boolean); /** * Gets or sets whether this Link is part of the tree for tree operations * such as Node#findTreeChildrenNodes or Node#collapseTree. * * The initial value is true. * @since 1.2 */ get isTreeLink(): boolean; set isTreeLink(value: boolean); /** * This read-only property returns the main Shape representing the path of this Link. * * The value depends on there being an element in this Link that is * a Shape and that has GraphObject#isPanelMain set to true. * This shape is what displays the stroke going from one node to another node. * * This path shape's geometry is automatically generated based on the #points * of this link's route, depending on other properties such as #curve. * Note that the points are in document coordinates, but the path's Shape#geometry * will have points that are in local Shape coordinates. * This Shape's GraphObject#scale should be one and GraphObject#angle should be zero. * * If there is no Shape with GraphObject#isPanelMain set to true, * the Link will use the first Shape for its path. */ get path(): Shape | null; /** * This read-only property returns the bounds of the link geometry in document coordinates. * @since 2.2 */ get routeBounds(): Rect; /** * This read-only property returns the point at the middle of the path, in document coordinates. */ get midPoint(): Point; /** * This read-only property returns the angle of the path at the #midPoint. */ get midAngle(): number; /** * Gets or sets the List of Points in the route. * All of the Points must be Point#isReal -- no NaN or infinite values -- * and all of the points are in document coordinates. * Although this list may be replaced by setting this property, * one must not modify the contents of the List directly. * * The setter also accepts an Array of alternating X,Y point values [1, 2, 3, 4, 5, 6], * or an Array of Objects each of which has (lowercase) 'x' and 'y' properties that are numbers * [{"x":1,"y":2}, {"x":3,"y":4}, {"x":5,"y":6}]. * * Ownership of the List and all of its Points that is provided to the setter * is transferred to this Link. */ get points(): List; set points(value: List); /** * This read-only property returns the number of points in the route. */ get pointsCount(): number; /** * Gets a particular point of the route. * @param {number} i int The zero-based index of the desired point. * @return {Point} in document coordinates */ getPoint(i: number): Point; /** * Sets a particular point of the route; this may only be called within an override of #computePoints. * @param {number} i int The zero-based index of the desired point. * @param {Point} p The new point in document coordinates, which should not have infinite or NaN coordinate values, and which must not be modified afterwards. * @see #getPoint * @see #insertPoint * @see #addPoint * @see #removePoint * @since 1.6 */ setPoint(i: number, p: Point): void; /** * (undocumented) * Sets a particular point of the route; this may only be called within an override of #computePoints. * @param {number} i int The zero-based index of the desired point. * @param {number} x The new X, which should not be infinite or NaN, in document coordinates. * @param {number} y The new Y, which should not be infinite or NaN, in document coordinates. */ setPointAt(i: number, x: number, y: number): void; /** * Insert a point at a particular position in the route, without replacing an existing point; this may only be called within an override of #computePoints. * @param {number} i int The zero-based index of the new point. * @param {Point} p The new point in document coordinates, which should not have infinite or NaN coordinate values, and which must not be modified afterwards. * @see #getPoint * @see #setPoint * @see #addPoint * @see #removePoint * @since 1.6 */ insertPoint(i: number, p: Point): void; /** * (undocumented) * Insert a point at a particular position in the route, without replacing an existing point; this may only be called within an override of #computePoints. * @param {number} i int The zero-based index of the new point. * @param {number} x The new X, which should not be infinite or NaN, in document coordinates. * @param {number} y The new Y, which should not be infinite or NaN, in document coordinates. */ insertPointAt(i: number, x: number, y: number): void; /** * Add a point at the end of the route; this may only be called within an override of #computePoints. * @param {Point} p The new point in document coordinates, which should not have infinite or NaN coordinate values, and which must not be modified afterwards. * @see #getPoint * @see #setPoint * @see #insertPoint * @see #removePoint * @since 1.6 */ addPoint(p: Point): void; /** * (undocumented) * Add a point at the end of the route; this may only be called within an override of #computePoints. * @param {number} x The new X, which should not be infinite or NaN, in document coordinates. * @param {number} y The new Y, which should not be infinite or NaN, in document coordinates. */ addPointAt(x: number, y: number): void; /** * Remove a particular point from the route; this may only be called within an override of #computePoints. * @param {number} i int The zero-based index of the point to extract. * @see #getPoint * @see #setPoint * @see #insertPoint * @see #addPoint * @see #clearPoints * @since 1.6 */ removePoint(i: number): void; /** * Remove all of the points from this link's route; this may only be called within an override of #computePoints. * @see #getPoint * @see #setPoint * @see #insertPoint * @see #addPoint * @see #removePoint * @since 1.6 */ clearPoints(): void; /** * (undocumented) * Allow calls to #setPoint, #addPoint, #insertPoint, * #removePoint, and #clearPoints. * You must call #commitRoute when you are done modifying the route. */ startRoute(): void; /** * (undocumented) * Call this method after a call to #startRoute and calls to methods that modify the route. */ commitRoute(): void; /** * (undocumented) * Call this method instead of #commitRoute if you need to cancel changes to the route. */ rollbackRoute(): void; /** * Declare that the route (the #points) of this Link need to be recomputed soon. * This causes #updateRoute to be called, which will call #computePoints * to perform the actual determination of the route. * @since 1.6 */ invalidateRoute(): void; set suspendsRouting(value: boolean); /** * (undocumented) */ get defaultFromPoint(): Point; set defaultFromPoint(value: Point); /** * (undocumented) */ get defaultToPoint(): Point; set defaultToPoint(value: Point); /** * This method recomputes the route if the route is invalid, * to make sure the #points are up-to-date. * This method calls #computePoints in order to calculate a new route. * * The route may become invalid if either connected node is moved, * or if various properties are modified, such as #routing. * Such changes will call #invalidateRoute. * * It is unusual for you to have to call this method. * @since 1.6 */ updateRoute(): void; /** * The code that constructs a new route by modifying the #points. * It is only called by #updateRoute, when needed. * All route points are always in document coordinates. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * * Overrides of this method may call a number of "protected" methods in order to build the route: * #clearPoints, #addPoint, #insertPoint, #removePoint, #setPoint. * Overrides of this method must not set #points. * * Other methods that are commonly called and may be overridden are: * #computeEndSegmentLength, #computeSpot, #computeOtherPoint, * #computeCurve, #computeCurviness, #hasCurviness, * #computeThickness, * #makeGeometry. * @expose * @return {boolean} true if it computed a route of points * @since 1.6 */ computePoints(): boolean; /** * Compute the intersection point in document coordinates for the edge of a particular port GraphObject, given a point, * when no particular spot or side has been specified. * @expose * @param {Node} node * @param {GraphObject} port the GraphObject representing a port on the node. * @param {Point} focus the point in document coordinates to/from which the link should point, * normally the center of the port. * @param {Point} p often this point is far away from the node, to give a general direction, * particularly an orthogonal one. * @param {boolean} from true if the link is coming out of the port; false if going to the port. * @param {Point=} result an optional Point that is modified and returned; otherwise it allocates and returns a new Point * @return {Point} the point in document coordinates of the intersection point on the edge of the port. * @since 1.2 */ getLinkPointFromPoint(node: Node | null, port: GraphObject | null, focus: Point, p: Point, from: boolean, result?: Point): Point; /** * Compute the point on a node/port in document coordinates at which the route of a link should end. * @expose * @param {Node} node * @param {GraphObject} port the GraphObject representing a port on the node. * @param {Spot} spot a Spot value describing where the link should connect. * @param {boolean} from true if the link is coming out of the port; false if going to the port. * @param {boolean} ortho whether the link should have orthogonal segments. * @param {Node} othernode the node at the other end of the link. * @param {GraphObject} otherport the GraphObject port at the other end of the link. * @param {Point=} result an optional Point that is modified and returned; otherwise it allocates and returns a new Point * @return {Point} in document coordinates. * @since 1.2 */ getLinkPoint(node: Node | null, port: GraphObject, spot: Spot, from: boolean, ortho: boolean, othernode: Node | null, otherport: GraphObject, result?: Point): Point; /** * Compute the direction in which a link should go from a given connection point. * @expose * @param {Node} node * @param {GraphObject} port the GraphObject representing a port on the node. * @param {Point} linkpoint the connection point, in document coordinates. * @param {Spot} spot a Spot value describing where the link should connect. * @param {boolean} from true if the link is coming out of the port; false if going to the port. * @param {boolean} ortho whether the link should have orthogonal segments. * @param {Node} othernode the node at the other end of the link. * @param {GraphObject} otherport the GraphObject port at the other end of the link. * @return {number} the absolute angle, in degrees. * @since 1.2 */ getLinkDirection(node: Node | null, port: GraphObject | null, linkpoint: Point, spot: Spot, from: boolean, ortho: boolean, othernode: Node | null, otherport: GraphObject | null): number; /** * Get the length of the end segment in document coordinates, typically a short distance, in document units. * For spot values that are Spot#isSide, this returns a computed value. * Depending on the `from` argument, this will return #fromEndSegmentLength or #toEndSegmentLength. * If the value is `NaN`, this will return the #fromPort's GraphObject#fromEndSegmentLength * or the #toPort's GraphObject#toEndSegmentLength. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Node} node * @param {GraphObject} port the GraphObject representing a port on the node. * @param {Spot} spot a Spot value describing where the link should connect. * @param {boolean} from true if the link is coming out of the port; false if going to the port. * @return {number} a distance in document coordinates; must be a real number, not NaN or infinity. * @since 1.6 */ computeEndSegmentLength(node: Node | null, port: GraphObject | null, spot: Spot, from: boolean): number; /** * Get the Spot that describes how the end of the link should connect with the port. * Depending on the `from` argument, this will return #fromSpot or #toSpot. * If the value is Spot#isDefault, this will return the #fromPort's GraphObject#fromSpot * or the #toPort's GraphObject#toSpot. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {boolean} from * @param {GraphObject=} port * @return {Spot} must not be Spot.Default, but may be Spot.None * @since 1.6 */ computeSpot(from: boolean, port?: GraphObject | null): Spot; /** * Find the approximate point of the other end of the link in document coordinates. * This is useful when computing the connection point when there is no specific spot, to have an idea of which general direction the link should be going. * By default this will return the center of the other port. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Node} othernode * @param {GraphObject} otherport * @return {Point} approximately where the other end of this link might end, in document coordinates * @since 1.6 */ computeOtherPoint(othernode: Node, otherport: GraphObject): Point; /** * (undocumented) * @expose * @param {boolean} from * @return {number} must be a real number, not NaN or infinity. */ protected computeShortLength(from: boolean): number; /** * This read-only property is true if #routing is a value that implies that the points * of the route should be orthogonal, such that each point shares a common X or a common Y value * with the immediately previous and next points. * This property is completely dependent on the #routing property. * Values of Link.Orthogonal and Link.AvoidsNodes causes this property to be true. * * The points in the route might not actually form an orthogonal route, but when the route is computed * the intent is to maintain orthogonality. * @since 1.2 */ get isOrthogonal(): boolean; /** * (undocumented) * This read-only property is true when the routing tries to be smart about not overlapping other parts. */ get isAvoiding(): boolean; /** * Returns the #curve, unless this link is supposed to pretend to be curved, as with reflexive links. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {EnumValue} * @since 1.6 */ computeCurve(): EnumValue; /** * (undocumented) * Returns the #corner, if it's a non-negative number, or else 10. * @expose * @return {number} must be a real number, not NaN or infinity */ protected computeCorner(): number; /** * (undocumented) * Returns the first label that should be at the "middle" of the link, if there is any such label. * Elements that have .isPanelMain === true are ignored, including the #path. * Elements that have a GraphObject#segmentIndex set are ignored, such as arrowheads. * If there are no label objects within the Link Panel, consider any #labelNodes * whose segmentIndex has not been set. * This could be overridden to return a different label than the first one, or to always return null. * @expose * @return {GraphObject} */ findMidLabel(): GraphObject | null; /** * Returns the expected spacing between this link and others that connect this link's fromPort and toPort. * This calls #computeThickness and also takes any "mid label"'s breadth into account. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {number} must be a real number, not NaN or infinity * @see #computeCurviness * @since 1.6 */ computeSpacing(): number; /** * (undocumented) * Sort the Links between two ports and invalidate their routes. * Only one of the Links in the bundle will get this method called -- it is undetermined which Link is chosen. * * By default does not change the order of the links, but does invalidate all routes if REROUTE is true. * This method must not add Links to or remove Links from the argument Array, but may re-order the Links in the Array. * @expose * @param {Array.} links * @param {boolean} reroute */ arrangeBundledLinks(links: Array, reroute: boolean): void; /** * Returns the #curviness, if it's a number, * or else a computed value based on how many links connect this pair of nodes/ports, * by calling #computeSpacing on each link. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {number} must be a real number, not NaN or infinity * @see #computeSpacing * @since 1.6 */ computeCurviness(): number; /** * Returns the thickness of this link. * By default it uses the strokeWidth of the main element, assuming it's a Shape. * This is called by #computeSpacing. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {number} a non-negative real number * @since 1.6 */ computeThickness(): number; /** * Returns true if an extra or a different point is needed based on #curviness. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {boolean} * @since 1.6 */ hasCurviness(): boolean; /** * (undocumented) * This method is called by #computePoints when the link is orthogonal * and at least one port has a link spot that is not Spot#isNoSpot. * * #computePoints is responsible for adding the first two * and the last two points of the stroke, including the startFrom and endTo values. * This method is responsible for adding any additional points in the middle of the stroke. * This method calls #computeMidOrthoPosition to determine the * distance of the middle segment between the two ports. * It also tries to avoid the source node and the destination node. * When the #routing property is not Normal, * this method uses another, more computationally expensive, * method for determining the proper path of the link, which may have many segments. * @expose * @param {Point} startFrom this Point will already have been added to the stroke by #computePoints before calling this method. * @param {number} fromDir Normally 0, 90, 180, or 270 degrees. * @param {Point} endTo #computePoints will add this Point after calling this method. * @param {number} toDir Normally 0, 90, 180, or 270 degrees. * @param {Node} fromnode the Node that the link is coming from. * @param {Node} tonode the Node that the link is going to. */ addOrthoPoints(startFrom: Point, fromDir: number, endTo: Point, toDir: number, fromnode: Node, tonode: Node): void; /** * (undocumented) * This method is called by #addOrthoPoints to determine the distance * of the middle segment between the two ports. * @expose * @param {number} fromX The first point's X coordinate. * @param {number} fromY The first point's Y coordinate. * @param {number} toX The last point's X coordinate. * @param {number} toY The last point's Y coordinate. * @param {boolean} vertical Whether the mid-position is along the vertical axis or horizontal axis. * @return {number} must be a real number, not NaN or infinity */ protected computeMidOrthoPosition(fromX: number, fromY: number, toX: number, toY: number, vertical: boolean): number; /** * Find the index of the segment that is closest to a given point. * This assumes the route only has straight line segments. * It ignores any jump-overs or jump-gaps. * @param {Point} p the Point, in document coordinates. * @return {number} int the index of the segment, from zero to the number of points minus 2. */ findClosestSegment(p: Point): number; /** * This read-only property returns the Geometry that is used by the #path, the link Shape based on the route points. * * This geometry is automatically generated using the route points and other properties * such as the #curve. * The points of the Geometry are in local coordinates, whereas the #points of the link route are in document coordinates. * * More than one Shape may share this geometry as its Shape#geometry, * if there is more than one shape element in the Link with GraphObject#isPanelMain set to true. */ get geometry(): Geometry; /** * Produce a Geometry given the points of this route, * depending on the value of #curve and #corner and perhaps other properties. * The points of the Geometry are in local coordinates, whereas the #points of the link route are in document coordinates. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {Geometry} * @since 1.6 */ makeGeometry(): Geometry; /** * (undocumented) */ get firstPickIndex(): number; /** * (undocumented) */ get lastPickIndex(): number; /** * Gets or sets how the route is computed, including whether it uses the points of its old route to determine the new route. * The value must be one of Link.None|None, Link.End|End, Link.Scale|Scale, or Link.Stretch|Stretch. * * The default value is Link.None|None -- the route is completely recalculated each time. * @see #computeAdjusting */ get adjusting(): EnumValue; set adjusting(value: EnumValue); /** * Returns the #adjusting value, unless this Link's Diagram is animating and the routing is AvoidsNodes -- * then it will return Link.End|End * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * * @expose * @return {EnumValue} * @since 2.1 * @see #adjusting */ computeAdjusting(): EnumValue; /** * Gets or sets how rounded the corners are for adjacent line segments when the #curve * is Link.None|None, Link.JumpGap|JumpGap, or Link.JumpOver|JumpOver and * the two line segments are orthogonal to each other. * * The default value is zero -- there is no curve at a corner. */ get corner(): number; set corner(value: number); /** * Gets or sets the way the path is generated from the route's points. * The value must be one of Link.None|None, Link.Bezier|Bezier, Link.JumpGap|JumpGap, or Link.JumpOver|JumpOver. * * Setting this property to Link.JumpOver|JumpOver or Link.JumpGap|JumpGap requires the Diagram to do * considerable computation when calculating Link routes. Consider not using * a Jump... value with Diagrams that contain large numbers of Links * if you are targeting slow devices. * * The default value is Link.None|None -- each link segment is a straight line. * @see #computeCurve */ get curve(): EnumValue; set curve(value: EnumValue); /** * Gets or sets how far the control points are offset when the #curve is Link.Bezier|Bezier * or when there are multiple links between the same two ports. * * The default value is NaN -- the actual curviness is computed based on how many links connect the same pair of ports. * @see #computeCurviness */ get curviness(): number; set curviness(value: number); /** * Gets or sets whether the link's path tries to avoid other nodes. * The value must be one of Link.Normal|Normal, Link.Orthogonal|Orthogonal, or Link.AvoidsNodes|AvoidsNodes. * * Setting this property to Link.AvoidsNodes|AvoidsNodes requires the Diagram to do * considerable computation when calculating Link routes. Consider not using * the Link.AvoidsNodes|AvoidsNodes with Diagrams that contain large numbers of Nodes and Links * if you are targeting slow devices. * When using Link.AvoidsNodes|AvoidsNodes, dragging performance can be improved by setting DraggingTool#isComplexRoutingRealtime to false. * * The default value is Link.Normal|Normal -- the route is primarily a single straight segment, * with possible short end segments when connecting with ports that have a "spot" value * as the #fromSpot or GraphObject#fromSpot or #toSpot or GraphObject#toSpot. */ get routing(): EnumValue; set routing(value: EnumValue); /** * Gets or sets how far the control points are from the points of the route * when #routing is Link.Orthogonal|Orthogonal and #curve is Link.Bezier|Bezier. * * The default value is 0.5. * Values of this property typically fall in the range of 0.0 to 1.0. * A value of 0.0 indicates that the control points of the curve are at the end points, * which will result in straight line segments. * A value of 1.0 indicates that the control points are one-third of the link's * length away from the end point along the direction of the link, * and the same distance away in a perpendicular direction. * The distance scales linearly with the value of this property, * even with negative values and values greater than 1.0. */ get smoothness(): number; set smoothness(value: number); /** * This read-only property returns the Links's Model data key if it is in a Diagram and is backed by Model data. * Otherwise this returns undefined. * * If the link data is in a GraphLinksModel, the GraphLinksModel#linkKeyProperty must not be an empty string. * @since 1.8 * @see GraphLinksModel#getKeyForLinkData */ get key(): Key; } /** * This is the base class for all of the predefined diagram layout implementations. * They only arrange Parts (primarily Nodes and Links) in a Diagram, * not to GraphObjects in Panels (i.e. panel layout). * * The layout classes include TreeLayout, ForceDirectedLayout, * LayeredDigraphLayout, CircularLayout, and GridLayout. * This base class is not abstract -- in fact an instance of this base class is the default * value for Diagram#layout and for Group#layout. * * An instance of a Layout class will be the value of Diagram#layout. * That layout positions the graph of top-level nodes and links. * Nodes and links that belong to a Group are laid out by that group's Group#layout. * The Diagram will automatically perform all nested group layouts before laying out the whole diagram. * * If you have position information for all of the nodes when you load a model, * you will typically have data bound the Part#location to some property on your node data. * In order to avoid an initial layout causing those saved node positions to be discarded, * you can either not set the Diagram#layout to a predefined layout or you can * set #isInitial to false. * * Because performing layouts can be expensive in space and time, automatic layouts * are performed only on "invalid" layouts, and only well after a layout has been invalidated. * This state is held by the #isValidLayout property. * Many standard operations, such as adding or removing nodes or links, will cause * the layout that is responsible for positioning those nodes or routing those links * to be invalidated. * Such invalidation is performed by calling #invalidateLayout, * which not only clears the #isValidLayout state but also requests that the diagram * do an automatic layout soon. * You can avoid such invalidations by setting #isOngoing to false. * * Layouts will ignore parts that have Part#isLayoutPositioned set to false * or parts that are not GraphObject#visible. * Layouts will also ignore parts that are in layers that are Layer#isTemporary. * * Various operations on Parts will cause the responsible Layout to be invalidated. * This includes adding or removing parts, changing their visibility, and changing their size. * You can disable such automatic layout invalidations by setting Part#layoutConditions * to the combination of Part flags named "Layout..." that you want. * * But operations on parts are not the only way in which layouts become invalidated. * Setting most properties on the layouts, thereby changing their behavior, will invalidate that layout. * Replacing the Diagram#layout or Group#layout will automatically invalidate the new layout. * If #isViewportSized is true, when a diagram's Diagram#viewportBounds changes size, * the Diagram#layout is invalidated. * (This is normally only true for GridLayouts when its GridLayout#wrappingWidth is `NaN`. * Most layouts do not care about the size of the viewport.) * * You can also explicitly call Diagram#layoutDiagram, which can invalidate all layouts and * then perform them all. * But we recommend that you avoid doing so, to allow the normal updating process perform layouts as needed. * * If an automatic layout is the first time that a layout has been performed for the model, * the diagram first raises the DiagramEvent named "InitialLayoutCompleted". * Whenever a Diagram finishes an automatic layout, it raises the DiagramEvent named "LayoutCompleted". * * It is also possible to call #doLayout explicitly, but this is uncommon and only used with * instances of Layout that are not the Diagram#layout or Group#layout. * It should only be needed when you want to layout a collection of nodes and links that is not * the normal graph of top-level parts of a Diagram or a subgraph of a Group. * * More complicated layouts make use of a separate LayoutNetwork, consisting of LayoutVertexes and LayoutEdges, * that normally holds a graph that is isomorphic to the graph consisting of Nodes and Links in the Diagram or Group. * The implementation of #doLayout will call #makeNetwork and remember the result as the #network. * #makeNetwork will call #createNetwork and initialize it by adding new instances of LayoutVertexes and LayoutEdges * corresponding to the given collection of Nodes and Links. * * When #doLayout is finished with its work it will call #updateParts, which will call #commitLayout * to set new node locations and route links. It then normally discards the #network. * * The LayoutVertex and LayoutEdge instances allow the layout to work with more information about each Node and Link without * actually modifying those Nodes and Links until #commitLayout is called to actually set the Node locations and route the Links. * The use of a LayoutNetwork also allows the Layout to work with a graph that is not isomorphic to the given collection of Nodes and Links. * This is useful when needing to use dummy vertexes and/or edges to achieve certain layout behaviors, * or when one wants to ignore certain vertexes or edges, without actually modifying or adding or removing the diagram's nodes or links. * * An instance of this base class provides a rudimentary default layout that will position * all of the parts that have no position (i.e. the Part#location is (NaN,NaN). * Parts that already have a position are ignored. * This primitive layout class does not make use of a LayoutNetwork because * it ignores all links. * * To implement your own custom layouts, you can inherit from either this class or * from one of the other predefined layout classes. * If you inherit from this base class, you will want to override the #doLayout method. * You can call the Part#move method to re-position a part, including whole groups. * Please read the Introduction page on Extensions for how to override methods and how to call a base method. * @category Layout */ export class Layout { /** * Create a minimal layout that only positions Nodes that do not have a location. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * Copies properties from this object to the given object, which is of the same class. * This is called by #copy and should be overridden for each class that adds properties. * There are examples of such overrides in the samples. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {?} copy * @since 1.6 */ protected cloneProtected(copy: this): void; /** * Creates a copy of this Layout and returns it. * When a Group is copied that has a Group#layout, the Layout must also be copied. * This calls #cloneProtected on a newly constructed Layout. * @expose * @return {Layout} */ copy(): this; /** * Gets the Diagram that owns this layout, if it is the value of Diagram#layout. * * If this property and #group are non-null, the Group should be in this Diagram. * @see #group */ get diagram(): Diagram | null; set diagram(value: Diagram | null); /** * Gets the Group that uses this layout, if it is the value of a group's Group#layout. * * If this property is set to a Group, the #diagram is automatically set to be the Group's Diagram. * @see #diagram */ get group(): Group | null; set group(value: Group | null); /** * Gets or sets whether this layout can be invalidated by #invalidateLayout. * Set this to false to prevent actions such as adding or removing Parts from invalidating this layout. * The default value is true. * Setting this property does not invalidate this layout. * * If you set both #isInitial and #isOngoing to false, * there will be no automatic layout invalidation, because #invalidateLayout * will not set #isValidLayout to false. * To get your nodes to appear, you will need to explicitly set or data-bind their Part#location * or GraphObject#position to real Point values, because automatic layout will not assign any positions. * * Another way of controlling when layouts are invalidated is by setting * Part#isLayoutPositioned or Part#layoutConditions. */ get isOngoing(): boolean; set isOngoing(value: boolean); /** * Gets or sets whether this layout is performed on an initial layout. * The default value is true. * Setting this property to false causes #isValidLayout to be set to true * so that the diagram does not perform this layout. * * If you set both #isInitial and #isOngoing to false, * there will be no automatic layout invalidation, because #invalidateLayout * will not set #isValidLayout to false. * To get your nodes to appear, you will need to explicitly set or data-bind their Part#location * or GraphObject#position to real Point values, because automatic layout will not assign any positions. * * Another way of controlling when layouts are invalidated is by setting * Part#isLayoutPositioned or Part#layoutConditions. */ get isInitial(): boolean; set isInitial(value: boolean); /** * Gets or sets whether this layout depends on the Diagram#viewportBounds's size. * If set to true, the layout will invalidate when the Diagram's viewport changes size. * This only applies to diagram layouts, not to group layouts, * and only when Diagram#autoScale is set to Diagram.None. * * The default value is false. * Setting this property to true will invalidate this layout. * * It is possible that a viewport-sized layout will trigger the Diagram to require scrollbars, * which modifies the Diagram#viewportBounds, which will in turn trigger another layout. * This is uncommon, but possible with GridLayout if the results require a vertical scrollbar, * and that vertical scrollbar shrinks the viewport width enough that a grid column can no longer fit. * When designing custom layouts, one should be careful that this behavior does not result in an infinite loop. */ get isViewportSized(): boolean; set isViewportSized(value: boolean); /** * Gets or sets whether this layout routes Links. * The default value is true. * When false, this layout will not explicitly set the Link#points, * and the default routing of each individual Link will take place after the Nodes are moved by #commitLayout. * Setting this property does not invalidate this layout. * * Some layouts ignore links, in which case this property is ignored. * @since 1.1 */ get isRouting(): boolean; set isRouting(value: boolean); /** * Gets or sets whether this layout be performed in real-time, before the end of a transaction. * All layouts that are invalidated will be performed at the end of a transaction. * The default value is null. * A null value is treated as true for a Diagram#layout but false for a Group#layout. * Setting this property does not invalidate this layout. * @since 1.2 */ get isRealtime(): boolean | null; set isRealtime(value: boolean | null); /** * Gets or sets whether this layout needs to be performed again (if false). * Instead of setting this property directly, it is normal to set it to false by calling #invalidateLayout, * since that also requests performing a layout in the near future. */ get isValidLayout(): boolean; set isValidLayout(value: boolean); /** * If #isOngoing is true and if an initial layout has not yet been performed, * set the #isValidLayout property to false, and ask to perform another layout in the near future. * If #isInitial is true, this layout is invalidated only when the Diagram#model is replaced, * not under the normal circumstances such as when parts are added or removed or * due to other calls to Layout#invalidateLayout. * * If you set both #isInitial and #isOngoing to false, * there will be no automatic layout invalidation, because this method * will not set #isValidLayout to false. * However you can still set #isValidLayout explicitly. * * This is typically called when a layout property value has changed, * or when a Part is added or removed or changes visibility, if Part#layoutConditions includes the pertinent flags. */ invalidateLayout(): void; /** * Gets or sets the LayoutNetwork used by this Layout, if any. * The default value is null. * Setting this property does not invalidate this layout. * Not all kinds of layout make use of a LayoutNetwork. * Call #createNetwork or #makeNetwork to create a network. */ get network(): LayoutNetwork | null; set network(value: LayoutNetwork | null); /** * Create a new LayoutNetwork of LayoutVertexes and LayoutEdges. * This may be overridden in Layout subclasses to create instances of subclasses of * LayoutNetwork. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {LayoutNetwork} a new LayoutNetwork. */ createNetwork(): LayoutNetwork; /** * Create and initialize a LayoutNetwork with the given nodes and links. * This should be called by #doLayout when this layout uses a #network. * This method calls #createNetwork to allocate the network. * This may be overridden in Layout subclasses to customize the initialization. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Diagram|Group|Iterable.} coll A Diagram or a Group or a collection of Parts. * @return {LayoutNetwork} normally the value of a call to #createNetwork initialized by vertexes and edges corresponding to the *coll* argument. */ makeNetwork(coll: Diagram | Group | Iterable): LayoutNetwork; /** * When using a LayoutNetwork, update the "physical" node positionings and link routings. * This should be called by #doLayout when this layout uses a #network. * This calls #commitLayout to actually set Node positions and route Links. * This performs the changes within a transaction. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ updateParts(): void; /** * When using a LayoutNetwork, commit changes to the diagram * by setting Node positions and by routing the Links. * This is called by #updateParts within a transaction. * * You should not call this method -- it is a "protected virtual" method. * This may be overridden by subclasses of Layout. * By default this method is implemented as follows: * ```js * protected commitLayout() { * if (this.network === null) return; * var vit = this.network.vertexes.iterator; * while (vit.next()) { * var vert = vit.value; * vert.commit(); * } * if (this.isRouting) { * var eit = this.network.edges.iterator; * while (eit.next()) { * var edge = eit.value; * edge.commit(); * } * } * } * ``` * * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ protected commitLayout(): void; /** * Position all of the nodes that do not have an assigned Part#location * in the manner of a simple rectangular array. * The default implementation ignores all Groups and Links; * many subclasses of Layout ignore all instances of Parts * that are not Nodes or Links. * * You can override this method to do whatever node positioning and link routing * that you wish. * * When the layout makes use of a LayoutNetwork, * this method should call #makeNetwork and #updateParts. * The #updateParts method will call #commitLayout within a transaction. * The outline of such an override should be like: * ```js * public doLayout(coll) { * if (this.network === null) this.network = this.makeNetwork(coll); * // assign LayoutVertex.bounds to all vertexes in the network: * var vit = this.network.vertexes.iterator; * while (vit.next()) { * var v = vit.value; * v.centerX = ... * v.centerY = ... * } * this.updateParts(); * this.network = null; * } * ``` * Override #commitLayout to actually position nodes and route links. * * When the layout does not make use of a LayoutNetwork, * this method should make direct changes to Nodes and Links * within a transaction, and it should call #collectParts on the argument *coll* in order * to get the proper set of Nodes and Links to work on. * Examples are provided in the Extensions directory. * * If this Layout belongs to a Diagram, the argument must be either the same Diagram or must denote Parts that belong to the Diagram. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Diagram|Group|Iterable.} coll A Diagram or a Group or a collection of Parts. */ doLayout(coll: Diagram | Group | Iterable): void; /** * This method is called by layouts to determine the size and initial position of the nodes that it is laying out. * Normally this just returns the part's GraphObject#actualBounds. * However, if #boundsComputation has been set to a function, that function will be called * in order to return the bounds of the given Part in document coordinates that the layout should pretend it has. * @param {Part} part the Part being laid out * @param {Rect=} rect an optional Rect that will be modified and returned * @return {Rect} a Rect in document coordinates * @since 2.0 */ getLayoutBounds(part: Part, rect?: Rect): Rect; /** * Gets or sets a function that determines the initial size and position in document coordinates of a LayoutVertex corresponding to a Node. * This function is called by #getLayoutBounds. * The default value for this property is null, in which case the GraphObject#actualBounds of the Node is used. * Setting this property to a new value invalidates this layout. * * The non-null value must be a function that takes 3 arguments. * The first argument will be the Part whose bounds the Layout should use. * The second argument will be this Layout. * The third argument will be a Rect that must be modified and returned * The return value must be in document coordinates. You may find it convenient to call GraphObject#getDocumentBounds * to get the bounds in document coordinates of an object within the node. * @since 2.0 */ get boundsComputation(): ((part: Part, lay: Layout, rect: Rect) => Rect) | null; set boundsComputation(value: ((part: Part, lay: Layout, rect: Rect) => Rect) | null); /** * A convenient way of converting the Diagram|Group|Iterable argument to doLayout to an actual collection of eligible Parts. * The resulting Set will not include any Nodes or Links for which Part#canLayout is false. * If the argument includes a Group for which Group#layout is null, the resulting Set * will include the member parts of that group rather than that group itself. * You will not need to call collectParts if you call #makeNetwork, * because that method does effectively the same thing when building the LayoutNetwork. * * Typical usage: * ```js * public doLayout(coll) { * // COLL might be a Diagram or a Group or some Iterable * var it = this.collectParts(coll).iterator; * while (it.next()) { * var node = it.value; * if (node instanceof go.Node) { * . . . position the node . . . * } * } * } * ``` * @param {Diagram|Group|Iterable.} coll * @return {Set.} * @since 1.7 */ protected collectParts(coll: Diagram | Group | Iterable): Set; /** * Gets or sets the top-left point for where the graph should be positioned when laid out. * The default value for this property is the Point(0, 0). * Setting this property to a new value invalidates this layout. * This property is likely to be set by many Layouts that belong to a Group when the layout is performed. */ get arrangementOrigin(): Point; set arrangementOrigin(value: Point); /** * Compute the desired value of #arrangementOrigin if this Layout is being performed for a Group. * This is typically called near the beginning of the implementation of #doLayout: * `this.arrangementOrigin = this.initialOrigin(this.arrangementOrigin);` * if the layout wants to respect the pre-layout location of the Group when deciding where to position its member nodes. * @expose * @param {Point} origin * @return {Point} */ protected initialOrigin(origin: Point): Point; } /** * This provides an abstract view of a diagram as a * network (graph) of vertexes and directed edges. * The network contains vertexes and edges corresponding to Nodes and Links. * * This class provides a framework for manipulating the * state of nodes and links without modifying the structure of the diagram. * Having a separate representation also permits adding or removing vertexes or edges * from the network so that the graph that is laid out is not isomorphic to the diagram's graph. * * For each kind of layout that uses a LayoutNetwork there is a subclass of LayoutVertex and a subclass of LayoutEdge: * - CircularLayout: CircularVertex and CircularEdge * - ForceDirectedLayout: ForceDirectedVertex and ForceDirectedEdge * - LayeredDigraphLayout: LayeredDigraphVertex and LayeredDigraphEdge * - TreeLayout: TreeVertex and TreeEdge * * Modifying a LayoutNetwork or a LayoutVertex or a LayoutEdge does not * invalidate the Layout or raise any changed events. * @unrestricted * @category Layout */ export class LayoutNetwork { /** * This constructs an empty network. * It is commonplace to call #addParts to build up the network * to have the same structure as a Diagram's or Group's nodes and links. */ constructor(layout: Layout); /** * Gets the Layout that uses this network * of LayoutVertexes and LayoutEdges. * The default value is null. * It is set automatically for you when this setting Layout#network. */ get layout(): Layout; set layout(value: Layout); /** * Gets a collection of all of the LayoutVertexes in this network. * Do not modify this collection directly. * Instead, call #addVertex, #deleteVertex, #addNode, or #deleteNode. */ get vertexes(): Set; /** * Gets a collection of all of the LayoutEdges in this network. * Do not modify this collection directly. * Instead, call #addEdge, #deleteEdge, #addLink, or #deleteLink. */ get edges(): Set; /** * Allocate a new instance of LayoutVertex. * This is overridden in LayoutNetwork subclasses to create instances of subclasses of LayoutVertex. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {LayoutVertex} */ createVertex(): LayoutVertex; /** * Allocate a new instance of LayoutEdge. * This is overridden in LayoutNetwork subclasses to create instances of subclasses of LayoutEdge. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @return {LayoutEdge} */ createEdge(): LayoutEdge; /** * Creates a network of LayoutVertexes and LayoutEdges * corresponding to the given Nodes and Links. * This is usually more convenient than repeatedly calling #addNode and #addLink. * This method ignores all instances of Parts that are not Nodes or Links. * This will recurse through Groups that have no Group#layout. * @param {Iterable.} parts A collection of Nodes or Links. * @param {boolean=} toplevelonly whether to skip Parts in the given collection that are contained by Groups; default is false * @param {function(Part):boolean|null=} pred optional predicate to apply to each Part -- * if it returns false do not include Vertex or Edge in the network; * default ignores link label nodes or links connecting with them */ addParts(parts: Iterable, toplevelonly?: boolean, pred?: ((a: Part) => boolean) | null): void; /** * Adds a LayoutVertex to the network. * @param {LayoutVertex} vertex */ addVertex(vertex: LayoutVertex): void; /** * This convenience method makes sure there is a LayoutVertex * in this network corresponding to a Node. * @param {Node} node * @return {LayoutVertex} a vertex in this network. */ addNode(node: Node): LayoutVertex; /** * Removes a LayoutVertex from the network. * This function also deletes all edges to or from the vertex. * @param {LayoutVertex} vertex */ deleteVertex(vertex: LayoutVertex): void; /** * This convenience method deletes any LayoutVertex * corresponding to a Node. * @param {Node} node */ deleteNode(node: Node): void; /** * Returns the LayoutVertex that was constructed for the Node. * @param {Node} node * @return {LayoutVertex} a vertex in this network, or null if no such vertex exists. */ findVertex(node: Node): LayoutVertex | null; /** * Adds a LayoutEdge to the network. * Although this method is provided for completeness, * #linkVertexes provides a more efficient manner of linking * vertexes already in the network. * @param {LayoutEdge} edge */ addEdge(edge: LayoutEdge): void; /** * This convenience method makes sure there is a LayoutEdge * in this network corresponding to a Link. * If #findEdge returns null, this method creates a new LayoutEdge, * makes sure the Link#fromNode and Link#toNode have * corresponding LayoutVertexes in the network, and adds the edge itself * to the network. * @param {Link} link * @return {LayoutEdge} an edge in this network. */ addLink(link: Link): LayoutEdge; /** * Removes a LayoutEdge from the network. * @param {LayoutEdge} edge */ deleteEdge(edge: LayoutEdge): void; /** * This convenience method deletes from this network any LayoutEdge * corresponding to a Link. * @param {Link} link */ deleteLink(link: Link): void; /** * Returns the LayoutEdge that was constructed for the Link. * @param {Link} link * @return {LayoutEdge} an edge in this network, or null if no such edge exists. */ findEdge(link: Link): LayoutEdge | null; /** * Links two vertexes already in the network and returns the created LayoutEdge. * @param {LayoutVertex} fromVertex * @param {LayoutVertex} toVertex * @param {Link} link * @return {LayoutEdge} an edge in this network, or null if both vertexes don't exist. */ linkVertexes(fromVertex: LayoutVertex, toVertex: LayoutVertex, link: Link | null): LayoutEdge; /** * Reverses the direction of a LayoutEdge in the network. * @param {LayoutEdge} edge */ reverseEdge(edge: LayoutEdge): void; /** * Deletes all LayoutEdges whose "to vertex" and "from vertex" are the same vertex. */ deleteSelfEdges(): void; /** * Deletes all vertexes and edges that have no Part associated with them. * @expose */ deleteArtificialVertexes(): void; /** * Modify this network by splitting it up into separate subnetworks, * each of which has all of its vertexes connected to each other, but not * to any vertexes in any other subnetworks. * * This method will first delete from this network all artificial vertexes and * all edges that do not connect two different vertexes. * Afterwards, this original network may be empty or may contain all of the * singleton vertexes, each of which had no edges connecting it to any other vertexes. * @param {boolean=} clean whether to delete artificial vertexes and edges, disconnected edges, and reflexive edges; default is true * @return {List.} a collection of LayoutNetworks, * sorted in order of decreasing vertex count. */ splitIntoSubNetworks(clean?: boolean): List; /** * Retrieve all of the Nodes and Links from the * LayoutVertexes and LayoutEdges that are in this network. * @return {Set.} A collection of Parts. * @since 1.1 */ findAllParts(): Set; } /** * A vertex represents a Node in a LayoutNetwork, * along with its #bounds and #focus and collections of LayoutEdges that come into and go out of the vertex. * The #node property may be null for vertexes that represent "dummy" nodes, * when the layout wants to work with a network that is not isomorphic with the collection of Nodes and Links being laid out. * * This holds layout-specific data for the node. * For each kind of layout that uses a LayoutNetwork there is a subclass of LayoutVertex and a subclass of LayoutEdge: * - CircularLayout: CircularVertex and CircularEdge * - ForceDirectedLayout: ForceDirectedVertex and ForceDirectedEdge * - LayeredDigraphLayout: LayeredDigraphVertex and LayeredDigraphEdge * - TreeLayout: TreeVertex and TreeEdge * * Modifying a LayoutNetwork or a LayoutVertex or a LayoutEdge does not * invalidate the Layout or raise any changed events. * @unrestricted * @category Layout */ export class LayoutVertex { /** * This constructs a vertex that does not know about any Node. */ constructor(network: LayoutNetwork); /** * (undocumented) */ get sourceEdgesArrayAccess(): Array; /** * (undocumented) */ get destinationEdgesArrayAccess(): Array; /** * Gets or sets the data object in the model that should be associated with this vertex, if any. * The value will be non-null if this vertex is virtualized, * not represented by a real Node in the Diagram. * Each data object should have a 'bounds' property that is a Rect * or any JavaScript Object with 'x', 'y', 'width', and 'height' properties that are real numbers, * and non-negative numbers for the width and the height. * Setting this data property will also set the #bounds and #focus properties. * @since 1.6 */ get data(): ObjectData | null; set data(value: ObjectData | null); /** * Gets or sets the Node associated with this vertex, if any. * The value may be null if this vertex is a "dummy" vertex, * not represented by a real Node in the Diagram. * * This property setter also sets the #bounds and #focus properties * according to the value of the Node's actualBounds and its Part#locationObject's center point. */ get node(): Node | null; set node(value: Node | null); /** * Gets or sets the bounds of this vertex, in document coordinates. * Setting this property does not directly modify the position of any Node, * but it will modify the value of #centerX and #centerY, * as well as the subsidiary convenience properties #x, #y, #width, and #height. */ get bounds(): Rect; set bounds(value: Rect); /** * Gets or sets the offset of the #focusX and #focusY * from the #bounds position. * Setting this property does not directly modify the position of any Node, * but it does affect the value of #centerX and #centerY. * * The "focus" is normally the center of the Node's Part#locationObject. */ get focus(): Point; set focus(value: Point); /** * Gets or sets the center Point#x of this vertex, in document coordinates. * This property depends on both #bounds and #focus. * Setting this property does not modify the position of any Node, * but it will modify the value of #bounds. */ get centerX(): number; set centerX(value: number); /** * Gets or sets the center Point#y of this vertex, in document coordinates. * This property depends on both #bounds and #focus. * Setting this property does not modify the position of any Node, * but it will modify the value of #bounds. */ get centerY(): number; set centerY(value: number); /** * Gets or sets the relative X position of the "center" point, the focus. */ get focusX(): number; set focusX(value: number); /** * Gets or sets the relative Y position of the "center" point, the focus. */ get focusY(): number; set focusY(value: number); /** * Gets or sets the left point of this vertex. */ get x(): number; set x(value: number); /** * Gets or sets the top point of this vertex. */ get y(): number; set y(value: number); /** * Gets or sets the width of this vertex. * This is always the horizontal distance reserved for the node. */ get width(): number; set width(value: number); /** * Gets or sets the height of this vertex. * This is always the vertical distance reserved for the node. */ get height(): number; set height(value: number); /** * Moves the Node corresponding to this vertex * so that its position is at the current #bounds point. * * To make the most common cases look right, the Node's Part#locationObject * is centered. Thus iconic nodes will have the center of the icon be positioned * according to the center of this vertex, ignoring any labels. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ commit(): void; /** * Adds a LayoutEdge to the list of predecessors * (the edge will be coming into this vertex). * Calling this method does not modify the LayoutEdge#toVertex of the LayoutEdge. * @param {LayoutEdge} edge */ addSourceEdge(edge: LayoutEdge): void; /** * Deletes a LayoutEdge from the list of predecessors * (the edge was coming into this vertex). * Calling this method does not modify the LayoutEdge#toVertex of the LayoutEdge. * @param {LayoutEdge} edge */ deleteSourceEdge(edge: LayoutEdge): void; /** * Adds a LayoutEdge to the list of successors * (the edge will be going out from this vertex). * Calling this method does not modify the LayoutEdge#fromVertex of the LayoutEdge. * @param {LayoutEdge} edge */ addDestinationEdge(edge: LayoutEdge): void; /** * Deletes a LayoutEdge from the list of successors * (the edge was going out from this vertex). * Calling this method does not modify the LayoutEdge#fromVertex of the LayoutEdge. * @param {LayoutEdge} edge */ deleteDestinationEdge(edge: LayoutEdge): void; /** * Gets the LayoutNetwork that owns this vertex. * The default value is null. * It is set automatically for you in LayoutNetwork#createVertex. */ get network(): LayoutNetwork; set network(value: LayoutNetwork); /** * This read-only property returns an iterator for all of the vertexes that are connected with edges coming into this vertex. * * Note that this is inefficient compared to iterating over the edges (#sourceEdges) due to the need * to avoid duplicate vertexes if there happen to be multiple edges connecting with the same vertex. */ get sourceVertexes(): Iterator; /** * This read-only property returns an iterator for all of the vertexes that are connected with edges going out of this vertex. * * Note that this is inefficient compared to iterating over the edges (#destinationEdges) due to the need * to avoid duplicate vertexes if there happen to be multiple edges connecting with the same vertex. */ get destinationVertexes(): Iterator; /** * This read-only property returns an iterator for all of the vertexes that are connected in either direction with this vertex. * * Note that this is inefficient compared to iterating over the edges (#sourceEdges and #destinationEdges) due to the need * to avoid duplicate vertexes if there happen to be multiple edges connecting with the same vertex. */ get vertexes(): Iterator; /** * This read-only property returns an iterator for all of the edges that come into this vertex. */ get sourceEdges(): Iterator; /** * This read-only property returns an iterator for all of the edges that go out of this vertex. */ get destinationEdges(): Iterator; /** * This read-only property returns an iterator for all of the edges that are connected with this vertex in either direction. * * Note that this is inefficient compared to iterating over the edges: #sourceEdges and #destinationEdges. */ get edges(): Iterator; /** * This read-only property returns the total number of edges that are connected with this vertex in either direction. */ get edgesCount(): number; /** * This static function is used to compare the Part#text values of the #nodes of * the argument LayoutVertexes. * This just does a simple case-sensitive string comparison. * Alternatively you may wish to use LayoutVertex.smartComparer or write your own comparison function. * @param {LayoutVertex} m * @param {LayoutVertex} n * @return {number} int -1, 0, or 1, depending on whether the comparison between M and N is less than, equal, or greater than. */ static standardComparer(m: LayoutVertex, n: LayoutVertex): number; /** * This static function is used to compare the Part#text values of the #nodes of * the argument LayoutVertexes. * If the text ends in a number, the values are compared as numbers rather than lexicographically. * Naturally this comparison is significantly slower than LayoutVertex.standardComparer. * @param {LayoutVertex} m * @param {LayoutVertex} n * @return {number} int -1, 0, or 1, depending on whether the comparison between M and N is less than, equal, or greater than. */ static smartComparer(m: LayoutVertex, n: LayoutVertex): number; } /** * An edge represents a Link in a LayoutNetwork, * along with its #fromVertex and #toVertex. * The #link property may be null for edges that represent "dummy" links, * when the layout wants to work with a network that is not isomorphic with the collection of Nodes and Links being laid out. * * It holds layout-specific data for the link. * For each kind of layout that uses a LayoutNetwork there is a subclass of LayoutVertex and a subclass of LayoutEdge: * - CircularLayout: CircularVertex and CircularEdge * - ForceDirectedLayout: ForceDirectedVertex and ForceDirectedEdge * - LayeredDigraphLayout: LayeredDigraphVertex and LayeredDigraphEdge * - TreeLayout: TreeVertex and TreeEdge * * Modifying a LayoutNetwork or a LayoutVertex or a LayoutEdge does not * invalidate the Layout or raise any changed events. * @unrestricted * @category Layout */ export class LayoutEdge { /** * This constructs an edge that does not know about any Link. */ constructor(network: LayoutNetwork); /** * Commits the route of this edge to the corresponding Link, if any. * By default this does nothing. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ commit(): void; /** * Returns the edge's vertex at the other of this edge from the given vertex. * @param {LayoutVertex} v */ getOtherVertex(v: LayoutVertex): LayoutVertex | null; /** * Gets the LayoutNetwork that owns this edge. * The default value is null. * It is set automatically for you in LayoutNetwork#createEdge. */ get network(): LayoutNetwork; set network(value: LayoutNetwork); /** * For virtualized layouts working on model data instead of a Link. * @since 1.6 */ get data(): ObjectData | null; set data(value: ObjectData | null); /** * Gets or sets the Link associated with this edge, if any. * The value may be null if this edge is a "dummy" edge, * not represented by a real Link in the Diagram. */ get link(): Link | null; set link(value: Link | null); /** * Gets or sets the LayoutVertex that this edge comes from. * Setting this property does not change any LayoutVertex#destinationEdges collection. */ get fromVertex(): LayoutVertex | null; set fromVertex(value: LayoutVertex | null); /** * Gets or sets the LayoutVertex that this edge goes to. * Setting this property does not change any LayoutVertex#sourceEdges collection. */ get toVertex(): LayoutVertex | null; set toVertex(value: LayoutVertex | null); } /** * This simple layout places all of the Parts in a grid-like arrangement, ordered, spaced apart, * and wrapping as needed. It ignores any Links connecting the Nodes being laid out. * There are many samples that use GridLayout. * Every Palette uses a GridLayout by default. *

* If you want to experiment interactively with most of the properties, try the Grid Layout sample. * See samples that make use of GridLayout in the samples index. * * By default this layout will sort all of the Parts alphabetically * (comparing Part#text values, respecting case) * and position them left-to-right, separated by #spacing`.width`, * until they do not fit in the current row. * At that time it starts a new row, separated from the previous row by #spacing`.height`. * There is a uniform cell size equal to the maximum Part width (plus spacing width) * and the maximum part height (plus spacing height). * At least one part is placed in each row, even if the part by itself is wider than the wrapping width. * * You can specify values for the #cellSize `width` and `height`. * If a part is wider than the cell size, it spans more than one cell in the row. * You can also specify a value for the #wrappingWidth, * which will be used instead of the diagram's viewport width, to control when each row is considered "full". * The value of Layout#isViewportSized will be true when * the value of #wrappingWidth is `NaN`. * This causes the layout to be performed again automatically as the viewport changes size. * * You can also set #wrappingColumn to limit the number of items in each row. * Both the #wrappingWidth and the #wrappingColumn are respected when deciding when to wrap to the next row. * * This layout is sufficiently simple that it does not use a LayoutNetwork. * @extends Layout * @unrestricted * @category Layout */ export class GridLayout extends Layout { /** * Constructs a GridLayout with no Layout#network * and with no owning Layout#diagram. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * Assign the positions of the parts, ignoring any links. * @param {Diagram|Group|Iterable.} coll A Diagram or a Group or a collection of Parts. */ doLayout(coll: Diagram | Group | Iterable): void; /** * Gets or sets the wrapping width. * * The default is NaN, meaning to use the width of the diagram's panel's viewport. * Must be a value greater than 0. */ get wrappingWidth(): number; set wrappingWidth(value: number); /** * Gets or sets the maximum number of columns. * * The default is NaN, meaning not to limit the number of columns. * 1 is a common value to produce a single column of parts. */ get wrappingColumn(): number; set wrappingColumn(value: number); /** * Gets or sets the minimum part size by which each part is positioned in the grid. * * The default value is NaN x NaN. * The units are in document coordinates. * * When the cell size is smaller than a part, the part will occupy more than one cell. * This allows parts to be positioned closer to each other, but then variations in part * sizes may cause them not to be aligned in perfect rows or columns. */ get cellSize(): Size; set cellSize(value: Size); /** * Gets or sets the minimum horizontal and vertical space between parts. * * The default value is 10 x 10. * The units are in document coordinates. */ get spacing(): Size; set spacing(value: Size); /** * Gets or sets whether the Part#location or the position should be used * to arrange each part. * * The default value is GridLayout.Location -- the Part#locations will * be aligned in a grid. */ get alignment(): EnumValue; set alignment(value: EnumValue); /** * Gets or sets how to arrange the parts. * Must be GridLayout.LeftToRight or GridLayout.RightToLeft. * * The default value is GridLayout.LeftToRight. */ get arrangement(): EnumValue; set arrangement(value: EnumValue); /** * Gets or sets what order to place the parts. * Must be GridLayout.Forward, GridLayout.Reverse, * GridLayout.Ascending, or GridLayout.Descending. * * The default value is GridLayout.Ascending. */ get sorting(): EnumValue; set sorting(value: EnumValue); /** * Gets or sets the comparison function used to sort the parts. * * The default value is a case-insensitive alphabetic comparison * using the Part#text property of each part. * ```js * $(go.GridLayout, * { * sorting: go.GridLayout.Ascending, * comparer: (pa, pb) => { * var da = pa.data; * var db = pb.data; * if (da.someProperty < db.someProperty) return -1; * if (da.someProperty > db.someProperty) return 1; * return 0; * } * } * ) * ``` */ get comparer(): ((a: Part, b: Part) => number); set comparer(value: ((a: Part, b: Part) => number)); /** * Position the top-left corner of each part at a grid point; * This value is used for GridLayout#alignment. * @constant */ static Position: EnumValue; /** * Position the part's Part#location at a grid point; * This value is used for GridLayout#alignment. * @constant */ static Location: EnumValue; /** * Fill each row from left to right; * This value is used for GridLayout#arrangement. * @constant */ static LeftToRight: EnumValue; /** * Fill each row from right to left; * This value is used for GridLayout#arrangement. * @constant */ static RightToLeft: EnumValue; /** * Lay out each child in the order in which they were found; * This value is used for GridLayout#sorting. * @constant */ static Forward: EnumValue; /** * Lay out each child in reverse order from which they were found; * This value is used for GridLayout#sorting. * @constant */ static Reverse: EnumValue; /** * Lay out each child according to the sort order given by GridLayout#comparer * This value is used for GridLayout#sorting. * @constant */ static Ascending: EnumValue; /** * Lay out each child in reverse sort order given by GridLayout#comparer * This value is used for GridLayout#sorting. * @constant */ static Descending: EnumValue; } /** * The Key type is the same as `string | number | undefined`. * @category Type */ export type Key = string | number | undefined; /** * For bindings: A side-effect-free function converting the data property value to the value to set the target property. * If the function is null or not supplied, no conversion takes place. * @category Type */ export type TargetConversion = ((val: any, targetObj: any) => any) | null; /** * For bindings: The optional conversion function to convert property values back to data values. * Specifying this function modifies a binding to set its Binding#mode to be Binding.TwoWay. * If you want a two-way binding without a back-conversion function, specify `null` for a `BackConversion`. * If you do not want a two-way binding, omit any `BackConversion`. * @category Type */ export type BackConversion = ((val: any, sourceData: any, model: Model) => any) | null; /** * Interface for the output object of Model#toIncrementalData. * * All properties of this object are optional, as they are only included if changes occurred. * For instance, if a transaction didn't include any changes to modelData, the modelData property of this interface won't be included on the output object. * * Any shared or cyclic references within the model data will be maintained on the data included on this output object. * @category Model * @since 2.1 */ export interface IncrementalData { /** * Object containing the modified Model#modelData. */ modelData?: ObjectData; /** * Array of node keys added. Any key included will also be included in the modifiedNodeData array. */ insertedNodeKeys?: Array; /** * Array of node data objects modified. */ modifiedNodeData?: Array; /** * Array of node keys deleted. */ removedNodeKeys?: Array; /** * Array of link keys added. Any key included will also be included in the modifiedLinkData array. */ insertedLinkKeys?: Array; /** * Array of link data objects modified. */ modifiedLinkData?: Array; /** * Array of link keys deleted. */ removedLinkKeys?: Array; } /** * Models hold the essential data of a diagram, describing the basic entities and their properties and relationships * without specifying the appearance and behavior of the Nodes and Links and Groups that represent them visually. * Models tend to hold only relatively simple data, making them easy to persist by serialization as JSON or XML formatted text. * * Models hold simple data objects, not Parts such as Nodes or Links. * Node data is normally represented in a Diagram by instances of Node, * but they could be represented by simple Parts or by Groups. * A Diagram constructs Parts for its Diagram#model's data by copying templates. * Templates are Panels of GraphObjects that get some property values from the model data, * accessible via the Panel#data property, using data Binding. * See Using Models and Data Binding for an introduction. * * This Model class only supports holding an array of node data * and interpreting properties on that data to be able to refer to them * using unique key values. * To support simple tree-structured graphs, use a TreeModel, which inherits from this class. * To support links and grouping, use a GraphLinksModel. * * Each node data object is assumed to have a unique key value. * The #nodeKeyProperty property names the property on the node data whose value * is the unique key for that node data object. * The default value for this property is "key". * You should not have a TwoWay data binding on the node key property, * because that might cause the property value to be set to a duplicate key value. * * The key values must be either strings or numbers or undefined. * If the key is undefined, or if there are duplicate key values, * the model will automatically try to assign a new unique key value. * Caution: if your keys are numbers, do not try to use string representations of those numbers as keys. * Conversely, if your keys are strings that happen to have number syntax, do not try to use those number values. * Sometimes JavaScript will automatically convert from string to number or vice-versa, but sometimes it won't. * * For example, one can define a graph consisting of just two nodes: * ```js * model.nodeDataArray = [ * { key: "Alpha" }, * { key: "Beta" } * ]; * ``` * * This model cannot detect the modification of the #nodeDataArray array * or the modification of any node data object. * If you want to add or remove node data from the #nodeDataArray, * call the #addNodeData or #removeNodeData methods. * * If you want to modify a node data object, it depends on whether the property you want to change * is a structural property that the model needs to know about, or whether it is a property * that is only used for data binding or other application-specific purposes. * * For the former case, call the appropriate method, such as * #setKeyForNodeData, #setCategoryForNodeData, * GraphLinksModel#setToKeyForLinkData, or GraphLinksModel#setGroupKeyForNodeData. * These methods have names that start with "set", "add", "insert", or "remove". * * For the latter case, when setting an application-specific property, typically for data binding, * and to support undo/redo, call #setDataProperty. * * The #copyNodeData method can be called to make a shallow copy of a node data object. * However, if some of those property values are Arrays that want not to be shared but to be copied, * you can set #copiesArrays to true. This is typically very useful when dealing * with data bound item arrays. * Furthermore if the items in those copied Arrays are in fact Objects that need to be copied, * you can also set #copiesArrayObjects to true, causing a copied Array to refer to * newly shallow-copied objects of the original array. * * Each model raises ChangedEvents that you can follow by registering a listener via #addChangedListener. * Read more at the Introduction page: Changed Events. * * Each model comes with its own UndoManager that is initially not enabled. * You will need to set UndoManager#isEnabled to true in order for the * UndoManager to record model changes and for your users to perform undo and redo. * * You can temporarily turn off the recording of changes by setting #skipsUndoManager to true. * A number of places within the system do that routinely in order to avoid recording temporary changes, * so be sure to remember the original value beforehand and restore it afterwards. * Note that in a ChangedEvent listener you may want to ignore events that happen when #skipsUndoManager is true. * * One normally saves a diagram by just saving its model. * If you can use JSON-formatted text, this is easy to do -- just call #toJson * to get the string representation of the model, and save that string. * Load the diagram by replacing the Diagram#model with one created by calling * the static function Model.fromJson: * ```js * myDiagram.model = go.Model.fromJson(loadedString); * ``` * Note that JSON and other textual data formats cannot faithfully store all JavaScript functions. * #toJson and Model.fromJson do not try to save and load functional property values. * You should arrange that all such functions, including event handlers, are established by your app. * #toJson and Model.fromJson also cannot handle circular references; any sharing of * references will be lost too. * They also skip properties that are not enumerable, those whose names start with an underscore, and those whose values are undefined. * * Note that models also do not store the templates used by diagrams, * nor any transient or temporary parts such as Adornments, nor any tools, * nor any UndoManager state, nor any event listeners. * These objects and all other properties of diagrams must be established by your app. * * You can add any number of properties to the #modelData object, which is serialized and deserialized * into JSON just like any other model data for nodes or links. * However #modelData is associated with the model as a whole and does not depend on the existence * of any node data or link data. * * It is also easy to save the changes that were recorded in the most recent transaction. * Call #toIncrementalJson to generate a JSON-format string that holds the current state of modified data * plus the keys of inserted or removed data. * That method requires as an argument a ChangedEvent that represents a transaction that completed or * an undo or a redo that just finished. * * It is also possible to use such "incremental" JSON to modify an existing model. * Call #applyIncrementalJson, giving it a string generated by #toIncrementalJson, * to modify this model by making all of the changes recorded in the JSON text. * Note how this method is a regular instance method, whereas Model.fromJson is a static function. * @unrestricted * @category Model */ export class Model { /** * You probably don't want to call this constructor, because this class * does not support links (relationships between nodes) or groups (nodes and links and subgraphs as nodes): * instead, create instances of a subclass such as GraphLinksModel or TreeModel. * @param {Array.=} nodedataarray an optional Array containing JavaScript objects to be represented by Parts. * @param {Partial=} init Optional initialization properties. */ constructor(nodedataarray?: Array, init?: Partial); /** * You probably don't want to call this constructor, because this class * does not support links (relationships between nodes) or groups (nodes and links and subgraphs as nodes): * instead, create instances of a subclass such as GraphLinksModel or TreeModel. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * Copies properties from this model to the given model, which must be of the same class. * This is called by #copy. * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {Model} copy * @since 1.6 */ protected cloneProtected(copy: this): void; /** * Creates a shallow copy of this Model and returns it. * The data are not copied: #nodeDataArray, #modelData, * GraphLinksModel#linkDataArray, GraphLinksModel#archetypeNodeData are left empty. * Nor are any Changed listeners or the UndoManager copied. * @expose * @return {Model} an empty copy of the model with the same properties, other than data * @since 1.6 */ copy(): Model; /** * Clear out all references to any model data. * This also clears out the UndoManager, so this operation is not undoable. * This method is called by Diagram#clear; it does not notify any Diagrams or other listeners. * This method does not unregister any Changed event listeners. * * Instead of calling this method, you may prefer to set #nodeDataArray to an empty JavaScript Array. * If this model is a GraphLinksModel, you would also want to set GraphLinksModel#linkDataArray to a separate empty JavaScript Array. */ clear(): void; /** * Produce an object representing the changes in the most recent Transaction. * The structure of the object follows the same format as the JSON output from #toIncrementalJson. * * Note that these incremental changes include the results of undo and redo operations. * * For GraphLinksModels, this method requires that GraphLinksModel#linkKeyProperty is not an empty string. * * Any node or link data objects contained in the "modified..." properties will be deep copies of the data in the model. * The objects will contain proper copies of certain GoJS classes, and some common built-in objects such as Dates and RegExps. * Other classes will just be copied as plain Javascript objects, so it is best to avoid using special classes in one's data. * * This method is most commonly used when GoJS must communicate with some external data source * and maintain integrity between the two while avoiding serialization/deserialization. * * ```js * myDiagram.addModelChangedListener(e => { * if (e.isTransactionFinished) { * var dataChanges = e.model.toIncrementalData(e); * ... update React state/save to database ... * } * }); * ``` * * Caution: don't call JSON.stringify on the resulting object, because that will not properly handle any instances of * JavaScript classes that are referenced by the object's properties. * Instead call #toIncrementalJson, which will produce a more compact textual serialization. * @param {ChangedEvent} e a Transaction ChangedEvent for which ChangedEvent#isTransactionFinished is true * @return {IncrementalData} returns either null if no changes occurred, or an object containing incremental model changes for the given Transaction * @see #toIncrementalJson * @since 2.1 */ toIncrementalData(e: ChangedEvent): IncrementalData; /** * Deeply copy an object or array and return the new object. * This is typically called on a #nodeDataArray or GraphLinksModel#linkDataArray or data objects within them. * * By default, this method will make deep clones of arrays and JavaScript objects and maintain any shared or cyclic references. * It will properly copy any `Date` or `RegExp` object, and will call a `copy` function on any object where one exists. * It also handles certain GoJS classes: `Point`, `Size`, `Rect`, `Margin`, `Spot`, `List`, `Set`, and `Map`. * It will not handle instances of `Diagram`, `Layer`, `GraphObject`, `Tool`, `CommandHandler`, `AnimationManager` or subclasses or related classes. * * This method may be overridden. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * Only override this method when the default behavior doesn't suit the data. * When cloning objects, we recommend skipping the `__gohashid` property, which is used internally. * @expose * @param {T} obj * @return {T} * @since 2.1 */ cloneDeep(obj: T): T; /** * Produce a JSON-format string representing the changes in the most recent Transaction. * This writes out JSON for a model, but recording only changes in the given Transaction, * with the addition of the "incremental" property to mark it as different from a complete model. * Instead of the "nodeDataArray" property (and "linkDataArray" property for GraphLinksModels), * this will have "inserted...", "modified...", and "removed..." properties that are non-empty Arrays. * * The "modifiedNodeData" Array holds JavaScript objects. * The "insertedNodeKeys" and "removedNodeKeys" Arrays hold keys (numbers or strings) of data, * not whole objects, that have been added and/or deleted. * The "modelData" property holds the Model#modelData object, if it was modified. * * Note that it is entirely plausible for the same object be in or referenced by all three Arrays, * because a single Transaction can include adding a node, modifying it, and removing it. * * The purpose of this method is to make it easier to send incremental changes to the server/database, * instead of sending the whole model. * Whereas it has always been easy to perform "batch" updates or "file saves": * ```js * myDiagram.addModelChangedListener(e => { * if (e.isTransactionFinished) { * var json = e.model.toJson(); * // save the whole model upon each transaction completion or undo/redo * ... send to server/database ... * } * }); * ``` * You can now easily send "incremental" updates: * ```js * myDiagram.addModelChangedListener(e => { * if (e.isTransactionFinished) { * var json = e.model.toIncrementalJson(e); * // record each Transaction as a JSON-format string * ... send to server/database ... * } * }); * ``` * Note that these incremental changes include the results of undo and redo operations. * Also, when you might call #applyIncrementalJson, you will need to disable your Changed listener, * so that it does not send spurious changes to your database during the process of apply incremental changes from the database. * * For GraphLinksModels, this method requires that GraphLinksModel#linkKeyProperty is not an empty string. * The incremental JSON for GraphLinksModels will include "modifiedLinkData", "insertedLinkKeys", and "removedLinkKeys" * properties that are non-empty Arrays. * * The same restrictions on data property names and data property values applies to this method as it does to #toJson. * @param {ChangedEvent} e a Transaction ChangedEvent for which ChangedEvent#isTransactionFinished is true * @param {string=} classname for the written model, defaults to the name of the class of the model * @return {string} * @since 1.6 */ toIncrementalJson(e: ChangedEvent, classname?: string): string; /** * Generate a string representation of the persistent data in this model, in JSON format, * that can be read in later with a call to Model.fromJson. * * Object properties that are not enumerable or whose names start with "_" are not written out. * * Functions are not able to be written in JSON format, so any properties that have function values * will not be saved in the JSON string. * * There must not be any circular references within the model data. * Any sharing of object references will be lost in the written JSON. * * Most object classes cannot be serialized into JSON without special knowledge and processing at both ends. * The #toJson and Model.fromJson methods automatically do such processing for numbers that are NaN * and for objects that are of class Point, Size, Rect, Margin, Spot, * Brush (but not for brush patterns), and for Geometry. * For instances of those classes, special objects are written out with a property named "class" whose value * will be one of the special cases that will be substituted by Model.fromJson: * "NaN", "Date", "go.EnumValue", "go.Point", "go.Size", "go.Rect", "go.Margin", "go.Spot", "go.Brush", "go.Geometry". * * However, we recommend that you use Binding converters (static functions named "parse" and "stringify") * to represent Points, Sizes, Rects, Margins, Spots, and Geometries as string values in your data, rather than as Objects. * This makes the JSON text smaller and simpler and easier to read. * * As a special case when serializing an object, if the property is named "points" and the * property value is a List of Points, it will write an Array of numbers. * * Note that this is a method on the Model class. * It cannot render unmodeled Parts such as the background grid or any Parts that you have added directly to a Diagram. * * Typical usage: * ```js * var modelAsText = myDiagram.model.toJson(); * // now save this text string by sending it to your database * ``` * @param {string=} classname The optional name of the model class to use in the output; * for the standard models, this is their class name prefixed with "go.". * @return {string} a String in JSON format containing all of the persistent properties of the model. */ toJson(classname?: string): string; /** * Modify this model by applying the changes given in an "incremental" model change in JSON format * generated by #toIncrementalJson. * The expected properties of the argument are described at #toIncrementalJson. * Incremental changes must be applied in the same order that the changes occurred in the original model. * * This requires the "incremental" property to be present and to be a number, as specified by #toIncrementalJson. * All of the top-level properties in the JSON, such as #nodeKeyProperty, must be the same as for this model. * Note that if the model is a GraphLinksModel, you will have to have set GraphLinksModel#linkKeyProperty * to the name of a property, the same both in the Diagram#model as well as in the data that you pass to this method. * * This conducts a transaction. * @param {string|ObjectData} s a String in JSON format containing modifications to be performed to the model, * or a JavaScript Object parsed from such a string * @since 1.6 */ applyIncrementalJson(s: string | ObjectData): void; /** * This static function parses a string in JSON format that was written by Model#toJson, * and then constructs, initializes, and returns a model with that information. * * Note that properties with values that are functions are not written out by #toJson, * so reading in such a model will require constructing such a model, initializing its functional property values, * and explicitly passing it in as the second argument. * * In order to serialize instances of some classes and enumerated values and some other cases, * Model#toJson writes out special Objects that this Model.fromJson function substitutes * with the intended values. * Those special objects will have a property named "class" whose value will be one of the special substitution cases: * "NaN", "Date", "go.EnumValue", "go.Point", "go.Size", "go.Rect", "go.Margin", "go.Spot", "go.Brush", "go.Geometry". * * As a special case when deserializing an object, if the property is named "points" and the * property value is an Array with an even number of numbers, it will substitute a List of Points. * * Typical usage: * ```js * var modelAsText = ...; // fetch the model in textual format from a database * myDiagram.model = go.Model.fromJson(modelAsText); * ``` * @param {string|ObjectData} s a String in JSON format containing all of the persistent properties of the model, or an Object already read from JSON text. * @param {Model=} model an optional model to be modified; if not supplied, it constructs and returns a new model whose name is specified by the "class" property. * @return {Model} the supplied or created model loaded with data from the given string. */ static fromJson(s: string | ObjectData, model?: Model): Model; /** * Gets or sets the name of this model. * The initial name is an empty string. * The value must not be null. */ get name(): string; set name(value: string); /** * Gets or sets the name of the format of the diagram data. * The default value is the empty string. * The value must not be null. * Use different values to prevent parts from one model to be copy/pasted or drag-and-dropped into another diagram/model. */ get dataFormat(): string; set dataFormat(value: string); /** * Gets or sets whether this model may be modified, such as adding nodes. * By default this value is false. * Setting the #nodeDataArray to something that is not a true Array of Objects * will cause this to be set to true. * * Model methods and property setters do not heed this property. * It is up to code that uses a model to check this property when it might want to * prevent changes to the model. */ get isReadOnly(): boolean; set isReadOnly(value: boolean); /** * Gets a JavaScript Object that can hold programmer-defined property values for the model as a whole, * rather than just for one node or one link. * * By default this an object with no properties. * Any properties that you add to this object will be written out by #toJson * and will be restored by Model.fromJson, if the following conditions are true: * - the property is enumerable and its name does not start with an underscore ('_') * - the property value is not undefined and is not a function * - the model knows how to convert the property value to JSON format * - property values that are Objects or Arrays form a tree structure -- no shared or cyclical references * * Most object classes cannot be serialized into JSON without special knowledge and processing at both ends. * The #toJson and Model.fromJson methods automatically do such processing for numbers that are NaN * and for objects that are of class Point, Size, Rect, Margin, Spot, * Brush (but not for brush patterns), and for Geometry. * * At the current time one cannot have a Diagram as a binding target. * Calling #setDataProperty will work to change a property value, but there are no target bindings in any Diagrams to be updated. * Because the binding mechanism is unavailable for this object, we recommend that when you want to save a model * that you explicitly set properties on this object just before calling #toJson. * When loading a model, call Model.fromJson and explicitly get the properties that you want to set on a Diagram. */ get modelData(): ObjectData; set modelData(value: ObjectData); /** * Register an event handler that is called when there is a ChangedEvent. * * This registration does not raise a ChangedEvent. * In case a Diagram's Model may be replaced, you may prefer calling Diagram#addModelChangedListener instead of this method. * * Event listeners are not written out by #toJson. * * Do not add or remove Changed listeners during the execution of a Changed listener. * @param {function(ChangedEvent)} listener a function that takes a ChangedEvent as its argument. * @see #removeChangedListener * @see Diagram#addModelChangedListener * @return {Model} this Model */ addChangedListener(listener: ((e: ChangedEvent) => void)): this; /** * Unregister an event handler listener. * * This deregistration does not raise a ChangedEvent. * In case a Diagram's Model may be replaced, you may prefer calling Diagram#removeModelChangedListener instead of this method. * @param {function(ChangedEvent)} listener a function that takes a ChangedEvent as its argument. * @see #addChangedListener * @see Diagram#removeModelChangedListener */ removeChangedListener(listener: ((e: ChangedEvent) => void)): void; /** * Call this method to notify that the model or its objects have changed. * This constructs a ChangedEvent and calls all Changed listeners. * @param {EnumValue} change specifies the general nature of the change; typically the value is ChangedEvent.Property. * @param {string|function(ObjectData,?=):?} propertyname names the property that was modified, or a function that takes an Object and returns the property value. * @param {Object} obj the object that was modified, typically a GraphObject, Diagram, or a Model. * @param {*} oldval the previous or older value. * @param {*} newval the next or newer value. * @param {*=} oldparam an optional value that helps describe the older value. * @param {*=} newparam an optional value that helps describe the newer value. */ raiseChangedEvent(change: EnumValue, propertyname: string | ((obj: ObjectData, val: any) => any), obj: ObjectData, oldval: any, newval: any, oldparam?: any, newparam?: any): void; /** * Call this method to notify about a data property having changed value. * This constructs a ChangedEvent and calls all Changed listeners. * * You should call this method only if the property value actually changed. * This method is called by #setDataProperty. * @param {Object} data the data object whose property changed value. * @param {string|function(ObjectData,?=):?} propertyname the name of the property, or a function that takes an Object and returns the property value. * @param {*} oldval the previous or old value for the property. * @param {*} newval the next or new value for the property. * @param {*=} oldparam an optional value additionally describing the old value. * @param {*=} newparam an optional value additionally describing the new value. */ raiseDataChanged(data: ObjectData, propertyname: string | ((obj: ObjectData, val: any) => any), oldval: any, newval: any, oldparam?: any, newparam?: any): void; /** * Gets or sets the UndoManager for this Model. * * The default UndoManager has its UndoManager#isEnabled property set to false. * If you want users to undo and redo, you should set that property to true once you have initialized the Diagram or its Model. * * This property setter does not raise a ChangedEvent. */ get undoManager(): UndoManager; set undoManager(value: UndoManager); /** * Gets or sets whether ChangedEvents are not recorded by the UndoManager. * The initial and normal value is false. * WARNING: while this property is true do not perform any changes that cause any previous transactions * to become impossible to undo. * * When this property is true, changing the Model or any data object does not call UndoManager#handleChanged. * Even when this property is true, * transactions (such as calls to #startTransaction) and undo/redo (such as calls to CommandHandler#undo) * are still delegated to the #undoManager. * * You should set this to true only temporarily, and you should remember its previous value before setting this to true. * When finishing the period for which you want the UndoManager to be disabled, * do not blindly set this property to false. * You should set this back to the value it had before you set it to true. * For more permanent disabling of the UndoManager, set UndoManager#isEnabled to false. * * This property is also set when setting Diagram#skipsUndoManager. * Setting this property does not raise a ChangedEvent. */ get skipsUndoManager(): boolean; set skipsUndoManager(value: boolean); /** * (undocumented) * This is called during an undo or redo to modify the model or its objects. * * This does not raise a ChangedEvent. * @expose * @param {ChangedEvent} e This describes the change that needs to be done. * @param {boolean} undo If true, this method should restore the older state, otherwise the newer state. */ changeState(e: ChangedEvent, undo: boolean): void; /** * Begin a transaction, where the changes are held by a Transaction object * in the UndoManager. * This just calls UndoManager#startTransaction. * @param {string=} tname a descriptive name for the transaction. * @return {boolean} the value returned by UndoManager#startTransaction. * @see #commit */ startTransaction(tname?: string): boolean; /** * Commit the changes of the current transaction. * This just calls UndoManager#commitTransaction. * @param {string=} tname a descriptive name for the transaction. * @return {boolean} the value returned by UndoManager#commitTransaction. */ commitTransaction(tname?: string): boolean; /** * Rollback the current transaction, undoing any recorded changes. * This just calls UndoManager#rollbackTransaction. * @return {boolean} the value returned by UndoManager#rollbackTransaction. */ rollbackTransaction(): boolean; /** * Starts a new transaction, calls the provided function, and commits the transaction. * Code is called within a try-finally loop. * If the function does not return normally, this rolls back the transaction rather than committing it. * Example usage: * ```js * model.commit(m => m.addNodeData({ counter: myCounter++ }), "Added Node"); * ``` * @param {Function} func the function to call as the transaction body * @param {(string|null)=} tname a descriptive name for the transaction, or null to temporarily set #skipsUndoManager to true; * if no string transaction name is given, an empty string is used as the transaction name * @since 1.8 */ commit(func: (m: Model) => void, tname?: string | null): void; /** * Find a Part corresponding to the given data and * call its Panel#updateTargetBindings method, in each Diagram * that uses this Model. * * Caution: setting a data property without calling #setDataProperty * and then calling this updateTargetBindings method will update GraphObjects that are bound to the property, * but such data settings will not be recorded in the UndoManager and therefore will not be undone/redone, * causing an inconsistency between the GraphObjects and the part data. * @param {Object} data The data object in this model that was modified. * @param {string=} srcpropname If not present or the empty string, * update all bindings on the target Part or item Panel * otherwise update only those bindings using this source property name. */ updateTargetBindings(data: ObjectData, srcpropname?: string): void; /** * Gets or sets the name of the data property that returns a unique id number or string for each node data object. * The value may also be a function taking two arguments, where the first argument will be a node data object. * If the second argument is not supplied, the function should return the unique key value; * if the second argument is supplied, the function should modify the node data object so that it has that new value as its unique key value. * The default value is the name 'key', meaning that it expects the data to have a property named 'key' if it has a key value. * The name must not be null or the empty string. * You must set this property before assigning the #nodeDataArray. * * If you want to set this property you must do so before using the model, and especially before you assign Diagram#model. * Note that functions cannot be serialized into JSON-formatted text, so if you are using #toJson and Model.fromJson, * and if you want this property to be a function, you will need to assign this property to your desired function * immediately after creating the model, including when it is created by Model.fromJson. * @see #getKeyForNodeData */ get nodeKeyProperty(): string | ((a: ObjectData, b?: Key) => Key); set nodeKeyProperty(value: string | ((a: ObjectData, b?: Key) => Key)); /** * Given a node data object return its unique key: a number or a string. * This returns undefined if there is no key value. * * It is possible to change the key for a node data object by calling #setKeyForNodeData. * @param {Object} nodedata a JavaScript object represented by a node, group, or non-link. * @return {string|number|undefined} * @see #nodeKeyProperty * @see #setKeyForNodeData * @see #findNodeDataForKey */ getKeyForNodeData(nodedata: ObjectData): Key; /** * Change the unique key of a given node data that is already in this model. * The new key value must be unique -- i.e. not in use by another node data object. * You can call #findNodeDataForKey to check if a proposed new key is already in use. * * This operation will check all data objects in the model and replace all references * using the old key value with the new one. * * If this is called on a node data object that is not (yet) in this model, * this unconditionally modifies the property to the new key value. * @param {Object} nodedata a JavaScript object represented by a node, group, or non-link. * @param {string|number} key * @see #nodeKeyProperty * @see #getKeyForNodeData * @since 1.1 */ setKeyForNodeData(nodedata: ObjectData, key: Key): void; /** * Gets or sets a function that returns a unique id number or string for a node data object. * This function is called by #makeNodeDataKeyUnique * when a node data object is added to the model, either as part of a new * #nodeDataArray or by a call to #addNodeData, to make sure the value of * #getKeyForNodeData is unique within the model. * * The value may be null in order to cause #makeNodeDataKeyUnique behave in the standard manner. * (The default value is null.) * You may want to supply a function here in order to make sure all of the automatically generated keys * are in a particular format. * Setting this property after setting #nodeDataArray has no real effect until there is a call * to #addNodeData. * * If you want to ensure that this function is called when copying data that already has a key, * set #copiesKey to false. * This is typically useful when copying a node from a Palette, where the key it has in the Palette's Model * happens to be unique within the target Diagram's Model. * Unless you set #copiesKey to false, the original key value will be copied and retained * if it is already unique within the target model. * * If a node data object is already in the model and you want to change its key value, * call #setKeyForNodeData with a new and unique key. */ get makeUniqueKeyFunction(): ((model: Model, data: ObjectData) => Key) | null; set makeUniqueKeyFunction(value: ((model: Model, data: ObjectData) => Key) | null); /** * Decide if a given node data object is in this model, using reference equality. * * If you do not have a reference to the particular data object that is in the #nodeDataArray, * you may need to search for it by iterating through that Array, * or by finding the desired Node or simple Part in a Diagram and getting that node's Panel#data, * or most likely by calling #findNodeDataForKey. * @param {Object} nodedata a JavaScript object represented by a node, group, or non-link. * @return {boolean} true if it is a node data object in this model; false otherwise. */ containsNodeData(nodedata: ObjectData): boolean; /** * Given a number or string, find the node data object in this model * that uses the given value as its unique key. * @param {(string|number|undefined)} key a string or a number. * @return {Object} null if the key is not present in the model, * or if the key is null or undefined or not a string or number. * @see #containsNodeData * @see #getKeyForNodeData */ findNodeDataForKey(key: Key): ObjectData | null; /** * Gets or sets the array of node data objects that correspond to Nodes, * Groups, or non-Link Parts in the Diagram. * The initial value is an empty Array. * * For each Object in the Array, #getKeyForNodeData should return a number or string * uniquely identifying the node data within the model. * If it returns undefined, this calls #makeNodeDataKeyUnique, * to make sure the node data has a unique key. * These key values may be used by other objects to refer to that particular node data object. * If more than one node data object has the same key, * there may be some confusion about which object to reference. * * If you want to use a custom data property for holding the unique key value on a node data object, * you should set #nodeKeyProperty before you set this `nodeDataArray` property. * * Adding or removing data from this Array will not notify this model or the diagram * that there are any new nodes or that any nodes have been deleted. * Instead you should call #addNodeData or #removeNodeData. */ get nodeDataArray(): Array; set nodeDataArray(value: Array); /** * This method is called when a node data object is added to the model to make sure that * #getKeyForNodeData returns a unique key value. * * The key value should be unique within the set of data managed by this model: * #nodeDataArray. * If the key is already in use, this will assign an unused number to the * #nodeKeyProperty property on the data. * * If you want to customize the way in which node data gets a unique key, * you can set the #makeUniqueKeyFunction functional property. * * If the node data object is already in the model and you want to change its key value, * call #setKeyForNodeData and give it a new unique key value. * @param {Object} nodedata a JavaScript object represented by a node, group, or non-link. */ makeNodeDataKeyUnique(nodedata: ObjectData): void; /** * When you want to add a node or group to the diagram, * call this method with a new data object. * This will add that data to the #nodeDataArray and * notify all listeners that a new node data object has been inserted into the collection. * * To remove a node from the diagram, you can remove its data object by calling #removeNodeData. * * To add or remove an object or value from an item array, call #insertArrayItem or #removeArrayItem. * @param {Object} nodedata a JavaScript object represented by a node, group, or non-link. */ addNodeData(nodedata: ObjectData): void; /** * Add to this model all of the node data held in an Array or in an Iterable of node data objects. * @param {Iterable.|Array.} coll a collection of node data objects to add to the #nodeDataArray * @since 1.3 */ addNodeDataCollection(coll: Iterable | Array): void; /** * When you want to remove a node or group from the diagram, * call this method with an existing data object. * This will remove that data from the #nodeDataArray and * notify all listeners that a node data object has been removed from the collection. * * If you do not have a reference to the particular data object that is in the #nodeDataArray, * you may need to search for it by iterating through that Array, * or by finding the desired Node or simple Part in a Diagram and getting that node's Panel#data, * or most likely by calling #findNodeDataForKey. * * Removing a node data from a model does not automatically remove * any connected link data from the model. * Removing a node data that represents a group does not automatically remove * any member node data or link data from the model. * * To add a node to the diagram, you can add its data object by calling #addNodeData. * * To add or remove an object or value from an item array, call #insertArrayItem or #removeArrayItem. * @param {Object} nodedata a JavaScript object represented by a node, group, or non-link. */ removeNodeData(nodedata: ObjectData): void; /** * Remove from this model all of the node data held in an Array or in an Iterable of node data objects. * @param {Iterable.|Array.} coll a collection of node data objects to remove from the #nodeDataArray * @since 1.3 */ removeNodeDataCollection(coll: Iterable | Array): void; /** * Take an Array of node data objects and update #nodeDataArray without replacing * the Array and without replacing any existing node data objects that are identified by key. * * For node data objects that have the same key value, this makes calls to #setDataProperty * to update the existing node data object. * For new keys, this calls #cloneDeep to copy the data and then #addNodeData to add a new node to the model. * For existing nodes that have keys that are not present in the given Array, * this calls #removeNodeData to remove the existing node from the model. * * This method is typically used when GoJS is being used within an application that is maintaining state * related to the diagram model. When state is updated, this method can be called to keep the GoJS model synchronized. * Any updates to the data should use new references since this method will use reference equality to check * if a node data object needs to be updated. * * This method does not conduct a transaction. * @param {Array.} arr * @since 2.1 */ mergeNodeDataArray(arr: Array): void; /** * (undocumented) * @param {string|number=} key */ clearUnresolvedReferences(key?: Key): void; /** * Gets or sets a function that makes a copy of a node data object. * * You may need to set this property in order to ensure that a copied Node is bound * to data that does not share certain data structures between the original node data and the copied node data. * This property value may be null in order to cause #copyNodeData to make a shallow copy of a JavaScript Object. * The default value is null. * * The first argument to the function will be a node data object (potentially a Part's Panel#data). * The second argument to the function will be this Model itself. * * It is common to implement a copying function when the node data has an Array of data * and that Array needs to be copied rather than shared. * Often the objects that are in the Array also need to be copied. */ get copyNodeDataFunction(): ((data: ObjectData, model: Model) => ObjectData) | null; set copyNodeDataFunction(value: ((data: ObjectData, model: Model) => ObjectData) | null); /** * Gets or sets whether the default behavior for #copyNodeData or GraphLinksModel#copyLinkData * makes copies of property values that are Arrays. * This only copies Arrays that are top-level property values in data objects, not for Arrays that are in nested objects. * Copying Arrays will also copy any array items that are Objects when #copiesArrayObjects is true. * * The default value is false. * It is commonplace to set #copiesArrayObjects to true when setting this property to true. * This property does not affect any behavior when the value of #copyNodeDataFunction * or GraphLinksModel#copyLinkDataFunction has been set to a function. * * Caution: if you want a copied data object to share some Arrays but not others, * you will need to provide your own copying function as #copyNodeDataFunction rather than setting * this property to true. * * Warning: there should not be any cyclical references within the model data. * @see #copiesArrayObjects * @see #copyNodeDataFunction * @since 1.5 */ get copiesArrays(): boolean; set copiesArrays(value: boolean); /** * Gets or sets whether the default behavior for #copyNodeData or GraphLinksModel#copyLinkData * when copying Arrays also copies array items that are Objects. * This only covers copying Objects that are items in Arrays that are copied when #copiesArrays is true. * Copying an Object when this property is true also recursively copies any Arrays that are property values. * It also assumes that the object's constructor can be called with no arguments. * * The default value is false. * This property does not affect any behavior when the value of #copyNodeDataFunction * or GraphLinksModel#copyLinkDataFunction has been set to a function. * This property has no effect unless #copiesArrays is true. * * Caution: if you want a copied data object to share some references but not others, * you will need to provide your own copying function as #copyNodeDataFunction rather than setting * this property and #copiesArrays to true. * * Warning: there should not be any cyclical references within the model data. * @see #copiesArrays * @see #copyNodeDataFunction * @since 1.5 */ get copiesArrayObjects(): boolean; set copiesArrayObjects(value: boolean); /** * Gets or sets whether the default behavior for #copyNodeData or GraphLinksModel#copyLinkData * when copying properties of a data object also copies the key property value. * Set this to false in order to force a unique key generation for data copied from another Diagram, such as a Palette. * * The default value is true. * This property does not affect any behavior when the value of #copyNodeDataFunction has been set to a function. * * @see #copiesArrays * @see #copyNodeDataFunction * @since 2.0 */ get copiesKey(): boolean; set copiesKey(value: boolean); /** * Make a copy of a node data object. * This uses the value of #copyNodeDataFunction to actually perform the copy, unless that property is null. * When it is null the default behavior is to just make a shallow copy of the JavaScript Object. * * However when #copiesArrays is true, this will make a copy of property values that are JavaScript Arrays. * This is useful when you do not want the Arrays to be shared between the node data objects. * Note that if you want to copy some property values that are Arrays but not other properties that are Arrays, * you cannot use #copiesArrays but must implement your own #copyNodeDataFunction. * * In addition when #copiesArrayObjects is true, if items in the Array being copied are JavaScript Objects, * those objects are copied, recursively. * This is useful when the items in copied Arrays are themselves objects that need to be copied. * Note that if you want to share references to some but not all of the objects in copied Arrays you cannot use * #copiesArrayObjects but must implement your own #copyNodeDataFunction. * * This does not modify the model -- the returned data object is not added to this model. * This assumes that the data's constructor can be called with no arguments. * * Models should not have any references to Diagrams or GraphObjects or Tools or Layouts or other objects * that form a Diagram. * * Warning: there should not be any cyclical references within the model data, unless you * either do not turn on #copiesArrays or #copiesArrayObjects or unless you have * supplied your own #copyNodeDataFunction that can handle cyclical references. * @expose * @param {Object} nodedata a JavaScript object represented by a node, group, or non-link. * @return {Object} * @see #addNodeData */ copyNodeData(nodedata: ObjectData): ObjectData | null; /** * (undocumented) * This function (if not null) is called towards the end of Diagram#copyParts * in order to support custom data copying operations that depend on references between the parts. * * The first argument to the function is a Map mapping original data objects to copied data objects. * The second argument to the function is this Model, the destination model for the copied parts. * The third argument to the function is the source Model, of the original data objects. */ get afterCopyFunction(): ((map: Map, destModel: Model, srcModel: Model) => void) | null; set afterCopyFunction(value: ((map: Map, destModel: Model, srcModel: Model) => void) | null); /** * Change the value of some property of a node data, a link data, an item data, or the Model#modelData, * given a string naming the property and the new value, * in a manner that can be undone/redone and that automatically updates any bindings. * * This gets the old value of the property; if the value is the same as the new value, no side-effects occur. * This calls #raiseDataChanged to notify about the change. * * Note that it is insufficient to modify an item Array (for example by pushing a new item onto the Array) and * then calling `setDataProperty(data, "items", data.items)` because the value of * `data.items` is still the same reference. * Instead you will want to call #insertArrayItem, #addArrayItem, or #removeArrayItem. * * If you modify the property that is the #nodeKeyProperty, this will call #setKeyForNodeData. * * If you modify the property that is the #nodeCategoryProperty or the GraphLinksModel#linkCategoryProperty, * this will call #setCategoryForNodeData or GraphLinksModel#setCategoryForLinkData. * But if the category might change, Binding sources should not be (or depend in a conversion function on) the category of the data, * because then some bindings might be evaluated before or after the category has been changed. * @expose * @param {Object} data a JavaScript object typically the value of a Panel#data and represented by a Node, Link, Group, simple Part, * or item in a Panel#itemArray; or this model's #modelData. * @param {string} propname a string that is not null or the empty string. * @param {*} val the new value for the property. * @see #set */ setDataProperty(data: ObjectData, propname: string, val: any): void; /** * A synonym for #setDataProperty * @param {Object} data a JavaScript object typically the value of a Panel#data and represented by a Node, Link, Group, simple Part, * or item in a Panel#itemArray; or this model's #modelData. * @param {string} propname a string that is not null or the empty string. * @param {*} val the new value for the property. * @see #setDataProperty * @since 1.8 */ set(data: ObjectData, propname: string, val: any): void; /** * This is similar to Object.assign, * but safely calls #setDataProperty for each property other than a key property. * This does not delete any properties on the DATA object, * although properties may be set to undefined if they are set that way on the PROPS object. * @param data a data object * @param props an Object holding various properties whose values are to be assigned to the DATA object */ assignAllDataProperties(data: ObjectData, props: ObjectData): void; /** * Add an item at the end of a data array that may be data bound by a Panel as its Panel#itemArray, * in a manner that can be undone/redone and that automatically updates any bindings. * * This also calls #raiseChangedEvent to notify all listeners about the ChangedEvent.Insert. * * If you want to add a new node or part to the diagram, call #addNodeData. * @param {Array.<*>} arr an Array that is the value of some Panel's Panel#itemArray. * @param {*} val the new value to be pushed onto the array. * @see #insertArrayItem * @since 1.1 */ addArrayItem(arr: Array, val: any): void; /** * Add an item to a data array that may be data bound by a Panel as its Panel#itemArray, * given a new data value and the index at which to insert the new value, in a manner that can be undone/redone and that automatically updates any bindings. * * This also calls #raiseChangedEvent to notify all listeners about the ChangedEvent.Insert. * * If you want to add a new node or part to the diagram, call #addNodeData. * @param {Array.<*>} arr an Array that is the value of some Panel's Panel#itemArray. * @param {number} idx the zero-based array index where the new value will be inserted; use -1 to push the new value on the end of the array. * @param {*} val the new value to be inserted into the array. * @see #removeArrayItem */ insertArrayItem(arr: Array, idx: number, val: any): void; /** * Remove an item from a data array that may be data bound by a Panel as its Panel#itemArray, * given the index at which to remove a data value, in a manner that can be undone/redone and that automatically updates any bindings. * * This also calls #raiseChangedEvent to notify all listeners about the ChangedEvent.Remove. * * If you want to remove a node from the diagram, call #removeNodeData. * * Note that there is no version of this method that takes an item value instead of an index into the array. * Because item arrays may hold any JavaScript value, including numbers and strings, there may be duplicate entries with that value in the array. * To avoid ambiguity, removing an item from an array requires an index. * @param {Array.<*>} arr an Array that is the value of some Panel's Panel#itemArray. * @param {number=} idx the zero-based array index of the data item to be removed from the array; * if not supplied it will remove the last item of the array. * @see #insertArrayItem */ removeArrayItem(arr: Array, idx?: number): void; /** * Gets or sets the name of the node data property that returns a string naming that data's category. * The value may also be a function taking two arguments, where the first argument will be a node data object. * If the second argument is not supplied, the function should return the category name; * if the second argument is supplied, the function should modify the node data object so that it has that new category name. * The default value is the string 'category', meaning that it expects the data to have a property named 'category' if it cares to name a category. * This is used by the diagram to distinguish between different kinds of nodes. * The name must not be null. * If the value is an empty string, * #getCategoryForNodeData will return an empty string for all node data objects. * * If you want to set this property you must do so before using the model, and especially before you assign Diagram#model. * Note that functions cannot be serialized into JSON-formatted text, so if you are using #toJson and Model.fromJson, * and if you want this property to be a function, you will need to assign this property to your desired function * immediately after creating the model, including when it is created by Model.fromJson. * @see #getCategoryForNodeData * @see #setCategoryForNodeData */ get nodeCategoryProperty(): string | ((a: ObjectData, b?: string) => string); set nodeCategoryProperty(value: string | ((a: ObjectData, b?: string) => string)); /** * Find the category of a given node data, a string naming the node template * or group template or part template * that the Diagram should use to represent the node data. * @param {Object} nodedata a JavaScript object represented by a node, group, or non-link. * @return {string} * @see #nodeCategoryProperty * @see #setCategoryForNodeData */ getCategoryForNodeData(nodedata: ObjectData): string; /** * Change the category of a given node data, a string naming the node template * or group template or part template * that the Diagram should use to represent the node data. * * Changing the node template for a node data will cause the existing Node, Group, or Part * to be replaced with a new instance of the same class * created by copying the new node template and applying any data-bindings. * That means that the templates in the Diagram#nodeTemplateMap or Diagram#groupTemplateMap * must be instances of the same class -- one cannot convert a Node into a Group or vice-versa * by setting the category. * * Binding sources should not be (or depend in a conversion function on) the category of the data * if you might be modifying the category, because then some bindings might be evaluated * before or after the category has been changed. * @param {Object} nodedata a JavaScript object represented by a node, group, or non-link. * @param {string} cat Must not be null. * @see #nodeCategoryProperty * @see #getCategoryForNodeData */ setCategoryForNodeData(nodedata: ObjectData, cat: string): void; } /** * A Binding describes how to automatically set a property on a GraphObject * to a value of a property of data in the model. * The target property name and the data source property name are strings. * All name matching is case-sensitive. * * Register bindings by calling GraphObject#bind with a new Binding. * Existing bindings become read-only, and no new bindings may be added, * when a template (a Part) is copied. * Bindings will be shared by all copies of the template's GraphObjects. * * For example, your node data might be like: * ```js * { key: 23, say: "hello!" } * ``` * * Your simple node template might be like: * ```js * var template = new go.Node(go.Panel.Auto); * // . . . define the rest of the Node's visual tree . . . * var txt = new go.TextBlock(); * txt.bind(new go.Binding("text", "say")); * template.add(txt); * myDiagram.nodeTemplate = template; * ``` * Using GraphObject.make it might look like: * ```js * var $ = go.GraphObject.make; * myDiagram.nodeTemplate = * $(go.Node, "Auto", * . . . * $(go.TextBlock, new go.Binding("text", "say")) * ) * ``` * * The data binding causes the TextBlock#text property of * the TextBlock to be set to the value of the data's "say" property. * If the value of the "say" property of a particular data object is undefined, * the binding is not evaluated: the target property is not set. * If there is an error with the binding, you may see a message in the console log. * For this reason you may want to explicitly set the initial value for a property * when defining the GraphObject, since that value will remain as the default value * if the Binding is not evaluated. * * Bindings are not necessarily evaluated in any particular order. * Binding sources should not be (or depend in a conversion function on) the category of the data * if you might be modifying the category (e.g. by calling Model#setCategoryForNodeData), * because then some bindings might be evaluated before or after the category has been changed. *

Conversions

* Sometimes the data value needs to be modified or converted in order * to be used as the new value of a GraphObject property. * The most common conversion functions are provided for you -- * they convert a string to a geometric class: * Point.parse, Size.parse, Rect.parse, * Margin.parse, Spot.parse, and Geometry.parse. * But you can easily define your own conversion function. * * As an example of a conversion function, let's use a function that adds some * text prefixing the data property value: * ```js * new go.Binding("text", "say", v => "I say: " + v) * ``` * Although simple conversions cover almost all binding cases, there are some infrequent uses * that are covered by "Advanced Conversions", discussed below. * Conversion functions must not have any side-effects. * Conversion functions may be called frequently, so they should be fast and avoid allocating memory. * The order in which conversion functions are called is not specified and may vary. *

OneWay and TwoWay Bindings

* By default bindings are Binding.OneWay. * OneWay bindings are evaluated when the Panel#data property is set * or when you call Panel#updateTargetBindings or Model#setDataProperty. * OneWay bindings only transfer values from the source to the target. * * TwoWay bindings are evaluated in the source-to-target direction just as OneWay * bindings are evaluated. * However when the GraphObject target property is set, the TwoWay * bindings are evaluated in the target-to-source direction. * There is no point in having a TwoWay binding on a GraphObject property that cannot be set. * For efficiency, avoid TwoWay bindings on GraphObject properties that do not change value in your app. * * You should not have a TwoWay binding with a source that is a node data object's key property, * i.e. on the data property whose name is the same as the value of Model#nodeKeyProperty. * Unintentionally changing the node key value to be the same as another node data's key value * may cause indeterminate behavior. * Furthermore, changing a node data key without changing any references to that node * using the key value will result in "dangling" references and inconsistent relationships. * You can make that change safely by calling Model#setKeyForNodeData, * but not via a data binding. * * The target-to-source update can also go through a conversion function. * The most common back-conversion functions are provided for you. * They convert a geometric class to a string: * Point.stringify, Size.stringify, Rect.stringify, * Margin.stringify, Spot.stringify, and Geometry.stringify. * * It is common to want to update some data properties based on changes to the diagram. * For example, as the user changes the Part#location by dragging a Node, * you can automatically keep the node's model data in sync using a TwoWay binding. * ```js * new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify) * ``` * The call to Binding#makeTwoWay changes the Binding#mode * to be Binding.TwoWay and specifies the Binding#backConverter * function to be the Point.stringify static function. * * Because the Binding is on the whole node (`template`), * the target object is the whole Node and the target property is "location". * The value of `data.loc` will be a string representation of the `Node.location` value. *

Binding Sources

* The target of a Binding is always a property of a GraphObject or a RowColumnDefinition. * The source of a Binding is normally a property of a data object in the model. * But it is also possible to have the source of a Binding be the shared JavaScript object that is the value of Model#modelData. * You can specify such a binding by calling Binding#ofModel, meaning "a binding of a source that is a property of the Model.modelData". * * As an example, you might want all Nodes to use the same color. * It would be possible but not natural to bind to a property on the node data object, because that property would have to be * duplicated on all of the node data objects in the model, and updating the property would mean calling Model#setDataProperty * on each node data object with the same new value. Furthermore if there happened to be no nodes at all in the model, * there would be no place to save the data. Hence using the shared Model#modelData object * would be the sensible place for that shared information. * ```js * new go.Binding("stroke", "strokeColor").ofModel() * ``` * and to set or modify that color one would just call, within a transaction: * ```js * model.setDataProperty(model.modelData, "strokeColor", "red"); * ``` * That would cause all nodes with that model data binding to be re-evaluated. * It is not commonplace to have a TwoWay Binding on "ofModel" Bindings, but that should work. * Converters also work with "ofModel" Bindings. * * And it is also possible to have the source of a Binding be another GraphObject that is in the same Part. * You can enable such a binding by calling Binding#ofObject, meaning "a binding of a source that is a property of a GraphObject". * You just have to make sure that object has a unique GraphObject#name or is the Part itself. * The source property on the GraphObject has to be settable, and the Part must have a value for Panel#data. * (If the source property setter does not notify about property value changes, the binding mechanism will not be invoked. * Similarly, if there is no Panel.data, the binding mechanism is not active.) * * As a common kind of example of data binding between two properties of GraphObjects, * consider this Binding on a Shape which changes the color of the Shape#stroke * depending on whether the Node is selected (Part#isSelected): * ```js * new go.Binding("stroke", "isSelected", s => s ? "dodgerblue" : "gray").ofObject() * ``` * Note the call to Binding#ofObject, which tells the Binding that it should use as the source * a GraphObject with a particular name. However that name argument is optional -- supplying no name * (or supplying an empty string) will cause the binding to operate with the root GraphObject. * In this case that would be the Node itself. * Now with this binding whenever the value of Part#isSelected changes, this Shape's stroke changes color. * The conversion function is what changes the boolean "isSelected" value to a brush color specifier. *

Advanced Conversions

* The binding functionality also has more advanced features for less common situations. * The source property name may be an empty string, to convert the object as a whole. * Conversion functions may take a second argument that takes the object that is bound. * For source-to-target conversions, the second argument will be the GraphObject whose property is bound. * For target-to-source (back-)conversions, the second argument will be the source data object and * the third argument will be the Model. * * Here's an example of a two-way data-binding using two custom conversion functions working with two separate data properties. * First we define the two conversion functions. * ```js * function toLocation(data, node) { * return new go.Point(data.x, data.y); * } * * function fromLocation(loc, data, model) { * model.setDataProperty(data, "x", loc.x); * model.setDataProperty(data, "y", loc.y); * } * * ``` * * Then to data-bind the default template's Part#location property * to two separate data properties, "x" and "y": * ```js * new go.Binding("location", "", toLocation).makeTwoWay(fromLocation) * ``` * * An empty string argument for the *sourceprop* parameter indicates * that the whole data object should be passed to the `toLocation` function, * rather than the value of some property of that data. * The return value is used as the new value for the Part#location property. * In almost all cases the second argument is not used. * Caution: for efficiency reasons you should try to avoid using an empty source property name. * Such bindings will be evaluated much more frequently than ones whose source is a particular property name. * * The binding works normally for the source-to-target direction. * But when the target property is modified it is the source property that is * set with the back-converted property value from the target object. * Because in this example the source property name is the empty string, * and because one cannot replace the whole source data object, * any return value from the conversion function is ignored. * Instead the conversion function has to modify the data object directly, * as this example `fromLocation` function does. * * Note that because the source property name is the empty string, the binding system will not know * which properties are modified in the call to `fromLocation`. * Hence to support undo and redo, in order to make the data changes we have to call * Model#setDataProperty so that the UndoManager can record the change, * including the previous value. *

Replacing Items in Arrays

* However, although a TwoWay Binding cannot replace the node data object in the Model#nodeDataArray, * it is possible to replace an item in an Panel#itemArray. * So if your node data were: * * ```js * { key: 1, items: ["one", "two", "three"] } * ``` * * And if your node template included something like: * ```js * $(go.Panel, "Vertical", * new go.Binding("itemArray", "items"), * { * itemTemplate: * $(go.Panel, * $(go.TextBlock, { editable: true }, * new go.Binding("text", "").makeTwoWay()) * ) * } * ) * ``` * * Then the user would be able to edit any of the TextBlocks, causing the item Array to be modified, * for example resulting in this node data: * ```js * { key: 1, items: ["one", "SOME NEW TEXT HERE", "three"] } * ``` * * @unrestricted * @category Model */ export class Binding { /** * The constructor creates a one-way binding. * @param {string=} targetprop A string naming the target property on the target object. * This should not be the empty string. * @param {string=} sourceprop A string naming the source property on the bound data object. * If this is the empty string, the whole Panel#data object is used. * If this argument is not supplied, the source property is assumed to be the same as the target property. * @param {TargetConversion=} conv A side-effect-free function converting the data property value to the value to set the target property. * If the function is null or not supplied, no conversion takes place. * @param {BackConversion=} backconv An optional conversion function to convert property values back to data values. * Specifying this function **or specifying null** modifies this binding to set its #mode to be Binding.TwoWay. * If you do not want a two-way binding, leave this argument unspecified (`undefined`). */ constructor(targetprop?: string, sourceprop?: string, conv?: TargetConversion, backconv?: BackConversion); /** * Create a copy of this Binding, with the same property values. * @expose * @return {Binding} */ copy(): Binding; /** * This value for Binding#mode uses data source values and sets GraphObject properties. * Bindings are evaluated when Panel#updateTargetBindings is called. * @constant */ static OneWay: EnumValue; /** * This value for Binding#mode uses data source values and GraphObject properties and keeps them in sync. * When Panel#updateTargetBindings is called, the GraphObject properties are set. * When GraphObject properties are modified, the Panel#data properties are set. * @constant */ static TwoWay: EnumValue; /** * This static function can be used to create a function that parses * a string into an enumerated value, given the class that the enumeration values * are defined on and a default value if the string cannot be parsed successfully. * * The normal usage is to pass the result of this function as the conversion function of a Binding. * ```js * linktemplate.bind(new go.Binding('routing', 'dataPropName', go.Binding.parseEnum(go.Link, go.Link.Normal))); * ``` * This binding will try to parse the string that is the value of the bound data's "dataPropName" property. * If it is a legitimate enumerated value defined on the Link class, the conversion * function will return that value. * If the bound data's "dataPropName" property is not present or has an unrecognized value, * the Link#routing property gets the default value, Link.Normal. * @param {function()} ctor the class constructor that defines the enumerated values that are being parsed. * @param {EnumValue} defval the default enumerated value to return if it fails to parse the given string. * @return {function(string):EnumValue} a function that takes a string and returns an enumerated value. */ static parseEnum(ctor: any, defval: EnumValue): ((name: string) => EnumValue); /** * This static function can be used to convert an object to a string, * looking for commonly defined data properties, such as "text", "name", "key", or "id". * If none are found, this just calls toString() on it. * @param {*=} val * @return {string} */ static toString(val?: any): string; /** * Gets or sets the name of the property to be set on the target GraphObject. * The default value is the empty string; you should set this to be the name of a property. */ get targetProperty(): string; set targetProperty(value: string); /** * Gets or sets the name of the GraphObject that should act as a source object * whose property should be gotten by this data binding. * The default value is null, which uses the bound Panel#data as the source. * If the value is a string, it should be the name of a GraphObject in the * visual tree of the Panel that is bound to the data. * Use the empty string to refer to the root panel, which is typically the whole Node or Link, * but will be a Panel if used in a Panel#itemTemplate. * The name must not contain a period. * * Binding only works if the source property is settable, not on computed or read-only properties, * and if it supports notification. * The documentation for the GraphObject (or subclass of GraphObject) property will indicate if the property is settable * and if it does not notify. */ get sourceName(): string | null; set sourceName(value: string | null); /** * Gets or sets whether the source data is Model#modelData rather than a node data or link data object in the model. * The default value is false -- the source data object will not be the shared Model.modelData object. * @see #ofModel * @since 1.7 */ get isToModel(): boolean; set isToModel(value: boolean); /** * Gets or sets the name of the property to get from the bound data object, * the value of Panel#data. * The default value is the empty string, which results in setting the target * property to the whole data object, rather than to a property value of the data object. * If #sourceName is not null, then this property names the settable * property on the GraphObject or RowColumnDefinition * that acts as the source. */ get sourceProperty(): string; set sourceProperty(value: string); /** * Gets or sets a converter function to apply to the data property value * in order to produce the value to set to the target property. * This conversion function is used in both OneWay and TwoWay bindings, * when transferring a value from the source to the target. * The default value is null -- no conversion takes place. * Otherwise the value should be a function that takes one or two arguments * and returns the desired value. * However, the return value is ignored when the #targetProperty * is the empty string. * * Conversion functions must not have any side-effects other than setting * the target property. In particular you should not try to modify the * structure of the visual tree in the target GraphObject's Part's visual tree. * * The function is passed the value from the source * (the first argument) and the target GraphObject (the second argument). * If the #targetProperty is a property name, that property is set to * the function's return value. * If the #targetProperty is the empty string, the function should * set a property on the second argument, which will be the target GraphObject. */ get converter(): TargetConversion; set converter(value: TargetConversion); /** * Gets or sets a converter function to apply to the GraphObject property value * in order to produce the value to set to a data property. * This conversion function is only used in a TwoWay binding, * when transferring a value from the target to the source. * The default value is null -- no conversion takes place. * Otherwise the value should be a function that takes one or two arguments * and returns the desired value. * However, the return value is ignored when the #sourceProperty * is the empty string. * * Conversion functions must not have any side-effects other than setting * the source property. * * The function is passed the value from the target * (the first argument), the source Panel#data object (the second argument), * and the Model (the third argument). * If the #sourceProperty is a property name, that property is set to * the function's return value. * If the #sourceProperty is the empty string, the function should * modify the second argument, which will be the source data object. */ get backConverter(): BackConversion; set backConverter(value: BackConversion); /** * Gets or sets the directions and frequency in which the binding may be evaluated. * The default value is Binding.OneWay. * Binding.TwoWay is the other choice. * * Use OneWay bindings to initialize GraphObject properties based on model data, * or to modify GraphObject properties when the model data changes with a call to Model#setDataProperty. * Use TwoWay bindings to keep model data in sync with changes to GraphObject properties. * For efficiency, avoid TwoWay bindings on GraphObject properties that do not change value in your app. * * You should not have a TwoWay binding on a node data object's key property. */ get mode(): EnumValue; set mode(value: EnumValue); /** * Modify this Binding to set its #mode to be Binding.TwoWay, and * provide an optional conversion function to convert GraphObject property * values back to data values, as the value of #backConverter. * * Use TwoWay bindings to keep model data in sync with changes to GraphObject properties. * For efficiency, avoid TwoWay bindings on GraphObject properties that do not change value in your app. * It is typical only to use TwoWay bindings on properties that are modified by tools or commands. * Examples include Part#location by DraggingTool and * TextBlock#text by TextEditingTool (only if TextBlock#editable is true). * * You should not have a TwoWay binding on a node data object's key property. * @param {BackConversion=} backconv * @return {Binding} this two-way Binding. */ makeTwoWay(backconv?: BackConversion): Binding; /** * Modify this Binding to set its #sourceName property so as to identify * a GraphObject in the visual tree of the bound Panel as the data source, * instead of the Panel#data as the data source. * * This permits data binding on GraphObject properties, such as Part#isSelected. * Remember that you can reliably data bind only on settable properties, not on read-only or computed properties. * @param {string=} srcname the GraphObject#name of an element in the visual tree of the bound Panel; * use an empty string to refer to the root panel of that visual tree, whose Panel#data is the bound data. * @return {Binding} this Binding to another GraphObject. * @see #sourceName * @see #ofModel */ ofObject(srcname?: string): Binding; /** * Modify this Binding so that the source is the Model#modelData object, * not a regular node data object or another GraphObject in the Part. * @return {Binding} this Binding to the Model#modelData object. * @see #isToModel * @see #ofObject * @since 1.7 */ ofModel(): Binding; } /** * GraphLinksModels support links between nodes and grouping nodes and links into subgraphs. * GraphLinksModels hold node data and link data in separate arrays. * Node data is normally represented in a Diagram by instances of Node, * but they could be represented by simple Parts or by Groups. * Link data should be represented by instances of Link. * * Each link data object is assumed to have two values, one referring to the node that the * link is coming from and one that the link is going to. * The #linkFromKeyProperty property names the property on the link data whose value * is the key of the "from" node. * The #linkToKeyProperty property names the property on the link data whose value * is the key of the "to" node. * The default values for these properties are "from" and "to" respectively. * * For example, one can define a graph consisting of two nodes with one link connecting them: * ```js * model.nodeDataArray = [ * { key: "Alpha" }, * { key: "Beta" } * ]; * model.linkDataArray = [ * { from: "Alpha", to: "Beta" } * ]; * ``` * * If you want to have subgraphs in your diagram, where a group node contains some number of nodes and links, * you need to declare that some node data actually represent groups, * and you need to provide a reference from a member node data to its containing group node data. * The #nodeIsGroupProperty property names the property on a node data that is true * if that node data represents a group. * The #nodeGroupKeyProperty property names the property on a node data whose value * is the key of the containing group's node data. * The default values for these properties are "isGroup" and "group" respectively. * * For example, one can define a graph consisting of one group containing a subgraph of * two nodes connected by a link, with a second link from that group to a third node * that is not a member of that group: * ```js * model.nodeDataArray = [ * { key: "Group1", isGroup: true}, * { key: "Alpha", group: "Group1" }, * { key: "Beta", group: "Group1" }, * { key: "Gamma" } * ]; * model.linkDataArray = [ * { from: "Alpha", to: "Beta" }, * { from: "Group1", to: "Gamma" } * ]; * ``` * * GraphLinksModels also support distinguishing the "port" element of a node to which * a link can connect, at either end of the link. * This identification is a string that names the "port" element in the node. * However, you need to set the #linkFromPortIdProperty and/or * #linkToPortIdProperty properties before the model is able to * get the "port id" information from the link data. * * For example, one can define a graph consisting of a "subtraction" node and two inputs and one output. * The "subtraction" node has two distinct inputs called "subtrahend" and "minuend"; * the output is called "difference". * ```js * model.linkFromPortIdProperty = "fromPort"; // necessary to remember portIds * model.linkToPortIdProperty = "toPort"; * model.nodeDataArray = [ * { key: 1, constant: 5 }, // a constant input node * { key: 2, constant: 2 }, // another constant node * { key: 3, operation: "subtract" }, * { key: 4, value: 3 } // the output node * ]; * model.linkDataArray = [ * { from: 1, to: 3, toPort: "subtrahend" }, * { from: 2, to: 3, toPort: "minuend" }, * { from: 3, to: 4, fromPort: "difference" } * ]; * ``` * In this case links connected to node 3 (which is the subtraction operation) * are distinguished by port id. * The connections to the other nodes do not have any port identification, * presumably because there is only one port on those nodes, representing the node value. * * Note that there is no requirement that the link data objects have any kind of unique identifier, unlike for node data. * There is no expectation that there be references to link data in the model, so there is no need for such an identifier. * When there are multiple links connecting two ports, the only way to distinguish the links in the model * is by reference to the particular link data object. * This is why there are two methods on the Diagram class for Nodes, Diagram#findNodeForKey and Diagram#findNodeForData, * but there is only the one method for Links, Diagram#findLinkForData. * * However you may wish to have the model maintain string or number identifiers on the link data just as all models do for node data. * To get that behavior, so that you can call #findLinkDataForKey, you need to set #linkKeyProperty to be a non-empty string. * Just as with the assignment of node keys, you can customize the assignment of link keys by setting * #makeUniqueLinkKeyFunction to a function that returns a unique identifier. * * This model does not support the modification of whether a node data object is a group. * * This model cannot detect the modification of the #linkDataArray array * or the modification of any link data object. * If you want to add or remove link data from the #linkDataArray, * call the #addLinkData or #removeLinkData methods. * If you want to modify the node a link connects to, call the * #setFromKeyForLinkData and/or #setToKeyForLinkData methods. * If you want to change the membership of a node data in a group, * call the #setGroupKeyForNodeData method. * @extends Model * @unrestricted * @category Model */ export class GraphLinksModel extends Model { /** * This constructs an empty GraphLinksModel unless one provides arguments as the initial data array values * for the Model#nodeDataArray and GraphLinksModel#linkDataArray properties. * @param {Array.=} nodedataarray an optional Array containing JavaScript objects to be represented by Nodes. * @param {Array.=} linkdataarray an optional Array containing JavaScript objects to be represented by Links. */ /** * This constructs an empty GraphLinksModel unless one provides arguments as the initial data array values * for the Model#nodeDataArray and GraphLinksModel#linkDataArray properties. * @param {Array.=} nodedataarray an optional Array containing JavaScript objects to be represented by Nodes. * @param {Array.=} linkdataarray an optional Array containing JavaScript objects to be represented by Links. * @param {Partial=} init optional initialization properties. */ constructor(nodedataarray?: Array, linkdataarray?: Array, init?: Partial); /** * This constructs an empty GraphLinksModel unless one provides arguments as the initial data array values * for the Model#nodeDataArray and GraphLinksModel#linkDataArray properties. * @param {Partial=} init optional initialization properties. */ constructor(init?: Partial); /** * Gets or sets a data object that will be copied and added to the model as a new node data each time there * is a link reference (either the "to" or the "from" of a link data) to a node key that does not yet exist in the model. * * The default value is null -- node data is not automatically copied and added to the model * when there is an unresolved reference in a link data. * When adding or modifying a link data if there is a "from" or "to" key value for which Model#findNodeDataForKey returns null, * it will call Model#copyNodeData on this property value and Model#addNodeData on the result. * @since 1.1 */ get archetypeNodeData(): ObjectData | null; set archetypeNodeData(value: ObjectData | null); /** * Gets or sets the name of the data property that returns * the key of the node data that the link data is coming from. * The value may also be a function taking two arguments, where the first argument will be a link data object. * If the second argument is not supplied, the function should return the key of the link's source node; * if the second argument is supplied, the function should modify the link data object so that it has that new key * (which may be undefined to refer to no node) as the identifier to the "from" node. * The default value is the name 'from', meaning that it expects the data to have a property named 'from' to refer to the link's source node. * The name must not be null. * If the value is an empty string, * #getFromKeyForLinkData will return undefined for all link data objects. * * If you want to set this property you must do so before using the model, and especially before you assign Diagram#model. * Note that functions cannot be serialized into JSON-formatted text, so if you are using #toJson and Model.fromJson, * and if you want this property to be a function, you will need to assign this property to your desired function * immediately after creating the model, including when it is created by Model.fromJson. * @see #getFromKeyForLinkData * @see #setFromKeyForLinkData */ get linkFromKeyProperty(): string | ((a: ObjectData, b?: Key) => Key); set linkFromKeyProperty(value: string | ((a: ObjectData, b?: Key) => Key)); /** * From a link data retrieve a value uniquely identifying the node data * from which this link is connected. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @return {string|number|undefined} This may return undefined if * the link is not coming from any node. * @see #linkFromKeyProperty * @see #setFromKeyForLinkData */ getFromKeyForLinkData(linkdata: ObjectData): Key; /** * Change the node key that the given link data references as the * source of the link. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @param {string|number|undefined} key This may be undefined if * the link should no longer come from any node. * @see #linkFromKeyProperty * @see #getFromKeyForLinkData */ setFromKeyForLinkData(linkdata: ObjectData, key: Key): void; /** * Gets or sets the name of the data property that returns * the key of the node data that the link data is going to, * The value may also be a function taking two arguments, where the first argument will be a link data object. * If the second argument is not supplied, the function should return the key of the link's destination node; * if the second argument is supplied, the function should modify the link data object so that it has that new key * (which may be undefined to refer to no node) as the identifier to the "to" node. * The default value is the name 'to', meaning that it expects the data to have a property named 'to' to refer to the link's destination node. * The name must not be null. * If the value is an empty string, * #getToKeyForLinkData will return undefined for all link data objects. * * If you want to set this property you must do so before using the model, and especially before you assign Diagram#model. * Note that functions cannot be serialized into JSON-formatted text, so if you are using #toJson and Model.fromJson, * and if you want this property to be a function, you will need to assign this property to your desired function * immediately after creating the model, including when it is created by Model.fromJson. * @see #getToKeyForLinkData * @see #setToKeyForLinkData */ get linkToKeyProperty(): string | ((a: ObjectData, b?: Key) => Key); set linkToKeyProperty(value: string | ((a: ObjectData, b?: Key) => Key)); /** * From a link data retrieve a value uniquely identifying the node data * to which this link is connected. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @return {string|number|undefined} This may return undefined if * the link is not going to any node. * @see #linkToKeyProperty * @see #setToKeyForLinkData */ getToKeyForLinkData(linkdata: ObjectData): Key; /** * Change the node key that the given link data references as the * destination of the link. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @param {string|number|undefined} key This may be undefined if * the link should no longer go to any node. * @see #linkToKeyProperty * @see #getToKeyForLinkData */ setToKeyForLinkData(linkdata: ObjectData, key: Key): void; /** * Gets or sets the name of the data property that returns * the optional parameter naming a "port" element on the node that the link data is connected from. * The value may also be a function taking two arguments, where the first argument will be a link data object. * If the second argument is not supplied, the function should return the string identifier of the link's source port; * if the second argument is supplied, the function should modify the link data object so that it has that string as the identifier to the "from" port. * The default value is the empty string indicating that one cannot distinguish * different logical connection points for any links. * The name must not be null nor the value of #linkFromKeyProperty or #linkToKeyProperty. * If the value is an empty string, * #getFromPortIdForLinkData will return an empty string for all link data objects. * * If you want to set this property you must do so before using the model, and especially before you assign Diagram#model. * Note that functions cannot be serialized into JSON-formatted text, so if you are using #toJson and Model.fromJson, * and if you want this property to be a function, you will need to assign this property to your desired function * immediately after creating the model, including when it is created by Model.fromJson. * @see #getFromPortIdForLinkData * @see #setFromPortIdForLinkData */ get linkFromPortIdProperty(): string | ((a: ObjectData, b?: string) => string); set linkFromPortIdProperty(value: string | ((a: ObjectData, b?: string) => string)); /** * From a link data retrieve a value identifying the port object of the node * from which this link is connected. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @return {string} This may return the empty string if * there is no particular port parameter information. * @see #linkFromPortIdProperty * @see #setFromPortIdForLinkData */ getFromPortIdForLinkData(linkdata: ObjectData): string; /** * Change the information that the given link data uses to identify the * particular "port" that the link is coming from. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @param {string} portname This may be the empty string if * the link should no longer be associated with any particular "port". * @see #linkFromPortIdProperty * @see #getFromPortIdForLinkData */ setFromPortIdForLinkData(linkdata: ObjectData, portname: string): void; /** * Gets or sets the name of the data property that returns * the optional parameter naming a "port" element on the node that the link data is connected to. * The value may also be a function taking two arguments, where the first argument will be a link data object. * If the second argument is not supplied, the function should return the string identifier of the link's destination port; * if the second argument is supplied, the function should modify the link data object so that it has that string as the identifier to the "to" port. * The default value is the empty string indicating that one cannot distinguish * different logical connection points for any links. * The name must not be null nor the value of #linkFromKeyProperty or #linkToKeyProperty. * If the value is an empty string, * #getToPortIdForLinkData will return an empty string for all link data objects. * * If you want to set this property you must do so before using the model, and especially before you assign Diagram#model. * Note that functions cannot be serialized into JSON-formatted text, so if you are using #toJson and Model.fromJson, * and if you want this property to be a function, you will need to assign this property to your desired function * immediately after creating the model, including when it is created by Model.fromJson. * @see #getToPortIdForLinkData * @see #setToPortIdForLinkData */ get linkToPortIdProperty(): string | ((a: ObjectData, b?: string) => string); set linkToPortIdProperty(value: string | ((a: ObjectData, b?: string) => string)); /** * From a link data retrieve a value identifying the port object of the node * to which this link is connected. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @return {string} This may return the empty string if * there is no particular port parameter information. * @see #linkToPortIdProperty * @see #setToPortIdForLinkData */ getToPortIdForLinkData(linkdata: ObjectData): string; /** * Change the information that the given link data uses to identify the * particular "port" that the link is going to. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @param {string} portname This may be the empty string if * the link should no longer be associated with any particular "port". * @see #linkToPortIdProperty * @see #getToPortIdForLinkData */ setToPortIdForLinkData(linkdata: ObjectData, portname: string): void; /** * Gets or sets the name of the data property that returns * an array of keys of node data that are labels on that link data. * The value may also be a function taking two arguments, where the first argument will be a link data object. * If the second argument is not supplied, the function should return the array of label node keys for the link; * if the second argument is supplied, the function should modify the link data object so that it holds that Array of node keys as references to label nodes. * The default value is the empty string: '', meaning that the model does not support links owning label nodes. * * The name must not be null. * If the value is an empty string, * #getLabelKeysForLinkData will return an empty array for all link data objects. * You will need to set this property in order to support nodes as link labels. * * If you want to set this property you must do so before using the model, and especially before you assign Diagram#model. * Note that functions cannot be serialized into JSON-formatted text, so if you are using #toJson and Model.fromJson, * and if you want this property to be a function, you will need to assign this property to your desired function * immediately after creating the model, including when it is created by Model.fromJson. * @see #getLabelKeysForLinkData * @see #setLabelKeysForLinkData */ get linkLabelKeysProperty(): string | ((a: ObjectData, b?: Array) => Array); set linkLabelKeysProperty(value: string | ((a: ObjectData, b?: Array) => Array)); /** * Gets an Array of node key values that identify node data acting as labels on the given link data. * * This method only works if #linkLabelKeysProperty has been set to something other than an empty string. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @return {Array.<(string|number)>} an Array of node keys; an empty Array if the property was not present. * @see #linkLabelKeysProperty * @see #setLabelKeysForLinkData * @see #addLabelKeyForLinkData * @see #removeLabelKeyForLinkData */ getLabelKeysForLinkData(linkdata: ObjectData): Array; /** * Replaces an Array of node key values that identify node data acting as labels on the given link data. * * This method only works if #linkLabelKeysProperty has been set to something other than an empty string. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @param {Array.<(string|number)>} arr an Array of node keys; an empty Array if the property was not present. * @see #linkLabelKeysProperty * @see #getLabelKeysForLinkData * @see #addLabelKeyForLinkData * @see #removeLabelKeyForLinkData */ setLabelKeysForLinkData(linkdata: ObjectData, arr: Array): void; /** * Adds a node key value that identifies a node data acting as a new label node on the given link data. * * This method only works if #linkLabelKeysProperty has been set to something other than an empty string. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @param {string|number} key a number or string that is the key of the new label node. * @see #removeLabelKeyForLinkData * @see #setLabelKeysForLinkData */ addLabelKeyForLinkData(linkdata: ObjectData, key: Key): void; /** * Removes a node key value that identifies a node data acting as a former label node on the given link data. * * Removing a reference to a node data from the collection of link label keys * does not automatically remove any node data from the model. * * This method only works if #linkLabelKeysProperty has been set to something other than an empty string. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @param {string|number} key a number or string that is the key of the label node being removed from the link. * @see #addLabelKeyForLinkData * @see #setLabelKeysForLinkData */ removeLabelKeyForLinkData(linkdata: ObjectData, key: Key): void; /** * Gets or sets the array of link data objects that correspond to Links in the Diagram. * The initial value is an empty Array. */ get linkDataArray(): Array; set linkDataArray(value: Array); /** * Gets or sets the name of the data property that returns a unique id number or string for each link data object. * The value may also be a function taking two arguments, where the first argument will be a link data object. * If the second argument is not supplied, the function should return the unique string or number key for that link data object; * if the second argument is supplied, the function should modify the link data object so that it has that string or number as the unique key for that link. * The default value is the empty string, which means the model will not maintain a key property value on link data objects. * The name must not be null. * * When this property has a value of an empty string (the default value), * #getKeyForLinkData will return undefined, and #findLinkDataForKey will always return null. * * If you want to set this property you must do so before using the model, and especially before you assign Diagram#model. * Note that functions cannot be serialized into JSON-formatted text, so if you are using #toJson and Model.fromJson, * and if you want this property to be a function, you will need to assign this property to your desired function * immediately after creating the model, including when it is created by Model.fromJson. * @see #getKeyForLinkData * @since 1.6 */ get linkKeyProperty(): string | ((a: ObjectData, b?: Key) => Key); set linkKeyProperty(value: string | ((a: ObjectData, b?: Key) => Key)); /** * Given a link data object return its unique key: a number or a string. * This returns undefined if there is no key value. * Unless #linkKeyProperty is set to a non-empty string, this model * will not automatically assign unique key values for link data objects. * * It is possible to change the key for a link data object by calling #setKeyForLinkData. * @param {ObjectData} linkdata a JavaScript object represented by a link * @return {string|number|undefined} * @see #linkKeyProperty * @see #setKeyForLinkData * @see #findLinkDataForKey * @since 1.6 */ getKeyForLinkData(linkdata: ObjectData): Key; /** * Change the unique key of a given link data that is already in this model. * The new key value must be unique -- i.e. not in use by another link data object. * You can call #findLinkDataForKey to check if a proposed new key is already in use. * * If this is called when #linkKeyProperty is the empty string (i.e. its default value), * this method has no effect. * If this is called on a link data object that is not (yet) in this model, * this unconditionally modifies the property to the new key value. * @param {ObjectData} linkdata a JavaScript object represented by a link * @param {string|number} key * @see #linkKeyProperty * @see #getKeyForLinkData * @since 1.6 */ setKeyForLinkData(linkdata: ObjectData, key: Key): void; /** * Gets or sets a function that returns a unique id number or string for a link data object. * This function is called by #makeLinkDataKeyUnique * when a link data object is added to the model, either as part of a new * #linkDataArray or by a call to #addLinkData, to make sure the value of * #getKeyForLinkData is unique within the model. * However it will not be called when #linkKeyProperty is the default value, an empty string. * * The value may be null in order to cause #makeLinkDataKeyUnique behave in the standard manner. * (The default value is null.) * You may want to supply a function here in order to make sure all of the automatically generated keys * are in a particular format. * Setting this property after setting #linkDataArray has no real effect until there is a call * to #addLinkData. * * If a link data object is already in the model and you want to change its key value, * call #setKeyForLinkData with a new and unique key. * @since 1.6 */ get makeUniqueLinkKeyFunction(): ((a: GraphLinksModel, b: ObjectData) => Key) | null; set makeUniqueLinkKeyFunction(value: ((a: GraphLinksModel, b: ObjectData) => Key) | null); /** * Given a number or string, find the link data object in this model * that uses the given value as its unique key. * * Unless #linkKeyProperty is set to a non-empty string, this model * will not automatically assign unique key values for link data objects, * and thus this method will always return null. * @param {(string|number|undefined)} key a string or a number. * @return {ObjectData} null if the key is not present in the model, * or if the key is null or undefined or not a string or number. * @see #containsLinkData * @see #getKeyForLinkData * @since 1.6 */ findLinkDataForKey(key: Key): ObjectData | null; /** * This method is called when a link data object is added to the model to make sure that * #getKeyForLinkData returns a unique key value. * * The key value should be unique within the set of data managed by this model: * #linkDataArray. * If the key is already in use, this will assign an unused number to the * #linkKeyProperty property on the data. * * If you want to customize the way in which link data gets a unique key, * you can set the #makeUniqueKeyFunction functional property. * * If the link data object is already in the model and you want to change its key value, * call #setKeyForLinkData and give it a new unique key value. * @param {ObjectData} linkdata a JavaScript object represented by a link * @since 1.6 */ makeLinkDataKeyUnique(linkdata: ObjectData): void; /** * Decide if a given link data object is in this model, using reference equality. * * If you do not have a reference to the particular data object that is in the #linkDataArray, * you may need to search for it by iterating through that Array, or (more likely), * by finding the desired Link in a Diagram and getting that link's Panel#data. * * Note that because link data are not assumed to be have a unique key property * they cannot be found using an index that this model would maintain. * However you may choose to provide such a property on the link data objects * and maintain your own index. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @return {boolean} * @see #addLinkData * @see #removeLinkData */ containsLinkData(linkdata: ObjectData): boolean; /** * When you want to add a link to the diagram, call this method with a new data object. * This will add that data to the #linkDataArray and * notify all listeners that a new link data object has been inserted into the collection. * * Presumably the link data object will already have its "from" and "to" node key references set, * but it is also possible to set them after the link data is in the model * by calling #setFromKeyForLinkData and #setToKeyForLinkData. * * This operation does nothing if the link data is already part of this model's #linkDataArray. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @see #removeLinkData */ addLinkData(linkdata: ObjectData): void; /** * Add to this model all of the link data held in an Array or in an Iterable of link data objects. * @param {Iterable.|Array.} coll a collection of link data objects to add to the #linkDataArray * @since 1.3 */ addLinkDataCollection(coll: Iterable | Array): void; /** * When you want to remove a link from the diagram, call this method with an existing link data object. * This will remove that data object from the #linkDataArray and * notify all listeners that a link data object has been removed from the collection. * * If you do not have a reference to the particular data object that is in the #linkDataArray, * you may need to search for it by iterating through that Array, or (more likely), * by finding the desired Link in a Diagram and getting that link's Panel#data. * * Removing a link data from a model does not automatically remove * any associated label node data from the model. * * This operation does nothing if the link data is not present in the #linkDataArray. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @see #addLinkData */ removeLinkData(linkdata: ObjectData): void; /** * Remove from this model all of the link data held in an Array or in an Iterable of link data objects. * @param {Iterable.|Array.} coll a collection of link data objects to remove from the #linkDataArray * @since 1.3 */ removeLinkDataCollection(coll: Iterable | Array): void; /** * Take an Array of link data objects and update #linkDataArray without replacing * the Array and without replacing any existing link data objects that are identified by key. * This depends on #linkKeyProperty being a non-empty string. * * For link data objects that have the same key value, this makes calls to #setDataProperty * to update the existing link data object. * For new keys, this calls #cloneDeep to copy the data and then #addLinkData to add a new link to the model. * For existing links that have keys that are not present in the given Array, * this calls #removeLinkData to remove the existing link from the model. * * This method is typically used when GoJS is being used within an application that is maintaining state * related to the diagram model. When state is updated, this method can be called to keep the GoJS model synchronized. * Any updates to the data should use new references since this method will use reference equality to check * if a link data object needs to be updated. * * This method does not conduct a transaction. * @param {Array.} arr * @since 2.1 */ mergeLinkDataArray(arr: Array): void; /** * Gets or sets a function that makes a copy of a link data object. * * You may need to set this property in order to ensure that a copied Link is bound * to data that does not share certain data structures between the original link data and the copied link data. * This property value may be null in order to cause #copyLinkData to make a shallow copy of a JavaScript Object. * The default value is null. */ get copyLinkDataFunction(): ((a: ObjectData, b: GraphLinksModel) => ObjectData) | null; set copyLinkDataFunction(value: ((a: ObjectData, b: GraphLinksModel) => ObjectData) | null); /** * Make a copy of a link data object. * This uses the value of #copyLinkDataFunction to actually perform the copy, * unless it is null, in which case this method just makes a shallow copy of the JavaScript Object. * * This does not modify the model -- the returned data object is not added to this model. * This assumes that the data's constructor can be called with no arguments. * This also makes sure there is no reference to either the "from" or the "to" node of the original data. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @return {ObjectData} * @see #addLinkData */ copyLinkData(linkdata: ObjectData): ObjectData; /** * Gets or sets the name of the boolean property on node data that indicates * whether the data should be represented as a group of nodes and links or as a simple node. * The value may also be a function taking two arguments, where the first argument will be a node data object. * If the second argument is not supplied, the function should return true if the node data object should be represented by a Group and false otherwise. * At the current time the function will not be called to change whether the node is a group or not. * The default value is the name 'isGroup', meaning that it expects the data to have a property named 'isGroup' on those node data objects that should be represented by Groups. * * The value must not be null. * If the value is an empty string, * #isGroupForNodeData will return false for all node data objects. * * If you want to set this property you must do so before using the model, and especially before you assign Diagram#model. * Note that functions cannot be serialized into JSON-formatted text, so if you are using #toJson and Model.fromJson, * and if you want this property to be a function, you will need to assign this property to your desired function * immediately after creating the model, including when it is created by Model.fromJson. */ get nodeIsGroupProperty(): string | ((a: ObjectData, b?: boolean) => boolean); set nodeIsGroupProperty(value: string | ((a: ObjectData, b?: boolean) => boolean)); /** * See if the given node data should be represented as a group or as a simple node. * * This value must not change as long as the node data is part of the model. * At the current time there is no `setIsGroupForNodeData` method. * @param {ObjectData} nodedata a JavaScript object represented by a node, group, or non-link. * @return {boolean} * @see #nodeIsGroupProperty */ isGroupForNodeData(nodedata: ObjectData): boolean; /** * Gets or sets the name of the property on node data that specifies * the string or number key of the group data that "owns" that node data. * The value may also be a function taking two arguments, where the first argument will be a node data object. * If the second argument is not supplied, the function should return the string or number key for the group data object of which the given data object is a member; * if the second argument is supplied, the function should modify the node data object so that it has that new key * (which may be undefined to refer to no node) as the containing group key for that node. * The default value is the name 'group', meaning that it expects the data to have a property named 'group' to refer to any containing group. * * The value must not be null. * If the value is an empty string, * #getGroupKeyForNodeData will return undefined for all node data objects. * * If you want to set this property you must do so before using the model, and especially before you assign Diagram#model. * Note that functions cannot be serialized into JSON-formatted text, so if you are using #toJson and Model.fromJson, * and if you want this property to be a function, you will need to assign this property to your desired function * immediately after creating the model, including when it is created by Model.fromJson. * @see #getGroupKeyForNodeData * @see #setGroupKeyForNodeData */ get nodeGroupKeyProperty(): string | ((a: ObjectData, b?: Key) => Key); set nodeGroupKeyProperty(value: string | ((a: ObjectData, b?: Key) => Key)); /** * If there is a container group for the given node data, return the group's key. * @param {ObjectData} nodedata a JavaScript object represented by a node, group, or non-link. * @return {string|number|undefined} This returns undefined if there is no containing group data. * @see #nodeGroupKeyProperty * @see #setGroupKeyForNodeData */ getGroupKeyForNodeData(nodedata: ObjectData): Key; /** * Change the container group for the given node data, given a key for the new group. * @param {ObjectData} nodedata a JavaScript object represented by a node, group, or non-link. * @param {string|number|undefined} key This may be undefined if there should be no containing group data. * @see #nodeGroupKeyProperty * @see #getGroupKeyForNodeData */ setGroupKeyForNodeData(nodedata: ObjectData, key: Key): void; /** * This override also makes sure any copied node data does not have a reference to the containing group. * @expose * @param {ObjectData} nodedata a JavaScript object represented by a node, group, or non-link. * @return {ObjectData} * @see Model#copyNodeData */ copyNodeData(nodedata: ObjectData): ObjectData | null; /** * This override changes the value of some property of a node data, a link data, or an item data, given a string naming the property * and the new value, in a manner that can be undone/redone and that automatically updates any bindings. * This override handles link data as well as node data. * * This gets the old value of the property; if the value is the same as the new value, no side-effects occur. * @expose * @param {ObjectData} data a JavaScript object typically the value of a Panel#data and represented by a Node, Link, Group, simple Part, * or item in a Panel#itemArray; or this model's #modelData. * @param {string} propname a string that is not null or the empty string. * @param {*} val the new value for the property. * @see Model#setDataProperty */ setDataProperty(data: ObjectData, propname: string, val: any): void; /** * This override is similar to Object.assign, * but safely calls #setDataProperty for each property other than a key property. * @param data a data object * @param props an Object holding various properties whose values are to be assigned to the DATA object */ assignAllDataProperties(data: ObjectData, props: ObjectData): void; /** * Gets or sets the name of the data property that returns a string naming that data's category, * The value may also be a function taking two arguments, where the first argument will be a link data object. * If the second argument is not supplied, the function should return the category name; * if the second argument is supplied, the function should modify the link data object so that it has that new category name. * The default value is the name 'category', meaning that it expects the data to have a property named 'category' if it cares to name the category for the Link. * This is used by the diagram to distinguish between different kinds of links. * The name must not be null. * If the value is an empty string, * #getCategoryForLinkData will return an empty string for all link data objects. * * If you want to set this property you must do so before using the model, and especially before you assign Diagram#model. * Note that functions cannot be serialized into JSON-formatted text, so if you are using #toJson and Model.fromJson, * and if you want this property to be a function, you will need to assign this property to your desired function * immediately after creating the model, including when it is created by Model.fromJson. * @see #getCategoryForLinkData * @see #setCategoryForLinkData */ get linkCategoryProperty(): string | ((a: ObjectData, b?: string) => string); set linkCategoryProperty(value: string | ((a: ObjectData, b?: string) => string)); /** * Find the category of a given link data, a string naming the link template * that the Diagram should use to represent the link data. * @param {ObjectData} linkdata a JavaScript object represented by a link. * @return {string} * @see #linkCategoryProperty * @see #setCategoryForLinkData */ getCategoryForLinkData(linkdata: ObjectData): string; /** * Change the category of a given link data, a string naming the link template * that the Diagram should use to represent the link data. * * Changing the link template for a link data will cause the existing Link * to be removed from the Diagram and be replaced with a new Link * created by copying the new link template and applying any data-bindings. * Note that the new template must be an instance of the same class as the original link. * Thus one cannot change the category of a link from an instance of Link * to an instance of a subclass of Link, nor vice-versa. * @param {Object} linkdata a JavaScript object represented by a link. * @param {string} cat Must not be null. * @see #linkCategoryProperty * @see #getCategoryForLinkData */ setCategoryForLinkData(linkdata: ObjectData, cat: string): void; } /** * TreeModels support tree-structured graphs of nodes and links. * Each node can have at most one "tree parent"; cycles are not permitted. * The reference to the parent node's key is a property of the child node data. * * TreeModels, unlike GraphLinksModels, do not support arbitrary link relationships between nodes, * nor is there a separate link data object for each parent-child relationship. * Furthermore there is no support for grouping or label nodes. * * The #nodeParentKeyProperty property names the property on the node data whose value * is the key of the "tree parent" node. * The default value for this property is "parent". * * For example, one can define a graph consisting of one parent node with two child nodes: * ```js * model.nodeDataArray = [ * { key: "Alpha" }, * { key: "Beta", parent: "Alpha" }, * { key: "Gamma", parent: "Alpha" } * ]; * ``` * * If you need to show a more complicated graph structure than a tree, use a GraphLinksModel. * If you want to have multiple links between the same pair of nodes, * or if you want to associate more information with each link and cannot put the information on the child node, * you will need to have a separate link data object for each link, * and that would require the use of GraphLinksModel. * @extends Model * @unrestricted * @since 1.1 * @category Model */ export class TreeModel extends Model { /** * This constructs an empty TreeModel unless one provides arguments as the initial data array values * @param {Array.=} nodedataarray an optional Array containing JavaScript objects to be represented by Parts. * @param {Partial=} init Optional initialization properties. */ constructor(nodedataarray?: Array, init?: Partial); /** * for the Model#nodeDataArray property. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * Gets or sets the name of the property on node data that specifies * the string or number key of the node data that acts as the "parent" for this "child" node data. * The value may also be a function taking two arguments, where the first argument will be a node data object. * If the second argument is not supplied, the function should return the string or number key for the parent node data object of which the given data object is a child; * if the second argument is supplied, the function should modify the node data object so that it has that new key * (which may be undefined to refer to no node) as the parent key for that node.. * The default value is the name 'parent', meaning that it expects the data to have a property named 'parent' if the node wants to refer to the parent node by its key. * The value must not be null nor an empty string. * * If you want to set this property you must do so before using the model, and especially before you assign Diagram#model. * Note that functions cannot be serialized into JSON-formatted text, so if you are using #toJson and Model.fromJson, * and if you want this property to be a function, you will need to assign this property to your desired function * immediately after creating the model, including when it is created by Model.fromJson. * @see #getParentKeyForNodeData * @see #setParentKeyForNodeData */ get nodeParentKeyProperty(): string | ((a: ObjectData, b?: Key) => Key); set nodeParentKeyProperty(value: string | ((a: ObjectData, b?: Key) => Key)); /** * If there is a parent node for the given node data, return the parent's key. * @param {Object} nodedata a JavaScript object represented by a node. * @return {string|number|undefined} This returns undefined if there is no parent node data object. * @see #nodeParentKeyProperty * @see #setParentKeyForNodeData */ getParentKeyForNodeData(nodedata: ObjectData): Key; /** * Change the parent node for the given node data, given a key for the new parent, or undefined if there should be no parent. * @param {Object} nodedata a JavaScript object represented by a node. * @param {string|number|undefined} key This may be undefined if there should be no parent node data. * @see #nodeParentKeyProperty * @see #getParentKeyForNodeData */ setParentKeyForNodeData(nodedata: ObjectData, key: Key): void; /** * Gets or sets the name of the data property that returns a string describing that node data's parent link's category. * The value may also be a function taking two arguments, where the first argument will be a node data object. * If the second argument is not supplied, the function should return the category name for any parent link; * if the second argument is supplied, the function should modify the node data object so that its parent link has that new category name. * The default value is the name 'parentLinkCategory'. * This is used by the diagram to distinguish between different kinds of links. * The name must not be null. * If the value is an empty string, * #getParentLinkCategoryForNodeData will return an empty string for all node data objects. * * If you want to set this property you must do so before using the model, and especially before you assign Diagram#model. * Note that functions cannot be serialized into JSON-formatted text, so if you are using #toJson and Model.fromJson, * and if you want this property to be a function, you will need to assign this property to your desired function * immediately after creating the model, including when it is created by Model.fromJson. * @see #getParentLinkCategoryForNodeData * @see #setParentLinkCategoryForNodeData */ get parentLinkCategoryProperty(): string | ((a: ObjectData, b?: string) => string); set parentLinkCategoryProperty(value: string | ((a: ObjectData, b?: string) => string)); set linkCategoryProperty(value: string | ((a: ObjectData, b?: string) => string)); /** * Find the category for the parent link of a given child node data, a string naming the link template * that the Diagram should use to represent the link. * @param {Object} childdata a JavaScript object represented by a node data. * @return {string} * @see #parentLinkCategoryProperty * @see #setParentLinkCategoryForNodeData */ getParentLinkCategoryForNodeData(childdata: ObjectData): string; /** * Change the category for the parent link of a given child node data, a string naming the link template * that the Diagram should use to represent the link. * * Changing the link template will cause any existing Link * to be removed from the Diagram and replaced with a new Link * created by copying the new link template and applying any data-bindings. * Note that the new template must be an instance of the same class as the original link. * Thus one cannot change the category of a link from an instance of Link * to an instance of a subclass of Link, nor vice-versa. * @param {Object} childdata a JavaScript object represented by a node data. * @param {string} cat Must not be null. * @see #parentLinkCategoryProperty * @see #getParentLinkCategoryForNodeData */ setParentLinkCategoryForNodeData(childdata: ObjectData, cat: string): void; /** * This override also makes sure any copied node data does not have a reference to a parent node. * @expose * @param {Object} nodedata a JavaScript object represented by a node, group, or non-link. * @return {Object} * @see Model#copyNodeData */ copyNodeData(nodedata: ObjectData): ObjectData | null; /** * This override changes the value of some property of a node data or an item data, given a string naming the property * and the new value, in a manner that can be undone/redone and that automatically updates any bindings. * * This gets the old value of the property; if the value is the same as the new value, no side-effects occur. * @expose * @param {Object} data a JavaScript object typically the value of a Panel#data and represented by a Node, Link, Group, simple Part, * or item in a Panel#itemArray; or this model's #modelData. * @param {string} propname a string that is not null or the empty string. * @param {*} val the new value for the property. * @see Model#setDataProperty */ setDataProperty(data: ObjectData, propname: string, val: any): void; } /** * This layout positions nodes in a circular arrangement. * There are several samples that use CircularLayout. * The layout cannot guarantee that it provides optimal positioning of nodes when trying to minimize link crossings. *

* If you want to experiment interactively with most of the properties, try the Circular Layout sample. * See samples that make use of CircularLayout in the samples index. * * This layout makes use of a LayoutNetwork of * CircularVertexes and CircularEdges that normally * correspond to the Nodes and Links of the Diagram. * @extends Layout * @unrestricted * @category Layout */ export class CircularLayout extends Layout { /** * Constructs a CircularLayout with no Layout#network * and with no owning Layout#diagram. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * Create a new LayoutNetwork of CircularVertexes and CircularEdges. * @return {CircularNetwork} a new LayoutNetwork. */ createNetwork(): CircularNetwork; /** * Assign the positions of the vertexes in the network. * @param {Diagram|Group|Iterable.} coll A Diagram or a Group or a collection of Parts. */ doLayout(coll: Diagram | Group | Iterable): void; /** * Position each Node according to the Vertex position, and then position the Links. * * You should not call this method -- it is a "protected virtual" method. */ protected commitLayout(): void; /** * Commit the position of all vertex nodes. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ protected commitNodes(): void; /** * Commit the position and routing of all edge links. * This is called by #commitLayout. * This is only called if Layout#isRouting is true. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ protected commitLinks(): void; /** * Gets or sets the horizontal radius of the elliptical arrangement. * * The default value is NaN. * NaN indicates that the #spacing will determine the size of the ring. * If #spacing is also NaN, the effective spacing will be 6. * If #spacing is a number, the effective radius will be > radius if and only if * the spacing between elements would otherwise be less than spacing. * The specified value for #radius will be ignored if #arrangement === CircularLayout.Packed. * This property must always be positive or NaN. */ get radius(): number; set radius(value: number); /** * Gets or sets the ratio of the arrangement's height to its width * (1 for a circle, >1 for a vertically elongated ellipse). * * This is 1 by default. * The value must be a positive number. * * Modifying this value changes the height, but keeps the width and the #radius constant. */ get aspectRatio(): number; set aspectRatio(value: number); /** * Gets or sets the angle (in degrees, clockwise from the positive side of the X axis) of the first element. * * The default value is 0. */ get startAngle(): number; set startAngle(value: number); /** * Gets or sets the absolute angle (in degrees) between the first and last node. * * The default value is 360. * The value must be greater than zero and less than or equal to 360. * If it is not in this range, it will be automatically set to 360. * * Whether the arrangement is clockwise or counterclockwise does not depend on the sign of this value. * The direction can be controlled by setting #direction. * If 360 is the specified value, the actual value will be less to keep the first and last * elements from overlapping, and the spacing between the first and last nodes will be determined * the same way as for all other adjacent nodes. */ get sweepAngle(): number; set sweepAngle(value: number); /** * Gets or sets how the nodes are spaced. * If #arrangement === CircularLayout.Packed, * the specified #radius will be ignored. * * The default value is CircularLayout.ConstantSpacing. */ get arrangement(): EnumValue; set arrangement(value: EnumValue); /** * Gets or sets whether the nodes are arranged clockwise or counterclockwise. * * The default value is CircularLayout.Clockwise. */ get direction(): EnumValue; set direction(value: EnumValue); /** * Gets or sets if and how the nodes are sorted. * * CircularLayout.Forwards indicates that the nodes are arranged in the order the layout gets them. * CircularLayout.Reverse indicates that the nodes are arranged in the reverse order that the layout gets them. * CircularLayout.Ascending and CircularLayout.Descending indicate that the nodes * will be sorted using the #comparer. * CircularLayout.Optimized indicates that the nodes will be arranged to minimize link crossings. * * The default value is CircularLayout.Optimized. */ get sorting(): EnumValue; set sorting(value: EnumValue); /** * Gets or sets the comparer which sorts the data when #sorting is * set to CircularLayout.Ascending or CircularLayout.Descending. * * The default function compares the Part#text values of the vertexes' LayoutVertex#nodes. */ get comparer(): ((a: CircularVertex, b: CircularVertex) => number); set comparer(value: ((a: CircularVertex, b: CircularVertex) => number)); /** * Gets or sets the distance between nodes (if #radius is NaN) * or the minimum distance between nodes (if #radius is a number). * * The default value is 6. * The value may be NaN. * * If #spacing is NaN, there is no minimum spacing, allowing nodes to overlap, * unless #radius is NaN, * in which case the effective spacing will be 6 to determine an effective radius. * If #spacing is a number but #radius isn't, * the effective spacing will be spacing, and this will determine the effective radius. * If both #spacing and #radius are numbers, * the effective radius will be at least #radius, * but may be larger so that the minimum spacing between nodes is #spacing. */ get spacing(): number; set spacing(value: number); /** * Specifies how the diameter of nodes will be calculated. * When a node is not circular, it is not clear what its diameter is. * * The default is CircularLayout.Pythagorean. */ get nodeDiameterFormula(): EnumValue; set nodeDiameterFormula(value: EnumValue); /** * This read-only property is the effective X radius that may have been calculated by the layout. */ get actualXRadius(): number; /** * This read-only property is the effective Y radius that may have been calculated by the layout. */ get actualYRadius(): number; /** * This read-only property is the effective spacing that may have been calculated by the layout. */ get actualSpacing(): number; /** * This read-only property is the coordinates of the center of the laid-out ellipse immediately after the layout. */ get actualCenter(): Point; /** * The spacing between the idealized boundaries of the nodes is constant; * This value is used for CircularLayout#arrangement. * @constant */ static ConstantSpacing: EnumValue; /** * The distance between the centers of the nodes is constant; * This value is used for CircularLayout#arrangement. * @constant */ static ConstantDistance: EnumValue; /** * The angular distance between the nodes is constant; * This value is used for CircularLayout#arrangement. * @constant */ static ConstantAngle: EnumValue; /** * The vertices are arranged as close together as possible considering the CircularLayout#spacing, * assuming the nodes are rectangular; * This value is used for CircularLayout#arrangement. * @constant */ static Packed: EnumValue; /** * Rings are filled clockwise; * This value is used for CircularLayout#direction. * @constant */ static Clockwise: EnumValue; /** * Rings are filled counterclockwise; * This value is used for CircularLayout#direction. * @constant */ static Counterclockwise: EnumValue; /** * The ring is filled by alternating sides; the second node is counterclockwise from the first node; * This value is used for CircularLayout#direction. * @constant */ static BidirectionalLeft: EnumValue; /** * The ring is filled by alternating sides; the second node is clockwise from the first node; * This value is used for CircularLayout#direction. * @constant */ static BidirectionalRight: EnumValue; /** * Nodes are arranged in the order given; * This value is used for CircularLayout#sorting. * @constant */ static Forwards: EnumValue; /** * Nodes are arranged in the reverse of the order given; * This value is used for CircularLayout#sorting. * @constant */ static Reverse: EnumValue; /** * Nodes are sorted using the #comparer, in ascending order; * This value is used for CircularLayout#sorting. * @constant */ static Ascending: EnumValue; /** * Nodes are sorted using the #comparer, in reverse ascending (descending) order; * This value is used for CircularLayout#sorting. * @constant */ static Descending: EnumValue; /** * Nodes are ordered to reduce link crossings; * This value is used for CircularLayout#sorting. * @constant */ static Optimized: EnumValue; /** * The effective diameter is sqrt(width^2+height^2); * The corners of square nodes will touch at 45 degrees when CircularLayout#spacing is 0; * This value is used for CircularLayout#nodeDiameterFormula. * @constant */ static Pythagorean: EnumValue; /** * The effective diameter is either the width or height of the node, whichever is larger; * This will cause circular nodes to touch when CircularLayout#spacing is 0; * This is ideal when the nodes are circular. * This value is used for CircularLayout#nodeDiameterFormula. * @constant */ static Circular: EnumValue; } /** * This class represents an abstract graph of CircularVertexes and CircularEdges * that can be constructed based on the Nodes and Links of a Diagram * so that the CircularLayout can operate independently of the diagram until it * is time to commit any node positioning or link routing. * * This class inherits from LayoutNetwork. * @extends LayoutNetwork * @unrestricted * @category Layout * @unindexed */ export class CircularNetwork extends LayoutNetwork { constructor(layout: CircularLayout); } /** * This holds CircularLayout-specific information about Nodes. * * This class inherits from LayoutVertex. * @extends LayoutVertex * @unrestricted * @category Layout * @unindexed */ export class CircularVertex extends LayoutVertex { constructor(network: CircularNetwork); /** * Gets or sets the value used as the vertex's diameter. * * By default the value depends on the CircularLayout#arrangement property. * Any computed value is cached, to avoid unnecessary expensive computations. */ get diameter(): number; set diameter(value: number); /** * Gets or sets the value used as the vertex's angle. */ get actualAngle(): number; set actualAngle(value: number); } /** * This holds CircularLayout-specific information about Links. * * This class inherits from LayoutEdge. * @extends LayoutEdge * @unrestricted * @category Layout * @unindexed */ export class CircularEdge extends LayoutEdge { constructor(network: CircularNetwork); } /** * Force-directed layout treats the graph as if it were a system of physical bodies * with repulsive electrical, attractional gravitational, and spring forces acting on them and between them. * * Electrical forces come both from the field at the vertex's location as well as from neighboring vertexes and are quadratic by distance. * Gravitational forces come from the field at the vertex's location and are constant. * Spring forces are only exerted between two different vertexes that are connected by an edge and are linear by distance. * * The electrical forces on a vertex are the sum of the electrical charge times the electrical field at that location * (#electricalCharge, #electricalFieldX, #electricalFieldY) * and the electrical forces of all nearby vertexes divided by the square of the distance between them. * You can easily assign the electrical charge for all vertexes by assigning #defaultElectricalCharge. * By default there is no electrical field, so all forces are due to nearby charged vertexes. * For efficiency, #infinityDistance determines a cut-off distance between vertexes for which to consider any influence. * * The gravitational forces on a vertex are the sum of the gravitational mass times the gravitational field at that location * (#gravitationalMass, #gravitationalFieldX, #gravitationalFieldY). * You can easily assign the gravitational mass for all vertexes by assigning #defaultGravitationalMass. * By default there is no gravitational field. * * The spring forces on a vertex are only exerted by the edges connecting it with other vertexes. * The force along an edge is the stiffness of the spring times the difference of the distance between the vertexes and the nominal length of the spring * (#springStiffness, #springLength) divided by the distance between the vertexes. * When the distance is less than the nominal length, the force pushes the vertexes apart; when the distance is greater, the force pulls them together. * You can easily assign the spring length and stiffness for all edges by assigning #defaultSpringLength and #defaultSpringStiffness. * * When the distance between two vertexes is less than one unit, this uses a random number generator to decide which direction the forces should go. * For layouts that start with all of the vertexes at the same location, this results in potentially dramatically different results. * Set #randomNumberGenerator to null in order to produce reproducible results given the same initial vertex locations. * * The algorithm seeks a configuration of the bodies with locally minimal energy, * i.e. vertex positions such that the sum of the forces on each vertex is zero. * This is achieved by repeatedly computing the forces on each vertex, moving them, and repeating. * Computations stop when no vertex moves more than #epsilonDistance or when #maxIterations have happened. * * The layout cannot guarantee that it provides optimal positioning of nodes. * Nodes will normally not overlap each other, but when there is a dense interconnectivity overlaps might not be avoidable. *

* If you want to experiment interactively with most of the properties, try the Force Directed Layout sample. * See samples that make use of ForceDirectedLayout in the samples index. * * This layout makes use of a LayoutNetwork of * ForceDirectedVertexes and ForceDirectedEdges that normally * correspond to the Nodes and Links of the Diagram. * @extends Layout * @unrestricted * @category Layout */ export class ForceDirectedLayout extends Layout { /** * Constructs a ForceDirectedLayout with no Layout#network * and with no owning Layout#diagram. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * Create a new LayoutNetwork of ForceDirectedVertexes and ForceDirectedEdges. * @return {ForceDirectedNetwork} a new LayoutNetwork. */ createNetwork(): ForceDirectedNetwork; /** * Perform the force-directed layout. * * If there is no Layout#network, this calls #makeNetwork to create a LayoutNetwork from the given collection of Parts. * This removes any reflexive edges in the network, since they should be ignored. * * For each vertex this calls and remembers the result of #electricalCharge as the ForceDirectedVertex#charge * and the result of #gravitationalMass as the ForceDirectedVertex#mass. * * For each edge this calls and remembers the result of #springStiffness as the ForceDirectedEdge#stiffness * and the result of #springLength as the ForceDirectedEdge#length. * * This then iterates, updating the position of each vertex according to the forces upon it, * until reaching #maxIterations or until no vertex moves more than about #epsilonDistance. * * Finally this calls Layout#updateParts to commit the Node positions from the vertex positions. * Layout#updateParts calls #commitLayout within a transaction. * @param {Diagram|Group|Iterable.} coll A Diagram or a Group or a collection of Parts */ doLayout(coll: Diagram | Group | Iterable): void; /** * Find any associated objects to be positioned along with the LayoutVertex#node. * * This method is called for each vertex in the network, when #comments is true. * The standard behavior is to look for Nodes whose Part#category * is "Comment" and that refer to the LayoutVertex#node. * By default this method will not be called unless you set #comments to true. * * You may want to override this method in order to customize how any * associated objects are found and how a new ForceDirectedVertex * and ForceDirectedEdge * may be added to the network to represent the (balloon?) comment. * This method sets the new vertex's ForceDirectedVertex#charge * to the value of #defaultCommentElectricalCharge, * and sets the new edge's ForceDirectedEdge#length * to the value of #defaultCommentSpringLength. * @expose * @param {ForceDirectedVertex} v * @since 1.3 */ addComments(v: ForceDirectedVertex): void; /** * (undocumented) * Move the vertex by its ForceDirectedVertex.forceX and ForceDirectedVertex.forceY. * Return the square of the distance moved. * This can be overridden in order to constrain the vertex's actual movement. * @expose * @param {ForceDirectedVertex} v * @return {number} square of distance moved */ moveVertex(v: ForceDirectedVertex): number; /** * Maybe move a vertex that #isFixed. * This is called each iteration on each such vertex. * By default this does nothing. * @expose * @param {ForceDirectedVertex} v */ moveFixedVertex(v: ForceDirectedVertex): void; /** * Set the fromSpot and toSpot on each Link, position each Node according * to the vertex position, and then position/route the Links. * * This calls the #commitNodes and #commitLinks methods, the latter only if #isRouting is true. * You should not call this method -- it is a "protected virtual" method. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. */ protected commitLayout(): void; /** * Commit the position of all nodes. * * This is called by #commitLayout. * See also #commitLinks. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ protected commitNodes(): void; /** * Routes the links. * * This is called by #commitLayout. * This is only called if Layout#isRouting is true. * See also #commitNodes. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ protected commitLinks(): void; /** * Returns the stiffness of the spring representing an edge. * * The spring force between two vertexes connected by an edge is linearly proportional by distance * to the difference between the #springLength and the distance. * When the distance is greater than the length, the force pulls the vertexes closer to each other. * When the distance is less than the length, the force pushes them apart. * * The two vertexes connected by the edge E are acted upon by a force of proportional to * `springStiffness(E) * (getNodeDistance(E.fromVertex, E.toVertex) - springLength(E))` divided by the distance between the vertexes. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {ForceDirectedEdge} e * @return {number} * Returns the stiffness of the edge representing a link, * the value of ForceDirectedEdge#stiffness if it's a number, * or else the value of #defaultSpringStiffness. */ springStiffness(e: ForceDirectedEdge): number; /** * Returns the length of the spring representing an edge. * The two vertexes connected by the edge E are acted upon by a force of proportional to * `springStiffness(E) * (getNodeDistance(E.fromVertex, E.toVertex) - springLength(E))` divided by the distance between the vertexes. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {ForceDirectedEdge} e * @return {number} * Returns the length of the edge representing a link, * the value of ForceDirectedEdge#length if it's a number, * or else the value of #defaultSpringLength. */ springLength(e: ForceDirectedEdge): number; /** * Returns the charge of the vertex, * the value of ForceDirectedVertex#charge if it's a number, * or else the value of #defaultElectricalCharge. * * The electrical forces between two vertexes decrease by the square of the distance between them. * Vertexes that are more than #infinityDistance apart are assumed to have no electrical charge effect on each other. * * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {ForceDirectedVertex} v * @return {number} */ electricalCharge(v: ForceDirectedVertex): number; /** * Returns the electrical field in the X direction acting on a vertex at the given point. * By default there is no electrical field at any location. * * Used to define an external electrical field at a point independent of the vertex charges. * A vertex L is acted upon by a force in the X direction of proportional to * `electricalFieldX(L.center.x, L.center.y) * electricalCharge(L)`. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {number} x * @param {number} y * @return {number} the default implementation returns zero. */ electricalFieldX(x: number, y: number): number; /** * Returns the electrical field in the Y direction acting on a vertex at the given point. * By default there is no electrical field at any location. * * Used to define an external electrical field at a point independent of the vertex charges. * A vertex L is acted upon by a force in the Y direction of proportional to * `electricalFieldY(L.center.x, L.center.y) * electricalCharge(L)`. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {number} x * @param {number} y * @return {number} the default implementation returns zero. */ electricalFieldY(x: number, y: number): number; /** * Returns the mass of the vertex, * the value of ForceDirectedVertex#mass if it's a number, * or else the value of #defaultGravitationalMass. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {ForceDirectedVertex} v * @return {number} */ gravitationalMass(v: ForceDirectedVertex): number; /** * This returns the gravitational field in the X direction acting on a vertex at the given point. * By default there is no gravitational field at any location. * * Used to define an external gravitational field at a point independent of the vertex masses. * A vertex L is acted upon by a force in the X direction of proportional to * `gravitationalFieldX(L.center.x, L.center.y) * gravitationalMass(L)`. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {number} x * @param {number} y * @return {number} the default implementation returns zero. */ gravitationalFieldX(x: number, y: number): number; /** * This returns the gravitational field in the Y direction acting on a vertex at the given point. * By default there is no gravitational field at any location. * * Used to define an external gravitational field at a point independent of the vertex masses. * A vertex L is acted upon by a force in the Y direction of proportional to * `gravitationalFieldY(L.center.x, L.center.y) * gravitationalMass(L)`. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {number} x * @param {number} y * @return {number} the default implementation returns zero. */ gravitationalFieldY(x: number, y: number): number; /** * This predicate returns true if the vertex should not be moved * by the layout algorithm but still have an effect on nearby and connected vertexes. * The default implementation returns ForceDirectedVertex#isFixed. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {ForceDirectedVertex} v * @return {boolean} returns true if the node should not be moved by the layout algorithm. */ isFixed(v: ForceDirectedVertex): boolean; /** * This read-only property returns the current iteration count, valid during a call to #doLayout. */ get currentIteration(): number; /** * Gets or sets the space between which the layout * will position the connected graphs that together compose the network. * This defaults to Size(100, 100). * These distances are used during a clustered layout; * afterwards the normal force-directed layout * will likely cause the size of any space between connected graphs to change, * perhaps considerably. */ get arrangementSpacing(): Size; set arrangementSpacing(value: Size); /** * Gets or sets whether #commitNodes should move all of the * nodes so that the nodes all fit with the top-left corner at the * Layout#arrangementOrigin. * By default this is false -- the Layout#arrangementOrigin is ignored. * When this is true, nodes are moved even though #isFixed was true. */ get arrangesToOrigin(): boolean; set arrangesToOrigin(value: boolean); /** * Gets or sets whether the fromSpot and the toSpot of every Link * should be set to Spot.Default. * The default value is true. */ get setsPortSpots(): boolean; set setsPortSpots(value: boolean); /** * Gets or sets whether this layout should find all Nodes * whose category is "Comment" and * whose anchors are nodes represented in the network, * and add ForceDirectedVertexes representing those balloon comments * as nodes in the network. * The default value is false. */ get comments(): boolean; set comments(value: boolean); /** * Gets or sets the maximum number of iterations to perform when doing the * force-directed auto layout. * The value must be non-negative. * The default value is 100. */ get maxIterations(): number; set maxIterations(value: number); /** * Gets or sets approximately how far a node must move in order for the iterations to continue. * The default value is 1. * The value must be larger than zero. */ get epsilonDistance(): number; set epsilonDistance(value: number); /** * Gets or sets a threshold for the distance beyond which the electrical charge forces may be ignored. * The default value is 1000. * The value must be larger than 1. */ get infinityDistance(): number; set infinityDistance(value: number); /** * Gets or sets how far a vertex may be moved in an iteration. * The default value is 10. * The value must be larger than 1. * @since 1.8 */ get moveLimit(): number; set moveLimit(value: number); /** * Gets or sets a random number generator. * The default value is Math, which results in calling Math.random(). * Change this to null in order to use an instance of an internal repeatable pseudo-random number generator, * which will become the new value of this property. * * The new value must be either null or an Object with a method named "random" taking zero arguments * and returning a random number between zero (inclusive) and one (exclusive). * @since 1.5 */ get randomNumberGenerator(): ({ random: () => number; } | null); set randomNumberGenerator(value: ({ random: () => number; } | null)); /** * Gets or sets the default value computed by #springStiffness. * The initial value is 0.05. */ get defaultSpringStiffness(): number; set defaultSpringStiffness(value: number); /** * Gets or sets the default value computed by #springLength. * The initial value is 50. */ get defaultSpringLength(): number; set defaultSpringLength(value: number); /** * Gets or sets the default value computed by #electricalCharge. * The initial value is 150. */ get defaultElectricalCharge(): number; set defaultElectricalCharge(value: number); /** * Gets or sets the default value computed by #gravitationalMass. * The initial value is zero. */ get defaultGravitationalMass(): number; set defaultGravitationalMass(value: number); /** * Gets or sets the default value computed by #springLength. * The initial value is 10. */ get defaultCommentSpringLength(): number; set defaultCommentSpringLength(value: number); /** * Gets or sets the default value computed by #electricalCharge. * The initial value is 5. */ get defaultCommentElectricalCharge(): number; set defaultCommentElectricalCharge(value: number); } /** * This class represents an abstract graph of ForceDirectedVertexes and ForceDirectedEdges * that can be constructed based on the Nodes and Links of a Diagram * so that the ForceDirectedLayout can operate independently of the diagram until it * is time to commit any node positioning or link routing. * * This class inherits from LayoutNetwork. * @extends LayoutNetwork * @unrestricted * @category Layout * @unindexed */ export class ForceDirectedNetwork extends LayoutNetwork { constructor(layout: ForceDirectedLayout); } /** * This holds ForceDirectedLayout-specific information about Nodes. * * This class inherits from LayoutVertex. * @extends LayoutVertex * @unrestricted * @category Layout * @unindexed */ export class ForceDirectedVertex extends LayoutVertex { constructor(network: ForceDirectedNetwork); /** * Gets or sets whether the vertex may be moved by any forces. * The default value is false. */ get isFixed(): boolean; set isFixed(value: boolean); /** * Gets or sets the electrical charge for this vertex. * The default value is NaN. */ get charge(): number; set charge(value: number); /** * Gets or sets the gravitational mass for this vertex. * The default value is NaN. */ get mass(): number; set mass(value: number); /** * Gets or sets the cumulative force on the vertex in the X direction. * The default value is zero. */ get forceX(): number; set forceX(value: number); /** * Gets or sets the cumulative force on the vertex in the Y direction. * The default value is zero. */ get forceY(): number; set forceY(value: number); } /** * This holds ForceDirectedLayout-specific information about Links. * * This class inherits from LayoutEdge. * @extends LayoutEdge * @unrestricted * @category Layout * @unindexed */ export class ForceDirectedEdge extends LayoutEdge { constructor(network: ForceDirectedNetwork); /** * Gets or sets this edge's stiffness or resistance to compression or stretching. * The default value is NaN. */ get stiffness(): number; set stiffness(value: number); /** * Gets or sets the length of this edge. * The default value is NaN. */ get length(): number; set length(value: number); } /** * This arranges nodes of directed graphs into layers (rows or columns). * There are many samples that use LayeredDigraphLayout. *

* If you want to experiment interactively with most of the properties, try the Layered Digraph Layout sample. * See samples that make use of LayeredDigraphLayout in the samples index. * * The #layerSpacing property controls the distance between layers. * The #columnSpacing property controls the breadth of each "column" -- * this affects the distance between nodes within a layer, although the exact distance also depends on the breadth of each node. * The #layeringOption property determines whether nodes without links coming in or without links going out are * lined up at the edge of the graph, or whether they are positioned close to their connected nodes. * * By default the layout will route the links in a manner that is consistent with the #direction. * So, for example, if the #direction is 90 degrees (i.e. downward), the links are expected to go from the top towards the bottom. * That means the links should come out from the bottom of the ports and should go into the top of the ports. * Basically the layout will set Link#fromSpot to `Spot.Bottom` and Link#toSpot to `Spot.Top`. * * If you want to the links to use the spots that are given by the ports or by the links themselves, you will need to set * #setsPortSpots to false to prevent this layout from setting the spots on the links. * For example, if each node only has one port that is the whole node, and if you want the links to be spread out along the sides * of the nodes, then you should set #setsPortSpots to false and set the node's GraphObject#fromSpot to * `Spot.BottomSide` and GraphObject#toSpot to `Spot.TopSide`. * * This layout handles links that form cycles better than TreeLayout does. * The normal routing behavior for "backwards" links is to route them "around" the source node and "around" the destination node, * so that all links come in one side and go out the other side. * However if you want "backwards" links to go more directly between nodes, set #setsPortSpots to false and * the node's GraphObject#fromSpot and GraphObject#toSpot both to `Spot.TopBottomSides`. * (Of course if the #direction is zero or 180, you'll want to use `Spot.LeftRightSides`.) * * If the diagram is structured in a tree-like fashion, * it may be better to use TreeLayout, * which has more options specific to trees. * TreeLayout is much faster than LayeredDigraphLayout, * and can handle a limited number of links that would prevent the * graph structure from being a true tree (i.e. some nodes having multiple parents). * * This layout makes use of a LayoutNetwork of * LayeredDigraphVertexes and LayeredDigraphEdges that normally * correspond to the Nodes and Links of the Diagram. * * The layout algorithm consists of four-major steps: Cycle Removal, * Layer Assignment, Crossing Reduction, and Straightening and Packing. * The layout cannot guarantee that it provides optimal positioning of nodes or routing of links. * * The Layer Assignment step can be slow if #layeringOption is * LayeredDigraphLayout.LayerOptimalLinkLength, which is the default value. * * The CrossingReduction step is usually slow, but it can be avoided if you want to * maintain a certain order within each layer by setting LayeredDigraphLayout#aggressiveOption * to LayeredDigraphLayout.AggressiveNone. * * The Straightening and Packing step is usually slow, but you can set * #packOption at the expense of less nicely placed nodes. * Moreover, if you do not set this property, the layout will automatically remove the * LayeredDigraphLayout.PackExpand flag if the graph is large enough, * in order to improve performance. * It is also worth experimenting whether using #alignOption to straighten and pack * provides good results for your graphs, as it is faster than #packOption. * * If performance remains a problem, contact us. * @extends Layout * @unrestricted * @category Layout */ export class LayeredDigraphLayout extends Layout { /** * Constructs a LayeredDigraphLayout with no Layout#network * and with no owning Layout#diagram. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * Create a new LayoutNetwork of LayeredDigraphVertexes and LayeredDigraphEdges. * @expose * @return {LayeredDigraphNetwork} a new LayoutNetwork. */ createNetwork(): LayeredDigraphNetwork; /** * Perform the layered digraph layout. * * If there is no Layout#network, this calls #makeNetwork to create a LayoutNetwork from the given collection of Parts. * This removes any reflexive edges in the network, since they should be ignored. * * In order to influence a vertex's layer, you can override #assignLayers. * * Finally this calls Layout#updateParts to commit the Node positions from the vertex positions. * Layout#updateParts calls #commitLayout within a transaction. * @param {Diagram|Group|Iterable.} coll A Diagram or a Group or a collection of Parts. */ doLayout(coll: Diagram | Group | Iterable): void; /** * (undocumented) * The function LinkMinLength returns the minimum length of the * link represented by the LayeredDigraphEdge link. * The default implementation gives links a minimum length of 1. * This function can be overridden to provide "fine-tuning" of the layout. * @expose * @param {LayeredDigraphEdge} edge * @return {number} Returns the minimum length of the link represented by link. */ protected linkMinLength(edge: LayeredDigraphEdge): number; /** * (undocumented) * This function returns the minimum space reserved for this node from the center point * for the "depth" of the layer that it is in. * * The default implementation returns 0 for nodes that do not * correspond to top-level Go objects. For nodes that do correspond * to top-level Go objects, the layer space is determined by the * width or height of the object depending on the #direction. * By default this adds 10 to the space, to account for port end segment lengths. * * @expose * @param {LayeredDigraphVertex} v * @param {boolean} topleft whether to return the distance from the vertex's position * @return {number} Returns the minimum space reserved above and below this node, in document coordinates. */ protected nodeMinLayerSpace(v: LayeredDigraphVertex, topleft: boolean): number; /** * (undocumented) * The function nodeMinColumnSpace returns the minimum space * reserved to either side of this node. * * The default implementation returns 0 for nodes that do not * correspond to top-level Go objects. For nodes that do correspond * to top-level Go objects, the column space is determined by the * width and height of the object divided by the #columnSpacing. * Note: all sub-classes that override this method should ensure that * nodes that do not correspond to top-level Go objects have a minimum * column space of 0. * This function can be overridden to provide "fine-tuning" of the layout. * * This property has no effect on positioning of nodes when using #alignOption. * @expose * @param {LayeredDigraphVertex} v * @param {boolean} topleft whether to return the distance from the vertex's position * @return {number} Returns the minimum space reserved to either side of the center of this node, in units of #columnSpacing. */ protected nodeMinColumnSpace(v: LayeredDigraphVertex, topleft: boolean): number; /** * (undocumented) * Removes cycles from the input network by reversing some number of links. * By default, this just calls #greedyCycleRemoval or #depthFirstCycleRemoval, * as appropriate, give the value of #cycleRemoveOption. * @expose */ protected removeCycles(): void; /** * Assigns every vertex in the input network to a layer. * The layer is a non-negative integer describing which row of vertexes each vertex belongs in. * (Do not confuse this concept of "layer" with Layers that control the Z-ordering of Parts.) * * The layering satisfies the following relationship: * if L is a link from node U to node V, then U.layer > V.layer. * * This method can be overridden to customize how nodes are assigned layers. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * By default, this does the appropriate assignments given the value of #layeringOption. * @expose * @since 1.1 */ protected assignLayers(): void; /** * (undocumented) * Assigns every node in the input network an index number, * such that nodes in the same layer will be labeled with * consecutive indices in left to right order. * All consecutive layout operations will preserve or update * the indices. * * In addition, the indices array is initialized such that * indices[layer] indicates the number of nodes in the layer. * Finally, the variables minIndexLayer and maxIndexLayer record * the layers that correspond to the minimum and maximum nodes * in a layer. * By default this will just call #naiveInitializeIndices, * #depthfirstOutInitializeIndices, or * #depthfirstInInitializeIndices, as appropriate * given the value of #initializeOption. * This method must not change the layer of any existing node, nor add or remove any layers. * @expose */ protected initializeIndices(): void; /** * (undocumented) * Reorders nodes within layers to reduce the total number of link * crossings in the network. * * There are many, many possible implementations of this function. * Basically, some iteration of MedianBarycenterCrossingReduction * and AdjacentExchangeCrossingReductionBendStraighten * sweeping back and forth over the layers is needed. * The default implementation has performed favorably on a large number * of networks, but other options are available. * @expose */ protected reduceCrossings(): void; /** * (undocumented) * Adjusts the columns of nodes in the network to produce a layout which reduces * the number of bends and is tightly packed. * * When using #alignOption, nodes are assigned coordinates within their layers * to produce straighter paths of nodes and small edge lengths. * @expose */ protected straightenAndPack(): void; /** * Set the fromSpot and toSpot on each Link, position each Node according * to the vertex position, and then position/route the Links. * * This calls the #commitNodes and #commitLinks methods, the latter only if #isRouting is true. * You should not call this method -- it is a "protected virtual" method. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. */ protected commitLayout(): void; /** * Commit the position of all nodes. * * This is called by #commitLayout. * See also #commitLinks. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ protected commitNodes(): void; /** * This overridable method is called by #commitLayout * to support custom arrangement of bands or labels across each layout layer. * By default this method does nothing. * * The coordinates used in the resulting Rects may need to be offset by the Layout#arrangementOrigin. * @expose * @param {Array.} layerRects an Array of Rects with the bounds of each of the "layers" * @param {Point} offset the position of the top-left corner of the banded area relative to the coordinates given by the layerRects * @since 1.4 */ protected commitLayers(layerRects: Array, offset: Point): void; /** * Routes the links. * * This is called by #commitLayout. * This is only called if Layout#isRouting is true. * See also #commitNodes. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ protected commitLinks(): void; /** * Gets or sets the space between each layer. * This value must be non-negative and it defaults to 25. */ get layerSpacing(): number; set layerSpacing(value: number); /** * Gets or sets the size of each column. * This value must be positive and it defaults to 25. * * When using #alignOption, this will act as node spacing for nodes within a layer. */ get columnSpacing(): number; set columnSpacing(value: number); /** * Gets or sets the direction the graph grows towards. * 0 is towards the right, 90 is downwards, 180 is towards the left, and 270 is upwards. * The default value is 0. */ get direction(): number; set direction(value: number); /** * Gets or set which cycle removal option is used. * The value must be one of the following values: * LayeredDigraphLayout.CycleDepthFirst, * LayeredDigraphLayout.CycleGreedy, or * LayeredDigraphLayout.CycleFromLayers. * The default value is LayeredDigraphLayout.CycleDepthFirst. */ get cycleRemoveOption(): EnumValue; set cycleRemoveOption(value: EnumValue); /** * Gets or sets which layering option is being used. * The value must be one of the following values: * LayeredDigraphLayout.LayerLongestPathSink, * LayeredDigraphLayout.LayerLongestPathSource, or * LayeredDigraphLayout.LayerOptimalLinkLength. * The default value is LayeredDigraphLayout.LayerOptimalLinkLength, * which is also the slowest option. */ get layeringOption(): EnumValue; set layeringOption(value: EnumValue); /** * Gets or sets which indices initialization option is being used. * The value must be one of the following values: * LayeredDigraphLayout.InitDepthFirstOut, * LayeredDigraphLayout.InitDepthFirstIn, or * LayeredDigraphLayout.InitNaive. * The default value is LayeredDigraphLayout.InitDepthFirstOut. */ get initializeOption(): EnumValue; set initializeOption(value: EnumValue); /** * Gets or sets the number of iterations to be done. * The value must be non-negative. The default value is 4. */ get iterations(): number; set iterations(value: number); /** * Gets or sets which aggressive option is being used to look for link crossings. * The default value is LayeredDigraphLayout.AggressiveLess. * The fastest option is LayeredDigraphLayout.AggressiveNone. */ get aggressiveOption(): EnumValue; set aggressiveOption(value: EnumValue); /** * Gets or sets the options used by the straighten and pack function; * this option is deprecated -- we recommend using #alignOption instead for better alignment and speed. * * The value must be a combination of the following bit flags: * LayeredDigraphLayout.PackMedian, * LayeredDigraphLayout.PackStraighten, and * LayeredDigraphLayout.PackExpand. * The default value is LayeredDigraphLayout.PackAll, which is a combination of all three flags. * * Each of the flags has a cost; PackExpand is particularly slow. * However if you do not set this property, this layout will automatically turn off the PackExpand * option for you if the graph is large enough. * You can set this property value to LayeredDigraphLayout.PackNone to avoid most of the work. * * This option is ignored if #alignOption is set to a value other than LayeredDigraphLayout.AlignNone. * This tends to be slower than #alignOption, particularly for larger graphs. * Larger graphs, however, will usually be more compact than when using alignOption. * * @see #alignOption */ get packOption(): number; set packOption(value: number); set packIterations(value: number); /** * Gets or sets the options used by the straighten and pack function, as a potentially faster * alternative to #packOption. * * When using this option, nodes are assigned coordinates within their layers * to produce straighter paths of nodes and small edge lengths. * * When used as an alternative to #packOption, this tends to be faster, * particularly for larger graphs. * Larger graphs, however, will usually be less compact than when using packOption. * If this option is set, packOption is ignored. * * This option does not use columns, but rather uses #columnSpacing to space nodes within a layer. * * The value must be a combination of the following bit flags: * LayeredDigraphLayout.AlignUpperLeft, * LayeredDigraphLayout.AlignUpperRight, * LayeredDigraphLayout.AlignLowerLeft, and * LayeredDigraphLayout.AlignLowerRight. * * Using LayeredDigraphLayout.AlignAll will tend to provide the most balanced results * and is what we recommend starting with. * * The default value is LayeredDigraphLayout.AlignNone, meaning #packOption is used. * LayeredDigraphLayout.AlignAll may become the default in a future major version. * * @see #packOption * @since 2.3 */ get alignOption(): number; set alignOption(value: number); /** * Gets or sets whether the FromSpot and ToSpot of each link should be set * to values appropriate for the given value of LayeredDigraphLayout#direction. * The default value is true. * * If you set this to false, the spot values of the links and port objects will be used. * If you do not set the spot values to sensible values matching the #direction, * the routing results may be poor and they may cross over nodes. */ get setsPortSpots(): boolean; set setsPortSpots(value: boolean); /** * (undocumented) * Gets or sets the distance between link segments for unrelated links that would otherwise be overlapping. * The default value is 4. The value must be non-negative. * * If there are a lot of possibly overlapping links and the #layerSpacing is not large enough, * some links may cross over nodes. * You will either need to increase the layerSpacing or decrease this linkSpacing property. */ get linkSpacing(): number; set linkSpacing(value: number); /** * This read-only property returns the largest layer value. */ get maxLayer(): number; /** * This read-only property returns the largest index value. */ get maxIndex(): number; /** * This read-only property returns the largest column value. */ get maxColumn(): number; /** * This read-only property returns the smallest index layer. */ get minIndexLayer(): number; /** * This read-only property returns the larges index layer. */ get maxIndexLayer(): number; /** * Remove cycles using depth first cycle removal; * a valid value of LayeredDigraphLayout#cycleRemoveOption. * @constant */ static CycleDepthFirst: EnumValue; /** * Remove cycles using greedy cycle removal; * a valid value of LayeredDigraphLayout#cycleRemoveOption. * @constant */ static CycleGreedy: EnumValue; /** * Remove cycles depending on #assignLayers determining entirely which links are backwards links; * a valid value of LayeredDigraphLayout#cycleRemoveOption. * @constant */ static CycleFromLayers: EnumValue; /** * Assign layers using optimal link length layering, so that links tend to cross the fewest number of layers; * A valid value for LayeredDigraphLayout#layeringOption. * @constant */ static LayerOptimalLinkLength: EnumValue; /** * Assign layers using longest path sink layering, so that nodes are placed in the latest layer possible * possibly resulting in longer links to nodes at the last/deepest layers; * a valid value for LayeredDigraphLayout#layeringOption. * @constant */ static LayerLongestPathSink: EnumValue; /** * Assign layers using longest path source layering, so that nodes without any predecessors are placed * in the first layer possibly resulting in longer links from nodes at the first/shallowest layers; * a valid value for LayeredDigraphLayout#layeringOption. * @constant */ static LayerLongestPathSource: EnumValue; /** * Initialize using depth first out initialization; * a valid value for LayeredDigraphLayout#initializeOption. * @constant */ static InitDepthFirstOut: EnumValue; /** * Initialize using depth first in initialization; * a valid value for LayeredDigraphLayout#initializeOption. * @constant */ static InitDepthFirstIn: EnumValue; /** * Initialize using naive initialization; * a valid value for LayeredDigraphLayout#initializeOption. * @constant */ static InitNaive: EnumValue; /** * The fastest, but poorest, crossing reduction algorithm; * a valid value for LayeredDigraphLayout#aggressiveOption. * @constant */ static AggressiveNone: EnumValue; /** * The faster, less aggressive, crossing reduction algorithm; * a valid value for LayeredDigraphLayout#aggressiveOption. * @constant */ static AggressiveLess: EnumValue; /** * The slower, more aggressive, crossing reduction algorithm, * a valid value for LayeredDigraphLayout#aggressiveOption. * @constant */ static AggressiveMore: EnumValue; /** * Does minimal work in packing the nodes; * a valid value for LayeredDigraphLayout#packOption; * but we recommend using #alignOption instead for better alignment and speed. * @constant */ static PackNone: number; /** * This option gives more chances for the packing algorithm to improve the network, * but is very expensive in time for large networks; * but we recommend using #alignOption instead for better alignment and speed; * a valid value for LayeredDigraphLayout#packOption. * @constant */ static PackExpand: number; /** * This option tries to have the packing algorithm straighten many of the * links that cross layers, * a valid value for LayeredDigraphLayout#packOption; * but we recommend using #alignOption instead for better alignment and speed. * @constant */ static PackStraighten: number; /** * This option tries to have the packing algorithm center groups of nodes * based on their relationships with nodes in other layers, * a valid value for LayeredDigraphLayout#packOption; * but we recommend using #alignOption instead for better alignment and speed. * @constant */ static PackMedian: number; /** * Enable all options for the LayeredDigraphLayout#packOption property; * but we recommend using #alignOption instead for better alignment and speed; * See also LayeredDigraphLayout.PackExpand, LayeredDigraphLayout.PackStraighten, * and LayeredDigraphLayout.PackMedian. * @constant */ static PackAll: number; /** * This option means the the layout will pack nodes using the LayeredDigraphLayout#packOption instead of LayeredDigraphLayout#alignOption, * a valid value for LayeredDigraphLayout#alignOption. * @constant */ static AlignNone: number; /** * This option aligns and compacts nodes based on upper neighbors, favoring leftmost neighbors, * a valid value for LayeredDigraphLayout#alignOption. * @constant */ static AlignUpperLeft: number; /** * This option aligns and compacts nodes based on upper neighbors, favoring rightmost neighbors, * a valid value for LayeredDigraphLayout#alignOption. * @constant */ static AlignUpperRight: number; /** * This option aligns and compacts nodes based on lower neighbors, favoring leftmost neighbors, * a valid value for LayeredDigraphLayout#alignOption. * @constant */ static AlignLowerLeft: number; /** * This option aligns and compacts nodes based on lower neighbors, favoring rightmost neighbors, * a valid value for LayeredDigraphLayout#alignOption. * @constant */ static AlignLowerRight: number; /** * Enable all options for the LayeredDigraphLayout#alignOption property; * See also LayeredDigraphLayout.AlignUpperLeft, LayeredDigraphLayout.AlignUpperRight, * LayeredDigraphLayout.AlignLowerLeft, and LayeredDigraphLayout.AlignLowerRight. * * This option will tend to balance nodes compared to their neighbors. * @constant */ static AlignAll: number; } /** * This class represents an abstract graph of LayeredDigraphVertexes and LayeredDigraphEdges * that can be constructed based on the Nodes and Links of a Diagram * so that the LayeredDigraphLayout can operate independently of the diagram until it * is time to commit any node positioning or link routing. * * This class inherits from LayoutNetwork. * @extends LayoutNetwork * @unrestricted * @category Layout * @unindexed */ export class LayeredDigraphNetwork extends LayoutNetwork { constructor(layout: LayeredDigraphLayout); } /** * This holds LayeredDigraphLayout-specific information about Nodes. * * This class inherits from LayoutVertex. * @extends LayoutVertex * @unrestricted * @category Layout * @unindexed */ export class LayeredDigraphVertex extends LayoutVertex { constructor(network: LayeredDigraphNetwork); /** * @param {LayoutEdge} edge */ addSourceEdge(edge: LayoutEdge): void; /** * @param {LayoutEdge} edge */ deleteSourceEdge(edge: LayoutEdge): void; /** * @param {LayoutEdge} edge */ addDestinationEdge(edge: LayoutEdge): void; /** * @param {LayoutEdge} edge */ deleteDestinationEdge(edge: LayoutEdge): void; /** * Gets or sets the layer to which the node is assigned. * The default value is -1. */ get layer(): number; set layer(value: number); /** * Gets or sets the column to which the node is assigned. * The default value is -1. * * This property is not used during straightening and packing of nodes * when using LayeredDigraphLayout#alignOption. */ get column(): number; set column(value: number); /** * Gets or sets the index to which the node is assigned. * The default value is -1. */ get index(): number; set index(value: number); /** * Gets or sets the connected component to which the node is assigned. * The default value is NaN. * * This property is not used during straightening and packing of nodes * when using LayeredDigraphLayout#alignOption. */ get component(): number; set component(value: number); /** * Gets or sets another LayeredDigraphVertex in the same layer that this node should be near. * The default value is null. */ get near(): LayeredDigraphVertex; set near(value: LayeredDigraphVertex); } /** * This holds LayeredDigraphLayout-specific information about Links. * * This class inherits from LayoutEdge. * @extends LayoutEdge * @unrestricted * @category Layout * @unindexed */ export class LayeredDigraphEdge extends LayoutEdge { constructor(network: LayeredDigraphNetwork); /** * Gets or sets the LayoutVertex that this edge comes from. * Setting this property does not change any LayoutVertex#destinationEdges collection. */ get fromVertex(): LayeredDigraphVertex | null; set fromVertex(value: LayeredDigraphVertex | null); /** * Gets or sets the LayoutVertex that this edge goes to. * Setting this property does not change any LayoutVertex#sourceEdges collection. */ get toVertex(): LayeredDigraphVertex | null; set toVertex(value: LayeredDigraphVertex | null); /** * True if the link is part of the proper digraph. * The default value is false. */ get valid(): boolean; set valid(value: boolean); /** * True if the link was reversed during cycle removal. * The default value is false. */ get rev(): boolean; set rev(value: boolean); /** * True if the link is part of the depth first forest. * The default value is false. */ get forest(): boolean; set forest(value: boolean); /** * Location of the port at the from node of the link. * Allows the crossing matrix to correctly calculate the crossings for nodes with multiple ports. * The default value is NaN. * * This property is also used to align link ports when using LayeredDigraphLayout#alignOption. */ get portFromPos(): number; set portFromPos(value: number); /** * Location of the port at the to node of the link. * Allows the crossing matrix to correctly calculate the crossings for nodes with multiple ports. * The default value is NaN. * * This property is also used to align link ports when using LayeredDigraphLayout#alignOption. */ get portToPos(): number; set portToPos(value: number); /** * Approximate column offset of the from port of the link from the from node column used in straightening. * The default value is 0. */ get portFromColOffset(): number; set portFromColOffset(value: number); /** * Approximate column offset of the to port of the link from the to node column used in straightening. * The default value is 0. */ get portToColOffset(): number; set portToColOffset(value: number); } /** * This layout positions nodes of a tree-structured graph in layers (rows or columns). *

* For a discussion and examples of the most commonly used properties, see Trees page in the Introduction. * If you want to experiment interactively with most of the properties, try the Tree Layout sample. * See samples that make use of TreeLayout in the samples index. * * This layout makes use of a LayoutNetwork of * TreeVertexes and TreeEdges that normally * correspond to the Nodes and Links of the Diagram. * * The most commonly set properties for controlling the results of a TreeLayout are: * - #angle: the direction in which the tree grows, from parent to child; * the default value of zero means that the tree grows towards the right, with the children of a node arranged in a layer that is a column. * An angle of 0 or 180 means that children form vertical layers -- breadth is height and depth is width; * an angle of 90 or 270 means that children form horizontal layers -- breadth is width and depth is height. * - #layerSpacing: the distance between layers -- between a parent node and its child nodes. * - #nodeSpacing: the distance between nodes within a layer -- between siblings. * - #alignment: the relative position of a parent node with its children. * - #sorting and #comparer: specify the order of the immediate children of a parent node. * - #compaction: whether subtrees should be packed closer together if there is room. * - #layerStyle: whether the children of one node are aligned with the children of a sibling node. * - #setsPortSpot, #portSpot, #setsChildPortSpot, and #childPortSpot: this controls whether to set the Link#fromSpot and * Link#toSpot to be sensible for the #angle. * - #nodeIndent and #nodeIndentPastParent: if the #alignment is TreeLayout.AlignmentStart or TreeLayout.AlignmentEnd, * control how much extra space the first child is given when positioned. * - #breadthLimit, #rowSpacing: try to limit the total breadth of a subtree to a certain distance; * when there are too many children or when they are too broad, this puts children into additional rows (or columns, depending on the angle) * thereby limiting the breadth while increasing the depth of the tree. * * When you set one of the TreeLayout properties listed above, that property normally applies to all of the nodes in the tree. * What if you want #alignment to be TreeLayout.AlignmentCenterChildren for the root node but TreeLayout.AlignmentBus for the other nodes in the tree? * Or what if you want want #layerSpacing to be 50 for all layers except for the layer separating "leaf" nodes from their parent? * * One common solution is to set #treeStyle. * For the former scenario, you could set #treeStyle to TreeLayout.StyleRootOnly; the value of #alignment would only apply to the root node. * For the latter scenario, you could set it to TreeLayout.StyleLastParents; * the value of #layerSpacing would apply to all nodes except those that have children but that do not have grandchildren. * How do you then set the alignment or layerSpacing for the other nodes? * By setting the TreeLayout properties whose names start with "alternate...". * In these cases that would mean setting #alternateAlignment or #alternateLayerSpacing. * * These TreeLayout properties actually apply to the TreeVertex that the TreeLayout uses to represent a Node within the LayoutNetwork. * All of those TreeLayout properties are actually stored in #rootDefaults; all of the "alternate..." properties are stored in #alternateDefaults. * Depending on the value of #treeStyle, the actual TreeVertex properties for each Node are copied appropriately from either rootDefaults or alternateDefaults. * In the default case where treeStyle is TreeLayout.StyleLayered, the alternateDefaults are ignored. * (Note that treeStyle, and a few other properties such as #path and #arrangement, apply to the whole layout, not to an individual node/vertex.) * * The use of #treeStyle and "alternate..." TreeLayout properties will cover a lot of common needs for tree layout customization. * However, there may be times when that is not enough. * Imagine a situation where you want a special TreeVertex property value for a particular Node. * The solution is to override #assignTreeVertexValues, where you can examine the given TreeVertex, * including its corresponding LayoutVertex#node, to decide what TreeVertex property values should apply. * @extends Layout * @unrestricted * @category Layout */ export class TreeLayout extends Layout { /** * Constructs a TreeLayout with no Layout#network * and with no owning Layout#diagram. * @param {Partial=} init Optional initialization properties. */ constructor(init?: Partial); /** * Create a new LayoutNetwork of TreeVertexes and TreeEdges. * @return {TreeNetwork} a new LayoutNetwork. */ createNetwork(): TreeNetwork; /** * Create and initialize a LayoutNetwork with the given nodes and links. * * This does not include any nodes of category "Comment". * Comment nodes are added by the #addComments method. * @param {Diagram|Group|Iterable.} coll A Diagram or a Group or a collection of Parts. * @return {LayoutNetwork} */ makeNetwork(coll: Diagram | Group | Iterable): LayoutNetwork; /** * Perform the tree layout. * * If there is no Layout#network, this calls #makeNetwork to create a LayoutNetwork from the given collection of Parts. * * If there are no TreeVertex #roots specified, this finds all roots in the Layout#network. * * This initializes all of the TreeVertexes and TreeEdges, calling #initializeTreeVertexValues on each vertex, * supporting inheritance of vertex values. * Then it calls #assignTreeVertexValues on each one, to allow for node/vertex-specific customizations. * Next it sorts all of the child vertexes for each parent vertex, if needed. * * This also calls #addComments of each vertex, in order to find any comment nodes associated with each vertex, * so that they can be accommodated by the layout. * * This then actually does the "layout" of the vertexes and optionally the routing of the edges of each tree in the network. * To deal with multiple roots/trees this also calls #arrangeTrees to position each separate tree relative to each other. * * Finally this calls Layout#updateParts to commit the Node positions from the vertex positions and the Link routes from the edges. * Layout#updateParts calls #commitLayout within a transaction. * @param {Diagram|Group|Iterable.} coll A Diagram or a Group or a collection of Parts. */ doLayout(coll: Diagram | Group | Iterable): void; /** * Assign initial property values for a TreeVertex. * * The values may be inherited, so this method is called while * propagating values from the root nodes. * This method should not walk the tree, since it is called for each * TreeVertex in a depth-first manner starting at a root. * * You probably do not need to override this method, * but if you do you should call first either the base method * or TreeVertex#copyInheritedPropertiesFrom, since they * assign most of the TreeVertex property values * used to influence the layout. * Informational properties such as TreeVertex#descendantCount * and TreeVertex#maxGenerationCount will not yet have been initialized * by the time this method is called. * It is more common to override #assignTreeVertexValues in order to * modify a property or two to customize the layout at that node. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * * When the TreeVertex#alignment is TreeLayout.AlignmentBusBranching, * this will modify the TreeVertex#angle appropriately depending on which * side of the bus the vertex is on. * @expose * @param {TreeVertex} v * @since 1.2 */ initializeTreeVertexValues(v: TreeVertex): void; /** * Assign final property values for a TreeVertex. * * This method is commonly overridden in order to provide * tree layout properties for particular nodes. * This method is called after values have been inherited from other * TreeVertexes, so you can examine and modify the * values of related tree nodes. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * * However, when TreeVertex#alignment is TreeLayout.AlignmentBusBranching, * changing the TreeVertex#sorting or * TreeVertex#comparer properties in this method will have no effect. * * This method should not walk the tree, since it is called for each * TreeVertex in a depth-first manner starting at a root. * * Here is an example where the children are squeezed together if there are many of them, * but only on nodes that have no grandchildren. This makes use of two TreeVertex * properties that are automatically computed for you, TreeVertex#childrenCount and TreeVertex#descendantCount. * ```js * function SqueezingTreeLayout() { * go.TreeLayout.call(this); * } * go.Diagram.inherit(SqueezingTreeLayout, go.TreeLayout); * * public assignTreeVertexValues(v) { * if (v.childrenCount > 6 && v.childrenCount === v.descendantCount) { * v.alignment = go.TreeLayout.AlignmentBottomRightBus; * v.layerSpacing = 10; * v.rowSpacing = 0; * } * } * ``` * * If you need to assign TreeVertex values and also have them be "inherited" by the child vertexes, * you should override #initializeTreeVertexValues instead. * However at the time that method is called, the computed properties of TreeVertex will not be available. * @expose * @param {TreeVertex} v * @since 1.1 */ assignTreeVertexValues(v: TreeVertex): void; /** * Find any associated objects to be positioned along with the LayoutVertex#node. * * This looks for visible Node's whose category is "Comment" and * that refer to the tree vertex's Node. * This method is only called when #comments is true. * * You may want to override this method in order to customize how * any associated objects are found and how the node's LayoutVertex#bounds * are set to reserve space for those associated objects. * This method should not walk the tree, since it is called for each * TreeVertex in an indeterminate order. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {TreeVertex} v * @since 1.2 */ addComments(v: TreeVertex): void; /** * Position and TreeVertex#comments around the vertex. * * This method should not walk the tree, since it is called for each * TreeVertex in an indeterminate order. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @param {TreeVertex} v * @since 1.2 */ layoutComments(v: TreeVertex): void; /** * (Undocumented) * @expose * @param v * @param offx * @param offy * @param subw * @param subh * @returns */ customAlignment(v: TreeVertex, offx: number, offy: number, subw: number, subh: number): Array; /** * Get the amount of space to insert between a child vertex and its parent spine * when the parent's TreeVertex#alignment is Bus or BusBranching. * * This function is called on each child vertex to determine the initial distance of a child * from the spine that connects to its parent vertex. * This function is not called on the last odd child * because that vertex is placed at the end of the spine rather than to either side. * @expose * @param {TreeVertex} child * @return {number} By default this returns the parent's TreeVertex#nodeSpacing; * a small value may result in unpleasant routing of links, * a negative value may cause the node overlaps. */ computeBusNodeSpacing(child: TreeVertex): number; /** * Get the amound of space to leave between the sibling child vertexes and this last odd vertex * when the parent's TreeVertex#alignment is Bus or BusBranching. * * This function is called only when there is an odd number of child vertexes. * This function is not called when the parent vertex only has one child. * In that case there is no spine separating the two columns of child vertexes. * @expose * @param {TreeVertex} lastchild * @param {number} dist the length of the central line (spine) separating the two sides, * so far excluding the initial TreeVertex#nodeSpacing * that extends form the parent's spine. * @return {number} By default this returns the parent's TreeVertex#rowSpacing; * a negative value may cause node overlaps. */ computeBusLastRowSpacing(lastchild: TreeVertex, dist: number): number; /** * Position each separate tree. * * This is called after each tree has been laid out and thus each subtree * bounds are known. * The #arrangement and #arrangementSpacing and Layout#arrangementOrigin * properties affect this method's behavior. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose * @since 1.2 */ arrangeTrees(): void; /** * Set the fromSpot and toSpot on each Link, position each Node according * to the vertex position, and then position/route the Links. * * This calls the #commitNodes and #commitLinks methods, the latter only if #isRouting is true. * You should not call this method -- it is a "protected virtual" method. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. */ protected commitLayout(): void; /** * Commit the position of all nodes. * * This is called by #commitLayout. * See also #commitLinks. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ protected commitNodes(): void; /** * This overridable method is called by #commitLayout * if #layerStyle is LayerUniform * to support custom arrangement of bands or labels across each layout layer. * By default this method does nothing. * * The coordinates used in the resulting Rects may need to be offset by the Layout#arrangementOrigin * and/or by the arrangement of subtrees done by #arrangeTrees. * @expose * @param {Array.} layerRects an Array of Rects with the bounds of each of the "layers" * @param {Point} offset the position of the top-left corner of the banded area relative to the coordinates given by the layerRects * @since 1.4 */ protected commitLayers(layerRects: Array, offset: Point): void; /** * Routes the links. * * This is called by #commitLayout. * This is only called if Layout#isRouting is true. * See also #commitNodes. * Please read the Introduction page on Extensions for how to override methods and how to call this base method. * @expose */ protected commitLinks(): void; /** * @expose * @param {TreeVertex} v * @return {number} */ computeLayerSpacing(v: TreeVertex): number; /** * @expose * @param {TreeVertex} v * @return {number} */ computeNodeIndent(v: TreeVertex): number; /** * Gets or sets the collection of root vertexes. * * Initially this will be an empty Set. * * If the #path is either TreeLayout.PathDestination|PathDestination or * TreeLayout.PathSource|PathSource, this layout can easily * determine all of the tree roots by searching the whole network. * Otherwise, you should explicitly initialize this collection * with one or more TreeVertexes. */ get roots(): Set<(TreeVertex | Node)>; set roots(value: Set<(TreeVertex | Node)>); /** * Gets or sets how the tree should be constructed from the * TreeEdges connecting TreeVertexes. * Must be TreeLayout.PathDestination or TreeLayout.PathSource or TreeLayout.PathDefault. * * The default value is TreeLayout.PathDefault, * where the value of Diagram#isTreePathToChildren determines the effective value of this property. */ get path(): EnumValue; set path(value: EnumValue); /** * Gets or sets the Style for the resulting trees. * Must be TreeLayout.StyleLayered, TreeLayout.StyleAlternating, * TreeLayout.StyleLastParents, or TreeLayout.StyleRootOnly. * * The default value is TreeLayout.StyleLayered. */ get treeStyle(): EnumValue; set treeStyle(value: EnumValue); /** * Gets or sets the manner in which the nodes are aligned in layers. * Must be TreeLayout.LayerIndividual, TreeLayout.LayerSiblings, * or TreeLayout.LayerUniform. * * The default value is TreeLayout.LayerIndividual. * @since 1.4 */ get layerStyle(): EnumValue; set layerStyle(value: EnumValue); /** * Gets or sets whether this layout should find all Nodes * whose category is "Comment" and * whose anchors are nodes represented in the network, * and increase the size of the corresponding TreeVertex to make room for the comment nodes. * The default value is true. * @since 1.3 */ get comments(): boolean; set comments(value: boolean); /** * Gets or sets how #arrangeTrees should lay out the separate trees. * Must be TreeLayout.ArrangementVertical, TreeLayout.ArrangementHorizontal, * or TreeLayout.ArrangementFixedRoots. * * The default value is TreeLayout.ArrangementVertical */ get arrangement(): EnumValue; set arrangement(value: EnumValue); /** * Gets or sets the space between which #arrangeTrees will position the trees. * * This defaults to the Size(10, 10). * * This property is ignored if #arrangement is TreeLayout.ArrangementFixedRoots. */ get arrangementSpacing(): Size; set arrangementSpacing(value: Size); /** * Gets or sets the object holding the default values for root TreeVertexes. * * The values for the following inheritable properties are actually stored in this object: * #sorting, #comparer, #angle, * #alignment, #nodeIndent, #nodeIndentPastParent, * #nodeSpacing, #layerSpacing, #layerSpacingParentOverlap, * #compaction, #breadthLimit, #rowSpacing, #rowIndent, * #commentSpacing, #commentMargin, * #setsPortSpot, #portSpot, #setsChildPortSpot, #childPortSpot. * The other properties of this TreeVertex are ignored. */ get rootDefaults(): TreeVertex; set rootDefaults(value: TreeVertex); /** * Gets or sets the object holding the default values for alternate layer TreeVertexes, * used when the #treeStyle is TreeLayout.StyleAlternating|StyleAlternating or TreeLayout.StyleLastParents|StyleLastParents. * * See the list of inheritable properties in the documentation for #rootDefaults. * The other properties of this TreeVertex are ignored. */ get alternateDefaults(): TreeVertex; set alternateDefaults(value: TreeVertex); /** * Gets or sets the default sorting policy for ordering the immediate children of a vertex. * Must be TreeLayout.SortingForwards, TreeLayout.SortingReverse, * TreeLayout.SortingAscending, or TreeLayout.SortingDescending. * * The default value is TreeLayout.SortingForwards. * * This sets the #rootDefaults' property of the same name. * The sort order is determined by #comparer. */ get sorting(): EnumValue; set sorting(value: EnumValue); /** * Gets or sets the default comparison function used for sorting the immediate children of a vertex. * * The default comparer compares the LayoutVertex#node Text values. * * This sets the #rootDefaults' property of the same name. * Whether this comparison function is used is determined by the value of #sorting. * ```js * $(go.TreeLayout, * { * sorting: go.TreeLayout.SortingAscending, * comparer: (va, vb) => { * var da = va.node.data; * var db = vb.node.data; * if (da.someProperty < db.someProperty) return -1; * if (da.someProperty > db.someProperty) return 1; * return 0; * } * } * ) * ``` */ get comparer(): ((a: TreeVertex, b: TreeVertex) => number); set comparer(value: ((a: TreeVertex, b: TreeVertex) => number)); /** * Gets or sets the default direction for tree growth. * * The default value is 0; the value must be one of: 0, 90, 180, 270. * * These values are in degrees, where 0 is along the positive X axis, * and where 90 is along the positive Y axis. * * This sets the #rootDefaults' property of the same name. */ get angle(): number; set angle(value: number); /** * Gets or sets the default alignment of parents relative to their children. * Must be a static constant of TreeLayout whose name starts with "Alignment". * * The default value is TreeLayout.AlignmentCenterChildren. * * This sets the #rootDefaults' property of the same name. */ get alignment(): EnumValue; set alignment(value: EnumValue); /** * Gets or sets the default indentation of the first child. * * The default value is zero. The value should be non-negative. * * This property is only sensible when the #alignment * is TreeLayout.AlignmentStart|AlignmentStart or TreeLayout.AlignmentEnd|AlignmentEnd. * Having a positive value is useful if you want to reserve space * at the start of the row of children for some reason. * For example, if you want to pretend the parent node is infinitely deep, * you can set this to be the breadth of the parent node. * * This sets the #rootDefaults' property of the same name. */ get nodeIndent(): number; set nodeIndent(value: number); /** * Gets or sets the fraction of this node's breadth is added to #nodeIndent * to determine any spacing at the start of the children. * * The default value is 0.0 -- the only indentation is specified by #nodeIndent. * When the value is 1.0, the children will be indented past the breadth of the parent node. * * This property is only sensible when the #alignment * is TreeLayout.AlignmentStart|AlignmentStart or TreeLayout.AlignmentEnd|AlignmentEnd. * * This sets the #rootDefaults' property of the same name. */ get nodeIndentPastParent(): number; set nodeIndentPastParent(value: number); /** * Gets or sets the distance between child nodes. * * This is the distance between sibling nodes. * A negative value causes sibling nodes to overlap. * The default value is 20. * * The #layerSpacing property determines the distance between a parent node and the layer of its children. * * This sets the #rootDefaults' property of the same name. */ get nodeSpacing(): number; set nodeSpacing(value: number); /** * Gets or sets the distance between a parent node and its children. * * This is the distance between a parent node and the layer of its children. * Negative values may cause children to overlap with the parent. * The default value is 50. * * The #nodeSpacing property determines the distance between siblings. * The #rowSpacing property determines the distance * between multiple rows or columns of children. * * This sets the #rootDefaults' property of the same name. */ get layerSpacing(): number; set layerSpacing(value: number); /** * Gets or sets the fraction of the node's depth for which the children's layer starts overlapped with the parent's layer. * * The default value is 0.0 -- there is overlap between layers only if #layerSpacing is negative. * A value of 1.0 and a zero #layerSpacing will cause child nodes to completely overlap the parent. * * A value greater than zero may still cause overlap between layers, * unless the value of #layerSpacing is large enough. * A value of zero might still allow overlap between layers, * if #layerSpacing is negative. * * This sets the #rootDefaults' property of the same name. */ get layerSpacingParentOverlap(): number; set layerSpacingParentOverlap(value: number); /** * Gets or sets how closely to pack the child nodes of a subtree. * Must be either TreeLayout.CompactionBlock or TreeLayout.CompactionNone. * * The default value is TreeLayout.CompactionBlock|CompactionBlock. * * This sets the #rootDefaults' property of the same name. */ get compaction(): EnumValue; set compaction(value: EnumValue); /** * Gets or sets a limit on how broad a tree should be. * * A value of zero (the default) means there is no limit; * a positive value specifies a limit. * The default value is zero. * * This property is just a suggested constraint on how * broadly the tree will be laid out. * When there isn't enough breadth for all of the children of a node, * the children are placed in as many rows as needed to try to stay * within the given breadth limit. * If the value is too small, since this layout algorithm * does not modify the size or shape of any node, the nodes will * just be laid out in a line, one per row, and the breadth is * determined by the broadest node. * The distance between rows is specified by #rowSpacing. * To make room for the links that go around earlier rows to get to * later rows, when the alignment is not a "center" alignment, the * #rowIndent property specifies that space at the * start of each row. * * This sets the #rootDefaults' property of the same name. */ get breadthLimit(): number; set breadthLimit(value: number); /** * Gets or sets the distance between rows or columns of a parent node's immediate children. * * The default value is 25. * * This property is only used when there is more than one * row of children for a given parent node. * The #nodeSpacing property determines the distance between siblings. * The #layerSpacing property determines the distance between * the parent node and its first row or column of child nodes. * * This sets the #rootDefaults' property of the same name. */ get rowSpacing(): number; set rowSpacing(value: number); /** * Gets or sets the default indentation of the first child of each row, * if the #alignment is not a "Center" alignment. * * The default value is 10. The value should be non-negative. * * This is used to leave room for the links that connect a parent node * with the child nodes that are in additional rows. * * This sets the #rootDefaults' property of the same name. */ get rowIndent(): number; set rowIndent(value: number); /** * Gets or sets the distance between comments. * * The default value is 10. * * This is used by #addComments and #layoutComments. * * This sets the #rootDefaults' property of the same name. */ get commentSpacing(): number; set commentSpacing(value: number); /** * Gets or sets the distance between a node and its comments. * * The default value is 20. * * This is used by #addComments and #layoutComments. * * This sets the #rootDefaults' property of the same name. */ get commentMargin(): number; set commentMargin(value: number); /** * Gets or sets whether the TreeLayout should set the * FromSpot for this parent node port. * * The default value is true -- this may modify the spot of the port of this node, the parent, * if the node has only a single port. * * The spot used depends on the value of #portSpot. * * This sets the #rootDefaults' property of the same name. */ get setsPortSpot(): boolean; set setsPortSpot(value: boolean); /** * Gets or sets the spot that this node's port gets as its FromSpot. * * The default value is Spot.Default. * * A value of Spot.Default will cause the TreeLayout * to assign a FromSpot based on the parent node's TreeVertex#angle. * If the value is other than NoSpot, it is just assigned. * When #path is TreeLayout.PathSource|PathSource, * the port's ToSpot is set instead of the FromSpot. * * This sets the #rootDefaults' property of the same name. */ get portSpot(): Spot; set portSpot(value: Spot); /** * Gets or sets whether the TreeLayout should set the * ToSpot for each child node port. * * The default value is true -- this may modify the spot of the ports of the children nodes, * if the node has only a single port. * * The spot used depends on the value of #childPortSpot. * * This sets the #rootDefaults' property of the same name. */ get setsChildPortSpot(): boolean; set setsChildPortSpot(value: boolean); /** * Gets or sets the spot that children nodes' ports get as their ToSpot. * * The default value is Spot.Default. * * A value of Spot.Default will cause the TreeLayout * to assign a ToSpot based on the parent node's TreeVertex#angle. * If the value is other than NoSpot, it is just assigned. * When #path is TreeLayout.PathSource|PathSource, * the port's FromSpot is set instead of the ToSpot. * * This sets the #rootDefaults' property of the same name. */ get childPortSpot(): Spot; set childPortSpot(value: Spot); /** * Gets or sets the alternate sorting policy for ordering the immediate children of a vertex. * Must be TreeLayout.SortingForwards, TreeLayout.SortingReverse, * TreeLayout.SortingAscending, or TreeLayout.SortingDescending. * * The default value is TreeLayout.SortingForwards|SortingForwards. * * This sets the #alternateDefaults' property of the same name. * The sort order is determined by #alternateComparer. */ get alternateSorting(): EnumValue; set alternateSorting(value: EnumValue); /** * Gets or sets the alternate comparison function used for sorting the immediate children of a vertex. * * The default comparer compares the LayoutVertex#node Text values. * * This sets the #alternateDefaults' property of the same name. * Whether this comparison function is used is determined by the value of #alternateSorting. */ get alternateComparer(): ((a: TreeVertex, b: TreeVertex) => number); set alternateComparer(value: ((a: TreeVertex, b: TreeVertex) => number)); /** * Gets or sets the alternate direction for tree growth. * * The default value is 0; the value must be one of: 0, 90, 180, 270. * * These values are in degrees, where 0 is along the positive X axis, * and where 90 is along the positive Y axis. * This sets the #alternateDefaults' property of the same name. */ get alternateAngle(): number; set alternateAngle(value: number); /** * Gets or sets the alternate alignment of parents relative to their children. * Must be a static constant of TreeLayout whose name starts with "Alignment". * * The default value is TreeLayout.AlignmentCenterChildren. * * This sets the #alternateDefaults' property of the same name. */ get alternateAlignment(): EnumValue; set alternateAlignment(value: EnumValue); /** * Gets or sets the alternate indentation of the first child. * * The default value is zero. The value should be non-negative. * * This property is only sensible when the #alignment * is TreeLayout.AlignmentStart|AlignmentStart or TreeLayout.AlignmentEnd|AlignmentEnd. * Having a positive value is useful if you want to reserve space * at the start of the row of children for some reason. * For example, if you want to pretend the parent node is infinitely deep, * you can set this to be the breadth of the parent node. * This sets the #alternateDefaults' property of the same name. */ get alternateNodeIndent(): number; set alternateNodeIndent(value: number); /** * Gets or sets the fraction of this node's breadth is added to #alternateNodeIndent * to determine any spacing at the start of the children. * * The default value is 0.0 -- the only indentation is specified by #alternateNodeIndent. * When the value is 1.0, the children will be indented past the breadth of the parent node. * * This property is only sensible when the #alignment * is TreeLayout.AlignmentStart|AlignmentStart or TreeLayout.AlignmentEnd|AlignmentEnd. */ get alternateNodeIndentPastParent(): number; set alternateNodeIndentPastParent(value: number); /** * Gets or sets the alternate distance between child nodes. * * The default value is 20. * * A negative value causes sibling nodes to overlap. * This sets the #alternateDefaults' property of the same name. */ get alternateNodeSpacing(): number; set alternateNodeSpacing(value: number); /** * Gets or sets the alternate distance between a parent node and its children. * * The default value is 50. * * This is the distance between a parent node and its first row * of children, in case there are multiple rows of its children. * The #alternateNodeSpacing property determines the distance between siblings. * The #alternateRowSpacing property determines the distance * between rows of children. * Negative values may cause children to overlap with the parent. * This sets the #alternateDefaults' property of the same name. */ get alternateLayerSpacing(): number; set alternateLayerSpacing(value: number); /** * Gets or sets the alternate fraction of the node's depth for which the children's layer starts overlapped with the parent's layer. * * The default value is 0.0 -- there is overlap between layers only if #alternateLayerSpacing is negative. * A value of 1.0 and a zero #alternateLayerSpacing will cause child nodes to completely overlap the parent. * * A value greater than zero may still cause overlap between layers, * unless the value of #alternateLayerSpacing is large enough. * A value of zero might still allow overlap between layers, * if #alternateLayerSpacing is negative. * This sets the #alternateDefaults' property of the same name. */ get alternateLayerSpacingParentOverlap(): number; set alternateLayerSpacingParentOverlap(value: number); /** * Gets or sets how closely to pack the child nodes of a subtree. * Must be either TreeLayout.CompactionBlock or TreeLayout.CompactionNone. * * The default value is TreeLayout.CompactionBlock. * * This sets the #alternateDefaults' property of the same name. */ get alternateCompaction(): EnumValue; set alternateCompaction(value: EnumValue); /** * Gets or sets an alternate limit on how broad a tree should be. * * A value of zero (the default) means there is no limit; * a positive value specifies a limit. * The default value is zero. * * This property is just a suggested constraint on how * broadly the tree will be laid out. * When there isn't enough breadth for all of the children of a node, * the children are placed in as many rows as needed to try to stay * within the given breadth limit. * If the value is too small, since this layout algorithm * does not modify the size or shape of any node, the nodes will * just be laid out in a line, one per row, and the breadth is * determined by the broadest node. * The distance between rows is specified by #alternateRowSpacing. * To make room for the links that go around earlier rows to get to * later rows, when the alignment is not a "center" alignment, the * #alternateRowIndent property specifies that space at the * start of each row. * This sets the #alternateDefaults' property of the same name. */ get alternateBreadthLimit(): number; set alternateBreadthLimit(value: number); /** * Gets or sets the alternate distance between rows of children. * * The default value is 25. * * This property is only used when there is more than one * row of children for a given parent node. * The #alternateLayerSpacing property determines the distance between * the parent node and its first row of child nodes. * This sets the #alternateDefaults' property of the same name. */ get alternateRowSpacing(): number; set alternateRowSpacing(value: number); /** * Gets or sets the alternate indentation of the first child of each row, * if the #alignment is not a "Center" alignment. * * The default value is 10. The value should be non-negative. * * This is used to leave room for the links that connect a parent node * with the child nodes that are in additional rows. * This sets the #alternateDefaults' property of the same name. */ get alternateRowIndent(): number; set alternateRowIndent(value: number); /** * Gets or sets the alternate distance between comments. * * The default value is 10. * * This is used by #addComments and #layoutComments. * This sets the #alternateDefaults' property of the same name. */ get alternateCommentSpacing(): number; set alternateCommentSpacing(value: number); /** * Gets or sets the alternate distance between a node and its comments. * * The default value is 20. * * This is used by #addComments and #layoutComments. * This sets the #alternateDefaults' property of the same name. */ get alternateCommentMargin(): number; set alternateCommentMargin(value: number); /** * Gets or sets whether the TreeLayout should set the * FromSpot for this parent node port. * * The default value is true -- this may modify the spot of the port of this node, the parent, * if the node has only a single port. * * The spot used depends on the value of #alternatePortSpot. * This sets the #alternateDefaults' property of the same name. */ get alternateSetsPortSpot(): boolean; set alternateSetsPortSpot(value: boolean); /** * Gets or sets the alternate spot that this node's port gets as its FromSpot. * * The default value is Spot.Default. * * A value of Spot.Default will cause the TreeLayout * to assign a FromSpot based on the parent node's TreeVertex#angle. * If the value is other than NoSpot, it is just assigned. * When #path is TreeLayout.PathSource|PathSource, * the port's ToSpot is set instead of the FromSpot. * This sets the #alternateDefaults' property of the same name. */ get alternatePortSpot(): Spot; set alternatePortSpot(value: Spot); /** * Gets or sets whether the TreeLayout should set the * ToSpot for each child node port. * * The default value is true -- this may modify the spot of the ports of the children nodes, * if the node has only a single port. * * The spot used depends on the value of #alternateChildPortSpot. * This sets the #alternateDefaults' property of the same name. */ get alternateSetsChildPortSpot(): boolean; set alternateSetsChildPortSpot(value: boolean); /** * Gets or sets the alternate spot that children nodes' ports get as their ToSpot * The default value is Spot.Default. * * A value of Spot.Default will cause the TreeLayout * to assign a ToSpot based on the parent node's TreeVertex#angle. * * If the value is other than NoSpot, it is just assigned. * When #path is TreeLayout.PathSource|PathSource, * the port's FromSpot is set instead of the ToSpot. * This sets the #alternateDefaults' property of the same name. */ get alternateChildPortSpot(): Spot; set alternateChildPortSpot(value: Spot); /** * This value for TreeLayout#path causes the value of Diagram#isTreePathToChildren * to effectively choose either TreeLayout.PathDestination (if true) or TreeLayout.PathSource (if false). * @constant */ static PathDefault: EnumValue; /** * The children of a TreeVertex are its LayoutVertex#destinationVertexes, * the collection of connected LayoutEdge#toVertexes; * this value is used for TreeLayout#path. * * The tree roots are those TreeVertexes that have zero source edges. * @constant */ static PathDestination: EnumValue; /** * The children of a TreeVertex are its LayoutVertex#sourceVertexes, * the collection of connected LayoutEdge#fromVertexes; * this value is used for TreeLayout#path. * * The tree roots are those TreeVertexes that have zero destination edges. * @constant */ static PathSource: EnumValue; /** * Lay out each child in the order in which they were found; * this value is used for TreeLayout#sorting or TreeLayout#alternateSorting. * @constant */ static SortingForwards: EnumValue; /** * Lay out each child in reverse order from which they were found; * this value is used for TreeLayout#sorting or TreeLayout#alternateSorting. * @constant */ static SortingReverse: EnumValue; /** * Lay out each child according to the sort order given by TreeVertex#comparer; * this value is used for TreeLayout#sorting or TreeLayout#alternateSorting. * @constant */ static SortingAscending: EnumValue; /** * Lay out each child in reverse sort order given by TreeVertex#comparer; * this value is used for TreeLayout#sorting or TreeLayout#alternateSorting. * @constant */ static SortingDescending: EnumValue; /** * The parent is centered at the middle of the range of its child subtrees; * this value is used for TreeLayout#alignment or TreeLayout#alternateAlignment. * * When there is a breadth limit that causes there to be multiple rows, * the links that extend from the parent to those children in rows past * the first one may cross over the nodes that are in earlier rows. * @constant */ static AlignmentCenterSubtrees: EnumValue; /** * The parent is centered at the middle of the range of its immediate child nodes; * this value is used for TreeLayout#alignment or TreeLayout#alternateAlignment. * * When there is a breadth limit that causes there to be multiple rows, * the links that extend from the parent to those children in rows past * the first one may cross over the nodes that are in earlier rows. * @constant */ static AlignmentCenterChildren: EnumValue; /** * The parent is positioned near the first of its children; * this value is used for TreeLayout#alignment or TreeLayout#alternateAlignment. * @constant */ static AlignmentStart: EnumValue; /** * The parent is positioned near the last of its children; * this value is used for TreeLayout#alignment or TreeLayout#alternateAlignment. * @constant */ static AlignmentEnd: EnumValue; /** * The children are positioned in a bus on both sides of an "aisle" where the links to them go, * with the last odd child (if any) placed at the end of the aisle in the middle; * this value is used for TreeLayout#alignment or TreeLayout#alternateAlignment. * * The children, if they are themselves parents, continue at the same inherited angle; * use TreeLayout.AlignmentBusBranching if you want grandchildren to proceed growing in * the different angle as determined by the side. * * A bus does not take TreeVertex#breadthLimit into account. * @constant */ static AlignmentBus: EnumValue; /** * Like TreeLayout.AlignmentBus with the children arranged on both sides of an "aisle" * with any last odd child placed at the end of the aisle, * but the children get an TreeVertex#angle that depends on which side of the aisle * they were placed; * this value is used for TreeLayout#alignment or TreeLayout#alternateAlignment. * * This only works well when the TreeLayout#treeStyle is TreeLayout.StyleLayered. * * A bus does not take TreeVertex#breadthLimit into account. * @constant */ static AlignmentBusBranching: EnumValue; /** * The children are positioned in a bus, only on the top or left side of the parent; * this value is used for TreeLayout#alignment or TreeLayout#alternateAlignment. * * A bus does not take TreeVertex#breadthLimit into account. * @constant */ static AlignmentTopLeftBus: EnumValue; /** * The children are positioned in a bus, only on the bottom or right side of the parent; * this value is used for TreeLayout#alignment or TreeLayout#alternateAlignment. * * A bus does not take TreeVertex#breadthLimit into account. * @constant */ static AlignmentBottomRightBus: EnumValue; /** * Only simple placement of children next to each other, as determined by their subtree breadth; * this value is used for TreeLayout#compaction or TreeLayout#alternateCompaction. * * For any node, there will not be another node at any depth occupying the same breadth position, * unless there are multiple rows; In other words, if there is no breadth limit resulting in * multiple rows, with this compaction mode it is as if every node were infinitely deep. * @constant */ static CompactionNone: EnumValue; /** * A simple fitting of subtrees; * this value is used for TreeLayout#compaction or TreeLayout#alternateCompaction. * * This mode produces more compact trees -- often nicer looking too; * Nodes will not overlap each other, unless you have negative values * for some of the spacing properties; * However it is possible when the links are orthogonally styled that * occasionally the subtrees will be placed so close together that some * links may overlap the links or even the nodes of other subtrees. * @constant */ static CompactionBlock: EnumValue; /** * The normal tree style, where all of the children of each TreeVertex are lined up * horizontally or vertically; * this value is used for TreeLayout#treeStyle. * * Each TreeVertex gets its properties from its parent node; * TreeLayout#rootDefaults is used for all default TreeVertex property values; * TreeLayout#alternateDefaults is ignored. * @constant */ static StyleLayered: EnumValue; /** * Just like the standard layered tree style, except that the nodes with children but no grandchildren * have alternate properties; * this value is used for TreeLayout#treeStyle. * * Each TreeVertex gets its properties from its parent node; * However, for those nodes whose TreeVertex#maxGenerationCount is 1, * in other words when it has children but no grandchildren, * the properties are copied from TreeLayout#alternateDefaults. * * If the tree only has two levels, the root node gets the TreeLayout#rootDefaults. * @constant */ static StyleLastParents: EnumValue; /** * Alternate layers of the tree have different properties, typically including the angle; * this value is used for TreeLayout#treeStyle. * * Each TreeVertex gets its properties from its grandparent node; * The root nodes get their defaults from TreeLayout#rootDefaults. * * The immediate children of root nodes get their defaults from TreeLayout#alternateDefaults. * * Depending on the properties used, it is possible for some link routes to cross over nodes. * @constant */ static StyleAlternating: EnumValue; /** * All of the nodes get the alternate properties, except the root node gets the default properties; * this value is used for TreeLayout#treeStyle. * * The root node gets the TreeLayout#rootDefaults properties, * the root node's children get the TreeLayout#alternateDefaults properties, * and all the rest of the TreeVertexes get their properties from their parent node. * @constant */ static StyleRootOnly: EnumValue; /** * Position each tree in a non-overlapping fashion by increasing Y coordinates, * starting at the Layout#arrangementOrigin; * this value is used for TreeLayout#arrangement. * @constant */ static ArrangementVertical: EnumValue; /** * Position each tree in a non-overlapping fashion by increasing X coordinates, * starting at the Layout#arrangementOrigin; * this value is used for TreeLayout#arrangement. * @constant */ static ArrangementHorizontal: EnumValue; /** * Do not move each root node, but position all of their descendants relative to their root; * this value is used for TreeLayout#arrangement. * @constant */ static ArrangementFixedRoots: EnumValue; /** * The normal layer style, where each node takes up only the depth that it needs; * this value is used for TreeLayout#layerStyle. * @constant * @since 1.4 */ static LayerIndividual: EnumValue; /** * A layer style where all of the children of a parent node take up the same amount of depth -- * this typically causes all cousins to be aligned; * this value is used for TreeLayout#layerStyle. * @constant * @since 1.4 */ static LayerSiblings: EnumValue; /** * A layer style where all nodes with the same TreeVertex#level throughout the tree take up the same amount of depth -- * if the TreeVertex#angle is the same for all nodes, this will result in all nodes in the same layer to be aligned; * this value is used for TreeLayout#layerStyle. * @constant * @since 1.4 */ static LayerUniform: EnumValue; } /** * This class represents an abstract graph of TreeVertexes and TreeEdges * that can be constructed based on the Nodes and Links of a Diagram * so that the TreeLayout can operate independently of the diagram until it * is time to commit any node positioning or link routing. * * This class inherits from LayoutNetwork. * @extends LayoutNetwork * @unrestricted * @category Layout * @unindexed */ export class TreeNetwork extends LayoutNetwork { constructor(layout: TreeLayout); } /** * This holds TreeLayout-specific information about Nodes. * * This class inherits from LayoutVertex. * @extends LayoutVertex * @unrestricted * @category Layout * @unindexed */ export class TreeVertex extends LayoutVertex { constructor(network: TreeNetwork); /** * Copy inherited properties from another TreeVertex to this one. * @expose * @param {TreeVertex} copy */ copyInheritedPropertiesFrom(copy: TreeVertex): void; /** * Gets or sets whether this node has been initialized as part of TreeLayout#doLayout when building the tree structures. * * The default value is false. */ get initialized(): boolean; set initialized(value: boolean); /** * Gets or sets the logical parent for this node. * * The default value is null. * * This structural property is computed in TreeLayout#doLayout when building the tree structures. * You should probably not be setting this property. */ get parent(): TreeVertex; set parent(value: TreeVertex); /** * Gets or sets the logical children for this node. * * The default value is an empty array. * * This structural property is computed in TreeLayout#doLayout when building the tree structures. * You should probably not be setting this property. */ get children(): Array; set children(value: Array); /** * Gets or sets the number of single-parent ancestors this node has. * * This could also be interpreted as which layer this node is in. * A root node will have a value of zero. * * This informational property is computed in TreeLayout#doLayout when building the tree structures. * You should probably not be setting this property. */ get level(): number; set level(value: number); /** * Gets or sets the number of descendants this node has. * * For a leaf node, this will be zero. * * This informational property is computed as part of the TreeLayout#initializeTreeVertexValues pass. * You should probably not be setting this property. */ get descendantCount(): number; set descendantCount(value: number); /** * Gets or sets the maximum number of children of any descendant of this node. * * For a leaf node, this will be zero. * * This informational property is computed as part of the TreeLayout#initializeTreeVertexValues pass. * You should probably not be setting this property. */ get maxChildrenCount(): number; set maxChildrenCount(value: number); /** * Gets or sets the maximum depth of the subtrees below this node. * * For a leaf node, this will be zero. * * This informational property is computed as part of the TreeLayout#initializeTreeVertexValues pass. * You should probably not be setting this value. */ get maxGenerationCount(): number; set maxGenerationCount(value: number); /** * Gets or sets an array of Nodes that will be positioned near this node. * * The default value is null. * * These objects should not have their own TreeVertexes to be laid out. * Typically these will be Nodes whose Category is "Comment". * This array should be allocated and initialized in TreeLayout#addComments. */ get comments(): Array; set comments(value: Array); /** * Gets or sets whether and in what order the children should be sorted. * * The default value is TreeLayout.SortingForwards. * * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. */ get sorting(): EnumValue; set sorting(value: EnumValue); /** * Gets or sets how the children should be sorted. * * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. */ get comparer(): ((a: TreeVertex, b: TreeVertex) => number); set comparer(value: ((a: TreeVertex, b: TreeVertex) => number)); /** * Gets or sets the absolute angle at which this subtree should grow from this vertex. * * The default value is zero, meaning that general tree growth should proceed rightwards along the X axis. * * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. * By default this is the same as the Angle of the parent TreeVertex. * However, after the initial propagation of property values, perhaps in * an override of TreeLayout#assignTreeVertexValues, * you could just set this property to specify the angle at which this node grows its subtrees. */ get angle(): number; set angle(value: number); /** * Gets or sets how this parent node should be aligned relative to its children. * * The default value is TreeLayout.AlignmentCenterChildren. * * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. */ get alignment(): EnumValue; set alignment(value: EnumValue); /** * Gets or sets the distance the first child should be indented. * * The default value is zero. The value should be non-negative. * * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. * This property is only sensible when the #alignment is * TreeLayout.AlignmentStart or TreeLayout.AlignmentEnd. */ get nodeIndent(): number; set nodeIndent(value: number); /** * Gets or sets whether the first child should be indented past the parent node's breadth. * * The default value is 0.0 -- the only start or end spacing is provided by #nodeIndent. * Values must range from 0.0 to 1.0, where 1.0 means the full breadth of this node. * * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. * This property is only sensible when the #alignment is * TreeLayout.AlignmentStart or TreeLayout.AlignmentEnd. */ get nodeIndentPastParent(): number; set nodeIndentPastParent(value: number); /** * Gets or sets the distance between child nodes. * * The default value is 20. * * A negative value will cause sibling nodes to overlap. * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. */ get nodeSpacing(): number; set nodeSpacing(value: number); /** * Gets or sets the distance between this node and its children. * * The default value is 50. * * Negative values may cause children to overlap with the parent. * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. */ get layerSpacing(): number; set layerSpacing(value: number); /** * Gets or sets the fraction of this node's depth that may overlap with the children's layer. * * The default value is 0.0 -- there is overlap only if #layerSpacing is negative. * Values must range from 0.0 to 1.0, where 1.0 means the full depth of this node. * * When this value is greater than 0.0, there might not be overlap if #layerSpacing * is larger than the depth of this node times this fraction. * Even when this value is 0.0, there may be overlap when #layerSpacing is negative. * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. */ get layerSpacingParentOverlap(): number; set layerSpacingParentOverlap(value: number); /** * Gets or sets how the children of this node should be packed together. * * The default value is TreeLayout.CompactionBlock. * * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. */ get compaction(): EnumValue; set compaction(value: EnumValue); /** * Gets or sets how broad a node and its descendants should be. * * By default this is zero. A value of zero imposes no limit; * a positive value will specify a limit for the total width of this subtree. * * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. */ get breadthLimit(): number; set breadthLimit(value: number); /** * Gets or sets the distance between rows within one layer, all sharing the same parent. * * The default value is 25. * * Negative values may cause nodes to overlap. * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. */ get rowSpacing(): number; set rowSpacing(value: number); /** * Gets or sets the distance the first child of each row should be indented. * * The default value is 10. The value should be non-negative. * * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. * This property is only used when the #breadthLimit is positive, * and some initial space needs to be reserved in each row of nodes for the links * that are routed around those rows. */ get rowIndent(): number; set rowIndent(value: number); /** * Gets or sets the space to leave between consecutive comments. * * The default value is 10. * * Negative values may cause comments to overlap. * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. */ get commentSpacing(): number; set commentSpacing(value: number); /** * Gets or sets the space to leave between the node and the comments. * * The default value is 20. * * Negative values may cause comments to overlap with the node. * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. */ get commentMargin(): number; set commentMargin(value: number); /** * Gets or sets whether the TreeLayout should set the FromSpot for this parent node port. * * The default value is true -- this may modify the spot of the port of this node, the parent, * if the node has only a single port. * * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. * The spot used depends on the value of #portSpot. */ get setsPortSpot(): boolean; set setsPortSpot(value: boolean); /** * Gets or sets the spot that this node's port gets as its FromSpot, * if #setsPortSpot is true and the node has only a single port. * * The default value is Spot.Default. * * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. * A value of Spot.Default will cause the TreeLayout * to assign a FromSpot based on the parent node's TreeVertex#angle. * If the value is other than NoSpot, it is just assigned. * When TreeLayout#path is TreeLayout.PathSource, the port's ToSpot is set instead of the FromSpot. */ get portSpot(): Spot; set portSpot(value: Spot); /** * Gets or sets whether the TreeLayout should set the ToSpot for each child node port. * * The default value is true -- this may modify the spots of the ports of the children nodes, * if the node has only a single port. * * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. * The spot used depends on the value of #childPortSpot. */ get setsChildPortSpot(): boolean; set setsChildPortSpot(value: boolean); /** * Gets or sets the spot that children nodes' ports get as their ToSpot, * if #setsChildPortSpot is true and the node has only a single port. * * The default value is Spot.Default. * * This inherited property is initialized in the TreeLayout#initializeTreeVertexValues pass. * A value of Spot.Default will cause the TreeLayout * to assign a ToSpot based on the parent node's TreeVertex#angle. * If the value is other than NoSpot, it is just assigned. * When TreeLayout#path is TreeLayout.PathSource, the port's FromSpot is set instead of the ToSpot. */ get childPortSpot(): Spot; set childPortSpot(value: Spot); /** * This read-only property returns the number of immediate children this node has. * * The default value is zero. */ get childrenCount(): number; /** * Gets or sets the position of this node relative to its parent node. * * This informational property is computed during TreeLayout#doLayout. * You should probably not be setting this property. */ get relativePosition(): Point; set relativePosition(value: Point); /** * Gets or sets the size of the subtree (including all descendants) parented by this node. * * This informational property is computed during TreeLayout#doLayout. * Of course if there are no children, this is just the same as Size. * You should probably not be setting this property. */ get subtreeSize(): Size; set subtreeSize(value: Size); /** * Gets or sets the offset of this parent node relative to its whole subtree. * * This informational property is computed during TreeLayout#doLayout. * Of course if there are no children, this is just (0, 0). * You should probably not be setting this property. */ get subtreeOffset(): Point; set subtreeOffset(value: Point); } /** * This holds TreeLayout-specific information about Links. * * This class inherits from LayoutEdge. * @extends LayoutEdge * @unrestricted * @category Layout * @unindexed */ export class TreeEdge extends LayoutEdge { constructor(network: TreeNetwork); /** * Commits the position of the Link and routes it. */ commit(): void; /** * Gets or sets the LayoutVertex that this edge comes from. * Setting this property does not change any LayoutVertex#destinationEdges collection. */ get fromVertex(): TreeVertex; set fromVertex(value: TreeVertex); /** * Gets or sets the LayoutVertex that this edge goes to. * Setting this property does not change any LayoutVertex#sourceEdges collection. */ get toVertex(): TreeVertex | null; set toVertex(value: TreeVertex | null); /** * Gets or sets a Point, relative to the parent node, * that may be useful in routing this link. */ get relativePoint(): Point; set relativePoint(value: Point); }