Files
weave-scope/client/app/scripts/selectors/graph-view/zoom.js
Filip Barl 69fd397217 Initial version of the resource view (#2296)
* Added resource view selector button

* Showing resource boxes in the resource view

* Crude CPU resource view prototype

* Improved the viewMode state logic

* Extracted zooming into a separate wrapper component

* Split the layout selectors between graph-view and resource-view

* Proper zooming logic for the resource view

* Moved all node networks utils to selectors

* Improved the zoom caching logic

* Further refactoring of selectors

* Added sticky labels to the resource boxes

* Added panning translation limits in the resource view

* Renamed GridModeSelector -> ViewModeSelector

* Polished the topology resource view selection logic

* Search bar hidden in the resource view

* Added per-layer topology names to the resource view

* Made metric selectors work for the resource view

* Adjusted the viewport selectors

* Renamed viewport selector to canvas (+ maximal zoom fix)

* Showing more useful metric info in the resource box labels

* Fetching only necessary nodes for the resource view

* Refactored the resource view layer component

* Addressed first batch UI comments (from the Scope meeting)

* Switch to deep zooming transform in the resource view to avoid SVG precision errors

* Renamed and moved resource view components

* Polished all the resource view components

* Changing the available metrics selection

* Improved and polished the state transition logic for the resource view

* Separated zoom limits from the zoom active state

* Renaming and bunch of comments

* Addressed all the UI comments (@davkal + @fons)

* Made graph view selectors independent from resource view selectors
2017-03-24 14:51:53 +01:00

91 lines
2.8 KiB
JavaScript

import { createSelector } from 'reselect';
import { Map as makeMap } from 'immutable';
import { NODE_BASE_SIZE } from '../../constants/styles';
import { canvasMarginsSelector, canvasWidthSelector, canvasHeightSelector } from '../canvas';
import { activeLayoutCachedZoomSelector } from '../zooming';
import { graphNodesSelector } from './graph';
const graphBoundingRectangleSelector = createSelector(
[
graphNodesSelector,
],
(graphNodes) => {
if (graphNodes.size === 0) return null;
const xMin = graphNodes.map(n => n.get('x') - NODE_BASE_SIZE).min();
const yMin = graphNodes.map(n => n.get('y') - NODE_BASE_SIZE).min();
const xMax = graphNodes.map(n => n.get('x') + NODE_BASE_SIZE).max();
const yMax = graphNodes.map(n => n.get('y') + NODE_BASE_SIZE).max();
return makeMap({ xMin, yMin, xMax, yMax });
}
);
// Max scale limit will always be such that a node covers 1/5 of the viewport.
const maxScaleSelector = createSelector(
[
canvasWidthSelector,
canvasHeightSelector,
],
(width, height) => Math.min(width, height) / NODE_BASE_SIZE / 5
);
// Compute the default zoom settings for the given graph.
export const graphDefaultZoomSelector = createSelector(
[
graphBoundingRectangleSelector,
canvasMarginsSelector,
canvasWidthSelector,
canvasHeightSelector,
maxScaleSelector,
],
(boundingRectangle, canvasMargins, width, height, maxScale) => {
if (!boundingRectangle) return makeMap();
const { xMin, xMax, yMin, yMax } = boundingRectangle.toJS();
const xFactor = width / (xMax - xMin);
const yFactor = height / (yMax - yMin);
// Initial zoom is such that the graph covers 90% of either the viewport,
// or one half of maximal zoom constraint, whichever is smaller.
const scale = Math.min(xFactor, yFactor, maxScale / 2) * 0.9;
// This translation puts the graph in the center of the viewport, respecting the margins.
const translateX = ((width - ((xMax + xMin) * scale)) / 2) + canvasMargins.left;
const translateY = ((height - ((yMax + yMin) * scale)) / 2) + canvasMargins.top;
return makeMap({
translateX,
translateY,
scaleX: scale,
scaleY: scale,
});
}
);
export const graphZoomLimitsSelector = createSelector(
[
graphDefaultZoomSelector,
maxScaleSelector,
],
(defaultZoom, maxScale) => {
if (defaultZoom.isEmpty()) return makeMap();
// We always allow zooming out exactly 5x compared to the initial zoom.
const minScale = defaultZoom.get('scaleX') / 5;
return makeMap({ minScale, maxScale });
}
);
export const graphZoomStateSelector = createSelector(
[
graphDefaultZoomSelector,
activeLayoutCachedZoomSelector,
],
// All the cached fields override the calculated default ones.
(graphDefaultZoom, cachedZoomState) => graphDefaultZoom.merge(cachedZoomState)
);