/** @format */ import _ from 'lodash'; import React, { useEffect, useRef, useState } from 'react'; import zrender from 'zrender'; import Echarts from '../Echarts'; interface BarLineChartProps { size?: Record; [key: string]: any; } const BarLineChart = (props: BarLineChartProps) => { const { size = { height: 500 }, option = {}, data, data: { xData = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'], yData = [ [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6], [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6], [2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3], ], } = {}, } = props; const [showTip, setShowTip] = useState({ isShow: false, seriesIndex: 0, dataIndex: 0, x: 0, y: 0, }); const optionBase = { color: ['#3398DB', '#9F4DF0'], tooltip: { show: true, trigger: 'axis', triggerOn: 'mousemove', axisPointer: { type: 'shadow', }, hideDelay: 100, textStyle: { fontFamily: 'Microsoft Yahei', fontWeight: 'normal', fontSize: 14, color: '#fff', }, }, legend: { show: true, padding: 2, itemGap: 5, left: 'center', itemWidth: 8, itemHeight: 4, orient: 'horizontal', textStyle: { fontFamily: 'Microsoft Yahei', fontWeight: 'normal', fontSize: 12, color: 'white', }, }, grid: { left: 30, right: 40, bottom: 30, top: 30, containLabel: true, }, xAxis: { type: 'category', show: true, name: '', data: xData, axisTick: { alignWithLabel: true, show: false, }, axisLabel: { show: true, color: '#fff', fontWeight: 'normal', fontFamily: 'Microsoft YaHei', fontSize: 12, rotate: 0, interval: 0, }, axisLine: { show: true, lineStyle: { color: '#fff', width: 1 }, }, splitLine: { show: false, lineStyle: { color: '#999', type: 'dashed' }, }, }, yAxis: [ { type: 'value', min: 0, max: 250, axisTick: { show: false, }, nameTextStyle: 'red', axisLine: { show: true, lineStyle: { color: '#fff' }, }, splitLine: { show: false, lineStyle: { color: '#aaa', type: 'dashed' }, }, axisLabel: { show: true, color: '#fff', fontWeight: 'normal', fontFamily: 'Microsoft YaHei', fontSize: 12, interval: 'auto', formatter: '{value} ', }, }, { type: 'value', min: 0, max: 25, axisTick: { show: false, }, axisLine: { show: true, lineStyle: { color: '#fff' }, }, splitLine: { show: false, lineStyle: { color: '#aaa', type: 'dashed' }, }, nameTextStyle: 'red', axisLabel: { show: true, color: '#fff', fontWeight: 'normal', fontFamily: 'Microsoft YaHei', fontSize: 12, interval: 'auto', formatter: '{value} ', }, }, ], series: [ { name: '直接访问', type: 'bar', data: [], symbolSize: 10, // 折线点大小 symbol: 'circle', // 折线点形状 label: { show: true, color: '#fff', fontWeight: 'normal', align: 'center', fontFamily: 'Microsoft YaHei', fontSize: 12, position: 'insideTop', }, }, ], animation: true, animationEasing: 'cubicOut', animationEasingUpdate: 'cubicOut', animationDuration: 500, animationDurationUpdate: 300, }; const [latestOption, setLatestOption] = useState(optionBase); function formatSeries(data: Record[], index: number) { const serie = (option.series && option.series[index]) || {}; const area = { opacity: 1, color: { type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: '#3398DB', // 0% 处的颜色 }, { offset: 1, color: 'rgba(9,9,9,0)', // 100% 处的颜色 }, ], global: false, // 缺省为 false }, }; const label = { show: true, color: '#999', fontWeight: 'normal', align: 'center', fontFamily: 'Microsoft YaHei', fontSize: 12, position: 'top', }; const r = { name: serie.name, type: serie.type || 'bar', data: data, itemStyle: serie.itemStyle, barCategoryGap: serie.barCategoryGap || null, yAxisIndex: serie.yAxisIndex || 0, barGap: serie.barGap, barWidth: serie.barWidth, animation: serie.animation, symbolSize: serie.symbolSize, symbol: serie.symbol, showBackground: serie.showBackground, // 背景阴影 backgroundStyle: serie.backgroundStyle, // 阴影颜色 label: _.merge(label, serie.label), // 阴影颜色 lineStyle: serie.lineStyle, areaStyle: _.merge(area, serie.areaStyle), smooth: serie.smooth, }; // 处理柱图是渐变色的情况 if ( serie.itemStyle && serie.itemStyle.colorLinear && serie.itemStyle.color2 && serie.itemStyle.color1 ) { r.itemStyle.color = new zrender.LinearGradient(0, 0, 0, 1, [ { offset: 1, color: serie.itemStyle.color2, }, { offset: 0, color: serie.itemStyle.color1, }, ]); } return r; } function setData() { const latestOption = _.mergeWith(optionBase, option); latestOption.series = yData.map( (item: Record[], index: number) => formatSeries(item, index), ); // y轴formatter latestOption.yAxis = latestOption.yAxis.map((item: any, index: number) => { if ( item.axisLabel.formatter !== '{value} ' && item.axisLabel.formatter !== '{value}' ) { item.axisLabel.formatter = `{value}${item.axisLabel.formatter}`; } return item; }); setShowTip({ isShow: option?.tooltip?.isShowToolTip || false, seriesIndex: 1, dataIndex: option?.tooltip?.dataIndex - 1, x: Number(option?.tooltip?.x), y: Number(option?.tooltip?.y), }); setLatestOption(latestOption); } useEffect(() => { setData(); }, [option, data]); return ; }; export default BarLineChart;