Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial version of the resource view #2296

Merged
merged 32 commits into from
Mar 24, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
08f9691
Added resource view selector button
fbarl Mar 2, 2017
7a049c1
Showing resource boxes in the resource view
fbarl Mar 3, 2017
f0e7007
Crude CPU resource view prototype
fbarl Mar 3, 2017
688c0f4
Improved the viewMode state logic
fbarl Mar 3, 2017
e52b123
Extracted zooming into a separate wrapper component
fbarl Mar 3, 2017
1e4dd6d
Split the layout selectors between graph-view and resource-view
fbarl Mar 6, 2017
a11e3a1
Proper zooming logic for the resource view
fbarl Mar 6, 2017
4d36806
Moved all node networks utils to selectors
fbarl Mar 7, 2017
b546acf
Improved the zoom caching logic
fbarl Mar 8, 2017
af0881d
Further refactoring of selectors
fbarl Mar 10, 2017
de3d99f
Added sticky labels to the resource boxes
fbarl Mar 10, 2017
ce1282c
Added panning translation limits in the resource view
fbarl Mar 10, 2017
e05302e
Renamed GridModeSelector -> ViewModeSelector
fbarl Mar 10, 2017
c225993
Polished the topology resource view selection logic
fbarl Mar 10, 2017
04bfca2
Search bar hidden in the resource view
fbarl Mar 10, 2017
7cdfcf7
Added per-layer topology names to the resource view
fbarl Mar 11, 2017
8ac6d8a
Made metric selectors work for the resource view
fbarl Mar 11, 2017
bfd3271
Adjusted the viewport selectors
fbarl Mar 12, 2017
a4a97e4
Renamed viewport selector to canvas (+ maximal zoom fix)
fbarl Mar 12, 2017
feb461c
Showing more useful metric info in the resource box labels
fbarl Mar 14, 2017
c273da2
Fetching only necessary nodes for the resource view
fbarl Mar 15, 2017
a57f043
Refactored the resource view layer component
fbarl Mar 15, 2017
b3eb612
Addressed first batch UI comments (from the Scope meeting)
fbarl Mar 16, 2017
f8348fc
Switch to deep zooming transform in the resource view to avoid SVG pr…
fbarl Mar 17, 2017
287d379
Renamed and moved resource view components
fbarl Mar 17, 2017
a52c979
Polished all the resource view components
fbarl Mar 17, 2017
a8d8e0e
Changing the available metrics selection
fbarl Mar 20, 2017
471251a
Improved and polished the state transition logic for the resource view
fbarl Mar 20, 2017
2373b71
Separated zoom limits from the zoom active state
fbarl Mar 21, 2017
8fec8a3
Renaming and bunch of comments
fbarl Mar 21, 2017
3dc4e9d
Addressed all the UI comments (@davkal + @fons)
fbarl Mar 22, 2017
ca3f74f
Made graph view selectors independent from resource view selectors
fbarl Mar 24, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Polished all the resource view components
  • Loading branch information
fbarl committed Mar 24, 2017
commit a52c979a7789c36a132d8a6341760edd79431bea
42 changes: 22 additions & 20 deletions client/app/scripts/actions/app-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,22 +351,33 @@ export function clickResumeUpdate() {
};
}

function updateTopology(dispatch, getState) {
const state = getState();
updateRoute(getState);
// update all request workers with new options
resetUpdateBuffer();
// NOTE: This is currently not needed for our static resource
// view,but we'll need it here later and it's simpler to just
// keep it than to redo the nodes delta updating logic.
getNodesDelta(
getCurrentTopologyUrl(state),
activeTopologyOptionsSelector(state),
dispatch
);
// Update the nodes for all topologies that appear in the current resource view.
if (isResourceViewModeSelector(state)) {
getResourceViewNodesSnapshot(getState, dispatch);
}
}

export function clickShowTopologyForNode(topologyId, nodeId) {
return (dispatch, getState) => {
dispatch({
type: ActionTypes.CLICK_SHOW_TOPOLOGY_FOR_NODE,
topologyId,
nodeId
});
updateRoute(getState);
// update all request workers with new options
resetUpdateBuffer();
const state = getState();
getNodesDelta(
getCurrentTopologyUrl(state),
activeTopologyOptionsSelector(state),
dispatch
);
updateTopology(dispatch, getState);
};
}

