Fix memory leaks from Cytoscape instances not returned/destroyed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 20:53:25 +08:00
parent 9aa60414e7
commit f04da6e278
4 changed files with 25 additions and 6 deletions

View File

@@ -121,7 +121,7 @@
* results with expandable activity sequences. * results with expandable activity sequences.
*/ */
import { ref, computed, watch, nextTick, useTemplateRef } from "vue"; import { ref, computed, watch, nextTick, useTemplateRef, onBeforeUnmount } from "vue";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { useConformanceStore } from "@/stores/conformance"; import { useConformanceStore } from "@/stores/conformance";
import cytoscapeMapTrace from "@/module/cytoscapeMapTrace.js"; import cytoscapeMapTrace from "@/module/cytoscapeMapTrace.js";
@@ -151,6 +151,7 @@ const infiniteData = ref(null);
const maxItems = ref(false); const maxItems = ref(false);
const infiniteFinish = ref(true); // Whether infinite scroll loading is complete const infiniteFinish = ref(true); // Whether infinite scroll loading is complete
const startNum = ref(0); const startNum = ref(0);
const cyTraceInstance = ref(null);
const processMap = ref({ const processMap = ref({
nodes: [], nodes: [],
edges: [], edges: [],
@@ -364,8 +365,9 @@ function createCy() {
setNodesData(); setNodesData();
setEdgesData(); setEdgesData();
cyTraceInstance.value?.destroy();
if (graphId !== null) if (graphId !== null)
cytoscapeMapTrace( cyTraceInstance.value = cytoscapeMapTrace(
processMap.value.nodes, processMap.value.nodes,
processMap.value.edges, processMap.value.edges,
graphId, graphId,
@@ -409,6 +411,10 @@ function handleScroll(event) {
if (overScrollHeight) fetchData(); if (overScrollHeight) fetchData();
} }
onBeforeUnmount(() => {
cyTraceInstance.value?.destroy();
});
</script> </script>
<style scoped> <style scoped>
@reference "../../../assets/tailwind.css"; @reference "../../../assets/tailwind.css";

View File

@@ -131,7 +131,7 @@
* trace detail display. * trace detail display.
*/ */
import { ref, computed, watch, onMounted } from "vue"; import { ref, computed, watch, onMounted, onBeforeUnmount } from "vue";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { useAllMapDataStore } from "@/stores/allMapData"; import { useAllMapDataStore } from "@/stores/allMapData";
import { useLoadingStore } from "@/stores/loading"; import { useLoadingStore } from "@/stores/loading";
@@ -161,6 +161,7 @@ const infiniteFinish = ref(true); // Whether infinite scroll loading is complete
const chartOptions = ref(null); const chartOptions = ref(null);
const selectArea = ref([0, 1]); const selectArea = ref([0, 1]);
const cyTraceRef = ref(null); const cyTraceRef = ref(null);
const cyTraceInstance = ref(null);
const traceTotal = computed(() => { const traceTotal = computed(() => {
return baseTraces.value.length; return baseTraces.value.length;
@@ -413,7 +414,8 @@ function createCy() {
setNodesData(); setNodesData();
setEdgesData(); setEdgesData();
cytoscapeMapTrace(processMap.value.nodes, processMap.value.edges, graphId); cyTraceInstance.value?.destroy();
cyTraceInstance.value = cytoscapeMapTrace(processMap.value.nodes, processMap.value.edges, graphId);
} }
/** /**
@@ -461,6 +463,10 @@ onMounted(() => {
selectArea.value = [0, traceTotal.value]; selectArea.value = [0, traceTotal.value];
isLoading.value = false; isLoading.value = false;
}); });
onBeforeUnmount(() => {
cyTraceInstance.value?.destroy();
});
</script> </script>
<style scoped> <style scoped>

View File

@@ -110,7 +110,7 @@
* clickable trace lists for highlighting on the map. * clickable trace lists for highlighting on the map.
*/ */
import { ref, computed, watch } from "vue"; import { ref, computed, watch, onBeforeUnmount } from "vue";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { useLoadingStore } from "@/stores/loading"; import { useLoadingStore } from "@/stores/loading";
import { useAllMapDataStore } from "@/stores/allMapData"; import { useAllMapDataStore } from "@/stores/allMapData";
@@ -140,6 +140,7 @@ const infinitMaxItems = ref(false);
const infiniteData = ref([]); const infiniteData = ref([]);
const infiniteFinish = ref(true); // Whether infinite scroll loading is complete const infiniteFinish = ref(true); // Whether infinite scroll loading is complete
const cyTraceRef = ref(null); const cyTraceRef = ref(null);
const cyTraceInstance = ref(null);
const traceTotal = computed(() => { const traceTotal = computed(() => {
return traces.value.length; return traces.value.length;
@@ -301,7 +302,8 @@ function createCy() {
setNodesData(); setNodesData();
setEdgesData(); setEdgesData();
cytoscapeMapTrace(processMap.value.nodes, processMap.value.edges, graphId); cyTraceInstance.value?.destroy();
cyTraceInstance.value = cytoscapeMapTrace(processMap.value.nodes, processMap.value.edges, graphId);
} }
/** /**
@@ -353,6 +355,10 @@ async function fetchData() {
console.error("Failed to load data:", error); console.error("Failed to load data:", error);
} }
} }
onBeforeUnmount(() => {
cyTraceInstance.value?.destroy();
});
</script> </script>
<style scoped> <style scoped>

View File

@@ -112,4 +112,5 @@ export default function cytoscapeMapTrace(nodes, edges, graphId) {
tip?.destroy(); tip?.destroy();
tip = null; tip = null;
}); });
return cy;
} }