feat: 看板: 年度对比; 切换groupType

feature/year-over-year
Lei OT 2 years ago
parent 6ea675f453
commit 9e87278cef

@ -4,33 +4,45 @@ import { merge, isEmpty, groupBy, sortBy } from '../utils/commons';
import { dataFieldAlias } from '../libs/ht'; import { dataFieldAlias } from '../libs/ht';
export default observer((props) => { export default observer((props) => {
const { dataSource, ...config } = props; const { dataSource, showKPI, ...config } = props;
const kpiKey = dataFieldAlias[config.yField]?.nestkey?.v; const kpiKey = dataFieldAlias[config.yField]?.nestkey?.v;
const seriesData = groupBy(dataSource, ele => ele[config.seriesField]); const seriesData = groupBy(dataSource, ele => ele[config.seriesField]);
const splitData = dataSource.reduce((r, v) => { const splitData = showKPI ? dataSource.reduce((r, v) => {
r.push(v); r.push(v);
if ( ! isEmpty(v[kpiKey])) { // 线, 线 if ( ! isEmpty(v[kpiKey])) { // 线, 线
r.push({...v, [config.yField]: v[kpiKey], [config.seriesField]: `${v[config.seriesField]} ${dataFieldAlias[kpiKey].label}`, extraLine: true,}); r.push({...v, [config.yField]: v[kpiKey], [config.seriesField]: `${v[config.seriesField]} ${dataFieldAlias[kpiKey].label}`, extraLine: true,});
} }
return r; return r;
}, []).sort(sortBy(config.xField)); }, []).sort(sortBy(config.xField)) : dataSource;
const dataColors = [ const dataColors = [
"#5B8FF9","#5AD8A6","#5D7092","#F6BD16","#6F5EF9","#6DC8EC","#945FB9","#FF9845","#1E9493", "#5D7092","#F6BD16","#6F5EF9","#6DC8EC","#945FB9","#FF9845","#1E9493",
"#FF99C3","#FF6B3B","#626681","#FFC100","#9FB40F","#76523B","#DAD5B5","#0E8E89","#E19348", "#FF99C3","#FF6B3B","#626681","#FFC100","#9FB40F","#76523B","#DAD5B5",
"#F383A2","#247FEA", "#0E8E89","#E19348","#F383A2","#247FEA","#5B8FF9","#5AD8A6",
]; ];
const colorSets = Object.keys(seriesData).sort().reduce((obj, k, i) => ({...obj, [k]: dataColors[i]}), {}); const colorSets = Object.keys(seriesData)
const mergeLineConfig = merge({ .sort()
.filter((ele) => !ele.includes(' '))
.reduce((obj, k, i) => ({ ...obj, [k]: dataColors[i] || dataColors[i % 20] }), {});
// console.log('colorSets', colorSets);
const mergeLineConfig = merge(
{
color: (item) => { color: (item) => {
const thisSeries = item[config.seriesField]?.split(' ')?.[0]; const thisSeries = item[config.seriesField]?.split(' ')?.[0];
return colorSets[thisSeries]; return colorSets[thisSeries];
// return thisSeries.includes('') ? '#F4664A' : colorSets[thisSeries];
}, },
lineStyle: (data) => { lineStyle: (data) => {
if (data[config.seriesField].includes('目标')) { if (data[config.seriesField].includes('目标')) {
return {
lineDash: [8, 20],
opacity: 0.5,
};
}
if (data[config.seriesField].includes('@')) {
return { return {
lineDash: [4, 8], lineDash: [4, 8],
opacity: 0.7, opacity: 0.6,
lineWidth: 1.5,
}; };
} }
@ -40,8 +52,42 @@ export default observer((props) => {
}, },
legend: { legend: {
custom: true, custom: true,
items: Object.keys(seriesData).map((ele) => ({ id: ele, name: ele, value: ele, marker: { symbol: 'circle', style: { fill: colorSets[ele], color: colorSets[ele] } } })), items: Object.keys(seriesData).map((ele) => ({
id: ele,
name: ele,
value: ele,
marker: { symbol: ele.includes(' ') ? 'hyphen' : 'circle', style: { fill: colorSets[ele], stroke: colorSets[ele?.split(' ')?.[0]], r: 3, lineWidth: 2, color: colorSets[ele] } },
})),
},
// annotations: [
// // 0
// {
// type: 'regionFilter',
// start: ['min', 0],
// end: ['max', 0],
// color: '#F4664A',
// },
// {
// type: 'text',
// position: ['min', 0],
// content: '0',
// offsetY: -4,
// style: {
// textBaseline: 'bottom',
// },
// },
// {
// type: 'line',
// start: ['min', 0],
// end: ['max', 0],
// style: {
// stroke: '#F4664A',
// lineDash: [2, 2],
// },
// },
// ],
}, },
}, config); config
);
return <Line {...mergeLineConfig} data={splitData} />; return <Line {...mergeLineConfig} data={splitData} />;
}); });

@ -3,26 +3,6 @@ import { Mix } from '@ant-design/plots';
import { merge, isEmpty, groupBy, cloneDeep } from '../utils/commons'; import { merge, isEmpty, groupBy, cloneDeep } from '../utils/commons';
import { dataFieldAlias } from '../libs/ht'; import { dataFieldAlias } from '../libs/ht';
const uniqueByKey = (array, key, pickLast) => {
const seen = new Map();
const isPickLast = pickLast === true;
return array.filter((item) => {
const k = item[key];
const storedItem = seen.get(k);
if (storedItem) {
if (isPickLast) {
seen.set(k, item); // update with last item
}
return false;
}
seen.set(k, item);
return true;
});
};
export default observer((props) => { export default observer((props) => {
const { dataSource, summaryData: areaData, ...config } = props; const { dataSource, summaryData: areaData, ...config } = props;
const kpiKey = dataFieldAlias[config.yField]?.nestkey?.v; const kpiKey = dataFieldAlias[config.yField]?.nestkey?.v;
@ -61,7 +41,7 @@ export default observer((props) => {
meta: { meta: {
[yField]: { [yField]: {
sync: true, sync: true,
} },
}, },
// color: ['#598cf3', '#69deae', '#F4664A', '#FAAD14'], // color: ['#598cf3', '#69deae', '#F4664A', '#FAAD14'],
color: (item) => { color: (item) => {
@ -117,22 +97,39 @@ export default observer((props) => {
}, },
{ [xField]: { sync: true }, [yField]: { sync: true } } { [xField]: { sync: true }, [yField]: { sync: true } }
), ),
// color: '#b32b19',
color: '#f58269', color: '#f58269',
smooth: true, // color: (datum) => {
// console.log('color', datum, String(datum[seriesField]).includes(''));
// return String(datum[seriesField]).includes('') ? '#f7a593' : '#f58269';
// }, // '#f58269',
// smooth: true,
line: { line: {
size: 0.1, size: 1,
style: (datum) => {
return String(datum[seriesField]).includes('对比')
? {
// lineWidth: 0.1,
lineDash: [4, 5],
stroke: '#f7a593',
}
: {
stroke: '#f58269',
};
}, },
areaStyle: () => { },
return { areaStyle: (datum) => {
// console.log('areaStyle', datum);
return String(datum[seriesField]).includes(' ')
? {
fill: 'l(270) 0:#ffffff 0.25:#f8e8e7 0.5:#fac9bd 0.75:#fac9bd',
}
: {
fill: 'l(270) 0:#ffffff 0.25:#f8e8e7 0.5:#fac9bd 0.75:#f7a593', fill: 'l(270) 0:#ffffff 0.25:#f8e8e7 0.5:#fac9bd 0.75:#f7a593',
// lineWidth: 0.1, // lineWidth: 0.1,
// lineOpacity: 0.5, // lineOpacity: 0.5,
}; };
}, },
label: { label: (datum) => ({ offsetY: -8 }),
offsetY: -8,
},
annotations: areaData.map((d) => { annotations: areaData.map((d) => {
return { return {
type: 'dataMarker', type: 'dataMarker',

@ -257,6 +257,13 @@ export default observer((props) => {
legend: false, // {}, legend: false, // {},
color: COLOR_SETS, color: COLOR_SETS,
annotations: diffLine, annotations: diffLine,
minColumnWidth: 5,
maxColumnWidth: 5,
// ()
dodgePadding: 1,
// ()
// intervalPadding: 20,
}, },
}, },
], ],

@ -75,7 +75,7 @@ export default observer((props) => {
description: diff ? ( description: diff ? (
<Space> <Space>
<Statistic title={diff.label} value={` ${diff.value}`} /> <Statistic title={diff.label} value={` ${diff.value}`} />
{diff.VSrate && <Statistic title="同比" value={`${diff.VSrate}%`} trend={diff.VSrate > 0 ? 'up' : 'down'} />} {diff.VSrate && <Statistic title="" value={`${diff.VSrate}%`} trend={diff.VSrate > 0 ? 'up' : 'down'} />}
</Space> </Space>
) : null, ) : null,
}} }}

@ -51,7 +51,7 @@ class DatePickerCharts extends Component {
locale={locale} locale={locale}
placeholder={"对比 Year"} placeholder={"对比 Year"}
onChange={(value) => { onChange={(value) => {
const fullYear = [value.clone().set('month', 0).set('date', 1), value.clone().set('month', 11).set('date', 31)]; const fullYear = value ? [value.clone().set('month', 0).set('date', 1), value.clone().set('month', 11).set('date', 31)] : undefined;
if (typeof this.props.onChange === 'function') { if (typeof this.props.onChange === 'function') {
this.props.onChange(fullYear); this.props.onChange(fullYear);
} }

@ -19,6 +19,10 @@ class Trade {
const curQueryData = cloneDeep(queryData); const curQueryData = cloneDeep(queryData);
curQueryData.groupType = curQueryData?.groupType || 'overview'; curQueryData.groupType = curQueryData?.groupType || 'overview';
curQueryData.groupDateType = 'year'; curQueryData.groupDateType = 'year';
if (isEmpty(curQueryData.DateDiff1)) {
curQueryData.DateDiff1 = moment(curQueryData.Date1).subtract(1, 'year').format(DATE_FORMAT);
curQueryData.DateDiff2 = moment(curQueryData.Date2).subtract(1, 'year').format(SMALL_DATETIME_FORMAT);
}
const multiData = await this.fetchTradeDataAll((curQueryData)); const multiData = await this.fetchTradeDataAll((curQueryData));
const { summary, traditional, biz } = multiData.result1; const { summary, traditional, biz } = multiData.result1;
const { summary: summary2, traditional: traditional2, biz: biz2 } = multiData.result2; const { summary: summary2, traditional: traditional2, biz: biz2 } = multiData.result2;
@ -137,16 +141,59 @@ class Trade {
queryData.groupType = queryData?.groupType || 'overview'; queryData.groupType = queryData?.groupType || 'overview';
Object.assign(queryData, { groupDateType: this.timeLineKey }); Object.assign(queryData, { groupDateType: this.timeLineKey });
const multiData = await this.fetchTradeDataAll(cloneDeep(queryData)); const multiData = await this.fetchTradeDataAll(cloneDeep(queryData));
const { traditional, biz } = multiData.result1; const { traditional, biz, summaryRows: summaryRows1, } = multiData.result1;
const { summary: summary2, traditional: traditional2, biz: biz2 } = multiData.result2; // const { summaryRows: summaryRows2, mergeRows: mergeRows2 } = multiData.result2;
console.log(biz, 'mmmmmmmm', queryData, multiData); // console.log(biz, 'mmmmmmmm', queryData, multiData);
const mergeData = [].concat(traditional, biz); const mergeData = [].concat(traditional, biz);
const dateKeyData = groupBy(mergeData, ele => ele.groupDateVal); const dateKeyData = groupBy(mergeData, ele => ele.groupDateVal);
const sortByDateKey = Object.values(sortKeys(dateKeyData)).reduce( (a, b) => a.concat(b), []); const sortByDateKey = Object.values(sortKeys(dateKeyData)).reduce( (a, b) => a.concat(b), []);
runInAction(() => { runInAction(() => {
this.timeData.loading = false; this.timeData.loading = false;
this.timeData.dataSource = sortByDateKey; this.timeData.dataSource = sortByDateKey;
this.timeData.origin = multiData.result1; this.timeData.origin = { summaryRows: summaryRows1 || [] }; // multiData.result1;
});
}
/**
* 有对比的时间轴
*/
async fetchTradeDataDiffByDate(queryData = {}) {
this.timeDiffData.loading = true;
queryData = Object.assign({}, this.searchPayloadHome, queryData); // queryData || this.searchPayloadHome;
queryData.groupType = queryData?.groupType || 'overview';
Object.assign(queryData, { groupDateType: this.timeLineKey });
const multiData = await this.fetchTradeDataAll(cloneDeep(queryData));
const { mergeRows: mergeRows1 } = multiData.result1;
const { mergeRows: mergeRows2 } = multiData.result2;
// console.log(biz, 'mmmmmmmm', queryData, multiData);
// 为了图表的X轴一致
const allDateKey1 = [...new Set(mergeRows1.reduce((rv, vk) => {
rv.push(vk.groupDateVal);
return rv;
}, []))].sort();
const allDateKey2 = [...new Set(mergeRows2.reduce((rv, vk) => {
rv.push(vk.groupDateVal);
return rv;
}, []))].sort();
const allLabelDateKeyMapped = {
...allDateKey2.reduce((obj, k, i) => ({...obj, [k]: allDateKey1[i] || `_${k}`}), {})
};
const mergeKeyDateRows = [].concat(
mergeRows1 || [],
(mergeRows2 || []).map((row, ri) => {
return {
...row,
groupsLabel: `${row.groupsLabel} @${moment(queryData.DateDiff1).year()}`,
groupDateVal: allLabelDateKeyMapped[row.groupDateVal],
rawGroupDateVal: row.groupDateVal,
};
})
).sort(sortBy('groupDateVal'));
runInAction(() => {
this.timeDiffData.loading = false;
this.timeDiffData.dataSource = mergeKeyDateRows;
}); });
} }
@ -291,18 +338,26 @@ class Trade {
this.targetTableProps.dataSource = [].concat(Object.values(finalTargetData.targetGuest), Object.values(finalTargetData.targetCountry)); // [finalTargetData.targetTotal], // todo: 总数是重复的 this.targetTableProps.dataSource = [].concat(Object.values(finalTargetData.targetGuest), Object.values(finalTargetData.targetCountry)); // [finalTargetData.targetTotal], // todo: 总数是重复的
}; };
setStateSearch(body) { searchValues = {};
setSearch(body, form) {
this.searchPayloadHome = body; this.searchPayloadHome = body;
this.searchValues = form;
} }
timeLineKey = 'week'; timeLineKey = 'month';
setTimeLineKey(v) { setTimeLineKey(v) {
this.timeLineKey = v; this.timeLineKey = v;
} }
groupKey = 'overview';
setGroupKey(v) {
this.groupKey = v;
}
resetData = () => { resetData = () => {
this.summaryData = { loading: false, dataSource: [], kpi: {}, }; this.summaryData = { loading: false, dataSource: [], kpi: {}, };
this.timeData = { loading: false, dataSource: [], origin: {} }; this.timeData = { loading: false, dataSource: [], origin: {}, diff: {} };
this.timeDiffData = { loading: false, dataSource: [], origin: {}, };
this.BuData = { loading: false, dataSource: [] }; this.BuData = { loading: false, dataSource: [] };
this.sideData = { loading: false, dataSource: {}, monthData: [], yearData: [] }; this.sideData = { loading: false, dataSource: {}, monthData: [], yearData: [] };
this.topData = {}; this.topData = {};
@ -312,7 +367,8 @@ class Trade {
searchPayloadHome = {}; searchPayloadHome = {};
summaryData = { loading: false, dataSource: [], kpi: {}, }; summaryData = { loading: false, dataSource: [], kpi: {}, };
timeData = { loading: false, dataSource: [], origin: {} }; timeData = { loading: false, dataSource: [], origin: {}, diff: {} };
timeDiffData = { loading: false, dataSource: [], origin: {}, };
BuData = { loading: false, dataSource: [] }; BuData = { loading: false, dataSource: [] };
sideData = { loading: false, dataSource: {}, monthData: [], yearData: [] }; sideData = { loading: false, dataSource: {}, monthData: [], yearData: [] };
topData = {}; topData = {};

@ -1,6 +1,6 @@
import { useContext, useEffect, useState } from 'react'; import { useContext, useEffect, useState } from 'react';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import { Row, Col, Spin, Space, Radio, Table } from 'antd'; import { Row, Col, Spin, Space, Radio, Table, Button } from 'antd';
import { CheckCircleTwoTone, MoneyCollectTwoTone, FlagTwoTone, SmileTwoTone } from '@ant-design/icons'; import { CheckCircleTwoTone, MoneyCollectTwoTone, FlagTwoTone, SmileTwoTone } from '@ant-design/icons';
import { stores_Context } from '../config'; import { stores_Context } from '../config';
import StatisticCard2 from '../components/StatisticCard2'; import StatisticCard2 from '../components/StatisticCard2';
@ -9,6 +9,7 @@ import Waterfall from '../components/Waterfall';
import MixTBWithKPI from './../components/MixTBWithKPI'; import MixTBWithKPI from './../components/MixTBWithKPI';
import Donut from './../components/Donut'; import Donut from './../components/Donut';
import MapCountry from './../components/MapCountry'; import MapCountry from './../components/MapCountry';
import LineWithKPI from '../components/LineWithKPI';
import DataFieldRadio from '../components/DataFieldRadio'; import DataFieldRadio from '../components/DataFieldRadio';
import { datePartOptions } from './../components/DateGroupRadio/date'; import { datePartOptions } from './../components/DateGroupRadio/date';
import SearchForm from './../components/search/SearchForm'; import SearchForm from './../components/search/SearchForm';
@ -17,11 +18,16 @@ import { dataFieldAlias } from './../libs/ht';
import './home.css'; import './home.css';
const topSeries = [ const topSeries = [
{ key: 'dept', label: '小组', graphVisible: true }, { key: 'dept', value: 'dept', label: '小组', graphVisible: true },
{ key: 'operator', label: '顾问', graphVisible: true }, { key: 'operator', value: 'operator', label: '顾问', graphVisible: true },
{ key: 'destination', label: '目的地', graphVisible: true }, { key: 'destination', value: 'destination', label: '目的地', graphVisible: true },
{ key: 'GuestGroupType', label: '客群类别', graphVisible: false }, { key: 'GuestGroupType', value: 'GuestGroupType', label: '客群类别', graphVisible: false },
{ key: 'country', label: '国籍', graphVisible: true }, { key: 'country', value: 'country', label: '国籍', graphVisible: true },
];
const allGroupTypes = [
{ key: 'overview', value: 'overview', label: '总额' },
...topSeries,
]; ];
// const iconSets = [CheckCircleTwoTone, <MoneyCollectTwoTone />, <FlagTwoTone />, <ClockCircleTwoTone />, <DashboardTwoTone />,<SmileTwoTone />,]; // const iconSets = [CheckCircleTwoTone, <MoneyCollectTwoTone />, <FlagTwoTone />, <ClockCircleTwoTone />, <DashboardTwoTone />,<SmileTwoTone />,];
@ -30,7 +36,7 @@ const iconSets = [CheckCircleTwoTone, MoneyCollectTwoTone, FlagTwoTone, SmileTwo
export default observer(() => { export default observer(() => {
// const navigate = useNavigate(); // const navigate = useNavigate();
const { TradeStore, date_picker_store: searchFormStore } = useContext(stores_Context); const { TradeStore, date_picker_store: searchFormStore } = useContext(stores_Context);
const { sideData, summaryData, BuData, topData, timeData, timeLineKey, targetTableProps } = TradeStore; const { searchValues, sideData, summaryData, BuData, topData, timeData, timeLineKey, targetTableProps, timeDiffData, groupKey } = TradeStore;
const { formValues } = searchFormStore; const { formValues } = searchFormStore;
useEffect(() => { useEffect(() => {
@ -51,6 +57,7 @@ export default observer(() => {
TradeStore.resetData(); TradeStore.resetData();
TradeStore.fetchSummaryData(Object.assign({}, queryData, { groupType })); TradeStore.fetchSummaryData(Object.assign({}, queryData, { groupType }));
TradeStore.fetchTradeDataByDate(queryData); TradeStore.fetchTradeDataByDate(queryData);
TradeStore.fetchTradeDataDiffByDate(queryData);
// // TradeStore.fetchTradeDataByBU(queryData); // // TradeStore.fetchTradeDataByBU(queryData);
TradeStore.fetchTradeDataByMonth(queryData); TradeStore.fetchTradeDataByMonth(queryData);
const topSeriesF = _overviewFlag ? topSeries : topSeries.filter((ele) => ele.key !== 'dept'); const topSeriesF = _overviewFlag ? topSeries : topSeries.filter((ele) => ele.key !== 'dept');
@ -133,7 +140,6 @@ export default observer(() => {
xAxis: { xAxis: {
type: 'cat', type: 'cat',
}, },
// smooth: true,
point: { point: {
size: 4, size: 4,
shape: 'cicle', shape: 'cicle',
@ -158,26 +164,38 @@ export default observer(() => {
TradeStore.setTimeLineKey(value); TradeStore.setTimeLineKey(value);
if (!isEmpty(TradeStore.searchPayloadHome)) { if (!isEmpty(TradeStore.searchPayloadHome)) {
TradeStore.fetchTradeDataByDate({ groupType: groupTypeVal }); TradeStore.fetchTradeDataByDate({ groupType: groupTypeVal });
TradeStore.fetchTradeDataDiffByDate({ groupType: diffGroupKey });
} }
}; };
const [diffGroupKey, setDiffGroupKey] = useState(groupKey);
const handleChangeDiffType = ({ target: { value } }) => {
console.log('diffGroupKey', diffGroupKey, value);
setDiffGroupKey(value);
TradeStore.setGroupKey(value);
if (!isEmpty(TradeStore.searchPayloadHome)) {
TradeStore.fetchTradeDataDiffByDate({ groupType: value });
}
};
const [showDiff, setShowDiff] = useState(false);
return ( return (
<> <>
<Row gutter={16} className='sticky-top' > <Row gutter={16} className="sticky-top">
<Col className="gutter-row" span={24}> <Col className="gutter-row" span={24}>
<SearchForm <SearchForm
defaultValue={{ defaultValue={{
initialValue: { initialValue: {
...formValues, ...formValues,
...searchValues,
}, },
shows: ['DateType', 'DepartmentList', 'WebCode', 'IncludeTickets', 'years'], shows: ['DateType', 'DepartmentList', 'WebCode', 'IncludeTickets', 'years'],
fieldProps: { fieldProps: {
DepartmentList: { show_all: true }, DepartmentList: { show_all: true },
WebCode: { show_all: true }, WebCode: { show_all: true },
years: { hide_vs: true }, years: { hide_vs: false },
}, },
}} }}
onSubmit={(_err, obj, form, str) => { onSubmit={(_err, obj, form, str) => {
TradeStore.setStateSearch(obj); TradeStore.setSearch(obj, form);
pageRefresh(obj); pageRefresh(obj);
}} }}
/> />
@ -185,7 +203,9 @@ export default observer(() => {
</Row> </Row>
<section> <section>
<Space> <Space>
<h2>年度业绩<span style={{fontSize: 'small'}}> =传统+商务</span></h2> <h2>
年度业绩<span style={{ fontSize: 'small' }}> =传统+商务</span>
</h2>
</Space> </Space>
<Spin spinning={summaryData.loading}> <Spin spinning={summaryData.loading}>
<Row gutter={layoutProps.gutter}> <Row gutter={layoutProps.gutter}>
@ -195,7 +215,7 @@ export default observer(() => {
</Col> </Col>
))} */} ))} */}
{summaryData.dataSource.map((item, i) => ( {summaryData.dataSource.map((item, i) => (
<Col {...layoutProps} key={item.title} lg={{span: ((item?.col || layoutProps.lg.span))}}> <Col {...layoutProps} key={item.title} lg={{ span: item?.col || layoutProps.lg.span }}>
<StatisticCard2 {...item} showProgress={item.hasKPI} icon={iconSets[i]} /> <StatisticCard2 {...item} showProgress={item.hasKPI} icon={iconSets[i]} />
</Col> </Col>
))} ))}
@ -203,22 +223,41 @@ export default observer(() => {
</Spin> </Spin>
</section> </section>
<section> <section>
<Space gutter={16} size={'large'}> <Space gutter={16} size={'small'}>
<h3>走势</h3> <h3>{showDiff === false ? '走势' : '对比'}</h3>
<DataFieldRadio value={timeDataField} onChange={handleChangetimeDataField} /> <DataFieldRadio value={timeDataField} onChange={handleChangetimeDataField} />
<Radio.Group options={datePartOptions} optionType="button" onChange={handleChangeDateType} value={dateField} /> <Radio.Group options={datePartOptions} optionType="button" onChange={handleChangeDateType} value={dateField} />
{showDiff && <Radio.Group options={allGroupTypes} optionType="button" onChange={handleChangeDiffType} value={diffGroupKey} />}
{searchValues.yearDiff && (
<Button type="link" size={'small'} onClick={() => setShowDiff(!showDiff)}>
{showDiff === false ? '显示对比' : '返回总额'}
</Button>
)}
</Space> </Space>
{showDiff === false ? (
<Spin spinning={timeData.loading}> <Spin spinning={timeData.loading}>
{/* <LineWithKPI dataSource={timeData.dataSource} {...lineConfig} /> */}
<MixTBWithKPI dataSource={timeData.dataSource} summaryData={timeData.origin?.summaryRows || []} {...lineConfig} /> <MixTBWithKPI dataSource={timeData.dataSource} summaryData={timeData.origin?.summaryRows || []} {...lineConfig} />
</Spin> </Spin>
) : (
<Spin spinning={timeDiffData.loading}>
<LineWithKPI
dataSource={timeDiffData.dataSource}
showKPI={false}
{...lineConfig}
{...{ appendPadding: 10, legend: { position: 'right-top', title: { text: '虚线: 对比年份' } }, point: false }}
/>
</Spin>
)}
</section> </section>
<section> <section>
<h3>市场 (仅传统订单) </h3> <h3>市场 (仅传统订单) </h3>
<Spin spinning={BuData.loading}> <Spin spinning={sideData.loading}>
<Row gutter={layoutProps3.gutter}> <Row gutter={layoutProps3.gutter}>
<Col {...layoutProps3}> <Col {...layoutProps3}>
<><Donut {...{angleField: 'SumML', colorField: 'groupsLabel'}} title={formValues.DepartmentList?.label} dataSource={sideData.yearData} /></> <>
<Donut {...{ angleField: 'SumML', colorField: 'groupsLabel' }} title={formValues.DepartmentList?.label} dataSource={sideData.yearData} />
</>
{/* {overviewFlag ? ( {/* {overviewFlag ? (
<> <>
<Bullet {...BUConfig} dataSource={BuData?.dataSource || []} /> <Bullet {...BUConfig} dataSource={BuData?.dataSource || []} />
@ -228,7 +267,9 @@ export default observer(() => {
<><Donut {...{angleField: 'SumML', colorField: 'groupsLabel'}} title={formValues.DepartmentList?.label} dataSource={sideData.yearData} /></> <><Donut {...{angleField: 'SumML', colorField: 'groupsLabel'}} title={formValues.DepartmentList?.label} dataSource={sideData.yearData} /></>
)} */} )} */}
</Col> </Col>
{Object.keys(sideData.dataSource).sort().map((key) => ( {Object.keys(sideData.dataSource)
.sort()
.map((key) => (
<Col {...layoutProps3} key={key}> <Col {...layoutProps3} key={key}>
<Waterfall key={key} {...WaterfallConfig} title={key} dataSource={sideData.dataSource[key]} line={summaryData.kpi} /> <Waterfall key={key} {...WaterfallConfig} title={key} dataSource={sideData.dataSource[key]} line={summaryData.kpi} />
<h3 style={{ textAlign: 'center' }}>{`${key}每月业绩`}</h3> <h3 style={{ textAlign: 'center' }}>{`${key}每月业绩`}</h3>
@ -265,7 +306,7 @@ export default observer(() => {
)} )}
<Col key={'mapG'} flex={'1 0 auto'}> <Col key={'mapG'} flex={'1 0 auto'}>
<Spin spinning={topData?.country?.loading || false}> <Spin spinning={topData?.country?.loading || false}>
<div id='topC' style={{height: '700px'}}> <div id="topC" style={{ height: '700px' }}>
<MapCountry sourceField={'groupsLabel'} valueField={BUConfig.measureField} dataSource={topData?.country?.dataSource || []} /> <MapCountry sourceField={'groupsLabel'} valueField={BUConfig.measureField} dataSource={topData?.country?.dataSource || []} />
</div> </div>
</Spin> </Spin>

@ -212,7 +212,7 @@ const Sale_KPI = () => {
</Space> </Space>
</Col> </Col>
<Col className="gutter-row" md={24}> <Col className="gutter-row" md={24}>
<LineWithKPI dataSource={sale_store.salesTrade.pickSalesData} {...lineConfig} /> <LineWithKPI dataSource={sale_store.salesTrade.pickSalesData} showKPI={true} {...lineConfig} />
</Col> </Col>
</Row> </Row>

Loading…
Cancel
Save