Expand All @@ -376,15 +387,7 @@ export function clickTopology(topologyId) {
type: ActionTypes.CLICK_TOPOLOGY,
topologyId
});
updateRoute(getState);
// update all request workers with new options
resetUpdateBuffer();
const state = getState();
getNodesDelta(
getCurrentTopologyUrl(state),
activeTopologyOptionsSelector(state),
dispatch
);
updateTopology(dispatch, getState);
};
}

Expand Down Expand Up @@ -732,8 +735,7 @@ export function route(urlState) {
// nodes for the current topology, but also the nodes of all the topologies that make
// the layers in the resource view.
if (isResourceViewModeSelector(state)) {
// Get all the nodes for the current resource view layout in the next run-cycle.
setTimeout(() => { getResourceViewNodesSnapshot(getState, dispatch); }, 0);
getResourceViewNodesSnapshot(getState, dispatch);
}
};
}
Expand Down
1 change: 0 additions & 1 deletion client/app/scripts/charts/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ class Node extends React.Component {
exportingGraph, showingNetworks, stack, id, metric } = this.props;
const { hovered } = this.state;

// console.log(metric && metric.toJS());
const color = getNodeColor(rank, label, pseudo);
const truncate = !focused && !hovered;
const labelOffsetY = (showingNetworks && networks) ? 40 : 28;
Expand Down
59 changes: 30 additions & 29 deletions client/app/scripts/charts/nodes-chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,53 @@ import CachableZoomWrapper from '../components/cachable-zoom-wrapper';
import { clickBackground } from '../actions/app-actions';


const EdgeMarkerDefinition = ({ selectedNodeId }) => {
const markerOffset = selectedNodeId ? '35' : '40';
const markerSize = selectedNodeId ? '10' : '30';
return (
<defs>
<marker
className="edge-marker"
id="end-arrow"
viewBox="1 0 10 10"
refX={markerOffset}
refY="3.5"
markerWidth={markerSize}
markerHeight={markerSize}
orient="auto">
<polygon className="link" points="0 0, 10 3.5, 0 7" />
</marker>
</defs>
);
};

