Removed old graph nodes obsolete code.

This commit is contained in:
Filip Barl
2018-08-07 17:07:01 +02:00
parent 18342634c8
commit 65dad7242e
5 changed files with 2 additions and 510 deletions

View File

@@ -1,24 +0,0 @@
import React from 'react';
import { NODE_BASE_SIZE } from '../constants/styles';
export default function NodeShapeStack(props) {
const verticalDistance = NODE_BASE_SIZE * (props.contrastMode ? 0.12 : 0.1);
const verticalTranslate = t => `translate(0, ${t * verticalDistance})`;
const Shape = props.shape;
// Stack three shapes on top of one another pretending they are never highlighted.
// Instead, fake the highlight of the whole stack with a vertically stretched shape
// drawn in the background. This seems to give a good approximation of the stack
// highlight and prevents us from needing to do some render-heavy SVG clipping magic.
return (
<g transform={verticalTranslate(-2.5)} className="stack">
<g transform={`${verticalTranslate(1)} scale(1, 1.14)`}>
<Shape className="highlight-only" {...props} />
</g>
<g transform={verticalTranslate(2)}><Shape {...props} highlighted={false} /></g>
<g transform={verticalTranslate(1)}><Shape {...props} highlighted={false} /></g>
<g transform={verticalTranslate(0)}><Shape {...props} highlighted={false} /></g>
</g>
);
}

View File

@@ -1,91 +0,0 @@
import React from 'react';
import classNames from 'classnames';
import { NODE_BASE_SIZE } from '../constants/styles';
import {
getMetricValue,
getMetricColor,
getClipPathDefinition,
} from '../utils/metric-utils';
import {
pathElement,
circleElement,
rectangleElement,
circleShapeProps,
triangleShapeProps,
squareShapeProps,
pentagonShapeProps,
hexagonShapeProps,
heptagonShapeProps,
octagonShapeProps,
cloudShapeProps,
cylinderShapeProps,
dottedCylinderShapeProps,
sheetShapeProps
} from '../utils/node-shape-utils';
import { encodeIdAttribute } from '../utils/dom-utils';
function NodeShape(shapeType, shapeElement, shapeProps, {
id, highlighted, color, metric
}) {
const { height, hasMetric, formattedValue } = getMetricValue(metric);
const className = classNames('shape', `shape-${shapeType}`, { metrics: hasMetric });
const metricStyle = { fill: getMetricColor(metric) };
const clipId = encodeIdAttribute(`metric-clip-${id}`);
return (
<g className={className}>
{highlighted && shapeElement({
className: 'highlight-border',
transform: `scale(${NODE_BASE_SIZE * 0.5})`,
...shapeProps,
})}
{highlighted && shapeElement({
className: 'highlight-shadow',
transform: `scale(${NODE_BASE_SIZE * 0.5})`,
...shapeProps,
})}
{shapeElement({
className: 'background',
transform: `scale(${NODE_BASE_SIZE * 0.48})`,
...shapeProps,
})}
{hasMetric && getClipPathDefinition(clipId, height, 0.48)}
{hasMetric && shapeElement({
className: 'metric-fill',
transform: `scale(${NODE_BASE_SIZE * 0.48})`,
clipPath: `url(#${clipId})`,
style: metricStyle,
...shapeProps,
})}
{shapeElement({
className: 'shadow',
transform: `scale(${NODE_BASE_SIZE * 0.49})`,
...shapeProps,
})}
{shapeElement({
className: 'border',
transform: `scale(${NODE_BASE_SIZE * 0.5})`,
stroke: color,
...shapeProps,
})}
{hasMetric && highlighted ?
<text>{formattedValue}</text> :
<circle className="node" r={NODE_BASE_SIZE * 0.1} />
}
</g>
);
}
export const NodeShapeCircle = props => NodeShape('circle', circleElement, circleShapeProps, props);
export const NodeShapeTriangle = props => NodeShape('triangle', pathElement, triangleShapeProps, props);
export const NodeShapeSquare = props => NodeShape('square', rectangleElement, squareShapeProps, props);
export const NodeShapePentagon = props => NodeShape('pentagon', pathElement, pentagonShapeProps, props);
export const NodeShapeHexagon = props => NodeShape('hexagon', pathElement, hexagonShapeProps, props);
export const NodeShapeHeptagon = props => NodeShape('heptagon', pathElement, heptagonShapeProps, props);
export const NodeShapeOctagon = props => NodeShape('octagon', pathElement, octagonShapeProps, props);
export const NodeShapeCloud = props => NodeShape('cloud', pathElement, cloudShapeProps, props);
export const NodeShapeCylinder = props => NodeShape('cylinder', pathElement, cylinderShapeProps, props);
export const NodeShapeDottedCylinder = props => NodeShape('dottedcylinder', pathElement, dottedCylinderShapeProps, props);
export const NodeShapeSheet = props => NodeShape('sheet', pathElement, sheetShapeProps, props);

