一个文笔一般,想到哪是哪的唯心论前端小白。
🧠 - 简介
所谓监控页面,其实主要还是和图表相关内容的处理。为此我做了一个组件,专门用来回显图表数据的。
效果图如下:
如图所示,它是一个卡片组件,头部显示的话可以切换图表类型,如果不显示头部就是一个简单的chart的引用。
👁️ - 分析
得益于前面的表单和表格组件,我依旧使用了 component 的方案来实现chart组件的开发。
🫀 - 拆解
首先要定义一下入参的数据格式,所有类型的图表都是这个数据结构:
const data = [
{
name: 'zhangsan',
data: [
12, 13, 18, 20, 30, 40, 50
],
xAxis: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
{
name: 'lisi',
data: [
112, 13, 18, 20, 310, 40, 59
],
xAxis: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
{
name: 'wangwu',
data: [
112, 13, 18, 20, 310, 40, 59
],
xAxis: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
]
如上所示,这是三条数据,分别对应三个人的:zhangsan、lisi、wangwu。每条数据的x周都是周一到周日,data中存放每天的数据。
另外为了保证页面好看应该有一个 chartConfig,里面存放一些常见的配置。
💪 - 落实
<template>
<div class="chart-card">
<div
v-if="!noHeader"
class="chart-card-head"
>
<div class="chart-card-head-title">
<span>{{ title }}</span>
<el-dropdown @command="handleCommand">
<span class="el-dropdown-link">
<el-icon>
<More />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="line">
折线图
</el-dropdown-item>
<el-dropdown-item command="bar">
柱状图
</el-dropdown-item>
<el-dropdown-item command="radar">
雷达图
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
<div
:id="chartId"
class="chart-card-content"
/>
</div>
</template>
<script lang="ts" setup>
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* @Name: ChartCard
* @Author:
* @Email: 14559@163.com
* @Date: 2023-11-30 19:07
* @Introduce: --
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
import { More } from '@element-plus/icons-vue'
import { onMounted, onUnmounted, toRefs } from 'vue';
import {
ChartType,
} from './utils';
import useChart from './useChart'
const chartId = 'chart_' + parseInt(Math.random() * 10 * 1024 * 1024 + '')
const {initChart} = useChart(chartId)
const props = defineProps<{
title: string
noHeader?: boolean
defaultType?: ChartType
}>()
const data = [
{
name: 'zhangsan',
data: [
12, 13, 18, 20, 30, 40, 50
],
xAxis: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
{
name: 'lisi',
data: [
112, 13, 18, 20, 310, 40, 59
],
xAxis: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
{
name: 'wangwu',
data: [
112, 13, 18, 20, 310, 40, 59
],
xAxis: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
]
const { title, defaultType, noHeader } = toRefs(props)
let chart;
const handleCommand = (v: ChartType) => {
initChart(v, data)
}
onMounted(() => {
initChart(defaultType!.value || 'line', data)
})
</script>
<style lang="scss" scoped>
.chart-card {
$cl: var(--el-border-color);
height: 100%;
width: 100%;
box-shadow: 3px 3px 6px $cl;
border: 1px solid $cl;
display: flex;
flex-direction: column;
.chart-card-head-title {
display: flex;
justify-content: space-between;
height: 40px;
border-bottom: 1px solid $cl;
span {
line-height: 40px;
padding: 0 10px;
}
}
.chart-card-content {
flex-grow: 1;
width: 100%;
height: 100%;
padding: 10px;
box-sizing: border-box;
}
}
</style>
这其实是个中间版本,需要把
<div
:id="chartId"
class="chart-card-content"
/>
部分替换成 component,但是这里很明显没有。
核心其实是一个转换器,通过配置和数据生成 echartOptions。
export type OptionDataType = {name: string, data: number[], xAxis: string[]}[]
export type LegendType = {
type?:string
bottom?: number
data: string[]}
export type ChartType = 'line' | 'bar' | 'radar'
export type ClearChart = undefined | (() => void);
export const initChartOptions = (type: ChartType, data: OptionDataType) => {
const legend:LegendType = {
type: 'scroll',
bottom: 10,
data: data.map(item => item.name)
}
const title = {}
if(['bar', 'line'].includes(type)){
return {
title,
legend,
xAxis: {
type: 'category',
data: [...data[0].xAxis]
},
yAxis: {
type: 'value'
},
series: [...data.map(item => ({
name: item.name,
type: type,
data: item.data,
}))]
}
}
if(['radar'].includes(type)){
return {
title,
legend,
radar:{
shape: 'circle',
indicator: [
...legend.data.map(item => ({name: item}))
]
},
series: [
{
name: legend.data.join(' vs '),
type: type,
data: [
...data.map(item => ({
name: item.name,
value: item.data
}))
]
}
]
}
}
}
设计上通过这个转换器,是可以适配多种图表框架的,不局限于 echart。
🛀 - 总结
本篇后续会再更新,到时候再细说吧。
系列文章:
- 脚手架开发
- 模板项目初始化
- 模板项目开发规范与设计思路
- layout设计与开发
- login 设计与开发
- CURD页面的设计与开发
- 监控页面的设计与开发
- 富文本编辑器的使用与页面设开发设计
- 主题切换的设计与开发并页面
- 水印切换的设计与开发
- 全屏与取消全屏
- 开发提效之一键生成模块(页面)