diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d93b4d4..e21a037 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: - node-version: [14.x, 16.x, 18.x] + node-version: [16.x, 18.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: diff --git a/__tests__/bugs/getChildren.spec.ts b/__tests__/bugs/getChildren.spec.ts new file mode 100644 index 0000000..2293225 --- /dev/null +++ b/__tests__/bugs/getChildren.spec.ts @@ -0,0 +1,150 @@ +import { Graph } from '../../src/graph'; + +describe('remove node and get children', () => { + const data = { + nodes: [ + { + id: 'Modeling Methods', + children: ['Classification', 'Consensus', 'Regression'], + }, + { + id: 'Classification', + children: [ + 'Logistic regression', + 'Linear discriminant analysis', + 'Rules', + 'Decision trees', + 'Naive Bayes', + 'K nearest neighbor', + 'Probabilistic neural network', + 'Support vector machine', + ], + }, + { id: 'Logistic regression' }, + { id: 'Linear discriminant analysis' }, + { id: 'Rules' }, + { id: 'Decision trees' }, + { id: 'Naive Bayes' }, + { id: 'K nearest neighbor' }, + { id: 'Probabilistic neural network' }, + { id: 'Support vector machine' }, + { id: 'Consensus', children: ['Models diversity', 'Methods', 'Common'] }, + { + id: 'Models diversity', + children: [ + 'Different initializations', + 'Different parameter choices', + 'Different architectures', + 'Different modeling methods', + 'Different training sets', + 'Different feature sets', + ], + }, + { id: 'Different initializations' }, + { id: 'Different parameter choices' }, + { id: 'Different architectures' }, + { id: 'Different modeling methods' }, + { id: 'Different training sets' }, + { id: 'Different feature sets' }, + { + id: 'Methods', + children: ['Classifier selection', 'Classifier fusion'], + }, + { id: 'Classifier selection' }, + { id: 'Classifier fusion' }, + { id: 'Common', children: ['Bagging', 'Boosting', 'AdaBoost'] }, + { id: 'Bagging' }, + { id: 'Boosting' }, + { id: 'AdaBoost' }, + { + id: 'Regression', + children: [ + 'Multiple linear regression', + 'Partial least squares', + 'Multi-layer feed forward neural network', + 'General regression neural network', + 'Support vector regression', + ], + }, + { id: 'Multiple linear regression' }, + { id: 'Partial least squares' }, + { id: 'Multi-layer feed forward neural network' }, + { id: 'General regression neural network' }, + { id: 'Support vector regression' }, + ], + edges: [ + { source: 'Modeling Methods', target: 'Classification' }, + { source: 'Modeling Methods', target: 'Consensus' }, + { source: 'Modeling Methods', target: 'Regression' }, + { source: 'Classification', target: 'Logistic regression' }, + { source: 'Classification', target: 'Linear discriminant analysis' }, + { source: 'Classification', target: 'Rules' }, + { source: 'Classification', target: 'Decision trees' }, + { source: 'Classification', target: 'Naive Bayes' }, + { source: 'Classification', target: 'K nearest neighbor' }, + { source: 'Classification', target: 'Probabilistic neural network' }, + { source: 'Classification', target: 'Support vector machine' }, + { source: 'Consensus', target: 'Models diversity' }, + { source: 'Consensus', target: 'Methods' }, + { source: 'Consensus', target: 'Common' }, + { source: 'Models diversity', target: 'Different initializations' }, + { source: 'Models diversity', target: 'Different parameter choices' }, + { source: 'Models diversity', target: 'Different architectures' }, + { source: 'Models diversity', target: 'Different modeling methods' }, + { source: 'Models diversity', target: 'Different training sets' }, + { source: 'Models diversity', target: 'Different feature sets' }, + { source: 'Methods', target: 'Classifier selection' }, + { source: 'Methods', target: 'Classifier fusion' }, + { source: 'Common', target: 'Bagging' }, + { source: 'Common', target: 'Boosting' }, + { source: 'Common', target: 'AdaBoost' }, + { source: 'Regression', target: 'Multiple linear regression' }, + { source: 'Regression', target: 'Partial least squares' }, + { + source: 'Regression', + target: 'Multi-layer feed forward neural network', + }, + { source: 'Regression', target: 'General regression neural network' }, + { source: 'Regression', target: 'Support vector regression' }, + ], + }; + + const graph = new Graph({ + nodes: data.nodes.map(({ id }) => ({ id, data: {} })), + edges: data.edges.map(({ source, target }) => ({ + id: `${source}-${target}`, + source, + target, + data: {}, + })), + }); + + graph.attachTreeStructure('tree'); + + data.nodes.forEach((node) => { + node.children?.forEach((child) => { + graph.setParent(child, node.id, 'tree'); + }); + }); + + it('should get the correct children', () => { + expect(graph.getParent('Logistic regression', 'tree')?.id).toBe( + 'Classification', + ); + + graph.removeNode('Rules'); + + expect( + graph.getChildren('Classification', 'tree').map((d) => d.id), + ).toEqual([ + 'Logistic regression', + 'Linear discriminant analysis', + // 'Rules', + 'Decision trees', + 'Naive Bayes', + 'K nearest neighbor', + 'Probabilistic neural network', + 'Support vector machine', + ]); + }); +}); diff --git a/package.json b/package.json index 636db7c..dd7eec3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@antv/graphlib", - "version": "2.0.2", + "version": "2.0.3", "main": "lib/index.js", "module": "esm/index.js", "types": "lib/index.d.ts", @@ -25,31 +25,31 @@ }, "devDependencies": { "@commitlint/cli": "^11.0.0", - "@rollup/plugin-commonjs": "^21.0.2", - "@rollup/plugin-node-resolve": "^15.2.1", - "@rollup/plugin-terser": "^0.4.3", - "@types/jest": "^29.2.4", - "@typescript-eslint/eslint-plugin": "^5.46.1", - "@typescript-eslint/parser": "^5.46.1", + "@rollup/plugin-commonjs": "^21.1.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-terser": "^0.4.4", + "@types/jest": "^29.5.12", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", "cross-env": "^7.0.3", - "eslint": "^8.29.0", - "eslint-plugin-import": "^2.26.0", - "husky": "^8.0.2", - "jest": "^29.3.1", + "eslint": "^8.57.0", + "eslint-plugin-import": "^2.29.1", + "husky": "^8.0.3", + "jest": "^29.7.0", "limit-size": "^0.1.4", - "lint-staged": "^13.1.0", + "lint-staged": "^13.3.0", "npm-run-all": "^4.1.5", - "prettier": "^2.8.1", + "prettier": "^2.8.8", "rimraf": "^3.0.2", - "rollup": "^2.39.0", + "rollup": "^2.79.1", "rollup-plugin-polyfill-node": "^0.8.0", "rollup-plugin-typescript2": "^0.35.0", - "rollup-plugin-visualizer": "^5.6.0", - "ts-jest": "^29.0.3", - "tslib": "^2.4.1", - "typedoc": "^0.25.2", - "typedoc-plugin-markdown": "^3.14.0", - "typescript": "^4.9.4" + "rollup-plugin-visualizer": "^5.12.0", + "ts-jest": "^29.1.5", + "tslib": "^2.6.3", + "typedoc": "^0.25.13", + "typedoc-plugin-markdown": "^3.17.1", + "typescript": "^4.9.5" }, "lint-staged": { "*.{ts,tsx}": [ diff --git a/src/graph.ts b/src/graph.ts index d05b691..9aafa61 100644 --- a/src/graph.ts +++ b/src/graph.ts @@ -399,9 +399,16 @@ export class Graph< tree.childrenMap.get(id)?.forEach((child) => { tree.parentMap.delete(child.id); }); + + const parent = tree.parentMap.get(id); + if (parent) tree.childrenMap.get(parent.id)?.delete(node); + tree.parentMap.delete(id); tree.childrenMap.delete(id); }); + this.bothEdgesMap.delete(id); + this.inEdgesMap.delete(id); + this.outEdgesMap.delete(id); this.changes.push({ type: 'NodeRemoved', value: node }); }