增加tooltip
This commit is contained in:
@@ -73,7 +73,7 @@ const IndustryTrendPage: React.FC = () => {
|
|||||||
let newStartTime = '';
|
let newStartTime = '';
|
||||||
|
|
||||||
if (value === '月') {
|
if (value === '月') {
|
||||||
newStartTime = now.subtract(6, 'month').format('YYYY-MM');
|
newStartTime = now.subtract(5, 'month').format('YYYY-MM');
|
||||||
} else if (value === '季度') {
|
} else if (value === '季度') {
|
||||||
newStartTime = now.subtract(6, 'quarter').format('YYYY-Q');
|
newStartTime = now.subtract(6, 'quarter').format('YYYY-Q');
|
||||||
} else {
|
} else {
|
||||||
@@ -101,6 +101,18 @@ const IndustryTrendPage: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const disabledDate = (current: dayjs.Dayjs) => {
|
||||||
|
const now = dayjs();
|
||||||
|
|
||||||
|
if (params.timeDimension === '月') {
|
||||||
|
return current.isAfter(now.endOf('month'));
|
||||||
|
} else if (params.timeDimension === '季度') {
|
||||||
|
return current.isAfter(now.endOf('quarter'));
|
||||||
|
} else {
|
||||||
|
return current.isAfter(now.endOf('year'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const currentIndustryData = useMemo(() => {
|
const currentIndustryData = useMemo(() => {
|
||||||
if (!params.selectedIndustry || allData.length === 0) return [];
|
if (!params.selectedIndustry || allData.length === 0) return [];
|
||||||
|
|
||||||
@@ -108,16 +120,32 @@ const IndustryTrendPage: React.FC = () => {
|
|||||||
.filter(item => item.category === params.selectedIndustry)
|
.filter(item => item.category === params.selectedIndustry)
|
||||||
.map(item => ({
|
.map(item => ({
|
||||||
...item,
|
...item,
|
||||||
|
originalDate: item.date,
|
||||||
date: formatDateForDisplay(item.date, params.timeDimension)
|
date: formatDateForDisplay(item.date, params.timeDimension)
|
||||||
}))
|
}))
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const dateA = a.date.includes('第')
|
if (params.timeDimension === '季度') {
|
||||||
? parseInt(a.date.split('第')[1])
|
// 处理中文季度格式,如 "2024-第一季度" -> ["2024", "第一"]
|
||||||
: dayjs(a.date).valueOf();
|
const [yearA, quarterA] = a.originalDate.split('-');
|
||||||
const dateB = b.date.includes('第')
|
const [yearB, quarterB] = b.originalDate.split('-');
|
||||||
? parseInt(b.date.split('第')[1])
|
|
||||||
: dayjs(b.date).valueOf();
|
// 转换中文季度为数字("第一" -> 1, "第二" -> 2...)
|
||||||
return dateA - dateB;
|
const quarterToNumber = (q: string) => {
|
||||||
|
if (q.includes('第一')) return 1;
|
||||||
|
if (q.includes('第二')) return 2;
|
||||||
|
if (q.includes('第三')) return 3;
|
||||||
|
if (q.includes('第四')) return 4;
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
return yearA === yearB
|
||||||
|
? quarterToNumber(quarterA) - quarterToNumber(quarterB)
|
||||||
|
: parseInt(yearA) - parseInt(yearB);
|
||||||
|
} else if (params.timeDimension === '年') {
|
||||||
|
return parseInt(a.originalDate) - parseInt(b.originalDate);
|
||||||
|
} else {
|
||||||
|
return dayjs(a.originalDate).valueOf() - dayjs(b.originalDate).valueOf();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}, [allData, params.selectedIndustry, params.timeDimension]);
|
}, [allData, params.selectedIndustry, params.timeDimension]);
|
||||||
|
|
||||||
@@ -143,16 +171,17 @@ const IndustryTrendPage: React.FC = () => {
|
|||||||
seriesField: 'category',
|
seriesField: 'category',
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'cat',
|
type: 'cat',
|
||||||
|
|
||||||
label: {
|
label: {
|
||||||
formatter: (text: string) => text,
|
formatter: (text: string) => text,
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
label: {
|
label: {
|
||||||
formatter: (val: string) => `${val}${params.type === '招聘增长率' ? '%' : '个'}`,
|
formatter: (val: string) => `${val}${params.type === '招聘增长率' ? '%' : ''}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
tooltip: false,
|
|
||||||
point: {
|
point: {
|
||||||
size: 4,
|
size: 4,
|
||||||
shape: 'circle',
|
shape: 'circle',
|
||||||
@@ -164,6 +193,48 @@ const IndustryTrendPage: React.FC = () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
smooth: true,
|
smooth: true,
|
||||||
|
interactions: [
|
||||||
|
{
|
||||||
|
type: 'tooltip',
|
||||||
|
cfg: {
|
||||||
|
render: (e, { title, items }) => {
|
||||||
|
const list = items.filter((item) => item.value);
|
||||||
|
return (
|
||||||
|
<div key={title} style={{ padding: '8px 12px' }}>
|
||||||
|
<h4 style={{ marginBottom: 8 }}>{title}</h4>
|
||||||
|
{list.map((item, index) => {
|
||||||
|
const { name, value, color } = item;
|
||||||
|
return (
|
||||||
|
<div key={index} style={{ margin: '4px 0', display: 'flex', justifyContent: 'space-between' }}>
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
display: 'inline-block',
|
||||||
|
width: 8,
|
||||||
|
height: 8,
|
||||||
|
borderRadius: '50%',
|
||||||
|
backgroundColor: color,
|
||||||
|
marginRight: 8,
|
||||||
|
}}
|
||||||
|
></span>
|
||||||
|
<span>{name}</span>
|
||||||
|
</div>
|
||||||
|
<b>{value}{params.type === '招聘增长率' ? '%' : ''}</b>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
legend: false,
|
||||||
|
tooltip: {
|
||||||
|
showTitle: undefined,
|
||||||
|
title: undefined,
|
||||||
|
customContent: undefined
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -206,6 +277,7 @@ const IndustryTrendPage: React.FC = () => {
|
|||||||
style={{ width: 180 }}
|
style={{ width: 180 }}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
allowClear={false}
|
allowClear={false}
|
||||||
|
disabledDate={disabledDate}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
@@ -310,6 +382,4 @@ const IndustryTrendPage: React.FC = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default IndustryTrendPage;
|
export default IndustryTrendPage;
|
||||||
25
src/types/analysis/industry.d.ts
vendored
25
src/types/analysis/industry.d.ts
vendored
@@ -1,4 +1,5 @@
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
export type TimeDimension = '月' | '季度' | '年';
|
export type TimeDimension = '月' | '季度' | '年';
|
||||||
export type AnalysisType = '岗位发布数量' | '招聘增长率';
|
export type AnalysisType = '岗位发布数量' | '招聘增长率';
|
||||||
@@ -27,6 +28,17 @@ export interface IndustryTrendApiResult {
|
|||||||
msg: string;
|
msg: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TooltipItem {
|
||||||
|
name: string;
|
||||||
|
value: number;
|
||||||
|
color: string;
|
||||||
|
data: {
|
||||||
|
date: string;
|
||||||
|
category: string;
|
||||||
|
value: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export interface ChartConfig {
|
export interface ChartConfig {
|
||||||
data: IndustryDataItem[];
|
data: IndustryDataItem[];
|
||||||
height: number;
|
height: number;
|
||||||
@@ -44,7 +56,11 @@ export interface ChartConfig {
|
|||||||
formatter: (val: string) => string;
|
formatter: (val: string) => string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
tooltip: false;
|
tooltip: {
|
||||||
|
showTitle?: boolean;
|
||||||
|
title?: string | ((title: string, data?: TooltipItem[]) => string);
|
||||||
|
customContent?: (title: string, items: TooltipItem[]) => ReactNode;
|
||||||
|
};
|
||||||
point: {
|
point: {
|
||||||
size: number;
|
size: number;
|
||||||
shape: string;
|
shape: string;
|
||||||
@@ -56,6 +72,13 @@ export interface ChartConfig {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
smooth: boolean;
|
smooth: boolean;
|
||||||
|
interactions?: Array<{
|
||||||
|
type: string;
|
||||||
|
cfg: {
|
||||||
|
render: (event: any, { title, items }: { title: string; items: TooltipItem[] }) => ReactNode;
|
||||||
|
};
|
||||||
|
}>;
|
||||||
|
legend?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DateFormatter = (dateStr: string, dimension: TimeDimension) => string;
|
export type DateFormatter = (dateStr: string, dimension: TimeDimension) => string;
|
||||||
|
|||||||
Reference in New Issue
Block a user