From fa502ae6adbb3a656754cbca8f34c881dcc64f6a Mon Sep 17 00:00:00 2001 From: Simon Howe Date: Wed, 4 May 2016 14:58:36 +0200 Subject: [PATCH] Removes the combined table-topo-view --- client/app/scripts/actions/app-actions.js | 24 ++++++++++---- client/app/scripts/charts/nodes-chart.js | 23 +++++++------ client/app/scripts/charts/nodes-grid.js | 27 ++-------------- client/app/scripts/charts/nodes-layout.js | 21 ++++++------ client/app/scripts/components/app.js | 2 ++ .../app/scripts/components/debug-toolbar.js | 2 +- .../node-details/node-details-table.js | 7 ++-- client/app/scripts/components/nodes.js | 32 ++++++++++--------- client/app/scripts/constants/action-types.js | 3 +- client/app/scripts/reducers/root.js | 6 ++++ client/app/scripts/utils/router-utils.js | 1 + client/app/styles/main.less | 3 +- 12 files changed, 72 insertions(+), 79 deletions(-) diff --git a/client/app/scripts/actions/app-actions.js b/client/app/scripts/actions/app-actions.js index 1b799642e..e1ec2eca5 100644 --- a/client/app/scripts/actions/app-actions.js +++ b/client/app/scripts/actions/app-actions.js @@ -18,10 +18,12 @@ export function showHelp() { return {type: ActionTypes.SHOW_HELP}; } + export function hideHelp() { return {type: ActionTypes.HIDE_HELP}; } + export function toggleHelp() { return (dispatch, getState) => { if (getState().get('showingHelp')) { @@ -32,6 +34,20 @@ export function toggleHelp() { }; } + +export function toggleGridMode(enabled) { + return {type: ActionTypes.SET_GRID_MODE, enabled}; +} + + +export function sortOrderChanged(newOrder) { + return { + type: ActionTypes.SORT_ORDER_CHANGED, + newOrder + }; +} + + // // Networks // @@ -78,18 +94,12 @@ export function unpinNetwork(networkId) { }; } -export function sortOrderChanged(newOrder) { - AppDispatcher.dispatch({ - type: ActionTypes.SORT_ORDER_CHANGED, - newOrder - }); -} - // // Metrics // + export function selectMetric(metricId) { return { type: ActionTypes.SELECT_METRIC, diff --git a/client/app/scripts/charts/nodes-chart.js b/client/app/scripts/charts/nodes-chart.js index 41a70a047..c248cf972 100644 --- a/client/app/scripts/charts/nodes-chart.js +++ b/client/app/scripts/charts/nodes-chart.js @@ -5,7 +5,6 @@ import React from 'react'; import { connect } from 'react-redux'; import { Map as makeMap, fromJS, is as isDeepEqual } from 'immutable'; import timely from 'timely'; -import { Set as makeSet } from 'immutable'; import { clickBackground } from '../actions/app-actions'; import { EDGE_ID_SEPARATOR } from '../constants/naming'; @@ -13,8 +12,7 @@ import { DETAILS_PANEL_WIDTH } from '../constants/styles'; import Logo from '../components/logo'; import { doLayout } from './nodes-layout'; import NodesChartElements from './nodes-chart-elements'; -import { getActiveTopologyOptions, getAdjacentNodes, - isSameTopology } from '../utils/topology-utils'; +import { getActiveTopologyOptions, getAdjacentNodes } from '../utils/topology-utils'; const log = debug('scope:nodes-chart'); @@ -62,7 +60,7 @@ class NodesChart extends React.Component { // re-apply cached canvas zoom/pan to d3 behavior (or set defaul values) const defaultZoom = { scale: 1, panTranslateX: 0, panTranslateY: 0, hasZoomed: false }; const nextZoom = this.state.zoomCache[nextProps.topologyId] || defaultZoom; - if (nextZoom && this.zoom) { + if (this.zoom && nextZoom) { this.zoom.scale(nextZoom.scale); this.zoom.translate([nextZoom.panTranslateX, nextZoom.panTranslateY]); } @@ -80,13 +78,15 @@ class NodesChart extends React.Component { } // reset layout dimensions only when forced - state.height = nextProps.height; - state.width = nextProps.width; + // state.height = nextProps.height; + // state.width = nextProps.width; + state.height = nextProps.forceRelayout ? nextProps.height : (state.height || nextProps.height); + state.width = nextProps.forceRelayout ? nextProps.width : (state.width || nextProps.width); - _.assign(state, this.updateGraphState(nextProps, state)); - // if (nextProps.forceRelayout || nextProps.nodes !== this.props.nodes) { - // _.assign(state, this.updateGraphState(nextProps, state)); - // } + // _.assign(state, this.updateGraphState(nextProps, state)); + if (nextProps.forceRelayout || nextProps.nodes !== this.props.nodes) { + _.assign(state, this.updateGraphState(nextProps, state)); + } if (this.props.selectedNodeId !== nextProps.selectedNodeId) { _.assign(state, this.restoreLayout(state)); @@ -326,7 +326,6 @@ class NodesChart extends React.Component { const stateEdges = this.initEdges(props.nodes, stateNodes); const nodeScale = this.getNodeScale(props.nodes, state.width, state.height); const nextState = { nodeScale }; - console.log(props.nodeOrder); const nodeOrder = props.nodeOrder || makeMap(stateNodes .toList() .sortBy(n => n.get('label')) @@ -343,7 +342,6 @@ class NodesChart extends React.Component { nodeOrder }; - console.log('nodes-chart', state.height); const timedLayouter = timely(doLayout); const graph = timedLayouter(stateNodes, stateEdges, options); @@ -370,6 +368,7 @@ class NodesChart extends React.Component { if (!this.props.noZoom && !state.hasZoomed && zoomFactor > 0 && zoomFactor < 1) { zoomScale = zoomFactor; + console.log(zoomScale); // saving in d3's behavior cache if (this.zoom) { this.zoom.scale(zoomFactor); diff --git a/client/app/scripts/charts/nodes-grid.js b/client/app/scripts/charts/nodes-grid.js index 771f74407..91b20458f 100644 --- a/client/app/scripts/charts/nodes-grid.js +++ b/client/app/scripts/charts/nodes-grid.js @@ -2,21 +2,10 @@ import React from 'react'; import { Set as makeSet, List as makeList, Map as makeMap } from 'immutable'; -import NodesChart from './nodes-chart'; import NodeDetailsTable from '../components/node-details/node-details-table'; import { enterNode, leaveNode } from '../actions/app-actions'; -function MiniChart(props) { - const {width, height} = props; - return ( -
- -
- ); -} - - const IGNORED_COLUMNS = ['docker_container_ports']; @@ -43,17 +32,7 @@ export default class NodesGrid extends React.Component { } render() { - const {margins, nodes, height, nodeSize} = this.props; - const rowStyle = { height: nodeSize }; - const tableHeight = nodes.size * rowStyle.height; - const graphProps = Object.assign({}, this.props, { - height: tableHeight, - width: 400, - noZoom: true, - nodeSize: nodeSize - 4, - margins: {top: 0, left: 0, right: 0, bottom: 0}, - nodes: nodes.map(node => node.remove('label').remove('label_minor')) - }); + const { margins, nodes, height } = this.props; const cmpStyle = { height, paddingTop: margins.top, @@ -77,9 +56,7 @@ export default class NodesGrid extends React.Component { onMouseOverRow={this.onMouseOverRow} {...detailsData} highlightedNodeIds={this.props.highlightedNodeIds} - limit={1000}> - - + limit={1000} /> ); } diff --git a/client/app/scripts/charts/nodes-layout.js b/client/app/scripts/charts/nodes-layout.js index 2a9aaff72..0c0392466 100644 --- a/client/app/scripts/charts/nodes-layout.js +++ b/client/app/scripts/charts/nodes-layout.js @@ -51,8 +51,8 @@ function runLayoutEngine(graph, imNodes, imEdges, opts) { graph.setGraph({ nodesep, ranksep, - rankdir: 'LR', - align: 'UL' + // rankdir: 'LR', + // align: 'UL' }); // add nodes to the graph if not already there @@ -182,16 +182,14 @@ function layoutSingleNodes(layout, opts) { const rows = Math.ceil(singleNodes.size / columns); let row = 0; let col = 0; - let singleX; - let singleY; nodes = nodes.sortBy(node => node.get('rank')).map(node => { if (singleNodes.has(node.get('id'))) { if (col === columns) { col = 0; row++; } - singleX = col * (nodesep + nodeWidth) + offsetX; - singleY = row * (ranksep + nodeHeight) + offsetY; + const singleX = col * (nodesep + nodeWidth) + offsetX; + const singleY = row * (ranksep + nodeHeight) + offsetY; col++; return node.merge({ x: singleX, @@ -201,8 +199,6 @@ function layoutSingleNodes(layout, opts) { return node; }); - console.log(singleX, singleY); - // adjust layout dimensions if graph is now bigger result.width = Math.max(layout.width, columns * nodeWidth + (columns - 1) * nodesep); result.height = Math.max(layout.height, rows * nodeHeight + (rows - 1) * ranksep); @@ -250,6 +246,7 @@ function shiftLayoutToCenter(layout, opts) { return result; } + /** * Adds `points` array to edge based on location of source and target * @param {Map} edge new edge @@ -266,7 +263,7 @@ function setSimpleEdgePoints(edge, nodeCache) { } -function uniqueRowConstraint(layout, options) { +export function uniqueRowConstraint(layout, options) { const result = Object.assign({}, layout); const scale = options.scale || DEFAULT_SCALE; const nodeHeight = scale(NODE_SIZE_FACTOR); @@ -285,7 +282,6 @@ function uniqueRowConstraint(layout, options) { .range([nodeWidth, options.width - nodeWidth]) .clamp(false); - console.log('uniqueRowConstraint', options.height); result.nodes = layout.nodes.map(node => node.merge({ x: xScale(node.get('x')), y: nodeOrder.get(node.get('id')) * rowHeight + nodeHeight * 0.5 + margins.top + 2 @@ -395,7 +391,8 @@ export function doLayout(immNodes, immEdges, opts) { let layout; ++layoutRuns; - if (false && !options.forceRelayout && cachedLayout && nodeCache && edgeCache + // if (false && !options.forceRelayout && cachedLayout && nodeCache && edgeCache + if (!options.forceRelayout && cachedLayout && nodeCache && edgeCache && !hasUnseenNodes(immNodes, nodeCache)) { log('skip layout, trivial adjustment', ++layoutRunsTrivial, layoutRuns); layout = cloneLayout(cachedLayout, immNodes, immEdges); @@ -410,7 +407,7 @@ export function doLayout(immNodes, immEdges, opts) { } layout = layoutSingleNodes(layout, opts); layout = shiftLayoutToCenter(layout, opts); - layout = uniqueRowConstraint(layout, opts); + // layout = uniqueRowConstraint(layout, opts); } // cache results diff --git a/client/app/scripts/components/app.js b/client/app/scripts/components/app.js index 29f77267e..0d3d01306 100644 --- a/client/app/scripts/components/app.js +++ b/client/app/scripts/components/app.js @@ -15,6 +15,7 @@ import { focusSearch, pinNextMetric, hitBackspace, hitEnter, hitEsc, unpinMetric selectMetric, toggleHelp } from '../actions/app-actions'; import Details from './details'; import Nodes from './nodes'; +import GridModeSelector from './grid-mode-selector'; import MetricSelector from './metric-selector'; import NetworkSelector from './networks-selector'; import EmbeddedTerminal from './embedded-terminal'; @@ -127,6 +128,7 @@ class App extends React.Component { + {showingMetricsSelector && } {showingNetworkSelector && } diff --git a/client/app/scripts/components/debug-toolbar.js b/client/app/scripts/components/debug-toolbar.js index ae61fff59..8d2a4e703 100644 --- a/client/app/scripts/components/debug-toolbar.js +++ b/client/app/scripts/components/debug-toolbar.js @@ -184,7 +184,7 @@ class DebugToolbar extends React.Component { addNodes(n, prefix = 'zing') { const ns = this.props.nodes; const nodeNames = ns.keySeq().toJS(); - const newNodeNames = _.range(ns.size, ns.size + n).map(i => ( + const newNodeNames = _.range(nodeNames.length, nodeNames.length + n).map(i => ( // `${randomLetter()}${randomLetter()}-zing` `${prefix}${i}` )); diff --git a/client/app/scripts/components/node-details/node-details-table.js b/client/app/scripts/components/node-details/node-details-table.js index 61c4a923f..74170199f 100644 --- a/client/app/scripts/components/node-details/node-details-table.js +++ b/client/app/scripts/components/node-details/node-details-table.js @@ -4,7 +4,6 @@ import { Map as makeMap } from 'immutable'; import ShowMore from '../show-more'; import NodeDetailsTableRow from './node-details-table-row'; -import { sortOrderChanged } from '../../actions/app-actions'; function isNumberField(field) { @@ -95,7 +94,6 @@ export default class NodeDetailsTable extends React.Component { ? !this.state.sortedDesc : this.state.sortedDesc; const sortBy = headerId; this.setState({sortBy, sortedDesc}); - sortOrderChanged({sortBy, sortedDesc}); } handleLimitClick() { @@ -185,8 +183,6 @@ export default class NodeDetailsTable extends React.Component { React.cloneElement(child, { nodeOrder }) )); - console.log(this.props.selectedRowId); - return (
@@ -198,7 +194,8 @@ export default class NodeDetailsTable extends React.Component { {nodes && nodes.map(node => ( @@ -82,15 +80,18 @@ class Nodes extends React.Component { show={topologiesLoaded && !nodesLoaded} /> {this.renderEmptyTopologyError(topologiesLoaded && nodesLoaded && topologyEmpty)} - + {this.props.gridMode ? + : + }
); } @@ -109,13 +110,14 @@ class Nodes extends React.Component { function mapStateToProps(state) { return { + gridMode: state.get('gridMode'), nodes: state.get('nodes'), nodesLoaded: state.get('nodesLoaded'), - selectedNodeId: state.get('selectedNodeId'), topologies: state.get('topologies'), topologiesLoaded: state.get('topologiesLoaded'), topologyEmpty: isTopologyEmpty(state), topology: state.get('currentTopology'), + highlightedNodeIds: state.get('highlightedNodeIds') }; } diff --git a/client/app/scripts/constants/action-types.js b/client/app/scripts/constants/action-types.js index 9245d42eb..4e9ab8c17 100644 --- a/client/app/scripts/constants/action-types.js +++ b/client/app/scripts/constants/action-types.js @@ -55,7 +55,8 @@ const ACTION_TYPES = [ 'UNPIN_NETWORK', 'SHOW_NETWORKS', 'SET_RECEIVED_NODES_DELTA', - 'SORT_ORDER_CHANGED' + 'SORT_ORDER_CHANGED', + 'SET_GRID_MODE', ]; export default _.zipObject(ACTION_TYPES, ACTION_TYPES); diff --git a/client/app/scripts/reducers/root.js b/client/app/scripts/reducers/root.js index 893247774..e2ad25ea0 100644 --- a/client/app/scripts/reducers/root.js +++ b/client/app/scripts/reducers/root.js @@ -28,6 +28,7 @@ export const initialState = makeMap({ currentTopologyId: 'containers', errorUrl: null, forceRelayout: false, + gridMode: false, highlightedEdgeIds: makeSet(), highlightedNodeIds: makeSet(), hostname: '...', @@ -166,6 +167,10 @@ export function rootReducer(state = initialState, action) { return state.set('exportingGraph', action.exporting); } + case ActionTypes.SET_GRID_MODE: { + return state.setIn(['gridMode'], action.enabled); + } + case ActionTypes.CLEAR_CONTROL_ERROR: { return state.removeIn(['controlStatus', action.nodeId, 'error']); } @@ -625,6 +630,7 @@ export function rootReducer(state = initialState, action) { selectedNodeId: action.state.selectedNodeId, pinnedMetricType: action.state.pinnedMetricType }); + state = state.set('gridMode', action.state.mode === 'grid'); if (action.state.showingNetworks) { state = state.set('showingNetworks', action.state.showingNetworks); } diff --git a/client/app/scripts/utils/router-utils.js b/client/app/scripts/utils/router-utils.js index 0aba5a157..7ed77ee20 100644 --- a/client/app/scripts/utils/router-utils.js +++ b/client/app/scripts/utils/router-utils.js @@ -39,6 +39,7 @@ export function getUrlState(state) { const urlState = { controlPipe: cp ? cp.toJS() : null, + mode: state.get('gridMode') ? 'grid' : 'topo', nodeDetails: nodeDetails.toJS(), pinnedMetricType: state.get('pinnedMetricType'), pinnedSearches: state.get('pinnedSearches').toJS(), diff --git a/client/app/styles/main.less b/client/app/styles/main.less index 8c8393a0a..f2a963f1d 100644 --- a/client/app/styles/main.less +++ b/client/app/styles/main.less @@ -269,10 +269,11 @@ h2 { cursor: pointer; padding: 4px 8px; border-radius: @border-radius; - opacity: 0.8; + opacity: 0.9; margin-bottom: 3px; border: 1px solid transparent; + background-color: #f7f7fa; &-active, &:hover { color: @text-color; background-color: @background-darker-secondary-color;