Merge pull request #124 from mayorovad/issue-96

development
Thomas Bouffard 2022-10-09 22:32:39 +02:00 committed by GitHub
commit 4622527af8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 128 additions and 88 deletions

View File

@ -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

View File

@ -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
});
} }
} }
} }

View File

@ -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
});
} }
} }
} }

View File

@ -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) {

View File

@ -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;
}

View File

@ -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"]
} }