mirror of
https://github.com/weaveworks/scope.git
synced 2026-05-05 00:39:04 +00:00
* 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
91 lines
2.8 KiB
JavaScript
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)
|
|
);
|