✨ 大数据可视化
This commit is contained in:
parent
fb6b427430
commit
dafb9b9db7
|
@ -4,9 +4,9 @@ import vueJsx from '@vitejs/plugin-vue-jsx';
|
||||||
import { presetIcons } from 'unocss';
|
import { presetIcons } from 'unocss';
|
||||||
import UnoCSS from 'unocss/vite';
|
import UnoCSS from 'unocss/vite';
|
||||||
import type { PluginOption } from 'vite';
|
import type { PluginOption } from 'vite';
|
||||||
// @ts-ignore
|
|
||||||
import { vitePluginFakeServer } from 'vite-plugin-fake-server';
|
import { vitePluginFakeServer } from 'vite-plugin-fake-server';
|
||||||
import removeConsole from 'vite-plugin-remove-console';
|
import removeConsole from 'vite-plugin-remove-console';
|
||||||
|
import vueDevTools from 'vite-plugin-vue-devtools';
|
||||||
import Inspector from 'vite-plugin-vue-inspector';
|
import Inspector from 'vite-plugin-vue-inspector';
|
||||||
|
|
||||||
import { useCDN } from './cdn';
|
import { useCDN } from './cdn';
|
||||||
|
@ -20,6 +20,7 @@ export const plugins = (mode: string): PluginOption[] => {
|
||||||
Inspector(),
|
Inspector(),
|
||||||
report(),
|
report(),
|
||||||
removeConsole(),
|
removeConsole(),
|
||||||
|
vueDevTools(),
|
||||||
useCDN(mode),
|
useCDN(mode),
|
||||||
viteConsoleLog(mode),
|
viteConsoleLog(mode),
|
||||||
UnoCSS({
|
UnoCSS({
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
import { defineFakeRoute } from 'vite-plugin-fake-server';
|
||||||
|
|
||||||
|
const BASE_URL = '/api/big-data';
|
||||||
|
|
||||||
|
const randomNumber = (range: number = 100) => {
|
||||||
|
return parseInt((Math.random() * range).toFixed(0));
|
||||||
|
};
|
||||||
|
|
||||||
|
export default defineFakeRoute([
|
||||||
|
// 规模效益
|
||||||
|
{
|
||||||
|
url: `${BASE_URL}/scale-benfit`,
|
||||||
|
method: 'GET',
|
||||||
|
response: () => ({
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
total: randomNumber(200),
|
||||||
|
income: randomNumber(999999999),
|
||||||
|
incomeChain: randomNumber(150),
|
||||||
|
expend: randomNumber(999999999),
|
||||||
|
expendChain: randomNumber(150),
|
||||||
|
},
|
||||||
|
message: '操作成功',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
// 经营收入
|
||||||
|
{
|
||||||
|
url: `${BASE_URL}/year-income`,
|
||||||
|
method: 'GET',
|
||||||
|
response: () => ({
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
list: Array(4)
|
||||||
|
.fill(0)
|
||||||
|
.map((_, index) => ({
|
||||||
|
title: `经营总收入-${index + 1}`,
|
||||||
|
amount: randomNumber(9999999),
|
||||||
|
percent: randomNumber(),
|
||||||
|
})),
|
||||||
|
endTime: new Date().getTime(),
|
||||||
|
},
|
||||||
|
message: '操作成功',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
// 园区规划
|
||||||
|
{
|
||||||
|
url: `${BASE_URL}/chart-plan`,
|
||||||
|
method: 'GET',
|
||||||
|
response: () => ({
|
||||||
|
code: 200,
|
||||||
|
data: [
|
||||||
|
Array(12)
|
||||||
|
.fill(0)
|
||||||
|
.map(() => {
|
||||||
|
const num = randomNumber().toFixed(2);
|
||||||
|
return parseInt(num);
|
||||||
|
}),
|
||||||
|
Array(12)
|
||||||
|
.fill(0)
|
||||||
|
.map(() => {
|
||||||
|
const num = randomNumber().toFixed(2);
|
||||||
|
return parseInt(num);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
message: '操作成功',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
// 税收概览
|
||||||
|
{
|
||||||
|
url: `${BASE_URL}/revenue-overview`,
|
||||||
|
method: 'GET',
|
||||||
|
response: () => ({
|
||||||
|
code: 200,
|
||||||
|
data: Array(12)
|
||||||
|
.fill(0)
|
||||||
|
.map(() => randomNumber(9999)),
|
||||||
|
message: '操作成功',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
// 园区进出口额
|
||||||
|
{
|
||||||
|
url: `${BASE_URL}/parks/import-export`,
|
||||||
|
method: 'GET',
|
||||||
|
response: () => ({
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
amount: randomNumber(99999999),
|
||||||
|
import: randomNumber(99999),
|
||||||
|
export: randomNumber(99999),
|
||||||
|
},
|
||||||
|
message: '操作成功',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
// 企业信息
|
||||||
|
{
|
||||||
|
url: `${BASE_URL}/enterprise-info`,
|
||||||
|
method: 'GET',
|
||||||
|
response: () => ({
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
// 报税金额
|
||||||
|
taxAmount: randomNumber(999999),
|
||||||
|
// 税收总金额
|
||||||
|
taxTotalAmount: randomNumber(99999),
|
||||||
|
// 企业数量
|
||||||
|
enterpriseCount: randomNumber(9999),
|
||||||
|
// 国营企业(强调国家控股)
|
||||||
|
stateOwnedEnterprise: randomNumber(9999),
|
||||||
|
// 私营企业
|
||||||
|
privateEnterprise: randomNumber(9999),
|
||||||
|
// 投资总金额
|
||||||
|
investmentTotal: randomNumber(10000),
|
||||||
|
},
|
||||||
|
message: '操作成功',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
// 园区规划
|
||||||
|
{
|
||||||
|
url: `${BASE_URL}/parks/areas`,
|
||||||
|
method: 'GET',
|
||||||
|
response: () => ({
|
||||||
|
code: 200,
|
||||||
|
data: Array(9)
|
||||||
|
.fill(0)
|
||||||
|
.map(() => ({
|
||||||
|
title: randomNumber(99999.99),
|
||||||
|
summary: '建成投产面积',
|
||||||
|
})),
|
||||||
|
message: '操作成功',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
]);
|
|
@ -8,6 +8,8 @@
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"report": "rimraf dist && vite build",
|
"report": "rimraf dist && vite build",
|
||||||
|
"lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock,build}/**/*.{vue,js,ts,tsx}\" --fix",
|
||||||
|
"lint:prettier": "prettier --write \"src/**/*.{js,ts,json,tsx,css,scss,vue,html,md}\"",
|
||||||
"lint:stylelint": "stylelint --cache --fix \"**/*.{html,vue,css,scss}\" --cache-location node_modules/.cache/stylelint/",
|
"lint:stylelint": "stylelint --cache --fix \"**/*.{html,vue,css,scss}\" --cache-location node_modules/.cache/stylelint/",
|
||||||
"lint": "pnpm lint:eslint && pnpm lint:prettier && pnpm lint:stylelint"
|
"lint": "pnpm lint:eslint && pnpm lint:prettier && pnpm lint:stylelint"
|
||||||
},
|
},
|
||||||
|
@ -57,7 +59,7 @@
|
||||||
"vite-plugin-fake-server": "^2.2.0",
|
"vite-plugin-fake-server": "^2.2.0",
|
||||||
"vite-plugin-remove-console": "^2.2.0",
|
"vite-plugin-remove-console": "^2.2.0",
|
||||||
"vite-plugin-vue-inspector": "^5.3.1",
|
"vite-plugin-vue-inspector": "^5.3.1",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.14",
|
||||||
"vue-demi": "^0.14.10",
|
"vue-demi": "^0.14.10",
|
||||||
"vue-eslint-parser": "^9.4.3",
|
"vue-eslint-parser": "^9.4.3",
|
||||||
"vue-router": "^4.4.3",
|
"vue-router": "^4.4.3",
|
||||||
|
@ -73,7 +75,9 @@
|
||||||
"typescript": "~5.7.2",
|
"typescript": "~5.7.2",
|
||||||
"vite": "6.2.6",
|
"vite": "6.2.6",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vue-tsc": "^2.2.0"
|
"vue-tsc": "^2.2.0",
|
||||||
|
"vite-plugin-vue-devtools": "^7.7.2",
|
||||||
|
"jiti": "^2.4.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0",
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0",
|
||||||
|
|
582
pnpm-lock.yaml
582
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
||||||
|
git checkout master
|
||||||
|
git merge dev
|
||||||
|
git push --all
|
||||||
|
git push --tags
|
||||||
|
git checkout dev
|
|
@ -0,0 +1,36 @@
|
||||||
|
import request from '@/api/server/request';
|
||||||
|
|
||||||
|
/* 规模效益 */
|
||||||
|
export const getScaleProfit = (data: any) => {
|
||||||
|
return request.get('big-data/scale-benfit', { params: data });
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 规模效益 */
|
||||||
|
export const getYearIncome = () => {
|
||||||
|
return request.get('big-data/year-income');
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 园区规划 */
|
||||||
|
export const getParkPlan = () => {
|
||||||
|
return request.get('big-data/chart-plan');
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 税收概览 */
|
||||||
|
export const getRevenueOverView = () => {
|
||||||
|
return request.get('big-data/revenue-overview');
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 园区进出口额 */
|
||||||
|
export const getParkImportExportData = (params: any) => {
|
||||||
|
return request.get('big-data/parks/import-export', { params });
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 企业信息 */
|
||||||
|
export const getEnterpriseInfo = () => {
|
||||||
|
return request.get('big-data/enterprise-info');
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 园区规划 */
|
||||||
|
export const getParkAreas = () => {
|
||||||
|
return request.get('big-data/parks/areas');
|
||||||
|
};
|
|
@ -12,10 +12,11 @@ export default defineComponent({
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props, { slots }) {
|
||||||
return () => (
|
return () => (
|
||||||
<div className={'mb-[20px]'}>
|
<div className={'mb-[20px]'}>
|
||||||
{(props.separator ? formatter(props.money) : props.money.toString())
|
{slots.default?.()}
|
||||||
|
{(props.separator ? formatter(props.money ?? 0) : props.money.toString())
|
||||||
.split(/(\d,)/g)
|
.split(/(\d,)/g)
|
||||||
.filter((item) => item !== '')
|
.filter((item) => item !== '')
|
||||||
.map((item) => (!item.includes(',') ? item.split('') : item))
|
.map((item) => (!item.includes(',') ? item.split('') : item))
|
||||||
|
@ -23,7 +24,6 @@ export default defineComponent({
|
||||||
.map((item, index) => (
|
.map((item, index) => (
|
||||||
<span key={index}>{item}</span>
|
<span key={index}>{item}</span>
|
||||||
))}
|
))}
|
||||||
{/* {moneyStringList.value?.map((item, index) => <span key={index}>{item}</span>)} */}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,11 +3,21 @@ import { TimeSelectType } from '@/components/TimeSelect/type';
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
timeList: Array<TimeSelectType>,
|
timeList: Array<TimeSelectType>,
|
||||||
|
modelValue: String,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'update:modelValue', value: string): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const handleChange = (e: Event) => {
|
||||||
|
const value = (e.target as HTMLSelectElement).value;
|
||||||
|
emit('update:modelValue', value); // 触发 v-model 更新
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<select class="time-select" name="timeSelect">
|
<select class="time-select" :value="modelValue" @change="handleChange">
|
||||||
<option v-for="(item, index) in timeList" :key="index" :value="item.value">
|
<option v-for="(item, index) in timeList" :key="index" :value="item.value">
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</option>
|
</option>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export interface TimeSelectType {
|
export interface TimeSelectType {
|
||||||
value: string | number;
|
value: string;
|
||||||
label: string | number;
|
label: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
|
||||||
|
import {
|
||||||
|
getEnterpriseInfo,
|
||||||
|
getParkAreas,
|
||||||
|
getParkImportExportData,
|
||||||
|
getParkPlan,
|
||||||
|
getRevenueOverView,
|
||||||
|
getScaleProfit,
|
||||||
|
getYearIncome,
|
||||||
|
} from '@/api/bigData';
|
||||||
|
|
||||||
|
export const useBigDataStore = defineStore('bidDataStore', {
|
||||||
|
state: () => ({
|
||||||
|
// 规模效益
|
||||||
|
scaleProfit: {
|
||||||
|
total: undefined,
|
||||||
|
income: undefined,
|
||||||
|
incomeChain: undefined,
|
||||||
|
expend: undefined,
|
||||||
|
expendChain: undefined,
|
||||||
|
},
|
||||||
|
// 本年经营收入
|
||||||
|
incomeList: { list: [], endTime: undefined },
|
||||||
|
// 园区规划
|
||||||
|
parkPlan: [],
|
||||||
|
// 税收概览
|
||||||
|
revenueOverview: [],
|
||||||
|
// 园区进出口额
|
||||||
|
parkImportExportData: { amount: undefined, import: undefined, export: undefined },
|
||||||
|
// 企业信息
|
||||||
|
enterpriseInfo: {
|
||||||
|
// 报税金额
|
||||||
|
taxAmount: undefined,
|
||||||
|
// 税收总金额
|
||||||
|
taxTotalAmount: undefined,
|
||||||
|
// 企业数量
|
||||||
|
enterpriseCount: undefined,
|
||||||
|
// 国营企业(强调国家控股)
|
||||||
|
stateOwnedEnterprise: undefined,
|
||||||
|
// 私营企业
|
||||||
|
privateEnterprise: undefined,
|
||||||
|
// 投资总金额
|
||||||
|
investmentTotal: undefined,
|
||||||
|
},
|
||||||
|
// 园区规划
|
||||||
|
parkAreas: [],
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
/* 规模效益 */
|
||||||
|
async fetchScaleProfit(data: any) {
|
||||||
|
this.scaleProfit = await getScaleProfit(data);
|
||||||
|
},
|
||||||
|
|
||||||
|
/* 本年经营收入 */
|
||||||
|
async fetchYearIncome() {
|
||||||
|
this.incomeList = await getYearIncome();
|
||||||
|
},
|
||||||
|
|
||||||
|
/* 园区规划 */
|
||||||
|
async fetchParkPlan() {
|
||||||
|
this.parkPlan = await getParkPlan();
|
||||||
|
},
|
||||||
|
|
||||||
|
/* 税收概览 */
|
||||||
|
async fetchRevenueOverview() {
|
||||||
|
this.revenueOverview = await getRevenueOverView();
|
||||||
|
},
|
||||||
|
|
||||||
|
/* 园区进出口额 */
|
||||||
|
async fetchParkImportExportData(data) {
|
||||||
|
this.parkImportExportData = await getParkImportExportData(data);
|
||||||
|
},
|
||||||
|
|
||||||
|
/* 企业信息 */
|
||||||
|
async fetchEnterpriseInfo() {
|
||||||
|
this.enterpriseInfo = await getEnterpriseInfo();
|
||||||
|
},
|
||||||
|
|
||||||
|
/* 园区规划 */
|
||||||
|
async fetchParkAreas() {
|
||||||
|
this.parkAreas = await getParkAreas();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
|
@ -13,7 +13,7 @@ export const debounceChart = (myChart: echarts.ECharts | undefined) => {
|
||||||
|
|
||||||
/** 数字格式化 */
|
/** 数字格式化 */
|
||||||
export const formatter = (number: any) => {
|
export const formatter = (number: any) => {
|
||||||
const numbers = number.toString().split('').reverse();
|
const numbers = number?.toString().split('').reverse();
|
||||||
const segs = [];
|
const segs = [];
|
||||||
|
|
||||||
while (numbers.length) segs.push(numbers.splice(0, 3).join(''));
|
while (numbers.length) segs.push(numbers.splice(0, 3).join(''));
|
||||||
|
|
|
@ -78,7 +78,7 @@ const option = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 渲染图表 */
|
/** 渲染图表 */
|
||||||
export const renderFooterChart = (element: Ref<HTMLDivElement>) => {
|
export const renderBigDateContentFooterChart = (element: Ref<HTMLDivElement>) => {
|
||||||
myChart = echarts.init(element.value, null, {
|
myChart = echarts.init(element.value, null, {
|
||||||
renderer: 'canvas',
|
renderer: 'canvas',
|
||||||
devicePixelRatio: window.devicePixelRatio,
|
devicePixelRatio: window.devicePixelRatio,
|
||||||
|
@ -88,3 +88,12 @@ export const renderFooterChart = (element: Ref<HTMLDivElement>) => {
|
||||||
|
|
||||||
myChart.setOption(option);
|
myChart.setOption(option);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 更新图标数据 */
|
||||||
|
export const updateBigDateContentFooterChart = (props: { data: Array<number> }) => {
|
||||||
|
const series = myChart.getOption()?.series;
|
||||||
|
series[0].data = props.data;
|
||||||
|
series[1].data = props.data;
|
||||||
|
|
||||||
|
myChart.setOption({ series });
|
||||||
|
};
|
||||||
|
|
|
@ -6,6 +6,8 @@ import { type Ref, ref } from 'vue';
|
||||||
import echarts from '@/plugins/echarts';
|
import echarts from '@/plugins/echarts';
|
||||||
import { debounceChart } from '@/utils/chart';
|
import { debounceChart } from '@/utils/chart';
|
||||||
|
|
||||||
|
let myChart = null;
|
||||||
|
|
||||||
const option = ref<EChartsOption>();
|
const option = ref<EChartsOption>();
|
||||||
option.value = {
|
option.value = {
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
@ -44,8 +46,8 @@ option.value = {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const renderEcharts = (element: Ref<HTMLDivElement>) => {
|
export const renderBigDataLeftTopEcharts = (element: Ref<HTMLDivElement>) => {
|
||||||
const myChart: any = echarts.init(element.value, null, {
|
myChart = echarts.init(element.value, null, {
|
||||||
renderer: 'svg',
|
renderer: 'svg',
|
||||||
devicePixelRatio: window.devicePixelRatio,
|
devicePixelRatio: window.devicePixelRatio,
|
||||||
});
|
});
|
||||||
|
@ -54,3 +56,15 @@ export const renderEcharts = (element: Ref<HTMLDivElement>) => {
|
||||||
|
|
||||||
myChart.setOption(option.value);
|
myChart.setOption(option.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 更新图标数据 */
|
||||||
|
export const updateBigDataLeftTopEcharts = (props: {
|
||||||
|
import: Array<number>;
|
||||||
|
export: Array<number>;
|
||||||
|
}) => {
|
||||||
|
const series = myChart.getOption()?.series;
|
||||||
|
series[0].data[0] = props.import;
|
||||||
|
series[1].data[0] = -props.export;
|
||||||
|
|
||||||
|
myChart.setOption({ series });
|
||||||
|
};
|
||||||
|
|
|
@ -1,17 +1,25 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useIntervalFn } from '@vueuse/core';
|
import { useIntervalFn } from '@vueuse/core';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
|
|
||||||
|
import { useBigDataStore } from '@/store/modules/bigData';
|
||||||
import { getImage } from '@/utils/image';
|
import { getImage } from '@/utils/image';
|
||||||
import { renderFooterChart } from '@/views/big-data/charts/content-footer';
|
import {
|
||||||
|
renderBigDateContentFooterChart,
|
||||||
|
updateBigDateContentFooterChart,
|
||||||
|
} from '@/views/big-data/charts/content-footer';
|
||||||
|
|
||||||
const headerList = [
|
const HEADER_LIST = [
|
||||||
{ title: '员工', img: '/images/big-data/bg-content-top-1.png' },
|
{ title: '员工', img: '/images/big-data/bg-content-top-1.png' },
|
||||||
{ title: '智慧大楼', img: '/images/big-data/bg-content-top-2.png' },
|
{ title: '智慧大楼', img: '/images/big-data/bg-content-top-2.png' },
|
||||||
{ title: '智慧设备', img: '/images/big-data/bg-content-top-3.png' },
|
{ title: '智慧设备', img: '/images/big-data/bg-content-top-3.png' },
|
||||||
{ title: '数据报表', img: '/images/big-data/bg-content-top-4.png' },
|
{ title: '数据报表', img: '/images/big-data/bg-content-top-4.png' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const bidDataStore = useBigDataStore();
|
||||||
|
const { revenueOverview } = storeToRefs(bidDataStore);
|
||||||
|
|
||||||
const isActive = ref(true);
|
const isActive = ref(true);
|
||||||
const footerChartRef = ref<HTMLDivElement>();
|
const footerChartRef = ref<HTMLDivElement>();
|
||||||
|
|
||||||
|
@ -22,9 +30,25 @@ const changeMoveState = () => {
|
||||||
}, 2000);
|
}, 2000);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const initAppData = async () => {
|
||||||
|
await bidDataStore.fetchRevenueOverview();
|
||||||
|
updateBigDateContentFooterChart({ data: revenueOverview.value });
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
// 修改工作台箭头状态
|
||||||
changeMoveState();
|
changeMoveState();
|
||||||
renderFooterChart(footerChartRef);
|
|
||||||
|
// 初始化渲染图表
|
||||||
|
renderBigDateContentFooterChart(footerChartRef);
|
||||||
|
|
||||||
|
// 初始化数据显示
|
||||||
|
initAppData();
|
||||||
|
|
||||||
|
// 定时获取数据内容
|
||||||
|
useIntervalFn(() => {
|
||||||
|
initAppData();
|
||||||
|
}, 1000);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -32,7 +56,7 @@ onMounted(() => {
|
||||||
<div class="big-data__content">
|
<div class="big-data__content">
|
||||||
<header class="big-data__header">
|
<header class="big-data__header">
|
||||||
<ul class="big-data__stats-list">
|
<ul class="big-data__stats-list">
|
||||||
<li v-for="(item, index) in headerList" :key="index">
|
<li v-for="(item, index) in HEADER_LIST" :key="index">
|
||||||
<img :src="getImage(item.img)" alt="" />
|
<img :src="getImage(item.img)" alt="" />
|
||||||
<h2>{{ item.title }}</h2>
|
<h2>{{ item.title }}</h2>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,70 +1,60 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useIntervalFn } from '@vueuse/core';
|
import { useIntervalFn } from '@vueuse/core';
|
||||||
import { onMounted, ref } from 'vue';
|
import dayjs from 'dayjs';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
|
|
||||||
import { displayContent } from '@/components/DigitalNumber/DigitalCurrency';
|
import DigitalNumber from '@/components/DigitalNumber/DigitalNumber';
|
||||||
import TimeSelect from '@/components/TimeSelect/index.vue';
|
import TimeSelect from '@/components/TimeSelect/index.vue';
|
||||||
import { TimeSelectType } from '@/components/TimeSelect/type';
|
import { TimeSelectType } from '@/components/TimeSelect/type';
|
||||||
|
import { useBigDataStore } from '@/store/modules/bigData';
|
||||||
import { formatter } from '@/utils/chart';
|
import { formatter } from '@/utils/chart';
|
||||||
import { ChartProgress } from '@/views/big-data/charts/left-body';
|
import { ChartProgress } from '@/views/big-data/charts/left-body';
|
||||||
import { renderFooterChart, updateFooterChart } from '@/views/big-data/charts/left-footer';
|
import { renderFooterChart, updateFooterChart } from '@/views/big-data/charts/left-footer';
|
||||||
|
|
||||||
const timeList = ref<TimeSelectType[]>([
|
const TIME_LIST = ref<TimeSelectType[]>([
|
||||||
{ label: '2020.09', value: '2021' },
|
{ label: '2020.09', value: '2020-09' },
|
||||||
{ label: '2020.09', value: '2021' },
|
{ label: '2021.09', value: '2021-09' },
|
||||||
{ label: '2020.09', value: '2021' },
|
{ label: '2022.09', value: '2022-08' },
|
||||||
|
{ label: '2023.09', value: '2023-08' },
|
||||||
|
{ label: '2025.09', value: '2025-08' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/* body数据---模拟数据 */
|
const bigdataStore = useBigDataStore();
|
||||||
const bodyList = ref([]);
|
const { scaleProfit, incomeList, parkPlan } = storeToRefs(bigdataStore);
|
||||||
const initBodyList = () => {
|
const form = reactive({
|
||||||
const randomNumber = (range: number = 100) => {
|
date: TIME_LIST.value[0].value,
|
||||||
return parseInt((Math.random() * range).toFixed(0));
|
});
|
||||||
};
|
|
||||||
|
|
||||||
bodyList.value = [
|
|
||||||
{ title: '经营总收入', amount: randomNumber(9999999), percent: randomNumber() },
|
|
||||||
{ title: '经营总收入', amount: randomNumber(9999999), percent: randomNumber() },
|
|
||||||
{ title: '经营总收入', amount: randomNumber(9999999), percent: randomNumber() },
|
|
||||||
{ title: '经营总收入', amount: randomNumber(9999999), percent: randomNumber() },
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 底部图表---模拟数据 */
|
/* 底部图表---模拟数据 */
|
||||||
const footerChartRef = ref<HTMLDivElement>();
|
const footerChartRef = ref<HTMLDivElement>();
|
||||||
const mockFooterChart = () => {
|
|
||||||
function random() {
|
|
||||||
return Array(12)
|
|
||||||
.fill(0)
|
|
||||||
.map(() => {
|
|
||||||
const num = (Math.random() * 100).toFixed(2);
|
|
||||||
return parseInt(num);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const data: Array<Array<number>> = [random(), random()];
|
/* 初始化数据 */
|
||||||
updateFooterChart(data);
|
const initAppData = () => {
|
||||||
|
bigdataStore.fetchScaleProfit({ date: form.date });
|
||||||
|
bigdataStore.fetchYearIncome();
|
||||||
|
bigdataStore.fetchParkPlan();
|
||||||
|
updateFooterChart(parkPlan.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 渲染底部图表
|
// 渲染底部图表
|
||||||
renderFooterChart(footerChartRef);
|
renderFooterChart(footerChartRef);
|
||||||
initBodyList();
|
initAppData();
|
||||||
|
|
||||||
// 模拟底部图表
|
// 模拟底部图表
|
||||||
useIntervalFn(() => {
|
useIntervalFn(() => {
|
||||||
mockFooterChart();
|
initAppData();
|
||||||
initBodyList();
|
|
||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="big-data__sidebar">
|
<div class="big-data__sidebar">
|
||||||
<div class="big-data__header">
|
<header class="big-data__header">
|
||||||
<div class="flex-x-between">
|
<div class="flex-x-between">
|
||||||
<h1 class="big-data__sidebar-title">规模效益</h1>
|
<h1 class="big-data__sidebar-title">规模效益</h1>
|
||||||
<TimeSelect :time-list="timeList" />
|
<TimeSelect v-model="form.date" :time-list="TIME_LIST" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -74,16 +64,16 @@ onMounted(() => {
|
||||||
<div>
|
<div>
|
||||||
<span>
|
<span>
|
||||||
总值增幅
|
总值增幅
|
||||||
<em>+123%</em>
|
<em>+{{ scaleProfit.total }}%</em>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
超越第二名
|
超越第二名
|
||||||
<em>+22.3%</em>
|
<em>+{{ scaleProfit.incomeChain }}%</em>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="money-digit">
|
<div class="money-digit">
|
||||||
<component :is="displayContent('8888888')" />
|
<DigitalNumber :money="scaleProfit.income" :separator="true" />
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
@ -93,47 +83,50 @@ onMounted(() => {
|
||||||
<div>
|
<div>
|
||||||
<span>
|
<span>
|
||||||
环比变化
|
环比变化
|
||||||
<em>+123%</em>
|
<em>+{{ scaleProfit.expendChain }}%</em>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="money-digit">
|
<div class="money-digit">
|
||||||
<component :is="displayContent('888888')" />
|
<DigitalNumber :money="scaleProfit.expend" :separator="true" />
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</header>
|
||||||
|
|
||||||
<div class="big-data__body h-[389px]">
|
<main class="big-data__body h-[389px]">
|
||||||
<div class="flex-x-between">
|
<div class="flex-x-between">
|
||||||
<h1 class="big-data__sidebar-title">本年经营收入</h1>
|
<h1 class="big-data__sidebar-title">本年经营收入</h1>
|
||||||
<span class="big-data__sidebar-title-describe">截止时间至2021年6月</span>
|
<span class="big-data__sidebar-title-describe">
|
||||||
|
截止时间至 {{ dayjs(incomeList.endTime).format('YYYY-MM-DD') }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="(item, index) in bodyList" :key="index">
|
<li v-for="(item, index) in incomeList.list" :key="index">
|
||||||
<div>
|
<div>
|
||||||
<h1>{{ item.title }}</h1>
|
<h1>{{ item.title }}</h1>
|
||||||
<em>¥ {{ formatter(item.amount) }}}</em>
|
<em>¥ {{ formatter(item.amount) }}</em>
|
||||||
</div>
|
</div>
|
||||||
<ChartProgress :percent="item.percent" />
|
<ChartProgress :percent="item.percent" />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</main>
|
||||||
|
|
||||||
<div class="big-data__footer">
|
<footer class="big-data__footer">
|
||||||
<div class="flex-x-between">
|
<div class="flex-x-between">
|
||||||
<div class="big-data__sidebar-title">
|
<div class="big-data__sidebar-title">
|
||||||
<h1>园区规划</h1>
|
<h1>园区规划</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div ref="footerChartRef" class="big-data__footer-chart-container" />
|
<div ref="footerChartRef" class="big-data__footer-chart-container" />
|
||||||
</div>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.big-data__header {
|
.big-data__header {
|
||||||
|
width: 100%;
|
||||||
height: 274px;
|
height: 274px;
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
|
|
|
@ -1,15 +1,24 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
const list = [
|
import { useIntervalFn } from '@vueuse/core';
|
||||||
{ title: '134.5㎡', summary: '建成投产面积' },
|
import { storeToRefs } from 'pinia';
|
||||||
{ title: '38000㎡', summary: '保税仓库面积' },
|
import { onMounted } from 'vue';
|
||||||
{ title: '327.3㎡', summary: '物流场站' },
|
|
||||||
{ title: '327.3㎡', summary: '物流场站' },
|
import { useBigDataStore } from '@/store/modules/bigData';
|
||||||
{ title: '327.3㎡', summary: '物流场站' },
|
|
||||||
{ title: '327.3㎡', summary: '物流场站' },
|
const bidDataStore = useBigDataStore();
|
||||||
{ title: '327.3㎡', summary: '物流场站' },
|
const { parkAreas } = storeToRefs(bidDataStore);
|
||||||
{ title: '327.3㎡', summary: '物流场站' },
|
|
||||||
{ title: '327.3㎡', summary: '物流场站' },
|
const initAppData = () => {
|
||||||
];
|
bidDataStore.fetchParkAreas();
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
initAppData();
|
||||||
|
|
||||||
|
useIntervalFn(() => {
|
||||||
|
initAppData();
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -19,8 +28,8 @@ const list = [
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="big-data__sidebar-card">
|
<ul class="big-data__sidebar-card">
|
||||||
<li v-for="(item, index) in list" :key="index">
|
<li v-for="(item, index) in parkAreas" :key="index">
|
||||||
<h1>{{ item.title }}</h1>
|
<h1>{{ item.title }} ㎡</h1>
|
||||||
<p>{{ item.summary }}</p>
|
<p>{{ item.summary }}</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1,12 +1,28 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { useIntervalFn } from '@vueuse/core';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
|
|
||||||
|
import { useBigDataStore } from '@/store/modules/bigData';
|
||||||
import { renderEcharts } from '@/views/business-supervision/charts/leftSidebarMiddle';
|
import { renderEcharts } from '@/views/business-supervision/charts/leftSidebarMiddle';
|
||||||
|
|
||||||
const chartPie = ref<HTMLDivElement>();
|
const chartPie = ref<HTMLDivElement>();
|
||||||
|
|
||||||
|
const bidDataStore = useBigDataStore();
|
||||||
|
const { enterpriseInfo } = storeToRefs(bidDataStore);
|
||||||
|
|
||||||
|
const initAppData = () => {
|
||||||
|
bidDataStore.fetchEnterpriseInfo();
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
renderEcharts(chartPie);
|
renderEcharts(chartPie);
|
||||||
|
|
||||||
|
initAppData();
|
||||||
|
|
||||||
|
useIntervalFn(() => {
|
||||||
|
initAppData();
|
||||||
|
}, 1000);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -20,24 +36,24 @@ onMounted(() => {
|
||||||
<ul class="big-data__sidebar-card">
|
<ul class="big-data__sidebar-card">
|
||||||
<li>
|
<li>
|
||||||
<h1>报税金额</h1>
|
<h1>报税金额</h1>
|
||||||
<p class="c-warning-secondary">¥1551154545</p>
|
<p class="c-warning-secondary">¥{{ enterpriseInfo.taxAmount }}</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div class="flex-x-between">
|
<div class="flex-x-between">
|
||||||
<div>
|
<div>
|
||||||
<h1>企业数量</h1>
|
<h1>企业数量</h1>
|
||||||
<p class="c-primary-secondary">783</p>
|
<p class="c-primary-secondary">{{ enterpriseInfo.enterpriseCount }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div ref="chartPie" class="big-data__sidebar-card-chart-pie" />
|
<div ref="chartPie" class="big-data__sidebar-card-chart-pie" />
|
||||||
</div>
|
</div>
|
||||||
<div class="big-data__sidebar-card-enterprise-type">
|
<div class="big-data__sidebar-card-enterprise-type">
|
||||||
<span class="mr-[13px]">
|
<span class="mr-[4px]">
|
||||||
<i class="bg-primary-secondary" />
|
<i class="bg-primary-secondary" />
|
||||||
国营企业 345
|
国营企业 {{ enterpriseInfo.stateOwnedEnterprise }}
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
<i class="bg-warning-secondary" />
|
<i class="bg-warning-secondary" />
|
||||||
私营企业 345
|
私营企业 {{ enterpriseInfo.privateEnterprise }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
@ -47,7 +63,7 @@ onMounted(() => {
|
||||||
<span class="font-size-[12px]">环比变化</span>
|
<span class="font-size-[12px]">环比变化</span>
|
||||||
<span class="font-size-[12px]">+123%</span>
|
<span class="font-size-[12px]">+123%</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="c-primary-secondary">¥1551154545</p>
|
<p class="c-primary-secondary">¥{{ enterpriseInfo.investmentTotal }}</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div class="flex-x-between">
|
<div class="flex-x-between">
|
||||||
|
@ -55,7 +71,7 @@ onMounted(() => {
|
||||||
<span class="font-size-[12px]">环比变化</span>
|
<span class="font-size-[12px]">环比变化</span>
|
||||||
<span class="font-size-[12px]">-123%</span>
|
<span class="font-size-[12px]">-123%</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="c-primary-secondary">¥1551154545</p>
|
<p class="c-primary-secondary">¥{{ enterpriseInfo.taxTotalAmount }}</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,50 +1,85 @@
|
||||||
<script lang="tsx" setup>
|
<script lang="tsx" setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { useIntervalFn } from '@vueuse/core';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
|
|
||||||
import { displayContent } from '@/components/DigitalNumber/DigitalCurrency';
|
import DigitalNumber from '@/components/DigitalNumber/DigitalNumber';
|
||||||
import TimeSelect from '@/components/TimeSelect/index.vue';
|
import TimeSelect from '@/components/TimeSelect/index.vue';
|
||||||
import { TimeSelectType } from '@/components/TimeSelect/type';
|
import { TimeSelectType } from '@/components/TimeSelect/type';
|
||||||
import { renderEcharts } from '@/views/big-data/charts/right-header';
|
import { useBigDataStore } from '@/store/modules/bigData';
|
||||||
|
import {
|
||||||
|
renderBigDataLeftTopEcharts,
|
||||||
|
updateBigDataLeftTopEcharts,
|
||||||
|
} from '@/views/big-data/charts/right-header';
|
||||||
|
|
||||||
const chartProgress = ref<HTMLDivElement>();
|
const TIME_LIST = ref<TimeSelectType[]>([
|
||||||
const money = '1386114';
|
{ label: '2020.09', value: '2020-09' },
|
||||||
|
{ label: '2021.09', value: '2021-09' },
|
||||||
const timeList = ref<TimeSelectType[]>([
|
{ label: '2022.09', value: '2022-08' },
|
||||||
{ label: '2020.09', value: '2021' },
|
{ label: '2023.09', value: '2023-08' },
|
||||||
{ label: '2020.09', value: '2021' },
|
{ label: '2025.09', value: '2025-08' },
|
||||||
{ label: '2020.09', value: '2021' },
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const bidDataStore = useBigDataStore();
|
||||||
|
const { parkImportExportData } = storeToRefs(bidDataStore);
|
||||||
|
|
||||||
|
// 图表
|
||||||
|
const chartProgressRef = ref<HTMLDivElement>();
|
||||||
|
|
||||||
|
// 查询表单
|
||||||
|
const form = reactive({
|
||||||
|
date: TIME_LIST.value[0].value,
|
||||||
|
});
|
||||||
|
|
||||||
|
/* 初始化数据 */
|
||||||
|
const initAppData = () => {
|
||||||
|
bidDataStore.fetchParkImportExportData({ date: form.date });
|
||||||
|
updateBigDataLeftTopEcharts({
|
||||||
|
import: parkImportExportData.value.import,
|
||||||
|
export: parkImportExportData.value.export,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
renderEcharts(chartProgress);
|
// 渲染图表
|
||||||
|
renderBigDataLeftTopEcharts(chartProgressRef);
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
initAppData();
|
||||||
|
|
||||||
|
// 定时刷新
|
||||||
|
useIntervalFn(() => {
|
||||||
|
initAppData();
|
||||||
|
}, 1000);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="big-data__header h-[226px]">
|
<div class="big-data__header h-[226px]">
|
||||||
<div class="flex-x-between">
|
<div class="flex-x-between">
|
||||||
<h1 class="big-data__header-title">园区进出口额</h1>
|
<h1 class="big-data__sidebar-title">园区进出口额</h1>
|
||||||
<div>
|
<div>
|
||||||
<span class="big-data__header-tag">总数据</span>
|
<TimeSelect v-model="form.date" :time-list="TIME_LIST" />
|
||||||
<TimeSelect :time-list="timeList" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="money-digit">
|
<div class="money-digit">
|
||||||
<component :is="displayContent(money)" />
|
<DigitalNumber :money="parkImportExportData.amount" :separator="true">
|
||||||
|
<span>¥</span>
|
||||||
|
</DigitalNumber>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div ref="chartProgress" class="big-data__header-progress" />
|
<div ref="chartProgressRef" class="big-data__header-progress" />
|
||||||
|
|
||||||
<ul class="big-data__header-value">
|
<ul class="big-data__header-value">
|
||||||
<li>
|
<li>
|
||||||
进口额
|
进口额
|
||||||
<i>¥1551154545</i>
|
<i>¥ {{ parkImportExportData.import }}</i>
|
||||||
</li>
|
</li>
|
||||||
<li class="thin-line h-[20px]" />
|
<li class="thin-line h-[20px]" />
|
||||||
<li>
|
<li>
|
||||||
<i>¥1551154545</i>
|
<i>¥ {{ parkImportExportData.export }}</i>
|
||||||
出口额
|
出口额
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -57,7 +92,7 @@ onMounted(() => {
|
||||||
margin: 14px 0 0 0;
|
margin: 14px 0 0 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
span {
|
:deep(span) {
|
||||||
height: 69px;
|
height: 69px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ onBeforeMount(async () => {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 9px 0 9px;
|
padding: 0 14px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@ const option = ref<EChartsOption>({
|
||||||
barWidth: 20,
|
barWidth: 20,
|
||||||
barGap: 0,
|
barGap: 0,
|
||||||
coordinateSystem: 'polar',
|
coordinateSystem: 'polar',
|
||||||
itemStyle: {},
|
|
||||||
label: { show: true, position: 'middle' },
|
label: { show: true, position: 'middle' },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -50,13 +49,14 @@ export const renderBodyChart = (element: Ref<HTMLDivElement>) => {
|
||||||
/** 更新图标数据 */
|
/** 更新图标数据 */
|
||||||
export const updateBodyChart = (props: any) => {
|
export const updateBodyChart = (props: any) => {
|
||||||
const series = myChart?.getOption()?.series;
|
const series = myChart?.getOption()?.series;
|
||||||
|
|
||||||
series[0].data = props.list?.map((item, index) => ({
|
series[0].data = props.list?.map((item, index) => ({
|
||||||
name: item.name,
|
name: item.name,
|
||||||
value: item.value,
|
value: item.value,
|
||||||
itemStyle: { color: colors[index], borderRadius: 10 },
|
itemStyle: { color: colors[index], borderRadius: 10 },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const total = props.list.reduce((old, item) => old + item.value, 0);
|
const total = props.list?.reduce((old, item) => old + item.value, 0);
|
||||||
|
|
||||||
const title = myChart?.getOption()?.title;
|
const title = myChart?.getOption()?.title;
|
||||||
title[0].text = total;
|
title[0].text = total;
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import 'echarts/lib/component/dataZoom';
|
import 'echarts/lib/component/dataZoom';
|
||||||
|
|
||||||
import type { EChartsOption, EChartsType } from 'echarts';
|
import type { EChartsOption } from 'echarts';
|
||||||
import { defineComponent, onMounted, type Ref, ref, watch } from 'vue';
|
import { defineComponent, onMounted, type Ref, ref, watch } from 'vue';
|
||||||
|
|
||||||
import echarts from '@/plugins/echarts';
|
import echarts from '@/plugins/echarts';
|
||||||
import { debounceChart } from '@/utils/chart';
|
|
||||||
|
|
||||||
const option = ref<EChartsOption>({
|
const option = ref<EChartsOption>({
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
@ -69,13 +68,11 @@ export const renderLeftHeaderEcharts: any = (
|
||||||
devicePixelRatio: window.devicePixelRatio,
|
devicePixelRatio: window.devicePixelRatio,
|
||||||
});
|
});
|
||||||
|
|
||||||
myChart.value!.setOption(option.value!);
|
myChart.value?.setOption(option.value);
|
||||||
|
|
||||||
debounceChart(myChart.value);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 更新图标数据 */
|
/** 更新图标数据 */
|
||||||
const updateChart = (myChart: Ref<EChartsType | undefined>, props: any) => {
|
const updateChart = (myChart: Ref<echarts.ECharts | undefined>, props: any) => {
|
||||||
const series = myChart.value.getOption().series;
|
const series = myChart.value.getOption().series;
|
||||||
series[0].data[0] = props.dataLeft;
|
series[0].data[0] = props.dataLeft;
|
||||||
series[1].data[0] = props.dataRight;
|
series[1].data[0] = props.dataRight;
|
||||||
|
@ -87,18 +84,18 @@ const LeftHeaderChart = defineComponent({
|
||||||
name: 'LeftHeaderChart',
|
name: 'LeftHeaderChart',
|
||||||
props: { dataLeft: { type: Number }, dataRight: { type: Number } },
|
props: { dataLeft: { type: Number }, dataRight: { type: Number } },
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const myChartRef = ref<EChartsType>();
|
const myChartRef = ref<echarts.ECharts>();
|
||||||
const chartRef = ref<HTMLDivElement>();
|
const chartRef = ref<HTMLDivElement>();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
renderLeftHeaderEcharts(myChartRef, chartRef);
|
renderLeftHeaderEcharts(myChartRef, chartRef);
|
||||||
|
updateChart(myChartRef, props);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => [props.dataLeft, () => props.dataRight],
|
() => [props.dataLeft, () => props.dataRight],
|
||||||
() => {
|
() => {
|
||||||
updateChart(myChartRef, props);
|
updateChart(myChartRef, props);
|
||||||
},
|
}
|
||||||
{ immediate: true }
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ defineProps({
|
||||||
.panel {
|
.panel {
|
||||||
width: 430px;
|
width: 430px;
|
||||||
height: 440px;
|
height: 440px;
|
||||||
background: url('../images/bg-common-panel.png') no-repeat;
|
background: url('../images/bg-common-panel.png') no-repeat center;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
|
|
|
@ -103,7 +103,7 @@ onMounted(() => {
|
||||||
|
|
||||||
.community__stat-card {
|
.community__stat-card {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 209px;
|
width: 215px;
|
||||||
height: 204px;
|
height: 204px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
||||||
|
@ -111,6 +111,8 @@ onMounted(() => {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.community__stat-content {
|
.community__stat-content {
|
||||||
|
@ -145,7 +147,7 @@ onMounted(() => {
|
||||||
margin: 40px 0 0 0;
|
margin: 40px 0 0 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 660px;
|
height: 660px;
|
||||||
background: url('../images/bg-body.png') no-repeat;
|
background: url('../images/bg-body.png') no-repeat center;
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
|
|
||||||
/* 数据图片内容 */
|
/* 数据图片内容 */
|
||||||
|
@ -186,7 +188,8 @@ onMounted(() => {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 105px;
|
width: 105px;
|
||||||
height: 170px;
|
height: 170px;
|
||||||
background: url('../images/bg-body-card.png');
|
background: url('../images/bg-body-card.png') no-repeat center;
|
||||||
|
background-size: cover;
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
|
@ -206,7 +209,8 @@ onMounted(() => {
|
||||||
width: 286px;
|
width: 286px;
|
||||||
height: 169px;
|
height: 169px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: url('../images/bg-body-instrument-panel.png');
|
background: url('../images/bg-body-instrument-panel.png') no-repeat center;
|
||||||
|
background-size: cover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue