import { useEffect, useState } from 'react'; import { observer } from 'mobx-react'; import { Bullet } from '@ant-design/plots'; import { sortBy, merge, isEmpty } from '../utils/commons'; import { dataFieldAlias } from '../libs/ht'; export default observer((props) => { const { dataSource, itemLength, ...extProps } = props; // 处理进度图的数据格式, number -> array const dataParser = (origin) => { const { measureField, rangeField, targetField } = extProps; const measureFieldArrKey = `${measureField}_arr`; const maxKPI = Math.max(...(origin || []).map((ele) => (ele?.[targetField] || 0))); const maxValue = Math.max(...(origin || []).map((ele) => ele[measureField])); const _max = Math.max(maxKPI, maxValue); const sortData = origin.sort(sortBy(measureField)).slice(-itemLength); // 顶格的值定在更远 const _parseData = sortData?.map((ele) => ({ ...ele, [rangeField]: [0, Math.ceil(_max / 0.9)], // [measureField]: [ele[measureField]], [measureField]: ele[measureFieldArrKey] || [ele[measureField]], [targetField]: (ele?.[targetField] || 0) })); return _parseData; }; const dataMapped = dataSource.reduce((r, v) => ({...r, [v.groupsLabel]: v}), {}); const ifMergeTB = isEmpty(dataSource) ? false : !isEmpty(dataSource[0]?.[`${extProps.measureField}_arr`]); const [parseData, setParseData] = useState([]); useEffect(() => { setParseData(dataParser(dataSource)); return () => {}; }, [extProps.measureField, dataSource]); const config = merge({ color: { range: [ '#FFF3E1', '#FFF3E1'], // range: [ '#FFF3E1', '#FFF3E1', '#FFe0b0', '#bfeec8'], // '#FFbcb8', '#FFe0b0', measure: ['#5B8FF9', '#61ddaa'], target: '#FF9845', }, label: { target: false, measure: { position: extProps?.layout === 'vertical' ? 'top' : 'right', // formatter: (v, ...d) => { // return dataFieldAlias[extProps.measureField]?.formatter(v[extProps.measureField]) || v; // }, content: (item, ...r) => { const val = isEmpty(dataMapped) ? 0 : dataMapped[item.groupsLabel][extProps.measureField]; return String(item?.mKey || '_0').endsWith('_0') ? '' : dataFieldAlias[extProps.measureField]?.formatter(val) || val; } }, }, xAxis: { line: null, label: { autoHide: false, autoRotate: true, }, }, yAxis: false, // 自定义 legend legend: { custom: true, position: 'bottom', items: [ { value: ifMergeTB ? '传统' : '实际', name: ifMergeTB ? '传统' : '实际', marker: { symbol: 'square', style: { fill: '#5B8FF9', r: 5, }, }, }, ...(ifMergeTB ? [{ value: '商务', name: '商务', marker: { symbol: 'square', style: { fill: '#61ddaa', r: 5, }, }, }] : []), { value: '目标', name: '目标', marker: { symbol: 'line', style: { stroke: '#FF9845', // '#39a3f4', r: 5, }, }, }, ], }, // ? 全局的alias不起作用 tooltip: { customItems: (originalItems) => { // process originalItems, const measureIndex = originalItems[0].name.split('_'); const measureKey = measureIndex[0]; const measureName = measureKey.endsWith('KPIvalue') ? '' : measureIndex[1] === 0 ? '传统' : '商务'; const measureFieldArrKey = `${measureKey}_arr`; const kpiKey = dataFieldAlias[measureKey]?.nestkey?.v; const mItems = (measureName && !String(measureKey).toLowerCase().endsWith('rates')) ? originalItems.reduce((r, ele) => { const _itemMeasures = dataMapped[ele.title][measureFieldArrKey]; r.push({ ...ele, color: '#5B8FF9', value: dataFieldAlias[measureKey]?.formatter(Number(_itemMeasures[0])), name: '传统' }); r.push({ ...ele, color: '#61ddaa', value: dataFieldAlias[measureKey]?.formatter(Number(_itemMeasures[1])), name: '商务' }); const _itemMeasureKPIv = dataMapped[ele.title][kpiKey]; if (kpiKey && _itemMeasureKPIv) { r.push({ ...ele, color: '#FF9845', value: dataFieldAlias[measureKey]?.formatter(Number(_itemMeasureKPIv)), name: dataFieldAlias[kpiKey].label }); } return r; }, []) : originalItems.map((ele) => ({ ...ele, value: dataFieldAlias[measureKey]?.formatter(Number(ele.value)), name: dataFieldAlias[measureKey]?.alias || measureKey, })); return mItems; }, }, }, extProps); return ( <> ); });