Skip to content

Commit 2b1a106

Browse files
committed
more robust callback graph layouts
1 parent 5616d1b commit 2b1a106

File tree

4 files changed

+67
-22
lines changed

4 files changed

+67
-22
lines changed

dash-renderer/package-lock.json

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dash-renderer/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"cookie": "^0.4.0",
3030
"cytoscape": "^3.14.1",
3131
"cytoscape-dagre": "^2.2.2",
32+
"cytoscape-fcose": "^1.2.3",
3233
"dependency-graph": "^0.9.0",
3334
"fast-isnumeric": "^1.1.3",
3435
"prop-types": "15.7.2",

dash-renderer/src/components/error/CallbackGraph/CallbackGraphContainer.react.js

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import PropTypes from 'prop-types';
33
import {connect, useSelector} from 'react-redux';
44
import Cytoscape from 'cytoscape';
55
import CytoscapeComponent from 'react-cytoscapejs';
6-
import Dagre from 'cytoscape-dagre';
6+
import dagre from 'cytoscape-dagre';
7+
import fcose from 'cytoscape-fcose';
78
import JSONTree from 'react-json-tree';
8-
import {keys, mergeRight, omit, path} from 'ramda';
9+
import {keys, mergeRight, omit, path, values} from 'ramda';
910

1011
import {getPath} from '../../../actions/paths';
1112
import {stringifyId} from '../../../actions/dependencies';
@@ -19,14 +20,16 @@ import {
1920
updateCallback
2021
} from './CallbackGraphEffects';
2122

22-
Cytoscape.use(Dagre);
23+
Cytoscape.use(dagre);
24+
Cytoscape.use(fcose);
2325

2426
/*
2527
* Generates all the elements (nodes, edeges) for the dependency graph.
2628
*/
27-
function generateElements(graphs, profile) {
29+
function generateElements(graphs, profile, extraLinks) {
2830
const consumed = [];
2931
const elements = [];
32+
const structure = {};
3033

3134
function recordNode(id, property) {
3235
const idStr = stringifyId(id);
@@ -45,6 +48,7 @@ function generateElements(graphs, profile) {
4548
type: idType
4649
}
4750
});
51+
structure[parentId] = [];
4852
}
4953

5054
if (!consumed.includes(childId)) {
@@ -57,6 +61,7 @@ function generateElements(graphs, profile) {
5761
type: 'property'
5862
}
5963
});
64+
structure[parentId].push(childId);
6065
}
6166

6267
return childId;
@@ -107,6 +112,19 @@ function generateElements(graphs, profile) {
107112
});
108113
});
109114

115+
// pull together props in the same component
116+
if (extraLinks) {
117+
values(structure).forEach(childIds => {
118+
childIds.forEach(childFrom => {
119+
childIds.forEach(childTo => {
120+
if (childFrom !== childTo) {
121+
recordEdge(childFrom, childTo, 'hidden');
122+
}
123+
});
124+
});
125+
});
126+
}
127+
110128
return elements;
111129
}
112130

@@ -142,24 +160,19 @@ function flattenInputs(inArray, final) {
142160
// len('__dash_callback__.')
143161
const cbPrefixLen = 18;
144162

163+
const dagreLayout = {
164+
name: 'dagre',
165+
padding: 10,
166+
ranker: 'tight-tree'
167+
};
168+
169+
const forceLayout = {name: 'fcose', padding: 10, animate: false};
170+
145171
const layouts = {
146-
'top-down': {
147-
name: 'dagre',
148-
padding: 10,
149-
spacingFactor: 0.8
150-
},
151-
'left-right': {
152-
name: 'dagre',
153-
padding: 10,
154-
nodeSep: 0,
155-
rankSep: 80,
156-
rankDir: 'LR'
157-
},
158-
force: {
159-
name: 'cose',
160-
padding: 10,
161-
animate: false
162-
}
172+
'top-down': {...dagreLayout, spacingFactor: 0.8},
173+
'left-right': {...dagreLayout, nodeSep: 0, rankSep: 80, rankDir: 'LR'},
174+
force: forceLayout,
175+
'force-loose': forceLayout
163176
};
164177

165178
function CallbackGraph() {
@@ -181,7 +194,10 @@ function CallbackGraph() {
181194
const [layoutType, setLayoutType] = useState(chosenType || 'top-down');
182195

183196
// Generate and memoize the elements.
184-
const elements = useMemo(() => generateElements(graphs, profile), [graphs]);
197+
const elements = useMemo(
198+
() => generateElements(graphs, profile, layoutType === 'force'),
199+
[graphs, layoutType]
200+
);
185201

186202
// Custom hook to make sure cytoscape is loaded.
187203
const useCytoscapeEffect = (effect, condition) => {

dash-renderer/src/components/error/CallbackGraph/CallbackGraphContainerStylesheet.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ const stylesheet = [
2424
}
2525
},
2626

27+
{
28+
selector: 'edge[type="hidden"]',
29+
style: {
30+
display: 'none'
31+
}
32+
},
33+
2734
{
2835
selector: 'edge[type="output"]',
2936
style: {

0 commit comments

Comments
 (0)