From dc61317ba5225c7976dc015fc4187c00abe1f094 Mon Sep 17 00:00:00 2001 From: Simon Howe Date: Mon, 17 Oct 2016 17:11:38 +0200 Subject: [PATCH] Bring shapes into the details panel and use them for view-in-topo (click on shape/title to view it in its topo) --- .../app/scripts/charts/node-shape-circle.js | 6 +- client/app/scripts/charts/node-shape-hex.js | 6 +- .../app/scripts/charts/node-shape-square.js | 6 +- client/app/scripts/charts/node-shape-stack.js | 8 +- client/app/scripts/charts/node.js | 4 +- client/app/scripts/components/node-details.js | 67 +++++-- client/app/styles/main.less | 184 +++++++++++------- 7 files changed, 180 insertions(+), 101 deletions(-) diff --git a/client/app/scripts/charts/node-shape-circle.js b/client/app/scripts/charts/node-shape-circle.js index dcf2327eb..8587f720e 100644 --- a/client/app/scripts/charts/node-shape-circle.js +++ b/client/app/scripts/charts/node-shape-circle.js @@ -4,11 +4,11 @@ import {getMetricValue, getMetricColor, getClipPathDefinition} from '../utils/me import {CANVAS_METRIC_FONT_SIZE} from '../constants/styles.js'; -export default function NodeShapeCircle({id, highlighted, size, color, metric}) { +export default function NodeShapeCircle({id, highlighted, size, color, metric, wireframe}) { const clipId = `mask-${id}`; const {height, hasMetric, formattedValue} = getMetricValue(metric, size); const metricStyle = { fill: getMetricColor(metric) }; - const className = classNames('shape', { metrics: hasMetric }); + const className = classNames('shape', { metrics: hasMetric, wireframe }); const fontSize = size * CANVAS_METRIC_FONT_SIZE; return ( @@ -21,7 +21,7 @@ export default function NodeShapeCircle({id, highlighted, size, color, metric}) clipPath={`url(#${clipId})`} />} {highlighted && hasMetric ? {formattedValue} : - } + } ); } diff --git a/client/app/scripts/charts/node-shape-hex.js b/client/app/scripts/charts/node-shape-hex.js index d7045c9ab..2e1a8c917 100644 --- a/client/app/scripts/charts/node-shape-hex.js +++ b/client/app/scripts/charts/node-shape-hex.js @@ -30,7 +30,7 @@ function getPoints(h) { } -export default function NodeShapeHex({id, highlighted, size, color, metric}) { +export default function NodeShapeHex({id, highlighted, size, color, metric, wireframe}) { const pathProps = v => ({ d: getPoints(size * v * 2), transform: `rotate(90) translate(-${size * getWidth(v)}, -${size * v})` @@ -42,7 +42,7 @@ export default function NodeShapeHex({id, highlighted, size, color, metric}) { const clipId = `mask-${id}`; const {height, hasMetric, formattedValue} = getMetricValue(metric, size); const metricStyle = { fill: getMetricColor(metric) }; - const className = classNames('shape', { metrics: hasMetric }); + const className = classNames('shape', { metrics: hasMetric, wireframe }); const fontSize = size * CANVAS_METRIC_FONT_SIZE; return ( @@ -58,7 +58,7 @@ export default function NodeShapeHex({id, highlighted, size, color, metric}) { {formattedValue} : - } + } ); } diff --git a/client/app/scripts/charts/node-shape-square.js b/client/app/scripts/charts/node-shape-square.js index d4cd116bc..345877bfd 100644 --- a/client/app/scripts/charts/node-shape-square.js +++ b/client/app/scripts/charts/node-shape-square.js @@ -5,7 +5,7 @@ import {CANVAS_METRIC_FONT_SIZE} from '../constants/styles.js'; export default function NodeShapeSquare({ - id, highlighted, size, color, rx = 0, ry = 0, metric + id, highlighted, size, color, rx = 0, ry = 0, metric, wireframe }) { const rectProps = (scale, radiusScale) => ({ width: scale * size * 2, @@ -19,7 +19,7 @@ export default function NodeShapeSquare({ const clipId = `mask-${id}`; const {height, hasMetric, formattedValue} = getMetricValue(metric, size); const metricStyle = { fill: getMetricColor(metric) }; - const className = classNames('shape', { metrics: hasMetric }); + const className = classNames('shape', { metrics: hasMetric, wireframe }); const fontSize = size * CANVAS_METRIC_FONT_SIZE; return ( @@ -34,7 +34,7 @@ export default function NodeShapeSquare({ {formattedValue} : - } + } ); } diff --git a/client/app/scripts/charts/node-shape-stack.js b/client/app/scripts/charts/node-shape-stack.js index 3d691888c..e566460d3 100644 --- a/client/app/scripts/charts/node-shape-stack.js +++ b/client/app/scripts/charts/node-shape-stack.js @@ -14,15 +14,13 @@ export default function NodeShapeStack(props) { - + - - - - + + ); } diff --git a/client/app/scripts/charts/node.js b/client/app/scripts/charts/node.js index 63511fdfa..bf354d1d0 100644 --- a/client/app/scripts/charts/node.js +++ b/client/app/scripts/charts/node.js @@ -36,7 +36,7 @@ const nodeShapes = { cloud: NodeShapeCloud }; -function getNodeShape({ shape, stack }) { +export function getNodeShape({ shape, stack }) { const nodeShape = nodeShapes[shape]; if (!nodeShape) { throw new Error(`Unknown shape: ${shape}!`); @@ -142,7 +142,7 @@ class Node extends React.Component { } - +
- {showSwitchTopology && }
@@ -138,30 +149,60 @@ export class NodeDetails extends React.Component { const { details, nodeControlStatus, nodeMatches = makeMap() } = this.props; const showControls = details.controls && details.controls.length > 0; const nodeColor = getNodeColorDark(details.rank, details.label, details.pseudo); + const controlsColor = brightenColor(nodeColor); const {error, pending} = nodeControlStatus ? nodeControlStatus.toJS() : {}; const tools = this.renderTools(); const styles = { controls: { - backgroundColor: brightenColor(nodeColor) + backgroundColor: controlsColor, }, header: { backgroundColor: nodeColor } }; + const NodeShapeType = getNodeShape(details); + const shapeMarginTop = details.stack ? -20 : -27; + const topologyTitle = `View ${this.props.label} in ${this.props.topologyId}`; + const showSwitchTopology = this.props.nodeId !== this.props.selectedNodeId; + const highlighted = this.state.highlighted; + + const commonProps = { + onClick: this.handleShowTopologyForNode, + onMouseEnter: showSwitchTopology && this.handleNodeMouseEnter, + onMouseLeave: showSwitchTopology && this.handleNodeMouseLeave, + style: { + cursor: showSwitchTopology && 'pointer', + }, + }; + const headerClassName = classnames('node-details-header', { + 'show-switch-topology': showSwitchTopology, + }); return (
{tools} -
+
-

+ + + {showSwitchTopology && {topologyTitle}} + + + +

-
- {details.parents && } -
+ {details.parents && }
diff --git a/client/app/styles/main.less b/client/app/styles/main.less index ba220398e..f14911ea2 100644 --- a/client/app/styles/main.less +++ b/client/app/styles/main.less @@ -482,77 +482,105 @@ h2 { } } } - - .stack .shape .highlighted { - display: none; - } - - .stack .onlyHighlight .shape { - .border { display: none; } - .shadow { display: none; } - .node { display: none; } - .highlighted { display: inline; } - } - - .stack .shape .metric-fill { - display: none; - } - - .shape { - transform: scale(1); - cursor: pointer; - - /* cloud paths have stroke-width set dynamically */ - &:not(.shape-cloud) .border { - stroke-width: @node-border-stroke-width; - fill: @background-color; - transition: stroke-opacity 0.333s @base-ease, fill 0.333s @base-ease; - stroke-opacity: 1; - } - - &.metrics .border { - fill: @background-lighter-color; - stroke-opacity: 0.3; - } - - .metric-fill { - stroke: none; - fill: #A0BE7E; - fill-opacity: 0.7; - } - - .shadow { - stroke: none; - fill: @background-lighter-color; - } - - .node { - fill: @text-color; - stroke: @background-lighter-color; - stroke-width: 2px; - } - - text { - font-size: 12px; - dominant-baseline: middle; - text-anchor: middle; - } - - .highlighted { - fill: @weave-blue; - fill-opacity: @node-highlight-fill-opacity; - stroke: @weave-blue; - stroke-width: @node-highlight-stroke-width; - stroke-opacity: @node-highlight-stroke-opacity; - } - } - - .stack .shape .border { - stroke-width: @node-border-stroke-width - 0.5; - } - } +// +// stacks and shapes!!! +// + +.stack .shape .highlighted { + display: none; +} + +.stack .onlyHighlight .shape { + .border { display: none; } + .shadow { display: none; } + .node { display: none; } + .highlighted { display: inline; } +} + +.stack .shape .metric-fill { + display: none; +} + +.shape { + transform: scale(1); + + /* cloud paths have stroke-width set dynamically */ + &:not(.shape-cloud) .border { + stroke-width: @node-border-stroke-width; + fill: @background-color; + transition: stroke-opacity 0.333s @base-ease, fill 0.333s @base-ease; + stroke-opacity: 1; + } + + &.metrics .border { + fill: @background-lighter-color; + stroke-opacity: 0.3; + } + + .metric-fill { + stroke: none; + fill: #A0BE7E; + fill-opacity: 0.7; + } + + .shadow { + stroke: none; + fill: @background-lighter-color; + } + + text { + font-size: 12px; + dominant-baseline: middle; + text-anchor: middle; + } + + .highlighted { + fill: @weave-blue; + fill-opacity: @node-highlight-fill-opacity; + stroke: @weave-blue; + stroke-width: @node-highlight-stroke-width; + stroke-opacity: @node-highlight-stroke-opacity; + } +} + +.shape.wireframe { + .shadow, .border { + fill-opacity: 0; + } + + .border { + stroke: white; + } + + .node { + fill: white; + stroke: white; + // fill-opacity: 0.9; + // stroke-opacity: 0.9; + } +} + +.noNode .wireframe .node { + display: none; +} + +.stack .shape .border { + stroke-width: @node-border-stroke-width - 0.5; +} + +.shape:not(.wireframe) .node { + fill: @text-color; + stroke: @background-lighter-color; + stroke-width: 2px; +} + + +// ---- + + + .matched-results { text-align: center; @@ -643,17 +671,28 @@ h2 { &-header { .colorable; + &.show-switch-topology &-label { + .btn-opacity; + opacity: 0.8; + &:hover { + opacity: 1; + } + } + &-wrapper { - padding: 36px 36px 8px 36px; + padding: 36px 36px 8px 24px; } &-label { color: white; - margin: 0; - width: 348px; + margin: 0 0 0 64px; padding-top: 0; } + svg { + float: left; + } + .details-tools { position: absolute; top: 16px; @@ -667,6 +706,7 @@ h2 { } &-relatives { + margin-left: 64px; margin-top: 4px; font-size: 120%; color: @white;