Merge pull request #124 from mayorovad/issue-96
commit
4622527af8
|
@ -70,9 +70,6 @@ For more details, have a look at the [storybook stories](packages/html/stories).
|
||||||
|
|
||||||
maxGraph is written in TypeScript and provides type definitions so maxGraph can be easily integrated into TypeScript projects.
|
maxGraph is written in TypeScript and provides type definitions so maxGraph can be easily integrated into TypeScript projects.
|
||||||
|
|
||||||
**WARN**: some definitions are currently buggy, so please set `skipLibCheck` to `true` in the `tsconfig.json` file of your project.
|
|
||||||
For more details, see issues [#96](https://github.com/maxGraph/maxGraph/issues/96) and [#105](https://github.com/maxGraph/maxGraph/issues/105#issuecomment-1240640369).
|
|
||||||
|
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import Geometry from '../geometry/Geometry';
|
||||||
import Point from '../geometry/Point';
|
import Point from '../geometry/Point';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
|
import { GraphLayoutTraverseArgs } from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class GraphLayout
|
* @class GraphLayout
|
||||||
|
@ -141,13 +142,7 @@ class GraphLayout {
|
||||||
* null for the first step of the traversal.
|
* null for the first step of the traversal.
|
||||||
* @param visited Optional {@link Dictionary} of cell paths for the visited cells.
|
* @param visited Optional {@link Dictionary} of cell paths for the visited cells.
|
||||||
*/
|
*/
|
||||||
traverse(
|
traverse({vertex, directed, func, edge, visited}: GraphLayoutTraverseArgs): void {
|
||||||
vertex: Cell,
|
|
||||||
directed?: boolean,
|
|
||||||
func?: Function,
|
|
||||||
edge?: Cell,
|
|
||||||
visited?: Dictionary<Cell, boolean>
|
|
||||||
): void {
|
|
||||||
if (func != null && vertex != null) {
|
if (func != null && vertex != null) {
|
||||||
directed = directed != null ? directed : true;
|
directed = directed != null ? directed : true;
|
||||||
visited = visited || new Dictionary();
|
visited = visited || new Dictionary();
|
||||||
|
@ -161,12 +156,18 @@ class GraphLayout {
|
||||||
|
|
||||||
if (edgeCount > 0) {
|
if (edgeCount > 0) {
|
||||||
for (let i = 0; i < edgeCount; i += 1) {
|
for (let i = 0; i < edgeCount; i += 1) {
|
||||||
const e = vertex.getEdgeAt(i);
|
const e: Cell = vertex.getEdgeAt(i);
|
||||||
const isSource = e.getTerminal(true) === vertex;
|
const isSource = e.getTerminal(true) === vertex;
|
||||||
|
|
||||||
if (!directed || isSource) {
|
if (!directed || isSource) {
|
||||||
const next = this.graph.view.getVisibleTerminal(e, !isSource);
|
const next = this.graph.view.getVisibleTerminal(e, !isSource);
|
||||||
this.traverse(<Cell>next, directed, func, e, visited);
|
this.traverse({
|
||||||
|
vertex: next,
|
||||||
|
directed,
|
||||||
|
func,
|
||||||
|
edge: e,
|
||||||
|
visited
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ import MedianHybridCrossingReduction from './hierarchical/MedianHybridCrossingRe
|
||||||
import CoordinateAssignment from './hierarchical/CoordinateAssignment';
|
import CoordinateAssignment from './hierarchical/CoordinateAssignment';
|
||||||
import { Graph } from '../../view/Graph';
|
import { Graph } from '../../view/Graph';
|
||||||
import Cell from '../../view/cell/Cell';
|
import Cell from '../../view/cell/Cell';
|
||||||
import GraphHierarchyNode from './datatypes/GraphHierarchyNode';
|
import { HierarchicalGraphLayoutTraverseArgs } from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A hierarchical layout algorithm.
|
* A hierarchical layout algorithm.
|
||||||
|
@ -444,15 +444,17 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
const vertexSet = Object();
|
const vertexSet = Object();
|
||||||
hierarchyVertices.push(vertexSet);
|
hierarchyVertices.push(vertexSet);
|
||||||
|
|
||||||
this.traverse(
|
this.traverse({
|
||||||
candidateRoots[i],
|
vertex: candidateRoots[i],
|
||||||
true,
|
directed: true,
|
||||||
null,
|
edge: null,
|
||||||
allVertexSet,
|
allVertices: allVertexSet,
|
||||||
vertexSet,
|
currentComp: vertexSet,
|
||||||
hierarchyVertices,
|
hierarchyVertices: hierarchyVertices,
|
||||||
filledVertexSet
|
filledVertexSet: filledVertexSet,
|
||||||
);
|
func: null,
|
||||||
|
visited: null
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < candidateRoots.length; i += 1) {
|
for (let i = 0; i < candidateRoots.length; i += 1) {
|
||||||
|
@ -477,15 +479,17 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
const vertexSet = Object();
|
const vertexSet = Object();
|
||||||
hierarchyVertices.push(vertexSet);
|
hierarchyVertices.push(vertexSet);
|
||||||
|
|
||||||
this.traverse(
|
this.traverse({
|
||||||
roots[i],
|
vertex: roots[i],
|
||||||
true,
|
directed: true,
|
||||||
null,
|
edge: null,
|
||||||
allVertexSet,
|
allVertices: allVertexSet,
|
||||||
vertexSet,
|
currentComp: vertexSet,
|
||||||
hierarchyVertices,
|
hierarchyVertices: hierarchyVertices,
|
||||||
null
|
filledVertexSet: null,
|
||||||
);
|
func: null,
|
||||||
|
visited: null
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,16 +604,14 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
* null for the first step of the traversal.
|
* null for the first step of the traversal.
|
||||||
* @param allVertices Array of cell paths for the visited cells.
|
* @param allVertices Array of cell paths for the visited cells.
|
||||||
*/
|
*/
|
||||||
// @ts-ignore
|
traverse({
|
||||||
traverse(
|
vertex,
|
||||||
vertex: Cell,
|
directed,
|
||||||
directed: boolean = false,
|
allVertices,
|
||||||
edge: Cell | null = null,
|
currentComp,
|
||||||
allVertices: { [key: string]: Cell } | null = null,
|
hierarchyVertices,
|
||||||
currentComp: { [key: string]: Cell | null },
|
filledVertexSet
|
||||||
hierarchyVertices: GraphHierarchyNode[],
|
}: HierarchicalGraphLayoutTraverseArgs) {
|
||||||
filledVertexSet: { [key: string]: Cell } | null = null
|
|
||||||
) {
|
|
||||||
if (vertex != null && allVertices != null) {
|
if (vertex != null && allVertices != null) {
|
||||||
// Has this vertex been seen before in any traversal
|
// Has this vertex been seen before in any traversal
|
||||||
// And if the filled vertex set is populated, only
|
// And if the filled vertex set is populated, only
|
||||||
|
@ -666,15 +668,17 @@ class HierarchicalLayout extends GraphLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netCount >= 0) {
|
if (netCount >= 0) {
|
||||||
currentComp = this.traverse(
|
currentComp = this.traverse({
|
||||||
<Cell>next,
|
vertex: next,
|
||||||
directed,
|
directed,
|
||||||
edges[i],
|
edge: edges[i],
|
||||||
allVertices,
|
allVertices,
|
||||||
currentComp,
|
currentComp,
|
||||||
hierarchyVertices,
|
hierarchyVertices,
|
||||||
filledVertexSet
|
filledVertexSet,
|
||||||
);
|
func: null,
|
||||||
|
visited: null
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ import CoordinateAssignment from './hierarchical/CoordinateAssignment';
|
||||||
import { Graph } from '../Graph';
|
import { Graph } from '../Graph';
|
||||||
import Cell from '../cell/Cell';
|
import Cell from '../cell/Cell';
|
||||||
import Geometry from '../../view/geometry/Geometry';
|
import Geometry from '../../view/geometry/Geometry';
|
||||||
import GraphHierarchyNode from './datatypes/GraphHierarchyNode';
|
import { SwimlaneGraphLayoutTraverseArgs } from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A hierarchical layout algorithm.
|
* A hierarchical layout algorithm.
|
||||||
|
@ -579,16 +579,18 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
const vertexSet = Object();
|
const vertexSet = Object();
|
||||||
hierarchyVertices.push(vertexSet);
|
hierarchyVertices.push(vertexSet);
|
||||||
|
|
||||||
this.traverse(
|
this.traverse({
|
||||||
candidateRoots[i],
|
vertex: candidateRoots[i],
|
||||||
true,
|
directed: true,
|
||||||
null,
|
edge: null,
|
||||||
allVertexSet,
|
allVertices: allVertexSet,
|
||||||
vertexSet,
|
currentComp: vertexSet,
|
||||||
hierarchyVertices,
|
hierarchyVertices,
|
||||||
filledVertexSet,
|
filledVertexSet,
|
||||||
laneCounter
|
swimlaneIndex: laneCounter,
|
||||||
);
|
func: null,
|
||||||
|
visited: null
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < candidateRoots.length; i += 1) {
|
for (let i = 0; i < candidateRoots.length; i += 1) {
|
||||||
|
@ -612,16 +614,18 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
for (let i = 0; i < roots.length; i += 1) {
|
for (let i = 0; i < roots.length; i += 1) {
|
||||||
const vertexSet = Object();
|
const vertexSet = Object();
|
||||||
hierarchyVertices.push(vertexSet);
|
hierarchyVertices.push(vertexSet);
|
||||||
this.traverse(
|
this.traverse({
|
||||||
roots[i],
|
vertex: roots[i],
|
||||||
true,
|
directed: true,
|
||||||
null,
|
edge: null,
|
||||||
allVertexSet,
|
allVertices: allVertexSet,
|
||||||
vertexSet,
|
currentComp: vertexSet,
|
||||||
hierarchyVertices,
|
hierarchyVertices,
|
||||||
null,
|
filledVertexSet: null,
|
||||||
i
|
swimlaneIndex: i,
|
||||||
); // CHECK THIS PARAM!! ====================
|
func: null,
|
||||||
|
visited: null
|
||||||
|
}); // CHECK THIS PARAM!! ====================
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,17 +735,15 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
* @param allVertices Array of cell paths for the visited cells.
|
* @param allVertices Array of cell paths for the visited cells.
|
||||||
* @param swimlaneIndex the laid out order index of the swimlane vertex is contained in
|
* @param swimlaneIndex the laid out order index of the swimlane vertex is contained in
|
||||||
*/
|
*/
|
||||||
// @ts-ignore
|
traverse({
|
||||||
traverse(
|
vertex,
|
||||||
vertex: Cell | null = null,
|
directed,
|
||||||
directed: boolean,
|
allVertices,
|
||||||
edge: Cell | null,
|
currentComp,
|
||||||
allVertices: { [key: string]: Cell } | null = null,
|
hierarchyVertices,
|
||||||
currentComp: { [key: string]: Cell },
|
filledVertexSet,
|
||||||
hierarchyVertices: GraphHierarchyNode[],
|
swimlaneIndex
|
||||||
filledVertexSet: { [key: string]: Cell } | null = null,
|
}: SwimlaneGraphLayoutTraverseArgs) {
|
||||||
swimlaneIndex: number
|
|
||||||
) {
|
|
||||||
if (vertex != null && allVertices != null) {
|
if (vertex != null && allVertices != null) {
|
||||||
// Has this vertex been seen before in any traversal
|
// Has this vertex been seen before in any traversal
|
||||||
// And if the filled vertex set is populated, only
|
// And if the filled vertex set is populated, only
|
||||||
|
@ -764,7 +766,6 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
const edges = this.getEdges(vertex);
|
const edges = this.getEdges(vertex);
|
||||||
const { model } = this.graph;
|
|
||||||
|
|
||||||
for (let i = 0; i < edges.length; i += 1) {
|
for (let i = 0; i < edges.length; i += 1) {
|
||||||
let otherVertex = this.getVisibleTerminal(edges[i], true);
|
let otherVertex = this.getVisibleTerminal(edges[i], true);
|
||||||
|
@ -775,16 +776,15 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
let otherIndex = 0;
|
let otherIndex = 0;
|
||||||
const swimlanes = this.swimlanes as Cell[];
|
|
||||||
|
|
||||||
// Get the swimlane index of the other terminal
|
// Get the swimlane index of the other terminal
|
||||||
for (otherIndex = 0; otherIndex < swimlanes.length; otherIndex++) {
|
for (otherIndex = 0; otherIndex < this.swimlanes!.length; otherIndex++) {
|
||||||
if (swimlanes[otherIndex].isAncestor(otherVertex)) {
|
if (this.swimlanes![otherIndex].isAncestor(otherVertex)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (otherIndex >= swimlanes.length) {
|
if (otherIndex >= this.swimlanes!.length) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -795,16 +795,18 @@ class SwimlaneLayout extends GraphLayout {
|
||||||
otherIndex > swimlaneIndex ||
|
otherIndex > swimlaneIndex ||
|
||||||
((!directed || isSource) && otherIndex === swimlaneIndex)
|
((!directed || isSource) && otherIndex === swimlaneIndex)
|
||||||
) {
|
) {
|
||||||
currentComp = this.traverse(
|
currentComp = this.traverse({
|
||||||
<Cell>otherVertex,
|
vertex: otherVertex,
|
||||||
directed,
|
directed,
|
||||||
edges[i],
|
edge: edges[i],
|
||||||
allVertices,
|
allVertices,
|
||||||
currentComp,
|
currentComp,
|
||||||
hierarchyVertices,
|
hierarchyVertices,
|
||||||
filledVertexSet,
|
filledVertexSet,
|
||||||
otherIndex
|
swimlaneIndex: otherIndex,
|
||||||
);
|
func: null,
|
||||||
|
visited: null
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (currentComp[vertexID] == null) {
|
} else if (currentComp[vertexID] == null) {
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022-present The maxGraph project Contributors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type Cell from '../cell/Cell';
|
||||||
|
import type Dictionary from '../../util/Dictionary';
|
||||||
|
import type GraphHierarchyNode from './datatypes/GraphHierarchyNode';
|
||||||
|
|
||||||
|
export interface GraphLayoutTraverseArgs {
|
||||||
|
vertex: Cell | null;
|
||||||
|
directed: boolean | null;
|
||||||
|
func: Function | null;
|
||||||
|
edge: Cell | null;
|
||||||
|
visited: Dictionary<Cell, boolean> | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HierarchicalGraphLayoutTraverseArgs extends GraphLayoutTraverseArgs {
|
||||||
|
allVertices: { [key: string]: Cell } | null;
|
||||||
|
currentComp: { [key: string]: Cell | null };
|
||||||
|
hierarchyVertices: GraphHierarchyNode[];
|
||||||
|
filledVertexSet: { [key: string]: Cell } | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SwimlaneGraphLayoutTraverseArgs extends HierarchicalGraphLayoutTraverseArgs {
|
||||||
|
swimlaneIndex: number;
|
||||||
|
}
|
|
@ -13,9 +13,7 @@
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true
|
||||||
// TODO required because some type definitions in the @maxgraph/core package generate errors: https://github.com/maxGraph/maxGraph/issues/96
|
|
||||||
"skipLibCheck": true
|
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue