数据分析完成

This commit is contained in:
bunny 2025-05-27 23:29:36 +08:00
parent 065a05d9f4
commit 51cda5a8be
7 changed files with 175 additions and 126 deletions

View File

@ -102,6 +102,7 @@ export default defineFakeRoute([
message: '操作成功', message: '操作成功',
}), }),
}, },
// 数据占有率
{ {
url: `${BASE_URL}/data-ratio`, url: `${BASE_URL}/data-ratio`,
method: 'GET', method: 'GET',
@ -116,4 +117,31 @@ export default defineFakeRoute([
message: '操作成功', 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: '操作成功',
}),
},
]); ]);

View File

@ -29,3 +29,13 @@ export const getRegionSalesRatio = () => {
export const getDataRatio = () => { export const getDataRatio = () => {
return request.get('data-analyse/data-ratio'); 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');
};

View File

@ -3,8 +3,10 @@ import { defineStore } from 'pinia';
import { import {
getBrandsDistribution, getBrandsDistribution,
getCompanySalesDistribution, getCompanySalesDistribution,
getDataAnalyse,
getDataRatio, getDataRatio,
getDataShow, getDataShow,
getDataShowStatistics,
getDeviceSalesStats, getDeviceSalesStats,
getRegionSalesRatio, getRegionSalesRatio,
} from '@/api/dataAnalyse'; } from '@/api/dataAnalyse';
@ -28,6 +30,10 @@ export const useDataAnalyseStore = defineStore('dataAnalyseStore', {
regionSalesRatio: [], regionSalesRatio: [],
// 数据占有率 // 数据占有率
dataRatio: [], dataRatio: [],
// 数据分析展示
dataAnalyse: [],
// 数据展示统计
dataShowStatistics: [],
}), }),
actions: { actions: {
/* 销售设备总量 */ /* 销售设备总量 */
@ -59,6 +65,16 @@ export const useDataAnalyseStore = defineStore('dataAnalyseStore', {
async fetchDataRatio() { async fetchDataRatio() {
this.dataRatio = await getDataRatio(); this.dataRatio = await getDataRatio();
}, },
/* 数据分析展示 */
async fetchDataAnalyse() {
this.dataAnalyse = await getDataAnalyse();
},
/* 数据展示统计 */
async fetchDataShowStatistics() {
this.dataShowStatistics = await getDataShowStatistics();
},
}, },
}); });

View File