View File

@@ -1,191 +0,0 @@
import React from 'react';
import { connect } from 'react-redux';
import classnames from 'classnames';
import { Map as makeMap, List as makeList } from 'immutable';
import { clickNode, enterNode, leaveNode } from '../actions/app-actions';
import { getNodeColor } from '../utils/color-utils';
import MatchedText from '../components/matched-text';
import MatchedResults from '../components/matched-results';
import { trackAnalyticsEvent } from '../utils/tracking-utils';
import { GRAPH_VIEW_MODE } from '../constants/naming';
import { NODE_BASE_SIZE } from '../constants/styles';
import NodeShapeStack from './node-shape-stack';
import NodeNetworksOverlay from './node-networks-overlay';
import {
NodeShapeCircle,
NodeShapeTriangle,
NodeShapeSquare,
NodeShapePentagon,
NodeShapeHexagon,
NodeShapeHeptagon,
NodeShapeOctagon,
NodeShapeCloud,
NodeShapeCylinder,
NodeShapeDottedCylinder,
NodeShapeSheet
} from './node-shapes';
const labelWidth = 1.2 * NODE_BASE_SIZE;
const nodeShapes = {
circle: NodeShapeCircle,
triangle: NodeShapeTriangle,
square: NodeShapeSquare,
pentagon: NodeShapePentagon,
hexagon: NodeShapeHexagon,
heptagon: NodeShapeHeptagon,
octagon: NodeShapeOctagon,
cloud: NodeShapeCloud,
cylinder: NodeShapeCylinder,
dottedcylinder: NodeShapeDottedCylinder,
storagesheet: NodeShapeSheet
};
function stackedShape(Shape) {
const factory = React.createFactory(NodeShapeStack);
return props => factory(Object.assign({}, props, {shape: Shape}));
}
function getNodeShape({ shape, stack }) {
const nodeShape = nodeShapes[shape];
if (!nodeShape) {
throw new Error(`Unknown shape: ${shape}!`);
}
return stack ? stackedShape(nodeShape) : nodeShape;
}
class Node extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
hovered: false,
};
this.handleMouseClick = this.handleMouseClick.bind(this);
this.handleMouseEnter = this.handleMouseEnter.bind(this);
this.handleMouseLeave = this.handleMouseLeave.bind(this);
this.saveShapeRef = this.saveShapeRef.bind(this);
}
renderSvgLabels(labelClassName, labelMinorClassName, labelOffsetY) {
const { label, labelMinor } = this.props;
return (
<g className="node-labels-container">
<text className={labelClassName} y={13 + labelOffsetY} textAnchor="middle">{label}</text>
<text className={labelMinorClassName} y={30 + labelOffsetY} textAnchor="middle">
{labelMinor}
</text>
</g>
);
}
renderStandardLabels(labelClassName, labelMinorClassName, labelOffsetY, mouseEvents) {
const { label, labelMinor, matches = makeMap() } = this.props;
const matchedMetadata = matches.get('metadata', makeList());
const matchedParents = matches.get('parents', makeList());
const matchedNodeDetails = matchedMetadata.concat(matchedParents);
return (
<foreignObject
className="node-labels-container"
y={labelOffsetY}
x={-0.5 * labelWidth}
width={labelWidth}
height="5em">
<div className="node-label-wrapper" {...mouseEvents}>
<div className={labelClassName}>
<MatchedText text={label} match={matches.get('label')} />
</div>
<div className={labelMinorClassName}>
<MatchedText text={labelMinor} match={matches.get('labelMinor')} />
</div>
<MatchedResults matches={matchedNodeDetails} />
</div>
</foreignObject>
);
}
render() {
const {
focused, highlighted, networks, pseudo, rank, label, transform,
exportingGraph, showingNetworks, stack, id, metric
} = this.props;
const { hovered } = this.state;
const color = getNodeColor(rank, label, pseudo);
const truncate = !focused && !hovered;
const labelOffsetY = (showingNetworks && networks) ? 40 : 28;
const nodeClassName = classnames('node', { highlighted, hovered, pseudo });
const labelClassName = classnames('node-label', { truncate });
const labelMinorClassName = classnames('node-label-minor', { truncate });
const NodeShapeType = getNodeShape(this.props);
const mouseEvents = {
onClick: this.handleMouseClick,
onMouseEnter: this.handleMouseEnter,
onMouseLeave: this.handleMouseLeave,
};
return (
<g className={nodeClassName} transform={transform}>
{exportingGraph ?
this.renderSvgLabels(labelClassName, labelMinorClassName, labelOffsetY) :
this.renderStandardLabels(labelClassName, labelMinorClassName, labelOffsetY, mouseEvents)}
<g {...mouseEvents} ref={this.saveShapeRef}>
<NodeShapeType
id={id}
highlighted={highlighted}
color={color}
metric={metric}
contrastMode={this.props.contrastMode}
/>
</g>
{showingNetworks && <NodeNetworksOverlay networks={networks} stack={stack} />}
</g>
);
}
saveShapeRef(ref) {
this.shapeRef = ref;
}
handleMouseClick(ev) {
ev.stopPropagation();
trackAnalyticsEvent('scope.node.click', {
layout: GRAPH_VIEW_MODE,
topologyId: this.props.currentTopology.get('id'),
parentTopologyId: this.props.currentTopology.get('parentId'),
});
this.props.clickNode(this.props.id, this.props.label, this.shapeRef.getBoundingClientRect());
}
handleMouseEnter() {
this.props.enterNode(this.props.id);
this.setState({ hovered: true });
}
handleMouseLeave() {
this.props.leaveNode(this.props.id);
this.setState({ hovered: false });
}
}
function mapStateToProps(state) {
return {
exportingGraph: state.get('exportingGraph'),
showingNetworks: state.get('showingNetworks'),
currentTopology: state.get('currentTopology'),
contrastMode: state.get('contrastMode'),
};
}
export default connect(
mapStateToProps,
{ clickNode, enterNode, leaveNode }
)(Node);

