YGG-CLI-7-监控页面的设计与开发

一个文笔一般,想到哪是哪的唯心论前端小白。

🧠 - 简介

所谓监控页面,其实主要还是和图表相关内容的处理。为此我做了一个组件,专门用来回显图表数据的。

效果图如下:

如图所示,它是一个卡片组件,头部显示的话可以切换图表类型,如果不显示头部就是一个简单的chart的引用。

👁️ - 分析

得益于前面的表单和表格组件,我依旧使用了 component 的方案来实现chart组件的开发。

🫀 - 拆解

首先要定义一下入参的数据格式,所有类型的图表都是这个数据结构:

ts 复制代码
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,里面存放一些常见的配置。

💪 - 落实

vue 复制代码
<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>

这其实是个中间版本,需要把

html 复制代码
<div
  :id="chartId"
  class="chart-card-content"
/>

部分替换成 component,但是这里很明显没有。

核心其实是一个转换器,通过配置和数据生成 echartOptions。

ts 复制代码
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。

🛀 - 总结

本篇后续会再更新,到时候再细说吧。

系列文章:

  1. 脚手架开发
  2. 模板项目初始化
  3. 模板项目开发规范与设计思路
  4. layout设计与开发
  5. login 设计与开发
  6. CURD页面的设计与开发
  7. 监控页面的设计与开发
  8. 富文本编辑器的使用与页面设开发设计
  9. 主题切换的设计与开发并页面
  10. 水印切换的设计与开发
  11. 全屏与取消全屏
  12. 开发提效之一键生成模块(页面)
相关推荐
二哈喇子!18 小时前
BOM模型
开发语言·前端·javascript·bom
二哈喇子!18 小时前
Vue2 监听器 watcher
前端·javascript·vue.js
yanyu-yaya18 小时前
前端面试题
前端·面试·前端框架
二哈喇子!18 小时前
使用NVM下载Node.js管理多版本
前端·npm·node.js
GGGG寄了19 小时前
HTML——文本标签
开发语言·前端·html
摘星编程19 小时前
在OpenHarmony上用React Native:ActionSheet确认删除
javascript·react native·react.js
2501_9445215919 小时前
Flutter for OpenHarmony 微动漫App实战:推荐动漫实现
android·开发语言·前端·javascript·flutter·ecmascript
Amumu1213820 小时前
Vue核心(三)
前端·javascript·vue.js
CoCo的编程之路20 小时前
2026 前端效能革命:如何利用智能助手实现“光速”页面构建?深度横评
前端·人工智能·ai编程·comate·智能编程助手·文心快码baiducomate
RFCEO20 小时前
HTML编程 课程五、:HTML5 新增语义化标签
前端·html·html5·跨平台·语义化标签·可生成安卓/ios·html最新版本