import Graph, { GraphOption } from '.'; type JSONNode = { id: NodeIDType; value?: NodeType; parent?: NodeIDType; }; /** * @description Convert a graph's node to JSON. * @description.zh-CN 转换图的节点为 JSON。 * @param graph * @returns */ const nodeToJSON = ( graph: Graph, ) => { return graph.nodes().map((n) => { const value = graph.node(n); const parent = graph.parent(n); const node = { id: n, value, parent, }; if (node.value === undefined) { delete node.value; } if (node.parent === undefined) { delete node.parent; } return node as JSONNode; }); }; type JSONEdge> = { /** * @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 = >( graph: Graph, ) => { return graph.edges().map((edge) => { const value = graph.edge(edge); const e = { v: edge.v, w: edge.w, value, name: edge.name, }; if (e.name === undefined) { delete e.name; } if (e.value === undefined) { delete e.value; } return e as JSONEdge; }); }; type JSONGraph = { options: GraphOption; nodes: JSONNode[]; edges: JSONEdge[]; value?: GraphType; }; /** * @description Convert a graph to JSON. * @description.zh-CN 转换图为 JSON。 * @param graph * @returns */ export const write = < NodeIDType = string, NodeType = Record, EdgeType = Record, GraphType = string, >( graph: Graph, ) => { const json: JSONGraph = { options: { directed: graph.isDirected(), multigraph: graph.isMultigraph(), compound: graph.isCompound(), }, nodes: nodeToJSON(graph), edges: edgeToJSON(graph), value: graph.graph(), }; if (json.value === undefined) { delete json.value; } return json; }; /** * @description read a graph from JSON. * @description.zh-CN 从 JSON 读取图。 * @param json * @returns */ export const read = < NodeIDType = string, NodeType = Record, EdgeType = Record, GraphType = string, >( json: JSONGraph, ) => { const graph = new Graph(json.options); if (json.value !== undefined) { graph.setGraph(json.value); } json.nodes.forEach((entry) => { graph.setNode(entry.id, entry.value); if (entry.parent) { graph.setParent(entry.id, entry.parent); } }); json.edges.forEach((entry) => { graph.setEdge(entry.v, entry.w, entry.value, entry.name); }); return graph; };