From ff73e54ad5f0d71dc86c3b1e8566e8a543247363 Mon Sep 17 00:00:00 2001 From: Jason Park Date: Mon, 3 Dec 2018 18:03:02 -0500 Subject: [PATCH] Add updateNode(), removeNode(), updateEdge(), and removeEdge() in GraphTracer --- src/frontend/core/datas/GraphData.js | 43 ++++++++++++++++--- .../core/renderers/GraphRenderer/index.jsx | 20 ++++++--- .../core/renderers/Renderer/index.jsx | 5 ++- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/src/frontend/core/datas/GraphData.js b/src/frontend/core/datas/GraphData.js index 1f887ce..add6303 100644 --- a/src/frontend/core/datas/GraphData.js +++ b/src/frontend/core/datas/GraphData.js @@ -48,9 +48,26 @@ class GraphData extends Data { this.isWeighted = isWeighted; } - addNode(id, weight = null, visitedCount = 0, selectedCount = 0, x = 0, y = 0) { + addNode(id, weight = null, x = 0, y = 0, visitedCount = 0, selectedCount = 0) { if (this.findNode(id)) return; - this.nodes.push({ id, weight, visitedCount, selectedCount, x, y }); + this.nodes.push({ id, weight, x, y, visitedCount, selectedCount }); + this.layout(); + } + + updateNode(id, weight, x, y, visitedCount, selectedCount) { + const node = this.findNode(id); + const update = { weight, x, y, visitedCount, selectedCount }; + Object.keys(update).forEach(key => { + if (update[key] === undefined) delete update[key]; + }); + Object.assign(node, update); + } + + removeNode(id) { + const node = this.findNode(id); + if (!node) return; + const index = this.nodes.indexOf(node); + this.nodes.splice(index, 1); this.layout(); } @@ -60,9 +77,21 @@ class GraphData extends Data { this.layout(); } - updateNode(id, update) { - const node = this.findNode(id); - Object.assign(node, update); + updateEdge(source, target, weight, visitedCount, selectedCount) { + const edge = this.findEdge(source, target); + const update = { weight, visitedCount, selectedCount }; + Object.keys(update).forEach(key => { + if (update[key] === undefined) delete update[key]; + }); + Object.assign(edge, update); + } + + removeEdge(source, target) { + const edge = this.findEdge(source, target); + if (!edge) return; + const index = this.edges.indexOf(edge); + this.edges.splice(index, 1); + this.layout(); } findNode(id) { @@ -195,11 +224,11 @@ class GraphData extends Data { this.visitOrLeave(false, target, source, weight); } - visitOrLeave(visit, target, source = null, weight = null) { + visitOrLeave(visit, target, source = null, weight) { const edge = this.findEdge(source, target); if (edge) edge.visitedCount += visit ? 1 : -1; const node = this.findNode(target); - node.weight = weight; + if (weight !== undefined) node.weight = weight; node.visitedCount += visit ? 1 : -1; if (this.logData) { this.logData.print(visit ? (source || '') + ' -> ' + target : (source || '') + ' <- ' + target); diff --git a/src/frontend/core/renderers/GraphRenderer/index.jsx b/src/frontend/core/renderers/GraphRenderer/index.jsx index 73c6f9c..b166fa0 100644 --- a/src/frontend/core/renderers/GraphRenderer/index.jsx +++ b/src/frontend/core/renderers/GraphRenderer/index.jsx @@ -21,8 +21,10 @@ class GraphRenderer extends Renderer { handleMouseMove(e) { if (this.selectedNode) { - const coords = this.computeCoords(e); - this.props.data.updateNode(this.selectedNode.id, coords); + const { x, y } = this.computeCoords(e); + const node = this.props.data.findNode(this.selectedNode.id); + node.x = x; + node.y = y; this.refresh(); } else { super.handleMouseMove(e); @@ -63,8 +65,11 @@ class GraphRenderer extends Renderer { { edges.sort((a, b) => a.visitedCount - b.visitedCount).map(edge => { const { source, target, weight, visitedCount, selectedCount } = edge; - const { x: sx, y: sy } = this.props.data.findNode(source); - let { x: ex, y: ey } = this.props.data.findNode(target); + const sourceNode = this.props.data.findNode(source); + const targetNode = this.props.data.findNode(target); + if (!sourceNode || !targetNode) return undefined; + const { x: sx, y: sy } = sourceNode; + let { x: ex, y: ey } = targetNode; const mx = (sx + ex) / 2; const my = (sy + ey) / 2; const dx = ex - sx; @@ -79,7 +84,8 @@ class GraphRenderer extends Renderer { } return ( - + { isWeighted && @@ -96,8 +102,8 @@ class GraphRenderer extends Renderer { nodes.map(node => { const { id, x, y, weight, visitedCount, selectedCount } = node; return ( - + {id} { diff --git a/src/frontend/core/renderers/Renderer/index.jsx b/src/frontend/core/renderers/Renderer/index.jsx index 0f56e86..7c1f2dc 100644 --- a/src/frontend/core/renderers/Renderer/index.jsx +++ b/src/frontend/core/renderers/Renderer/index.jsx @@ -58,7 +58,10 @@ class Renderer extends React.Component { toString(value) { switch (typeof(value)) { case 'number': - return value === Infinity ? '∞' : Number.isInteger(value) ? value.toString() : value.toFixed(3); + return [Number.POSITIVE_INFINITY, Number.MAX_SAFE_INTEGER, 0x7fffffff].includes(value) ? '∞' : + [Number.NEGATIVE_INFINITY, Number.MIN_SAFE_INTEGER, -0x80000000].includes(value) ? '-∞' : + Number.isInteger(value) ? value.toString() : + value.toFixed(3); case 'boolean': return value ? 'T' : 'F'; default: -- GitLab