mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-03 02:00:43 +00:00
Pure-mixin-ify more stuff.
Helps a lot for dragging around the canvas.
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
"comma-dangle": 0,
|
||||
"object-curly-spacing": 0,
|
||||
"react/jsx-closing-bracket-location": 0,
|
||||
"react/prefer-stateless-function": 0,
|
||||
"react/sort-comp": 0,
|
||||
"react/prop-types": 0
|
||||
}
|
||||
|
||||
@@ -1,27 +1,33 @@
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||
import reactMixin from 'react-mixin';
|
||||
import d3 from 'd3';
|
||||
import { Motion, spring } from 'react-motion';
|
||||
|
||||
import Node from './node';
|
||||
|
||||
export default function NodeContainer(props) {
|
||||
const { dx, dy, focused, layoutPrecision, zoomScale } = props;
|
||||
const animConfig = [80, 20]; // stiffness, damping
|
||||
const scaleFactor = focused ? (2 / zoomScale) : 1;
|
||||
const other = _.omit(props, 'dx', 'dy');
|
||||
export default class NodeContainer extends React.Component {
|
||||
render() {
|
||||
const { dx, dy, focused, layoutPrecision, zoomScale } = this.props;
|
||||
const animConfig = [80, 20]; // stiffness, damping
|
||||
const scaleFactor = focused ? (2 / zoomScale) : 1;
|
||||
const other = _.omit(this.props, 'dx', 'dy');
|
||||
|
||||
return (
|
||||
<Motion style={{
|
||||
x: spring(dx, animConfig),
|
||||
y: spring(dy, animConfig),
|
||||
f: spring(scaleFactor, animConfig)
|
||||
}}>
|
||||
{interpolated => {
|
||||
const transform = `translate(${d3.round(interpolated.x, layoutPrecision)},`
|
||||
+ `${d3.round(interpolated.y, layoutPrecision)})`;
|
||||
return <Node {...other} transform={transform} scaleFactor={interpolated.f} />;
|
||||
}}
|
||||
</Motion>
|
||||
);
|
||||
return (
|
||||
<Motion style={{
|
||||
x: spring(dx, animConfig),
|
||||
y: spring(dy, animConfig),
|
||||
f: spring(scaleFactor, animConfig)
|
||||
}}>
|
||||
{interpolated => {
|
||||
const transform = `translate(${d3.round(interpolated.x, layoutPrecision)},`
|
||||
+ `${d3.round(interpolated.y, layoutPrecision)})`;
|
||||
return <Node {...other} transform={transform} scaleFactor={interpolated.f} />;
|
||||
}}
|
||||
</Motion>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
reactMixin.onClass(NodeContainer, PureRenderMixin);
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
import React from 'react';
|
||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||
import reactMixin from 'react-mixin';
|
||||
|
||||
import EdgeContainer from './edge-container';
|
||||
|
||||
export default function NodesChartEdges({hasSelectedNode, highlightedEdgeIds,
|
||||
layoutEdges, layoutPrecision, selectedNodeId}) {
|
||||
return (
|
||||
<g className="nodes-chart-edges">
|
||||
{layoutEdges.toIndexedSeq().map(edge => <EdgeContainer key={edge.get('id')}
|
||||
id={edge.get('id')} source={edge.get('source')} target={edge.get('target')}
|
||||
points={edge.get('points')} layoutPrecision={layoutPrecision}
|
||||
highlightedEdgeIds={highlightedEdgeIds} hasSelectedNode={hasSelectedNode}
|
||||
selectedNodeId={selectedNodeId} />)}
|
||||
</g>
|
||||
);
|
||||
export default class NodesChartEdges extends React.Component {
|
||||
render() {
|
||||
const {hasSelectedNode, highlightedEdgeIds, layoutEdges, layoutPrecision,
|
||||
selectedNodeId} = this.props;
|
||||
|
||||
return (
|
||||
<g className="nodes-chart-edges">
|
||||
{layoutEdges.toIndexedSeq().map(edge => <EdgeContainer key={edge.get('id')}
|
||||
id={edge.get('id')} source={edge.get('source')} target={edge.get('target')}
|
||||
points={edge.get('points')} layoutPrecision={layoutPrecision}
|
||||
highlightedEdgeIds={highlightedEdgeIds} hasSelectedNode={hasSelectedNode}
|
||||
selectedNodeId={selectedNodeId} />)}
|
||||
</g>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
reactMixin.onClass(NodesChartEdges, PureRenderMixin);
|
||||
|
||||
@@ -1,23 +1,30 @@
|
||||
import React from 'react';
|
||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||
import reactMixin from 'react-mixin';
|
||||
|
||||
import NodesChartEdges from './nodes-chart-edges';
|
||||
import NodesChartNodes from './nodes-chart-nodes';
|
||||
|
||||
export default function NodesChartElements(props) {
|
||||
return (
|
||||
<g className="nodes-chart-elements" transform={props.transform}>
|
||||
<NodesChartEdges layoutEdges={props.edges} selectedNodeId={props.selectedNodeId}
|
||||
highlightedEdgeIds={props.highlightedEdgeIds}
|
||||
hasSelectedNode={props.hasSelectedNode}
|
||||
layoutPrecision={props.layoutPrecision} />
|
||||
<NodesChartNodes layoutNodes={props.nodes} selectedNodeId={props.selectedNodeId}
|
||||
selectedMetric={props.selectedMetric}
|
||||
highlightedNodeIds={props.highlightedNodeIds}
|
||||
hasSelectedNode={props.hasSelectedNode}
|
||||
adjacentNodes={props.adjacentNodes}
|
||||
nodeScale={props.nodeScale} onNodeClick={props.onNodeClick}
|
||||
scale={props.scale} selectedNodeScale={props.selectedNodeScale}
|
||||
topologyId={props.topologyId} layoutPrecision={props.layoutPrecision} />
|
||||
</g>
|
||||
);
|
||||
export default class NodesChartElements extends React.Component {
|
||||
render() {
|
||||
const props = this.props;
|
||||
return (
|
||||
<g className="nodes-chart-elements" transform={props.transform}>
|
||||
<NodesChartEdges layoutEdges={props.edges} selectedNodeId={props.selectedNodeId}
|
||||
highlightedEdgeIds={props.highlightedEdgeIds}
|
||||
hasSelectedNode={props.hasSelectedNode}
|
||||
layoutPrecision={props.layoutPrecision} />
|
||||
<NodesChartNodes layoutNodes={props.nodes} selectedNodeId={props.selectedNodeId}
|
||||
selectedMetric={props.selectedMetric}
|
||||
highlightedNodeIds={props.highlightedNodeIds}
|
||||
hasSelectedNode={props.hasSelectedNode}
|
||||
adjacentNodes={props.adjacentNodes}
|
||||
nodeScale={props.nodeScale} onNodeClick={props.onNodeClick}
|
||||
scale={props.scale} selectedNodeScale={props.selectedNodeScale}
|
||||
topologyId={props.topologyId} layoutPrecision={props.layoutPrecision} />
|
||||
</g>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
reactMixin.onClass(NodesChartElements, PureRenderMixin);
|
||||
|
||||
@@ -1,68 +1,76 @@
|
||||
import React from 'react';
|
||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||
import reactMixin from 'react-mixin';
|
||||
|
||||
import NodeContainer from './node-container';
|
||||
|
||||
export default function NodesChartNodes({adjacentNodes, highlightedNodeIds,
|
||||
layoutNodes, layoutPrecision, nodeScale, onNodeClick, scale,
|
||||
selectedMetric, selectedNodeScale, selectedNodeId, topologyId}) {
|
||||
const zoomScale = scale;
|
||||
export default class NodesChartNodes extends React.Component {
|
||||
render() {
|
||||
const {adjacentNodes, highlightedNodeIds,
|
||||
layoutNodes, layoutPrecision, nodeScale, onNodeClick, scale,
|
||||
selectedMetric, selectedNodeScale, selectedNodeId, topologyId} = this.props;
|
||||
|
||||
// highlighter functions
|
||||
const setHighlighted = node => node.set('highlighted',
|
||||
highlightedNodeIds.has(node.get('id')) || selectedNodeId === node.get('id'));
|
||||
const setFocused = node => node.set('focused', selectedNodeId
|
||||
&& (selectedNodeId === node.get('id')
|
||||
|| (adjacentNodes && adjacentNodes.includes(node.get('id')))));
|
||||
const setBlurred = node => node.set('blurred', selectedNodeId && !node.get('focused'));
|
||||
const zoomScale = scale;
|
||||
|
||||
// make sure blurred nodes are in the background
|
||||
const sortNodes = node => {
|
||||
if (node.get('blurred')) {
|
||||
return 0;
|
||||
}
|
||||
if (node.get('highlighted')) {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
// highlighter functions
|
||||
const setHighlighted = node => node.set('highlighted',
|
||||
highlightedNodeIds.has(node.get('id')) || selectedNodeId === node.get('id'));
|
||||
const setFocused = node => node.set('focused', selectedNodeId
|
||||
&& (selectedNodeId === node.get('id')
|
||||
|| (adjacentNodes && adjacentNodes.includes(node.get('id')))));
|
||||
const setBlurred = node => node.set('blurred', selectedNodeId && !node.get('focused'));
|
||||
|
||||
// TODO: think about pulling this up into the store.
|
||||
const metric = node => (
|
||||
node.get('metrics') && node.get('metrics')
|
||||
.filter(m => m.get('id') === selectedMetric)
|
||||
.first()
|
||||
);
|
||||
// make sure blurred nodes are in the background
|
||||
const sortNodes = node => {
|
||||
if (node.get('blurred')) {
|
||||
return 0;
|
||||
}
|
||||
if (node.get('highlighted')) {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
const nodesToRender = layoutNodes.toIndexedSeq()
|
||||
.map(setHighlighted)
|
||||
.map(setFocused)
|
||||
.map(setBlurred)
|
||||
.sortBy(sortNodes);
|
||||
// TODO: think about pulling this up into the store.
|
||||
const metric = node => (
|
||||
node.get('metrics') && node.get('metrics')
|
||||
.filter(m => m.get('id') === selectedMetric)
|
||||
.first()
|
||||
);
|
||||
|
||||
return (
|
||||
<g className="nodes-chart-nodes">
|
||||
{nodesToRender.map(node => <NodeContainer
|
||||
blurred={node.get('blurred')}
|
||||
focused={node.get('focused')}
|
||||
highlighted={node.get('highlighted')}
|
||||
topologyId={topologyId}
|
||||
shape={node.get('shape')}
|
||||
stack={node.get('stack')}
|
||||
onClick={onNodeClick}
|
||||
key={node.get('id')}
|
||||
id={node.get('id')}
|
||||
label={node.get('label')}
|
||||
pseudo={node.get('pseudo')}
|
||||
nodeCount={node.get('nodeCount')}
|
||||
subLabel={node.get('subLabel')}
|
||||
metric={metric(node)}
|
||||
rank={node.get('rank')}
|
||||
layoutPrecision={layoutPrecision}
|
||||
selectedNodeScale={selectedNodeScale}
|
||||
nodeScale={nodeScale}
|
||||
zoomScale={zoomScale}
|
||||
dx={node.get('x')}
|
||||
dy={node.get('y')} />)}
|
||||
</g>
|
||||
);
|
||||
const nodesToRender = layoutNodes.toIndexedSeq()
|
||||
.map(setHighlighted)
|
||||
.map(setFocused)
|
||||
.map(setBlurred)
|
||||
.sortBy(sortNodes);
|
||||
|
||||
return (
|
||||
<g className="nodes-chart-nodes">
|
||||
{nodesToRender.map(node => <NodeContainer
|
||||
blurred={node.get('blurred')}
|
||||
focused={node.get('focused')}
|
||||
highlighted={node.get('highlighted')}
|
||||
topologyId={topologyId}
|
||||
shape={node.get('shape')}
|
||||
stack={node.get('stack')}
|
||||
onClick={onNodeClick}
|
||||
key={node.get('id')}
|
||||
id={node.get('id')}
|
||||
label={node.get('label')}
|
||||
pseudo={node.get('pseudo')}
|
||||
nodeCount={node.get('nodeCount')}
|
||||
subLabel={node.get('subLabel')}
|
||||
metric={metric(node)}
|
||||
rank={node.get('rank')}
|
||||
layoutPrecision={layoutPrecision}
|
||||
selectedNodeScale={selectedNodeScale}
|
||||
nodeScale={nodeScale}
|
||||
zoomScale={zoomScale}
|
||||
dx={node.get('x')}
|
||||
dy={node.get('y')} />)}
|
||||
</g>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
reactMixin.onClass(NodesChartNodes, PureRenderMixin);
|
||||
|
||||
Reference in New Issue
Block a user