Socket
Socket
Sign inDemoInstall

@antv/graphlib

Package Overview
Dependencies
Maintainers
57
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@antv/graphlib - npm Package Compare versions

Comparing version 1.0.2 to 1.1.0

COMPARE_TO_DAGRE_GRAPHLIB.md

4

es/algorithm/dfs.d.ts
import Graph from '../Graph';
/**
* @description DFS traversal.
* @description.zh-CN DFS 遍历。
*/
declare const dfs: <NodeIDType = any>(graph: Graph<NodeIDType, any, any, any>, node: NodeIDType | NodeIDType[], order: 'pre' | 'post') => NodeIDType[];
export default dfs;

@@ -0,1 +1,5 @@

/**
* @description DFS traversal.
* @description.zh-CN DFS 遍历。
*/
var doDFS = function doDFS(graph, node, postorder, visited, navigator, result) {

@@ -18,3 +22,8 @@ if (!visited.includes(node)) {

};
/**
* @description DFS traversal.
* @description.zh-CN DFS 遍历。
*/
var dfs = function dfs(graph, node, order) {

@@ -21,0 +30,0 @@ var nodes = Array.isArray(node) ? node : [node];

import Graph, { DefaultEdgeType } from '../Graph';
/**
* @description Dijkstra's algorithm for single-source shortest paths.
* @description https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
* @description.zh-CN Dijkstra 算法用于单源最短路径。
*/
declare const dijkstra: <NodeIDType, EdgeType>(graph: Graph<NodeIDType, any, EdgeType, string>, source: NodeIDType, weightFn?: ((node: DefaultEdgeType<NodeIDType, EdgeType>) => number) | undefined, edgeFn?: ((node: NodeIDType) => DefaultEdgeType<NodeIDType, EdgeType>[]) | undefined) => Record<string, Entry<NodeIDType>>;

@@ -3,0 +8,0 @@ declare type Entry<NodeIDType> = {

@@ -18,3 +18,9 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

};
/**
* @description Dijkstra's algorithm for single-source shortest paths.
* @description https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
* @description.zh-CN Dijkstra 算法用于单源最短路径。
*/
var dijkstra = function dijkstra(graph, source, weightFn, edgeFn) {

@@ -25,3 +31,9 @@ return runDijkstra(graph, source, weightFn || DEFAULT_WEIGHT_FUNC, edgeFn || function (v) {

};
/**
* @description Dijkstra's algorithm for single-source shortest paths.
* @description https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
* @description.zh-CN Dijkstra 算法用于单源最短路径。
*/
var runDijkstra = function runDijkstra(graph, source, weightFn, edgeFn) {

@@ -41,4 +53,5 @@ var results = new Map();

throw new Error('dijkstra does not allow negative edge weights. ' + 'Bad edge: ' + edge + ' Weight: ' + weight);
}
} // If there is already a shorter path to w, ignore this edge.
if (distance < wEntry.distance) {

@@ -45,0 +58,0 @@ wEntry.distance = distance;

2

es/algorithm/is-acyclic.d.ts
import Graph from '../Graph';
declare const isAcyclic: <NodeType>(graph: Graph) => boolean;
declare const isAcyclic: (graph: Graph) => boolean;
export default isAcyclic;
import Graph from '../Graph';
/**
* @description Tarjan's algorithm for finding the strongly connected components of a graph.
* @description https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
* @description.zh-CN Tarjan 算法用于找到图的强连通子图。
* @param graph
* @returns
*/
declare const tarjan: <NodeIDType>(graph: Graph<NodeIDType, Record<string, any>, Record<string, any>, string>) => NodeIDType[][];
export default tarjan;

@@ -0,1 +1,8 @@

/**
* @description Tarjan's algorithm for finding the strongly connected components of a graph.
* @description https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
* @description.zh-CN Tarjan 算法用于找到图的强连通子图。
* @param graph
* @returns
*/
var tarjan = function tarjan(graph) {

@@ -22,12 +29,14 @@ var index = 0;

// 如果 w 没有被访问过,则继续访问 w
if (!visited.has(w)) {
dfs(w);
var wEntry = visited.get(w);
entry.lowlink = Math.min(entry.lowlink, wEntry.lowlink);
entry.lowlink = Math.min(entry.lowlink, wEntry.lowlink); // 如果 w 在栈顶,则说明 w 和 v 不是强连通的
} else if ((_visited$get = visited.get(w)) === null || _visited$get === void 0 ? void 0 : _visited$get.onStack) {
var _wEntry = visited.get(w);
var _wEntry = visited.get(w); // 如果 w 在栈中,则说明 w 在当前访问的路径上
entry.lowlink = Math.min(entry.lowlink, _wEntry.index);
}
});
}); // 如果 v 的 lowlink 不等于 v 的 index,则说明 v 和 v 的 lowlink 不是强连通的

@@ -39,2 +48,3 @@ if (entry.lowlink === entry.index) {

do {
// 将 w 出栈,并将 w 的所有邻接点加入强连通子图
w = stack.pop();

@@ -41,0 +51,0 @@ var wEntry = visited.get(w);

@@ -22,5 +22,21 @@ export interface GraphOption {

export interface DefaultEdgeType<NodeIDType, EdgeType> {
/**
* @description the node where this edge start
* @description.zh-CN 边开始的节点
*/
v: NodeIDType;
/**
* @description the node where this edge end
* @description.zh-CN 边结束的节点
*/
w: NodeIDType;
/**
* @description The name used to distinguish the multilateral relationship between two nodes
* @description.zh-CN 用来区分两点之间的多边关系的名称
*/
name?: string;
/**
* @description The value of the edge
* @description.zh-CN 边的值
*/
value?: EdgeType;

@@ -51,13 +67,49 @@ }

private edgeCountNum;
/**
* @description return node label with its id
* @description.zh-CN 返回节点的默认的标签
*/
private defaultNodeLabelFn;
/**
* @description return edge label with its id
* @description.zh-CN 返回边的默认的标签
*/
private defaultEdgeLabelFn;
constructor(options?: GraphOption);
/**
* @description Map for parent relationship
* @description.zh-CN 父子关系的映射
*/
private parentMap?;
/**
* @description Map for children relationship
* @description.zh-CN 子孙关系的映射
*/
private childrenMap?;
private nodesLabelMap;
/**
* @description Map for edges
* @description.zh-CN 边的映射
*/
private inEdgesMap;
private outEdgesMap;
/**
* @description Map for predecessors
* @description.zh-CN 前驱节点的映射
*/
private predecessorsMap;
/**
* @description Map for successors
* @description.zh-CN 后继节点的映射
*/
private successorsMap;
/**
* @description Map for edge object
* @description.zh-CN 边的映射
*/
private edgesMap;
/**
* @description Map for edge label
* @description.zh-CN 边的标签的映射
*/
private edgesLabelsMap;

@@ -108,2 +160,6 @@ /**

nodeCount: () => number;
/**
* @description get node label
* @description.zh-CN 获取节点的标签
*/
node: (n: NodeIDType) => NodeType | undefined;

@@ -296,2 +352,6 @@ /**

removeEdge: (v_: NodeIDType, w_: NodeIDType, name?: any) => this;
/**
* @description remove a specific edge by edge object
* @description.zh-CN 删除一条边
*/
removeEdgeObj: ({ v, w, name }: {

@@ -302,2 +362,6 @@ v: NodeIDType;

}) => this;
/**
* @description get all edges object in graph
* @description.zh-CN 获得图中所有的边对象
*/
edges: () => DefaultEdgeType<NodeIDType, EdgeType>[];

@@ -358,2 +422,32 @@ /**

};
/**
* @description Count the in edges of node
* @description.zh-CN 计算节点的入边的数量
*/
nodeInDegree: (node: NodeIDType) => number;
/**
* @description Count the out edges of node
* @description.zh-CN 计算节点的出边的数量
*/
nodeOutDegree: (node: NodeIDType) => number;
/**
* @description Count the total edges of node
* @description.zh-CN 计算节点的所有边的数量
*/
nodeDegree: (node: NodeIDType) => number;
/**
* @description Get the source of edge
* @description.zh-CN 获取边的源节点
*/
source: (edge: DefaultEdgeType<NodeIDType, EdgeType>) => NodeIDType;
/**
* @description Get the target of edge
* @description.zh-CN 获取边的目标节点
*/
target: (edge: DefaultEdgeType<NodeIDType, EdgeType>) => NodeIDType;
/**
* @description Count the total edges with self loop
* @description.zh-CN 计算节点的自环边的数量
*/
countSelfLoops: () => number;
}

@@ -7,2 +7,8 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

@@ -43,2 +49,12 @@

*/
/**
* @description return node label with its id
* @description.zh-CN 返回节点的默认的标签
*/
/**
* @description return edge label with its id
* @description.zh-CN 返回边的默认的标签
*/
function Graph() {

@@ -147,3 +163,3 @@ var _this = this;

predecessorsMap = _this.predecessorsMap,
successorsMap = _this.successorsMap;
successorsMap = _this.successorsMap; // 如果节点不在图中,则创建节点

@@ -158,3 +174,3 @@ if (nodesLabelMap.has(node)) {

nodesLabelMap.set(node, value || defaultNodeLabelFn(node));
nodesLabelMap.set(node, value || defaultNodeLabelFn(node)); // 如果是复合图,则创建节点的子节点

@@ -562,2 +578,57 @@ if (isCompound()) {

this.nodeInDegree = function (node) {
var inEdges = _this.inEdgesMap.get(node);
if (inEdges) {
return inEdges.size;
}
return 0;
};
this.nodeOutDegree = function (node) {
var outEdges = _this.outEdgesMap.get(node);
if (outEdges) {
return outEdges.size;
}
return 0;
};
this.nodeDegree = function (node) {
return _this.nodeInDegree(node) + _this.nodeOutDegree(node);
};
this.source = function (edge) {
return edge.v;
};
this.target = function (edge) {
return edge.w;
};
this.countSelfLoops = function () {
var count = 0;
var _iterator = _createForOfIteratorHelper(_this.edges()),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var edge = _step.value;
if (edge.v === edge.w) {
count += 1;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return count;
};
var resultOptions = _objectSpread(_objectSpread({}, defaultOption), options);

@@ -574,2 +645,7 @@

} // Map for graph
/**
* @description Map for parent relationship
* @description.zh-CN 父子关系的映射
*/
);

@@ -576,0 +652,0 @@

@@ -8,5 +8,21 @@ import Graph, { GraphOption } from '.';

declare type JSONEdge<NodeIDType = string, EdgeType = Record<string, any>> = {
/**
* @description The source node id.
* @description.zh-CN 源节点 id。
*/
v: NodeIDType;
/**
* @description The target node id.
* @description.zh-CN 目标节点 id。
*/
w: NodeIDType;
/**
* @description The edge value.
* @description.zh-CN 边的值。
*/
value?: EdgeType;
/**
* @description The edge name.
* @description.zh-CN 边的名称。
*/
name?: string;

@@ -20,4 +36,16 @@ };

};
/**
* @description Convert a graph to JSON.
* @description.zh-CN 转换图为 JSON。
* @param graph
* @returns
*/
export declare const write: <NodeIDType = string, NodeType = Record<string, any>, EdgeType = Record<string, any>, GraphType = string>(graph: Graph<NodeIDType, NodeType, EdgeType, GraphType>) => JSONGraph<NodeIDType, NodeType, EdgeType, GraphType>;
/**
* @description read a graph from JSON.
* @description.zh-CN 从 JSON 读取图。
* @param json
* @returns
*/
export declare const read: <NodeIDType = string, NodeType = Record<string, any>, EdgeType = Record<string, any>, GraphType = string>(json: JSONGraph<NodeIDType, NodeType, EdgeType, GraphType>) => Graph<NodeIDType, NodeType, EdgeType, GraphType>;
export {};
import Graph from '.';
/**
* @description Convert a graph's node to JSON.
* @description.zh-CN 转换图的节点为 JSON。
* @param graph
* @returns
*/

@@ -24,3 +30,10 @@ var nodeToJSON = function nodeToJSON(graph) {

};
/**
* @description Convert all graph's edges to JSON.
* @description.zh-CN 转换图的所有边为 JSON。
* @param graph
* @returns
*/
var edgeToJSON = function edgeToJSON(graph) {

@@ -47,3 +60,10 @@ return graph.edges().map(function (edge) {

};
/**
* @description Convert a graph to JSON.
* @description.zh-CN 转换图为 JSON。
* @param graph
* @returns
*/
export var write = function write(graph) {

@@ -67,2 +87,9 @@ var json = {

};
/**
* @description read a graph from JSON.
* @description.zh-CN 从 JSON 读取图。
* @param json
* @returns
*/
export var read = function read(json) {

@@ -69,0 +96,0 @@ var graph = new Graph(json.options);

import Graph from './Graph';
import { isGraph } from './util';
import * as algorithm from './algorithm';
export { Graph, algorithm };
import * as comparision from './comparison';
export { Graph, algorithm, isGraph, comparision };
import Graph from './Graph';
import { isGraph } from './util';
import * as algorithm from './algorithm';
export { Graph, algorithm };
import * as comparision from './comparison';
export { Graph, algorithm, isGraph, comparision };
export default class PriorityQueue<T = string> {
/**
* @description The internal data structure.
* @description.zh-CN 内部数据结构。
*/
private arr;
/**
* @description the index indiced by the key.
* @description.zh-CN 通过 key 找到的索引。
*/
private keyIndice;
/**
* @description The number of elements in the queue.
* @description.zh-CN 队列中元素的数量。
*/
size: () => number;
/**
* @description all the keys in the queue.
* @description.zh-CN 队列中所有的 key。
*/
keys: () => T[];
/**
* @description does the queue contain the key?
* @description.zh-CN 队列中是否包含 key?
* @param key
* @returns
*/
has: (key: T) => boolean;
/**
* @description get the priority of the key.
* @description.zh-CN 获取 key 的优先级。
* @param key
* @returns
*/
priority: (key: T) => number | undefined;
/**
* @description swap the index of two keys.
* @description.zh-CN 交换两个 key 的索引。
* @param i
* @param j
*/
private swap;
/**
* @description decrease the priority of the key by index
* @description.zh-CN 通过索引减小 key 的优先级。
* @param index
*/
private innerDecrease;
/**
* @description create heap from the array by index
* @description.zh-CN 通过索引创建堆。
* @param i
*/
private heapify;
/**
* @description the key with min priority in the queue.
* @description.zh-CN 队列中优先级最小的 key。
* @returns
*/
min: () => T;
/**
* @description insert a key with priority.
* @description.zh-CN 用优先级插入一个 key。
* @param key
* @param priority
* @returns
*/
add: (key: T, priority: number) => boolean;
/**
* @description remove the key with min priority and return the key.
* @description.zh-CN 删除优先级最小的 key,并返回 key。
* @returns
*/
removeMin: () => T;
/**
* @description decrease the priority of the key.
* @description.zh-CN 通过 key 减小 key 的优先级。
* @param key
* @param priority
*/
decrease: (key: T, priority: number) => void;
}

@@ -7,2 +7,3 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

// A PriorityQueue is a queue that can be sorted by priority.
var PriorityQueue = /*#__PURE__*/_createClass(function PriorityQueue() {

@@ -102,3 +103,3 @@ var _this = this;

var keyIndice = _this.keyIndice,
arr = _this.arr;
arr = _this.arr; // if the key is already in the queue, update the priority

@@ -105,0 +106,0 @@ if (!keyIndice.has(key)) {

import { DefaultEdgeType } from './Graph';
/**
* @description add one to key's value in map
* @description.zh-CN 在 map 中 key 的值加 1
* @param map
* @param key
*/
export declare function incrementOrInitEntry(map: Map<any, any>, key: any): void;
/**
* @description minus one from key's value in map, is value is 0, delete the key
* @description.zh-CN 在 map 中 key 的值减 1,如果值为 0,则删除 key
*/
export declare function decrementOrRemoveEntry(map: Map<any, number>, key: any): void;
/**
* @description convert edge to string id
* @description.zh-CN 转换边为字符串 id
*/
export declare function edgeArgsToId<NodeType>(isDirected: boolean, v_: NodeType, w_: NodeType, name?: any): string;
/**
* @description convert edge arguments to edge object
* @description.zh-CN 转换边参数为边对象
*/
export declare function edgeArgsToObj<NodeType>(isDirected: boolean, v: NodeType, w: NodeType, name?: string): DefaultEdgeType<NodeType, any>;
/**
* @description convert edge object to string id
* @description.zh-CN 转换边对象为字符串 id
*/
export declare function edgeObjToId(isDirected: boolean, edgeObj: {

@@ -11,2 +33,3 @@ v: any;

}): string;
export declare function isFunction(target: any): boolean;
export declare function isFunction(obj: any): boolean;
export declare function isGraph(obj: any): boolean;
import { GraphEnum } from './enum';
import Graph from './Graph';
/**
* @description add one to key's value in map
* @description.zh-CN 在 map 中 key 的值加 1
* @param map
* @param key
*/
export function incrementOrInitEntry(map, key) {

@@ -6,2 +14,7 @@ var val = map.get(key) || 0;

}
/**
* @description minus one from key's value in map, is value is 0, delete the key
* @description.zh-CN 在 map 中 key 的值减 1,如果值为 0,则删除 key
*/
export function decrementOrRemoveEntry(map, key) {

@@ -20,2 +33,7 @@ var val = map.get(key);

}
/**
* @description convert edge to string id
* @description.zh-CN 转换边为字符串 id
*/
export function edgeArgsToId(isDirected, v_, w_, name) {

@@ -33,2 +51,7 @@ var v = String(v_);

}
/**
* @description convert edge arguments to edge object
* @description.zh-CN 转换边参数为边对象
*/
export function edgeArgsToObj(isDirected, v, w, name) {

@@ -54,7 +77,15 @@ var strV = String(v);

}
/**
* @description convert edge object to string id
* @description.zh-CN 转换边对象为字符串 id
*/
export function edgeObjToId(isDirected, edgeObj) {
return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name);
}
export function isFunction(target) {
return !!(target && target.constructor && target.call && target.apply);
export function isFunction(obj) {
return typeof obj === 'function';
}
export function isGraph(obj) {
return obj instanceof Graph;
}
import Graph from '../Graph';
/**
* @description DFS traversal.
* @description.zh-CN DFS 遍历。
*/
declare const dfs: <NodeIDType = any>(graph: Graph<NodeIDType, any, any, any>, node: NodeIDType | NodeIDType[], order: 'pre' | 'post') => NodeIDType[];
export default dfs;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* @description DFS traversal.
* @description.zh-CN DFS 遍历。
*/
var doDFS = function (graph, node, postorder, visited, navigator, result) {

@@ -17,2 +21,6 @@ if (!visited.includes(node)) {

};
/**
* @description DFS traversal.
* @description.zh-CN DFS 遍历。
*/
var dfs = function (graph, node, order) {

@@ -19,0 +27,0 @@ var nodes = Array.isArray(node) ? node : [node];

import Graph, { DefaultEdgeType } from '../Graph';
/**
* @description Dijkstra's algorithm for single-source shortest paths.
* @description https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
* @description.zh-CN Dijkstra 算法用于单源最短路径。
*/
declare const dijkstra: <NodeIDType, EdgeType>(graph: Graph<NodeIDType, any, EdgeType, string>, source: NodeIDType, weightFn?: ((node: DefaultEdgeType<NodeIDType, EdgeType>) => number) | undefined, edgeFn?: ((node: NodeIDType) => DefaultEdgeType<NodeIDType, EdgeType>[]) | undefined) => Record<string, Entry<NodeIDType>>;

@@ -3,0 +8,0 @@ declare type Entry<NodeIDType> = {

@@ -8,2 +8,7 @@ "use strict";

var DEFAULT_WEIGHT_FUNC = function () { return 1; };
/**
* @description Dijkstra's algorithm for single-source shortest paths.
* @description https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
* @description.zh-CN Dijkstra 算法用于单源最短路径。
*/
var dijkstra = function (graph, source, weightFn, edgeFn) {

@@ -15,2 +20,7 @@ return runDijkstra(graph, source, weightFn || DEFAULT_WEIGHT_FUNC, edgeFn ||

};
/**
* @description Dijkstra's algorithm for single-source shortest paths.
* @description https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
* @description.zh-CN Dijkstra 算法用于单源最短路径。
*/
var runDijkstra = function (graph, source, weightFn, edgeFn) {

@@ -33,2 +43,3 @@ var results = new Map();

}
// If there is already a shorter path to w, ignore this edge.
if (distance < wEntry.distance) {

@@ -35,0 +46,0 @@ wEntry.distance = distance;

import Graph from '../Graph';
declare const isAcyclic: <NodeType>(graph: Graph) => boolean;
declare const isAcyclic: (graph: Graph) => boolean;
export default isAcyclic;
import Graph from '../Graph';
/**
* @description Tarjan's algorithm for finding the strongly connected components of a graph.
* @description https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
* @description.zh-CN Tarjan 算法用于找到图的强连通子图。
* @param graph
* @returns
*/
declare const tarjan: <NodeIDType>(graph: Graph<NodeIDType, Record<string, any>, Record<string, any>, string>) => NodeIDType[][];
export default tarjan;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* @description Tarjan's algorithm for finding the strongly connected components of a graph.
* @description https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
* @description.zh-CN Tarjan 算法用于找到图的强连通子图。
* @param graph
* @returns
*/
var tarjan = function (graph) {

@@ -20,2 +27,3 @@ var index = 0;

var _a;
// 如果 w 没有被访问过,则继续访问 w
if (!visited.has(w)) {

@@ -25,8 +33,11 @@ dfs(w);

entry.lowlink = Math.min(entry.lowlink, wEntry.lowlink);
// 如果 w 在栈顶,则说明 w 和 v 不是强连通的
}
else if ((_a = visited.get(w)) === null || _a === void 0 ? void 0 : _a.onStack) {
var wEntry = visited.get(w);
// 如果 w 在栈中,则说明 w 在当前访问的路径上
entry.lowlink = Math.min(entry.lowlink, wEntry.index);
}
});
// 如果 v 的 lowlink 不等于 v 的 index,则说明 v 和 v 的 lowlink 不是强连通的
if (entry.lowlink === entry.index) {

@@ -36,2 +47,3 @@ var cmpt = [];

do {
// 将 w 出栈,并将 w 的所有邻接点加入强连通子图
w = stack.pop();

@@ -38,0 +50,0 @@ var wEntry = visited.get(w);

@@ -22,5 +22,21 @@ export interface GraphOption {

export interface DefaultEdgeType<NodeIDType, EdgeType> {
/**
* @description the node where this edge start
* @description.zh-CN 边开始的节点
*/
v: NodeIDType;
/**
* @description the node where this edge end
* @description.zh-CN 边结束的节点
*/
w: NodeIDType;
/**
* @description The name used to distinguish the multilateral relationship between two nodes
* @description.zh-CN 用来区分两点之间的多边关系的名称
*/
name?: string;
/**
* @description The value of the edge
* @description.zh-CN 边的值
*/
value?: EdgeType;

@@ -51,13 +67,49 @@ }

private edgeCountNum;
/**
* @description return node label with its id
* @description.zh-CN 返回节点的默认的标签
*/
private defaultNodeLabelFn;
/**
* @description return edge label with its id
* @description.zh-CN 返回边的默认的标签
*/
private defaultEdgeLabelFn;
constructor(options?: GraphOption);
/**
* @description Map for parent relationship
* @description.zh-CN 父子关系的映射
*/
private parentMap?;
/**
* @description Map for children relationship
* @description.zh-CN 子孙关系的映射
*/
private childrenMap?;
private nodesLabelMap;
/**
* @description Map for edges
* @description.zh-CN 边的映射
*/
private inEdgesMap;
private outEdgesMap;
/**
* @description Map for predecessors
* @description.zh-CN 前驱节点的映射
*/
private predecessorsMap;
/**
* @description Map for successors
* @description.zh-CN 后继节点的映射
*/
private successorsMap;
/**
* @description Map for edge object
* @description.zh-CN 边的映射
*/
private edgesMap;
/**
* @description Map for edge label
* @description.zh-CN 边的标签的映射
*/
private edgesLabelsMap;

@@ -108,2 +160,6 @@ /**

nodeCount: () => number;
/**
* @description get node label
* @description.zh-CN 获取节点的标签
*/
node: (n: NodeIDType) => NodeType | undefined;

@@ -296,2 +352,6 @@ /**

removeEdge: (v_: NodeIDType, w_: NodeIDType, name?: any) => this;
/**
* @description remove a specific edge by edge object
* @description.zh-CN 删除一条边
*/
removeEdgeObj: ({ v, w, name }: {

@@ -302,2 +362,6 @@ v: NodeIDType;

}) => this;
/**
* @description get all edges object in graph
* @description.zh-CN 获得图中所有的边对象
*/
edges: () => DefaultEdgeType<NodeIDType, EdgeType>[];

@@ -358,2 +422,32 @@ /**

};
/**
* @description Count the in edges of node
* @description.zh-CN 计算节点的入边的数量
*/
nodeInDegree: (node: NodeIDType) => number;
/**
* @description Count the out edges of node
* @description.zh-CN 计算节点的出边的数量
*/
nodeOutDegree: (node: NodeIDType) => number;
/**
* @description Count the total edges of node
* @description.zh-CN 计算节点的所有边的数量
*/
nodeDegree: (node: NodeIDType) => number;
/**
* @description Get the source of edge
* @description.zh-CN 获取边的源节点
*/
source: (edge: DefaultEdgeType<NodeIDType, EdgeType>) => NodeIDType;
/**
* @description Get the target of edge
* @description.zh-CN 获取边的目标节点
*/
target: (edge: DefaultEdgeType<NodeIDType, EdgeType>) => NodeIDType;
/**
* @description Count the total edges with self loop
* @description.zh-CN 计算节点的自环边的数量
*/
countSelfLoops: () => number;
}

@@ -44,10 +44,38 @@ "use strict";

this.edgeCountNum = 0;
/**
* @description return node label with its id
* @description.zh-CN 返回节点的默认的标签
*/
this.defaultNodeLabelFn = function () { return undefined; };
/**
* @description return edge label with its id
* @description.zh-CN 返回边的默认的标签
*/
this.defaultEdgeLabelFn = function () { return undefined; };
this.nodesLabelMap = new Map();
/**
* @description Map for edges
* @description.zh-CN 边的映射
*/
this.inEdgesMap = new Map();
this.outEdgesMap = new Map();
/**
* @description Map for predecessors
* @description.zh-CN 前驱节点的映射
*/
this.predecessorsMap = new Map();
/**
* @description Map for successors
* @description.zh-CN 后继节点的映射
*/
this.successorsMap = new Map();
/**
* @description Map for edge object
* @description.zh-CN 边的映射
*/
this.edgesMap = new Map();
/**
* @description Map for edge label
* @description.zh-CN 边的标签的映射
*/
this.edgesLabelsMap = new Map();

@@ -109,2 +137,6 @@ /**

this.nodeCount = function () { return _this.nodeCountNum; };
/**
* @description get node label
* @description.zh-CN 获取节点的标签
*/
this.node = function (n) { return _this.nodesLabelMap.get(n); };

@@ -139,2 +171,3 @@ /**

var _b = _this, nodesLabelMap = _b.nodesLabelMap, defaultNodeLabelFn = _b.defaultNodeLabelFn, isCompound = _b.isCompound, parentMap = _b.parentMap, childrenMap = _b.childrenMap, inEdgesMap = _b.inEdgesMap, outEdgesMap = _b.outEdgesMap, predecessorsMap = _b.predecessorsMap, successorsMap = _b.successorsMap;
// 如果节点不在图中,则创建节点
if (nodesLabelMap.has(node)) {

@@ -147,2 +180,3 @@ if (value !== undefined) {

nodesLabelMap.set(node, value || defaultNodeLabelFn(node));
// 如果是复合图,则创建节点的子节点
if (isCompound()) {

@@ -510,2 +544,6 @@ parentMap === null || parentMap === void 0 ? void 0 : parentMap.set(node, _this.GRAPH_NODE);

};
/**
* @description remove a specific edge by edge object
* @description.zh-CN 删除一条边
*/
this.removeEdgeObj = function (_a) {

@@ -515,2 +553,6 @@ var v = _a.v, w = _a.w, name = _a.name;

};
/**
* @description get all edges object in graph
* @description.zh-CN 获得图中所有的边对象
*/
this.edges = function () { return Array.from(_this.edgesMap.values()); };

@@ -560,2 +602,56 @@ /**

this.toJSON = function () { return (0, toJSON_1.write)(_this); };
// ver 2 function
/**
* @description Count the in edges of node
* @description.zh-CN 计算节点的入边的数量
*/
this.nodeInDegree = function (node) {
var inEdges = _this.inEdgesMap.get(node);
if (inEdges) {
return inEdges.size;
}
return 0;
};
/**
* @description Count the out edges of node
* @description.zh-CN 计算节点的出边的数量
*/
this.nodeOutDegree = function (node) {
var outEdges = _this.outEdgesMap.get(node);
if (outEdges) {
return outEdges.size;
}
return 0;
};
/**
* @description Count the total edges of node
* @description.zh-CN 计算节点的所有边的数量
*/
this.nodeDegree = function (node) {
return _this.nodeInDegree(node) + _this.nodeOutDegree(node);
};
/**
* @description Get the source of edge
* @description.zh-CN 获取边的源节点
*/
this.source = function (edge) { return edge.v; };
/**
* @description Get the target of edge
* @description.zh-CN 获取边的目标节点
*/
this.target = function (edge) { return edge.w; };
/**
* @description Count the total edges with self loop
* @description.zh-CN 计算节点的自环边的数量
*/
this.countSelfLoops = function () {
var count = 0;
for (var _i = 0, _a = _this.edges(); _i < _a.length; _i++) {
var edge = _a[_i];
if (edge.v === edge.w) {
count += 1;
}
}
return count;
};
var resultOptions = __assign(__assign({}, defaultOption), options);

@@ -562,0 +658,0 @@ this.compound = resultOptions.compound;

@@ -8,5 +8,21 @@ import Graph, { GraphOption } from '.';

declare type JSONEdge<NodeIDType = string, EdgeType = Record<string, any>> = {
/**
* @description The source node id.
* @description.zh-CN 源节点 id。
*/
v: NodeIDType;
/**
* @description The target node id.
* @description.zh-CN 目标节点 id。
*/
w: NodeIDType;
/**
* @description The edge value.
* @description.zh-CN 边的值。
*/
value?: EdgeType;
/**
* @description The edge name.
* @description.zh-CN 边的名称。
*/
name?: string;

@@ -20,4 +36,16 @@ };

};
/**
* @description Convert a graph to JSON.
* @description.zh-CN 转换图为 JSON。
* @param graph
* @returns
*/
export declare const write: <NodeIDType = string, NodeType = Record<string, any>, EdgeType = Record<string, any>, GraphType = string>(graph: Graph<NodeIDType, NodeType, EdgeType, GraphType>) => JSONGraph<NodeIDType, NodeType, EdgeType, GraphType>;
/**
* @description read a graph from JSON.
* @description.zh-CN 从 JSON 读取图。
* @param json
* @returns
*/
export declare const read: <NodeIDType = string, NodeType = Record<string, any>, EdgeType = Record<string, any>, GraphType = string>(json: JSONGraph<NodeIDType, NodeType, EdgeType, GraphType>) => Graph<NodeIDType, NodeType, EdgeType, GraphType>;
export {};

@@ -8,2 +8,8 @@ "use strict";

var _1 = __importDefault(require("."));
/**
* @description Convert a graph's node to JSON.
* @description.zh-CN 转换图的节点为 JSON。
* @param graph
* @returns
*/
var nodeToJSON = function (graph) {

@@ -27,2 +33,8 @@ return graph.nodes().map(function (n) {

};
/**
* @description Convert all graph's edges to JSON.
* @description.zh-CN 转换图的所有边为 JSON。
* @param graph
* @returns
*/
var edgeToJSON = function (graph) {

@@ -46,2 +58,8 @@ return graph.edges().map(function (edge) {

};
/**
* @description Convert a graph to JSON.
* @description.zh-CN 转换图为 JSON。
* @param graph
* @returns
*/
var write = function (graph) {

@@ -64,2 +82,8 @@ var json = {

exports.write = write;
/**
* @description read a graph from JSON.
* @description.zh-CN 从 JSON 读取图。
* @param json
* @returns
*/
var read = function (json) {

@@ -66,0 +90,0 @@ var graph = new _1.default(json.options);

import Graph from './Graph';
import { isGraph } from './util';
import * as algorithm from './algorithm';
export { Graph, algorithm };
import * as comparision from './comparison';
export { Graph, algorithm, isGraph, comparision };

@@ -25,6 +25,10 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.algorithm = exports.Graph = void 0;
exports.comparision = exports.isGraph = exports.algorithm = exports.Graph = void 0;
var Graph_1 = __importDefault(require("./Graph"));
exports.Graph = Graph_1.default;
var util_1 = require("./util");
Object.defineProperty(exports, "isGraph", { enumerable: true, get: function () { return util_1.isGraph; } });
var algorithm = __importStar(require("./algorithm"));
exports.algorithm = algorithm;
var comparision = __importStar(require("./comparison"));
exports.comparision = comparision;
export default class PriorityQueue<T = string> {
/**
* @description The internal data structure.
* @description.zh-CN 内部数据结构。
*/
private arr;
/**
* @description the index indiced by the key.
* @description.zh-CN 通过 key 找到的索引。
*/
private keyIndice;
/**
* @description The number of elements in the queue.
* @description.zh-CN 队列中元素的数量。
*/
size: () => number;
/**
* @description all the keys in the queue.
* @description.zh-CN 队列中所有的 key。
*/
keys: () => T[];
/**
* @description does the queue contain the key?
* @description.zh-CN 队列中是否包含 key?
* @param key
* @returns
*/
has: (key: T) => boolean;
/**
* @description get the priority of the key.
* @description.zh-CN 获取 key 的优先级。
* @param key
* @returns
*/
priority: (key: T) => number | undefined;
/**
* @description swap the index of two keys.
* @description.zh-CN 交换两个 key 的索引。
* @param i
* @param j
*/
private swap;
/**
* @description decrease the priority of the key by index
* @description.zh-CN 通过索引减小 key 的优先级。
* @param index
*/
private innerDecrease;
/**
* @description create heap from the array by index
* @description.zh-CN 通过索引创建堆。
* @param i
*/
private heapify;
/**
* @description the key with min priority in the queue.
* @description.zh-CN 队列中优先级最小的 key。
* @returns
*/
min: () => T;
/**
* @description insert a key with priority.
* @description.zh-CN 用优先级插入一个 key。
* @param key
* @param priority
* @returns
*/
add: (key: T, priority: number) => boolean;
/**
* @description remove the key with min priority and return the key.
* @description.zh-CN 删除优先级最小的 key,并返回 key。
* @returns
*/
removeMin: () => T;
/**
* @description decrease the priority of the key.
* @description.zh-CN 通过 key 减小 key 的优先级。
* @param key
* @param priority
*/
decrease: (key: T, priority: number) => void;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// A PriorityQueue is a queue that can be sorted by priority.
var PriorityQueue = /** @class */ (function () {
function PriorityQueue() {
var _this = this;
/**
* @description The internal data structure.
* @description.zh-CN 内部数据结构。
*/
this.arr = [];
/**
* @description the index indiced by the key.
* @description.zh-CN 通过 key 找到的索引。
*/
this.keyIndice = new Map();
/**
* @description The number of elements in the queue.
* @description.zh-CN 队列中元素的数量。
*/
this.size = function () { return _this.arr.length; };
/**
* @description all the keys in the queue.
* @description.zh-CN 队列中所有的 key。
*/
this.keys = function () { return _this.arr.map(function (e) { return e.key; }); };
/**
* @description does the queue contain the key?
* @description.zh-CN 队列中是否包含 key?
* @param key
* @returns
*/
this.has = function (key) { return _this.keyIndice.has(key); };
/**
* @description get the priority of the key.
* @description.zh-CN 获取 key 的优先级。
* @param key
* @returns
*/
this.priority = function (key) {

@@ -17,2 +46,8 @@ var index = _this.keyIndice.get(key);

};
/**
* @description swap the index of two keys.
* @description.zh-CN 交换两个 key 的索引。
* @param i
* @param j
*/
this.swap = function (i, j) {

@@ -26,2 +61,7 @@ var _a = _this, arr = _a.arr, keyIndice = _a.keyIndice;

};
/**
* @description decrease the priority of the key by index
* @description.zh-CN 通过索引减小 key 的优先级。
* @param index
*/
this.innerDecrease = function (index) {

@@ -42,2 +82,7 @@ var _a;

};
/**
* @description create heap from the array by index
* @description.zh-CN 通过索引创建堆。
* @param i
*/
this.heapify = function (i) {

@@ -59,2 +104,7 @@ var arr = _this.arr;

};
/**
* @description the key with min priority in the queue.
* @description.zh-CN 队列中优先级最小的 key。
* @returns
*/
this.min = function () {

@@ -66,4 +116,12 @@ if (_this.size() === 0) {

};
/**
* @description insert a key with priority.
* @description.zh-CN 用优先级插入一个 key。
* @param key
* @param priority
* @returns
*/
this.add = function (key, priority) {
var _a = _this, keyIndice = _a.keyIndice, arr = _a.arr;
// if the key is already in the queue, update the priority
if (!keyIndice.has(key)) {

@@ -81,2 +139,7 @@ var index = arr.length;

};
/**
* @description remove the key with min priority and return the key.
* @description.zh-CN 删除优先级最小的 key,并返回 key。
* @returns
*/
this.removeMin = function () {

@@ -89,2 +152,8 @@ _this.swap(0, _this.arr.length - 1);

};
/**
* @description decrease the priority of the key.
* @description.zh-CN 通过 key 减小 key 的优先级。
* @param key
* @param priority
*/
this.decrease = function (key, priority) {

@@ -91,0 +160,0 @@ if (!_this.has(key)) {

import { DefaultEdgeType } from './Graph';
/**
* @description add one to key's value in map
* @description.zh-CN 在 map 中 key 的值加 1
* @param map
* @param key
*/
export declare function incrementOrInitEntry(map: Map<any, any>, key: any): void;
/**
* @description minus one from key's value in map, is value is 0, delete the key
* @description.zh-CN 在 map 中 key 的值减 1,如果值为 0,则删除 key
*/
export declare function decrementOrRemoveEntry(map: Map<any, number>, key: any): void;
/**
* @description convert edge to string id
* @description.zh-CN 转换边为字符串 id
*/
export declare function edgeArgsToId<NodeType>(isDirected: boolean, v_: NodeType, w_: NodeType, name?: any): string;
/**
* @description convert edge arguments to edge object
* @description.zh-CN 转换边参数为边对象
*/
export declare function edgeArgsToObj<NodeType>(isDirected: boolean, v: NodeType, w: NodeType, name?: string): DefaultEdgeType<NodeType, any>;
/**
* @description convert edge object to string id
* @description.zh-CN 转换边对象为字符串 id
*/
export declare function edgeObjToId(isDirected: boolean, edgeObj: {

@@ -11,2 +33,3 @@ v: any;

}): string;
export declare function isFunction(target: any): boolean;
export declare function isFunction(obj: any): boolean;
export declare function isGraph(obj: any): boolean;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isFunction = exports.edgeObjToId = exports.edgeArgsToObj = exports.edgeArgsToId = exports.decrementOrRemoveEntry = exports.incrementOrInitEntry = void 0;
exports.isGraph = exports.isFunction = exports.edgeObjToId = exports.edgeArgsToObj = exports.edgeArgsToId = exports.decrementOrRemoveEntry = exports.incrementOrInitEntry = void 0;
var enum_1 = require("./enum");
var Graph_1 = __importDefault(require("./Graph"));
/**
* @description add one to key's value in map
* @description.zh-CN 在 map 中 key 的值加 1
* @param map
* @param key
*/
function incrementOrInitEntry(map, key) {

@@ -10,2 +20,6 @@ var val = map.get(key) || 0;

exports.incrementOrInitEntry = incrementOrInitEntry;
/**
* @description minus one from key's value in map, is value is 0, delete the key
* @description.zh-CN 在 map 中 key 的值减 1,如果值为 0,则删除 key
*/
function decrementOrRemoveEntry(map, key) {

@@ -24,2 +38,6 @@ var val = map.get(key);

exports.decrementOrRemoveEntry = decrementOrRemoveEntry;
/**
* @description convert edge to string id
* @description.zh-CN 转换边为字符串 id
*/
function edgeArgsToId(isDirected, v_, w_, name) {

@@ -40,2 +58,6 @@ var v = String(v_);

exports.edgeArgsToId = edgeArgsToId;
/**
* @description convert edge arguments to edge object
* @description.zh-CN 转换边参数为边对象
*/
function edgeArgsToObj(isDirected, v, w, name) {

@@ -56,2 +78,6 @@ var strV = String(v);

exports.edgeArgsToObj = edgeArgsToObj;
/**
* @description convert edge object to string id
* @description.zh-CN 转换边对象为字符串 id
*/
function edgeObjToId(isDirected, edgeObj) {

@@ -61,5 +87,9 @@ return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name);

exports.edgeObjToId = edgeObjToId;
function isFunction(target) {
return !!(target && target.constructor && target.call && target.apply);
function isFunction(obj) {
return typeof obj === 'function';
}
exports.isFunction = isFunction;
function isGraph(obj) {
return obj instanceof Graph_1.default;
}
exports.isGraph = isGraph;
{
"name": "@antv/graphlib",
"version": "1.0.2",
"version": "1.1.0",
"scripts": {
"start": "dumi dev",
"docs:build": "dumi build",
"docs:build": "typedoc --plugin typedoc-plugin-markdown --out docs src/index.ts",
"docs:deploy": "gh-pages -d docs-dist",

@@ -55,4 +55,6 @@ "build:esm": "father-build",

"sprintf": "^0.1.5",
"typedoc": "^0.22.15",
"typedoc-plugin-markdown": "^3.12.0",
"yorkie": "^2.0.0"
}
}
# Graphlib
> The typescript rewrite version of @dagrejs/graphlib, because graphlib was old and lacked typescript annotations, which led to inconsistent typescript files and even compilation failure or failure due to the typescript of Graphlib, antv team has rewritten it;
> a lib containing multible usages for graph structure, graph algorithm, and other graph ops.
>
> 一个包含方便的图结构,图算法,以及其他操作图的方法的图库,为 antv 上层提供相应的图基础能力
![build status](https://img.shields.io/github/workflow/status/antvis/graphlib/Build) ![coverage status](https://img.shields.io/codecov/c/github/mxz96102/new-graphlib)
![build status](https://img.shields.io/github/workflow/status/antvis/graphlib/Build) ![coverage status](https://img.shields.io/codecov/c/github/antvis/graphlib)
### Improvements and break changes
## Content of Package
- Graph has a type that accepts four parameters `<NodeIDType,NodeType, EdgeType, GraphType>` to make it easier for users to customize it themselves, no longer stuck to the original single number/string type, now because of the use of Map and Set, you can use any type (including reference Now, because of Map and Set, you can use any type (including reference type) as the index of a point.
- no longer accept the same node ID string, 1 and "1" are two different points, no automatic type conversion of NodeIDType comparison. 1.
- Graph's edge-related methods `edge` `setEdge` `removeEdge` no longer accept type overloading.
- `edge` `setEdgeObj` `removeEdgeObj` accepts an edgeObj
- `edgeFromArgs` `setEdge` `removeEdge` accepts specific parameters (v, w, name, value)
### Namespaces
### Benchmark
- [algorithm](docs/modules/algorithm.md)
- [comparision](docs/modules/comparision.md)
| test\\performance(ops/s) | @dagre/graphlib | @antv/graphlib | times |
| ------------------------- | --------------- | -------------- | -------- |
| nodes(100,0.2) | 353,396.95 | 3,429,316.12 | **9.7** |
| sources(100,0.2) | 10,521.67 | 392,493.77 | **37** |
| sinks(100,0.2) | 10,959.91 | 386,649.19 | **35** |
| filterNodes all(100,0.2) | 153.71 | 309.45 | **2.0** |
| filterNodes none(100,0.2) | 2,519.81 | 9,639.13 | **3.83** |
| setNode(100,0.2) | 12,312,125.13 | 46,866,922.24 | **3.81** |
| node(100,0.2) | 28,205,461.65 | 47,093,921.57 | **1.67** |
| set + removeNode(100,0.2) | 1,272,331.16 | 391,557.00 | **0.31** |
| predecessors(100,0.2) | 1,307,177.14 | 7,508,958.21 | **5.7** |
| successors(100,0.2) | 1,485,256.81 | 7,448,177.23 | **5.0** |
| neighbors(100,0.2) | 250,082.05 | 326,744.33 | **1.31** |
| edges(100,0.2) | 4,594.50 | 195,840.56 | **43** |
| setPath(100,0.2) | 1,056,189.24 | 1,579,308.80 | **1.5** |
| setEdge(100,0.2) | 4,483,547.20 | 5,541,620.41 | **1.24** |
| edge(100,0.2) | 3,254,316.17 | 7,126,976.06 | **2.2** |
| set + removeEdge(100,0.2) | 557,579.88 | 76,798.23 | **0.14** |
| inEdges(100,0.2) | 710,823.70 | 3,856,353.97 | **5.4** |
| outEdges(100,0.2) | 690,512.54 | 3,756,590.81 | **5.4** |
| nodeEdges(100,0.2) | 309,098.91 | 1,263,443.14 | **4.1** |
| components(100,0.2) | 1,729.79 | 5,321.20 | **3.1** |
| dijkstraAll(100,0.2) | 30.83 | 47.73 | **1.55** |
### Classes
### Test Coverage
- [Graph](docs/classes/Graph.md)
| File | % Stmts | % Branch | % Funcs | % Lines |
| ----------------- | ------- | -------- | ------- | ------- |
| All files | 100 | 100 | 100 | 100 |
| src | 100 | 100 | 100 | 100 |
| enum.ts | 0 | 0 | 0 | 0 |
| index.ts | 0 | 0 | 0 | 0 |
| util.ts | 100 | 100 | 100 | 100 |
| src/Graph | 100 | 100 | 100 | 100 |
| index.ts | 100 | 100 | 100 | 100 |
| src/PriorityQueue | 100 | 100 | 100 | 100 |
| index.ts | 100 | 100 | 100 | 100 |
| src/algorithm | 100 | 100 | 100 | 100 |
| components.ts | 100 | 100 | 100 | 100 |
| dfs.ts | 100 | 100 | 100 | 100 |
| dijkstra-all.ts | 100 | 100 | 100 | 100 |
| dijkstra.ts | 100 | 100 | 100 | 100 |
| find-cycles.ts | 100 | 100 | 100 | 100 |
| floyd-warshall.ts | 100 | 100 | 100 | 100 |
| index.ts | 0 | 0 | 0 | 0 |
| is-acyclic.ts | 100 | 100 | 100 | 100 |
| postorder.ts | 100 | 100 | 100 | 100 |
| preorder.ts | 100 | 100 | 100 | 100 |
| prim.ts | 100 | 100 | 100 | 100 |
| tarjan.ts | 100 | 100 | 100 | 100 |
| topsort.ts | 100 | 100 | 100 | 100 |
### Functions
- [isGraph](docs/modules.md#isgraph)
## Change Log
#### 1.1.0
- 🎉 Now we have comparision module for graph comparing with nodes/edges/options even subgraph
- 💪 Add isGraph to check if a object is a "Graph", and add a self loop checking function
#### 1.0.1
- 🔨 Completes test and bring all to 100%
#### 1.0.0
- 🎉 Release new graphlib with graph and algorithm
import Graph from '../Graph';
/**
* @description DFS traversal.
* @description.zh-CN DFS 遍历。
*/
const doDFS = <NodeIDType = any>(

@@ -25,2 +29,6 @@ graph: Graph<NodeIDType>,

/**
* @description DFS traversal.
* @description.zh-CN DFS 遍历。
*/
const dfs = <NodeIDType = any>(

@@ -27,0 +35,0 @@ graph: Graph<NodeIDType, any, any, any>,

@@ -6,2 +6,7 @@ import Graph, { DefaultEdgeType } from '../Graph';

/**
* @description Dijkstra's algorithm for single-source shortest paths.
* @description https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
* @description.zh-CN Dijkstra 算法用于单源最短路径。
*/
const dijkstra = <NodeIDType, EdgeType>(

@@ -29,2 +34,7 @@ graph: Graph<NodeIDType, any, EdgeType>,

/**
* @description Dijkstra's algorithm for single-source shortest paths.
* @description https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
* @description.zh-CN Dijkstra 算法用于单源最短路径。
*/
const runDijkstra = <NodeIDType, EdgeType>(

@@ -58,2 +68,3 @@ graph: Graph<NodeIDType, any, EdgeType>,

// If there is already a shorter path to w, ignore this edge.
if (distance < wEntry.distance) {

@@ -60,0 +71,0 @@ wEntry.distance = distance;

import Graph from '../Graph';
import topsort, { CycleException } from './topsort';
const isAcyclic = <NodeType>(graph: Graph) => {
const isAcyclic = (graph: Graph) => {
try {

@@ -6,0 +6,0 @@ topsort(graph);

@@ -9,2 +9,9 @@ import Graph from '../Graph';

/**
* @description Tarjan's algorithm for finding the strongly connected components of a graph.
* @description https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
* @description.zh-CN Tarjan 算法用于找到图的强连通子图。
* @param graph
* @returns
*/
const tarjan = <NodeIDType>(graph: Graph<NodeIDType>) => {

@@ -27,2 +34,3 @@ let index = 0;

graph.successors(v)?.forEach(function (w) {
// 如果 w 没有被访问过,则继续访问 w
if (!visited.has(w)) {

@@ -32,4 +40,6 @@ dfs(w);

entry.lowlink = Math.min(entry.lowlink, wEntry!.lowlink);
// 如果 w 在栈顶,则说明 w 和 v 不是强连通的
} else if (visited.get(w)?.onStack) {
const wEntry = visited.get(w);
// 如果 w 在栈中,则说明 w 在当前访问的路径上
entry.lowlink = Math.min(entry.lowlink, wEntry!.index);

@@ -39,2 +49,3 @@ }

// 如果 v 的 lowlink 不等于 v 的 index,则说明 v 和 v 的 lowlink 不是强连通的
if (entry.lowlink === entry.index) {

@@ -44,2 +55,3 @@ const cmpt = [];

do {
// 将 w 出栈,并将 w 的所有邻接点加入强连通子图
w = stack.pop()!;

@@ -46,0 +58,0 @@ const wEntry = visited.get(w)!;

@@ -36,5 +36,21 @@ import { edgeArgsToId, isFunction } from '../util';

export interface DefaultEdgeType<NodeIDType, EdgeType> {
/**
* @description the node where this edge start
* @description.zh-CN 边开始的节点
*/
v: NodeIDType;
/**
* @description the node where this edge end
* @description.zh-CN 边结束的节点
*/
w: NodeIDType;
/**
* @description The name used to distinguish the multilateral relationship between two nodes
* @description.zh-CN 用来区分两点之间的多边关系的名称
*/
name?: string;
/**
* @description The value of the edge
* @description.zh-CN 边的值
*/
value?: EdgeType;

@@ -81,4 +97,12 @@ }

/**
* @description return node label with its id
* @description.zh-CN 返回节点的默认的标签
*/
private defaultNodeLabelFn: (v: NodeIDType) => NodeType | undefined = () => undefined;
/**
* @description return edge label with its id
* @description.zh-CN 返回边的默认的标签
*/
private defaultEdgeLabelFn: (

@@ -107,4 +131,12 @@ v: NodeIDType,

/**
* @description Map for parent relationship
* @description.zh-CN 父子关系的映射
*/
private parentMap?: Map<NodeIDType, NodeIDType>;
/**
* @description Map for children relationship
* @description.zh-CN 子孙关系的映射
*/
private childrenMap?: Map<NodeIDType, Map<NodeIDType, boolean>>;

@@ -114,2 +146,6 @@

/**
* @description Map for edges
* @description.zh-CN 边的映射
*/
private inEdgesMap = new Map<NodeIDType, Map<EdgeID, DefaultEdgeType<NodeIDType, EdgeType>>>();

@@ -119,8 +155,24 @@

/**
* @description Map for predecessors
* @description.zh-CN 前驱节点的映射
*/
private predecessorsMap = new Map<NodeIDType, Map<NodeIDType, number>>();
/**
* @description Map for successors
* @description.zh-CN 后继节点的映射
*/
private successorsMap = new Map<NodeIDType, Map<NodeIDType, number>>();
/**
* @description Map for edge object
* @description.zh-CN 边的映射
*/
private edgesMap = new Map<string, DefaultEdgeType<NodeIDType, EdgeType>>();
/**
* @description Map for edge label
* @description.zh-CN 边的标签的映射
*/
private edgesLabelsMap = new Map<string, EdgeType | undefined>();

@@ -189,2 +241,6 @@

/**
* @description get node label
* @description.zh-CN 获取节点的标签
*/
node = (n: NodeIDType) => this.nodesLabelMap.get(n);

@@ -232,2 +288,4 @@

} = this;
// 如果节点不在图中,则创建节点
if (nodesLabelMap.has(node)) {

@@ -242,2 +300,3 @@ if (value !== undefined) {

// 如果是复合图,则创建节点的子节点
if (isCompound()) {

@@ -599,3 +658,2 @@ parentMap?.set(node, this.GRAPH_NODE);

*/
edgeFromArgs = (v: NodeIDType, w: NodeIDType, name?: any) => {

@@ -655,2 +713,6 @@ return this.edge({ v, w, name });

/**
* @description remove a specific edge by edge object
* @description.zh-CN 删除一条边
*/
removeEdgeObj = ({ v, w, name }: { v: NodeIDType; w: NodeIDType; name?: any }) => {

@@ -660,2 +722,6 @@ return this.removeEdge(v, w, name);

/**
* @description get all edges object in graph
* @description.zh-CN 获得图中所有的边对象
*/
edges = () => Array.from(this.edgesMap.values());

@@ -710,2 +776,62 @@

toJSON = () => write<NodeIDType, NodeType, EdgeType, GraphType>(this);
// ver 2 function
/**
* @description Count the in edges of node
* @description.zh-CN 计算节点的入边的数量
*/
nodeInDegree = (node: NodeIDType) => {
const inEdges = this.inEdgesMap.get(node);
if (inEdges) {
return inEdges.size;
}
return 0;
};
/**
* @description Count the out edges of node
* @description.zh-CN 计算节点的出边的数量
*/
nodeOutDegree = (node: NodeIDType) => {
const outEdges = this.outEdgesMap.get(node);
if (outEdges) {
return outEdges.size;
}
return 0;
};
/**
* @description Count the total edges of node
* @description.zh-CN 计算节点的所有边的数量
*/
nodeDegree = (node: NodeIDType) => {
return this.nodeInDegree(node) + this.nodeOutDegree(node);
};
/**
* @description Get the source of edge
* @description.zh-CN 获取边的源节点
*/
source = (edge: DefaultEdgeType<NodeIDType, EdgeType>) => edge.v;
/**
* @description Get the target of edge
* @description.zh-CN 获取边的目标节点
*/
target = (edge: DefaultEdgeType<NodeIDType, EdgeType>) => edge.w;
/**
* @description Count the total edges with self loop
* @description.zh-CN 计算节点的自环边的数量
*/
countSelfLoops = () => {
let count = 0;
for (const edge of this.edges()) {
if (edge.v === edge.w) {
count += 1;
}
}
return count;
};
}

@@ -9,2 +9,8 @@ import Graph, { GraphOption } from '.';

/**
* @description Convert a graph's node to JSON.
* @description.zh-CN 转换图的节点为 JSON。
* @param graph
* @returns
*/
const nodeToJSON = <NodeIDType = string, NodeType = any>(

@@ -32,8 +38,30 @@ graph: Graph<NodeIDType, NodeType, any, any>,

type JSONEdge<NodeIDType = string, EdgeType = Record<string, any>> = {
/**
* @description The source node id.
* @description.zh-CN 源节点 id。
*/
v: NodeIDType;
/**
* @description The target node id.
* @description.zh-CN 目标节点 id。
*/
w: NodeIDType;
/**
* @description The edge value.
* @description.zh-CN 边的值。
*/
value?: EdgeType;
/**
* @description The edge name.
* @description.zh-CN 边的名称。
*/
name?: string;
};
/**
* @description Convert all graph's edges to JSON.
* @description.zh-CN 转换图的所有边为 JSON。
* @param graph
* @returns
*/
const edgeToJSON = <NodeIDType = string, EdgeType = Record<string, any>>(

@@ -70,2 +98,8 @@ graph: Graph<NodeIDType, any, EdgeType, any>,

/**
* @description Convert a graph to JSON.
* @description.zh-CN 转换图为 JSON。
* @param graph
* @returns
*/
export const write = <

@@ -96,2 +130,8 @@ NodeIDType = string,

/**
* @description read a graph from JSON.
* @description.zh-CN 从 JSON 读取图。
* @param json
* @returns
*/
export const read = <

@@ -98,0 +138,0 @@ NodeIDType = string,

import Graph from './Graph';
import { isGraph } from './util';
import * as algorithm from './algorithm';
import * as comparision from './comparison';
export { Graph, algorithm };
export { Graph, algorithm, isGraph, comparision };

@@ -0,11 +1,41 @@

// A PriorityQueue is a queue that can be sorted by priority.
export default class PriorityQueue<T = string> {
/**
* @description The internal data structure.
* @description.zh-CN 内部数据结构。
*/
private arr: { key: T; priority: number }[] = [];
/**
* @description the index indiced by the key.
* @description.zh-CN 通过 key 找到的索引。
*/
private keyIndice = new Map<T, number>();
/**
* @description The number of elements in the queue.
* @description.zh-CN 队列中元素的数量。
*/
size = () => this.arr.length;
/**
* @description all the keys in the queue.
* @description.zh-CN 队列中所有的 key。
*/
keys = () => this.arr.map((e) => e.key);
/**
* @description does the queue contain the key?
* @description.zh-CN 队列中是否包含 key?
* @param key
* @returns
*/
has = (key: T) => this.keyIndice.has(key);
/**
* @description get the priority of the key.
* @description.zh-CN 获取 key 的优先级。
* @param key
* @returns
*/
priority = (key: T) => {

@@ -19,2 +49,8 @@ const index = this.keyIndice.get(key);

/**
* @description swap the index of two keys.
* @description.zh-CN 交换两个 key 的索引。
* @param i
* @param j
*/
private swap = (i: number, j: number) => {

@@ -29,2 +65,7 @@ const { arr, keyIndice } = this;

/**
* @description decrease the priority of the key by index
* @description.zh-CN 通过索引减小 key 的优先级。
* @param index
*/
private innerDecrease = (index: number) => {

@@ -46,2 +87,7 @@ const { arr } = this;

/**
* @description create heap from the array by index
* @description.zh-CN 通过索引创建堆。
* @param i
*/
private heapify = (i: number) => {

@@ -64,2 +110,7 @@ const { arr } = this;

/**
* @description the key with min priority in the queue.
* @description.zh-CN 队列中优先级最小的 key。
* @returns
*/
min = () => {

@@ -72,5 +123,13 @@ if (this.size() === 0) {

/**
* @description insert a key with priority.
* @description.zh-CN 用优先级插入一个 key。
* @param key
* @param priority
* @returns
*/
add = (key: T, priority: number) => {
const { keyIndice, arr } = this;
// if the key is already in the queue, update the priority
if (!keyIndice.has(key)) {

@@ -90,2 +149,7 @@ const index = arr.length;

/**
* @description remove the key with min priority and return the key.
* @description.zh-CN 删除优先级最小的 key,并返回 key。
* @returns
*/
removeMin = () => {

@@ -99,2 +163,8 @@ this.swap(0, this.arr.length - 1);

/**
* @description decrease the priority of the key.
* @description.zh-CN 通过 key 减小 key 的优先级。
* @param key
* @param priority
*/
decrease = (key: T, priority: number) => {

@@ -101,0 +171,0 @@ if (!this.has(key)) {

import { GraphEnum } from './enum';
import { DefaultEdgeType } from './Graph';
import Graph, { DefaultEdgeType } from './Graph';
/**
* @description add one to key's value in map
* @description.zh-CN 在 map 中 key 的值加 1
* @param map
* @param key
*/
export function incrementOrInitEntry(map: Map<any, any>, key: any) {

@@ -9,2 +15,6 @@ const val = map.get(key) || 0;

/**
* @description minus one from key's value in map, is value is 0, delete the key
* @description.zh-CN 在 map 中 key 的值减 1,如果值为 0,则删除 key
*/
export function decrementOrRemoveEntry(map: Map<any, number>, key: any) {

@@ -22,4 +32,12 @@ let val = map.get(key);

export function edgeArgsToId<NodeType>(isDirected: boolean, v_: NodeType, w_: NodeType, name?: any) {
/**
* @description convert edge to string id
* @description.zh-CN 转换边为字符串 id
*/
export function edgeArgsToId<NodeType>(
isDirected: boolean,
v_: NodeType,
w_: NodeType,
name?: any,
) {
let v = String(v_);

@@ -42,2 +60,6 @@ let w = String(w_);

/**
* @description convert edge arguments to edge object
* @description.zh-CN 转换边参数为边对象
*/
export function edgeArgsToObj<NodeType>(

@@ -64,2 +86,6 @@ isDirected: boolean,

/**
* @description convert edge object to string id
* @description.zh-CN 转换边对象为字符串 id
*/
export function edgeObjToId(isDirected: boolean, edgeObj: { v: any; w: any; name?: any }) {

@@ -69,4 +95,8 @@ return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name);

export function isFunction(target: any) {
return !!(target && target.constructor && target.call && target.apply);
export function isFunction(obj: any) {
return typeof obj === 'function';
}
export function isGraph(obj: any) {
return obj instanceof Graph;
}

@@ -13,3 +13,4 @@ {

"declaration": true
}
},
"exclude": ["test"]
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc