@@ -3,9 +3,10 @@ import PropTypes from 'prop-types';
3
3
import { connect , useSelector } from 'react-redux' ;
4
4
import Cytoscape from 'cytoscape' ;
5
5
import CytoscapeComponent from 'react-cytoscapejs' ;
6
- import Dagre from 'cytoscape-dagre' ;
6
+ import dagre from 'cytoscape-dagre' ;
7
+ import fcose from 'cytoscape-fcose' ;
7
8
import JSONTree from 'react-json-tree' ;
8
- import { keys , mergeRight , omit , path } from 'ramda' ;
9
+ import { keys , mergeRight , omit , path , values } from 'ramda' ;
9
10
10
11
import { getPath } from '../../../actions/paths' ;
11
12
import { stringifyId } from '../../../actions/dependencies' ;
@@ -19,14 +20,16 @@ import {
19
20
updateCallback
20
21
} from './CallbackGraphEffects' ;
21
22
22
- Cytoscape . use ( Dagre ) ;
23
+ Cytoscape . use ( dagre ) ;
24
+ Cytoscape . use ( fcose ) ;
23
25
24
26
/*
25
27
* Generates all the elements (nodes, edeges) for the dependency graph.
26
28
*/
27
- function generateElements ( graphs , profile ) {
29
+ function generateElements ( graphs , profile , extraLinks ) {
28
30
const consumed = [ ] ;
29
31
const elements = [ ] ;
32
+ const structure = { } ;
30
33
31
34
function recordNode ( id , property ) {
32
35
const idStr = stringifyId ( id ) ;
@@ -45,6 +48,7 @@ function generateElements(graphs, profile) {
45
48
type : idType
46
49
}
47
50
} ) ;
51
+ structure [ parentId ] = [ ] ;
48
52
}
49
53
50
54
if ( ! consumed . includes ( childId ) ) {
@@ -57,6 +61,7 @@ function generateElements(graphs, profile) {
57
61
type : 'property'
58
62
}
59
63
} ) ;
64
+ structure [ parentId ] . push ( childId ) ;
60
65
}
61
66
62
67
return childId ;
@@ -107,6 +112,19 @@ function generateElements(graphs, profile) {
107
112
} ) ;
108
113
} ) ;
109
114
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
+
110
128
return elements ;
111
129
}
112
130
@@ -142,24 +160,19 @@ function flattenInputs(inArray, final) {
142
160
// len('__dash_callback__.')
143
161
const cbPrefixLen = 18 ;
144
162
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
+
145
171
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
163
176
} ;
164
177
165
178
function CallbackGraph ( ) {
@@ -181,7 +194,10 @@ function CallbackGraph() {
181
194
const [ layoutType , setLayoutType ] = useState ( chosenType || 'top-down' ) ;
182
195
183
196
// 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
+ ) ;
185
201
186
202
// Custom hook to make sure cytoscape is loaded.
187
203
const useCytoscapeEffect = ( effect , condition ) => {
0 commit comments