diff --git a/src/components/Bullet.jsx b/src/components/Bullet.jsx
index e2cc0dd..c2e22d7 100644
--- a/src/components/Bullet.jsx
+++ b/src/components/Bullet.jsx
@@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';
import { observer } from 'mobx-react';
import { Bullet } from '@ant-design/plots';
-import { sortBy } from '../utils/commons';
+import { sortBy, merge } from '../utils/commons';
import { dataFieldAlias } from './../libs/ht';
export default observer((props) => {
@@ -24,7 +24,7 @@ export default observer((props) => {
return () => {};
}, [extProps.measureField, dataSource]);
- const config = {
+ const config = merge({
color: {
range: ['#FFbcb8', '#FFe0b0', '#bfeec8'],
measure: '#5B8FF9',
@@ -72,17 +72,17 @@ export default observer((props) => {
},
],
},
- // 全局的alias不起作用
+ // ? 全局的alias不起作用
tooltip: {
customItems: (originalItems) => {
// process originalItems,
return originalItems.map((ele) => ({ ...ele, name: dataFieldAlias[ele.name]?.alias || ele.name }));
},
},
- };
+ }, extProps);
return (
<>
-
+
>
);
});
diff --git a/src/components/Column.jsx b/src/components/Column.jsx
new file mode 100644
index 0000000..301de04
--- /dev/null
+++ b/src/components/Column.jsx
@@ -0,0 +1,66 @@
+import { useEffect, useState } from 'react';
+import { observer } from 'mobx-react';
+import { sortBy, merge } from '../utils/commons';
+import { dataFieldAlias } from '../libs/ht';
+import { Column } from '@ant-design/plots';
+
+export default observer((props) => {
+ const { dataSource, line, ...extProps } = props;
+ const yMax = Math.max(line?.value || 0, ...dataSource.map((ele) => ele[extProps.yField]));
+ const annotationsLine = line
+ ? [
+ {
+ type: 'text',
+ position: ['start', line.value],
+ content: `${line.label} ${line.value / 1000} K`,
+ // offsetX: -15,
+ style: {
+ fill: '#F4664A',
+ textBaseline: 'bottom',
+ },
+ },
+ {
+ type: 'line',
+ start: [-10, line.value],
+ end: ['max', line.value],
+ style: {
+ stroke: '#F4664A',
+ lineDash: [2, 2],
+ },
+ },
+ ]
+ : [];
+ const config = merge({
+ isStack: true,
+ // xField: 'value',
+ // yField: 'year',
+ // seriesField: 'type',
+ label: {
+ // 可手动配置 label 数据标签位置
+ position: 'middle',
+ // 'left', 'middle', 'right'
+ // 可配置附加的布局方法
+ layout: [
+ // 柱形图数据标签位置自动调整
+ {
+ type: 'interval-adjust-position',
+ }, // 数据标签防遮挡
+ {
+ type: 'interval-hide-overlap',
+ }, // 数据标签文颜色自动调整
+ {
+ type: 'adjust-color',
+ },
+ ],
+ },
+ meta: {
+ [extProps.yField]: {
+ alias: dataFieldAlias[extProps.yField]?.alias || extProps.yField,
+ formatter: (v) => dataFieldAlias[extProps.yField]?.formatter(v) || v,
+ max: Math.ceil(yMax / 0.95),
+ },
+ },
+ annotations: [...annotationsLine],
+ }, extProps);
+ return ;
+});
diff --git a/src/components/Waterfall.jsx b/src/components/Waterfall.jsx
index b23c2d1..9fc15f0 100644
--- a/src/components/Waterfall.jsx
+++ b/src/components/Waterfall.jsx
@@ -1,6 +1,7 @@
import { observer } from 'mobx-react';
import { Waterfall } from '@ant-design/plots';
import { dataFieldAlias } from './../libs/ht';
+import { merge } from '../utils/commons';
export default observer((props) => {
const { dataSource, line, title, ...extProps } = props;
@@ -29,7 +30,7 @@ export default observer((props) => {
]
: [];
- const config = {
+ const config = merge({
padding: 'auto',
appendPadding: [20, 0, 0, 0],
@@ -50,18 +51,16 @@ export default observer((props) => {
},
annotations: [...annotationsLine],
meta: {
- ...extProps.mergeMeta,
[extProps.yField]: {
- ...extProps.mergeMeta[extProps.yField],
max: Math.ceil(yMax / 0.95),
alias: dataFieldAlias[extProps.yField]?.alias || extProps.yField,
formatter: (v) => dataFieldAlias[extProps.yField]?.formatter(v) || v,
},
},
- };
+ }, extProps);
return (
<>
-
+
>
);
});
diff --git a/src/mock/2.0/trade.json b/src/mock/2.0/trade.json
index d78ed3d..12d533c 100644
--- a/src/mock/2.0/trade.json
+++ b/src/mock/2.0/trade.json
@@ -13,7 +13,7 @@
"SumOrderKPIrate|20-100": 25,
"SumPersonNum": "@integer(999,9999)",
"SumPersonNumrate|-50-1": 33,
- "SumPersonNumKPIrate|20-100": 33,
+ "SumPersonNumKPIrate": 0,
"groups": "2023-05-01~2023-05-31",
"key": "@increment"
},
@@ -87,11 +87,11 @@
"result1|24": [
{
"groups|1": "@pick([\"inside\",\"outside\"])",
+ "groupDateVal": "@date('2023-MM')",
"SumML": "@increment(1000)",
"SumMLVSrate": "@float(0,70,2,2)",
"SumMLKPI": "@integer(1000,10000)",
"SumMLKPIrate": "@float(0,70,2,2)",
- "month": "@date('2023-MM')",
"SumOrder": "@integer(9,999)",
"SumOrderVSrate": "@float(-20,20,0,2)",
"SumOrderKPIrate": "@float(20,100,0,2)",
@@ -103,5 +103,26 @@
"result2": [
{}
]
+ },
+ "get|/service-web/QueryData/Getkpi": {
+ "errcode": 0,
+ "errmsg": "",
+ "loading": false,
+ "data": null,
+ "result1|10": [
+ {
+ "object|1": "@pick([\"dept\",\"sales\", \"group\"])",
+ "subject|1": "@pick([\"OrderCount\",\"SumML\", \"AvgML\", \"SuccessRate\"])",
+ "object_id": "@integer(10,100)",
+ "object_name": "@cname",
+ "date_type": "@pick([\"ConfirmDate\",\"startDate\", \"applyDate\"])",
+ "start_date": "@date(\"yyyy-MM-dd\")",
+ "end_date": "@datetime(\"yyyy-MM-dd HH:mm:ss\")",
+ "value": "@integer(99,9999)",
+ "key": "@increment"
+ }],
+ "result2": [
+ {}
+ ]
}
}
diff --git a/src/stores/Trade.js b/src/stores/Trade.js
index db40f98..113d473 100644
--- a/src/stores/Trade.js
+++ b/src/stores/Trade.js
@@ -23,6 +23,9 @@ class Trade {
const summaryData = {
loading: false,
dataSource: [
+ { title: '成团', value: json.result1?.SumOrder, VSrate: json.result1?.SumOrderrate, KPIrate: json.result1?.SumOrderKPIrate, hasKPI: !isEmpty(json.result1?.SumOrderKPIrate) },
+ { title: '毛利', value: json.result1?.SumML, VSrate: json.result1?.SumMLrate, KPIrate: json.result1?.SumMLKPIrate, hasKPI: !isEmpty(json.result1?.SumMLKPIrate) },
+ { title: '完成率', value: `${json.result1?.SumMLKPIrate}%`, hasKPI: false },
{
title: '人数',
value: json.result1?.SumPersonNum,
@@ -30,9 +33,6 @@ class Trade {
KPIrate: json.result1?.SumPersonNumKPIrate,
hasKPI: !isEmpty(json.result1?.SumPersonNumKPIrate),
},
- { title: '成团', value: json.result1?.SumOrder, VSrate: json.result1?.SumOrderrate, KPIrate: json.result1?.SumOrderKPIrate, hasKPI: !isEmpty(json.result1?.SumOrderKPIrate) },
- { title: '毛利', value: json.result1?.SumML, VSrate: json.result1?.SumMLrate, KPIrate: json.result1?.SumMLKPIrate, hasKPI: !isEmpty(json.result1?.SumMLKPIrate) },
- { title: '完成率', value: `${json.result1?.SumMLKPIrate}%`, hasKPI: false },
],
};
this.summaryData = summaryData;
@@ -47,7 +47,7 @@ class Trade {
// req.fetchJSON('/service-web/QueryData/GetTradeByMonth').then((json) => {
if (json.errcode === 0) {
runInAction(() => {
- const sortResult = json.result1.sort(sortBy('month'));
+ const sortResult = json.result1.sort(sortBy('groupDateVal'));
const groupsData = sortResult.reduce((r, v) => {
(r[v.groups] || (r[v.groups] = [])).push(v);
return r;
@@ -56,6 +56,7 @@ class Trade {
const kpi = { label: '', value: 1200000 }; // 标注KPI
this.sideData.loading = false;
this.sideData.dataSource = groupsData;
+ this.sideData.monthData = sortResult;
this.sideData.kpi = kpi;
});
}
@@ -76,7 +77,7 @@ class Trade {
}
summaryData = { loading: false, dataSource: [] };
- sideData = { loading: false, dataSource: {}, kpi: {}, };
+ sideData = { loading: false, dataSource: {}, kpi: {}, monthData: [] };
topData = {};
defaultDataSubject = 'CJCount';
}
diff --git a/src/utils/commons.js b/src/utils/commons.js
index 5cde768..e1c856d 100644
--- a/src/utils/commons.js
+++ b/src/utils/commons.js
@@ -282,3 +282,36 @@ export function set_array_index(result) {
export const sortBy = (key) => {
return (a, b) => (a[key] > b[key]) ? 1 : ((b[key] > a[key]) ? -1 : 0);
};
+
+/**
+ * 合并Object, 递归地
+ */
+export function merge(...objects) {
+ const isDeep = objects.some(obj => obj !== null && typeof obj === 'object');
+
+ const result = objects[0] ?? {};
+
+ for (let i = 1; i < objects.length; i++) {
+ const obj = objects[i];
+
+ if (!obj) continue;
+
+ Object.keys(obj).forEach(key => {
+ const val = obj[key];
+
+ if (isDeep) {
+ if (Array.isArray(val)) {
+ result[key] = [...result[key] || [], ...val];
+ } else if (typeof val === 'object') {
+ result[key] = merge(result[key], val);
+ } else {
+ result[key] = val;
+ }
+ } else {
+ result[key] = typeof val === 'boolean' ? val : result[key];
+ }
+ });
+ }
+
+ return result;
+}
diff --git a/src/views/Home.jsx b/src/views/Home.jsx
index 09de37a..75b7d6b 100644
--- a/src/views/Home.jsx
+++ b/src/views/Home.jsx
@@ -3,10 +3,11 @@ import { observer } from 'mobx-react';
import { Row, Col, Spin, Space } from 'antd';
import { stores_Context } from '../config';
import { useNavigate } from 'react-router-dom';
-import { SlackOutlined, SketchOutlined, AntCloudOutlined, RedditOutlined, GithubOutlined, ArrowUpOutlined, ArrowDownOutlined } from '@ant-design/icons';
+// import { SlackOutlined, SketchOutlined, AntCloudOutlined, RedditOutlined, GithubOutlined, ArrowUpOutlined, ArrowDownOutlined } from '@ant-design/icons';
import StatisticCard from '../components/StatisticCard';
import Bullet from '../components/Bullet';
import Waterfall from '../components/Waterfall';
+import Column from '../components/Column';
import DataFieldRadio from './../components/DateFieldRadio';
import DatePickerCharts from './../components/search/DatePickerCharts';
@@ -68,10 +69,10 @@ export default observer(() => {
};
const WaterfallConfig = {
- xField: 'month',
+ xField: 'groupDateVal',
yField: 'SumML',
- mergeMeta: {
- month: {
+ meta: {
+ groupDateVal: {
alias: '月份',
},
},
@@ -80,6 +81,29 @@ export default observer(() => {
},
};
+ const ColumnConfig = {
+ xField: 'groupDateVal',
+ yField: 'SumML',
+ seriesField: 'groups',
+ label: {
+ formatter: (v) => ((v.SumML / sideData.kpi.value) * 100).toFixed(2) + '%',
+ },
+ legend: false,
+ // annotations: sideData.monthData.map((d, ...args) => {
+ // console.log('aaa', d, args);
+ // return {
+ // type: 'dataMarker',
+ // position: d,
+ // point: {
+ // style: {
+ // stroke: '#FF6B3B',
+ // lineWidth: 1.5,
+ // },
+ // },
+ // };
+ // }),
+ };
+
return (
<>
@@ -101,6 +125,9 @@ export default observer(() => {
市场进度
+
+
+
{Object.keys(sideData.dataSource).map((key) => (