Skip to content

Commit cb1b5de

Browse files
Merge pull request #43 from reactome/feature/update-reacfoam
⚡ Improve performance and rendering of Reacfoam
2 parents 18fc782 + 767c751 commit cb1b5de

2 files changed

Lines changed: 26 additions & 35 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"dependencies": {
2424
"@angular/animations": "^19.2.20",
2525
"@angular/cdk": "^19.2.19",
26-
"@carrotsearch/foamtree": "^3.5.7",
2726
"@angular/common": "^19.2.20",
2827
"@angular/compiler": "^19.2.20",
2928
"@angular/core": "^19.2.20",
@@ -35,6 +34,7 @@
3534
"@angular/platform-browser-dynamic": "^19.2.20",
3635
"@angular/router": "^19.2.20",
3736
"@angular/ssr": "^19.2.20",
37+
"@carrotsearch/foamtree": "^3.6.0-rc1",
3838
"@hakimio/ngx-google-analytics": "^15.0.0",
3939
"@lottiefiles/dotlottie-web": "^0.49.0",
4040
"@ngneat/until-destroy": "^10.0.0",

projects/pathway-browser/src/app/reacfoam/reacfoam.component.ts

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export class ReacfoamComponent implements OnDestroy {
4646
stacking: "flattened",
4747
relaxationInitializer: "ordered", // Impactful on the sub-groups of TLPs
4848
layoutByWeightOrder: false,
49-
relaxationVisible: true, // TODO evaluate if we wanna keep this
49+
relaxationVisible: false,
5050
pixelRatio: window.devicePixelRatio || 1,
5151
wireframePixelRatio: window.devicePixelRatio || 1,
5252
exposeDuration: 500,
@@ -93,7 +93,7 @@ export class ReacfoamComponent implements OnDestroy {
9393
wireframeToFinalFadeDuration: 0,
9494
groupLabelColorThreshold: 0.8,
9595
relaxationMaxDuration: 4000,
96-
relaxationQualityThreshold: 0.5,
96+
relaxationQualityThreshold: 10,
9797

9898
// Labels
9999
groupLabelFontFamily: 'Roboto',
@@ -106,12 +106,12 @@ export class ReacfoamComponent implements OnDestroy {
106106
// Roll out in groups
107107
rolloutMethod: "groups",
108108

109-
onGroupDoubleClick: (event: any) => {
109+
onGroupDoubleClick: (event) => {
110110
event.preventDefault();
111111
this.state.navigateTo(event.group.stId, {queryParamsHandling: 'preserve', preserveFragment: true})
112112
},
113113

114-
onGroupClick: (event: any) => {
114+
onGroupClick: (event) => {
115115
event.preventDefault();
116116
if (!event.secondary) {
117117
this.state.select.set(event.group.stId)
@@ -124,22 +124,6 @@ export class ReacfoamComponent implements OnDestroy {
124124
}
125125
},
126126

127-
// For now, add exposure at end of relaxation, useful upon resizing reset. to be removed when alternative solution found for stable layout
128-
onRelaxationStep: (relaxationProgress: any, relaxationComplete: any, relaxationTimeout: any) => {
129-
this.relaxing.set(true)
130-
this.foamTree().set("groupLabelMinFontSize", 20);
131-
if ((relaxationTimeout || relaxationComplete)) {
132-
this.relaxing.set(false)
133-
this.foamTree().set("groupLabelMinFontSize", 3);
134-
this.foamTree().redraw()
135-
if (this.correctedSelectedId()) {
136-
setTimeout(() => {
137-
this.foamTree().expose({groups: this.correctedSelectedId(), keepPrevious: false})
138-
})
139-
}
140-
}
141-
},
142-
143127
onViewReset: () => { // Reset selection on esc pressed
144128
this.state.select.set(null)
145129
this.state.path.set([])
@@ -160,18 +144,25 @@ export class ReacfoamComponent implements OnDestroy {
160144

161145
relaxing = signal(false)
162146

163-
sizeObserver = new ResizeObserver(() => {
164-
setTimeout(() => { // Avoid white flickering
165-
this.foamTree().set('exposeDuration', 0) // Make removal of exposure instant
166-
this.foamTree().expose({
167-
groups: undefined,
168-
keepPrevious: false
169-
}).then(() => {
170-
this.foamTree().set('exposeDuration', this.options()['exposeDuration']!) // Put back initial exposure time
171-
this.foamTree().resize()
147+
sizeObserver = new ResizeObserver(throttle(50, () => {
148+
setTimeout(() => { // Avoid white flickering
149+
this.foamTree().set('exposeDuration', 0) // Make removal of exposure instant
150+
this.foamTree().expose({
151+
groups: undefined,
152+
keepPrevious: false
153+
}).then(() => {
154+
this.foamTree().resize()
155+
if (this.correctedSelectedId()) {
156+
this.foamTree().expose({
157+
groups: this.correctedSelectedId(),
158+
keepPrevious: false
159+
})
160+
}
161+
this.foamTree().set('exposeDuration', this.options().exposeDuration!) // Put back initial exposure time
162+
})
172163
})
173164
})
174-
});
165+
);
175166

176167
cleanFlagIdentifiers = computed(() => new Set(this.data.flagIdentifiers().filter(id => id.startsWith('R-'))))
177168
flagging = computed(() => this.cleanFlagIdentifiers().size !== 0)
@@ -236,7 +227,7 @@ export class ReacfoamComponent implements OnDestroy {
236227
this.foamTree().set({
237228
groupStrokePlainLightnessShift: this.dark.isDark() ? 70 : -70,
238229
groupStrokePlainSaturationShift: 0,
239-
groupColorDecorator: (options: any, props: any, values: any) => {
230+
groupColorDecorator: (options, props, values) => {
240231
const depth = props.group.depth;
241232
// If child groups of some group doesn't have enough space to
242233
// render, draw the parent group in red.
@@ -261,10 +252,10 @@ export class ReacfoamComponent implements OnDestroy {
261252
values.groupColor = notFoundColor;
262253
} else {
263254
if (this.analysis.type() === 'OVERREPRESENTATION' || this.analysis.type() === 'SPECIES_COMPARISON') { // FDR ~ color
264-
values.groupColor = (this.analysis.palette().scale(props.group.fdr) as any).hex()
255+
values.groupColor = this.analysis.palette().scale(props.group.fdr).hex()
265256
} else { // expression ~ color
266257
if (props.group.expressions) {
267-
values.groupColor = (this.analysis.palette().scale(props.group.expressions[this.analysis.sampleIndex()]) as any).hex()
258+
values.groupColor = this.analysis.palette().scale(props.group.expressions[this.analysis.sampleIndex()]).hex()
268259
} else {
269260
values.groupColor = notFoundColor;
270261
}
@@ -330,7 +321,7 @@ export class ReacfoamComponent implements OnDestroy {
330321

331322
}
332323

333-
function throttle<Args extends any[]>(func: (...args: Args) => void, delay: number): (...args: Args) => void {
324+
function throttle<Args extends any[]>(delay: number, func: (...args: Args) => void): (...args: Args) => void {
334325
let lastCall = 0;
335326
return (...args: Args) => {
336327
const now = new Date().getTime();

0 commit comments

Comments
 (0)