nodes-chart only re-rendered on prop updates!!!

This commit is contained in:
Simon Howe
2016-09-06 16:06:19 +02:00
parent 4b7471b1b0
commit a1b8e963dc
7 changed files with 65 additions and 31 deletions

View File

@@ -13,6 +13,8 @@ class NodeContainer extends React.Component {
const scaleFactor = focused ? (1 / zoomScale) : 1;
const other = _.omit(this.props, 'dx', 'dy');
console.log('nodecontainer.render');
return (
<Motion style={{
x: spring(dx, animConfig),

View File

@@ -5,14 +5,16 @@ import React from 'react';
import { connect } from 'react-redux';
import { Map as makeMap, fromJS, is } from 'immutable';
import timely from 'timely';
import { diff } from 'deep-diff';
import { nodeAdjacenciesSelector, adjacentNodesSelector } from '../selectors/chartSelectors';
import { clickBackground } from '../actions/app-actions';
import { EDGE_ID_SEPARATOR } from '../constants/naming';
import { MIN_NODE_SIZE, DETAILS_PANEL_WIDTH, MAX_NODE_SIZE } from '../constants/styles';
import Logo from '../components/logo';
import { doLayout } from './nodes-layout';
import NodesChartElements from './nodes-chart-elements';
import { getActiveTopologyOptions, getAdjacentNodes } from '../utils/topology-utils';
import { getActiveTopologyOptions } from '../utils/topology-utils';
const log = debug('scope:nodes-chart');
@@ -23,6 +25,24 @@ const radiusDensity = d3.scale.threshold()
.domain([3, 6])
.range([2.5, 3.5, 3]);
/**
* dynamic coords precision based on topology size
*/
function getLayoutPrecision(nodesCount) {
let precision;
if (nodesCount >= 50) {
precision = 0;
} else if (nodesCount > 20) {
precision = 1;
} else if (nodesCount > 10) {
precision = 2;
} else {
precision = 3;
}
return precision;
}
function identityPresevingMerge(a, b) {
//
@@ -152,6 +172,7 @@ class NodesChart extends React.Component {
}
componentWillReceiveProps(nextProps) {
console.log('componentWillReceiveProps', diff(nextProps, this.props), nextProps);
// gather state, setState should be called only once here
const state = _.assign({}, this.state);
@@ -224,6 +245,7 @@ class NodesChart extends React.Component {
const svgClassNames = this.props.isEmpty ? 'hide' : '';
console.log('nodes-chart.render');
const layoutPrecision = getLayoutPrecision(nodes.size);
return (
<div className="nodes-chart">
<svg width="100%" height="100%" id="nodes-chart-canvas"
@@ -238,7 +260,7 @@ class NodesChart extends React.Component {
scale={scale}
transform={transform}
selectedNodeScale={this.state.selectedNodeScale}
layoutPrecision={this.props.layoutPrecision} />
layoutPrecision={layoutPrecision} />
</svg>
</div>
);
@@ -411,7 +433,8 @@ class NodesChart extends React.Component {
function mapStateToProps(state) {
return {
adjacentNodes: getAdjacentNodes(state),
nodes: nodeAdjacenciesSelector(state),
adjacentNodes: adjacentNodesSelector(state),
forceRelayout: state.get('forceRelayout'),
selectedNodeId: state.get('selectedNodeId'),
topologyId: state.get('currentTopologyId'),

View File

@@ -5,6 +5,7 @@ import { connect } from 'react-redux';
import { List as makeList, Map as makeMap } from 'immutable';
import NodeDetailsTable from '../components/node-details/node-details-table';
import { clickNode, sortOrderChanged } from '../actions/app-actions';
import { nodesSelector } from '../selectors/chartSelectors';
import { getNodeColor } from '../utils/color-utils';
@@ -142,6 +143,7 @@ class NodesGrid extends React.Component {
function mapStateToProps(state) {
return {
nodes: nodesSelector(state),
gridSortBy: state.get('gridSortBy'),
gridSortedDesc: state.get('gridSortedDesc'),
currentTopology: state.get('currentTopology'),

View File

@@ -142,6 +142,7 @@ class App extends React.Component {
}
}
function mapStateToProps(state) {
return {
activeTopologyOptions: getActiveTopologyOptions(state),
@@ -158,6 +159,7 @@ function mapStateToProps(state) {
};
}
export default connect(
mapStateToProps
)(App);

View File

@@ -8,30 +8,11 @@ import { DelayedShow } from '../utils/delayed-show';
import { Loading, getNodeType } from './loading';
import { isTopologyEmpty } from '../utils/topology-utils';
import { CANVAS_MARGINS } from '../constants/styles';
import { nodesSelector } from '../selectors/chartSelectors';
const navbarHeight = 194;
const marginTop = 0;
/**
* dynamic coords precision based on topology size
*/
function getLayoutPrecision(nodesCount) {
let precision;
if (nodesCount >= 50) {
precision = 0;
} else if (nodesCount > 20) {
precision = 1;
} else if (nodesCount > 10) {
precision = 2;
} else {
precision = 3;
}
return precision;
}
class Nodes extends React.Component {
constructor(props, context) {
super(props, context);
@@ -68,9 +49,8 @@ class Nodes extends React.Component {
}
render() {
const { nodes, topologyEmpty, gridMode, topologiesLoaded, nodesLoaded, topologies,
const { topologyEmpty, gridMode, topologiesLoaded, nodesLoaded, topologies,
currentTopology } = this.props;
const layoutPrecision = getLayoutPrecision(nodes.size);
console.log('nodes.render');
@@ -87,13 +67,10 @@ class Nodes extends React.Component {
{gridMode ?
<NodesGrid {...this.state}
nodeSize="24"
nodes={nodes}
margins={CANVAS_MARGINS}
/> :
<NodesChart {...this.state}
nodes={nodes}
margins={CANVAS_MARGINS}
layoutPrecision={layoutPrecision}
/>}
</div>
);
@@ -116,7 +93,6 @@ function mapStateToProps(state) {
return {
currentTopology: state.get('currentTopology'),
gridMode: state.get('gridMode'),
nodes: nodesSelector(state),
nodesLoaded: state.get('nodesLoaded'),
topologies: state.get('topologies'),
topologiesLoaded: state.get('topologiesLoaded'),

View File

@@ -1,5 +1,15 @@
import { createSelector } from 'reselect';
import { Map as makeMap } from 'immutable';
import { createSelector, createSelectorCreator, defaultMemoize } from 'reselect';
import { Map as makeMap, is } from 'immutable';
import { getAdjacentNodes } from '../utils/topology-utils';
// imm createSelector
//
const imCreateSelector = createSelectorCreator(
defaultMemoize,
is
);
const allNodesSelector = state => state.get('nodes');
@@ -11,7 +21,7 @@ export const nodesSelector = createSelector(
);
export const nodeAdjacenciesSelector = createSelector(
export const _nodeAdjacenciesSelector = createSelector(
nodesSelector,
(nodes) => nodes.map(n => makeMap({
id: n.get('id'),
@@ -20,6 +30,24 @@ export const nodeAdjacenciesSelector = createSelector(
);
export const nodeAdjacenciesSelector = imCreateSelector(
_nodeAdjacenciesSelector,
(nodes) => nodes
);
const _adjacentNodesSelector = createSelector(
getAdjacentNodes,
(ns) => ns
);
export const adjacentNodesSelector = imCreateSelector(
_adjacentNodesSelector,
(adjacentNodes) => adjacentNodes
);
export const layoutNodesSelector = (_, props) => props.layoutNodes;

View File

@@ -143,6 +143,7 @@ export function isTopologyEmpty(state) {
&& state.get('nodes').size === 0;
}
export function getAdjacentNodes(state, originNodeId) {
let adjacentNodes = makeSet();
const nodeId = originNodeId || state.get('selectedNodeId');