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: { width: 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: { width: 5, length: '55%', offsetCenter: [0, -5], itemStyle: { color: 'auto' } }, // 指针 axisTick: { distance: 10, length: 8, lineStyle: { color: 'auto', width: 2 } }, // 虚线 splitLine: { lineStyle: { width: 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 ? { width: '500px', height: '400px' } : { width: '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、效果
标签:current,封装,target,color,react,sprint,echarts,unit,name 来源: https://www.cnblogs.com/wuqilang/p/15963390.html