@ -32,37 +32,19 @@ const option: EChartsOption = {
right: 10, right: 10,
itemGap: 34, itemGap: 34,
}, },
xAxis: { xAxis: {
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], data: [],
type: 'category', type: 'category',
boundaryGap: false, boundaryGap: false,
axisLine: { axisLine: { symbol: 'none', lineStyle: { color: '#50637A' } },
symbol: 'none',
lineStyle: {
color: '#50637A',
},
},
axisTick: { show: false }, axisTick: { show: false },
axisLabel: { axisLabel: { interval: 0, color: '#fff', fontSize: 12, padding: [10, 0, 0, 0] },
interval: 0,
color: '#6071A9',
fontSize: 12,
padding: [10, 0, 0, 0],
},
}, },
yAxis: { yAxis: {
type: 'value', type: 'value',
axisLabel: { axisLabel: { color: '#fff', fontSize: 12, padding: [0, 10, 0, 0] },
color: '#6071A9',
fontSize: 12,
padding: [0, 10, 0, 0],
},
splitLine: { splitLine: {
lineStyle: { lineStyle: { color: '#50637A', type: 'dashed' },
color: '#50637A',
type: 'dashed',
},
}, },
}, },
series: [ series: [
@ -72,9 +54,7 @@ const option: EChartsOption = {
type: 'line', type: 'line',
// smooth: true, // smooth: true,
color: '#00F7FF', color: '#00F7FF',
lineStyle: { lineStyle: { width: 2 },
width: 2,
},
areaStyle: { areaStyle: {
color: new echarts.graphic.LinearGradient( color: new echarts.graphic.LinearGradient(
0, 0,
@ -115,7 +95,10 @@ export const renderFooterChart = (element: Ref<HTMLDivElement>) => {
/** 更新图表数据 */ /** 更新图表数据 */
export const updateChart = (data: any) => { export const updateChart = (data: any) => {
const xAxis = myChart.getOption().xAxis;
xAxis[0].data = data.map((item: any) => item.name);
const series = myChart.getOption().series; const series = myChart.getOption().series;
series[0].data = data; series[0].data = data;
myChart.setOption({ series }); myChart.setOption({ xAxis, series });
}; };

View File

@ -4,102 +4,93 @@ import type { Ref } from 'vue';
import echarts from '@/plugins/echarts'; import echarts from '@/plugins/echarts';
import { debounceChart } from '@/utils/chart'; 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; let myChart = null;
const option: EChartsOption = { const option: EChartsOption = {
grid: { tooltip: { trigger: 'axis' },
left: '4%',
right: '4%',
bottom: '19%',
top: '20%',
containLabel: true,
},
title: { title: {
text: '单位:(万元)', text: '单位:(万元)',
textStyle: { color: '#83A2C0FF', fontSize: 12 }, textStyle: { color: '#83A2C0FF', fontSize: 12 },
top: '4%', top: '4%',
left: '2%', left: '2%',
}, },
tooltip: { trigger: 'axis' }, grid: {
legend: { left: '9%',
show: false, right: '2%',
data: ['增加值'], bottom: '9%',
icon: 'rich', top: '19%',
itemWidth: 18, containLabel: false,
itemHeight: 2,
textStyle: { color: '#AFBDD1', fontSize: '12px' },
top: 8,
right: 10,
itemGap: 34,
}, },
xAxis: { xAxis: {
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], data: [],
type: 'category', type: 'category',
boundaryGap: false, // boundaryGap: false,
axisLine: { axisLine: { symbol: 'none', lineStyle: { color: '#50637A' } },
symbol: 'none',
lineStyle: {
color: '#50637A',
},
},
axisTick: { show: false }, axisTick: { show: false },
axisLabel: { axisLabel: { interval: 0, color: '#fff', fontSize: 12 },
interval: 0,
color: '#6071A9',
fontSize: 12,
padding: [10, 0, 0, 0],
},
}, },
yAxis: { yAxis: {
type: 'value', type: 'value',
axisLabel: { axisLabel: { color: '#fff', fontSize: 12 },
color: '#6071A9', splitLine: { lineStyle: { color: '#50637A', type: 'dashed' } },
fontSize: 12,
padding: [0, 10, 0, 0],
},
splitLine: {
lineStyle: {
color: '#50637A',
type: 'dashed',
},
},
}, },
series: [ series: [
{ {
name: '增加值', name: '数据分析',
data: [], data: [],
type: 'line', type: 'pictorialBar',
// smooth: true,
color: '#00F7FF', color: '#00F7FF',
lineStyle: { barWidth: 40,
width: 2, symbol: 'triangle',
}, label: { show: true, position: 'top', color: '#fff' },
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,
}, },
], ],
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<HTMLDivElement>) => {
renderer: 'canvas', renderer: 'canvas',
devicePixelRatio: window.devicePixelRatio, devicePixelRatio: window.devicePixelRatio,
}); });
debounceChart(myChart); debounceChart(myChart);
myChart.setOption(option); myChart.setOption(option);
}; };
/** 更新图表数据 */ /** 更新图表数据 */
export const updateChart = (option: Array<Array<number>>) => { export const updateBodyChart = (data: any) => {
const xAxis = myChart.getOption().xAxis;
xAxis[0].data = data.map((item: any) => item.name);
const series = myChart.getOption().series; const series = myChart.getOption().series;
// series[0].data = option[0]; series[0].data = data;
// series[1].data = option[1]; myChart.setOption({ xAxis, series });
myChart.setOption({ series });
}; };

View File

@ -4,26 +4,16 @@ import echarts from '@/plugins/echarts';
import { debounceChart } from '@/utils/chart'; import { debounceChart } from '@/utils/chart';
let myChart = null; 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 = { const option = {
title: { title: {
text: '34467', text: '34467',
subtext: '历史预警数',
left: 'center', left: 'center',
top: 'center', top: 'center',
textStyle: { color: '#fff', fontSize: 34 }, textStyle: { color: '#fff', fontSize: 19 },
subtextStyle: { color: '#fff', fontSize: 16 },
}, },
grid: { containLabel: false }, grid: { containLabel: false },
polar: { radius: [60, '100%'] }, polar: { radius: [40, '90%'] },
angleAxis: { show: false, startAngle: 90 }, angleAxis: { show: false, startAngle: 90 },
radiusAxis: { show: false, type: 'category' }, radiusAxis: { show: false, type: 'category' },
tooltip: {}, tooltip: {},
@ -31,10 +21,23 @@ const option = {
type: 'bar', type: 'bar',
data: [], data: [],
barWidth: 20, barWidth: 20,
barGap: 0, barGap: 9,
coordinateSystem: 'polar', coordinateSystem: 'polar',
label: { show: true, position: 'middle' }, 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<HTMLDivElement>) => {
}; };
/** 更新图表数据 */ /** 更新图表数据 */
export const updateChart = (option: Array<Array<number>>) => { export const updateFooterChart = (data: any) => {
const series = myChart.getOption().series; const series = myChart.getOption().series;
// series[0].data = option[0]; series[0].data = data.map((item: any) => ({
// series[1].data = option[1]; name: item.name,
myChart.setOption({ series }); 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 });
}; };

View File

@ -4,8 +4,8 @@ import { storeToRefs } from 'pinia';
import { onMounted, ref } from 'vue'; import { onMounted, ref } from 'vue';
import { useDataAnalyseHook } from '@/store/modules/dataAnalyse'; import { useDataAnalyseHook } from '@/store/modules/dataAnalyse';
import { renderBodyChart } from '@/views/data-analyse/charts/right-body'; import { renderBodyChart, updateBodyChart } from '@/views/data-analyse/charts/right-body';
import { renderFooterChart } from '@/views/data-analyse/charts/right-footer'; import { renderFooterChart, updateFooterChart } from '@/views/data-analyse/charts/right-footer';
import { renderTopChart, updateTopChart } from '@/views/data-analyse/charts/right-top'; import { renderTopChart, updateTopChart } from '@/views/data-analyse/charts/right-top';
import PanelTitle from '@/views/data-analyse/components/PanelTitle.vue'; import PanelTitle from '@/views/data-analyse/components/PanelTitle.vue';
@ -14,7 +14,7 @@ const bodyChartRef = ref();
const footerChartRef = ref(); const footerChartRef = ref();
const dataAnalyseHook = useDataAnalyseHook(); const dataAnalyseHook = useDataAnalyseHook();
const { dataRatio } = storeToRefs(dataAnalyseHook); const { dataRatio, dataAnalyse, dataShowStatistics } = storeToRefs(dataAnalyseHook);
/* 渲染图表 */ /* 渲染图表 */
const renderChart = () => { const renderChart = () => {
@ -26,12 +26,23 @@ const renderChart = () => {
const initAppData = async () => { const initAppData = async () => {
await dataAnalyseHook.fetchDataRatio(); await dataAnalyseHook.fetchDataRatio();
updateTopChart(dataRatio.value); updateTopChart(dataRatio.value);
//
await dataAnalyseHook.fetchDataAnalyse();
updateBodyChart(dataAnalyse.value);
//
await dataAnalyseHook.fetchDataShowStatistics();
updateFooterChart(dataShowStatistics.value);
}; };
onMounted(() => { onMounted(() => {
//
renderChart(); renderChart();
//
initAppData(); initAppData();
//
useIntervalFn(() => { useIntervalFn(() => {
initAppData(); initAppData();
}, 10000); }, 10000);
@ -91,6 +102,7 @@ onMounted(() => {
height: 257px; height: 257px;
&-chart { &-chart {
margin: 19px 0 0 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }