mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-03 18:20:27 +00:00
Merge pull request #1773 from weaveworks/1692-scale-node-labels-with-nodes
Scale node labels with the node's size.
This commit is contained in:
@@ -16,6 +16,12 @@ import NodeShapeHex from './node-shape-hex';
|
||||
import NodeShapeHeptagon from './node-shape-heptagon';
|
||||
import NodeShapeCloud from './node-shape-cloud';
|
||||
import NodeNetworksOverlay from './node-networks-overlay';
|
||||
import { MIN_NODE_LABEL_SIZE, BASE_NODE_LABEL_SIZE, BASE_NODE_SIZE } from '../constants/styles';
|
||||
|
||||
|
||||
function labelFontSize(nodeSize) {
|
||||
return Math.max(MIN_NODE_LABEL_SIZE, (BASE_NODE_LABEL_SIZE / BASE_NODE_SIZE) * nodeSize);
|
||||
}
|
||||
|
||||
function stackedShape(Shape) {
|
||||
const factory = React.createFactory(NodeShapeStack);
|
||||
@@ -56,6 +62,7 @@ class Node extends React.Component {
|
||||
this.handleMouseClick = this.handleMouseClick.bind(this);
|
||||
this.handleMouseEnter = this.handleMouseEnter.bind(this);
|
||||
this.handleMouseLeave = this.handleMouseLeave.bind(this);
|
||||
this.saveShapeRef = this.saveShapeRef.bind(this);
|
||||
this.state = {
|
||||
hovered: false,
|
||||
matched: false
|
||||
@@ -77,18 +84,18 @@ class Node extends React.Component {
|
||||
|
||||
render() {
|
||||
const { blurred, focused, highlighted, label, matches = makeMap(), networks,
|
||||
pseudo, rank, subLabel, scaleFactor, transform, zoomScale, exportingGraph,
|
||||
pseudo, rank, subLabel, scaleFactor, transform, exportingGraph,
|
||||
showingNetworks, stack } = this.props;
|
||||
const { hovered, matched } = this.state;
|
||||
const nodeScale = focused ? this.props.selectedNodeScale : this.props.nodeScale;
|
||||
|
||||
const color = getNodeColor(rank, label, pseudo);
|
||||
const truncate = !focused && !hovered;
|
||||
const labelTransform = focused ? `scale(${1 / zoomScale})` : '';
|
||||
const labelWidth = nodeScale(scaleFactor * 3);
|
||||
const labelOffsetX = -labelWidth / 2;
|
||||
const labelDy = (showingNetworks && networks) ? 0.75 : 0.60;
|
||||
const labelOffsetY = focused ? nodeScale(labelDy) : nodeScale(labelDy * scaleFactor);
|
||||
const labelOffsetY = nodeScale(labelDy * scaleFactor);
|
||||
const networkOffset = nodeScale(scaleFactor * 0.67);
|
||||
|
||||
const nodeClassName = classnames('node', {
|
||||
highlighted,
|
||||
@@ -104,7 +111,7 @@ class Node extends React.Component {
|
||||
const NodeShapeType = getNodeShape(this.props);
|
||||
const useSvgLabels = exportingGraph;
|
||||
const size = nodeScale(scaleFactor);
|
||||
const networkOffset = focused ? nodeScale(scaleFactor * 0.67) : nodeScale(0.67);
|
||||
const fontSize = labelFontSize(size);
|
||||
const mouseEvents = {
|
||||
onClick: this.handleMouseClick,
|
||||
onMouseEnter: this.handleMouseEnter,
|
||||
@@ -119,8 +126,10 @@ class Node extends React.Component {
|
||||
svgLabels(label, subLabel, labelClassName, subLabelClassName, labelOffsetY) :
|
||||
|
||||
<foreignObject style={{pointerEvents: 'none'}} x={labelOffsetX} y={labelOffsetY}
|
||||
width={labelWidth} height="100em" transform={labelTransform}>
|
||||
<div className="node-label-wrapper" style={{pointerEvents: 'all'}} {...mouseEvents}>
|
||||
width={labelWidth} height="100em">
|
||||
<div className="node-label-wrapper"
|
||||
style={{pointerEvents: 'all', fontSize, maxWidth: labelWidth}}
|
||||
{...mouseEvents}>
|
||||
<div className={labelClassName}>
|
||||
<MatchedText text={label} match={matches.get('label')} />
|
||||
</div>
|
||||
@@ -131,7 +140,7 @@ class Node extends React.Component {
|
||||
</div>
|
||||
</foreignObject>}
|
||||
|
||||
<g {...mouseEvents}>
|
||||
<g {...mouseEvents} ref={this.saveShapeRef}>
|
||||
<NodeShapeType
|
||||
size={size}
|
||||
color={color}
|
||||
@@ -144,10 +153,14 @@ class Node extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
saveShapeRef(ref) {
|
||||
this.shapeRef = ref;
|
||||
}
|
||||
|
||||
handleMouseClick(ev) {
|
||||
ev.stopPropagation();
|
||||
this.props.clickNode(this.props.id, this.props.label,
|
||||
ReactDOM.findDOMNode(this).getBoundingClientRect());
|
||||
ReactDOM.findDOMNode(this.shapeRef).getBoundingClientRect());
|
||||
}
|
||||
|
||||
handleMouseEnter() {
|
||||
|
||||
@@ -8,7 +8,7 @@ import timely from 'timely';
|
||||
|
||||
import { clickBackground } from '../actions/app-actions';
|
||||
import { EDGE_ID_SEPARATOR } from '../constants/naming';
|
||||
import { DETAILS_PANEL_WIDTH } from '../constants/styles';
|
||||
import { DETAILS_PANEL_WIDTH, MAX_NODE_SIZE } from '../constants/styles';
|
||||
import Logo from '../components/logo';
|
||||
import { doLayout } from './nodes-layout';
|
||||
import NodesChartElements from './nodes-chart-elements';
|
||||
@@ -370,7 +370,7 @@ class NodesChart extends React.Component {
|
||||
getNodeScale(nodes, width, height) {
|
||||
const expanse = Math.min(height, width);
|
||||
const nodeSize = expanse / 3; // single node should fill a third of the screen
|
||||
const maxNodeSize = expanse / 10;
|
||||
const maxNodeSize = Math.min(MAX_NODE_SIZE, expanse / 10);
|
||||
const normalizedNodeSize = Math.min(nodeSize / Math.sqrt(nodes.size), maxNodeSize);
|
||||
return this.state.nodeScale.copy().range([0, normalizedNodeSize]);
|
||||
}
|
||||
|
||||
@@ -17,3 +17,11 @@ export const CANVAS_MARGINS = {
|
||||
right: 40,
|
||||
bottom: 100,
|
||||
};
|
||||
|
||||
//
|
||||
// The base size the shapes were defined at matches nicely w/ a 14px font.
|
||||
//
|
||||
export const BASE_NODE_SIZE = 64;
|
||||
export const MAX_NODE_SIZE = 96;
|
||||
export const BASE_NODE_LABEL_SIZE = 14;
|
||||
export const MIN_NODE_LABEL_SIZE = BASE_NODE_LABEL_SIZE;
|
||||
|
||||
@@ -368,10 +368,15 @@ h2 {
|
||||
|
||||
.node-label {
|
||||
color: @text-color;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.node-label-wrapper {
|
||||
|
||||
//
|
||||
// Base line height doesn't hop across foreignObject =/
|
||||
//
|
||||
line-height: 150%;
|
||||
|
||||
//
|
||||
// inline-block so wrapper is only as wide as content.
|
||||
//
|
||||
@@ -390,7 +395,7 @@ h2 {
|
||||
|
||||
.node-sublabel {
|
||||
color: @text-secondary-color;
|
||||
font-size: 12px;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
&.hovered {
|
||||
@@ -547,7 +552,7 @@ h2 {
|
||||
text-align: center;
|
||||
|
||||
&-match {
|
||||
font-size: 0.7rem;
|
||||
font-size: 0.8em;
|
||||
|
||||
&-wrapper {
|
||||
display: inline-block;
|
||||
@@ -564,7 +569,7 @@ h2 {
|
||||
|
||||
&-more {
|
||||
text-transform: uppercase;
|
||||
font-size: 0.6rem;
|
||||
font-size: 0.7em;
|
||||
color: darken(@weave-blue, 10%);
|
||||
margin-top: -2px;
|
||||
}
|
||||
@@ -1162,6 +1167,7 @@ h2 {
|
||||
}
|
||||
|
||||
&-wrapper {
|
||||
pointer-events: all;
|
||||
border-radius: @border-radius;
|
||||
border: 1px solid @background-darker-color;
|
||||
display: inline-block;
|
||||
@@ -1275,6 +1281,7 @@ h2 {
|
||||
font-size: .7rem;
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.sidebar-gridmode {
|
||||
|
||||
Reference in New Issue
Block a user