class NodesChart extends React.Component {
constructor(props, context) {
super(props, context);

this.handleMouseClick = this.handleMouseClick.bind(this);
}

render() {
// TODO: What to do with empty?
const { isEmpty, selectedNodeId } = this.props;
const markerOffset = selectedNodeId ? '35' : '40';
const markerSize = selectedNodeId ? '10' : '30';
const svgClassNames = isEmpty ? 'hide' : '';
handleMouseClick() {
if (this.props.selectedNodeId) {
this.props.clickBackground();
}
}

render() {
const { selectedNodeId } = this.props;
return (
<div className="nodes-chart">
<svg
width="100%" height="100%" id="nodes-chart-canvas"
className={svgClassNames} onClick={this.handleMouseClick}>
<defs>
<marker
className="edge-marker"
id="end-arrow"
viewBox="1 0 10 10"
refX={markerOffset}
refY="3.5"
markerWidth={markerSize}
markerHeight={markerSize}
orient="auto">
<polygon className="link" points="0 0, 10 3.5, 0 7" />
</marker>
</defs>
<svg id="canvas" width="100%" height="100%" onClick={this.handleMouseClick}>
<Logo transform="translate(24,24) scale(0.25)" />
<CachableZoomWrapper disabled={selectedNodeId}>
<EdgeMarkerDefinition selectedNodeId={selectedNodeId} />
<CachableZoomWrapper svg="canvas" disabled={selectedNodeId}>
<NodesChartElements />
</CachableZoomWrapper>
</svg>
</div>
);
}

handleMouseClick() {
if (this.props.selectedNodeId) {
this.props.clickBackground();
}
}
}


Expand Down
1 change: 1 addition & 0 deletions client/app/scripts/charts/nodes-grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class NodesGrid extends React.Component {
paddingLeft: canvasMargins.left,
paddingRight: canvasMargins.right,
};
// TODO: What are 24 and 18? Use a comment or extract into constants.
const tbodyHeight = height - 24 - 18;
const className = 'scroll-body';
const tbodyStyle = {
Expand Down
1 change: 0 additions & 1 deletion client/app/scripts/components/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ class App extends React.Component {
showingMetricsSelector, showingNetworkSelector, showingTroubleshootingMenu } = this.props;
const isIframe = window !== window.top;

// TODO: Remove 'grid', 'topo' constants.
return (
<div className="scope-app">
{showingDebugToolbar() && <DebugToolbar />}
Expand Down
31 changes: 23 additions & 8 deletions client/app/scripts/components/cachable-zoom-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { event as d3Event, select } from 'd3-selection';
import { zoom, zoomIdentity } from 'd3-zoom';

import { cacheZoomState } from '../actions/app-actions';
import { transformToString } from '../utils/transform-utils';
import { activeLayoutZoomSelector } from '../selectors/zooming';
import { activeTopologyZoomCacheKeyPathSelector } from '../selectors/topology';
import {
Expand Down Expand Up @@ -42,8 +43,7 @@ class CachableZoomWrapper extends React.Component {
componentDidMount() {
this.zoomRestored = false;
this.zoom = zoom().on('zoom', this.zoomed);
// TODO: Make this correct
this.svg = select('.nodes-chart svg');
this.svg = select(`svg#${this.props.svg}`);

this.setZoomTriggers(!this.props.disabled);
this.restoreCachedZoom(this.props);
Expand Down Expand Up @@ -77,13 +77,15 @@ class CachableZoomWrapper extends React.Component {
}

render() {
// `forwardTransform` says whether the zoom transform is forwarded to the child
// component. The advantage of that is more control rendering control in the
// children, while the disadvantage is that it's slower, as all the children
// get updated on every zoom/pan action.
const { children, forwardTransform } = this.props;
const { translateX, translateY, scaleX, scaleY } = this.state;
const transform = `translate(${translateX},${translateY}) scale(${scaleX},${scaleY})`;
const transform = forwardTransform ? '' : transformToString(this.state);

// Not passing transform into child components by default for perf reasons.
return (
<g className="zoom-container" transform={forwardTransform ? '' : transform}>
<g className="cachable-zoom-wrapper" transform={transform}>
{forwardTransform ? children(this.state) : children}
</g>
);
Expand All @@ -97,7 +99,12 @@ class CachableZoomWrapper extends React.Component {
}
}

// Decides which part of the zoom state is cachable depending
// on the horizontal/vertical degrees of freedom.
cachableState(state = this.state) {
// TODO: Probably shouldn't cache the limits if the layout can
// change a lot. However, before removing them from here, we have
// to make sure we can always get them from the default zooms.
let cachableFields = [
'minTranslateX', 'maxTranslateX',
'minTranslateY', 'maxTranslateY',
Expand All @@ -116,30 +123,38 @@ class CachableZoomWrapper extends React.Component {
this.props.cacheZoomState(fromJS(this.cachableState()));
}

// Restore the zooming settings
restoreCachedZoom(props) {
if (!props.layoutZoom.isEmpty()) {
const zoomState = props.layoutZoom.toJS();

// Restore the zooming settings
// Scaling limits are always set.
this.zoom = this.zoom.scaleExtent([zoomState.minScale, zoomState.maxScale]);

// Translation limits are optional.
if (props.bounded) {
this.zoom = this.zoom
// Translation limits are only set if explicitly demanded (currently we are using them
// in the resource view, but not in the graph view, although I think the idea would be
// to use them everywhere).
.translateExtent([
[zoomState.minTranslateX, zoomState.minTranslateY],
[zoomState.maxTranslateX, zoomState.maxTranslateY],
])
// This is to ensure that the translation limits are properly
// centered, so that the canvas margins are respected.
.extent([
[props.canvasMargins.left, props.canvasMargins.top],
[props.canvasMargins.left + props.width, props.canvasMargins.top + props.height]
]);
}

// After the limits have been set, update the zoom.
this.svg.call(this.zoom.transform, zoomIdentity
.translate(zoomState.translateX, zoomState.translateY)
.scale(zoomState.scaleX, zoomState.scaleY));

// Update the state variables
// Update the state variables.
this.setState(zoomState);
this.zoomRestored = true;
}
Expand Down
4 changes: 2 additions & 2 deletions client/app/scripts/components/help-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,10 @@ function renderFieldsPanel(currentTopologyName, searchableFields) {
}


function HelpPanel({currentTopologyName, searchableFields, onClickClose}) {
function HelpPanel({ currentTopologyName, searchableFields, onClickClose, canvasMargins }) {
return (
<div className="help-panel-wrapper">
<div className="help-panel" style={{marginTop: this.props.canvasMargins.top}}>
<div className="help-panel" style={{marginTop: canvasMargins.top}}>
<div className="help-panel-header">
<h2>Help</h2>
</div>
Expand Down
Loading