View File

@@ -1,34 +0,0 @@
import React from 'react';
import range from 'lodash/range';
import { line, curveCardinalClosed } from 'd3-shape';
import { UNIT_CLOUD_PATH, UNIT_CYLINDER_PATH, SHEET } from '../constants/styles';
export const pathElement = React.createFactory('path');
export const circleElement = React.createFactory('circle');
export const rectangleElement = React.createFactory('rect');
function curvedUnitPolygonPath(n) {
const curve = curveCardinalClosed.tension(0.65);
const spline = line().curve(curve);
const innerAngle = (2 * Math.PI) / n;
return spline(range(0, n).map(k => [
Math.sin(k * innerAngle),
-Math.cos(k * innerAngle),
]));
}
export const circleShapeProps = { r: 1 };
export const triangleShapeProps = { d: curvedUnitPolygonPath(3) };
export const squareShapeProps = {
width: 1.8, height: 1.8, rx: 0.4, ry: 0.4, x: -0.9, y: -0.9
};
export const pentagonShapeProps = { d: curvedUnitPolygonPath(5) };
export const hexagonShapeProps = { d: curvedUnitPolygonPath(6) };
export const heptagonShapeProps = { d: curvedUnitPolygonPath(7) };
export const octagonShapeProps = { d: curvedUnitPolygonPath(8) };
export const cloudShapeProps = { d: UNIT_CLOUD_PATH };
export const cylinderShapeProps = { d: UNIT_CYLINDER_PATH };
export const dottedCylinderShapeProps = { d: UNIT_CYLINDER_PATH };
export const sheetShapeProps = { d: SHEET };

