• react封装echarts仪表盘 吴小明


    1、仪表盘组件

      GaugeChart/index.tsx(组件中的nightFlag是适配黑夜模式,获取公共状态中的值)

    import React, { useEffect, useRef } from 'react'
    import styles from './index.less'
    import { connect } from 'umi'
    import { ConnectState } from '@/models/connect'
    // echarts
    import * as echarts from 'echarts/lib/echarts'
    import 'echarts/lib/chart/gauge'
    
    interface GaugeProps {
      name: string // 仪表盘名称
      unit: string // 单位
      target?: number // 目标值
      sprint?: number // 冲刺值
      current?: number // 当前值
      nightFlag?: boolean // 是否开了黑夜模式
    }
    const GaugeChart: React.FC<GaugeProps> = (props) => {
      let chartInstance: any = null // 图表实例
      const chartRef = useRef(null)
      const { name, unit, target = 0, sprint = 0, current = 0, nightFlag } = props
      const hasTargetAndSprint = !!(target && sprint) // 是否有目标值和冲刺值
    
      const max = (sprint: number, target: number, current: number) => {
        if (sprint) return Math.ceil(sprint / 5) * 5
        if (target) return Math.ceil(target / 5) * 5
        if (current) return Math.ceil(current / 5) * 5
        return 100
      }
      const option = {
        series: [
          {
            type: 'gauge',
            max: max(sprint, target, current), // 最大值的优先级顺序:冲刺值 任务值 当前值 100
            axisLine: {
              roundCap: true,
              lineStyle: {
                 10,
                color: hasTargetAndSprint
                  ? [
                      [target / max(sprint, target, current), '#416EFF'],
                      [1, '#FF6565']
                    ]
                  : [[1, '#416EFF']]
              }
            },
            anchor: {
              show: true,
              showAbove: true,
              size: 12,
              itemStyle: {
                color: '#fff',
                borderColor: current > target && hasTargetAndSprint ? '#FF6565' : '#416EFF',
                borderWidth: 1
              }
            }, // 空心圆圈
            pointer: {  5, length: '55%', offsetCenter: [0, -5], itemStyle: { color: 'auto' } }, // 指针
            axisTick: { distance: 10, length: 8, lineStyle: { color: 'auto',  2 } }, // 虚线
            splitLine: { lineStyle: {  0 } }, // 当前值 虚线 的宽度
            axisLabel: { color: 'inherit', distance: 20, fontSize: 10 }, // 进度数字 0 10 20 30 40 50 60...
            detail: { valueAnimation: true, color: 'inherit', fontSize: 30, offsetCenter: [0, '70%'] }, // 当前值
            data: [
              {
                value: current,
                name: name,
                title: {
                  fontSize: '16',
                  color: nightFlag ? '#fff' : '#373A44',
                  offsetCenter: [0, '90%']
                }
              }
            ]
          }
        ]
      }
    
      // 初始化
      const initChart = () => {
        const renderedInstance = echarts.getInstanceByDom(chartRef.current)
        if (renderedInstance) {
          chartInstance = renderedInstance
        } else {
          chartInstance = echarts.init(chartRef.current)
        }
        chartInstance.setOption(option)
      }
      useEffect(() => {
        initChart()
        return () => {
          chartInstance && chartInstance.dispose()
        }
      }, [nightFlag])
    
      return (
        <div className={styles.gaugeChartContainer}>
          <div
            style={
              hasTargetAndSprint
                ? {  '500px', height: '400px' }
                : {  '500px', height: '400px', opacity: 0.8 }
            }
            ref={chartRef}
          ></div>
          {/* {hasTargetAndSprint ? ( */}
          <ul className={styles.legend}>
            <li>
              <i></i>任务指标:{target}
              {unit}
            </li>
            <li>
              <i></i>冲刺指标:{sprint}
              {unit}
            </li>
          </ul>
          {/* ) : null} */}
        </div>
      )
    }
    
    // export default GaugeChart
    export default connect(({ night: { nightFlag } }: ConnectState) => ({ nightFlag }))(GaugeChart)

      GaugeChart/index.less

    .gaugeChartContainer {
      position: relative;
      margin-bottom: 20px;
      ul.legend {
        position: absolute;
        bottom: 20px;
        display: flex;
        justify-content: space-around;
        width: 100%;
        margin-bottom: 0;
        padding-left: 0;
        li {
          display: flex;
          align-items: center;
          color: var(--theme-text-color);
          font-size: 14px;
          i {
            display: block;
            width: 20px;
            height: 12px;
            margin-right: 8px;
            background-image: linear-gradient(90deg, #6489ff 0%, #416eff 100%);
          }
          &:last-of-type i {
            background-image: linear-gradient(90deg, #ff926d 0%, #ff6565 100%);
          }
        }
      }
    }
    View Code

    2、使用

      gaugeOptions是一个数组(数据结构中label和value是提供给下拉框组件使用的,仪表盘组件中不需要)

    [
        {
            "label": "销售额",
            "value": 0,
            "name": "销售额(万元)",
            "unit": "万元",
            "target": 49.000066,
            "sprint": 100,
            "current": "82.6"
        },
        {
            "label": "实收款",
            "value": 1,
            "name": "实收款(万元)",
            "unit": "万元",
            "target": 0,
            "sprint": 0,
            "current": "82.9"
        },
        {
            "label": "新拓客户",
            "value": 2,
            "name": "新拓客户(个)",
            "unit": "个",
            "target": 51,
            "sprint": 200,
            "current": 0
        },
        {
            "label": "续签客户",
            "value": 3,
            "name": "续签客户(个)",
            "unit": "个",
            "target": 55,
            "sprint": 300,
            "current": 0
        },
        {
            "label": "至尊占比",
            "value": 4,
            "name": "至尊占比(%)",
            "unit": "%",
            "target": 10000,
            "sprint": 0,
            "current": 35.45
        },
        {
            "label": "普及率",
            "value": 5,
            "name": "普及率(%)",
            "unit": "%",
            "target": 45,
            "sprint": 120,
            "current": 25.03
        }
    ]

      DOM

            {gaugeOptions.map((item) => (
              <GaugeChart
                key={item.value}
                unit={item.unit}
                name={item.name}
                target={item.target}
                sprint={item.sprint}
                current={item.current}
              />
            ))}

    3、效果

      

  • 相关阅读:
    ajax异步上传图片&SpringMVC后台代码
    Jdk与Tomcat配置与安装
    Jpa常用注解@Test
    关于ssh和ajax小小总结
    关于EL表达式的大小写问题。谁来帮我解答?
    关于spring管理hibernate事物
    关于session更新的问题
    ssh使用ajax异步通讯. json与对象转换的几个小问题
    通过http Post XML文件的接口 (System.Web.IHttpHandler)
    HTTP Post方法
  • 原文地址:https://www.cnblogs.com/wuqilang/p/15963390.html
Copyright © 2020-2023  润新知