diff --git a/mock/model/route.ts b/mock/model/route.ts index 1d0b2809..a2f57a06 100644 --- a/mock/model/route.ts +++ b/mock/model/route.ts @@ -221,6 +221,47 @@ export const routeModel: Record = { requiresAuth: true, icon: 'ic:baseline-local-printshop' } + }, + { + name: 'plugin_charts', + path: '/plugin/charts', + component: 'multi', + children: [ + { + name: 'plugin_charts_echarts', + path: '/plugin/charts/echarts', + component: 'self', + meta: { + title: 'ECharts', + requiresAuth: true, + icon: 'simple-icons:apacheecharts' + } + }, + { + name: 'plugin_charts_d3', + path: '/plugin/charts/d3', + component: 'self', + meta: { + title: 'D3', + requiresAuth: true, + icon: 'simple-icons:d3dotjs' + } + }, + { + name: 'plugin_charts_antv', + path: '/plugin/charts/antv', + component: 'self', + meta: { + title: 'AntV', + requiresAuth: true, + icon: 'ant-design:bar-chart-outlined' + } + } + ], + meta: { + title: '图表', + icon: 'material-symbols:bar-chart-rounded' + } } ], meta: { @@ -592,6 +633,47 @@ export const routeModel: Record = { requiresAuth: true, icon: 'ic:baseline-local-printshop' } + }, + { + name: 'plugin_charts', + path: '/plugin/charts', + component: 'multi', + children: [ + { + name: 'plugin_charts_echarts', + path: '/plugin/charts/echarts', + component: 'self', + meta: { + title: 'ECharts', + requiresAuth: true, + icon: 'simple-icons:apacheecharts' + } + }, + { + name: 'plugin_charts_d3', + path: '/plugin/charts/d3', + component: 'self', + meta: { + title: 'D3', + requiresAuth: true, + icon: 'simple-icons:d3dotjs' + } + }, + { + name: 'plugin_charts_antv', + path: '/plugin/charts/antv', + component: 'self', + meta: { + title: 'AntV', + requiresAuth: true, + icon: 'ant-design:bar-chart-outlined' + } + } + ], + meta: { + title: '图表', + icon: 'material-symbols:bar-chart-rounded' + } } ], meta: { diff --git a/src/hooks/business/useEcharts.ts b/src/hooks/business/useEcharts.ts index 1e66cf5d..f444b94e 100644 --- a/src/hooks/business/useEcharts.ts +++ b/src/hooks/business/useEcharts.ts @@ -1,8 +1,8 @@ import { ref, watch, nextTick, onUnmounted, computed } from 'vue'; import type { Ref, ComputedRef } from 'vue'; import * as echarts from 'echarts/core'; -import { BarChart, LineChart, PieChart } from 'echarts/charts'; -import type { BarSeriesOption, LineSeriesOption, PieSeriesOption } from 'echarts/charts'; +import { BarChart, LineChart, PieChart, ScatterChart } from 'echarts/charts'; +import type { BarSeriesOption, LineSeriesOption, PieSeriesOption, ScatterSeriesOption } from 'echarts/charts'; import { TitleComponent, LegendComponent, @@ -28,6 +28,7 @@ export type ECOption = echarts.ComposeOption< | BarSeriesOption | LineSeriesOption | PieSeriesOption + | ScatterSeriesOption | TitleComponentOption | LegendComponentOption | TooltipComponentOption @@ -47,6 +48,7 @@ echarts.use([ BarChart, LineChart, PieChart, + ScatterChart, LabelLayout, UniversalTransition, CanvasRenderer @@ -55,7 +57,9 @@ echarts.use([ /** * Echarts hooks函数 * @param options - 图表配置 - * @param renderFun - 图表函数(例如:图表监听函数) + * @param darkMode - 暗黑模式 + * @param renderFun - 图表渲染函数(例如:图表监听函数) + * @description 按需引入图表组件,没注册的组件需要先引入 */ export default function useEcharts( options: Ref | ComputedRef, diff --git a/src/router/modules/charts.ts b/src/router/modules/charts.ts new file mode 100644 index 00000000..6f873665 --- /dev/null +++ b/src/router/modules/charts.ts @@ -0,0 +1,43 @@ +const charts: AuthRoute.Route = { + name: 'plugin_charts', + path: '/plugin/charts', + component: 'multi', + children: [ + { + name: 'plugin_charts_echarts', + path: '/plugin/charts/echarts', + component: 'self', + meta: { + title: 'ECharts', + requiresAuth: true, + icon: 'simple-icons:apacheecharts' + } + }, + { + name: 'plugin_charts_d3', + path: '/plugin/charts/d3', + component: 'self', + meta: { + title: 'D3', + requiresAuth: true, + icon: 'simple-icons:d3dotjs' + } + }, + { + name: 'plugin_charts_antv', + path: '/plugin/charts/antv', + component: 'self', + meta: { + title: 'AntV', + requiresAuth: true, + icon: 'ant-design:bar-chart-outlined' + } + } + ], + meta: { + title: '图表', + icon: 'material-symbols:bar-chart-rounded' + } +}; + +export default charts; diff --git a/src/typings/route.d.ts b/src/typings/route.d.ts index da5f4edc..3029ef86 100644 --- a/src/typings/route.d.ts +++ b/src/typings/route.d.ts @@ -36,6 +36,10 @@ declare namespace AuthRoute { | 'plugin_icon' | 'plugin_print' | 'plugin_swiper' + | 'plugin_charts' + | 'plugin_charts_echarts' + | 'plugin_charts_d3' + | 'plugin_charts_antv' | 'auth-demo' | 'auth-demo_permission' | 'auth-demo_super' diff --git a/src/views/dashboard/analysis/components/TopChart/index.vue b/src/views/dashboard/analysis/components/TopChart/index.vue index fd5fda74..3d3d2919 100644 --- a/src/views/dashboard/analysis/components/TopChart/index.vue +++ b/src/views/dashboard/analysis/components/TopChart/index.vue @@ -39,152 +39,148 @@ const theme = useThemeStore(); const darkMode = computed(() => theme.darkMode); -const { domRef: lineRef } = useEcharts( - ref({ - tooltip: { - trigger: 'axis', - axisPointer: { - type: 'cross', - label: { - backgroundColor: '#6a7985' +const lineOptions = ref({ + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + label: { + backgroundColor: '#6a7985' + } + } + }, + legend: { + data: ['下载量', '注册数'] + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true + }, + xAxis: [ + { + type: 'category', + boundaryGap: false, + data: ['06:00', '08:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00', '24:00'] + } + ], + yAxis: [ + { + type: 'value' + } + ], + series: [ + { + color: '#8e9dff', + name: '下载量', + type: 'line', + smooth: true, + stack: 'Total', + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { + offset: 0.25, + color: '#8e9dff' + }, + { + offset: 1, + color: '#fff' + } + ] } - } - }, - legend: { - data: ['下载量', '注册数'] - }, - grid: { - left: '3%', - right: '4%', - bottom: '3%', - containLabel: true - }, - xAxis: [ - { - type: 'category', - boundaryGap: false, - data: ['06:00', '08:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00', '24:00'] - } - ], - yAxis: [ - { - type: 'value' - } - ], - series: [ - { - color: '#8e9dff', - name: '下载量', - type: 'line', - smooth: true, - stack: 'Total', - areaStyle: { - color: { - type: 'linear', - x: 0, - y: 0, - x2: 0, - y2: 1, - colorStops: [ - { - offset: 0.25, - color: '#8e9dff' - }, - { - offset: 1, - color: '#fff' - } - ] - } - }, - emphasis: { - focus: 'series' - }, - data: [4623, 6145, 6268, 6411, 1890, 4251, 2978, 3880, 3606, 4311] }, - { - color: '#26deca', - name: '注册数', - type: 'line', - smooth: true, - stack: 'Total', - areaStyle: { - color: { - type: 'linear', - x: 0, - y: 0, - x2: 0, - y2: 1, - colorStops: [ - { - offset: 0.25, - color: '#26deca' - }, - { - offset: 1, - color: '#fff' - } - ] - } - }, - emphasis: { - focus: 'series' - }, - data: [2208, 2016, 2916, 4512, 8281, 2008, 1963, 2367, 2956, 678] - } - ] - }), - darkMode -); + emphasis: { + focus: 'series' + }, + data: [4623, 6145, 6268, 6411, 1890, 4251, 2978, 3880, 3606, 4311] + }, + { + color: '#26deca', + name: '注册数', + type: 'line', + smooth: true, + stack: 'Total', + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { + offset: 0.25, + color: '#26deca' + }, + { + offset: 1, + color: '#fff' + } + ] + } + }, + emphasis: { + focus: 'series' + }, + data: [2208, 2016, 2916, 4512, 8281, 2008, 1963, 2367, 2956, 678] + } + ] +}); +const { domRef: lineRef } = useEcharts(lineOptions, darkMode); -const { domRef: pieRef } = useEcharts( - ref({ - tooltip: { - trigger: 'item' - }, - legend: { - bottom: '1%', - left: 'center', +const pieOptions = ref({ + tooltip: { + trigger: 'item' + }, + legend: { + bottom: '1%', + left: 'center', + itemStyle: { + borderWidth: 0 + } + }, + series: [ + { + color: ['#5da8ff', '#8e9dff', '#fedc69', '#26deca'], + name: '时间安排', + type: 'pie', + radius: ['45%', '75%'], + avoidLabelOverlap: false, itemStyle: { - borderWidth: 0 - } - }, - series: [ - { - color: ['#5da8ff', '#8e9dff', '#fedc69', '#26deca'], - name: '时间安排', - type: 'pie', - radius: ['45%', '75%'], - avoidLabelOverlap: false, - itemStyle: { - borderRadius: 10, - borderColor: '#fff', - borderWidth: 1 - }, + borderRadius: 10, + borderColor: '#fff', + borderWidth: 1 + }, + label: { + show: false, + position: 'center' + }, + emphasis: { label: { - show: false, - position: 'center' - }, - emphasis: { - label: { - show: true, - fontSize: '12' - } - }, - labelLine: { - show: false - }, - data: [ - { value: 20, name: '学习' }, - { value: 10, name: '娱乐' }, - { value: 30, name: '工作' }, - { value: 40, name: '休息' } - ] - } - ] - }), - darkMode -); + show: true, + fontSize: '12' + } + }, + labelLine: { + show: false + }, + data: [ + { value: 20, name: '学习' }, + { value: 10, name: '娱乐' }, + { value: 30, name: '工作' }, + { value: 40, name: '休息' } + ] + } + ] +}); +const { domRef: pieRef } = useEcharts(pieOptions, darkMode); diff --git a/src/views/plugin/charts/antv/index.vue b/src/views/plugin/charts/antv/index.vue new file mode 100644 index 00000000..794430b6 --- /dev/null +++ b/src/views/plugin/charts/antv/index.vue @@ -0,0 +1,9 @@ + + + + + diff --git a/src/views/plugin/charts/d3/index.vue b/src/views/plugin/charts/d3/index.vue new file mode 100644 index 00000000..90ef4606 --- /dev/null +++ b/src/views/plugin/charts/d3/index.vue @@ -0,0 +1,9 @@ + + + + + diff --git a/src/views/plugin/charts/echarts/index.vue b/src/views/plugin/charts/echarts/index.vue new file mode 100644 index 00000000..cbc921ce --- /dev/null +++ b/src/views/plugin/charts/echarts/index.vue @@ -0,0 +1,159 @@ + + + + +