View File

@@ -435,97 +435,8 @@ a {
fill: $text-secondary-color;
}
.nodes-chart-elements .node {
text-align: center;
.node-label {
color: $text-color;
}
.node-label-minor {
line-height: 125%;
}
.node-labels-container {
transform: scale($node-text-scale);
pointer-events: none;
}
.node-label-wrapper {
//
// Base line height doesn't hop across foreignObject =/
//
line-height: 150%;
//
// inline-block so wrapper is only as wide as content.
//
display: inline-block;
//
// - inline-block gets a different baseline depending on overflow value
// - this element gets its overflow value changed sometimes.
// - explicitly set the baseline so the text doesn't jump up and down.
// http://stackoverflow.com/questions/9273016
//
vertical-align: top;
cursor: pointer;
pointer-events: all;
font-size: $font-size-small;
width: 100%;
}
.node-label-minor {
color: $text-secondary-color;
font-size: $font-size-tiny;
}
.node-label, .node-label-minor {
span {
border-radius: $border-radius-soft;
}
span:not(.match) {
padding: 0 0.25em;
background-color: $label-background-color;
}
span:empty {
padding: 0;
}
}
.matched-results {
background-color: $label-background-color;
}
&.pseudo {
cursor: default;
.node-label {
fill: $text-secondary-color;
}
.node-label-minor {
fill: $text-tertiary-color;
}
.node {
opacity: $node-pseudo-opacity;
}
.border {
opacity: $node-pseudo-opacity;
stroke: $text-tertiary-color;
}
}
.node-label, .node-label-minor {
text-align: center;
}
.match {
background-color: transparentize($color-blue-400, 0.25);
border: 1px solid $color-blue-400;
}
.nodes-chart-elements .matched-results {
background-color: $label-background-color;
}
.edge {
@@ -555,85 +466,6 @@ a {
}
}
.stack .highlight-only {
.background { display: none; }
.shadow { display: none; }
.border { display: none; }
.node { display: none; }
}
.stack .shape .metric-fill {
display: none;
}
.shape {
transform: scale(1);
cursor: pointer;
.highlight-border {
fill: none;
stroke: $color-blue-400;
stroke-width: 0.7 + $node-highlight-stroke-width * 2;
stroke-opacity: $node-highlight-stroke-opacity;
}
.highlight-shadow {
fill: none;
stroke: $color-white;
stroke-width: 0.7;
stroke-opacity: $node-highlight-shadow-opacity;
}
.background {
stroke: none;
fill: $background-lighter-color;
}
.metric-fill {
stroke: none;
fill-opacity: 0.7;
}
.border {
fill: none;
stroke-opacity: 1;
stroke-width: $node-border-stroke-width;
}
&.metrics .border {
stroke-opacity: 0.3;
}
.shadow {
fill: none;
stroke: $background-color;
stroke-width: $node-shadow-stroke-width;
}
.node {
fill: $text-color;
stroke: $background-lighter-color;
stroke-width: 0.05;
}
text {
transform: scale($node-text-scale);
font-size: $font-size-tiny;
dominant-baseline: middle;
text-anchor: middle;
}
}
.shape-dottedcylinder {
.border{
stroke-dasharray: 0.07;
}
}
.stack .shape .border {
stroke-width: $node-border-stroke-width * 0.8;
}
.edge-marker {
color: $edge-color;
fill: $edge-color;