diff --git a/plugins/analysis/dashboard/frontend/src/app/components/Autopeering.tsx b/plugins/analysis/dashboard/frontend/src/app/components/Autopeering.tsx index 7077f1332c77be7c116f60b44b020b34689c2183..46d4a2f2e9e1955921e4ce2dbf522ebaec3adfe4 100644 --- a/plugins/analysis/dashboard/frontend/src/app/components/Autopeering.tsx +++ b/plugins/analysis/dashboard/frontend/src/app/components/Autopeering.tsx @@ -31,7 +31,7 @@ export class NodeView extends React.Component<Props, any> { <Badge pill style={{background: "#cb4b16", color: "white"}}> Selected Node </Badge> - {this.props.autopeeringStore.selectedNode} + <em>{this.props.autopeeringStore.selectedNode}</em> <br/> <Badge pill style={{background: "#1c8d7f", color: "white"}}> Incoming Neighbors ({this.props.autopeeringStore.selectedNodeInNeighbors.size.toString()}) @@ -72,7 +72,7 @@ export class Autopeering extends React.Component<Props, any> { <Container> <Row className={"mb-1"}> - <Col xs={6} style={{paddingBottom: 30}}> + <Col xs={6} style={{paddingBottom: 15}}> <Row className={"mb-1"}> <h3>Autopeering Visualizer</h3> </Row> @@ -107,20 +107,21 @@ export class Autopeering extends React.Component<Props, any> { </Button> </InputGroup> - <ListGroup style={{maxHeight: 180, overflow: 'auto'}}> + <ListGroup style={{maxHeight: 220, overflow: 'auto'}}> {nodeListView} </ListGroup> </Col> - <Col xs={6}> + <Col xs={6} style={{height: 385, overflow:'auto'}}> <NodeView></NodeView> </Col> </Row> <div className={"visualizer"} style={{ - zIndex: -1, position: "static", + zIndex: -1, top: 0, left: 0, width: "100%", height: "600px", background: "#202126", + borderRadius: 20, }} id={"visualizer"}/> diff --git a/plugins/analysis/dashboard/frontend/src/app/stores/AutopeeringStore.tsx b/plugins/analysis/dashboard/frontend/src/app/stores/AutopeeringStore.tsx index 3db646556b0b935d7ee937510a06e1f013f18f48..a3889d7dd86191e8913bebbcaed391d11c6d1a6f 100644 --- a/plugins/analysis/dashboard/frontend/src/app/stores/AutopeeringStore.tsx +++ b/plugins/analysis/dashboard/frontend/src/app/stores/AutopeeringStore.tsx @@ -36,12 +36,16 @@ export class Neighbors { } const EDGE_COLOR_DEFAULT = "#ff7d6cff"; +const EDGE_COLOR_HIDE = "#ff7d6c40"; const EDGE_COLOR_OUTGOING = "#336db5ff"; const EDGE_COLOR_INCOMING = "#1c8d7fff"; const VERTEX_COLOR_DEFAULT = "0xa8d0e6"; -const VERTEX_COLOR_ACTIVE = "0x336db5"; -const VERTEX_COLOR_CONNECTED = "0x1c8d7f"; +const VERTEX_COLOR_ACTIVE = "0xcb4b16"; +const VERTEX_COLOR_IN_NEIGHBOR = "0x1c8d7f"; +const VERTEX_COLOR_OUT_NEIGHBOR = "0x336db5"; const VERTEX_SIZE = 14; +const VERTEX_SIZE_ACTIVE = 24; +const VERTEX_SIZE_CONNECTED = 18; const statusWebSocketPath = "/ws"; export class AutopeeringStore { @@ -99,7 +103,10 @@ export class AutopeeringStore { springLength: 30, springCoeff: 0.0001, dragCoeff: 0.02, - gravity: -1.2 + stableThreshold: 0.15, + gravity: -2, + timeStep: 20, + theta: 0.8, }); graphics.link((link) => { return Viva.Graph.View.webglLine(EDGE_COLOR_DEFAULT); @@ -264,10 +271,11 @@ export class AutopeeringStore { } // updates color of a node (vertex) in the graph - updateNodeUiColor = (node, color) => { + updateNodeUiColor = (node, color, size) => { let nodeUI = this.graphics.getNodeUI(node); if (nodeUI != undefined) { nodeUI.color = color; + nodeUI.size = size; } } @@ -289,18 +297,19 @@ export class AutopeeringStore { this.graph.beginUpdate(); + this.graph.forEachLink((link) => { + let linkUi = this.graphics.getLinkUI(link.id); + linkUi.color = parseColor(EDGE_COLOR_HIDE); + }) + // Highlight selected node - this.updateNodeUiColor(this.selectedNode, VERTEX_COLOR_ACTIVE); + this.updateNodeUiColor(this.selectedNode, VERTEX_COLOR_ACTIVE, VERTEX_SIZE_ACTIVE); this.selectedNodeInNeighbors.forEach((inNeighborID) => { - // Remove highlighting of neighbor - this.updateNodeUiColor(inNeighborID, VERTEX_COLOR_CONNECTED); - // Remove highlighting of linkde); + this.updateNodeUiColor(inNeighborID, VERTEX_COLOR_IN_NEIGHBOR, VERTEX_SIZE_CONNECTED); this.updateLinkUiColor(inNeighborID, this.selectedNode, EDGE_COLOR_INCOMING); }) this.selectedNodeOutNeighbors.forEach((outNeighborID) => { - // Remove highlighting of neighbor - this.updateNodeUiColor(outNeighborID, VERTEX_COLOR_CONNECTED); - // Remove highlighting of link + this.updateNodeUiColor(outNeighborID, VERTEX_COLOR_OUT_NEIGHBOR, VERTEX_SIZE_CONNECTED); this.updateLinkUiColor(this.selectedNode, outNeighborID, EDGE_COLOR_OUTGOING); }) @@ -309,25 +318,38 @@ export class AutopeeringStore { } // disables highlighting of selectedNode, its links and neighbors - resetPreviousColors = () => { + resetPreviousColors = (skipAllLink: boolean = false, toLinkHide: boolean = false) => { if (!this.selectionActive) {return}; this.graph.beginUpdate(); + let edgeColor = EDGE_COLOR_DEFAULT; + + if (toLinkHide) { + edgeColor = EDGE_COLOR_HIDE; + } + // Remove highlighting of selected node - this.updateNodeUiColor(this.selectedNode, VERTEX_COLOR_DEFAULT); + this.updateNodeUiColor(this.selectedNode, VERTEX_COLOR_DEFAULT, VERTEX_SIZE); this.selectedNodeInNeighbors.forEach((inNeighborID) => { // Remove highlighting of neighbor - this.updateNodeUiColor(inNeighborID, VERTEX_COLOR_DEFAULT); + this.updateNodeUiColor(inNeighborID, VERTEX_COLOR_DEFAULT, VERTEX_SIZE); // Remove highlighting of link - this.updateLinkUiColor(inNeighborID, this.selectedNode, EDGE_COLOR_DEFAULT); + this.updateLinkUiColor(inNeighborID, this.selectedNode, edgeColor); }) this.selectedNodeOutNeighbors.forEach((outNeighborID) => { // Remove highlighting of neighbor - this.updateNodeUiColor(outNeighborID, VERTEX_COLOR_DEFAULT); + this.updateNodeUiColor(outNeighborID, VERTEX_COLOR_DEFAULT, VERTEX_SIZE); // Remove highlighting of link - this.updateLinkUiColor(this.selectedNode, outNeighborID, EDGE_COLOR_DEFAULT); + this.updateLinkUiColor(this.selectedNode, outNeighborID, edgeColor); }) + if (!skipAllLink) { + this.graph.forEachLink((link) => { + let linkUi = this.graphics.getLinkUI(link.id); + linkUi.color = parseColor(EDGE_COLOR_DEFAULT); + }) + } + this.graph.endUpdate(); this.renderer.rerender(); } @@ -344,7 +366,7 @@ export class AutopeeringStore { // Stop highlighting anything else if (this.selectionActive) { - this.resetPreviousColors(); + this.resetPreviousColors(true); } this.selectedNode = node.id; @@ -368,15 +390,18 @@ export class AutopeeringStore { // handles click on a node in list @action handleNodeListOnClick = (e) => { - // Disable selection on second click when clicked on the same node - if (this.selectionActive && this.selectedNode == e.target.innerHTML) { - this.clearSelection(); - return; - } - // Stop highlighting the other node if clicked if (this.selectionActive) { - this.resetPreviousColors(); + if (this.selectedNode == e.target.innerHTML) { + // Disable selection on second click when clicked on the same node + this.clearSelection(); + return; + } else { + // we clicked on a different node + // stop highlighting the other node if clicked + // note that edge color defaults back to "hide" + this.resetPreviousColors(true, true); + } } this.selectedNode = e.target.innerHTML; diff --git a/plugins/analysis/dashboard/plugin.go b/plugins/analysis/dashboard/plugin.go index f0f97e576478ad36ba099dd21cc7bd4187073040..99e1b7ae514c2b23c6961af2eeb302de7881bb99 100644 --- a/plugins/analysis/dashboard/plugin.go +++ b/plugins/analysis/dashboard/plugin.go @@ -20,7 +20,7 @@ const PluginName = "Analysis-Dashboard" var ( // Plugin is the plugin instance of the dashboard plugin. - Plugin = node.NewPlugin(PluginName, node.Enabled, configure, run) + Plugin = node.NewPlugin(PluginName, node.Disabled, configure, run) log *logger.Logger server *echo.Echo