From 510c6ca4577cf54a70a529e4d0249e90f78d306d Mon Sep 17 00:00:00 2001 From: bunny <1319900154@qq.com> Date: Wed, 4 Jun 2025 18:50:06 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=84=20=E4=BF=AE=E6=94=B9echart?= =?UTF-8?q?=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/utils.ts | 54 ++++++++++++++++++++++++++++++++++-------- src/plugins/echarts.ts | 14 ++++++++++- src/utils/chart.ts | 18 +++++++++++++- 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/build/utils.ts b/build/utils.ts index baabe97..ae05eb4 100644 --- a/build/utils.ts +++ b/build/utils.ts @@ -94,20 +94,54 @@ export const logOutputSize = (): string => { return `${size.toFixed(2)} ${units[index]}`; } - // 计算文件夹字节大小 - function getFolderSize(folderPath: string) { + /** + * 计算文件夹大小(排除图片文件) + * @param folderPath 文件夹路径 + * @param currentDepth 当前递归深度(内部使用) + * @returns 文件夹大小(字节) + */ + function getFolderSize(folderPath: string, currentDepth: number = 0): number { + // 公共常量定义 + const EXCLUDED_FILE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg']; + const MAX_DEPTH = 10; // 最大递归深度限制 + + // 安全检查 + if (!fs.existsSync(folderPath)) { + throw new Error(`文件夹不存在: ${folderPath}`); + } + + if (currentDepth > MAX_DEPTH) { + console.warn(`达到最大递归深度 ${MAX_DEPTH},停止遍历: ${folderPath}`); + return 0; + } + let size = 0; - fs.readdirSync(folderPath).forEach((fileName: string) => { - const filePath = path.join(folderPath, fileName); - const stats = fs.statSync(filePath); + try { + const files = fs.readdirSync(folderPath); - if (stats.isFile()) { - size += stats.size; - } else if (stats.isDirectory()) { - size += getFolderSize(filePath); + for (const fileName of files) { + const filePath = path.join(folderPath, fileName); + + try { + const stats = fs.statSync(filePath); + + if (stats.isFile()) { + // 检查文件扩展名是否在排除列表中 + const ext = path.extname(fileName).toLowerCase(); + if (!EXCLUDED_FILE_EXTENSIONS.includes(ext)) { + size += stats.size; + } + } else if (stats.isDirectory()) { + size += getFolderSize(filePath, currentDepth + 1); + } + } catch (error) { + console.error(`无法访问文件: ${filePath}`, error); + } } - }); + } catch (error) { + console.error(`无法读取目录: ${folderPath}`, error); + } return size; } diff --git a/src/plugins/echarts.ts b/src/plugins/echarts.ts index 308dcb9..4056ba4 100644 --- a/src/plugins/echarts.ts +++ b/src/plugins/echarts.ts @@ -1,4 +1,13 @@ -import { BarChart, GaugeChart, LineChart, PictorialBarChart, PieChart } from 'echarts/charts'; +import { + BarChart, + EffectScatterChart, + GaugeChart, + LineChart, + MapChart, + PictorialBarChart, + PieChart, + TreemapChart, +} from 'echarts/charts'; import { DataZoomComponent, GraphicComponent, @@ -17,11 +26,13 @@ import type { App } from 'vue'; const { use } = echarts; use([ PieChart, + EffectScatterChart, BarChart, LineChart, CanvasRenderer, SVGRenderer, GridComponent, + TreemapChart, TitleComponent, PolarComponent, LegendComponent, @@ -32,6 +43,7 @@ use([ VisualMapComponent, PictorialBarChart, GaugeChart, + MapChart, ]); /** diff --git a/src/utils/chart.ts b/src/utils/chart.ts index 0d68ecb..bc69184 100644 --- a/src/utils/chart.ts +++ b/src/utils/chart.ts @@ -1,4 +1,5 @@ import { useDebounceFn, useEventListener } from '@vueuse/core'; +import type { EChartsType } from 'echarts'; import echarts from '@/plugins/echarts'; @@ -13,7 +14,7 @@ export const debounceChart = (myChart: echarts.ECharts | undefined) => { /** 数字格式化 */ export const formatter = (number: any) => { - const numbers = number.toString().split('').reverse(); + const numbers = number?.toString().split('').reverse(); const segs = []; while (numbers.length) segs.push(numbers.splice(0, 3).join('')); @@ -38,3 +39,18 @@ export const graphicLinearGradient = ( ] ); }; + +export const resetSelect = (myChart: EChartsType) => { + myChart.dispatchAction({ + type: 'downplay', + seriesIndex: 0, + }); +}; + +export const selectSector = (myChart: EChartsType, dataIndex: number) => { + myChart.dispatchAction({ + type: 'highlight', + seriesIndex: 0, + dataIndex, + }); +};