🚸 优化图表下载交互

This commit is contained in:
BTMuli
2025-11-22 13:00:19 +08:00
parent dcc0d7d052
commit c521f3cc26
3 changed files with 70 additions and 10 deletions

View File

@@ -1,6 +1,7 @@
<!-- 祈愿日历图表组件 -->
<template>
<v-chart
ref="chartRef"
class="gro-chart-calendar"
:option="chartOptions"
autoresize
@@ -13,6 +14,7 @@
<script lang="ts" setup>
import TSUserGacha from "@Sqlm/userGacha.js";
import useAppStore from "@store/app.js";
import { getImageBuffer, saveCanvasImg } from "@utils/TGShare.js";
import type { HeatmapSeriesOption } from "echarts/charts.js";
import { HeatmapChart } from "echarts/charts.js";
import type {
@@ -27,12 +29,12 @@ import {
TooltipComponent,
VisualMapComponent,
} from "echarts/components.js";
import type { ComposeOption } from "echarts/core.js";
import type { ComposeOption, EChartsType } from "echarts/core.js";
import { use } from "echarts/core.js";
import { LabelLayout } from "echarts/features.js";
import { CanvasRenderer } from "echarts/renderers.js";
import { storeToRefs } from "pinia";
import { computed, onMounted, shallowRef, watch } from "vue";
import { computed, onMounted, shallowRef, useTemplateRef, watch } from "vue";
import VChart from "vue-echarts";
use([
@@ -60,6 +62,8 @@ const { theme } = storeToRefs(useAppStore());
const chartOptions = shallowRef<EChartsOption>();
const yearCount = shallowRef<number>(1); // 默认至少1年避免高度为0
const chartEl = useTemplateRef<InstanceType<typeof VChart>>("chartRef");
const echartsTheme = computed<"dark" | "light">(() => (theme.value === "dark" ? "dark" : "light"));
// 根据年份数量动态计算高度每个日历约160px加上顶部空间
@@ -95,7 +99,24 @@ async function getCalendarOptions(): Promise<EChartsOption> {
show: true,
feature: {
restore: {},
saveAsImage: { pixelRatio: 2 },
saveAsImage: { show: false },
myDownloadChart: {
show: true,
title: "下载图表",
icon: "M12 4v12m-4-4l4 4 4-4",
onclick: async () => {
if (!chartEl.value) return;
const chart: EChartsType = chartEl.value.chart;
if (!chart) return;
const dataUrl = chart.getDataURL({
pixelRatio: 2,
backgroundColor: theme.value === "dark" ? "#2c343c" : "#ffffff",
excludeComponents: ["toolbox"],
});
const buffer = await getImageBuffer(dataUrl);
await saveCanvasImg(buffer, `gacha-chart-calendar-${props.uid}`);
},
},
},
},
visualMap: {

View File

@@ -1,6 +1,6 @@
<!-- 祈愿分析图表组件 -->
<template>
<v-chart
ref="chartRef"
class="gro-chart-overview"
:option="chartOptions"
autoresize
@@ -12,6 +12,7 @@
<script lang="ts" setup>
import TSUserGacha from "@Sqlm/userGacha.js";
import useAppStore from "@store/app.js";
import { getImageBuffer, saveCanvasImg } from "@utils/TGShare.js";
import type { PieSeriesOption } from "echarts/charts.js";
import { BarChart, PieChart } from "echarts/charts.js";
import type {
@@ -28,12 +29,12 @@ import {
ToolboxComponent,
TooltipComponent,
} from "echarts/components.js";
import type { ComposeOption } from "echarts/core.js";
import type { ComposeOption, EChartsType } from "echarts/core.js";
import { use } from "echarts/core.js";
import { LabelLayout } from "echarts/features.js";
import { CanvasRenderer } from "echarts/renderers.js";
import { storeToRefs } from "pinia";
import { computed, onMounted, shallowRef, watch } from "vue";
import { computed, onMounted, shallowRef, useTemplateRef, watch } from "vue";
import VChart from "vue-echarts";
use([
@@ -64,6 +65,7 @@ const { theme } = storeToRefs(useAppStore());
const chartOptions = shallowRef<EChartsOption>({});
const echartsTheme = computed<"dark" | "light">(() => (theme.value === "dark" ? "dark" : "light"));
const chartEl = useTemplateRef<InstanceType<typeof VChart>>("chartRef");
/**
* @description 获取整体祈愿图表配置
@@ -85,7 +87,24 @@ async function getOverviewOptions(): Promise<EChartsOption> {
show: true,
feature: {
restore: {},
saveAsImage: { pixelRatio: 2 },
saveAsImage: { show: false },
myDownloadChart: {
show: true,
title: "下载图表",
icon: "M12 4v12m-4-4l4 4 4-4",
onclick: async () => {
if (!chartEl.value) return;
const chart: EChartsType = chartEl.value.chart;
if (!chart) return;
const dataUrl = chart.getDataURL({
pixelRatio: 2,
backgroundColor: theme.value === "dark" ? "#2c343c" : "#ffffff",
excludeComponents: ["toolbox"],
});
const buffer = await getImageBuffer(dataUrl);
await saveCanvasImg(buffer, `gacha-overview-${props.uid}`);
},
},
},
},
series: [

View File

@@ -1,6 +1,7 @@
<!-- 祈愿柱状图组件 -->
<template>
<v-chart
ref="chartRef"
class="gro-chart-stackbar"
:option="chartOptions"
autoresize
@@ -12,6 +13,7 @@
<script lang="ts" setup>
import TSUserGacha from "@Sqlm/userGacha.js";
import useAppStore from "@store/app.js";
import { getImageBuffer, saveCanvasImg } from "@utils/TGShare.js";
import type { BarSeriesOption } from "echarts/charts.js";
import { BarChart } from "echarts/charts.js";
import type {
@@ -28,12 +30,12 @@ import {
ToolboxComponent,
TooltipComponent,
} from "echarts/components.js";
import type { ComposeOption } from "echarts/core.js";
import type { ComposeOption, EChartsType } from "echarts/core.js";
import { use } from "echarts/core.js";
import { LabelLayout } from "echarts/features.js";
import { CanvasRenderer } from "echarts/renderers.js";
import { storeToRefs } from "pinia";
import { computed, onMounted, shallowRef, watch } from "vue";
import { computed, onMounted, shallowRef, useTemplateRef, watch } from "vue";
import VChart from "vue-echarts";
use([
@@ -63,6 +65,7 @@ const { theme } = storeToRefs(useAppStore());
const chartOptions = shallowRef<EChartsOption>({});
const echartsTheme = computed<"dark" | "light">(() => (theme.value === "dark" ? "dark" : "light"));
const chartEl = useTemplateRef<InstanceType<typeof VChart>>("chartRef");
/**
* @description 堆叠柱状图
@@ -129,7 +132,24 @@ async function getStackBarOptions(): Promise<EChartsOption> {
show: true,
feature: {
restore: {},
saveAsImage: { pixelRatio: 2 },
saveAsImage: { show: false },
myDownloadChart: {
show: true,
title: "下载图表",
icon: "M12 4v12m-4-4l4 4 4-4",
onclick: async () => {
if (!chartEl.value) return;
const chart: EChartsType = chartEl.value.chart;
if (!chart) return;
const dataUrl = chart.getDataURL({
pixelRatio: 2,
backgroundColor: theme.value === "dark" ? "#2c343c" : "#ffffff",
excludeComponents: ["toolbox"],
});
const buffer = await getImageBuffer(dataUrl);
await saveCanvasImg(buffer, `gacha-overview-${props.uid}`);
},
},
},
},
legend: { data: ["三星数量", "四星数量", "五星数量"] },