From 51cda5a8be8261ee374e5fd729e2699ea067dd9e Mon Sep 17 00:00:00 2001 From: bunny <1319900154@qq.com> Date: Tue, 27 May 2025 23:29:36 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E6=95=B0=E6=8D=AE=E5=88=86?= =?UTF-8?q?=E6=9E=90=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mock/data-analyse.ts | 28 ++++ src/api/dataAnalyse.ts | 10 ++ src/store/modules/dataAnalyse.ts | 16 ++ .../data-analyse/charts/content-footer.ts | 37 ++--- src/views/data-analyse/charts/right-body.ts | 149 ++++++++---------- src/views/data-analyse/charts/right-footer.ts | 43 +++-- .../components/data-analyse-right.vue | 18 ++- 7 files changed, 175 insertions(+), 126 deletions(-) diff --git a/mock/data-analyse.ts b/mock/data-analyse.ts index 4fca254..6d11449 100644 --- a/mock/data-analyse.ts +++ b/mock/data-analyse.ts @@ -102,6 +102,7 @@ export default defineFakeRoute([ message: '操作成功', }), }, + // 数据占有率 { url: `${BASE_URL}/data-ratio`, method: 'GET', @@ -116,4 +117,31 @@ export default defineFakeRoute([ message: '操作成功', }), }, + // 数据分析展示 + { + url: `${BASE_URL}/data-analyse`, + method: 'GET', + response: () => ({ + code: 200, + data: Array(5) + .fill(0) + .map((_, index) => ({ + name: `品牌${index + 1}`, + value: randomNumber(999), + })), + message: '操作成功', + }), + }, + // 数据展示统计 + { + url: `${BASE_URL}/data-show-statistics`, + method: 'GET', + response: () => ({ + code: 200, + data: Array(6) + .fill(0) + .map((_, index) => ({ name: `数据展示${index + 1}`, value: randomNumber() })), + message: '操作成功', + }), + }, ]); diff --git a/src/api/dataAnalyse.ts b/src/api/dataAnalyse.ts index b315486..5ec895e 100644 --- a/src/api/dataAnalyse.ts +++ b/src/api/dataAnalyse.ts @@ -29,3 +29,13 @@ export const getRegionSalesRatio = () => { export const getDataRatio = () => { return request.get('data-analyse/data-ratio'); }; + +/* 数据分析展示 */ +export const getDataAnalyse = () => { + return request.get('data-analyse/data-analyse'); +}; + +/* 数据展示统计 */ +export const getDataShowStatistics = () => { + return request.get('data-analyse/data-show-statistics'); +}; diff --git a/src/store/modules/dataAnalyse.ts b/src/store/modules/dataAnalyse.ts index e80060c..c8ea4f2 100644 --- a/src/store/modules/dataAnalyse.ts +++ b/src/store/modules/dataAnalyse.ts @@ -3,8 +3,10 @@ import { defineStore } from 'pinia'; import { getBrandsDistribution, getCompanySalesDistribution, + getDataAnalyse, getDataRatio, getDataShow, + getDataShowStatistics, getDeviceSalesStats, getRegionSalesRatio, } from '@/api/dataAnalyse'; @@ -28,6 +30,10 @@ export const useDataAnalyseStore = defineStore('dataAnalyseStore', { regionSalesRatio: [], // 数据占有率 dataRatio: [], + // 数据分析展示 + dataAnalyse: [], + // 数据展示统计 + dataShowStatistics: [], }), actions: { /* 销售设备总量 */ @@ -59,6 +65,16 @@ export const useDataAnalyseStore = defineStore('dataAnalyseStore', { async fetchDataRatio() { this.dataRatio = await getDataRatio(); }, + + /* 数据分析展示 */ + async fetchDataAnalyse() { + this.dataAnalyse = await getDataAnalyse(); + }, + + /* 数据展示统计 */ + async fetchDataShowStatistics() { + this.dataShowStatistics = await getDataShowStatistics(); + }, }, }); diff --git a/src/views/data-analyse/charts/content-footer.ts b/src/views/data-analyse/charts/content-footer.ts index a8e9ccd..cee2b99 100644 --- a/src/views/data-analyse/charts/content-footer.ts +++ b/src/views/data-analyse/charts/content-footer.ts @@ -32,37 +32,19 @@ const option: EChartsOption = { right: 10, itemGap: 34, }, - xAxis: { - data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + data: [], type: 'category', boundaryGap: false, - axisLine: { - symbol: 'none', - lineStyle: { - color: '#50637A', - }, - }, + axisLine: { symbol: 'none', lineStyle: { color: '#50637A' } }, axisTick: { show: false }, - axisLabel: { - interval: 0, - color: '#6071A9', - fontSize: 12, - padding: [10, 0, 0, 0], - }, + axisLabel: { interval: 0, color: '#fff', fontSize: 12, padding: [10, 0, 0, 0] }, }, yAxis: { type: 'value', - axisLabel: { - color: '#6071A9', - fontSize: 12, - padding: [0, 10, 0, 0], - }, + axisLabel: { color: '#fff', fontSize: 12, padding: [0, 10, 0, 0] }, splitLine: { - lineStyle: { - color: '#50637A', - type: 'dashed', - }, + lineStyle: { color: '#50637A', type: 'dashed' }, }, }, series: [ @@ -72,9 +54,7 @@ const option: EChartsOption = { type: 'line', // smooth: true, color: '#00F7FF', - lineStyle: { - width: 2, - }, + lineStyle: { width: 2 }, areaStyle: { color: new echarts.graphic.LinearGradient( 0, @@ -115,7 +95,10 @@ export const renderFooterChart = (element: Ref) => { /** 更新图表数据 */ export const updateChart = (data: any) => { + const xAxis = myChart.getOption().xAxis; + xAxis[0].data = data.map((item: any) => item.name); + const series = myChart.getOption().series; series[0].data = data; - myChart.setOption({ series }); + myChart.setOption({ xAxis, series }); }; diff --git a/src/views/data-analyse/charts/right-body.ts b/src/views/data-analyse/charts/right-body.ts index d1d04c2..8bb9830 100644 --- a/src/views/data-analyse/charts/right-body.ts +++ b/src/views/data-analyse/charts/right-body.ts @@ -4,102 +4,93 @@ import type { Ref } from 'vue'; import echarts from '@/plugins/echarts'; import { debounceChart } from '@/utils/chart'; +const getLinearGradient = (color1: string, color2: string): any => { + return new echarts.graphic.LinearGradient( + 0, + 0, + 0, + 1, + [ + { offset: 0, color: color1 }, + { offset: 0.8, color: color2 }, + ], + false + ); +}; let myChart = null; const option: EChartsOption = { - grid: { - left: '4%', - right: '4%', - bottom: '19%', - top: '20%', - containLabel: true, - }, + tooltip: { trigger: 'axis' }, title: { text: '单位:(万元)', textStyle: { color: '#83A2C0FF', fontSize: 12 }, top: '4%', left: '2%', }, - tooltip: { trigger: 'axis' }, - legend: { - show: false, - data: ['增加值'], - icon: 'rich', - itemWidth: 18, - itemHeight: 2, - textStyle: { color: '#AFBDD1', fontSize: '12px' }, - top: 8, - right: 10, - itemGap: 34, + grid: { + left: '9%', + right: '2%', + bottom: '9%', + top: '19%', + containLabel: false, }, - xAxis: { - data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + data: [], type: 'category', - boundaryGap: false, - axisLine: { - symbol: 'none', - lineStyle: { - color: '#50637A', - }, - }, + // boundaryGap: false, + axisLine: { symbol: 'none', lineStyle: { color: '#50637A' } }, axisTick: { show: false }, - axisLabel: { - interval: 0, - color: '#6071A9', - fontSize: 12, - padding: [10, 0, 0, 0], - }, + axisLabel: { interval: 0, color: '#fff', fontSize: 12 }, }, yAxis: { type: 'value', - axisLabel: { - color: '#6071A9', - fontSize: 12, - padding: [0, 10, 0, 0], - }, - splitLine: { - lineStyle: { - color: '#50637A', - type: 'dashed', - }, - }, + axisLabel: { color: '#fff', fontSize: 12 }, + splitLine: { lineStyle: { color: '#50637A', type: 'dashed' } }, }, series: [ { - name: '增加值', + name: '数据分析', data: [], - type: 'line', - // smooth: true, + type: 'pictorialBar', color: '#00F7FF', - lineStyle: { - width: 2, - }, - areaStyle: { - color: new echarts.graphic.LinearGradient( - 0, - 0, - 0, - 1, - [ - { - offset: 0, - color: 'rgba(0, 247, 255, .6)', - }, - { - offset: 0.8, - color: 'rgba(0, 247, 255, .2)', - }, - ], - false - ), - shadowColor: 'rgba(0, 0, 0, 0.1)', - shadowBlur: 10, - }, - symbol: 'circle', - symbolSize: 6, + barWidth: 40, + symbol: 'triangle', + label: { show: true, position: 'top', color: '#fff' }, }, ], + visualMap: { + show: false, + showLabel: false, + type: 'piecewise', + pieces: [ + { min: 0, max: 100, label: '低', color: getLinearGradient('#FF6363', 'rgba(255,99,99,0.2)') }, + { + min: 100, + max: 300, + label: '低中', + color: getLinearGradient('#FFCC00', 'rgba(255,204,0,0.2)'), + }, + { + min: 300, + max: 500, + label: '中', + color: getLinearGradient('#00FFFF', 'rgba(0,255,255,0.2)'), + }, + { + min: 500, + max: 700, + label: '中高', + color: getLinearGradient('#00CCFF', 'rgba(0,204,255,0.2)'), + }, + { + min: 700, + max: 1000, + label: '高', + color: getLinearGradient('#0096FF', 'rgba(0,150,255,0.2)'), + }, + ], + seriesIndex: 0, + }, }; /** 渲染图表 */ @@ -108,16 +99,16 @@ export const renderBodyChart = (element: Ref) => { renderer: 'canvas', devicePixelRatio: window.devicePixelRatio, }); - debounceChart(myChart); - myChart.setOption(option); }; /** 更新图表数据 */ -export const updateChart = (option: Array>) => { +export const updateBodyChart = (data: any) => { + const xAxis = myChart.getOption().xAxis; + xAxis[0].data = data.map((item: any) => item.name); + const series = myChart.getOption().series; - // series[0].data = option[0]; - // series[1].data = option[1]; - myChart.setOption({ series }); + series[0].data = data; + myChart.setOption({ xAxis, series }); }; diff --git a/src/views/data-analyse/charts/right-footer.ts b/src/views/data-analyse/charts/right-footer.ts index 14e7312..5e901b7 100644 --- a/src/views/data-analyse/charts/right-footer.ts +++ b/src/views/data-analyse/charts/right-footer.ts @@ -4,26 +4,16 @@ import echarts from '@/plugins/echarts'; import { debounceChart } from '@/utils/chart'; let myChart = null; -const data = [ - { name: '张三', value: 88 }, - { name: '李四', value: 250 }, - { name: '王五', value: 5438 }, - { name: '赵六', value: 8848 }, - { name: '陈七', value: 9527 }, - { name: '朱八', value: 10086 }, -]; const option = { title: { text: '34467', - subtext: '历史预警数', left: 'center', top: 'center', - textStyle: { color: '#fff', fontSize: 34 }, - subtextStyle: { color: '#fff', fontSize: 16 }, + textStyle: { color: '#fff', fontSize: 19 }, }, grid: { containLabel: false }, - polar: { radius: [60, '100%'] }, + polar: { radius: [40, '90%'] }, angleAxis: { show: false, startAngle: 90 }, radiusAxis: { show: false, type: 'category' }, tooltip: {}, @@ -31,10 +21,23 @@ const option = { type: 'bar', data: [], barWidth: 20, - barGap: 0, + barGap: 9, coordinateSystem: 'polar', label: { show: true, position: 'middle' }, }, + visualMap: { + show: false, + showLabel: false, + type: 'piecewise', + pieces: [ + { min: 0, max: 20, label: '低', color: '#FF6363' }, + { min: 20, max: 30, label: '低中', color: '#FFCC00' }, + { min: 30, max: 50, label: '中', color: '#00FFFF' }, + { min: 50, max: 70, label: '中高', color: '#00CCFF' }, + { min: 70, max: 100, label: '高', color: '#0096FF' }, + ], + seriesIndex: 0, + }, }; /** 渲染图表 */ @@ -50,9 +53,15 @@ export const renderFooterChart = (element: Ref) => { }; /** 更新图表数据 */ -export const updateChart = (option: Array>) => { +export const updateFooterChart = (data: any) => { const series = myChart.getOption().series; - // series[0].data = option[0]; - // series[1].data = option[1]; - myChart.setOption({ series }); + series[0].data = data.map((item: any) => ({ + name: item.name, + value: item.value, + })); + + const total = data?.reduce((old, item) => old + item.value, 0); + const title = myChart?.getOption()?.title; + title[0].text = total; + myChart.setOption({ title, series }); }; diff --git a/src/views/data-analyse/components/data-analyse-right.vue b/src/views/data-analyse/components/data-analyse-right.vue index 274bd9f..4b21ff4 100644 --- a/src/views/data-analyse/components/data-analyse-right.vue +++ b/src/views/data-analyse/components/data-analyse-right.vue @@ -4,8 +4,8 @@ import { storeToRefs } from 'pinia'; import { onMounted, ref } from 'vue'; import { useDataAnalyseHook } from '@/store/modules/dataAnalyse'; -import { renderBodyChart } from '@/views/data-analyse/charts/right-body'; -import { renderFooterChart } from '@/views/data-analyse/charts/right-footer'; +import { renderBodyChart, updateBodyChart } from '@/views/data-analyse/charts/right-body'; +import { renderFooterChart, updateFooterChart } from '@/views/data-analyse/charts/right-footer'; import { renderTopChart, updateTopChart } from '@/views/data-analyse/charts/right-top'; import PanelTitle from '@/views/data-analyse/components/PanelTitle.vue'; @@ -14,7 +14,7 @@ const bodyChartRef = ref(); const footerChartRef = ref(); const dataAnalyseHook = useDataAnalyseHook(); -const { dataRatio } = storeToRefs(dataAnalyseHook); +const { dataRatio, dataAnalyse, dataShowStatistics } = storeToRefs(dataAnalyseHook); /* 渲染图表 */ const renderChart = () => { @@ -26,12 +26,23 @@ const renderChart = () => { const initAppData = async () => { await dataAnalyseHook.fetchDataRatio(); updateTopChart(dataRatio.value); + + // 更新中间图表 + await dataAnalyseHook.fetchDataAnalyse(); + updateBodyChart(dataAnalyse.value); + + // 数据展示统计 + await dataAnalyseHook.fetchDataShowStatistics(); + updateFooterChart(dataShowStatistics.value); }; onMounted(() => { + // 渲染图表 renderChart(); + // 获取图表的数据 initAppData(); + // 定时更新 useIntervalFn(() => { initAppData(); }, 10000); @@ -91,6 +102,7 @@ onMounted(() => { height: 257px; &-chart { + margin: 19px 0 0 0; width: 100%; height: 100%; }