You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
5.0 KiB
JavaScript
138 lines
5.0 KiB
JavaScript
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 (
|
|
<>
|
|
<Bullet {...config} data={parseData} />
|
|
</>
|
|
);
|
|
});
|