提交 ff73e54a 编写于 作者: J Jason Park

Add updateNode(), removeNode(), updateEdge(), and removeEdge() in GraphTracer

上级 e2285892
......@@ -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);
......
......@@ -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 (
<g className={classes(styles.edge, selectedCount && styles.selected, visitedCount && styles.visited)} key={`${source}-${target}`}>
<g className={classes(styles.edge, selectedCount && styles.selected, visitedCount && styles.visited)}
key={`${source}-${target}`}>
<path d={`M${sx},${sy} L${ex},${ey}`} className={classes(styles.line, isDirected && styles.directed)} />
{
isWeighted &&
......@@ -96,8 +102,8 @@ class GraphRenderer extends Renderer {
nodes.map(node => {
const { id, x, y, weight, visitedCount, selectedCount } = node;
return (
<g className={classes(styles.node, selectedCount && styles.selected, visitedCount && styles.visited)} key={id}
transform={`translate(${x},${y})`}>
<g className={classes(styles.node, selectedCount && styles.selected, visitedCount && styles.visited)}
key={id} transform={`translate(${x},${y})`}>
<circle className={styles.circle} r={nodeRadius} />
<text className={styles.id}>{id}</text>
{
......
......@@ -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:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册