|
|
@@ -42,26 +42,56 @@ const extractProvinceFromKey = (key: string): string => {
|
|
|
return parts[0] || key
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 合并相同省份的数据,解决"两个山东"的问题
|
|
|
+ * 例如:"山东-济南" 和 "山东-青岛" 合并为 "山东",人数相加
|
|
|
+ */
|
|
|
+const mergeProvinceData = (stats: any[]) => {
|
|
|
+ const provinceMap = new Map<string, number>()
|
|
|
+
|
|
|
+ stats.forEach(item => {
|
|
|
+ // 确定省份名称:优先使用 province,如果是数字则从 key 提取
|
|
|
+ let provinceName: string
|
|
|
+ if (item.province && !isNumericString(item.province)) {
|
|
|
+ provinceName = item.province
|
|
|
+ } else if (item.key) {
|
|
|
+ provinceName = extractProvinceFromKey(item.key)
|
|
|
+ } else {
|
|
|
+ provinceName = item.province || item.key || '未知'
|
|
|
+ }
|
|
|
+
|
|
|
+ // 累加人数(确保取整)
|
|
|
+ const count = Math.round(item.value || 0)
|
|
|
+ provinceMap.set(provinceName, (provinceMap.get(provinceName) || 0) + count)
|
|
|
+ })
|
|
|
+
|
|
|
+ // 转换回数组格式
|
|
|
+ return Array.from(provinceMap.entries()).map(([province, value]) => ({
|
|
|
+ key: province,
|
|
|
+ province,
|
|
|
+ value
|
|
|
+ }))
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* 数据转换工具:将API统计数据转换为柱状图格式
|
|
|
* 优先使用中文名称的 province,如果是数字ID则从 key 提取
|
|
|
+ * 修复:合并相同省份的数据,人数显示为整数
|
|
|
*/
|
|
|
const convertToColumnData = (stats: any[]) => {
|
|
|
console.debug('[convertToColumnData] Input stats:', JSON.stringify(stats))
|
|
|
+
|
|
|
+ // 先合并相同省份的数据
|
|
|
+ const mergedStats = mergeProvinceData(stats)
|
|
|
+
|
|
|
const result = {
|
|
|
- categories: stats.map(item => {
|
|
|
- // 优先使用 province,但如果 province 是纯数字,则从 key 提取省份名称
|
|
|
- if (item.province && !isNumericString(item.province)) {
|
|
|
- return item.province
|
|
|
- }
|
|
|
- // 如果 province 是数字或不存在,从 key 提取
|
|
|
- return item.key ? extractProvinceFromKey(item.key) : item.province || item.key
|
|
|
- }),
|
|
|
+ categories: mergedStats.map(item => item.province),
|
|
|
series: [{
|
|
|
name: '人数',
|
|
|
- data: stats.map(item => item.value || 0)
|
|
|
+ data: mergedStats.map(item => item.value)
|
|
|
}]
|
|
|
}
|
|
|
+ console.debug('[convertToColumnData] Merged stats:', JSON.stringify(mergedStats))
|
|
|
console.debug('[convertToColumnData] Output categories:', result.categories)
|
|
|
console.debug('[convertToColumnData] Output series:', result.series)
|
|
|
return result
|
|
|
@@ -69,11 +99,12 @@ const convertToColumnData = (stats: any[]) => {
|
|
|
|
|
|
/**
|
|
|
* 数据转换工具:将API统计数据转换为饼图格式
|
|
|
+ * 修复:人数显示为整数
|
|
|
*/
|
|
|
const convertToPieData = (stats: any[]) =>
|
|
|
stats.map(item => ({
|
|
|
name: item.key,
|
|
|
- data: item.value || 0
|
|
|
+ data: Math.round(item.value || 0)
|
|
|
}))
|
|
|
|
|
|
export interface StatisticsProps {
|
|
|
@@ -385,6 +416,7 @@ const Statistics: React.FC<StatisticsProps> = () => {
|
|
|
series={convertToPieData(ageStats)}
|
|
|
config={{
|
|
|
color: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6', '#ef4444'],
|
|
|
+ dataLabel: true,
|
|
|
}}
|
|
|
/>
|
|
|
</View>
|
|
|
@@ -426,6 +458,7 @@ const Statistics: React.FC<StatisticsProps> = () => {
|
|
|
series={chartData.series}
|
|
|
config={{
|
|
|
color: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6', '#ef4444', '#ec4899'],
|
|
|
+ dataLabel: true,
|
|
|
}}
|
|
|
/>
|
|
|
</View>
|
|
|
@@ -453,6 +486,7 @@ const Statistics: React.FC<StatisticsProps> = () => {
|
|
|
series={convertToPieData(stats)}
|
|
|
config={{
|
|
|
color: ['#3b82f6', '#f59e0b', '#ef4444', '#10b981'],
|
|
|
+ dataLabel: true,
|
|
|
legend: {
|
|
|
show: true,
|
|
|
position: "right",
|
|
|
@@ -487,6 +521,7 @@ const Statistics: React.FC<StatisticsProps> = () => {
|
|
|
series={chartData.series}
|
|
|
config={{
|
|
|
color: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6', '#ef4444'],
|
|
|
+ dataLabel: true,
|
|
|
}}
|
|
|
/>
|
|
|
</View>
|