fix(frontend): チャートコンポーネントのマウント解除時にChartインスタンスが破棄されていない問題を修正 (#17763)

* fix(frontend): Chartのマウント解除時にChartインスタンスが破棄されていない問題を修正

* Update Changelog

* fix
This commit is contained in:
かっこかり
2026-07-22 10:16:15 +09:00
committed by GitHub
parent 4c3f40a87d
commit 2d2aa779ad
16 changed files with 119 additions and 26 deletions
+4 -1
View File
@@ -46,7 +46,7 @@ export type ChartSrc =
<script lang="ts" setup>
import { onMounted, ref, useTemplateRef, watch } from 'vue';
import { onMounted, onUnmounted, ref, useTemplateRef, watch } from 'vue';
import { Chart } from 'chart.js';
import * as Misskey from 'misskey-js';
import { misskeyApiGet } from '@/utility/misskey-api.js';
@@ -879,6 +879,9 @@ onMounted(() => {
fetchAndRender();
});
onUnmounted(() => {
chartInstance?.destroy();
});
</script>
<style lang="scss" module>
@@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { onMounted, nextTick, watch, useTemplateRef, ref } from 'vue';
import { onMounted, onUnmounted, nextTick, watch, useTemplateRef, ref } from 'vue';
import { Chart } from 'chart.js';
import * as Misskey from 'misskey-js';
import { misskeyApi } from '@/utility/misskey-api.js';
@@ -232,7 +232,11 @@ watch(() => props.src, () => {
renderChart();
});
onMounted(async () => {
onMounted(() => {
renderChart();
});
onUnmounted(() => {
chartInstance?.destroy();
});
</script>
@@ -55,7 +55,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { onMounted, computed, useTemplateRef } from 'vue';
import { onMounted, onUnmounted, computed, useTemplateRef } from 'vue';
import { Chart } from 'chart.js';
import type { MkSelectItem, ItemOption } from '@/components/MkSelect.vue';
import type { ChartSrc } from '@/components/MkChart.vue';
@@ -163,9 +163,13 @@ const {
]),
initialValue: 'active-users',
});
const subDoughnutEl = useTemplateRef('subDoughnutEl');
const pubDoughnutEl = useTemplateRef('pubDoughnutEl');
let subDoughnutChartInstance: Chart | null = null;
let pubDoughnutChartInstance: Chart | null = null;
const { handler: externalTooltipHandler1 } = useChartTooltip({
position: 'middle',
});
@@ -246,7 +250,9 @@ onMounted(() => {
value: fedStats.otherFollowersCount,
});
if (subDoughnutEl.value != null) createDoughnut(subDoughnutEl.value, externalTooltipHandler1, subs);
if (subDoughnutEl.value != null) {
subDoughnutChartInstance = createDoughnut(subDoughnutEl.value, externalTooltipHandler1, subs);
}
const pubs: ChartData = fedStats.topPubInstances.map(x => ({
name: x.host,
@@ -263,9 +269,16 @@ onMounted(() => {
value: fedStats.otherFollowingCount,
});
if (pubDoughnutEl.value != null) createDoughnut(pubDoughnutEl.value, externalTooltipHandler2, pubs);
if (pubDoughnutEl.value != null) {
pubDoughnutChartInstance = createDoughnut(pubDoughnutEl.value, externalTooltipHandler2, pubs);
}
});
});
onUnmounted(() => {
subDoughnutChartInstance?.destroy();
pubDoughnutChartInstance?.destroy();
});
</script>
<style lang="scss" module>
@@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { onMounted, nextTick, useTemplateRef, ref } from 'vue';
import { onMounted, onUnmounted, nextTick, useTemplateRef, ref } from 'vue';
import { Chart } from 'chart.js';
import { misskeyApi } from '@/utility/misskey-api.js';
import { store } from '@/store.js';
@@ -203,7 +203,11 @@ async function renderChart() {
});
}
onMounted(async () => {
onMounted(() => {
renderChart();
});
onUnmounted(() => {
chartInstance?.destroy();
});
</script>
@@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { onMounted, useTemplateRef } from 'vue';
import { onMounted, onUnmounted, useTemplateRef } from 'vue';
import { Chart } from 'chart.js';
import type { ScatterDataPoint } from 'chart.js';
import tinycolor from 'tinycolor2';
@@ -139,4 +139,8 @@ onMounted(async () => {
plugins: [chartVLine(vLineColor)],
});
});
onUnmounted(() => {
chartInstance?.destroy();
});
</script>
@@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { onMounted, useTemplateRef, ref, nextTick } from 'vue';
import { onMounted, onUnmounted, useTemplateRef, ref, nextTick } from 'vue';
import { Chart } from 'chart.js';
import tinycolor from 'tinycolor2';
import { misskeyApi } from '@/utility/misskey-api.js';
@@ -152,9 +152,13 @@ async function renderChart() {
});
}
onMounted(async () => {
onMounted(() => {
renderChart();
});
onUnmounted(() => {
chartInstance?.destroy();
});
</script>
<style lang="scss" module>