mirror of
https://github.com/weaveworks/scope.git
synced 2026-08-23 22:36:24 +00:00
Don't draw svg labels when we don't need them.
Having the DOM nodes w/ display:none is still expensive. We only need them briefly for svg export.
This commit is contained in:
committed by
David Kaltschmidt
parent
14e06e03ba
commit
af3f18b933
@@ -143,8 +143,10 @@ export function clickCloseTerminal(pipeId, closePipe) {
|
||||
}
|
||||
|
||||
export function clickDownloadGraph() {
|
||||
return () => {
|
||||
return (dispatch) => {
|
||||
dispatch({ type: ActionTypes.SET_EXPORTING_GRAPH, exporting: true });
|
||||
saveGraph();
|
||||
dispatch({ type: ActionTypes.SET_EXPORTING_GRAPH, exporting: false });
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,17 @@ function getNodeShape({ shape, stack }) {
|
||||
return stack ? stackedShape(nodeShape) : nodeShape;
|
||||
}
|
||||
|
||||
function svgLabels(label, subLabel, labelClassName, subLabelClassName, labelOffsetY) {
|
||||
return (
|
||||
<g className="node-label-svg">
|
||||
<text className={labelClassName} y={labelOffsetY + 18} textAnchor="middle">{label}</text>
|
||||
<text className={subLabelClassName} y={labelOffsetY + 35} textAnchor="middle">
|
||||
{subLabel}
|
||||
</text>
|
||||
</g>
|
||||
);
|
||||
}
|
||||
|
||||
class Node extends React.Component {
|
||||
|
||||
constructor(props, context) {
|
||||
@@ -65,7 +76,7 @@ class Node extends React.Component {
|
||||
|
||||
render() {
|
||||
const { blurred, focused, highlighted, label, matches = makeMap(),
|
||||
pseudo, rank, subLabel, scaleFactor, transform, zoomScale } = this.props;
|
||||
pseudo, rank, subLabel, scaleFactor, transform, zoomScale, exportingGraph } = this.props;
|
||||
const { hovered, matched } = this.state;
|
||||
const nodeScale = focused ? this.props.selectedNodeScale : this.props.nodeScale;
|
||||
|
||||
@@ -88,30 +99,29 @@ class Node extends React.Component {
|
||||
const subLabelClassName = classnames('node-sublabel', { truncate });
|
||||
|
||||
const NodeShapeType = getNodeShape(this.props);
|
||||
const useSvgLabels = exportingGraph;
|
||||
|
||||
return (
|
||||
<g className={nodeClassName} transform={transform}
|
||||
onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
|
||||
{/* For browser */}
|
||||
<foreignObject x={labelOffsetX} y={labelOffsetY} width={labelWidth} height="10em"
|
||||
transform={labelTransform}>
|
||||
<div className="node-label-wrapper" onClick={this.handleMouseClick}>
|
||||
<div className={labelClassName}>
|
||||
<MatchedText text={label} match={matches.get('label')} />
|
||||
|
||||
{useSvgLabels ?
|
||||
|
||||
svgLabels(label, subLabel, labelClassName, subLabelClassName, labelOffsetY) :
|
||||
|
||||
<foreignObject x={labelOffsetX} y={labelOffsetY} width={labelWidth}
|
||||
height="10em" transform={labelTransform}>
|
||||
<div className="node-label-wrapper" onClick={this.handleMouseClick}>
|
||||
<div className={labelClassName}>
|
||||
<MatchedText text={label} match={matches.get('label')} />
|
||||
</div>
|
||||
<div className={subLabelClassName}>
|
||||
<MatchedText text={subLabel} match={matches.get('sublabel')} />
|
||||
</div>
|
||||
{!blurred && <MatchedResults matches={matches.get('metadata')} />}
|
||||
</div>
|
||||
<div className={subLabelClassName}>
|
||||
<MatchedText text={subLabel} match={matches.get('sublabel')} />
|
||||
</div>
|
||||
{!blurred && <MatchedResults matches={matches.get('metadata')} />}
|
||||
</div>
|
||||
</foreignObject>
|
||||
{/* For SVG export */}
|
||||
<g className="node-label-svg">
|
||||
<text className={labelClassName} y={labelOffsetY + 18} textAnchor="middle">{label}</text>
|
||||
<text className={subLabelClassName} y={labelOffsetY + 35} textAnchor="middle">
|
||||
{subLabel}
|
||||
</text>
|
||||
</g>
|
||||
</foreignObject>}
|
||||
|
||||
<g onClick={this.handleMouseClick}>
|
||||
<NodeShapeType
|
||||
size={nodeScale(scaleFactor)}
|
||||
@@ -140,6 +150,9 @@ class Node extends React.Component {
|
||||
}
|
||||
|
||||
export default connect(
|
||||
state => ({ searchQuery: state.get('searchQuery') }),
|
||||
state => ({
|
||||
searchQuery: state.get('searchQuery'),
|
||||
exportingGraph: state.get('exportingGraph')
|
||||
}),
|
||||
{ clickNode, enterNode, leaveNode }
|
||||
)(Node);
|
||||
|
||||
@@ -46,7 +46,8 @@ const ACTION_TYPES = [
|
||||
'RECEIVE_ERROR',
|
||||
'ROUTE_TOPOLOGY',
|
||||
'SELECT_METRIC',
|
||||
'SHOW_HELP'
|
||||
'SHOW_HELP',
|
||||
'SET_EXPORTING_GRAPH'
|
||||
];
|
||||
|
||||
export default _.zipObject(ACTION_TYPES, ACTION_TYPES);
|
||||
|
||||
@@ -70,7 +70,8 @@ export const initialState = makeMap({
|
||||
updatePausedAt: null, // Date
|
||||
version: '...',
|
||||
versionUpdate: null,
|
||||
websocketClosed: true
|
||||
websocketClosed: true,
|
||||
exportingGraph: false
|
||||
});
|
||||
|
||||
// adds ID field to topology (based on last part of URL path) and save urls in
|
||||
@@ -169,6 +170,10 @@ export function rootReducer(state = initialState, action) {
|
||||
return state;
|
||||
}
|
||||
|
||||
case ActionTypes.SET_EXPORTING_GRAPH: {
|
||||
return state.set('exportingGraph', action.exporting);
|
||||
}
|
||||
|
||||
case ActionTypes.CLEAR_CONTROL_ERROR: {
|
||||
return state.removeIn(['controlStatus', action.nodeId, 'error']);
|
||||
}
|
||||
|
||||
@@ -322,12 +322,12 @@ h2 {
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.logo, .node-label-svg {
|
||||
.logo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
svg.exported {
|
||||
.logo, .node-label-svg {
|
||||
.logo {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user