@visuallyjs/browser-ui 1.2.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@visuallyjs/browser-ui",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "license": "Commercial",
5
5
  "main": "js/visuallyjs.browser-ui.cjs.js",
6
6
  "module": "js/visuallyjs.browser-ui.esm.js",
@@ -24,6 +24,7 @@ export interface BrowserUIPlugin<O extends UIPluginOptions> extends UIPlugin<Bro
24
24
  * @category Definitions
25
25
  */
26
26
  export declare abstract class BaseBrowserUIPlugin {
27
+ tracksEdgeRedraws: boolean;
27
28
  /**
28
29
  * Empty implementation of $groupMemberAdded.
29
30
  */
@@ -6,7 +6,7 @@ import { SurfaceSaveData } from "../definitions";
6
6
  import { BrowserElement } from "../../util";
7
7
  import { PaletteMode } from "../../components/palette/palette-options";
8
8
  import { PanOptions, WheelOptions, ZoomOptions } from "../../pan-zoom-options";
9
- import { MiniviewPluginOptions, LassoPluginOptions, ResizingToolsModelUpdater, ResizingToolsHandlerFactory, DragGroupsPluginOptions, ResizingToolsResizeMethod, SnaplinesPluginOptions, PanButtonsPluginOptions } from "../plugins";
9
+ import { MiniviewPluginOptions, LassoPluginOptions, ResizingToolsModelUpdater, ResizingToolsHandlerFactory, DragGroupsPluginOptions, ResizingToolsResizeMethod, SnaplinesPluginOptions, PanButtonsPluginOptions, LineCrossingsPluginOptions } from "../plugins";
10
10
  import { EdgeSnapOptions } from "../../edge-handler-base";
11
11
  import { DiagramActionMediator } from "./mediator";
12
12
  import { OnVertexAddedCallback, FontSpec } from "../../definitions";
@@ -435,6 +435,10 @@ export interface DiagramOptions {
435
435
  * Controls whether pan buttons are displayed at the edges of the canvas, defaults to false. You can either supply a boolean and have the panbuttons plugin initialize with its default settings, or supply your own settings.
436
436
  */
437
437
  panButtons?: boolean | PanButtonsPluginOptions;
438
+ /**
439
+ * Controls whether line crossings are shown by a visual cue. Defaults to false. You can either supply a boolean and have the panbuttons plugin initialize with its default settings, or supply your own settings.
440
+ */
441
+ lineCrossings?: boolean | LineCrossingsPluginOptions;
438
442
  }
439
443
  /**
440
444
  * Options for a palette for a diagram.
@@ -9,3 +9,4 @@ export * from './pan-buttons';
9
9
  export * from './list-manager';
10
10
  export * from './vertex-drawing';
11
11
  export * from './resizing-tools';
12
+ export * from './line-crossings';
@@ -0,0 +1,7 @@
1
+ import { BridgeDefinition, IntersectingPoint } from "./definitions";
2
+ /**
3
+ * @internal
4
+ * @param ip
5
+ * @param orientation
6
+ */
7
+ export declare function $arcBridge(ip: IntersectingPoint, orientation: "h" | "v"): BridgeDefinition;
@@ -0,0 +1,116 @@
1
+ import { Edge, LineXY, PointXY } from "../../../../core";
2
+ import { Connection, Connector } from "../../../../ui";
3
+ import { BrowserElement } from "../../../util";
4
+ /**
5
+ * Options for the line crossings plugin.
6
+ */
7
+ export interface LineCrossingsPluginOptions {
8
+ /**
9
+ * Whether to apply the bridge to the horizontal or the vertical segment in a crossing. Defaults to horizontal.
10
+ */
11
+ orientation: 'h' | 'v';
12
+ /**
13
+ * Type of bridge to use. Defaults to 'arch'.
14
+ */
15
+ bridgeType: "dot" | "arch" | "gap";
16
+ /**
17
+ * Radius to use for dot bridges. Defaults to 5.
18
+ */
19
+ dotRadius?: number;
20
+ /**
21
+ * Color to use for dot bridges. Defaults to null, and the dot is painted with the stroke color of the dominant segment. You can also control this via the CSS class defined by the constant CLASS_LINE_CROSSING_BRIDGE_DOT, but using CSS will be lost in an SVG export.
22
+ */
23
+ dotColor?: string;
24
+ /**
25
+ * Optional function to invoke when the user taps on a bridge. This will only fire for bridge types that draw extra components - arch and dot - but the gap bridge just masks
26
+ * @param edge1 First edge in the intersection
27
+ * @param edge2 Second edge in the intersection.
28
+ * @param canvasLocation The location on the canvas that the intersection is located at.
29
+ * @param e The mouse event associated with the tap.
30
+ */
31
+ onTap?: (edge1: Edge, edge2: Edge, canvasLocation: PointXY, e: MouseEvent) => any;
32
+ }
33
+ /**
34
+ * Line crossings plugin type
35
+ */
36
+ export declare const PLUGIN_TYPE_LINE_CROSSINGS = "lineCrossings";
37
+ /**
38
+ * Assigned to all bridges (of any type) that mark a line crossing.
39
+ * @cssClass
40
+ * @context Line crossings plugin
41
+ */
42
+ export declare const CLASS_LINE_CROSSING_BRIDGE = "vjs-bridge";
43
+ /**
44
+ * Assigned to all bridges (of any type) that mark a line crossing when the bridge is on the vertical axis
45
+ * @cssClass
46
+ * @context Line crossings plugin
47
+ */
48
+ export declare const CLASS_LINE_CROSSING_BRIDGE_VERTICAL = "vjs-bridge-vertical";
49
+ /**
50
+ * Assigned to all bridges (of any type) that mark a line crossing when the bridge is on the horizontal axis
51
+ * @cssClass
52
+ * @context Line crossings plugin
53
+ */
54
+ export declare const CLASS_LINE_CROSSING_BRIDGE_HORIZONTAL = "vjs-bridge-horizontal";
55
+ /**
56
+ * Assigned to all dot bridges that mark a line crossing.
57
+ * @cssClass
58
+ * @context Line crossings plugin
59
+ */
60
+ export declare const CLASS_LINE_CROSSING_BRIDGE_DOT = "vjs-bridge-dot";
61
+ /**
62
+ * Assigned to all arch bridges that mark a line crossing.
63
+ * @cssClass
64
+ * @context Line crossings plugin
65
+ */
66
+ export declare const CLASS_LINE_CROSSING_BRIDGE_ARCH = "vjs-bridge-arch";
67
+ /**
68
+ * Assigned to all gap bridges that mark a line crossing.
69
+ * @cssClass
70
+ * @context Line crossings plugin
71
+ */
72
+ export declare const CLASS_LINE_CROSSING_BRIDGE_GAP = "vjs-bridge-gap";
73
+ type SegmentOrientation = "h" | "v";
74
+ export type SegmentInfo = {
75
+ o: SegmentOrientation;
76
+ index: 0 | 1;
77
+ line: LineXY;
78
+ strokeWidth: number;
79
+ };
80
+ export type ConnectionInfo = {
81
+ segments: Array<SegmentInfo>;
82
+ connection: Connection<BrowserElement>;
83
+ connector: Connector;
84
+ intersectingPoints: Array<IntersectingPoint>;
85
+ pathElement: BrowserElement;
86
+ canvasElement: BrowserElement;
87
+ stroke: string;
88
+ strokeWidth: number;
89
+ id: string;
90
+ };
91
+ /**
92
+ * @internal
93
+ */
94
+ export interface IntersectingPoint {
95
+ index: 0 | 1;
96
+ point: PointXY;
97
+ o: {
98
+ ref: SegmentOrientation;
99
+ other: SegmentOrientation;
100
+ };
101
+ strokeWidth: {
102
+ ref: number;
103
+ other: number;
104
+ };
105
+ stroke: {
106
+ ref: string;
107
+ other: string;
108
+ };
109
+ refConnector: ConnectionInfo;
110
+ otherConnector: ConnectionInfo;
111
+ }
112
+ /**
113
+ * @internal
114
+ */
115
+ export type BridgeDefinition = [Array<BrowserElement>, number, Array<BrowserElement>];
116
+ export {};
@@ -0,0 +1,7 @@
1
+ import { BridgeDefinition, IntersectingPoint } from "./definitions";
2
+ /**
3
+ * @internal
4
+ * @param ip
5
+ * @param _orientation
6
+ */
7
+ export declare function $dotBridge(ip: IntersectingPoint, _orientation: "h" | "v", dotRadius: number, dotColor: string): BridgeDefinition;
@@ -0,0 +1,7 @@
1
+ import { BridgeDefinition, IntersectingPoint } from "./definitions";
2
+ /**
3
+ * @internal
4
+ * @param ip
5
+ * @param orientation
6
+ */
7
+ export declare function $gapBridge(ip: IntersectingPoint, orientation: "h" | "v"): BridgeDefinition;
@@ -0,0 +1,5 @@
1
+ export * from "./definitions";
2
+ export * from "./arch-bridge";
3
+ export * from "./dot-bridge";
4
+ export * from "./gap-bridge";
5
+ export * from "./line-crossings-plugin";
@@ -0,0 +1,74 @@
1
+ import { Connection, ConnectionEstablishedParams } from "../../../../ui";
2
+ import { BaseBrowserUIPlugin } from "../../../plugins";
3
+ import { Edge, PointXY } from "../../../../core";
4
+ import { ConnectionInfo, LineCrossingsPluginOptions } from "./definitions";
5
+ import { Surface } from "../../surface";
6
+ import { BrowserElement } from "../../../util";
7
+ interface InternalBridgeDefinition {
8
+ canvasElements: Array<BrowserElement>;
9
+ bgSize: number;
10
+ masks: Array<BrowserElement>;
11
+ edge: Edge;
12
+ otherEdge: Edge;
13
+ id: string;
14
+ }
15
+ /**
16
+ * Adds visual artifacts ("bridges") to the canvas at the locations where two orthogonal segments intersect. As of the first release, this plugin will only work with Orthogonal connectors (or Straight connectors with 'orthogonal' constrain set).
17
+ *
18
+ * Three bridge types are supported: "arch" (the default), "gap" and "dot". For dot bridges you can supply a dot radius and fill colour to use, or VisuallyJs will just use the stroke from the dominant connector at the intersection.
19
+ *
20
+ * The plugin has the concept of "orientation": which axis to apply updates to segments in. "h" - horizontal - is the default, and in this orientation VisuallyJs will add bridges to the horizontal segment at an intersection. You can set orientation to "v" to switch to vertical.
21
+ */
22
+ export declare class LineCrossingsPlugin extends BaseBrowserUIPlugin {
23
+ _surface: Surface;
24
+ _orientation: "h" | "v";
25
+ _otherAxisOrientation: "h" | "v";
26
+ _orientationClass: string;
27
+ _dotRadius: number;
28
+ _dotColor: string;
29
+ _onTap: (edge1: Edge, edge2: Edge, canvasLocation: PointXY, e: MouseEvent) => any;
30
+ _edgeCache: Map<string, ConnectionInfo>;
31
+ _bridgeType: "arch" | "dot" | "gap";
32
+ _key: string;
33
+ tracksEdgeRedraws: boolean;
34
+ _bridgesByEdgeId: Map<string, Array<InternalBridgeDefinition>>;
35
+ _bridgesById: Map<string, InternalBridgeDefinition>;
36
+ initialise(surface: Surface, options: LineCrossingsPluginOptions): boolean;
37
+ $edgeRedraw(c: Connection<BrowserElement>): void;
38
+ private _getConnectorInfo;
39
+ private _resetCache;
40
+ private _trackOneEdge;
41
+ private _getEdgeInfo;
42
+ /**
43
+ * Gets the list of segments for the reference orientation. This is a stub; it isnt entirely necessary if we are going to be locked to orthogonal always. But if we decided to support arbitrary angles, we could update this method to have it ignore orientation.
44
+ * @param s
45
+ */
46
+ private _getRefConnectorSegments;
47
+ /**
48
+ * Gets the list of segments for the other orientation. This is a stub; it isnt entirely necessary if we are going to be locked to orthogonal always. But if we decided to support arbitrary angles, we could update this method to have it ignore orientation.
49
+ * @param s
50
+ */
51
+ private _getOtherConnectorSegments;
52
+ private _getBridgeSize;
53
+ private _cleanupBridgesForEdge;
54
+ private _cleanupBridges;
55
+ /**
56
+ * Place bridges for a single edge, either looking for segment's in the current orientation in that edge only (testAllCombinations:false), or by also testing segments in any overlapping connectors. The first case is for when we're painting the whole dataset, and we know that every segment will be reached. The second case is when we're just repainting a single edge.
57
+ * @param edge
58
+ * @param testAllCombinations
59
+ */
60
+ private _placeBridgesForEdge;
61
+ /**
62
+ * Clears the edge cache and recomputes bridges for every edge in the dataset
63
+ */
64
+ private _placeAllBridges;
65
+ private _drawBridge;
66
+ destroy(): void;
67
+ reset(): void;
68
+ private _createMaskId;
69
+ private _ensureMaskDef;
70
+ private _removeMaskDef;
71
+ $edgeRemoved(edge: Edge): void;
72
+ $edgeRendered(p: ConnectionEstablishedParams): void;
73
+ }
74
+ export {};
@@ -183,6 +183,13 @@ export declare function isNodeVertex(v: Vertex): v is Node;
183
183
  * @category Utils
184
184
  */
185
185
  export declare function isVertex(o: any): o is Vertex;
186
+ /**
187
+ * Checks if an edge is connected to the given vertex or any of its ports.
188
+ * @param edge The edge to check.
189
+ * @param vertex The vertex (Node or Group) to check against.
190
+ * @returns True if the edge's source or target (or their parent Node/Group if a Port) matches the vertex.
191
+ */
192
+ export declare function isEdgeConnectedTo(edge: Edge, ...vertex: Array<Vertex>): boolean;
186
193
  /**
187
194
  * @internal
188
195
  */
@@ -26,7 +26,6 @@ export declare const Connectors: {
26
26
  register: (name: string, handler: ConnectorHandler) => void;
27
27
  compute: (c: Connection<any>, geometry: PaintGeometry, params: ConnectorComputeParams) => Geometry;
28
28
  update: (c: Connection<any>, geometry: PaintGeometry, params: ConnectorComputeParams, sourceMoved: boolean, targetMoved: boolean) => Geometry;
29
- markEdited(connection: Connection<any>, g?: Geometry): void;
30
29
  /**
31
30
  * Import the given geometry, setting it on the connector, marking the connector persistToModel, and setting
32
31
  * anchor locations to the values from the geometry, then locking them. This method does not write the
@@ -71,6 +70,7 @@ export declare function defaultImportGeometry(ac: Connector, g: Geometry): boole
71
70
  */
72
71
  export declare function _updateConnectorBounds(ac: Connector, segment: Segment): void;
73
72
  export declare function _clearConnectorSegments(c: Connector): void;
73
+ export declare function clampToHalfPixel(value: number): number;
74
74
  export declare function _addConnectorSegment(c: Connector, type: string, params: any): void;
75
75
  /**
76
76
  * This abstraction exists to support using the various pointOnPath, pointAlongPath etc methods, without needing a Connector. The initial use case is to support ad-hoc drawing of edges, for such things as the edge type picker, but also this is really a step on the way to refactoring the paint code to make it less complex and more of a rubber-stamp operation.
@@ -97,6 +97,7 @@ export declare abstract class UICore<EL, EVT = CoreUIEvent> extends OptimisticEv
97
97
  zoomToFitOnLoad: boolean;
98
98
  plugins: Array<UIPlugin<EL, any, any>>;
99
99
  pluginMap: Map<string, UIPlugin<EL, any, any>>;
100
+ _edgeRedrawPlugins: Array<UIPlugin<EL, any, any>>;
100
101
  connectorClass: string;
101
102
  connectorOutlineClass: string;
102
103
  connectorPathClass: string;
@@ -37,6 +37,12 @@ export interface ViewportElement<E> extends ElementBase {
37
37
  export interface ViewportNodeElement<E> extends ViewportElement<E> {
38
38
  modelObject: Node;
39
39
  }
40
+ /**
41
+ * @internal
42
+ */
43
+ export interface ConnectorBounds extends RectangleXY {
44
+ id: string;
45
+ }
40
46
  /**
41
47
  * An element that tracks a Group
42
48
  * @internal
@@ -81,6 +87,7 @@ export declare class Viewport<EL> {
81
87
  private getRenderedElement;
82
88
  private _currentTransaction;
83
89
  private rtree;
90
+ private edgertree;
84
91
  private _suspended;
85
92
  private _boundsDirty;
86
93
  constructor(instance: UICore<EL, any>, getRenderedElement: (id: string) => EL);
@@ -116,6 +123,7 @@ export declare class Viewport<EL> {
116
123
  * @internal
117
124
  */
118
125
  findVerticesIntersectingWithRect(rect: RectangleXY, margin: number, greedy: boolean, ignoreIds: Array<string>, ignoreBoundaryMatch: boolean): Array<ViewportElement<any>>;
126
+ findConnectorBoundsIntersectingWithRect(rect: RectangleXY, margin: number, greedy: boolean, ignoreIds: Array<string>, ignoreBoundaryMatch: boolean): Array<ConnectorBounds>;
119
127
  /**
120
128
  * Returns vertices that are enclosed by the given rectangle, optionally ignoring a set of vertex IDs when performing the calculation.
121
129
  * @param rect Rectangle to test
@@ -155,6 +163,12 @@ export declare class Viewport<EL> {
155
163
  * @param doNotRecalculateBounds Defaults to false. For internal use. If true, does not update viewport bounds after updating the element.
156
164
  */
157
165
  updateElement(id: string, x: number, y: number, width: number, height: number, rotation: number, modelObject: Vertex, doNotRecalculateBounds: boolean): ViewportElement<EL>;
166
+ /**
167
+ * @internal
168
+ * @param c
169
+ */
170
+ $updateEdge(c: ConnectorBounds): void;
171
+ $removeEdge(id: string): void;
158
172
  $forEachElement(cb: (e: ViewportElement<any>) => any): void;
159
173
  $refreshEveryElement(): void;
160
174
  $refreshElement(elId: string, doNotRecalculateBounds?: boolean, pos?: PointXY, size?: Size, rotation?: number): ViewportElement<EL>;
@@ -17,6 +17,15 @@ export interface UIPlugin<EL, O extends UIPluginOptions, U extends UICore<EL, an
17
17
  initialise(ui: U, options: O): boolean;
18
18
  destroy(): void;
19
19
  reset(): void;
20
+ /**
21
+ * Set this to true to inform the UI that the plugin wishes to be informed at the end of an edge paint.
22
+ */
23
+ tracksEdgeRedraws: boolean;
24
+ /**
25
+ * Optional method you can implement if you set `tracksEdgeRedraws:true`; the UI will invoke this method at the end of each edge's paint cycle. You can access the underlying edge via `c.edge`.
26
+ * @param c
27
+ */
28
+ $edgeRedraw?: (c: Connection<EL>) => any;
20
29
  /**
21
30
  * Invoked when a group member has been removed
22
31
  * @param element
@@ -1 +1 @@
1
- export declare const VERSION = "1.2.2";
1
+ export declare const VERSION = "1.2.3";