/** @format */ import _ from 'lodash'; import React, { useEffect, useState } from 'react'; import zrender from 'zrender'; import { customMergeWith } from '../../../utils'; import { globalTheme, ThemeData } from '../../../utils/theme'; import Echarts from '../Echarts'; import { Container } from './styled'; interface SCBarChartProps { size?: { width: number; height: number; }; option?: Record; data?: Record; theme?: ThemeData; } const SCBarChart = (props: SCBarChartProps) => { const { size = { height: 500 }, option = {}, data, data: { xData = [], yData = [] } = {}, theme = { /** * 文本颜色 */ textColor: 'red', /** * 组件主色 */ primaryColor: '#50E1', secondColor: '#FDAFFF', thirdColor: '#DDD', colorList: ['#50E1', '#FDA568', '#DDD'], }, } = props; const themeList = theme ? theme : globalTheme; const [isLegendShow, setIsLegendShow] = useState(false); const [colorArray, setColorArray] = useState([]); const [seriesNameArray, setSeriesNameArray] = useState([]); const optionBase = { color: [...themeList.colorList], legend: { show: false, padding: 2, itemGap: 16, left: 'right', itemWidth: 8, itemHeight: 8, orient: 'horizontal', textStyle: { fontFamily: 'Microsoft Yahei', fontWeight: 'normal', fontSize: 12, color: '#999', }, icon: 'circle', }, tooltip: { show: true, trigger: 'axis', triggerOn: 'mousemove', axisPointer: { type: '', }, hideDelay: 100, textStyle: { fontFamily: 'Microsoft Yahei', fontWeight: 'normal', fontSize: 14, color: themeList.textColor, }, }, grid: { left: 30, right: 40, bottom: 30, top: 30, containLabel: true, }, xAxis: { type: 'category', show: true, name: '', data: [], axisTick: { alignWithLabel: true, show: false, }, axisLabel: { show: true, color: themeList.textColor, fontWeight: 'normal', fontFamily: 'Microsoft YaHei', fontSize: 12, rotate: 0, interval: 0, }, axisLine: { show: true, lineStyle: { color: '#363A43' }, }, splitLine: { show: false, lineStyle: { color: '#999', type: 'dashed' }, }, }, yAxis: { name: '', type: 'value', min: null, max: null, nameTextStyle: { color: '#fff', }, axisTick: { show: false, }, axisLabel: { show: true, color: '#999', fontWeight: 'normal', fontFamily: 'Microsoft YaHei', fontSize: 12, interval: 'auto', formatter: '{value}', }, axisLine: { show: true, lineStyle: { color: '#363A43' }, }, splitLine: { show: true, lineStyle: { color: 'rgb(54 58 67 / .8)', type: 'dashed' }, }, }, series: [ { name: '直接访问', type: 'bar', data: [], label: { show: true, color: themeList.textColor, fontWeight: 'normal', align: 'center', fontFamily: 'Microsoft YaHei', fontSize: 12, position: 'insideTop', }, }, ], animation: true, animationEasing: 'cubicOut', animationEasingUpdate: 'cubicOut', animationDuration: 500, animationDurationUpdate: 300, }; const baseSeriesItemStyle = { barBorderRadius: 0, }; const [latestOption, setLatestOption] = useState(optionBase); function formatSeries(data: Record, index: number, op = {}) { const series = (option && option.series && option.series[index]) || {}; const r = { name: series.name || `系列${index + 1}`, type: series.type || 'bar', data: data, markPoint: series.markPoint ? { ...series.markPoint, symbol: 'pin', //使用此方式隐藏图标 symbolSize: 0.1, symbolOffset: [0, -10], label: { color: colorArray[index], fontSize: 16, fontWeight: 'lighter', }, } : {}, itemStyle: customMergeWith(series.itemStyle, baseSeriesItemStyle), // barCategoryGap: series.barCategoryGap || null, // barGap: '100%', label: series.label, barWidth: series.barWidth, barCategoryGap: series.barCategoryGap, stack: series.stack ? series.stack : '', showBackground: series.showBackground, // 背景阴影 backgroundStyle: series.backgroundStyle, // 阴影颜色 }; // 处理柱图是渐变色的情况 if ( series.itemStyle && series.itemStyle.colorLinear && series.itemStyle.color2 && series.itemStyle.color1 ) { r.itemStyle.color = new zrender.LinearGradient(0, 0, 0, 1, [ { offset: 1, color: series.itemStyle.color2, }, { offset: 0, color: series.itemStyle.color1, }, ]); } return r; const latestSeries = _.mergeWith(r, op); latestSeries.data = data; return latestSeries; } useEffect(() => { const mergedOption = customMergeWith(optionBase, option, { xAxis: { data: xData }, series: yData.map((item: Record, index: number) => { return formatSeries(item, index, option.series && option.series[index]); }), }); // legend不以默认方式显示,自定义样式 if (mergedOption.legend && mergedOption.legend.show) { // mergedOption.legend.show = false; // setIsLegendShow(false); } setLatestOption(mergedOption); setColorArray(mergedOption.color); setSeriesNameArray( mergedOption.series.map((item: Record) => item.name), ); }, [theme.primaryColor, option, data]); return ( {isLegendShow ? (
{seriesNameArray && seriesNameArray.length ? seriesNameArray.map((itemName, index) => { const color = colorArray[index % colorArray.length]; return (
{/*
*/} {latestOption.series[index].type === 'bar' ? (
) : (
)}
{itemName}
); }) : null}
) : null}
); }; export default SCBarChart;