perf: 老客户: 订单走势
parent
12e99bb816
commit
6ea43a58e2
@ -0,0 +1,168 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Row, Col, Spin } from 'antd';
|
||||
import { Line } from '@ant-design/plots';
|
||||
import { observer } from 'mobx-react';
|
||||
import { dataFieldAlias } from '../libs/ht';
|
||||
import DateGroupRadio from '../components/DateGroupRadio';
|
||||
import { cloneDeep, groupBy, sortBy } from '../utils/commons';
|
||||
|
||||
export default observer((props) => {
|
||||
const { dataSource: rawData, showAVG, showSUM, loading, ...config } = props;
|
||||
const { xField, yField, yFieldAlias, seriesField } = config;
|
||||
|
||||
const [dataBeforeXChange, setDataBeforeXChange] = useState([]);
|
||||
|
||||
const [dataSource, setDataSource] = useState([]);
|
||||
const [sumSeries, setSumSeries] = useState([]);
|
||||
|
||||
const line_config = {
|
||||
// data: dataSource,
|
||||
padding: 'auto',
|
||||
xField,
|
||||
yField,
|
||||
seriesField,
|
||||
// seriesField: 'rowLabel',
|
||||
// xAxis: {
|
||||
// type: 'timeCat',
|
||||
// },
|
||||
yAxis: {
|
||||
min: 0,
|
||||
maxTickInterval: 5,
|
||||
},
|
||||
meta: {
|
||||
...cloneDeep(dataFieldAlias),
|
||||
},
|
||||
// smooth: true,
|
||||
label: {}, // 显示标签
|
||||
legend: {
|
||||
position: 'right-top',
|
||||
// title: {
|
||||
// text: '总合计 ' + dataSource.reduce((a, b) => a + b.SumOrder, 0),
|
||||
// },
|
||||
itemMarginBottom: 12, // 垂直间距
|
||||
},
|
||||
tooltip: {
|
||||
customItems: (originalItems) => {
|
||||
return originalItems
|
||||
.map((ele) => ({ ...ele, valueR: ele.data[yField] }))
|
||||
.sort(sortBy('valueR'))
|
||||
.reverse();
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const [lineConfig, setLineConfig] = useState(cloneDeep(line_config));
|
||||
|
||||
useEffect(() => {
|
||||
resetX();
|
||||
|
||||
return () => {};
|
||||
}, [rawData]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (lineChartX === 'day') {
|
||||
setDataBeforeXChange(dataSource);
|
||||
}
|
||||
|
||||
return () => {};
|
||||
}, [dataSource]);
|
||||
|
||||
// 日月年切换
|
||||
const [lineChartX, setLineChartX] = useState('day');
|
||||
const orderCountDataMapper = { data1: 'data1', data2: undefined };
|
||||
const orderCountDataFieldMapper = { 'dateKey': xField, 'valueKey': yField, 'seriesKey': seriesField, _f: 'sum' };
|
||||
const resetX = () => {
|
||||
setLineChartX('day');
|
||||
setDataSource(rawData);
|
||||
setDataBeforeXChange(rawData);
|
||||
// 初始化`平均`线, `总计`线
|
||||
const byDays = groupBy(rawData, xField);
|
||||
const sumY = rawData.reduce((a, b) => a + b[yField], 0);
|
||||
const avgVal = Math.round(sumY / (Object.keys(byDays).length));
|
||||
const avgLine = [
|
||||
{ type: 'text', position: ['start', avgVal], content: avgVal, offsetX: -15, style: { fill: '#F4664A', textBaseline: 'bottom' } },
|
||||
{ type: 'line', start: [-10, avgVal], end: ['max', avgVal], style: { stroke: '#F4664A', lineDash: [2, 2] } },
|
||||
];
|
||||
setLineConfig({ ...lineConfig, yField, xField, annotations: avgLine });
|
||||
if (showSUM) {
|
||||
const _sumLine = Object.keys(byDays).reduce((r, _d) => {
|
||||
const summaryVal = byDays[_d].reduce((rows, row) => rows + row[yField], 0);
|
||||
r.push({ ...byDays[_d][0], [yField]: summaryVal, [seriesField]: '总计' });
|
||||
return r;
|
||||
}, []);
|
||||
// console.log(_sumLine.map((ele) => ele[yField]));
|
||||
setSumSeries(_sumLine);
|
||||
}
|
||||
};
|
||||
|
||||
const onChangeXDateFieldGroup = (value, data, avg1) => {
|
||||
// console.log(value, data, avg1);
|
||||
const _sumLine = [];
|
||||
const { xField, yField, seriesField } = lineConfig;
|
||||
const groupByDate = data.reduce((r, v) => {
|
||||
(r[v[xField]] || (r[v[xField]] = [])).push(v);
|
||||
return r;
|
||||
}, {});
|
||||
// console.log(groupByDate);
|
||||
const _data = Object.keys(groupByDate).reduce((r, _d) => {
|
||||
const summaryVal = groupByDate[_d].reduce((rows, row) => rows + row[yField], 0);
|
||||
_sumLine.push({ ...groupByDate[_d][0], [yField]: summaryVal, [seriesField]: '总计' });
|
||||
|
||||
const xAxisGroup = groupByDate[_d].reduce((a, v) => {
|
||||
(a[v[seriesField]] || (a[v[seriesField]] = [])).push(v);
|
||||
return a;
|
||||
}, {});
|
||||
// console.log(xAxisGroup);
|
||||
Object.keys(xAxisGroup).map((_group) => {
|
||||
const summaryVal = xAxisGroup[_group].reduce((rows, row) => rows + row[yField], 0);
|
||||
r.push({ ...xAxisGroup[_group][0], [yField]: summaryVal, });
|
||||
return _group;
|
||||
});
|
||||
return r;
|
||||
}, []);
|
||||
// const _sum = Object.values(groupBy(_data, 'dateGroup')).reduce((ac, b) => ({...b, [yField]: 0}), {});
|
||||
// console.log(xField, avg1);
|
||||
// console.log('date source=====', _data);
|
||||
setLineChartX(value);
|
||||
setDataSource(_data);
|
||||
if (showSUM) {
|
||||
setSumSeries(_sumLine);
|
||||
}
|
||||
|
||||
// setAvgLine1(avg1);
|
||||
const avg1Int = Math.round(avg1);
|
||||
const mergedConfig = { ...lineConfig,
|
||||
annotations: [
|
||||
{ type: 'text', position: ['start', avg1Int], content: avg1Int, offsetX: -15, style: { fill: '#F4664A', textBaseline: 'bottom' } },
|
||||
{ type: 'line', start: [-10, avg1Int], end: ['max', avg1Int], style: { stroke: '#F4664A', lineDash: [2, 2] } },
|
||||
],
|
||||
};
|
||||
// console.log(mergedConfig);
|
||||
setLineConfig(mergedConfig);
|
||||
};
|
||||
return (
|
||||
<section>
|
||||
<Row gutter={16} justify={'space-between'} className="mb-1">
|
||||
<Col flex={'auto'}>
|
||||
<h3>
|
||||
走势: <span style={{ fontSize: 'smaller' }}>{dataFieldAlias[lineConfig.yField].label}</span>
|
||||
</h3>
|
||||
</Col>
|
||||
<Col style={{ textAlign: 'right' }} align={'end'}>
|
||||
<DateGroupRadio
|
||||
visible={true}
|
||||
dataRaw={{ data1: dataBeforeXChange }}
|
||||
onChange={onChangeXDateFieldGroup}
|
||||
value={lineChartX}
|
||||
dataMapper={orderCountDataMapper}
|
||||
fieldMapper={orderCountDataFieldMapper}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Spin spinning={loading}>
|
||||
<Line {...lineConfig} data={[].concat(dataSource, sumSeries)} />
|
||||
</Spin>
|
||||
</section>
|
||||
);
|
||||
});
|
Loading…
Reference in New Issue