From 376e6f014eb428446ebf39fa961329194ea3c100 Mon Sep 17 00:00:00 2001 From: jpellizzari Date: Mon, 27 Feb 2017 15:34:32 -0800 Subject: [PATCH 1/2] Added edge arrows --- client/app/scripts/charts/edge.js | 28 +++++++++++++++---- client/app/scripts/charts/marker.js | 18 ++++++++++++ client/app/scripts/charts/nodes-chart.js | 19 ++++++++++++- .../scripts/selectors/nodes-chart-graph.js | 4 +-- client/app/styles/_base.scss | 7 +++-- client/app/styles/_contrast-overrides.scss | 1 + client/app/styles/_variables.scss | 1 + 7 files changed, 67 insertions(+), 11 deletions(-) create mode 100644 client/app/scripts/charts/marker.js diff --git a/client/app/scripts/charts/edge.js b/client/app/scripts/charts/edge.js index f443a1953..84836dd4b 100644 --- a/client/app/scripts/charts/edge.js +++ b/client/app/scripts/charts/edge.js @@ -14,19 +14,35 @@ class Edge extends React.Component { } render() { - const { id, path, highlighted, blurred, focused, scale, contrastMode } = this.props; + const { + id, + path, + highlighted, + blurred, + focused, + scale, + source, + target + } = this.props; const className = classNames('edge', { highlighted, blurred, focused }); - const thickness = scale * (contrastMode ? 0.02 : 0.01) * NODE_BASE_SIZE; - + const thickness = (scale * 0.01) * NODE_BASE_SIZE; + const strokeWidth = focused ? thickness * 3 : thickness; + const shouldRenderMarker = (focused || highlighted) && (source !== target); // Draws the edge so that its thickness reflects the zoom scale. // Edge shadow is always made 10x thicker than the edge itself. return ( - - + onMouseLeave={this.handleMouseLeave} + > + + ); } diff --git a/client/app/scripts/charts/marker.js b/client/app/scripts/charts/marker.js new file mode 100644 index 000000000..241f6d824 --- /dev/null +++ b/client/app/scripts/charts/marker.js @@ -0,0 +1,18 @@ +import React from 'react'; + +export default function Marker({id, offset, size, children, viewBox}) { + return ( + + {children} + + ); +} diff --git a/client/app/scripts/charts/nodes-chart.js b/client/app/scripts/charts/nodes-chart.js index 14e80aa37..1307a3962 100644 --- a/client/app/scripts/charts/nodes-chart.js +++ b/client/app/scripts/charts/nodes-chart.js @@ -84,12 +84,29 @@ class NodesChart extends React.Component { const { panTranslateX, panTranslateY, zoomScale } = this.state; const transform = `translate(${panTranslateX}, ${panTranslateY}) scale(${zoomScale})`; const svgClassNames = this.props.isEmpty ? 'hide' : ''; + const markerOffset = this.props.selectedNodeId ? '35' : '40'; + const markerSize = this.props.selectedNodeId ? '10' : '30'; return (
+ className={svgClassNames} onClick={this.handleMouseClick} + > + + + + + diff --git a/client/app/scripts/selectors/nodes-chart-graph.js b/client/app/scripts/selectors/nodes-chart-graph.js index 39dbdb9c7..a8728d4b5 100644 --- a/client/app/scripts/selectors/nodes-chart-graph.js +++ b/client/app/scripts/selectors/nodes-chart-graph.js @@ -3,7 +3,7 @@ import { createSelector, createStructuredSelector } from 'reselect'; import { Map as makeMap } from 'immutable'; import timely from 'timely'; -import { initEdgesFromNodes, collapseMultiEdges } from '../utils/layouter-utils'; +import { initEdgesFromNodes } from '../utils/layouter-utils'; import { viewportWidthSelector, viewportHeightSelector } from './canvas-viewport'; import { activeTopologyOptionsSelector } from './topology'; import { shownNodesSelector } from './node-filters'; @@ -72,5 +72,5 @@ export const graphEdgesSelector = createSelector( [ graphLayoutSelector, ], - graph => collapseMultiEdges(graph.edges) + graph => graph.edges ); diff --git a/client/app/styles/_base.scss b/client/app/styles/_base.scss index 22b295662..c2d22f2f3 100644 --- a/client/app/styles/_base.scss +++ b/client/app/styles/_base.scss @@ -411,8 +411,7 @@ .link { fill: none; - stroke: $text-secondary-color; - stroke-opacity: $edge-opacity; + stroke: $edge-color; } .shadow { fill: none; @@ -494,6 +493,10 @@ stroke-width: $node-border-stroke-width * 0.8; } + .edge-marker { + color: $edge-color; + fill: $edge-color; + } } .matched-results { diff --git a/client/app/styles/_contrast-overrides.scss b/client/app/styles/_contrast-overrides.scss index 9685d363b..3cc85ed1b 100644 --- a/client/app/styles/_contrast-overrides.scss +++ b/client/app/styles/_contrast-overrides.scss @@ -10,6 +10,7 @@ $text-tertiary-color: lighten($text-color, 20%); $border-light-color: lighten($text-color, 50%); $text-darker-color: darken($text-color, 20%); $white: white; +$edge-color: black; $node-highlight-fill-opacity: 0.3; $node-highlight-stroke-opacity: 0.5; diff --git a/client/app/styles/_variables.scss b/client/app/styles/_variables.scss index 9c3c5fdff..49bb144dc 100644 --- a/client/app/styles/_variables.scss +++ b/client/app/styles/_variables.scss @@ -39,6 +39,7 @@ $node-text-scale: 2; $edge-highlight-opacity: 0.1; $edge-opacity-blurred: 0.2; $edge-opacity: 0.5; +$edge-color: rgb(110, 110, 156); $btn-opacity-default: 0.7; $btn-opacity-hover: 1; From 9b648834eef131ab6abee3cc365aabde998482f0 Mon Sep 17 00:00:00 2001 From: jpellizzari Date: Mon, 13 Mar 2017 09:03:50 -0700 Subject: [PATCH 2/2] removed old marker code --- client/app/scripts/charts/marker.js | 18 --------------- .../utils/__tests__/layouter-utils-test.js | 17 -------------- client/app/scripts/utils/layouter-utils.js | 23 ------------------- 3 files changed, 58 deletions(-) delete mode 100644 client/app/scripts/charts/marker.js diff --git a/client/app/scripts/charts/marker.js b/client/app/scripts/charts/marker.js deleted file mode 100644 index 241f6d824..000000000 --- a/client/app/scripts/charts/marker.js +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; - -export default function Marker({id, offset, size, children, viewBox}) { - return ( - - {children} - - ); -} diff --git a/client/app/scripts/utils/__tests__/layouter-utils-test.js b/client/app/scripts/utils/__tests__/layouter-utils-test.js index 467bfa57f..f5d36ee23 100644 --- a/client/app/scripts/utils/__tests__/layouter-utils-test.js +++ b/client/app/scripts/utils/__tests__/layouter-utils-test.js @@ -2,7 +2,6 @@ import { fromJS } from 'immutable'; import { initEdgesFromNodes, - collapseMultiEdges, } from '../layouter-utils'; @@ -22,20 +21,4 @@ describe('LayouterUtils', () => { }); }); }); - - describe('collapseMultiEdges', () => { - it('should return collapsed multi-edges', () => { - const input = fromJS({ - 'a-b': { id: 'a-b', source: 'a', target: 'b' }, - 'a-c': { id: 'a-c', source: 'a', target: 'c' }, - 'b-a': { id: 'b-a', source: 'b', target: 'a' }, - 'b-b': { id: 'b-b', source: 'b', target: 'b' }, - }); - expect(collapseMultiEdges(input).toJS()).toEqual({ - 'a-b': { id: 'a-b', source: 'a', target: 'b', bidirectional: true }, - 'a-c': { id: 'a-c', source: 'a', target: 'c' }, - 'b-b': { id: 'b-b', source: 'b', target: 'b' }, - }); - }); - }); }); diff --git a/client/app/scripts/utils/layouter-utils.js b/client/app/scripts/utils/layouter-utils.js index c364b4280..4c853571c 100644 --- a/client/app/scripts/utils/layouter-utils.js +++ b/client/app/scripts/utils/layouter-utils.js @@ -30,26 +30,3 @@ export function initEdgesFromNodes(nodes) { return edges; } - -// Replaces all pairs of edges (A->B, B->A) with a single A->B edge that is marked as -// bidirectional. We do this to prevent double rendering of edges between the same nodes. -export function collapseMultiEdges(directedEdges) { - let collapsedEdges = makeMap(); - - directedEdges.forEach((edge, edgeId) => { - const source = edge.get('source'); - const target = edge.get('target'); - const reversedEdgeId = constructEdgeId(target, source); - - if (collapsedEdges.has(reversedEdgeId)) { - // If the edge between the same nodes with the opposite direction already exists, - // mark it as bidirectional and don't add any other edges (making graph simple). - collapsedEdges = collapsedEdges.setIn([reversedEdgeId, 'bidirectional'], true); - } else { - // Otherwise just copy the edge. - collapsedEdges = collapsedEdges.set(edgeId, edge); - } - }); - - return collapsedEdges; -}