From 4cef22904bbf2b51d9c391ba776fef17f47c3843 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Tue, 5 May 2026 16:53:26 +0800 Subject: [PATCH] feat(chart): add chart functionality with ECharts integration and update output view options --- package.json | 2 + pnpm-lock.yaml | 37 ++++++ src/App.vue | 2 +- src/components/chart/QueryChart.vue | 167 ++++++++++++++++++++++++++ src/components/layout/ContentArea.vue | 29 ++++- src/composables/useSqlExecution.ts | 2 +- src/i18n/locales/en.ts | 8 ++ src/i18n/locales/zh-CN.ts | 8 ++ 8 files changed, 250 insertions(+), 5 deletions(-) create mode 100644 src/components/chart/QueryChart.vue diff --git a/package.json b/package.json index 184bba11be..904f585e7e 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "codemirror": "^6.0.2", + "echarts": "^6.0.0", "lucide-vue-next": "^1.0.0", "pinia": "^3.0.0", "reka-ui": "^2.9.6", @@ -45,6 +46,7 @@ "tailwind-merge": "^3.5.0", "tw-animate-css": "^1.4.0", "vue": "^3.5.0", + "vue-echarts": "^8.0.1", "vue-i18n": "^11.4.0", "vue-virtual-scroller": "^3.0.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fbb765f7ae..df391e2ad0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -74,6 +74,9 @@ importers: codemirror: specifier: ^6.0.2 version: 6.0.2 + echarts: + specifier: ^6.0.0 + version: 6.0.0 lucide-vue-next: specifier: ^1.0.0 version: 1.0.0(vue@3.5.33(typescript@5.6.3)) @@ -101,6 +104,9 @@ importers: vue: specifier: ^3.5.0 version: 3.5.33(typescript@5.6.3) + vue-echarts: + specifier: ^8.0.1 + version: 8.0.1(echarts@6.0.0)(vue@3.5.33(typescript@5.6.3)) vue-i18n: specifier: ^11.4.0 version: 11.4.0(vue@3.5.33(typescript@5.6.3)) @@ -1556,6 +1562,9 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + echarts@6.0.0: + resolution: {integrity: sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==} + eciesjs@0.4.18: resolution: {integrity: sha512-wG99Zcfcys9fZux7Cft8BAX/YrOJLJSZ3jyYPfhZHqN2E+Ffx+QXBDsv3gubEgPtV6dTzJMSQUwk1H98/t/0wQ==} engines: {bun: '>=1', deno: '>=2', node: '>=16'} @@ -2727,6 +2736,9 @@ packages: ts-morph@27.0.2: resolution: {integrity: sha512-fhUhgeljcrdZ+9DZND1De1029PrE+cMkIP7ooqkLRTrRLTqcki2AstsyJm0vRNbTbVCNJ0idGlbBrfqc7/nA8w==} + tslib@2.3.0: + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -2842,6 +2854,12 @@ packages: '@vue/composition-api': optional: true + vue-echarts@8.0.1: + resolution: {integrity: sha512-23rJTFLu1OUEGRWjJGmdGt8fP+8+ja1gVgzMYPIPaHWpXegcO1viIAaeu2H4QHESlVeHzUAHIxKXGrwjsyXAaA==} + peerDependencies: + echarts: ^6.0.0 + vue: ^3.3.0 + vue-eslint-parser@10.4.0: resolution: {integrity: sha512-Vxi9pJdbN3ZnVGLODVtZ7y4Y2kzAAE2Cm0CZ3ZDRvydVYxZ6VrnBhLikBsRS+dpwj4Jv4UCv21PTEwF5rQ9WXg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2940,6 +2958,9 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zrender@6.0.0: + resolution: {integrity: sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==} + snapshots: '@babel/code-frame@7.29.0': @@ -4277,6 +4298,11 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + echarts@6.0.0: + dependencies: + tslib: 2.3.0 + zrender: 6.0.0 + eciesjs@0.4.18: dependencies: '@ecies/ciphers': 0.2.6(@noble/ciphers@1.3.0) @@ -5529,6 +5555,8 @@ snapshots: '@ts-morph/common': 0.28.1 code-block-writer: 13.0.3 + tslib@2.3.0: {} + tslib@2.8.1: {} tw-animate-css@1.4.0: {} @@ -5595,6 +5623,11 @@ snapshots: dependencies: vue: 3.5.33(typescript@5.6.3) + vue-echarts@8.0.1(echarts@6.0.0)(vue@3.5.33(typescript@5.6.3)): + dependencies: + echarts: 6.0.0 + vue: 3.5.33(typescript@5.6.3) + vue-eslint-parser@10.4.0(eslint@10.2.1(jiti@2.6.1)): dependencies: debug: 4.4.3 @@ -5709,3 +5742,7 @@ snapshots: zod: 3.25.76 zod@3.25.76: {} + + zrender@6.0.0: + dependencies: + tslib: 2.3.0 diff --git a/src/App.vue b/src/App.vue index e4c455250e..470930ca18 100644 --- a/src/App.vue +++ b/src/App.vue @@ -71,7 +71,7 @@ const aiAssistantRef = ref | null>(null); const selectedSql = ref(""); const cursorPos = ref(0); const formatSqlRequestId = ref(0); -const activeOutputView = ref<"result" | "explain">("result"); +const activeOutputView = ref<"result" | "explain" | "chart">("result"); const activeTab = computed(() => queryStore.tabs.find((t) => t.id === queryStore.activeTabId)); diff --git a/src/components/chart/QueryChart.vue b/src/components/chart/QueryChart.vue new file mode 100644 index 0000000000..80f041747b --- /dev/null +++ b/src/components/chart/QueryChart.vue @@ -0,0 +1,167 @@ + + + diff --git a/src/components/layout/ContentArea.vue b/src/components/layout/ContentArea.vue index df0834ae99..8125716827 100644 --- a/src/components/layout/ContentArea.vue +++ b/src/components/layout/ContentArea.vue @@ -1,7 +1,7 @@