Skip to content

Commit

Permalink
Renaming and bunch of comments
Browse files Browse the repository at this point in the history
  • Loading branch information
fbarl committed Mar 22, 2017
1 parent fdde690 commit 30ae2a3
Show file tree
Hide file tree
Showing 17 changed files with 285 additions and 217 deletions.
2 changes: 1 addition & 1 deletion client/app/scripts/components/nodes-resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React from 'react';
import { connect } from 'react-redux';

import Logo from './logo';
import { layersTopologyIdsSelector } from '../selectors/resource-view/layers';
import ZoomWrapper from './zoom-wrapper';
import NodesResourcesLayer from './nodes-resources/node-resources-layer';
import { layersTopologyIdsSelector } from '../selectors/resource-view/layout';


class NodesResources extends React.Component {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,24 @@ import { Map as makeMap } from 'immutable';
import NodeResourcesMetricBox from './node-resources-metric-box';
import NodeResourcesLayerTopology from './node-resources-layer-topology';
import {
layersVerticalPositionSelector,
positionedNodesByTopologySelector,
} from '../../selectors/resource-view/layers';
layerVerticalPositionByTopologyIdSelector,
layoutNodesByTopologyIdSelector,
} from '../../selectors/resource-view/layout';


class NodesResourcesLayer extends React.Component {
render() {
const { layerVerticalPosition, topologyId, transform, nodes } = this.props;
const { layerVerticalPosition, topologyId, transform, layoutNodes } = this.props;

return (
<g className="node-resources-layer">
<g className="node-resources-metric-boxes">
{nodes.toIndexedSeq().map(node => (
{layoutNodes.toIndexedSeq().map(node => (
<NodeResourcesMetricBox
key={node.get('id')}
color={node.get('color')}
label={node.get('label')}
withCapacity={node.get('withCapacity')}
activeMetric={node.get('activeMetric')}
metricSummary={node.get('metricSummary')}
width={node.get('width')}
height={node.get('height')}
x={node.get('offset')}
Expand All @@ -32,7 +31,7 @@ class NodesResourcesLayer extends React.Component {
/>
))}
</g>
{!nodes.isEmpty() && <NodeResourcesLayerTopology
{!layoutNodes.isEmpty() && <NodeResourcesLayerTopology
verticalPosition={layerVerticalPosition}
transform={transform}
topologyId={topologyId}
Expand All @@ -44,8 +43,8 @@ class NodesResourcesLayer extends React.Component {

function mapStateToProps(state, props) {
return {
layerVerticalPosition: layersVerticalPositionSelector(state).get(props.topologyId),
nodes: positionedNodesByTopologySelector(state).get(props.topologyId, makeMap()),
layerVerticalPosition: layerVerticalPositionByTopologyIdSelector(state).get(props.topologyId),
layoutNodes: layoutNodesByTopologyIdSelector(state).get(props.topologyId, makeMap()),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { formatMetricSvg } from '../../utils/string-utils';

export default class NodeResourcesMetricBoxInfo extends React.Component {
humanizedMetricInfo() {
const metric = this.props.activeMetric.toJS();
const showExtendedInfo = metric.withCapacity && metric.format !== 'percent';
const totalCapacity = formatMetricSvg(metric.totalCapacity, metric);
const absoluteConsumption = formatMetricSvg(metric.absoluteConsumption, metric);
const relativeConsumption = formatMetricSvg(100.0 * metric.relativeConsumption,
const metricSummary = this.props.metricSummary.toJS();
const showExtendedInfo = metricSummary.showCapacity && metricSummary.format !== 'percent';
const totalCapacity = formatMetricSvg(metricSummary.totalCapacity, metricSummary);
const absoluteConsumption = formatMetricSvg(metricSummary.absoluteConsumption, metricSummary);
const relativeConsumption = formatMetricSvg(100.0 * metricSummary.relativeConsumption,
{ format: 'percent' });

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,25 +69,24 @@ class NodeResourcesMetricBox extends React.Component {
}

render() {
const { label, color, withCapacity, activeMetric } = this.props;
const { relativeConsumption, info } = activeMetric.toJS();
const { x, y, width } = this.state;
const { label, color, metricSummary } = this.props;
const { showCapacity, relativeConsumption } = metricSummary.toJS();

const showInfo = width >= RESOURCES_LABEL_MIN_SIZE;
const showNode = width >= 1; // px
const showNode = width >= 1; // hide the thin nodes

// Don't display the nodes which are less than 1px wide.
// TODO: Show `+ 31 nodes` kind of tag in their stead.
if (!showNode) return null;

return (
<g className="node-resources-metric-box">
<title>{info}</title>
{withCapacity && <rect className="frame" {...this.defaultRectProps()} />}
{showCapacity && <rect className="frame" {...this.defaultRectProps()} />}
<rect className="bar" fill={color} {...this.defaultRectProps(relativeConsumption)} />
{showInfo && <NodeResourcesMetricBoxInfo
label={label}
activeMetric={activeMetric}
metricSummary={metricSummary}
width={width - (2 * RESOURCES_LABEL_PADDING)}
x={x + RESOURCES_LABEL_PADDING}
y={y + RESOURCES_LABEL_PADDING}
Expand Down
2 changes: 1 addition & 1 deletion client/app/scripts/components/view-mode-selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import classNames from 'classnames';

import MetricSelector from './metric-selector';
import { setGraphView, setTableView, setResourceView } from '../actions/app-actions';
import { layersTopologyIdsSelector } from '../selectors/resource-view/layers';
import { layersTopologyIdsSelector } from '../selectors/resource-view/layout';
import {
isGraphViewModeSelector,
isTableViewModeSelector,
Expand Down
8 changes: 6 additions & 2 deletions client/app/scripts/constants/resources.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@

// Cap the number of layers in the resource view to this constant. The reason why we have
// this constant is not just about the style, but also helps us build the selectors.
export const RESOURCE_VIEW_MAX_LAYERS = 3;

// TODO: Consider fetching these from the backend.
export const topologiesWithCapacity = ['hosts'];
export const resourceViewLayers = {
export const TOPOLOGIES_WITH_CAPACITY = ['hosts'];
export const RESOURCE_VIEW_LAYERS = {
hosts: ['hosts', 'containers', 'processes'],
containers: ['containers', 'processes'],
processes: ['processes'],
Expand Down
13 changes: 0 additions & 13 deletions client/app/scripts/constants/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,3 @@ export const NODE_DETAILS_TABLE_XS_LABEL = {
// TODO: consider changing the name of this field on the BE
container: '#',
};


export const layersDefs = {
hosts: {
withCapacity: true,
},
containers: {
withCapacity: false,
},
processes: {
withCapacity: false,
},
};
61 changes: 34 additions & 27 deletions client/app/scripts/decorators/node.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Map as makeMap } from 'immutable';

import { getNodeColor } from '../utils/color-utils';
import { getMetricValue } from '../utils/metric-utils';
import { RESOURCES_LAYER_HEIGHT } from '../constants/styles';


Expand All @@ -11,37 +10,45 @@ export function nodeResourceViewColorDecorator(node) {
return node.set('color', getNodeColor(node.get('rank'), '', node.get('pseudo')));
}

export function nodeActiveMetricDecorator(node) {
const metricType = node.get('activeMetricType');
const metric = node.get('metrics', makeMap()).find(m => m.get('label') === metricType);
if (!metric) return node;

const { formattedValue } = getMetricValue(metric);
const info = `${metricType} - ${formattedValue}`;
const absoluteConsumption = metric.get('value');
const withCapacity = node.get('withCapacity');
const totalCapacity = withCapacity ? metric.get('max') : absoluteConsumption;
const relativeConsumption = absoluteConsumption / totalCapacity;
const format = metric.get('format');

return node.set('activeMetric', makeMap({
totalCapacity, absoluteConsumption, relativeConsumption, withCapacity, info, format
}));
}

// Decorates the resource node with dimensions taken from its metric summary.
export function nodeResourceBoxDecorator(node) {
const widthCriterion = node.get('withCapacity') ? 'totalCapacity' : 'absoluteConsumption';
const width = node.getIn(['activeMetric', widthCriterion]);
const metricSummary = node.get('metricSummary', makeMap());
const width = metricSummary.get('showCapacity') ?
metricSummary.get('totalCapacity') :
metricSummary.get('absoluteConsumption');
const height = RESOURCES_LAYER_HEIGHT;

return node.merge(makeMap({ width, height }));
}

export function nodeParentNodeDecorator(node) {
const parentTopologyId = node.get('directParentTopologyId');
const parents = node.get('parents', makeMap());
const parent = parents.find(p => p.get('topologyId') === parentTopologyId);
if (!parent) return node;
// Decorates the node with the summary info of its metric of a fixed type.
export function nodeMetricSummaryDecoratorByType(metricType, showCapacity) {
return (node) => {
const metric = node
.get('metrics', makeMap())
.find(m => m.get('label') === metricType);

// Do nothing if there is no metric info.
if (!metric) return node;

const absoluteConsumption = metric.get('value');
const totalCapacity = showCapacity ? metric.get('max') : absoluteConsumption;
const relativeConsumption = absoluteConsumption / totalCapacity;
const format = metric.get('format');

return node.set('metricSummary', makeMap({
showCapacity, totalCapacity, absoluteConsumption, relativeConsumption, format
}));
};
}

// Decorates the node with the ID of the parent node belonging to a fixed topology.
export function nodeParentDecoratorByTopologyId(topologyId) {
return (node) => {
const parent = node
.get('parents', makeMap())
.find(p => p.get('topologyId') === topologyId);

return node.set('parentNodeId', parent.get('id'));
return parent ? node.set('parentNodeId', parent.get('id')) : node;
};
}
2 changes: 1 addition & 1 deletion client/app/scripts/selectors/graph-view/default-zoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const graphZoomLimitsSelector = createSelector(
maxScaleSelector,
],
(defaultZoom, maxScale) => {
if (defaultZoom.isEmpty()) return makeMap({ minScale: 1, maxScale: 1 });
if (defaultZoom.isEmpty()) return makeMap();

// We always allow zooming out exactly 5x compared to the initial zoom.
const minScale = defaultZoom.get('scaleX') / 5;
Expand Down
41 changes: 24 additions & 17 deletions client/app/scripts/selectors/resource-view/default-zoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,29 @@ import { Map as makeMap } from 'immutable';

import { RESOURCES_LAYER_HEIGHT } from '../../constants/styles';
import { canvasMarginsSelector, canvasWidthSelector, canvasHeightSelector } from '../canvas';
import { layersVerticalPositionSelector, positionedNodesByTopologySelector } from './layers';
import {
layerVerticalPositionByTopologyIdSelector,
layoutNodesByTopologyIdSelector,
} from './layout';


const resourcesBoundingRectangleSelector = createSelector(
// This is used to determine the maximal zoom factor.
const minNodeWidthSelector = createSelector(
[
layoutNodesByTopologyIdSelector,
],
layoutNodes => layoutNodes.flatten(true).map(n => n.get('width')).min()
);

const resourceNodesBoundingRectangleSelector = createSelector(
[
layersVerticalPositionSelector,
positionedNodesByTopologySelector,
layerVerticalPositionByTopologyIdSelector,
layoutNodesByTopologyIdSelector,
],
(verticalPositions, nodes) => {
if (nodes.size === 0) return null;
(verticalPositions, layoutNodes) => {
if (layoutNodes.size === 0) return null;

const flattenedNodes = nodes.flatten(true);
const flattenedNodes = layoutNodes.flatten(true);
const xMin = flattenedNodes.map(n => n.get('offset')).min();
const yMin = verticalPositions.toList().min();
const xMax = flattenedNodes.map(n => n.get('offset') + n.get('width')).max();
Expand All @@ -24,10 +35,10 @@ const resourcesBoundingRectangleSelector = createSelector(
}
);

// Compute the default zoom settings for the given chart.
// Compute the default zoom settings for given resources.
export const resourcesDefaultZoomSelector = createSelector(
[
resourcesBoundingRectangleSelector,
resourceNodesBoundingRectangleSelector,
canvasMarginsSelector,
canvasWidthSelector,
canvasHeightSelector,
Expand All @@ -37,6 +48,7 @@ export const resourcesDefaultZoomSelector = createSelector(

const { xMin, xMax, yMin, yMax } = boundingRectangle.toJS();

// The default scale takes all the available horizontal space and 70% of the vertical space.
const scaleX = (width / (xMax - xMin)) * 1.0;
const scaleY = (height / (yMax - yMin)) * 0.7;

Expand All @@ -53,17 +65,10 @@ export const resourcesDefaultZoomSelector = createSelector(
}
);

const minNodeWidthSelector = createSelector(
[
positionedNodesByTopologySelector,
],
nodes => nodes.flatten(true).map(n => n.get('width')).min()
);

export const resourcesZoomLimitsSelector = createSelector(
[
resourcesDefaultZoomSelector,
resourcesBoundingRectangleSelector,
resourceNodesBoundingRectangleSelector,
minNodeWidthSelector,
canvasWidthSelector,
],
Expand All @@ -73,7 +78,9 @@ export const resourcesZoomLimitsSelector = createSelector(
const { xMin, xMax, yMin, yMax } = boundingRectangle.toJS();

return makeMap({
// Maximal zoom is such that the smallest box takes the whole canvas.
maxScale: width / minNodeWidth,
// Minimal zoom is equivalent to the initial one, where the whole layout matches the canvas.
minScale: defaultZoom.get('scaleX'),
minTranslateX: xMin,
maxTranslateX: xMax,
Expand Down
Loading

0 comments on commit 30ae2a3

Please sign in to comment.