@yoka-ui/ui 1.0.7 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,13 @@
1
1
  # @yoka-ui/ui 具名导出表
2
2
 
3
3
  > **自动生成**:`pnpm run generate:yoka-llms`(源文件 `src/index.tsx`)
4
- > **包版本**:`1.0.7`
5
- > **生成时间**:`2026-04-23T09:55:19.921Z`
4
+ > **包版本**:`1.1.0`
5
+ > **生成时间**:`2026-04-27T11:44:30.343Z`
6
6
  > 请勿手动编辑本文件;修改导出请改 `src/index.tsx` 后重新运行上述命令。
7
7
 
8
8
  ## 使用约定(给 LLM / 业务开发者)
9
9
 
10
- - **包名**:`@yoka-ui/ui`(npm 公网);可选 Git 安装:`@yoka-ui/ui`: `git+http://gitlab.sh.com/web/yoka-ui.git#v1.0.7` 等,以实际 tag 为准
10
+ - **包名**:`@yoka-ui/ui`(npm 公网);可选 Git 安装:`@yoka-ui/ui`: `git+http://gitlab.sh.com/web/yoka-ui.git#v1.1.0` 等,以实际 tag 为准
11
11
  - **导入**:仅使用下表中的**具名**导出(组件/值与 `export type` 类型),与发布产物 `dist/es/index.d.ts` 一致;勿臆造未列出符号。
12
12
  - **全局样式(常用)**:业务入口引入一行,例如 `import '@yoka-ui/ui/dist/index.less'`(若以 README / 实际产物路径为准)。
13
13
  - **技术栈**:React 18、Ant Design 5;复杂表单/表格优先使用库内封装(`InputTheme`、`TableTheme`、`ModCommonFilter` 等),需要原生 antd API 时查阅 [Ant Design 文档](https://ant.design) 或本仓库 `@Docs/llms.txt`(克隆源码时可用)。
@@ -123,7 +123,7 @@ var Bar = ({
123
123
  data,
124
124
  dataSum: data.reduce((sum, val) => {
125
125
  const num = typeof val === "number" ? val : 0;
126
- return sum + (isNaN(num) ? 0 : num);
126
+ return sum + (Number.isNaN(num) ? 0 : num);
127
127
  }, 0)
128
128
  };
129
129
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/business/YkCharts/Bar.tsx"],
4
- "sourcesContent": ["import { Empty, message } from 'antd';\nimport classNames from 'classnames';\nimport Decimal from 'decimal.js';\nimport * as echarts from 'echarts';\nimport { isEmpty } from 'lodash';\nimport React, { type FC, memo, useEffect, useMemo, useRef } from 'react';\nimport ReactDOMServer from 'react-dom/server';\nimport { chartColors } from './constants';\nimport styles from './index.module.less';\nimport type { ColumnConfig, GroupByItem, SqlMetaConfig, TableData } from './typing';\nimport { formatNumber, formatValue, sqlFormat } from './utils';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n sqlFormatMap?: { [key: string]: SqlMetaConfig };\n height?: number;\n};\n\nconst MAX_SECTORS = 500;\n\nconst Bar: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n sqlFormatMap, // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n height,\n}) => {\n const { x = [], x_field, group_by } = tableData;\n const chartContainerRef = useRef<HTMLDivElement | null>(null);\n const chartInstanceRef = useRef<echarts.ECharts | null>(null);\n\n // 是否只有一个指标\n const onlyOneMetric = useMemo(() => {\n return metric.length === 1;\n }, [metric]);\n\n // 获取series数据\n const seriesData = useMemo(() => {\n if (Array.isArray(groupBys) && groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0)) {\n return [];\n }\n // 提前计算 validGroupBys 和 validGroupByKeys\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n const validGroupByKeys = validGroupBys.map((g) => g.key);\n // 如果没有 baseData,直接返回空数组\n if (!baseData || baseData.length === 0) {\n return [];\n }\n // 根据 groupBys 的 selected 过滤 baseData\n // 只保留符合所有 groupBy selected 条件的数据\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 建立 baseData 索引 Map,使用复合键 (x_field + validGroupByKeys + category) 作为 key\n // 格式: `${x_field}|${groupByKey1}|${groupByKey2}|...|${category}`\n const dataIndexMap = new Map<string, RowItem>();\n // 从 baseData 中提取实际存在的 groupBy 组合(而不是生成所有可能的组合)\n // 使用 Set 存储唯一的组合标识符,格式: `${groupByValue1}|${groupByValue2}|...|${metric}`\n const existingCombinations = new Map<\n string,\n {\n groupByValues: string;\n category: string;\n groupByObj: any;\n name: string;\n }\n >();\n\n // 预计算 name 的生成函数(提取到循环外,避免重复创建函数)\n const getName = (category: string, groupByObj: any) => {\n if (group_by && group_by.length > 0) {\n if (onlyOneMetric) {\n return group_by.map((g) => groupByObj[g]).join(',');\n }\n return [category, ...group_by.map((g) => groupByObj[g])].join(',');\n }\n return category;\n };\n\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n // 为每个 metric 建立索引和记录组合\n metric.forEach((cat) => {\n const key = `${item[x_field]}|${groupByValues}|${cat}`;\n dataIndexMap.set(key, item);\n // 记录实际存在的组合(每个 metric + groupBy 组合只记录一次)\n const combinationKey = `${groupByValues}|${cat}`;\n if (!existingCombinations.has(combinationKey)) {\n // 构建 groupBy 对象,用于后续生成 name\n const groupByObj: any = { category: cat };\n validGroupByKeys.forEach((gKey) => {\n groupByObj[gKey] = item[gKey];\n });\n // 预先计算 name,避免在 map 时重复计算\n const name = getName(cat, groupByObj);\n existingCombinations.set(combinationKey, {\n groupByValues,\n category: cat,\n groupByObj,\n name, // 预先计算好的 name\n });\n }\n });\n });\n\n // 直接从实际存在的组合生成 series,避免生成数百万个无效组合\n const result = Array.from(existingCombinations.values()).map(({ groupByValues, category, name }) => {\n // 预分配数组,避免动态扩容\n const data = new Array(x.length);\n for (let i = 0; i < x.length; i++) {\n const item = x[i];\n const key = `${item}|${groupByValues}|${category}`;\n const itemData = dataIndexMap.get(key);\n data[i] = itemData?.[category];\n }\n return {\n name,\n type: 'bar',\n barMaxWidth: 20,\n stack: (name as string).split(',')[0],\n smooth: true,\n showSymbol: false,\n data,\n dataSum: data.reduce((sum, val) => {\n const num = typeof val === 'number' ? val : 0;\n return sum + (isNaN(num) ? 0 : num);\n }, 0),\n };\n });\n\n // 按照 data 中数值合计从大到小排序\n const sortedResult = result.sort((a, b) => {\n const sumA = a.dataSum;\n const sumB = b.dataSum;\n return sumB - sumA; // 从大到小排序\n });\n return sortedResult;\n }, [baseData, metric, groupBys, x, x_field, group_by, onlyOneMetric]);\n\n // 获取y轴的格式化方式\n const yAxisFormatter = useMemo(() => {\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metric[0]]?.format;\n if (format?.type === 'currency') {\n return 'number';\n }\n if (format?.type === 'percent') {\n return 'percent';\n }\n if (format?.decimals > 0) {\n return 'decimal';\n }\n return 'number';\n }\n if (metric.length === 1) {\n return columnConfigMap[metric[0]]?.format;\n }\n return null;\n }, [metric, columnConfigMap, sqlFormatMap]);\n\n const grid = {\n top: 10,\n left: 0,\n right: 10,\n bottom: 40,\n containLabel: true,\n };\n const legend = {\n bottom: 0,\n type: 'scroll',\n };\n const xAxis = {\n type: 'category',\n data: x,\n axisLine: {\n lineStyle: {\n color: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#9CA4B3',\n fontSize: 12,\n },\n axisTick: {\n alignWithLabel: true,\n },\n boundaryGap: true,\n };\n const yAxis = {\n type: 'value',\n splitNumber: 4, // 设置Y轴坐标点数量\n axisLine: {\n show: true,\n lineStyle: {\n color: '#EBEEF4',\n shadowOffsetY: -10,\n shadowColor: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#999999',\n fontSize: 12,\n formatter: (value: number) => {\n if (yAxisFormatter === 'percent') {\n return new Decimal(value).mul(100) + '%';\n }\n if (yAxisFormatter === 'decimal') {\n return formatValue(value, yAxisFormatter);\n }\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n },\n },\n splitLine: {\n lineStyle: {\n type: [2, 3], // 虚线\n color: '#E7E7E7', // 背景线颜色\n },\n },\n axisTick: {\n show: true,\n },\n };\n const tooltipFormatter = (params: any) => {\n const title = params[0]?.axisValue ?? '';\n const tooltipDom = (\n <div className={styles.tooltip}>\n <div className={styles.title}>\n <span>{title}</span>\n <span style={{ float: 'right', paddingRight: 10 }}>\n {onlyOneMetric && metric.length === 1 ? ' ' + metric[0] : ''}\n </span>\n </div>\n <div className={styles.content}>\n {params.map((m: any) => {\n const metricName = onlyOneMetric && metric.length === 1 ? metric[0] : m.seriesName.split(',')[0];\n const columnConfig = columnConfigMap[metricName];\n const format = columnConfig?.format ?? 'string'; // 使用可选链和默认值\n let showValue = format === 'currency' ? formatNumber(m.value, true) : formatValue(m.value, format);\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metricName]?.format;\n showValue = sqlFormat(m.value, format);\n }\n const showValueText = showValue === '' || showValue[0] === '' ? '-' : showValue;\n return (\n <div className={styles.item} key={m.seriesName}>\n <div className={classNames(styles.point, styles.pointBar)} style={{ background: m.color }}></div>\n <div className={styles.category}>{m.seriesName}</div>\n <div className={styles.value}>{showValueText}</div>\n </div>\n );\n })}\n </div>\n </div>\n );\n return ReactDOMServer.renderToStaticMarkup(tooltipDom);\n };\n\n const tooltip = {\n trigger: 'axis',\n padding: 0,\n confine: true,\n enterable: true,\n axisPointer: {\n type: 'shadow',\n },\n formatter: tooltipFormatter,\n };\n\n // 图表配置\n const chartOptions = useMemo(() => {\n if (seriesData.length > MAX_SECTORS) {\n message.warning(`数据量过大,仅绘制前 ${MAX_SECTORS} 条数据`);\n }\n const result = {\n color: chartColors,\n grid,\n legend: {\n ...legend,\n itemWidth: 10,\n itemHeight: 10,\n },\n xAxis,\n yAxis,\n // 前端这里做个限制,防止数据量过大导致性能问题\n series: seriesData.length > MAX_SECTORS ? seriesData.slice(0, MAX_SECTORS) : seriesData,\n tooltip,\n barGap: '0%',\n };\n return result;\n }, [seriesData]);\n\n // 初始化图表\n useEffect(() => {\n if (!chartContainerRef.current) return;\n let chart = chartInstanceRef.current;\n if (!chart) {\n chart = echarts.init(chartContainerRef.current);\n chartInstanceRef.current = chart;\n }\n chart?.setOption(chartOptions, true);\n return () => {\n if (chartInstanceRef.current) {\n chartInstanceRef.current.dispose();\n chartInstanceRef.current = null;\n }\n };\n }, [chartOptions]);\n\n // 监听图表容器大小变化\n useEffect(() => {\n const chartElement = chartContainerRef.current;\n if (!chartElement) return;\n const resizeObserver = new ResizeObserver(() => {\n const chart = chartInstanceRef.current;\n if (chart) {\n chart.resize();\n }\n });\n resizeObserver.observe(chartElement);\n return () => {\n resizeObserver.unobserve(chartElement);\n resizeObserver.disconnect();\n };\n }, [seriesData]);\n\n return (\n <>\n {seriesData.length > 0 ? (\n <div\n ref={chartContainerRef}\n className={styles.echarts}\n style={{ width: '100%', height: height || '100%', minHeight: 220 }}\n ></div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\nexport default memo(Bar);\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Empty, message } from 'antd';\nimport classNames from 'classnames';\nimport Decimal from 'decimal.js';\nimport * as echarts from 'echarts';\nimport { isEmpty } from 'lodash';\nimport React, { type FC, memo, useEffect, useMemo, useRef } from 'react';\nimport ReactDOMServer from 'react-dom/server';\nimport { chartColors } from './constants';\nimport styles from './index.module.less';\nimport type { ColumnConfig, GroupByItem, SqlMetaConfig, TableData } from './typing';\nimport { formatNumber, formatValue, sqlFormat } from './utils';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n sqlFormatMap?: { [key: string]: SqlMetaConfig };\n height?: number;\n};\n\nconst MAX_SECTORS = 500;\n\nconst Bar: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n sqlFormatMap, // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n height,\n}) => {\n const { x = [], x_field, group_by } = tableData;\n const chartContainerRef = useRef<HTMLDivElement | null>(null);\n const chartInstanceRef = useRef<echarts.ECharts | null>(null);\n\n // 是否只有一个指标\n const onlyOneMetric = useMemo(() => {\n return metric.length === 1;\n }, [metric]);\n\n // 获取series数据\n const seriesData = useMemo(() => {\n if (Array.isArray(groupBys) && groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0)) {\n return [];\n }\n // 提前计算 validGroupBys 和 validGroupByKeys\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n const validGroupByKeys = validGroupBys.map((g) => g.key);\n // 如果没有 baseData,直接返回空数组\n if (!baseData || baseData.length === 0) {\n return [];\n }\n // 根据 groupBys 的 selected 过滤 baseData\n // 只保留符合所有 groupBy selected 条件的数据\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 建立 baseData 索引 Map,使用复合键 (x_field + validGroupByKeys + category) 作为 key\n // 格式: `${x_field}|${groupByKey1}|${groupByKey2}|...|${category}`\n const dataIndexMap = new Map<string, RowItem>();\n // 从 baseData 中提取实际存在的 groupBy 组合(而不是生成所有可能的组合)\n // 使用 Set 存储唯一的组合标识符,格式: `${groupByValue1}|${groupByValue2}|...|${metric}`\n const existingCombinations = new Map<\n string,\n {\n groupByValues: string;\n category: string;\n groupByObj: any;\n name: string;\n }\n >();\n\n // 预计算 name 的生成函数(提取到循环外,避免重复创建函数)\n const getName = (category: string, groupByObj: any) => {\n if (group_by && group_by.length > 0) {\n if (onlyOneMetric) {\n return group_by.map((g) => groupByObj[g]).join(',');\n }\n return [category, ...group_by.map((g) => groupByObj[g])].join(',');\n }\n return category;\n };\n\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n // 为每个 metric 建立索引和记录组合\n metric.forEach((cat) => {\n const key = `${item[x_field]}|${groupByValues}|${cat}`;\n dataIndexMap.set(key, item);\n // 记录实际存在的组合(每个 metric + groupBy 组合只记录一次)\n const combinationKey = `${groupByValues}|${cat}`;\n if (!existingCombinations.has(combinationKey)) {\n // 构建 groupBy 对象,用于后续生成 name\n const groupByObj: any = { category: cat };\n validGroupByKeys.forEach((gKey) => {\n groupByObj[gKey] = item[gKey];\n });\n // 预先计算 name,避免在 map 时重复计算\n const name = getName(cat, groupByObj);\n existingCombinations.set(combinationKey, {\n groupByValues,\n category: cat,\n groupByObj,\n name, // 预先计算好的 name\n });\n }\n });\n });\n\n // 直接从实际存在的组合生成 series,避免生成数百万个无效组合\n const result = Array.from(existingCombinations.values()).map(({ groupByValues, category, name }) => {\n // 预分配数组,避免动态扩容\n const data = new Array(x.length);\n for (let i = 0; i < x.length; i++) {\n const item = x[i];\n const key = `${item}|${groupByValues}|${category}`;\n const itemData = dataIndexMap.get(key);\n data[i] = itemData?.[category];\n }\n return {\n name,\n type: 'bar',\n barMaxWidth: 20,\n stack: (name as string).split(',')[0],\n smooth: true,\n showSymbol: false,\n data,\n dataSum: data.reduce((sum, val) => {\n const num = typeof val === 'number' ? val : 0;\n return sum + (Number.isNaN(num) ? 0 : num);\n }, 0),\n };\n });\n\n // 按照 data 中数值合计从大到小排序\n const sortedResult = result.sort((a, b) => {\n const sumA = a.dataSum;\n const sumB = b.dataSum;\n return sumB - sumA; // 从大到小排序\n });\n return sortedResult;\n }, [baseData, metric, groupBys, x, x_field, group_by, onlyOneMetric]);\n\n // 获取y轴的格式化方式\n const yAxisFormatter = useMemo(() => {\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metric[0]]?.format;\n if (format?.type === 'currency') {\n return 'number';\n }\n if (format?.type === 'percent') {\n return 'percent';\n }\n if (format?.decimals > 0) {\n return 'decimal';\n }\n return 'number';\n }\n if (metric.length === 1) {\n return columnConfigMap[metric[0]]?.format;\n }\n return null;\n }, [metric, columnConfigMap, sqlFormatMap]);\n\n const grid = {\n top: 10,\n left: 0,\n right: 10,\n bottom: 40,\n containLabel: true,\n };\n const legend = {\n bottom: 0,\n type: 'scroll',\n };\n const xAxis = {\n type: 'category',\n data: x,\n axisLine: {\n lineStyle: {\n color: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#9CA4B3',\n fontSize: 12,\n },\n axisTick: {\n alignWithLabel: true,\n },\n boundaryGap: true,\n };\n const yAxis = {\n type: 'value',\n splitNumber: 4, // 设置Y轴坐标点数量\n axisLine: {\n show: true,\n lineStyle: {\n color: '#EBEEF4',\n shadowOffsetY: -10,\n shadowColor: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#999999',\n fontSize: 12,\n formatter: (value: number) => {\n if (yAxisFormatter === 'percent') {\n return new Decimal(value).mul(100) + '%';\n }\n if (yAxisFormatter === 'decimal') {\n return formatValue(value, yAxisFormatter);\n }\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n },\n },\n splitLine: {\n lineStyle: {\n type: [2, 3], // 虚线\n color: '#E7E7E7', // 背景线颜色\n },\n },\n axisTick: {\n show: true,\n },\n };\n const tooltipFormatter = (params: any) => {\n const title = params[0]?.axisValue ?? '';\n const tooltipDom = (\n <div className={styles.tooltip}>\n <div className={styles.title}>\n <span>{title}</span>\n <span style={{ float: 'right', paddingRight: 10 }}>\n {onlyOneMetric && metric.length === 1 ? ' ' + metric[0] : ''}\n </span>\n </div>\n <div className={styles.content}>\n {params.map((m: any) => {\n const metricName = onlyOneMetric && metric.length === 1 ? metric[0] : m.seriesName.split(',')[0];\n const columnConfig = columnConfigMap[metricName];\n const format = columnConfig?.format ?? 'string'; // 使用可选链和默认值\n let showValue = format === 'currency' ? formatNumber(m.value, true) : formatValue(m.value, format);\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metricName]?.format;\n showValue = sqlFormat(m.value, format);\n }\n const showValueText = showValue === '' || showValue[0] === '' ? '-' : showValue;\n return (\n <div className={styles.item} key={m.seriesName}>\n <div className={classNames(styles.point, styles.pointBar)} style={{ background: m.color }}></div>\n <div className={styles.category}>{m.seriesName}</div>\n <div className={styles.value}>{showValueText}</div>\n </div>\n );\n })}\n </div>\n </div>\n );\n return ReactDOMServer.renderToStaticMarkup(tooltipDom);\n };\n\n const tooltip = {\n trigger: 'axis',\n padding: 0,\n confine: true,\n enterable: true,\n axisPointer: {\n type: 'shadow',\n },\n formatter: tooltipFormatter,\n };\n\n // 图表配置\n const chartOptions = useMemo(() => {\n if (seriesData.length > MAX_SECTORS) {\n message.warning(`数据量过大,仅绘制前 ${MAX_SECTORS} 条数据`);\n }\n const result = {\n color: chartColors,\n grid,\n legend: {\n ...legend,\n itemWidth: 10,\n itemHeight: 10,\n },\n xAxis,\n yAxis,\n // 前端这里做个限制,防止数据量过大导致性能问题\n series: seriesData.length > MAX_SECTORS ? seriesData.slice(0, MAX_SECTORS) : seriesData,\n tooltip,\n barGap: '0%',\n };\n return result;\n }, [seriesData]);\n\n // 初始化图表\n useEffect(() => {\n if (!chartContainerRef.current) return;\n let chart = chartInstanceRef.current;\n if (!chart) {\n chart = echarts.init(chartContainerRef.current);\n chartInstanceRef.current = chart;\n }\n chart?.setOption(chartOptions, true);\n return () => {\n if (chartInstanceRef.current) {\n chartInstanceRef.current.dispose();\n chartInstanceRef.current = null;\n }\n };\n }, [chartOptions]);\n\n // 监听图表容器大小变化\n useEffect(() => {\n const chartElement = chartContainerRef.current;\n if (!chartElement) return;\n const resizeObserver = new ResizeObserver(() => {\n const chart = chartInstanceRef.current;\n if (chart) {\n chart.resize();\n }\n });\n resizeObserver.observe(chartElement);\n return () => {\n resizeObserver.unobserve(chartElement);\n resizeObserver.disconnect();\n };\n }, [seriesData]);\n\n return (\n <>\n {seriesData.length > 0 ? (\n <div\n ref={chartContainerRef}\n className={styles.echarts}\n style={{ width: '100%', height: height || '100%', minHeight: 220 }}\n ></div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\nexport default memo(Bar);\n"],
5
+ "mappings": "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",
6
6
  "names": ["_a", "_b", "format"]
7
7
  }
@@ -81,7 +81,7 @@ var BarTotal = ({
81
81
  const sum = rows.reduce((s, r) => s + (Number(r[m]) || 0), 0);
82
82
  return sum;
83
83
  });
84
- const dataSum = data.reduce((s, v) => s + (isNaN(v) ? 0 : v), 0);
84
+ const dataSum = data.reduce((s, v) => s + (Number.isNaN(v) ? 0 : v), 0);
85
85
  return {
86
86
  name,
87
87
  type: "bar",
@@ -110,9 +110,13 @@ var BarTotal = ({
110
110
  }));
111
111
  }, [seriesData]);
112
112
  const chartData = useMemo(() => {
113
- return series.map((s) => __spreadValues({
114
- name: s.name
115
- }, metric.reduce((acc, m, i) => __spreadProps(__spreadValues({}, acc), { [m]: s.data[i] }), {})));
113
+ return series.map((s) => {
114
+ const obj = {};
115
+ metric.forEach((m, i) => {
116
+ obj[m] = s.data[i];
117
+ });
118
+ return __spreadValues({ name: s.name }, obj);
119
+ });
116
120
  }, [series, metric]);
117
121
  const yAxisFormatter = useMemo(() => {
118
122
  var _a;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/business/YkCharts/BarTotal.tsx"],
4
- "sourcesContent": ["/**\n * 基础分析-合计且有维度时的柱状图\n */\n\nimport { Empty, message } from 'antd';\nimport classNames from 'classnames';\nimport Decimal from 'decimal.js';\nimport * as echarts from 'echarts';\nimport React, { type FC, useEffect, useMemo, useRef } from 'react';\nimport ReactDOMServer from 'react-dom/server';\nimport { chartColors } from './constants';\nimport styles from './index.module.less';\nimport type { ColumnConfig, GroupByItem, TableData } from './typing';\nimport { formatNumber, formatValue } from './utils';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n height?: number;\n};\n\nconst MAX_SECTORS = 500;\n\nconst BarTotal: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n height,\n}) => {\n const chartContainerRef = useRef<HTMLDivElement | null>(null);\n const chartInstanceRef = useRef<echarts.ECharts | null>(null);\n\n const validGroupByKeys = useMemo(() => {\n return groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0).map((g) => g.key);\n }, [groupBys]);\n\n // 参照 Bar:从 baseData 提取实际存在的维度组合,不做笛卡尔积\n const seriesData = useMemo(() => {\n if (Array.isArray(groupBys) && groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0)) {\n return [];\n }\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n if (!baseData || baseData.length === 0) {\n return [];\n }\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 按维度组合聚合行(同一组合可能多行,如多日期需汇总指标)\n const byGroupBy = new Map<string, { name: string; rows: RowItem[] }>();\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n const name = validGroupByKeys.map((key) => item[key]).join(',');\n if (!byGroupBy.has(groupByValues)) {\n byGroupBy.set(groupByValues, { name, rows: [] });\n }\n byGroupBy.get(groupByValues)!.rows.push(item);\n });\n const result = Array.from(byGroupBy.entries()).map(([, { name, rows }]) => {\n const data = metric.map((m) => {\n const sum = rows.reduce((s, r) => s + (Number(r[m]) || 0), 0);\n return sum;\n });\n const dataSum = data.reduce((s, v) => s + (isNaN(v) ? 0 : v), 0);\n return {\n name,\n type: 'bar' as const,\n barMaxWidth: 20,\n smooth: true,\n showSymbol: false,\n data,\n dataSum,\n };\n });\n result.sort((a, b) => b.dataSum - a.dataSum);\n return result;\n }, [baseData, metric, groupBys, validGroupByKeys]);\n\n const series = useMemo(() => {\n const list = seriesData.length > MAX_SECTORS ? seriesData.slice(0, MAX_SECTORS) : seriesData;\n if (seriesData.length > MAX_SECTORS) {\n message.warning(`数据量过大,仅绘制前 ${MAX_SECTORS} 条数据`);\n }\n return list.map(({ name, data, type, barMaxWidth, smooth, showSymbol }) => ({\n name,\n type,\n barMaxWidth,\n smooth,\n showSymbol,\n data,\n }));\n }, [seriesData]);\n\n // 供 tooltip 使用:由 series 反推 chartData 结构\n const chartData = useMemo(() => {\n return series.map((s) => ({\n name: s.name,\n ...metric.reduce((acc, m, i) => ({ ...acc, [m]: s.data[i] }), {} as Record<string, number>),\n }));\n }, [series, metric]);\n\n // 获取y轴的格式化方式\n const yAxisFormatter = useMemo(() => {\n if (metric.length === 1) {\n return columnConfigMap[metric[0]]?.format;\n }\n return null;\n }, [metric, columnConfigMap]);\n\n const grid = {\n top: 10,\n left: 0,\n right: 10,\n bottom: 40,\n containLabel: true,\n };\n const legend = {\n bottom: 0,\n type: 'scroll',\n };\n const xAxis = {\n type: 'category',\n data: metric,\n axisLine: {\n lineStyle: {\n color: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#9CA4B3',\n fontSize: 12,\n },\n axisTick: {\n alignWithLabel: true,\n },\n boundaryGap: true,\n };\n const yAxis = {\n type: 'value',\n splitNumber: 4, // 设置Y轴坐标点数量\n axisLine: {\n show: true,\n lineStyle: {\n color: '#EBEEF4',\n shadowOffsetY: -10,\n shadowColor: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#999999',\n fontSize: 12,\n formatter: (value: number) => {\n // 目前只有一个指标时, Y轴进行格式化\n if (yAxisFormatter) {\n if (yAxisFormatter === 'currency') {\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n }\n if (yAxisFormatter === 'percent') {\n return new Decimal(value).mul(100) + '%';\n }\n return formatValue(value, yAxisFormatter);\n }\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n },\n },\n splitLine: {\n lineStyle: {\n type: [2, 3], // 虚线\n color: '#E7E7E7', // 背景线颜色\n },\n },\n axisTick: {\n show: true,\n },\n };\n const tooltipFormatter = (params: any) => {\n const title = params[0]?.axisValue ?? '';\n const filterParams = params.filter((f: any) => {\n const { name, seriesName } = f;\n if (name === '合计') {\n return true;\n } else if (\n chartData.some((dataItem) => {\n return dataItem?.name === seriesName;\n })\n ) {\n return true;\n }\n return false;\n });\n\n const tooltipDom = (\n <div className={styles.tooltip}>\n <div className={styles.title}>{title}</div>\n <div className={styles.content}>\n {filterParams.map((m: any) => {\n const columnConfig = columnConfigMap[metric[0]];\n const format = columnConfig?.format ?? 'string'; // 使用可选链和默认值\n const showValue = format === 'currency' ? formatNumber(m.value, true) : formatValue(m.value, format);\n const showValueText = showValue === '' || showValue[0] === '' ? '-' : showValue;\n return (\n <div className={styles.item} key={m.seriesName}>\n <div className={classNames(styles.point, styles.pointBar)} style={{ background: m.color }}></div>\n <div className={styles.category}>{m.seriesName}</div>\n <div className={styles.value}>{showValueText}</div>\n </div>\n );\n })}\n </div>\n </div>\n );\n return ReactDOMServer.renderToStaticMarkup(tooltipDom);\n };\n const tooltip = {\n trigger: 'axis',\n padding: 0,\n confine: true,\n enterable: true,\n axisPointer: {\n type: 'shadow',\n },\n formatter: tooltipFormatter,\n };\n\n // 图表配置\n const chartOptions = useMemo(() => {\n return {\n color: chartColors,\n grid,\n legend: {\n ...legend,\n itemWidth: 10,\n itemHeight: 10,\n },\n xAxis,\n yAxis,\n series,\n tooltip,\n };\n }, [series]);\n\n // 仅卸载时销毁实例\n useEffect(() => {\n return () => {\n if (chartInstanceRef.current) {\n chartInstanceRef.current.dispose();\n chartInstanceRef.current = null;\n }\n };\n }, []);\n\n // 配置变化时仅 setOption\n useEffect(() => {\n const container = chartContainerRef.current;\n if (!container) return;\n let chart = chartInstanceRef.current;\n if (!chart) {\n chart = echarts.init(container);\n chartInstanceRef.current = chart;\n }\n chart.setOption(chartOptions, true);\n }, [chartOptions]);\n\n // 监听容器大小变化(仅挂载时注册)\n useEffect(() => {\n const chartElement = chartContainerRef.current;\n if (!chartElement) return;\n const resizeObserver = new ResizeObserver(() => {\n chartInstanceRef.current?.resize();\n });\n resizeObserver.observe(chartElement);\n return () => {\n resizeObserver.unobserve(chartElement);\n resizeObserver.disconnect();\n };\n }, []);\n\n return (\n <>\n {chartData.length > 0 ? (\n <div\n ref={chartContainerRef}\n className={styles.echarts}\n style={{ width: '100%', height: height || '100%', minHeight: 220 }}\n ></div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\nexport default BarTotal;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * 基础分析-合计且有维度时的柱状图\n */\n\nimport { Empty, message } from 'antd';\nimport classNames from 'classnames';\nimport Decimal from 'decimal.js';\nimport * as echarts from 'echarts';\nimport React, { type FC, useEffect, useMemo, useRef } from 'react';\nimport ReactDOMServer from 'react-dom/server';\nimport { chartColors } from './constants';\nimport styles from './index.module.less';\nimport type { ColumnConfig, GroupByItem, TableData } from './typing';\nimport { formatNumber, formatValue } from './utils';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n height?: number;\n};\n\nconst MAX_SECTORS = 500;\n\nconst BarTotal: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n height,\n}) => {\n const chartContainerRef = useRef<HTMLDivElement | null>(null);\n const chartInstanceRef = useRef<echarts.ECharts | null>(null);\n\n const validGroupByKeys = useMemo(() => {\n return groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0).map((g) => g.key);\n }, [groupBys]);\n\n // 参照 Bar:从 baseData 提取实际存在的维度组合,不做笛卡尔积\n const seriesData = useMemo(() => {\n if (Array.isArray(groupBys) && groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0)) {\n return [];\n }\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n if (!baseData || baseData.length === 0) {\n return [];\n }\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 按维度组合聚合行(同一组合可能多行,如多日期需汇总指标)\n const byGroupBy = new Map<string, { name: string; rows: RowItem[] }>();\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n const name = validGroupByKeys.map((key) => item[key]).join(',');\n if (!byGroupBy.has(groupByValues)) {\n byGroupBy.set(groupByValues, { name, rows: [] });\n }\n byGroupBy.get(groupByValues)!.rows.push(item);\n });\n const result = Array.from(byGroupBy.entries()).map(([, { name, rows }]) => {\n const data = metric.map((m) => {\n const sum = rows.reduce((s, r) => s + (Number(r[m]) || 0), 0);\n return sum;\n });\n const dataSum = data.reduce((s, v) => s + (Number.isNaN(v) ? 0 : v), 0);\n return {\n name,\n type: 'bar' as const,\n barMaxWidth: 20,\n smooth: true,\n showSymbol: false,\n data,\n dataSum,\n };\n });\n result.sort((a, b) => b.dataSum - a.dataSum);\n return result;\n }, [baseData, metric, groupBys, validGroupByKeys]);\n\n const series = useMemo(() => {\n const list = seriesData.length > MAX_SECTORS ? seriesData.slice(0, MAX_SECTORS) : seriesData;\n if (seriesData.length > MAX_SECTORS) {\n message.warning(`数据量过大,仅绘制前 ${MAX_SECTORS} 条数据`);\n }\n return list.map(({ name, data, type, barMaxWidth, smooth, showSymbol }) => ({\n name,\n type,\n barMaxWidth,\n smooth,\n showSymbol,\n data,\n }));\n }, [seriesData]);\n\n // 供 tooltip 使用:由 series 反推 chartData 结构\n const chartData = useMemo(() => {\n return series.map((s) => {\n const obj: Record<string, number> = {};\n metric.forEach((m, i) => {\n obj[m] = s.data[i];\n });\n return { name: s.name, ...obj };\n });\n }, [series, metric]);\n\n // 获取y轴的格式化方式\n const yAxisFormatter = useMemo(() => {\n if (metric.length === 1) {\n return columnConfigMap[metric[0]]?.format;\n }\n return null;\n }, [metric, columnConfigMap]);\n\n const grid = {\n top: 10,\n left: 0,\n right: 10,\n bottom: 40,\n containLabel: true,\n };\n const legend = {\n bottom: 0,\n type: 'scroll',\n };\n const xAxis = {\n type: 'category',\n data: metric,\n axisLine: {\n lineStyle: {\n color: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#9CA4B3',\n fontSize: 12,\n },\n axisTick: {\n alignWithLabel: true,\n },\n boundaryGap: true,\n };\n const yAxis = {\n type: 'value',\n splitNumber: 4, // 设置Y轴坐标点数量\n axisLine: {\n show: true,\n lineStyle: {\n color: '#EBEEF4',\n shadowOffsetY: -10,\n shadowColor: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#999999',\n fontSize: 12,\n formatter: (value: number) => {\n // 目前只有一个指标时, Y轴进行格式化\n if (yAxisFormatter) {\n if (yAxisFormatter === 'currency') {\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n }\n if (yAxisFormatter === 'percent') {\n return new Decimal(value).mul(100) + '%';\n }\n return formatValue(value, yAxisFormatter);\n }\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n },\n },\n splitLine: {\n lineStyle: {\n type: [2, 3], // 虚线\n color: '#E7E7E7', // 背景线颜色\n },\n },\n axisTick: {\n show: true,\n },\n };\n const tooltipFormatter = (params: any) => {\n const title = params[0]?.axisValue ?? '';\n const filterParams = params.filter((f: any) => {\n const { name, seriesName } = f;\n if (name === '合计') {\n return true;\n } else if (\n chartData.some((dataItem) => {\n return dataItem?.name === seriesName;\n })\n ) {\n return true;\n }\n return false;\n });\n\n const tooltipDom = (\n <div className={styles.tooltip}>\n <div className={styles.title}>{title}</div>\n <div className={styles.content}>\n {filterParams.map((m: any) => {\n const columnConfig = columnConfigMap[metric[0]];\n const format = columnConfig?.format ?? 'string'; // 使用可选链和默认值\n const showValue = format === 'currency' ? formatNumber(m.value, true) : formatValue(m.value, format);\n const showValueText = showValue === '' || showValue[0] === '' ? '-' : showValue;\n return (\n <div className={styles.item} key={m.seriesName}>\n <div className={classNames(styles.point, styles.pointBar)} style={{ background: m.color }}></div>\n <div className={styles.category}>{m.seriesName}</div>\n <div className={styles.value}>{showValueText}</div>\n </div>\n );\n })}\n </div>\n </div>\n );\n return ReactDOMServer.renderToStaticMarkup(tooltipDom);\n };\n const tooltip = {\n trigger: 'axis',\n padding: 0,\n confine: true,\n enterable: true,\n axisPointer: {\n type: 'shadow',\n },\n formatter: tooltipFormatter,\n };\n\n // 图表配置\n const chartOptions = useMemo(() => {\n return {\n color: chartColors,\n grid,\n legend: {\n ...legend,\n itemWidth: 10,\n itemHeight: 10,\n },\n xAxis,\n yAxis,\n series,\n tooltip,\n };\n }, [series]);\n\n // 仅卸载时销毁实例\n useEffect(() => {\n return () => {\n if (chartInstanceRef.current) {\n chartInstanceRef.current.dispose();\n chartInstanceRef.current = null;\n }\n };\n }, []);\n\n // 配置变化时仅 setOption\n useEffect(() => {\n const container = chartContainerRef.current;\n if (!container) return;\n let chart = chartInstanceRef.current;\n if (!chart) {\n chart = echarts.init(container);\n chartInstanceRef.current = chart;\n }\n chart.setOption(chartOptions, true);\n }, [chartOptions]);\n\n // 监听容器大小变化(仅挂载时注册)\n useEffect(() => {\n const chartElement = chartContainerRef.current;\n if (!chartElement) return;\n const resizeObserver = new ResizeObserver(() => {\n chartInstanceRef.current?.resize();\n });\n resizeObserver.observe(chartElement);\n return () => {\n resizeObserver.unobserve(chartElement);\n resizeObserver.disconnect();\n };\n }, []);\n\n return (\n <>\n {chartData.length > 0 ? (\n <div\n ref={chartContainerRef}\n className={styles.echarts}\n style={{ width: '100%', height: height || '100%', minHeight: 220 }}\n ></div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\nexport default BarTotal;\n"],
5
+ "mappings": "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",
6
6
  "names": ["result", "unit", "_a"]
7
7
  }
@@ -128,7 +128,7 @@ var Line = ({
128
128
  data,
129
129
  dataSum: data.reduce((sum, val) => {
130
130
  const num = typeof val === "number" ? val : 0;
131
- return sum + (isNaN(num) ? 0 : num);
131
+ return sum + (Number.isNaN(num) ? 0 : num);
132
132
  }, 0)
133
133
  };
134
134
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/business/YkCharts/Line.tsx"],
4
- "sourcesContent": ["import { Empty, message } from 'antd';\nimport Decimal from 'decimal.js';\nimport * as echarts from 'echarts';\nimport { isEmpty } from 'lodash';\nimport React, { type FC, memo, useEffect, useMemo, useRef } from 'react';\nimport ReactDOMServer from 'react-dom/server';\nimport { chartColors } from './constants';\nimport styles from './index.module.less';\nimport type { ColumnConfig, GroupByItem, SqlMetaConfig, TableData } from './typing';\nimport { formatNumber, formatValue, sqlFormat } from './utils';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n sqlFormatMap?: { [key: string]: SqlMetaConfig };\n height?: number;\n};\n\nconst MAX_SECTORS = 500;\n\nconst Line: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n sqlFormatMap, // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n height,\n}) => {\n const { x = [], x_field, group_by } = tableData;\n const chartContainerRef = useRef<HTMLDivElement | null>(null);\n const chartInstanceRef = useRef<echarts.ECharts | null>(null);\n\n // 是否只有一个指标\n const onlyOneMetric = useMemo(() => {\n return metric.length === 1;\n }, [metric]);\n\n // 获取series数据\n const seriesData = useMemo(() => {\n if (Array.isArray(groupBys) && groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0)) {\n return [];\n }\n // 提前计算 validGroupBys 和 validGroupByKeys\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n const validGroupByKeys = validGroupBys.map((g) => g.key);\n // 如果没有 baseData,直接返回空数组\n if (!baseData || baseData.length === 0) {\n return [];\n }\n // 根据 groupBys 的 selected 过滤 baseData\n // 只保留符合所有 groupBy selected 条件的数据\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 建立 baseData 索引 Map,使用复合键 (x_field + validGroupByKeys + category) 作为 key\n // 格式: `${x_field}|${groupByKey1}|${groupByKey2}|...|${category}`\n const dataIndexMap = new Map<string, RowItem>();\n // 从 baseData 中提取实际存在的 groupBy 组合(而不是生成所有可能的组合)\n // 使用 Set 存储唯一的组合标识符,格式: `${groupByValue1}|${groupByValue2}|...|${metric}`\n const existingCombinations = new Map<\n string,\n {\n groupByValues: string;\n category: string;\n groupByObj: any;\n name: string;\n }\n >();\n\n // 预计算 name 的生成函数(提取到循环外,避免重复创建函数)\n const getName = (category: string, groupByObj: any) => {\n if (group_by && group_by.length > 0) {\n if (onlyOneMetric) {\n return group_by.map((g) => groupByObj[g]).join(',');\n }\n return [category, ...group_by.map((g) => groupByObj[g])].join(',');\n }\n return category;\n };\n\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n // 为每个 metric 建立索引和记录组合\n metric.forEach((cat) => {\n const key = `${item[x_field]}|${groupByValues}|${cat}`;\n dataIndexMap.set(key, item);\n // 记录实际存在的组合(每个 metric + groupBy 组合只记录一次)\n const combinationKey = `${groupByValues}|${cat}`;\n if (!existingCombinations.has(combinationKey)) {\n // 构建 groupBy 对象,用于后续生成 name\n const groupByObj: any = { category: cat };\n validGroupByKeys.forEach((gKey) => {\n groupByObj[gKey] = item[gKey];\n });\n // 预先计算 name,避免在 map 时重复计算\n const name = getName(cat, groupByObj);\n existingCombinations.set(combinationKey, {\n groupByValues,\n category: cat,\n groupByObj,\n name, // 预先计算好的 name\n });\n }\n });\n });\n\n // 直接从实际存在的组合生成 series,避免生成数百万个无效组合\n const result = Array.from(existingCombinations.values()).map(({ groupByValues, category, name }) => {\n // 预分配数组,避免动态扩容\n const data = new Array(x.length);\n for (let i = 0; i < x.length; i++) {\n const item = x[i];\n const key = `${item}|${groupByValues}|${category}`;\n const itemData = dataIndexMap.get(key);\n data[i] = itemData?.[category];\n }\n\n return {\n name,\n type: 'line',\n smooth: true,\n showSymbol: true,\n symbol: 'emptyCircle',\n symbolSize: 0.8,\n lineStyle: {\n width: 1.5,\n },\n emphasis: {\n scale: 8,\n },\n data,\n dataSum: data.reduce((sum, val) => {\n const num = typeof val === 'number' ? val : 0;\n return sum + (isNaN(num) ? 0 : num);\n }, 0),\n };\n });\n\n // 按照 data 中数值合计从大到小排序\n const sortedResult = result.sort((a, b) => {\n const sumA = a.dataSum;\n const sumB = b.dataSum;\n return sumB - sumA; // 从大到小排序\n });\n return sortedResult;\n }, [baseData, metric, groupBys, x, x_field, group_by, onlyOneMetric]);\n\n // 获取y轴的格式化方式\n const yAxisFormatter = useMemo(() => {\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metric[0]]?.format;\n if (format?.type === 'currency') {\n return 'number';\n }\n if (format?.type === 'percent') {\n return 'percent';\n }\n if (format?.decimals > 0) {\n return 'decimal';\n }\n return 'number';\n }\n if (metric.length === 1) {\n return columnConfigMap[metric[0]]?.format;\n }\n return null;\n }, [metric, columnConfigMap, sqlFormatMap]);\n\n const grid = {\n top: 10,\n left: 5,\n right: 10,\n bottom: 40,\n containLabel: true,\n };\n const legend = {\n bottom: 0,\n type: 'scroll',\n itemWidth: 13,\n itemStyle: {\n opacity: 0,\n },\n lineStyle: {\n width: 2,\n type: 'solid',\n },\n };\n const xAxis = {\n type: 'category',\n data: x,\n axisLine: {\n lineStyle: {\n color: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#9CA4B3',\n fontSize: 12,\n },\n axisTick: {\n alignWithLabel: true,\n },\n boundaryGap: true,\n };\n const yAxis = {\n type: 'value',\n splitNumber: 4, // 设置Y轴坐标点数量\n axisLine: {\n show: true,\n lineStyle: {\n color: '#EBEEF4',\n shadowOffsetY: -10,\n shadowColor: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#999999',\n fontSize: 12,\n padding: [0, 0, 0, 5],\n formatter: (value: number) => {\n if (yAxisFormatter === 'percent') {\n return new Decimal(value).mul(100) + '%';\n }\n if (yAxisFormatter === 'decimal') {\n return formatValue(value, yAxisFormatter);\n }\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n },\n },\n splitLine: {\n lineStyle: {\n type: [2, 3], // 虚线\n color: '#E7E7E7', // 背景线颜色\n },\n },\n axisTick: {\n show: true,\n },\n };\n const tooltipFormatter = (params: any) => {\n const title = params[0]?.axisValue ?? '';\n const tooltipDom = (\n <div className={styles.tooltip}>\n <div className={styles.title}>\n <span>{title}</span>\n <span style={{ float: 'right', paddingRight: 10 }}>\n {onlyOneMetric && metric.length === 1 ? ' ' + metric[0] : ''}\n </span>\n </div>\n <div className={styles.content}>\n {params.map((m: any) => {\n const metricName = onlyOneMetric && metric.length === 1 ? metric[0] : m.seriesName.split(',')[0];\n const columnConfig = columnConfigMap[metricName];\n const format = columnConfig?.format ?? 'string'; // 使用可选链和默认值\n let showValue = format === 'currency' ? formatNumber(m.value, true) : formatValue(m.value, format);\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metricName]?.format;\n showValue = sqlFormat(m.value, format);\n }\n const showValueText = showValue === '' || showValue[0] === '' ? '-' : showValue;\n return (\n <div className={styles.item} key={m.seriesName}>\n <div className={styles.point} style={{ background: m.color }}></div>\n <div className={styles.category}>{m.seriesName}</div>\n <div className={styles.value}>{showValueText}</div>\n </div>\n );\n })}\n </div>\n </div>\n );\n return ReactDOMServer.renderToStaticMarkup(tooltipDom);\n };\n\n const tooltip = {\n trigger: 'axis',\n padding: 0,\n confine: true,\n enterable: true,\n axisPointer: {\n type: 'line', // 设置悬浮指针为线\n lineStyle: {\n color: '#EBEEF4', // 设置线的颜色\n type: 'dashed', // 设置虚线样式\n },\n },\n formatter: tooltipFormatter,\n };\n\n // 图表配置\n const chartOptions = useMemo(() => {\n if (seriesData.length > MAX_SECTORS) {\n message.warning(`数据量过大,仅绘制前 ${MAX_SECTORS} 条数据`);\n }\n const result = {\n color: chartColors,\n grid,\n legend: {\n ...legend,\n itemWidth: 13,\n itemStyle: {\n opacity: 0,\n },\n lineStyle: {\n width: 2,\n type: 'solid',\n },\n },\n xAxis,\n yAxis,\n // 前端这里做个限制,防止数据量过大导致性能问题\n series: seriesData.length > MAX_SECTORS ? seriesData.slice(0, MAX_SECTORS) : seriesData,\n tooltip,\n };\n\n return result;\n }, [seriesData]);\n\n // 初始化图表\n useEffect(() => {\n if (!chartContainerRef.current) return;\n let chart = chartInstanceRef.current;\n if (!chart) {\n chart = echarts.init(chartContainerRef.current);\n chartInstanceRef.current = chart;\n }\n chart?.setOption(chartOptions, true);\n return () => {\n if (chartInstanceRef.current) {\n chartInstanceRef.current.dispose();\n chartInstanceRef.current = null;\n }\n };\n }, [chartOptions]);\n\n // 监听图表容器大小变化\n useEffect(() => {\n const chartElement = chartContainerRef.current;\n if (!chartElement) return;\n const resizeObserver = new ResizeObserver(() => {\n const chart = chartInstanceRef.current;\n if (chart) {\n chart.resize();\n }\n });\n resizeObserver.observe(chartElement);\n return () => {\n resizeObserver.unobserve(chartElement);\n resizeObserver.disconnect();\n };\n }, [seriesData]);\n\n return (\n <>\n {seriesData.length > 0 ? (\n <div\n ref={chartContainerRef}\n className={styles.echarts}\n style={{ width: '100%', height: height || '100%', minHeight: 220 }}\n ></div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\n// 使用 memo 包裹组件,避免不必要的重新渲染\n// 自定义比较函数,深度比较关键 props\nexport default memo(Line);\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Empty, message } from 'antd';\nimport Decimal from 'decimal.js';\nimport * as echarts from 'echarts';\nimport { isEmpty } from 'lodash';\nimport React, { type FC, memo, useEffect, useMemo, useRef } from 'react';\nimport ReactDOMServer from 'react-dom/server';\nimport { chartColors } from './constants';\nimport styles from './index.module.less';\nimport type { ColumnConfig, GroupByItem, SqlMetaConfig, TableData } from './typing';\nimport { formatNumber, formatValue, sqlFormat } from './utils';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n sqlFormatMap?: { [key: string]: SqlMetaConfig };\n height?: number;\n};\n\nconst MAX_SECTORS = 500;\n\nconst Line: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n sqlFormatMap, // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n height,\n}) => {\n const { x = [], x_field, group_by } = tableData;\n const chartContainerRef = useRef<HTMLDivElement | null>(null);\n const chartInstanceRef = useRef<echarts.ECharts | null>(null);\n\n // 是否只有一个指标\n const onlyOneMetric = useMemo(() => {\n return metric.length === 1;\n }, [metric]);\n\n // 获取series数据\n const seriesData = useMemo(() => {\n if (Array.isArray(groupBys) && groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0)) {\n return [];\n }\n // 提前计算 validGroupBys 和 validGroupByKeys\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n const validGroupByKeys = validGroupBys.map((g) => g.key);\n // 如果没有 baseData,直接返回空数组\n if (!baseData || baseData.length === 0) {\n return [];\n }\n // 根据 groupBys 的 selected 过滤 baseData\n // 只保留符合所有 groupBy selected 条件的数据\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 建立 baseData 索引 Map,使用复合键 (x_field + validGroupByKeys + category) 作为 key\n // 格式: `${x_field}|${groupByKey1}|${groupByKey2}|...|${category}`\n const dataIndexMap = new Map<string, RowItem>();\n // 从 baseData 中提取实际存在的 groupBy 组合(而不是生成所有可能的组合)\n // 使用 Set 存储唯一的组合标识符,格式: `${groupByValue1}|${groupByValue2}|...|${metric}`\n const existingCombinations = new Map<\n string,\n {\n groupByValues: string;\n category: string;\n groupByObj: any;\n name: string;\n }\n >();\n\n // 预计算 name 的生成函数(提取到循环外,避免重复创建函数)\n const getName = (category: string, groupByObj: any) => {\n if (group_by && group_by.length > 0) {\n if (onlyOneMetric) {\n return group_by.map((g) => groupByObj[g]).join(',');\n }\n return [category, ...group_by.map((g) => groupByObj[g])].join(',');\n }\n return category;\n };\n\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n // 为每个 metric 建立索引和记录组合\n metric.forEach((cat) => {\n const key = `${item[x_field]}|${groupByValues}|${cat}`;\n dataIndexMap.set(key, item);\n // 记录实际存在的组合(每个 metric + groupBy 组合只记录一次)\n const combinationKey = `${groupByValues}|${cat}`;\n if (!existingCombinations.has(combinationKey)) {\n // 构建 groupBy 对象,用于后续生成 name\n const groupByObj: any = { category: cat };\n validGroupByKeys.forEach((gKey) => {\n groupByObj[gKey] = item[gKey];\n });\n // 预先计算 name,避免在 map 时重复计算\n const name = getName(cat, groupByObj);\n existingCombinations.set(combinationKey, {\n groupByValues,\n category: cat,\n groupByObj,\n name, // 预先计算好的 name\n });\n }\n });\n });\n\n // 直接从实际存在的组合生成 series,避免生成数百万个无效组合\n const result = Array.from(existingCombinations.values()).map(({ groupByValues, category, name }) => {\n // 预分配数组,避免动态扩容\n const data = new Array(x.length);\n for (let i = 0; i < x.length; i++) {\n const item = x[i];\n const key = `${item}|${groupByValues}|${category}`;\n const itemData = dataIndexMap.get(key);\n data[i] = itemData?.[category];\n }\n\n return {\n name,\n type: 'line',\n smooth: true,\n showSymbol: true,\n symbol: 'emptyCircle',\n symbolSize: 0.8,\n lineStyle: {\n width: 1.5,\n },\n emphasis: {\n scale: 8,\n },\n data,\n dataSum: data.reduce((sum, val) => {\n const num = typeof val === 'number' ? val : 0;\n return sum + (Number.isNaN(num) ? 0 : num);\n }, 0),\n };\n });\n\n // 按照 data 中数值合计从大到小排序\n const sortedResult = result.sort((a, b) => {\n const sumA = a.dataSum;\n const sumB = b.dataSum;\n return sumB - sumA; // 从大到小排序\n });\n return sortedResult;\n }, [baseData, metric, groupBys, x, x_field, group_by, onlyOneMetric]);\n\n // 获取y轴的格式化方式\n const yAxisFormatter = useMemo(() => {\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metric[0]]?.format;\n if (format?.type === 'currency') {\n return 'number';\n }\n if (format?.type === 'percent') {\n return 'percent';\n }\n if (format?.decimals > 0) {\n return 'decimal';\n }\n return 'number';\n }\n if (metric.length === 1) {\n return columnConfigMap[metric[0]]?.format;\n }\n return null;\n }, [metric, columnConfigMap, sqlFormatMap]);\n\n const grid = {\n top: 10,\n left: 5,\n right: 10,\n bottom: 40,\n containLabel: true,\n };\n const legend = {\n bottom: 0,\n type: 'scroll',\n itemWidth: 13,\n itemStyle: {\n opacity: 0,\n },\n lineStyle: {\n width: 2,\n type: 'solid',\n },\n };\n const xAxis = {\n type: 'category',\n data: x,\n axisLine: {\n lineStyle: {\n color: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#9CA4B3',\n fontSize: 12,\n },\n axisTick: {\n alignWithLabel: true,\n },\n boundaryGap: true,\n };\n const yAxis = {\n type: 'value',\n splitNumber: 4, // 设置Y轴坐标点数量\n axisLine: {\n show: true,\n lineStyle: {\n color: '#EBEEF4',\n shadowOffsetY: -10,\n shadowColor: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#999999',\n fontSize: 12,\n padding: [0, 0, 0, 5],\n formatter: (value: number) => {\n if (yAxisFormatter === 'percent') {\n return new Decimal(value).mul(100) + '%';\n }\n if (yAxisFormatter === 'decimal') {\n return formatValue(value, yAxisFormatter);\n }\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n },\n },\n splitLine: {\n lineStyle: {\n type: [2, 3], // 虚线\n color: '#E7E7E7', // 背景线颜色\n },\n },\n axisTick: {\n show: true,\n },\n };\n const tooltipFormatter = (params: any) => {\n const title = params[0]?.axisValue ?? '';\n const tooltipDom = (\n <div className={styles.tooltip}>\n <div className={styles.title}>\n <span>{title}</span>\n <span style={{ float: 'right', paddingRight: 10 }}>\n {onlyOneMetric && metric.length === 1 ? ' ' + metric[0] : ''}\n </span>\n </div>\n <div className={styles.content}>\n {params.map((m: any) => {\n const metricName = onlyOneMetric && metric.length === 1 ? metric[0] : m.seriesName.split(',')[0];\n const columnConfig = columnConfigMap[metricName];\n const format = columnConfig?.format ?? 'string'; // 使用可选链和默认值\n let showValue = format === 'currency' ? formatNumber(m.value, true) : formatValue(m.value, format);\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metricName]?.format;\n showValue = sqlFormat(m.value, format);\n }\n const showValueText = showValue === '' || showValue[0] === '' ? '-' : showValue;\n return (\n <div className={styles.item} key={m.seriesName}>\n <div className={styles.point} style={{ background: m.color }}></div>\n <div className={styles.category}>{m.seriesName}</div>\n <div className={styles.value}>{showValueText}</div>\n </div>\n );\n })}\n </div>\n </div>\n );\n return ReactDOMServer.renderToStaticMarkup(tooltipDom);\n };\n\n const tooltip = {\n trigger: 'axis',\n padding: 0,\n confine: true,\n enterable: true,\n axisPointer: {\n type: 'line', // 设置悬浮指针为线\n lineStyle: {\n color: '#EBEEF4', // 设置线的颜色\n type: 'dashed', // 设置虚线样式\n },\n },\n formatter: tooltipFormatter,\n };\n\n // 图表配置\n const chartOptions = useMemo(() => {\n if (seriesData.length > MAX_SECTORS) {\n message.warning(`数据量过大,仅绘制前 ${MAX_SECTORS} 条数据`);\n }\n const result = {\n color: chartColors,\n grid,\n legend: {\n ...legend,\n itemWidth: 13,\n itemStyle: {\n opacity: 0,\n },\n lineStyle: {\n width: 2,\n type: 'solid',\n },\n },\n xAxis,\n yAxis,\n // 前端这里做个限制,防止数据量过大导致性能问题\n series: seriesData.length > MAX_SECTORS ? seriesData.slice(0, MAX_SECTORS) : seriesData,\n tooltip,\n };\n\n return result;\n }, [seriesData]);\n\n // 初始化图表\n useEffect(() => {\n if (!chartContainerRef.current) return;\n let chart = chartInstanceRef.current;\n if (!chart) {\n chart = echarts.init(chartContainerRef.current);\n chartInstanceRef.current = chart;\n }\n chart?.setOption(chartOptions, true);\n return () => {\n if (chartInstanceRef.current) {\n chartInstanceRef.current.dispose();\n chartInstanceRef.current = null;\n }\n };\n }, [chartOptions]);\n\n // 监听图表容器大小变化\n useEffect(() => {\n const chartElement = chartContainerRef.current;\n if (!chartElement) return;\n const resizeObserver = new ResizeObserver(() => {\n const chart = chartInstanceRef.current;\n if (chart) {\n chart.resize();\n }\n });\n resizeObserver.observe(chartElement);\n return () => {\n resizeObserver.unobserve(chartElement);\n resizeObserver.disconnect();\n };\n }, [seriesData]);\n\n return (\n <>\n {seriesData.length > 0 ? (\n <div\n ref={chartContainerRef}\n className={styles.echarts}\n style={{ width: '100%', height: height || '100%', minHeight: 220 }}\n ></div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\n// 使用 memo 包裹组件,避免不必要的重新渲染\n// 自定义比较函数,深度比较关键 props\nexport default memo(Line);\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,OAAO,eAAe;AAC/B,OAAO,aAAa;AACpB,YAAY,aAAa;AACzB,SAAS,eAAe;AACxB,OAAO,SAAkB,MAAM,WAAW,SAAS,cAAc;AACjE,OAAO,oBAAoB;AAC3B,SAAS,mBAAmB;AAC5B,OAAO,YAAY;AAEnB,SAAS,cAAc,aAAa,iBAAiB;AAiBrD,IAAM,cAAc;AAEpB,IAAM,OAAsB,CAAC;AAAA,EAC3B;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,IAAI,CAAC,GAAG,SAAS,SAAS,IAAI;AACtC,QAAM,oBAAoB,OAA8B,IAAI;AAC5D,QAAM,mBAAmB,OAA+B,IAAI;AAG5D,QAAM,gBAAgB,QAAQ,MAAM;AAClC,WAAO,OAAO,WAAW;AAAA,EAC3B,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,aAAa,QAAQ,MAAM;AAC/B,QAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,KAAK,CAAC,MAAM,MAAM,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,WAAW,CAAC,GAAG;AACzG,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,gBAAgB,SAAS,OAAO,CAAC,MAAM,MAAM,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,SAAS,CAAC;AAC/F,UAAM,mBAAmB,cAAc,IAAI,CAAC,MAAM,EAAE,GAAG;AAEvD,QAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACtC,aAAO,CAAC;AAAA,IACV;AAGA,UAAM,mBAAmB,SAAS,OAAO,CAAC,SAAS;AACjD,aAAO,cAAc,MAAM,CAAC,MAAM;AA9DxC;AA+DQ,cAAM,YAAY,QAAO,UAAK,EAAE,GAAG,MAAV,YAAe,EAAE;AAC1C,eAAO,EAAE,SAAS,SAAS,SAAS;AAAA,MACtC,CAAC;AAAA,IACH,CAAC;AAGD,UAAM,eAAe,oBAAI,IAAqB;AAG9C,UAAM,uBAAuB,oBAAI,IAQ/B;AAGF,UAAM,UAAU,CAAC,UAAkB,eAAoB;AACrD,UAAI,YAAY,SAAS,SAAS,GAAG;AACnC,YAAI,eAAe;AACjB,iBAAO,SAAS,IAAI,CAAC,MAAM,WAAW,CAAC,CAAC,EAAE,KAAK,GAAG;AAAA,QACpD;AACA,eAAO,CAAC,UAAU,GAAG,SAAS,IAAI,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG;AAAA,MACnE;AACA,aAAO;AAAA,IACT;AAEA,qBAAiB,QAAQ,CAAC,SAAS;AACjC,YAAM,gBAAgB,iBAAiB,IAAI,CAAC,QAAK;AA9FvD;AA8F0D,uBAAO,UAAK,GAAG,MAAR,YAAa,EAAE;AAAA,OAAC,EAAE,KAAK,GAAG;AAErF,aAAO,QAAQ,CAAC,QAAQ;AACtB,cAAM,MAAM,GAAG,KAAK,OAAO,KAAK,iBAAiB;AACjD,qBAAa,IAAI,KAAK,IAAI;AAE1B,cAAM,iBAAiB,GAAG,iBAAiB;AAC3C,YAAI,CAAC,qBAAqB,IAAI,cAAc,GAAG;AAE7C,gBAAM,aAAkB,EAAE,UAAU,IAAI;AACxC,2BAAiB,QAAQ,CAAC,SAAS;AACjC,uBAAW,IAAI,IAAI,KAAK,IAAI;AAAA,UAC9B,CAAC;AAED,gBAAM,OAAO,QAAQ,KAAK,UAAU;AACpC,+BAAqB,IAAI,gBAAgB;AAAA,YACvC;AAAA,YACA,UAAU;AAAA,YACV;AAAA,YACA;AAAA;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAGD,UAAM,SAAS,MAAM,KAAK,qBAAqB,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,eAAe,UAAU,KAAK,MAAM;AAElG,YAAM,OAAO,IAAI,MAAM,EAAE,MAAM;AAC/B,eAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,cAAM,OAAO,EAAE,CAAC;AAChB,cAAM,MAAM,GAAG,QAAQ,iBAAiB;AACxC,cAAM,WAAW,aAAa,IAAI,GAAG;AACrC,aAAK,CAAC,IAAI,qCAAW;AAAA,MACvB;AAEA,aAAO;AAAA,QACL;AAAA,QACA,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,WAAW;AAAA,UACT,OAAO;AAAA,QACT;AAAA,QACA,UAAU;AAAA,UACR,OAAO;AAAA,QACT;AAAA,QACA;AAAA,QACA,SAAS,KAAK,OAAO,CAAC,KAAK,QAAQ;AACjC,gBAAM,MAAM,OAAO,QAAQ,WAAW,MAAM;AAC5C,iBAAO,OAAO,OAAO,MAAM,GAAG,IAAI,IAAI;AAAA,QACxC,GAAG,CAAC;AAAA,MACN;AAAA,IACF,CAAC;AAGD,UAAM,eAAe,OAAO,KAAK,CAAC,GAAG,MAAM;AACzC,YAAM,OAAO,EAAE;AACf,YAAM,OAAO,EAAE;AACf,aAAO,OAAO;AAAA,IAChB,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,QAAQ,UAAU,GAAG,SAAS,UAAU,aAAa,CAAC;AAGpE,QAAM,iBAAiB,QAAQ,MAAM;AAjKvC;AAmKI,QAAI,CAAC,QAAQ,YAAY,KAAK,OAAO,SAAS,GAAG;AAC/C,YAAM,UAAS,kBAAa,OAAO,CAAC,CAAC,MAAtB,mBAAyB;AACxC,WAAI,iCAAQ,UAAS,YAAY;AAC/B,eAAO;AAAA,MACT;AACA,WAAI,iCAAQ,UAAS,WAAW;AAC9B,eAAO;AAAA,MACT;AACA,WAAI,iCAAQ,YAAW,GAAG;AACxB,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AACA,QAAI,OAAO,WAAW,GAAG;AACvB,cAAO,qBAAgB,OAAO,CAAC,CAAC,MAAzB,mBAA4B;AAAA,IACrC;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,iBAAiB,YAAY,CAAC;AAE1C,QAAM,OAAO;AAAA,IACX,KAAK;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,cAAc;AAAA,EAChB;AACA,QAAM,SAAS;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,WAAW;AAAA,IACX,WAAW;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA,WAAW;AAAA,MACT,OAAO;AAAA,MACP,MAAM;AAAA,IACR;AAAA,EACF;AACA,QAAM,QAAQ;AAAA,IACZ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,MACR,WAAW;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,WAAW;AAAA,MACT,OAAO;AAAA,MACP,UAAU;AAAA,IACZ;AAAA,IACA,UAAU;AAAA,MACR,gBAAgB;AAAA,IAClB;AAAA,IACA,aAAa;AAAA,EACf;AACA,QAAM,QAAQ;AAAA,IACZ,MAAM;AAAA,IACN,aAAa;AAAA;AAAA,IACb,UAAU;AAAA,MACR,MAAM;AAAA,MACN,WAAW;AAAA,QACT,OAAO;AAAA,QACP,eAAe;AAAA,QACf,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,WAAW;AAAA,MACT,OAAO;AAAA,MACP,UAAU;AAAA,MACV,SAAS,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,MACpB,WAAW,CAAC,UAAkB;AAC5B,YAAI,mBAAmB,WAAW;AAChC,iBAAO,IAAI,QAAQ,KAAK,EAAE,IAAI,GAAG,IAAI;AAAA,QACvC;AACA,YAAI,mBAAmB,WAAW;AAChC,iBAAO,YAAY,OAAO,cAAc;AAAA,QAC1C;AACA,cAAM,CAAC,QAAQ,IAAI,IAAI,aAAa,OAAO,IAAI;AAC/C,eAAO,SAAS;AAAA,MAClB;AAAA,IACF;AAAA,IACA,WAAW;AAAA,MACT,WAAW;AAAA,QACT,MAAM,CAAC,GAAG,CAAC;AAAA;AAAA,QACX,OAAO;AAAA;AAAA,MACT;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,IACR;AAAA,EACF;AACA,QAAM,mBAAmB,CAAC,WAAgB;AA9P5C;AA+PI,UAAM,SAAQ,kBAAO,CAAC,MAAR,mBAAW,cAAX,YAAwB;AACtC,UAAM,aACJ,oCAAC,SAAI,WAAW,OAAO,WACrB,oCAAC,SAAI,WAAW,OAAO,SACrB,oCAAC,cAAM,KAAM,GACb,oCAAC,UAAK,OAAO,EAAE,OAAO,SAAS,cAAc,GAAG,KAC7C,iBAAiB,OAAO,WAAW,IAAI,MAAM,OAAO,CAAC,IAAI,EAC5D,CACF,GACA,oCAAC,SAAI,WAAW,OAAO,WACpB,OAAO,IAAI,CAAC,MAAW;AAzQlC,UAAAA,KAAAC;AA0QY,YAAM,aAAa,iBAAiB,OAAO,WAAW,IAAI,OAAO,CAAC,IAAI,EAAE,WAAW,MAAM,GAAG,EAAE,CAAC;AAC/F,YAAM,eAAe,gBAAgB,UAAU;AAC/C,YAAM,UAASD,MAAA,6CAAc,WAAd,OAAAA,MAAwB;AACvC,UAAI,YAAY,WAAW,aAAa,aAAa,EAAE,OAAO,IAAI,IAAI,YAAY,EAAE,OAAO,MAAM;AAEjG,UAAI,CAAC,QAAQ,YAAY,KAAK,OAAO,SAAS,GAAG;AAC/C,cAAME,WAASD,MAAA,aAAa,UAAU,MAAvB,gBAAAA,IAA0B;AACzC,oBAAY,UAAU,EAAE,OAAOC,OAAM;AAAA,MACvC;AACA,YAAM,gBAAgB,cAAc,MAAM,UAAU,CAAC,MAAM,KAAK,MAAM;AACtE,aACE,oCAAC,SAAI,WAAW,OAAO,MAAM,KAAK,EAAE,cAClC,oCAAC,SAAI,WAAW,OAAO,OAAO,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,GAC9D,oCAAC,SAAI,WAAW,OAAO,YAAW,EAAE,UAAW,GAC/C,oCAAC,SAAI,WAAW,OAAO,SAAQ,aAAc,CAC/C;AAAA,IAEJ,CAAC,CACH,CACF;AAEF,WAAO,eAAe,qBAAqB,UAAU;AAAA,EACvD;AAEA,QAAM,UAAU;AAAA,IACd,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,MACX,MAAM;AAAA;AAAA,MACN,WAAW;AAAA,QACT,OAAO;AAAA;AAAA,QACP,MAAM;AAAA;AAAA,MACR;AAAA,IACF;AAAA,IACA,WAAW;AAAA,EACb;AAGA,QAAM,eAAe,QAAQ,MAAM;AACjC,QAAI,WAAW,SAAS,aAAa;AACnC,cAAQ,QAAQ,cAAc,iBAAiB;AAAA,IACjD;AACA,UAAM,SAAS;AAAA,MACb,OAAO;AAAA,MACP;AAAA,MACA,QAAQ,iCACH,SADG;AAAA,QAEN,WAAW;AAAA,QACX,WAAW;AAAA,UACT,SAAS;AAAA,QACX;AAAA,QACA,WAAW;AAAA,UACT,OAAO;AAAA,UACP,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA,QAAQ,WAAW,SAAS,cAAc,WAAW,MAAM,GAAG,WAAW,IAAI;AAAA,MAC7E;AAAA,IACF;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,CAAC;AAGf,YAAU,MAAM;AACd,QAAI,CAAC,kBAAkB;AAAS;AAChC,QAAI,QAAQ,iBAAiB;AAC7B,QAAI,CAAC,OAAO;AACV,cAAgB,aAAK,kBAAkB,OAAO;AAC9C,uBAAiB,UAAU;AAAA,IAC7B;AACA,mCAAO,UAAU,cAAc;AAC/B,WAAO,MAAM;AACX,UAAI,iBAAiB,SAAS;AAC5B,yBAAiB,QAAQ,QAAQ;AACjC,yBAAiB,UAAU;AAAA,MAC7B;AAAA,IACF;AAAA,EACF,GAAG,CAAC,YAAY,CAAC;AAGjB,YAAU,MAAM;AACd,UAAM,eAAe,kBAAkB;AACvC,QAAI,CAAC;AAAc;AACnB,UAAM,iBAAiB,IAAI,eAAe,MAAM;AAC9C,YAAM,QAAQ,iBAAiB;AAC/B,UAAI,OAAO;AACT,cAAM,OAAO;AAAA,MACf;AAAA,IACF,CAAC;AACD,mBAAe,QAAQ,YAAY;AACnC,WAAO,MAAM;AACX,qBAAe,UAAU,YAAY;AACrC,qBAAe,WAAW;AAAA,IAC5B;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,SACE,0DACG,WAAW,SAAS,IACnB;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAW,OAAO;AAAA,MAClB,OAAO,EAAE,OAAO,QAAQ,QAAQ,UAAU,QAAQ,WAAW,IAAI;AAAA;AAAA,EAClE,IAED,oCAAC,SAAM,WAAW,OAAO,OAAO,aAAY,QAAO,OAAO,MAAM,wBAAwB,CAE5F;AAEJ;AAIA,IAAO,eAAQ,KAAK,IAAI;",
6
6
  "names": ["_a", "_b", "format"]
7
7
  }
@@ -227,9 +227,13 @@ var Pies = ({
227
227
  combinationsList.forEach(({ groupByValues, category, name }) => {
228
228
  xValues.forEach((xVal) => {
229
229
  const { value, sample } = getSumAndSample(xVal, groupByValues, category);
230
+ const obj = {};
231
+ validGroupByKeys.forEach((k) => {
232
+ obj[k] = sample == null ? void 0 : sample[k];
233
+ });
230
234
  chartData.push(__spreadProps(__spreadValues({
231
235
  [x_field]: xVal
232
- }, validGroupByKeys.reduce((acc, k) => __spreadProps(__spreadValues({}, acc), { [k]: sample == null ? void 0 : sample[k] }), {})), {
236
+ }, obj), {
233
237
  x: xVal,
234
238
  name,
235
239
  metricName: category,
@@ -269,7 +273,7 @@ var Pies = ({
269
273
  type: "pie",
270
274
  radius: ["50%", "70%"],
271
275
  label: {
272
- show: pieData.length <= 1 ? false : true,
276
+ show: !(pieData.length <= 1),
273
277
  textStyle: {
274
278
  color: "#666"
275
279
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/business/YkCharts/Pies.tsx"],
4
- "sourcesContent": ["import { Empty, message } from 'antd';\nimport React, { type FC, memo, useMemo } from 'react';\nimport type { ColumnConfig, GroupByItem, SqlMetaConfig, TableData } from './typing';\nimport { formatValue } from './utils';\nimport 'swiper/css';\nimport 'swiper/css/navigation';\nimport 'swiper/css/pagination';\nimport { Navigation, Pagination } from 'swiper/modules';\nimport { Swiper, SwiperSlide } from 'swiper/react';\nimport styles from './index.module.less';\nimport Pie from './Pie';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\n// 限制 fullData 组合数量与单饼扇区数,防止维度和选项过多时卡死\nconst FULL_DATA_MAX_COMBINATIONS = 2000;\nconst MAX_SECTORS = 500;\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n reportType: number;\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n sqlFormatMap?: { [key: string]: SqlMetaConfig }; // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n cardSize?: string;\n height?: number;\n};\n\n// 处理饼图数据(用 Map 按 name 聚合,O(n) 避免大数据量时 O(n²) 卡顿)\nconst mergeData = (data: any[], metric: string, isDistribution?: boolean, maxSectors = MAX_SECTORS) => {\n const byName = new Map<\n string,\n { name: string; value: number; format: any; formattedValue?: string; metricName?: string }\n >();\n for (let i = 0; i < data.length; i++) {\n const item = data[i];\n // 分布分析时 sortedNames 为完整 name(如 \"(-∞, 1),IOS\"),需按 name 匹配;否则按 metricName 匹配\n if (isDistribution ? item.name !== metric : item.metricName !== metric) continue;\n const name = item.name.startsWith(item.metricName) ? item.name.slice(item.metricName.length + 1).trim() : item.name;\n const val = Number(item.value) || 0;\n const existing = byName.get(name);\n if (existing) {\n existing.value += val;\n } else {\n byName.set(name, {\n name,\n value: val,\n format: item.format,\n formattedValue: formatValue(val, item.format?.format),\n ...(isDistribution ? { metricName: item.name } : {}),\n });\n }\n }\n let result = Array.from(byName.values()).map((r) => ({\n ...r,\n formattedValue: formatValue(r.value, r.format?.format),\n }));\n result.sort((a, b) => b.value - a.value);\n if (result.length > maxSectors) {\n message.warning(`数据量过大,仅绘制前 ${maxSectors} 条数据`);\n result = result.slice(0, maxSectors);\n }\n return result;\n};\n\nconst Pies: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n cardSize = 'middle', // 卡片大小\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n sqlFormatMap, // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n reportType, // 分析模型\n height,\n}) => {\n const { x = [], table_head = [], table_body = [], x_field, group_by } = tableData;\n\n const useMetric = useMemo(() => {\n if (metric.length > 0) {\n return metric;\n } else {\n return tableData.metric;\n }\n }, [metric]);\n\n const fullData = useMemo(() => {\n if (!metric || metric.length === 0) {\n return [];\n }\n // 分布分析的日期选择合计时,需要特殊处理(name 用 '合计' 便于饼图显示;避免 mergeData 把 name 裁成空串)\n if (x.length === 0 && table_head.indexOf(x_field) === -1 && reportType === 4) {\n return metric.map((m) => ({\n x: '合计',\n name: m,\n metricName: m,\n format: columnConfigMap[m],\n value: baseData.reduce((sum, item) => sum + (Number(item[m]) || 0), 0),\n }));\n }\n // x_field 在 table_head 中的索引\n const index = table_head.indexOf(x_field);\n // 存在维度时的数据处理(参照 Bar:从 baseData 提取实际组合,不做笛卡尔积)\n if (group_by && group_by.length > 0) {\n if (\n Array.isArray(groupBys) &&\n groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0) &&\n reportType !== 4 // 分布分析时,维度为空代表选了总体\n ) {\n return [];\n }\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n const validGroupByKeys = validGroupBys.map((g) => g.key);\n const onlyOneMetric = metric.length === 1;\n if (!baseData || baseData.length === 0) {\n return [];\n }\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 分布分析且维度 selected 全为空:按「总体」合计,对每个 (x, category) 在 filteredBaseData 上求和\n const isDistributionTotal = reportType === 4 && validGroupBys.length === 0;\n if (isDistributionTotal) {\n const xValues = x.length > 0 ? x : [...new Set(filteredBaseData.map((item) => String(item[x_field] ?? '')))];\n const chartData: any[] = [];\n xValues.forEach((xVal) => {\n metric.forEach((cat) => {\n const value = filteredBaseData\n .filter((item) => String(item[x_field] ?? '') === xVal)\n .reduce((sum, item) => sum + (Number(item[cat]) || 0), 0);\n chartData.push({\n [x_field]: xVal,\n x: xVal,\n name: cat,\n metricName: cat,\n value,\n format: columnConfigMap[cat],\n });\n });\n });\n return chartData;\n }\n const dataIndexMap = new Map<string, RowItem>();\n const existingCombinations = new Map<string, { groupByValues: string; category: string; name: string }>();\n const getName = (category: string, groupByObj: Record<string, string | number>) => {\n if (onlyOneMetric) {\n return group_by.map((g) => groupByObj[g]).join(',');\n }\n return [category, ...group_by.map((g) => groupByObj[g]).filter(Boolean)].join(',');\n };\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n metric.forEach((cat) => {\n const key = `${item[x_field]}|${groupByValues}|${cat}`;\n dataIndexMap.set(key, item);\n const combinationKey = `${groupByValues}|${cat}`;\n if (!existingCombinations.has(combinationKey)) {\n const groupByObj: Record<string, string | number> = { category: cat };\n validGroupByKeys.forEach((gKey) => {\n groupByObj[gKey] = item[gKey];\n });\n const name = getName(cat, groupByObj);\n existingCombinations.set(combinationKey, { groupByValues, category: cat, name });\n }\n });\n });\n // x 为空时(如仅分组、无 x 轴)从数据中取 x_field 的唯一值,否则 dataIndexMap 的 key 对不上\n const xValues = x.length > 0 ? x : [...new Set(filteredBaseData.map((item) => String(item[x_field] ?? '')))];\n const combinationsList = Array.from(existingCombinations.values());\n // 按 (xVal, groupByValues) 聚合:未选中的维度会多行共用一个 groupByValues,需求和而非取单条\n const getSumForCombination = (xVal: string, groupByValues: string, category: string) =>\n filteredBaseData\n .filter(\n (item) =>\n String(item[x_field] ?? '') === xVal &&\n validGroupByKeys.map((k) => String(item[k] ?? '')).join('|') === groupByValues,\n )\n .reduce((sum, item) => sum + (Number(item[category]) || 0), 0);\n // 按该组合在所有 x 上的合计排序,只保留前 N 个,避免维度和选项过多时 fullData 爆炸\n if (combinationsList.length > FULL_DATA_MAX_COMBINATIONS) {\n const withSum = combinationsList.map(({ groupByValues, category, name }) => {\n let sum = 0;\n for (let i = 0; i < xValues.length; i++) {\n sum += getSumForCombination(xValues[i], groupByValues, category);\n }\n return { groupByValues, category, name, sum };\n });\n withSum.sort((a, b) => b.sum - a.sum);\n combinationsList.length = 0;\n for (let i = 0; i < FULL_DATA_MAX_COMBINATIONS && i < withSum.length; i++) {\n combinationsList.push({\n groupByValues: withSum[i].groupByValues,\n category: withSum[i].category,\n name: withSum[i].name,\n });\n }\n }\n const getSumAndSample = (xVal: string, groupByValues: string, category: string) => {\n const matches = filteredBaseData.filter(\n (item) =>\n String(item[x_field] ?? '') === xVal &&\n validGroupByKeys.map((k) => String(item[k] ?? '')).join('|') === groupByValues,\n );\n const value = matches.reduce((sum, item) => sum + (Number(item[category]) || 0), 0);\n const sample = matches[0];\n return { value, sample };\n };\n const chartData: any[] = [];\n combinationsList.forEach(({ groupByValues, category, name }) => {\n xValues.forEach((xVal) => {\n const { value, sample } = getSumAndSample(xVal, groupByValues, category);\n chartData.push({\n [x_field]: xVal,\n ...validGroupByKeys.reduce((acc, k) => ({ ...acc, [k]: sample?.[k] }), {}),\n x: xVal,\n name,\n metricName: category,\n value: Number(value) || 0,\n format: columnConfigMap[category],\n });\n });\n });\n return chartData;\n } else {\n const chartData: any[] = [];\n metric.forEach((m) => {\n x.forEach((item) => {\n const row = table_body.find((d) => d[index] === item);\n const obj: any = {\n x: item,\n name: m,\n metricName: m,\n format: columnConfigMap[m],\n };\n table_head.forEach((key, i) => {\n obj[key] = row ? row[i] : 0;\n });\n obj.value = obj[m];\n chartData.push(obj);\n });\n });\n return chartData;\n }\n }, [baseData, metric, groupBys, reportType]);\n\n // 获取series\n const series = useMemo(() => {\n return useMetric.map((m) => {\n const pieData = mergeData(fullData, m);\n return {\n name: m,\n type: 'pie',\n radius: ['50%', '70%'],\n label: {\n show: pieData.length <= 1 ? false : true,\n textStyle: {\n color: '#666',\n },\n },\n data: pieData,\n ...(sqlFormatMap &&\n sqlFormatMap?.[m]?.format && {\n format: sqlFormatMap?.[m]?.format,\n }),\n };\n });\n }, [fullData, metric, count, groupBys]);\n\n // 分布分析的饼图\n const distributionPie = useMemo(() => {\n // 日期选择合计:x 为空,fullData 为「合计」数据,直接用它建一张饼图\n const isTotalCase =\n x.length === 0 && fullData.length > 0 && fullData.every((d) => d.x === '合计') && reportType === 4;\n if (isTotalCase) {\n const data = fullData.map((d) => ({\n name: d.name,\n value: Number(d.value) || 0,\n format: d.format,\n formattedValue: formatValue(Number(d.value) || 0, (d as any).format?.format),\n }));\n return {\n name: '',\n type: 'pie',\n radius: ['50%', '70%'],\n label: { textStyle: { color: '#666' } },\n data,\n };\n }\n const firstPointX = x[0];\n if (firstPointX === undefined) return [];\n const firstPointData = fullData.filter((d) => d.x === firstPointX);\n const sortedData =\n reportType === 4 ? firstPointData : firstPointData.sort((a, b) => Number(b.value) - Number(a.value));\n // 直接从数据中提取名称\n const uniqueNames = [...new Set(sortedData.map((d) => d.name))];\n // 当分析模型为分布分析时,series的顺序直接按照metric的顺序\n const sortedNames = reportType === 4 ? uniqueNames : count ? uniqueNames.slice(0, count) : uniqueNames;\n const data = sortedNames.map((item) => {\n return {\n ...mergeData(fullData, item, true)[0],\n name: item,\n };\n });\n return {\n name: '',\n type: 'pie',\n radius: ['50%', '70%'],\n label: {\n textStyle: {\n color: '#666',\n },\n },\n data: data,\n };\n }, [useMetric, fullData, reportType, groupBys, x]);\n\n return (\n <>\n {fullData.length > 0 ? (\n <div className={styles.pieLegend} style={{ height: height || '100%', width: '100%' }}>\n {reportType === 4 ? (\n // 分布分析的饼图\n <Pie item={distributionPie} />\n ) : series && series.length > 1 ? (\n <Swiper\n modules={[Navigation, Pagination]}\n navigation\n slidesPerView={cardSize === 'large' ? 2 : 1}\n spaceBetween={10}\n slidesPerGroup={cardSize === 'large' ? 2 : 1}\n className={styles.pieSlider}\n style={{ height: '100%' }}\n >\n {series?.map((item) => (\n <SwiperSlide key={item.name} className={styles.pieSlideItem} tabIndex={-1}>\n <Pie item={item} />\n </SwiperSlide>\n ))}\n </Swiper>\n ) : (\n series?.map((item) => (\n <div key={item.name} style={{ height: height || '100%', width: '100%', minHeight: 220 }}>\n <Pie item={item} />\n </div>\n ))\n )}\n </div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\nexport default memo(Pies);\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Empty, message } from 'antd';\nimport React, { type FC, memo, useMemo } from 'react';\nimport type { ColumnConfig, GroupByItem, SqlMetaConfig, TableData } from './typing';\nimport { formatValue } from './utils';\nimport 'swiper/css';\nimport 'swiper/css/navigation';\nimport 'swiper/css/pagination';\nimport { Navigation, Pagination } from 'swiper/modules';\nimport { Swiper, SwiperSlide } from 'swiper/react';\nimport styles from './index.module.less';\nimport Pie from './Pie';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\n// 限制 fullData 组合数量与单饼扇区数,防止维度和选项过多时卡死\nconst FULL_DATA_MAX_COMBINATIONS = 2000;\nconst MAX_SECTORS = 500;\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n reportType: number;\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n sqlFormatMap?: { [key: string]: SqlMetaConfig }; // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n cardSize?: string;\n height?: number;\n};\n\n// 处理饼图数据(用 Map 按 name 聚合,O(n) 避免大数据量时 O(n²) 卡顿)\nconst mergeData = (data: any[], metric: string, isDistribution?: boolean, maxSectors = MAX_SECTORS) => {\n const byName = new Map<\n string,\n { name: string; value: number; format: any; formattedValue?: string; metricName?: string }\n >();\n for (let i = 0; i < data.length; i++) {\n const item = data[i];\n // 分布分析时 sortedNames 为完整 name(如 \"(-∞, 1),IOS\"),需按 name 匹配;否则按 metricName 匹配\n if (isDistribution ? item.name !== metric : item.metricName !== metric) continue;\n const name = item.name.startsWith(item.metricName) ? item.name.slice(item.metricName.length + 1).trim() : item.name;\n const val = Number(item.value) || 0;\n const existing = byName.get(name);\n if (existing) {\n existing.value += val;\n } else {\n byName.set(name, {\n name,\n value: val,\n format: item.format,\n formattedValue: formatValue(val, item.format?.format),\n ...(isDistribution ? { metricName: item.name } : {}),\n });\n }\n }\n let result = Array.from(byName.values()).map((r) => ({\n ...r,\n formattedValue: formatValue(r.value, r.format?.format),\n }));\n result.sort((a, b) => b.value - a.value);\n if (result.length > maxSectors) {\n message.warning(`数据量过大,仅绘制前 ${maxSectors} 条数据`);\n result = result.slice(0, maxSectors);\n }\n return result;\n};\n\nconst Pies: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n cardSize = 'middle', // 卡片大小\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n sqlFormatMap, // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n reportType, // 分析模型\n height,\n}) => {\n const { x = [], table_head = [], table_body = [], x_field, group_by } = tableData;\n\n const useMetric = useMemo(() => {\n if (metric.length > 0) {\n return metric;\n } else {\n return tableData.metric;\n }\n }, [metric]);\n\n const fullData = useMemo(() => {\n if (!metric || metric.length === 0) {\n return [];\n }\n // 分布分析的日期选择合计时,需要特殊处理(name 用 '合计' 便于饼图显示;避免 mergeData 把 name 裁成空串)\n if (x.length === 0 && table_head.indexOf(x_field) === -1 && reportType === 4) {\n return metric.map((m) => ({\n x: '合计',\n name: m,\n metricName: m,\n format: columnConfigMap[m],\n value: baseData.reduce((sum, item) => sum + (Number(item[m]) || 0), 0),\n }));\n }\n // x_field 在 table_head 中的索引\n const index = table_head.indexOf(x_field);\n // 存在维度时的数据处理(参照 Bar:从 baseData 提取实际组合,不做笛卡尔积)\n if (group_by && group_by.length > 0) {\n if (\n Array.isArray(groupBys) &&\n groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0) &&\n reportType !== 4 // 分布分析时,维度为空代表选了总体\n ) {\n return [];\n }\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n const validGroupByKeys = validGroupBys.map((g) => g.key);\n const onlyOneMetric = metric.length === 1;\n if (!baseData || baseData.length === 0) {\n return [];\n }\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 分布分析且维度 selected 全为空:按「总体」合计,对每个 (x, category) 在 filteredBaseData 上求和\n const isDistributionTotal = reportType === 4 && validGroupBys.length === 0;\n if (isDistributionTotal) {\n const xValues = x.length > 0 ? x : [...new Set(filteredBaseData.map((item) => String(item[x_field] ?? '')))];\n const chartData: any[] = [];\n xValues.forEach((xVal) => {\n metric.forEach((cat) => {\n const value = filteredBaseData\n .filter((item) => String(item[x_field] ?? '') === xVal)\n .reduce((sum, item) => sum + (Number(item[cat]) || 0), 0);\n chartData.push({\n [x_field]: xVal,\n x: xVal,\n name: cat,\n metricName: cat,\n value,\n format: columnConfigMap[cat],\n });\n });\n });\n return chartData;\n }\n const dataIndexMap = new Map<string, RowItem>();\n const existingCombinations = new Map<string, { groupByValues: string; category: string; name: string }>();\n const getName = (category: string, groupByObj: Record<string, string | number>) => {\n if (onlyOneMetric) {\n return group_by.map((g) => groupByObj[g]).join(',');\n }\n return [category, ...group_by.map((g) => groupByObj[g]).filter(Boolean)].join(',');\n };\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n metric.forEach((cat) => {\n const key = `${item[x_field]}|${groupByValues}|${cat}`;\n dataIndexMap.set(key, item);\n const combinationKey = `${groupByValues}|${cat}`;\n if (!existingCombinations.has(combinationKey)) {\n const groupByObj: Record<string, string | number> = { category: cat };\n validGroupByKeys.forEach((gKey) => {\n groupByObj[gKey] = item[gKey];\n });\n const name = getName(cat, groupByObj);\n existingCombinations.set(combinationKey, { groupByValues, category: cat, name });\n }\n });\n });\n // x 为空时(如仅分组、无 x 轴)从数据中取 x_field 的唯一值,否则 dataIndexMap 的 key 对不上\n const xValues = x.length > 0 ? x : [...new Set(filteredBaseData.map((item) => String(item[x_field] ?? '')))];\n const combinationsList = Array.from(existingCombinations.values());\n // 按 (xVal, groupByValues) 聚合:未选中的维度会多行共用一个 groupByValues,需求和而非取单条\n const getSumForCombination = (xVal: string, groupByValues: string, category: string) =>\n filteredBaseData\n .filter(\n (item) =>\n String(item[x_field] ?? '') === xVal &&\n validGroupByKeys.map((k) => String(item[k] ?? '')).join('|') === groupByValues,\n )\n .reduce((sum, item) => sum + (Number(item[category]) || 0), 0);\n // 按该组合在所有 x 上的合计排序,只保留前 N 个,避免维度和选项过多时 fullData 爆炸\n if (combinationsList.length > FULL_DATA_MAX_COMBINATIONS) {\n const withSum = combinationsList.map(({ groupByValues, category, name }) => {\n let sum = 0;\n for (let i = 0; i < xValues.length; i++) {\n sum += getSumForCombination(xValues[i], groupByValues, category);\n }\n return { groupByValues, category, name, sum };\n });\n withSum.sort((a, b) => b.sum - a.sum);\n combinationsList.length = 0;\n for (let i = 0; i < FULL_DATA_MAX_COMBINATIONS && i < withSum.length; i++) {\n combinationsList.push({\n groupByValues: withSum[i].groupByValues,\n category: withSum[i].category,\n name: withSum[i].name,\n });\n }\n }\n const getSumAndSample = (xVal: string, groupByValues: string, category: string) => {\n const matches = filteredBaseData.filter(\n (item) =>\n String(item[x_field] ?? '') === xVal &&\n validGroupByKeys.map((k) => String(item[k] ?? '')).join('|') === groupByValues,\n );\n const value = matches.reduce((sum, item) => sum + (Number(item[category]) || 0), 0);\n const sample = matches[0];\n return { value, sample };\n };\n const chartData: any[] = [];\n combinationsList.forEach(({ groupByValues, category, name }) => {\n xValues.forEach((xVal) => {\n const { value, sample } = getSumAndSample(xVal, groupByValues, category);\n const obj: Record<string, any> = {};\n validGroupByKeys.forEach((k) => {\n obj[k] = sample?.[k];\n });\n chartData.push({\n [x_field]: xVal,\n ...obj,\n x: xVal,\n name,\n metricName: category,\n value: Number(value) || 0,\n format: columnConfigMap[category],\n });\n });\n });\n return chartData;\n } else {\n const chartData: any[] = [];\n metric.forEach((m) => {\n x.forEach((item) => {\n const row = table_body.find((d) => d[index] === item);\n const obj: any = {\n x: item,\n name: m,\n metricName: m,\n format: columnConfigMap[m],\n };\n table_head.forEach((key, i) => {\n obj[key] = row ? row[i] : 0;\n });\n obj.value = obj[m];\n chartData.push(obj);\n });\n });\n return chartData;\n }\n }, [baseData, metric, groupBys, reportType]);\n\n // 获取series\n const series = useMemo(() => {\n return useMetric.map((m) => {\n const pieData = mergeData(fullData, m);\n return {\n name: m,\n type: 'pie',\n radius: ['50%', '70%'],\n label: {\n show: !(pieData.length <= 1),\n textStyle: {\n color: '#666',\n },\n },\n data: pieData,\n ...(sqlFormatMap &&\n sqlFormatMap?.[m]?.format && {\n format: sqlFormatMap?.[m]?.format,\n }),\n };\n });\n }, [fullData, metric, count, groupBys]);\n\n // 分布分析的饼图\n const distributionPie = useMemo(() => {\n // 日期选择合计:x 为空,fullData 为「合计」数据,直接用它建一张饼图\n const isTotalCase =\n x.length === 0 && fullData.length > 0 && fullData.every((d) => d.x === '合计') && reportType === 4;\n if (isTotalCase) {\n const data = fullData.map((d) => ({\n name: d.name,\n value: Number(d.value) || 0,\n format: d.format,\n formattedValue: formatValue(Number(d.value) || 0, (d as any).format?.format),\n }));\n return {\n name: '',\n type: 'pie',\n radius: ['50%', '70%'],\n label: { textStyle: { color: '#666' } },\n data,\n };\n }\n const firstPointX = x[0];\n if (firstPointX === undefined) return [];\n const firstPointData = fullData.filter((d) => d.x === firstPointX);\n const sortedData =\n reportType === 4 ? firstPointData : firstPointData.sort((a, b) => Number(b.value) - Number(a.value));\n // 直接从数据中提取名称\n const uniqueNames = [...new Set(sortedData.map((d) => d.name))];\n // 当分析模型为分布分析时,series的顺序直接按照metric的顺序\n const sortedNames = reportType === 4 ? uniqueNames : count ? uniqueNames.slice(0, count) : uniqueNames;\n const data = sortedNames.map((item) => {\n return {\n ...mergeData(fullData, item, true)[0],\n name: item,\n };\n });\n return {\n name: '',\n type: 'pie',\n radius: ['50%', '70%'],\n label: {\n textStyle: {\n color: '#666',\n },\n },\n data: data,\n };\n }, [useMetric, fullData, reportType, groupBys, x]);\n\n return (\n <>\n {fullData.length > 0 ? (\n <div className={styles.pieLegend} style={{ height: height || '100%', width: '100%' }}>\n {reportType === 4 ? (\n // 分布分析的饼图\n <Pie item={distributionPie} />\n ) : series && series.length > 1 ? (\n <Swiper\n modules={[Navigation, Pagination]}\n navigation\n slidesPerView={cardSize === 'large' ? 2 : 1}\n spaceBetween={10}\n slidesPerGroup={cardSize === 'large' ? 2 : 1}\n className={styles.pieSlider}\n style={{ height: '100%' }}\n >\n {series?.map((item) => (\n <SwiperSlide key={item.name} className={styles.pieSlideItem} tabIndex={-1}>\n <Pie item={item} />\n </SwiperSlide>\n ))}\n </Swiper>\n ) : (\n series?.map((item) => (\n <div key={item.name} style={{ height: height || '100%', width: '100%', minHeight: 220 }}>\n <Pie item={item} />\n </div>\n ))\n )}\n </div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\nexport default memo(Pies);\n"],
5
+ "mappings": "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",
6
6
  "names": ["_a", "xValues", "chartData", "data"]
7
7
  }
@@ -23,7 +23,7 @@ var formatValue = (value, format) => {
23
23
  };
24
24
  function formatNumber(num, isInteger = false) {
25
25
  const numberValue = typeof num === "string" ? parseFloat(num) : num;
26
- if (isNaN(numberValue)) {
26
+ if (Number.isNaN(numberValue)) {
27
27
  return [(num == null ? void 0 : num.toString()) || "", ""];
28
28
  }
29
29
  let result = "";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/business/YkCharts/utils.ts"],
4
- "sourcesContent": ["import Decimal from 'decimal.js';\nimport type { Format, SqlFormat } from './typing';\n\nexport const formatValue = (value: string | number, format: Format | undefined | null): string => {\n if (value === null || value === undefined || value === '-') {\n return '-';\n }\n if (!format || format === null) {\n return value.toString();\n }\n const numValue = Number(value);\n if (format === 'percent') {\n return new Decimal(numValue).mul(100).toFixed(2) + '%';\n }\n if (format === 'decimal') {\n return new Decimal(numValue).toFixed(2);\n }\n if (format === 'integer') {\n return new Intl.NumberFormat().format(numValue);\n }\n return numValue.toString();\n};\n\nexport function formatNumber(num: number | string, isInteger: boolean = false): [string, string] {\n const numberValue = typeof num === 'string' ? parseFloat(num) : num;\n if (isNaN(numberValue)) {\n return [num?.toString() || '', ''];\n }\n let result: string = '';\n let unit: string = '';\n function setFixed(v: number, dot: number) {\n const multiplier = 10 ** dot;\n return Math.floor(v * multiplier) / multiplier;\n }\n if (numberValue < 1000) {\n result = new Decimal(numberValue).toFixed(1);\n } else if (numberValue < 10000) {\n result = numberValue.toLocaleString('en-US', {\n minimumFractionDigits: isInteger ? 0 : 1,\n maximumFractionDigits: isInteger ? 0 : 1,\n });\n } else if (numberValue < 100000000) {\n const v = setFixed(numberValue / 10000, 2);\n result = v.toLocaleString('en-US', {\n minimumFractionDigits: isInteger ? 1 : 2,\n maximumFractionDigits: isInteger ? 1 : 2,\n });\n unit = ' 万';\n } else {\n const v = setFixed(numberValue / 100000000, 2);\n result = v.toLocaleString('en-US', {\n minimumFractionDigits: isInteger ? 1 : 2,\n maximumFractionDigits: isInteger ? 1 : 2,\n });\n unit = ' 亿';\n }\n if (isInteger) {\n result = result.replace(/\\.0+(?=\\D*$)/, '');\n }\n return [result, unit];\n}\n\nexport function sqlFormat(value: string | number | boolean, format: SqlFormat | undefined | null): string {\n if (value === null || value === undefined || value === '-') {\n return '-';\n }\n if (!format) {\n return value?.toString();\n }\n if (typeof value === 'boolean') {\n return value?.toString();\n }\n const { type, decimals = 0, thousand_separator = true, unit = 0, prefix = '', suffix = '' } = format;\n switch (type) {\n case 'number': {\n let result: string;\n if (thousand_separator) {\n result = value\n ? value?.toLocaleString('en-US', {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n })\n : '0';\n } else {\n result = new Decimal(value || 0).toFixed(decimals);\n }\n return `${prefix}${result}${suffix}`;\n }\n case 'percent': {\n const result = new Decimal(value || 0).mul(100).toFixed(decimals) + '%';\n return `${prefix}${result}${suffix}`;\n }\n case 'currency': {\n const numericValue = new Decimal(value || 0).div(10 ** unit).toNumber();\n const unitValue = numericValue.toLocaleString('en-US', {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n });\n const unitLabel = unit === 0 ? '' : unit === 4 ? '万' : unit === 8 ? '亿' : '';\n return `${prefix}${unitValue}${unitLabel}${suffix}`;\n }\n case 'normal':\n default:\n return value?.toString() || '-';\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import Decimal from 'decimal.js';\nimport type { Format, SqlFormat } from './typing';\n\nexport const formatValue = (value: string | number, format: Format | undefined | null): string => {\n if (value === null || value === undefined || value === '-') {\n return '-';\n }\n if (!format || format === null) {\n return value.toString();\n }\n const numValue = Number(value);\n if (format === 'percent') {\n return new Decimal(numValue).mul(100).toFixed(2) + '%';\n }\n if (format === 'decimal') {\n return new Decimal(numValue).toFixed(2);\n }\n if (format === 'integer') {\n return new Intl.NumberFormat().format(numValue);\n }\n return numValue.toString();\n};\n\nexport function formatNumber(num: number | string, isInteger: boolean = false): [string, string] {\n const numberValue = typeof num === 'string' ? parseFloat(num) : num;\n if (Number.isNaN(numberValue)) {\n return [num?.toString() || '', ''];\n }\n let result: string = '';\n let unit: string = '';\n function setFixed(v: number, dot: number) {\n const multiplier = 10 ** dot;\n return Math.floor(v * multiplier) / multiplier;\n }\n if (numberValue < 1000) {\n result = new Decimal(numberValue).toFixed(1);\n } else if (numberValue < 10000) {\n result = numberValue.toLocaleString('en-US', {\n minimumFractionDigits: isInteger ? 0 : 1,\n maximumFractionDigits: isInteger ? 0 : 1,\n });\n } else if (numberValue < 100000000) {\n const v = setFixed(numberValue / 10000, 2);\n result = v.toLocaleString('en-US', {\n minimumFractionDigits: isInteger ? 1 : 2,\n maximumFractionDigits: isInteger ? 1 : 2,\n });\n unit = ' 万';\n } else {\n const v = setFixed(numberValue / 100000000, 2);\n result = v.toLocaleString('en-US', {\n minimumFractionDigits: isInteger ? 1 : 2,\n maximumFractionDigits: isInteger ? 1 : 2,\n });\n unit = ' 亿';\n }\n if (isInteger) {\n result = result.replace(/\\.0+(?=\\D*$)/, '');\n }\n return [result, unit];\n}\n\nexport function sqlFormat(value: string | number | boolean, format: SqlFormat | undefined | null): string {\n if (value === null || value === undefined || value === '-') {\n return '-';\n }\n if (!format) {\n return value?.toString();\n }\n if (typeof value === 'boolean') {\n return value?.toString();\n }\n const { type, decimals = 0, thousand_separator = true, unit = 0, prefix = '', suffix = '' } = format;\n switch (type) {\n case 'number': {\n let result: string;\n if (thousand_separator) {\n result = value\n ? value?.toLocaleString('en-US', {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n })\n : '0';\n } else {\n result = new Decimal(value || 0).toFixed(decimals);\n }\n return `${prefix}${result}${suffix}`;\n }\n case 'percent': {\n const result = new Decimal(value || 0).mul(100).toFixed(decimals) + '%';\n return `${prefix}${result}${suffix}`;\n }\n case 'currency': {\n const numericValue = new Decimal(value || 0).div(10 ** unit).toNumber();\n const unitValue = numericValue.toLocaleString('en-US', {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n });\n const unitLabel = unit === 0 ? '' : unit === 4 ? '万' : unit === 8 ? '亿' : '';\n return `${prefix}${unitValue}${unitLabel}${suffix}`;\n }\n case 'normal':\n default:\n return value?.toString() || '-';\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -132,7 +132,7 @@ var Bar = ({
132
132
  data,
133
133
  dataSum: data.reduce((sum, val) => {
134
134
  const num = typeof val === "number" ? val : 0;
135
- return sum + (isNaN(num) ? 0 : num);
135
+ return sum + (Number.isNaN(num) ? 0 : num);
136
136
  }, 0)
137
137
  };
138
138
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/business/YkCharts/Bar.tsx"],
4
- "sourcesContent": ["import { Empty, message } from 'antd';\nimport classNames from 'classnames';\nimport Decimal from 'decimal.js';\nimport * as echarts from 'echarts';\nimport { isEmpty } from 'lodash';\nimport React, { type FC, memo, useEffect, useMemo, useRef } from 'react';\nimport ReactDOMServer from 'react-dom/server';\nimport { chartColors } from './constants';\nimport styles from './index.module.less';\nimport type { ColumnConfig, GroupByItem, SqlMetaConfig, TableData } from './typing';\nimport { formatNumber, formatValue, sqlFormat } from './utils';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n sqlFormatMap?: { [key: string]: SqlMetaConfig };\n height?: number;\n};\n\nconst MAX_SECTORS = 500;\n\nconst Bar: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n sqlFormatMap, // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n height,\n}) => {\n const { x = [], x_field, group_by } = tableData;\n const chartContainerRef = useRef<HTMLDivElement | null>(null);\n const chartInstanceRef = useRef<echarts.ECharts | null>(null);\n\n // 是否只有一个指标\n const onlyOneMetric = useMemo(() => {\n return metric.length === 1;\n }, [metric]);\n\n // 获取series数据\n const seriesData = useMemo(() => {\n if (Array.isArray(groupBys) && groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0)) {\n return [];\n }\n // 提前计算 validGroupBys 和 validGroupByKeys\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n const validGroupByKeys = validGroupBys.map((g) => g.key);\n // 如果没有 baseData,直接返回空数组\n if (!baseData || baseData.length === 0) {\n return [];\n }\n // 根据 groupBys 的 selected 过滤 baseData\n // 只保留符合所有 groupBy selected 条件的数据\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 建立 baseData 索引 Map,使用复合键 (x_field + validGroupByKeys + category) 作为 key\n // 格式: `${x_field}|${groupByKey1}|${groupByKey2}|...|${category}`\n const dataIndexMap = new Map<string, RowItem>();\n // 从 baseData 中提取实际存在的 groupBy 组合(而不是生成所有可能的组合)\n // 使用 Set 存储唯一的组合标识符,格式: `${groupByValue1}|${groupByValue2}|...|${metric}`\n const existingCombinations = new Map<\n string,\n {\n groupByValues: string;\n category: string;\n groupByObj: any;\n name: string;\n }\n >();\n\n // 预计算 name 的生成函数(提取到循环外,避免重复创建函数)\n const getName = (category: string, groupByObj: any) => {\n if (group_by && group_by.length > 0) {\n if (onlyOneMetric) {\n return group_by.map((g) => groupByObj[g]).join(',');\n }\n return [category, ...group_by.map((g) => groupByObj[g])].join(',');\n }\n return category;\n };\n\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n // 为每个 metric 建立索引和记录组合\n metric.forEach((cat) => {\n const key = `${item[x_field]}|${groupByValues}|${cat}`;\n dataIndexMap.set(key, item);\n // 记录实际存在的组合(每个 metric + groupBy 组合只记录一次)\n const combinationKey = `${groupByValues}|${cat}`;\n if (!existingCombinations.has(combinationKey)) {\n // 构建 groupBy 对象,用于后续生成 name\n const groupByObj: any = { category: cat };\n validGroupByKeys.forEach((gKey) => {\n groupByObj[gKey] = item[gKey];\n });\n // 预先计算 name,避免在 map 时重复计算\n const name = getName(cat, groupByObj);\n existingCombinations.set(combinationKey, {\n groupByValues,\n category: cat,\n groupByObj,\n name, // 预先计算好的 name\n });\n }\n });\n });\n\n // 直接从实际存在的组合生成 series,避免生成数百万个无效组合\n const result = Array.from(existingCombinations.values()).map(({ groupByValues, category, name }) => {\n // 预分配数组,避免动态扩容\n const data = new Array(x.length);\n for (let i = 0; i < x.length; i++) {\n const item = x[i];\n const key = `${item}|${groupByValues}|${category}`;\n const itemData = dataIndexMap.get(key);\n data[i] = itemData?.[category];\n }\n return {\n name,\n type: 'bar',\n barMaxWidth: 20,\n stack: (name as string).split(',')[0],\n smooth: true,\n showSymbol: false,\n data,\n dataSum: data.reduce((sum, val) => {\n const num = typeof val === 'number' ? val : 0;\n return sum + (isNaN(num) ? 0 : num);\n }, 0),\n };\n });\n\n // 按照 data 中数值合计从大到小排序\n const sortedResult = result.sort((a, b) => {\n const sumA = a.dataSum;\n const sumB = b.dataSum;\n return sumB - sumA; // 从大到小排序\n });\n return sortedResult;\n }, [baseData, metric, groupBys, x, x_field, group_by, onlyOneMetric]);\n\n // 获取y轴的格式化方式\n const yAxisFormatter = useMemo(() => {\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metric[0]]?.format;\n if (format?.type === 'currency') {\n return 'number';\n }\n if (format?.type === 'percent') {\n return 'percent';\n }\n if (format?.decimals > 0) {\n return 'decimal';\n }\n return 'number';\n }\n if (metric.length === 1) {\n return columnConfigMap[metric[0]]?.format;\n }\n return null;\n }, [metric, columnConfigMap, sqlFormatMap]);\n\n const grid = {\n top: 10,\n left: 0,\n right: 10,\n bottom: 40,\n containLabel: true,\n };\n const legend = {\n bottom: 0,\n type: 'scroll',\n };\n const xAxis = {\n type: 'category',\n data: x,\n axisLine: {\n lineStyle: {\n color: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#9CA4B3',\n fontSize: 12,\n },\n axisTick: {\n alignWithLabel: true,\n },\n boundaryGap: true,\n };\n const yAxis = {\n type: 'value',\n splitNumber: 4, // 设置Y轴坐标点数量\n axisLine: {\n show: true,\n lineStyle: {\n color: '#EBEEF4',\n shadowOffsetY: -10,\n shadowColor: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#999999',\n fontSize: 12,\n formatter: (value: number) => {\n if (yAxisFormatter === 'percent') {\n return new Decimal(value).mul(100) + '%';\n }\n if (yAxisFormatter === 'decimal') {\n return formatValue(value, yAxisFormatter);\n }\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n },\n },\n splitLine: {\n lineStyle: {\n type: [2, 3], // 虚线\n color: '#E7E7E7', // 背景线颜色\n },\n },\n axisTick: {\n show: true,\n },\n };\n const tooltipFormatter = (params: any) => {\n const title = params[0]?.axisValue ?? '';\n const tooltipDom = (\n <div className={styles.tooltip}>\n <div className={styles.title}>\n <span>{title}</span>\n <span style={{ float: 'right', paddingRight: 10 }}>\n {onlyOneMetric && metric.length === 1 ? ' ' + metric[0] : ''}\n </span>\n </div>\n <div className={styles.content}>\n {params.map((m: any) => {\n const metricName = onlyOneMetric && metric.length === 1 ? metric[0] : m.seriesName.split(',')[0];\n const columnConfig = columnConfigMap[metricName];\n const format = columnConfig?.format ?? 'string'; // 使用可选链和默认值\n let showValue = format === 'currency' ? formatNumber(m.value, true) : formatValue(m.value, format);\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metricName]?.format;\n showValue = sqlFormat(m.value, format);\n }\n const showValueText = showValue === '' || showValue[0] === '' ? '-' : showValue;\n return (\n <div className={styles.item} key={m.seriesName}>\n <div className={classNames(styles.point, styles.pointBar)} style={{ background: m.color }}></div>\n <div className={styles.category}>{m.seriesName}</div>\n <div className={styles.value}>{showValueText}</div>\n </div>\n );\n })}\n </div>\n </div>\n );\n return ReactDOMServer.renderToStaticMarkup(tooltipDom);\n };\n\n const tooltip = {\n trigger: 'axis',\n padding: 0,\n confine: true,\n enterable: true,\n axisPointer: {\n type: 'shadow',\n },\n formatter: tooltipFormatter,\n };\n\n // 图表配置\n const chartOptions = useMemo(() => {\n if (seriesData.length > MAX_SECTORS) {\n message.warning(`数据量过大,仅绘制前 ${MAX_SECTORS} 条数据`);\n }\n const result = {\n color: chartColors,\n grid,\n legend: {\n ...legend,\n itemWidth: 10,\n itemHeight: 10,\n },\n xAxis,\n yAxis,\n // 前端这里做个限制,防止数据量过大导致性能问题\n series: seriesData.length > MAX_SECTORS ? seriesData.slice(0, MAX_SECTORS) : seriesData,\n tooltip,\n barGap: '0%',\n };\n return result;\n }, [seriesData]);\n\n // 初始化图表\n useEffect(() => {\n if (!chartContainerRef.current) return;\n let chart = chartInstanceRef.current;\n if (!chart) {\n chart = echarts.init(chartContainerRef.current);\n chartInstanceRef.current = chart;\n }\n chart?.setOption(chartOptions, true);\n return () => {\n if (chartInstanceRef.current) {\n chartInstanceRef.current.dispose();\n chartInstanceRef.current = null;\n }\n };\n }, [chartOptions]);\n\n // 监听图表容器大小变化\n useEffect(() => {\n const chartElement = chartContainerRef.current;\n if (!chartElement) return;\n const resizeObserver = new ResizeObserver(() => {\n const chart = chartInstanceRef.current;\n if (chart) {\n chart.resize();\n }\n });\n resizeObserver.observe(chartElement);\n return () => {\n resizeObserver.unobserve(chartElement);\n resizeObserver.disconnect();\n };\n }, [seriesData]);\n\n return (\n <>\n {seriesData.length > 0 ? (\n <div\n ref={chartContainerRef}\n className={styles.echarts}\n style={{ width: '100%', height: height || '100%', minHeight: 220 }}\n ></div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\nexport default memo(Bar);\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Empty, message } from 'antd';\nimport classNames from 'classnames';\nimport Decimal from 'decimal.js';\nimport * as echarts from 'echarts';\nimport { isEmpty } from 'lodash';\nimport React, { type FC, memo, useEffect, useMemo, useRef } from 'react';\nimport ReactDOMServer from 'react-dom/server';\nimport { chartColors } from './constants';\nimport styles from './index.module.less';\nimport type { ColumnConfig, GroupByItem, SqlMetaConfig, TableData } from './typing';\nimport { formatNumber, formatValue, sqlFormat } from './utils';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n sqlFormatMap?: { [key: string]: SqlMetaConfig };\n height?: number;\n};\n\nconst MAX_SECTORS = 500;\n\nconst Bar: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n sqlFormatMap, // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n height,\n}) => {\n const { x = [], x_field, group_by } = tableData;\n const chartContainerRef = useRef<HTMLDivElement | null>(null);\n const chartInstanceRef = useRef<echarts.ECharts | null>(null);\n\n // 是否只有一个指标\n const onlyOneMetric = useMemo(() => {\n return metric.length === 1;\n }, [metric]);\n\n // 获取series数据\n const seriesData = useMemo(() => {\n if (Array.isArray(groupBys) && groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0)) {\n return [];\n }\n // 提前计算 validGroupBys 和 validGroupByKeys\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n const validGroupByKeys = validGroupBys.map((g) => g.key);\n // 如果没有 baseData,直接返回空数组\n if (!baseData || baseData.length === 0) {\n return [];\n }\n // 根据 groupBys 的 selected 过滤 baseData\n // 只保留符合所有 groupBy selected 条件的数据\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 建立 baseData 索引 Map,使用复合键 (x_field + validGroupByKeys + category) 作为 key\n // 格式: `${x_field}|${groupByKey1}|${groupByKey2}|...|${category}`\n const dataIndexMap = new Map<string, RowItem>();\n // 从 baseData 中提取实际存在的 groupBy 组合(而不是生成所有可能的组合)\n // 使用 Set 存储唯一的组合标识符,格式: `${groupByValue1}|${groupByValue2}|...|${metric}`\n const existingCombinations = new Map<\n string,\n {\n groupByValues: string;\n category: string;\n groupByObj: any;\n name: string;\n }\n >();\n\n // 预计算 name 的生成函数(提取到循环外,避免重复创建函数)\n const getName = (category: string, groupByObj: any) => {\n if (group_by && group_by.length > 0) {\n if (onlyOneMetric) {\n return group_by.map((g) => groupByObj[g]).join(',');\n }\n return [category, ...group_by.map((g) => groupByObj[g])].join(',');\n }\n return category;\n };\n\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n // 为每个 metric 建立索引和记录组合\n metric.forEach((cat) => {\n const key = `${item[x_field]}|${groupByValues}|${cat}`;\n dataIndexMap.set(key, item);\n // 记录实际存在的组合(每个 metric + groupBy 组合只记录一次)\n const combinationKey = `${groupByValues}|${cat}`;\n if (!existingCombinations.has(combinationKey)) {\n // 构建 groupBy 对象,用于后续生成 name\n const groupByObj: any = { category: cat };\n validGroupByKeys.forEach((gKey) => {\n groupByObj[gKey] = item[gKey];\n });\n // 预先计算 name,避免在 map 时重复计算\n const name = getName(cat, groupByObj);\n existingCombinations.set(combinationKey, {\n groupByValues,\n category: cat,\n groupByObj,\n name, // 预先计算好的 name\n });\n }\n });\n });\n\n // 直接从实际存在的组合生成 series,避免生成数百万个无效组合\n const result = Array.from(existingCombinations.values()).map(({ groupByValues, category, name }) => {\n // 预分配数组,避免动态扩容\n const data = new Array(x.length);\n for (let i = 0; i < x.length; i++) {\n const item = x[i];\n const key = `${item}|${groupByValues}|${category}`;\n const itemData = dataIndexMap.get(key);\n data[i] = itemData?.[category];\n }\n return {\n name,\n type: 'bar',\n barMaxWidth: 20,\n stack: (name as string).split(',')[0],\n smooth: true,\n showSymbol: false,\n data,\n dataSum: data.reduce((sum, val) => {\n const num = typeof val === 'number' ? val : 0;\n return sum + (Number.isNaN(num) ? 0 : num);\n }, 0),\n };\n });\n\n // 按照 data 中数值合计从大到小排序\n const sortedResult = result.sort((a, b) => {\n const sumA = a.dataSum;\n const sumB = b.dataSum;\n return sumB - sumA; // 从大到小排序\n });\n return sortedResult;\n }, [baseData, metric, groupBys, x, x_field, group_by, onlyOneMetric]);\n\n // 获取y轴的格式化方式\n const yAxisFormatter = useMemo(() => {\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metric[0]]?.format;\n if (format?.type === 'currency') {\n return 'number';\n }\n if (format?.type === 'percent') {\n return 'percent';\n }\n if (format?.decimals > 0) {\n return 'decimal';\n }\n return 'number';\n }\n if (metric.length === 1) {\n return columnConfigMap[metric[0]]?.format;\n }\n return null;\n }, [metric, columnConfigMap, sqlFormatMap]);\n\n const grid = {\n top: 10,\n left: 0,\n right: 10,\n bottom: 40,\n containLabel: true,\n };\n const legend = {\n bottom: 0,\n type: 'scroll',\n };\n const xAxis = {\n type: 'category',\n data: x,\n axisLine: {\n lineStyle: {\n color: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#9CA4B3',\n fontSize: 12,\n },\n axisTick: {\n alignWithLabel: true,\n },\n boundaryGap: true,\n };\n const yAxis = {\n type: 'value',\n splitNumber: 4, // 设置Y轴坐标点数量\n axisLine: {\n show: true,\n lineStyle: {\n color: '#EBEEF4',\n shadowOffsetY: -10,\n shadowColor: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#999999',\n fontSize: 12,\n formatter: (value: number) => {\n if (yAxisFormatter === 'percent') {\n return new Decimal(value).mul(100) + '%';\n }\n if (yAxisFormatter === 'decimal') {\n return formatValue(value, yAxisFormatter);\n }\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n },\n },\n splitLine: {\n lineStyle: {\n type: [2, 3], // 虚线\n color: '#E7E7E7', // 背景线颜色\n },\n },\n axisTick: {\n show: true,\n },\n };\n const tooltipFormatter = (params: any) => {\n const title = params[0]?.axisValue ?? '';\n const tooltipDom = (\n <div className={styles.tooltip}>\n <div className={styles.title}>\n <span>{title}</span>\n <span style={{ float: 'right', paddingRight: 10 }}>\n {onlyOneMetric && metric.length === 1 ? ' ' + metric[0] : ''}\n </span>\n </div>\n <div className={styles.content}>\n {params.map((m: any) => {\n const metricName = onlyOneMetric && metric.length === 1 ? metric[0] : m.seriesName.split(',')[0];\n const columnConfig = columnConfigMap[metricName];\n const format = columnConfig?.format ?? 'string'; // 使用可选链和默认值\n let showValue = format === 'currency' ? formatNumber(m.value, true) : formatValue(m.value, format);\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metricName]?.format;\n showValue = sqlFormat(m.value, format);\n }\n const showValueText = showValue === '' || showValue[0] === '' ? '-' : showValue;\n return (\n <div className={styles.item} key={m.seriesName}>\n <div className={classNames(styles.point, styles.pointBar)} style={{ background: m.color }}></div>\n <div className={styles.category}>{m.seriesName}</div>\n <div className={styles.value}>{showValueText}</div>\n </div>\n );\n })}\n </div>\n </div>\n );\n return ReactDOMServer.renderToStaticMarkup(tooltipDom);\n };\n\n const tooltip = {\n trigger: 'axis',\n padding: 0,\n confine: true,\n enterable: true,\n axisPointer: {\n type: 'shadow',\n },\n formatter: tooltipFormatter,\n };\n\n // 图表配置\n const chartOptions = useMemo(() => {\n if (seriesData.length > MAX_SECTORS) {\n message.warning(`数据量过大,仅绘制前 ${MAX_SECTORS} 条数据`);\n }\n const result = {\n color: chartColors,\n grid,\n legend: {\n ...legend,\n itemWidth: 10,\n itemHeight: 10,\n },\n xAxis,\n yAxis,\n // 前端这里做个限制,防止数据量过大导致性能问题\n series: seriesData.length > MAX_SECTORS ? seriesData.slice(0, MAX_SECTORS) : seriesData,\n tooltip,\n barGap: '0%',\n };\n return result;\n }, [seriesData]);\n\n // 初始化图表\n useEffect(() => {\n if (!chartContainerRef.current) return;\n let chart = chartInstanceRef.current;\n if (!chart) {\n chart = echarts.init(chartContainerRef.current);\n chartInstanceRef.current = chart;\n }\n chart?.setOption(chartOptions, true);\n return () => {\n if (chartInstanceRef.current) {\n chartInstanceRef.current.dispose();\n chartInstanceRef.current = null;\n }\n };\n }, [chartOptions]);\n\n // 监听图表容器大小变化\n useEffect(() => {\n const chartElement = chartContainerRef.current;\n if (!chartElement) return;\n const resizeObserver = new ResizeObserver(() => {\n const chart = chartInstanceRef.current;\n if (chart) {\n chart.resize();\n }\n });\n resizeObserver.observe(chartElement);\n return () => {\n resizeObserver.unobserve(chartElement);\n resizeObserver.disconnect();\n };\n }, [seriesData]);\n\n return (\n <>\n {seriesData.length > 0 ? (\n <div\n ref={chartContainerRef}\n className={styles.echarts}\n style={{ width: '100%', height: height || '100%', minHeight: 220 }}\n ></div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\nexport default memo(Bar);\n"],
5
+ "mappings": "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",
6
6
  "names": ["Decimal", "React", "styles", "_a", "format", "classNames", "ReactDOMServer"]
7
7
  }
@@ -90,7 +90,7 @@ var BarTotal = ({
90
90
  const sum = rows.reduce((s, r) => s + (Number(r[m]) || 0), 0);
91
91
  return sum;
92
92
  });
93
- const dataSum = data.reduce((s, v) => s + (isNaN(v) ? 0 : v), 0);
93
+ const dataSum = data.reduce((s, v) => s + (Number.isNaN(v) ? 0 : v), 0);
94
94
  return {
95
95
  name,
96
96
  type: "bar",
@@ -119,10 +119,13 @@ var BarTotal = ({
119
119
  }));
120
120
  }, [seriesData]);
121
121
  const chartData = (0, import_react.useMemo)(() => {
122
- return series.map((s) => ({
123
- name: s.name,
124
- ...metric.reduce((acc, m, i) => ({ ...acc, [m]: s.data[i] }), {})
125
- }));
122
+ return series.map((s) => {
123
+ const obj = {};
124
+ metric.forEach((m, i) => {
125
+ obj[m] = s.data[i];
126
+ });
127
+ return { name: s.name, ...obj };
128
+ });
126
129
  }, [series, metric]);
127
130
  const yAxisFormatter = (0, import_react.useMemo)(() => {
128
131
  var _a;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/business/YkCharts/BarTotal.tsx"],
4
- "sourcesContent": ["/**\n * 基础分析-合计且有维度时的柱状图\n */\n\nimport { Empty, message } from 'antd';\nimport classNames from 'classnames';\nimport Decimal from 'decimal.js';\nimport * as echarts from 'echarts';\nimport React, { type FC, useEffect, useMemo, useRef } from 'react';\nimport ReactDOMServer from 'react-dom/server';\nimport { chartColors } from './constants';\nimport styles from './index.module.less';\nimport type { ColumnConfig, GroupByItem, TableData } from './typing';\nimport { formatNumber, formatValue } from './utils';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n height?: number;\n};\n\nconst MAX_SECTORS = 500;\n\nconst BarTotal: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n height,\n}) => {\n const chartContainerRef = useRef<HTMLDivElement | null>(null);\n const chartInstanceRef = useRef<echarts.ECharts | null>(null);\n\n const validGroupByKeys = useMemo(() => {\n return groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0).map((g) => g.key);\n }, [groupBys]);\n\n // 参照 Bar:从 baseData 提取实际存在的维度组合,不做笛卡尔积\n const seriesData = useMemo(() => {\n if (Array.isArray(groupBys) && groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0)) {\n return [];\n }\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n if (!baseData || baseData.length === 0) {\n return [];\n }\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 按维度组合聚合行(同一组合可能多行,如多日期需汇总指标)\n const byGroupBy = new Map<string, { name: string; rows: RowItem[] }>();\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n const name = validGroupByKeys.map((key) => item[key]).join(',');\n if (!byGroupBy.has(groupByValues)) {\n byGroupBy.set(groupByValues, { name, rows: [] });\n }\n byGroupBy.get(groupByValues)!.rows.push(item);\n });\n const result = Array.from(byGroupBy.entries()).map(([, { name, rows }]) => {\n const data = metric.map((m) => {\n const sum = rows.reduce((s, r) => s + (Number(r[m]) || 0), 0);\n return sum;\n });\n const dataSum = data.reduce((s, v) => s + (isNaN(v) ? 0 : v), 0);\n return {\n name,\n type: 'bar' as const,\n barMaxWidth: 20,\n smooth: true,\n showSymbol: false,\n data,\n dataSum,\n };\n });\n result.sort((a, b) => b.dataSum - a.dataSum);\n return result;\n }, [baseData, metric, groupBys, validGroupByKeys]);\n\n const series = useMemo(() => {\n const list = seriesData.length > MAX_SECTORS ? seriesData.slice(0, MAX_SECTORS) : seriesData;\n if (seriesData.length > MAX_SECTORS) {\n message.warning(`数据量过大,仅绘制前 ${MAX_SECTORS} 条数据`);\n }\n return list.map(({ name, data, type, barMaxWidth, smooth, showSymbol }) => ({\n name,\n type,\n barMaxWidth,\n smooth,\n showSymbol,\n data,\n }));\n }, [seriesData]);\n\n // 供 tooltip 使用:由 series 反推 chartData 结构\n const chartData = useMemo(() => {\n return series.map((s) => ({\n name: s.name,\n ...metric.reduce((acc, m, i) => ({ ...acc, [m]: s.data[i] }), {} as Record<string, number>),\n }));\n }, [series, metric]);\n\n // 获取y轴的格式化方式\n const yAxisFormatter = useMemo(() => {\n if (metric.length === 1) {\n return columnConfigMap[metric[0]]?.format;\n }\n return null;\n }, [metric, columnConfigMap]);\n\n const grid = {\n top: 10,\n left: 0,\n right: 10,\n bottom: 40,\n containLabel: true,\n };\n const legend = {\n bottom: 0,\n type: 'scroll',\n };\n const xAxis = {\n type: 'category',\n data: metric,\n axisLine: {\n lineStyle: {\n color: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#9CA4B3',\n fontSize: 12,\n },\n axisTick: {\n alignWithLabel: true,\n },\n boundaryGap: true,\n };\n const yAxis = {\n type: 'value',\n splitNumber: 4, // 设置Y轴坐标点数量\n axisLine: {\n show: true,\n lineStyle: {\n color: '#EBEEF4',\n shadowOffsetY: -10,\n shadowColor: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#999999',\n fontSize: 12,\n formatter: (value: number) => {\n // 目前只有一个指标时, Y轴进行格式化\n if (yAxisFormatter) {\n if (yAxisFormatter === 'currency') {\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n }\n if (yAxisFormatter === 'percent') {\n return new Decimal(value).mul(100) + '%';\n }\n return formatValue(value, yAxisFormatter);\n }\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n },\n },\n splitLine: {\n lineStyle: {\n type: [2, 3], // 虚线\n color: '#E7E7E7', // 背景线颜色\n },\n },\n axisTick: {\n show: true,\n },\n };\n const tooltipFormatter = (params: any) => {\n const title = params[0]?.axisValue ?? '';\n const filterParams = params.filter((f: any) => {\n const { name, seriesName } = f;\n if (name === '合计') {\n return true;\n } else if (\n chartData.some((dataItem) => {\n return dataItem?.name === seriesName;\n })\n ) {\n return true;\n }\n return false;\n });\n\n const tooltipDom = (\n <div className={styles.tooltip}>\n <div className={styles.title}>{title}</div>\n <div className={styles.content}>\n {filterParams.map((m: any) => {\n const columnConfig = columnConfigMap[metric[0]];\n const format = columnConfig?.format ?? 'string'; // 使用可选链和默认值\n const showValue = format === 'currency' ? formatNumber(m.value, true) : formatValue(m.value, format);\n const showValueText = showValue === '' || showValue[0] === '' ? '-' : showValue;\n return (\n <div className={styles.item} key={m.seriesName}>\n <div className={classNames(styles.point, styles.pointBar)} style={{ background: m.color }}></div>\n <div className={styles.category}>{m.seriesName}</div>\n <div className={styles.value}>{showValueText}</div>\n </div>\n );\n })}\n </div>\n </div>\n );\n return ReactDOMServer.renderToStaticMarkup(tooltipDom);\n };\n const tooltip = {\n trigger: 'axis',\n padding: 0,\n confine: true,\n enterable: true,\n axisPointer: {\n type: 'shadow',\n },\n formatter: tooltipFormatter,\n };\n\n // 图表配置\n const chartOptions = useMemo(() => {\n return {\n color: chartColors,\n grid,\n legend: {\n ...legend,\n itemWidth: 10,\n itemHeight: 10,\n },\n xAxis,\n yAxis,\n series,\n tooltip,\n };\n }, [series]);\n\n // 仅卸载时销毁实例\n useEffect(() => {\n return () => {\n if (chartInstanceRef.current) {\n chartInstanceRef.current.dispose();\n chartInstanceRef.current = null;\n }\n };\n }, []);\n\n // 配置变化时仅 setOption\n useEffect(() => {\n const container = chartContainerRef.current;\n if (!container) return;\n let chart = chartInstanceRef.current;\n if (!chart) {\n chart = echarts.init(container);\n chartInstanceRef.current = chart;\n }\n chart.setOption(chartOptions, true);\n }, [chartOptions]);\n\n // 监听容器大小变化(仅挂载时注册)\n useEffect(() => {\n const chartElement = chartContainerRef.current;\n if (!chartElement) return;\n const resizeObserver = new ResizeObserver(() => {\n chartInstanceRef.current?.resize();\n });\n resizeObserver.observe(chartElement);\n return () => {\n resizeObserver.unobserve(chartElement);\n resizeObserver.disconnect();\n };\n }, []);\n\n return (\n <>\n {chartData.length > 0 ? (\n <div\n ref={chartContainerRef}\n className={styles.echarts}\n style={{ width: '100%', height: height || '100%', minHeight: 220 }}\n ></div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\nexport default BarTotal;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * 基础分析-合计且有维度时的柱状图\n */\n\nimport { Empty, message } from 'antd';\nimport classNames from 'classnames';\nimport Decimal from 'decimal.js';\nimport * as echarts from 'echarts';\nimport React, { type FC, useEffect, useMemo, useRef } from 'react';\nimport ReactDOMServer from 'react-dom/server';\nimport { chartColors } from './constants';\nimport styles from './index.module.less';\nimport type { ColumnConfig, GroupByItem, TableData } from './typing';\nimport { formatNumber, formatValue } from './utils';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n height?: number;\n};\n\nconst MAX_SECTORS = 500;\n\nconst BarTotal: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n height,\n}) => {\n const chartContainerRef = useRef<HTMLDivElement | null>(null);\n const chartInstanceRef = useRef<echarts.ECharts | null>(null);\n\n const validGroupByKeys = useMemo(() => {\n return groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0).map((g) => g.key);\n }, [groupBys]);\n\n // 参照 Bar:从 baseData 提取实际存在的维度组合,不做笛卡尔积\n const seriesData = useMemo(() => {\n if (Array.isArray(groupBys) && groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0)) {\n return [];\n }\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n if (!baseData || baseData.length === 0) {\n return [];\n }\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 按维度组合聚合行(同一组合可能多行,如多日期需汇总指标)\n const byGroupBy = new Map<string, { name: string; rows: RowItem[] }>();\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n const name = validGroupByKeys.map((key) => item[key]).join(',');\n if (!byGroupBy.has(groupByValues)) {\n byGroupBy.set(groupByValues, { name, rows: [] });\n }\n byGroupBy.get(groupByValues)!.rows.push(item);\n });\n const result = Array.from(byGroupBy.entries()).map(([, { name, rows }]) => {\n const data = metric.map((m) => {\n const sum = rows.reduce((s, r) => s + (Number(r[m]) || 0), 0);\n return sum;\n });\n const dataSum = data.reduce((s, v) => s + (Number.isNaN(v) ? 0 : v), 0);\n return {\n name,\n type: 'bar' as const,\n barMaxWidth: 20,\n smooth: true,\n showSymbol: false,\n data,\n dataSum,\n };\n });\n result.sort((a, b) => b.dataSum - a.dataSum);\n return result;\n }, [baseData, metric, groupBys, validGroupByKeys]);\n\n const series = useMemo(() => {\n const list = seriesData.length > MAX_SECTORS ? seriesData.slice(0, MAX_SECTORS) : seriesData;\n if (seriesData.length > MAX_SECTORS) {\n message.warning(`数据量过大,仅绘制前 ${MAX_SECTORS} 条数据`);\n }\n return list.map(({ name, data, type, barMaxWidth, smooth, showSymbol }) => ({\n name,\n type,\n barMaxWidth,\n smooth,\n showSymbol,\n data,\n }));\n }, [seriesData]);\n\n // 供 tooltip 使用:由 series 反推 chartData 结构\n const chartData = useMemo(() => {\n return series.map((s) => {\n const obj: Record<string, number> = {};\n metric.forEach((m, i) => {\n obj[m] = s.data[i];\n });\n return { name: s.name, ...obj };\n });\n }, [series, metric]);\n\n // 获取y轴的格式化方式\n const yAxisFormatter = useMemo(() => {\n if (metric.length === 1) {\n return columnConfigMap[metric[0]]?.format;\n }\n return null;\n }, [metric, columnConfigMap]);\n\n const grid = {\n top: 10,\n left: 0,\n right: 10,\n bottom: 40,\n containLabel: true,\n };\n const legend = {\n bottom: 0,\n type: 'scroll',\n };\n const xAxis = {\n type: 'category',\n data: metric,\n axisLine: {\n lineStyle: {\n color: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#9CA4B3',\n fontSize: 12,\n },\n axisTick: {\n alignWithLabel: true,\n },\n boundaryGap: true,\n };\n const yAxis = {\n type: 'value',\n splitNumber: 4, // 设置Y轴坐标点数量\n axisLine: {\n show: true,\n lineStyle: {\n color: '#EBEEF4',\n shadowOffsetY: -10,\n shadowColor: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#999999',\n fontSize: 12,\n formatter: (value: number) => {\n // 目前只有一个指标时, Y轴进行格式化\n if (yAxisFormatter) {\n if (yAxisFormatter === 'currency') {\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n }\n if (yAxisFormatter === 'percent') {\n return new Decimal(value).mul(100) + '%';\n }\n return formatValue(value, yAxisFormatter);\n }\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n },\n },\n splitLine: {\n lineStyle: {\n type: [2, 3], // 虚线\n color: '#E7E7E7', // 背景线颜色\n },\n },\n axisTick: {\n show: true,\n },\n };\n const tooltipFormatter = (params: any) => {\n const title = params[0]?.axisValue ?? '';\n const filterParams = params.filter((f: any) => {\n const { name, seriesName } = f;\n if (name === '合计') {\n return true;\n } else if (\n chartData.some((dataItem) => {\n return dataItem?.name === seriesName;\n })\n ) {\n return true;\n }\n return false;\n });\n\n const tooltipDom = (\n <div className={styles.tooltip}>\n <div className={styles.title}>{title}</div>\n <div className={styles.content}>\n {filterParams.map((m: any) => {\n const columnConfig = columnConfigMap[metric[0]];\n const format = columnConfig?.format ?? 'string'; // 使用可选链和默认值\n const showValue = format === 'currency' ? formatNumber(m.value, true) : formatValue(m.value, format);\n const showValueText = showValue === '' || showValue[0] === '' ? '-' : showValue;\n return (\n <div className={styles.item} key={m.seriesName}>\n <div className={classNames(styles.point, styles.pointBar)} style={{ background: m.color }}></div>\n <div className={styles.category}>{m.seriesName}</div>\n <div className={styles.value}>{showValueText}</div>\n </div>\n );\n })}\n </div>\n </div>\n );\n return ReactDOMServer.renderToStaticMarkup(tooltipDom);\n };\n const tooltip = {\n trigger: 'axis',\n padding: 0,\n confine: true,\n enterable: true,\n axisPointer: {\n type: 'shadow',\n },\n formatter: tooltipFormatter,\n };\n\n // 图表配置\n const chartOptions = useMemo(() => {\n return {\n color: chartColors,\n grid,\n legend: {\n ...legend,\n itemWidth: 10,\n itemHeight: 10,\n },\n xAxis,\n yAxis,\n series,\n tooltip,\n };\n }, [series]);\n\n // 仅卸载时销毁实例\n useEffect(() => {\n return () => {\n if (chartInstanceRef.current) {\n chartInstanceRef.current.dispose();\n chartInstanceRef.current = null;\n }\n };\n }, []);\n\n // 配置变化时仅 setOption\n useEffect(() => {\n const container = chartContainerRef.current;\n if (!container) return;\n let chart = chartInstanceRef.current;\n if (!chart) {\n chart = echarts.init(container);\n chartInstanceRef.current = chart;\n }\n chart.setOption(chartOptions, true);\n }, [chartOptions]);\n\n // 监听容器大小变化(仅挂载时注册)\n useEffect(() => {\n const chartElement = chartContainerRef.current;\n if (!chartElement) return;\n const resizeObserver = new ResizeObserver(() => {\n chartInstanceRef.current?.resize();\n });\n resizeObserver.observe(chartElement);\n return () => {\n resizeObserver.unobserve(chartElement);\n resizeObserver.disconnect();\n };\n }, []);\n\n return (\n <>\n {chartData.length > 0 ? (\n <div\n ref={chartContainerRef}\n className={styles.echarts}\n style={{ width: '100%', height: height || '100%', minHeight: 220 }}\n ></div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\nexport default BarTotal;\n"],
5
+ "mappings": "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",
6
6
  "names": ["result", "unit", "Decimal", "React", "styles", "classNames", "ReactDOMServer"]
7
7
  }
@@ -137,7 +137,7 @@ var Line = ({
137
137
  data,
138
138
  dataSum: data.reduce((sum, val) => {
139
139
  const num = typeof val === "number" ? val : 0;
140
- return sum + (isNaN(num) ? 0 : num);
140
+ return sum + (Number.isNaN(num) ? 0 : num);
141
141
  }, 0)
142
142
  };
143
143
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/business/YkCharts/Line.tsx"],
4
- "sourcesContent": ["import { Empty, message } from 'antd';\nimport Decimal from 'decimal.js';\nimport * as echarts from 'echarts';\nimport { isEmpty } from 'lodash';\nimport React, { type FC, memo, useEffect, useMemo, useRef } from 'react';\nimport ReactDOMServer from 'react-dom/server';\nimport { chartColors } from './constants';\nimport styles from './index.module.less';\nimport type { ColumnConfig, GroupByItem, SqlMetaConfig, TableData } from './typing';\nimport { formatNumber, formatValue, sqlFormat } from './utils';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n sqlFormatMap?: { [key: string]: SqlMetaConfig };\n height?: number;\n};\n\nconst MAX_SECTORS = 500;\n\nconst Line: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n sqlFormatMap, // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n height,\n}) => {\n const { x = [], x_field, group_by } = tableData;\n const chartContainerRef = useRef<HTMLDivElement | null>(null);\n const chartInstanceRef = useRef<echarts.ECharts | null>(null);\n\n // 是否只有一个指标\n const onlyOneMetric = useMemo(() => {\n return metric.length === 1;\n }, [metric]);\n\n // 获取series数据\n const seriesData = useMemo(() => {\n if (Array.isArray(groupBys) && groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0)) {\n return [];\n }\n // 提前计算 validGroupBys 和 validGroupByKeys\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n const validGroupByKeys = validGroupBys.map((g) => g.key);\n // 如果没有 baseData,直接返回空数组\n if (!baseData || baseData.length === 0) {\n return [];\n }\n // 根据 groupBys 的 selected 过滤 baseData\n // 只保留符合所有 groupBy selected 条件的数据\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 建立 baseData 索引 Map,使用复合键 (x_field + validGroupByKeys + category) 作为 key\n // 格式: `${x_field}|${groupByKey1}|${groupByKey2}|...|${category}`\n const dataIndexMap = new Map<string, RowItem>();\n // 从 baseData 中提取实际存在的 groupBy 组合(而不是生成所有可能的组合)\n // 使用 Set 存储唯一的组合标识符,格式: `${groupByValue1}|${groupByValue2}|...|${metric}`\n const existingCombinations = new Map<\n string,\n {\n groupByValues: string;\n category: string;\n groupByObj: any;\n name: string;\n }\n >();\n\n // 预计算 name 的生成函数(提取到循环外,避免重复创建函数)\n const getName = (category: string, groupByObj: any) => {\n if (group_by && group_by.length > 0) {\n if (onlyOneMetric) {\n return group_by.map((g) => groupByObj[g]).join(',');\n }\n return [category, ...group_by.map((g) => groupByObj[g])].join(',');\n }\n return category;\n };\n\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n // 为每个 metric 建立索引和记录组合\n metric.forEach((cat) => {\n const key = `${item[x_field]}|${groupByValues}|${cat}`;\n dataIndexMap.set(key, item);\n // 记录实际存在的组合(每个 metric + groupBy 组合只记录一次)\n const combinationKey = `${groupByValues}|${cat}`;\n if (!existingCombinations.has(combinationKey)) {\n // 构建 groupBy 对象,用于后续生成 name\n const groupByObj: any = { category: cat };\n validGroupByKeys.forEach((gKey) => {\n groupByObj[gKey] = item[gKey];\n });\n // 预先计算 name,避免在 map 时重复计算\n const name = getName(cat, groupByObj);\n existingCombinations.set(combinationKey, {\n groupByValues,\n category: cat,\n groupByObj,\n name, // 预先计算好的 name\n });\n }\n });\n });\n\n // 直接从实际存在的组合生成 series,避免生成数百万个无效组合\n const result = Array.from(existingCombinations.values()).map(({ groupByValues, category, name }) => {\n // 预分配数组,避免动态扩容\n const data = new Array(x.length);\n for (let i = 0; i < x.length; i++) {\n const item = x[i];\n const key = `${item}|${groupByValues}|${category}`;\n const itemData = dataIndexMap.get(key);\n data[i] = itemData?.[category];\n }\n\n return {\n name,\n type: 'line',\n smooth: true,\n showSymbol: true,\n symbol: 'emptyCircle',\n symbolSize: 0.8,\n lineStyle: {\n width: 1.5,\n },\n emphasis: {\n scale: 8,\n },\n data,\n dataSum: data.reduce((sum, val) => {\n const num = typeof val === 'number' ? val : 0;\n return sum + (isNaN(num) ? 0 : num);\n }, 0),\n };\n });\n\n // 按照 data 中数值合计从大到小排序\n const sortedResult = result.sort((a, b) => {\n const sumA = a.dataSum;\n const sumB = b.dataSum;\n return sumB - sumA; // 从大到小排序\n });\n return sortedResult;\n }, [baseData, metric, groupBys, x, x_field, group_by, onlyOneMetric]);\n\n // 获取y轴的格式化方式\n const yAxisFormatter = useMemo(() => {\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metric[0]]?.format;\n if (format?.type === 'currency') {\n return 'number';\n }\n if (format?.type === 'percent') {\n return 'percent';\n }\n if (format?.decimals > 0) {\n return 'decimal';\n }\n return 'number';\n }\n if (metric.length === 1) {\n return columnConfigMap[metric[0]]?.format;\n }\n return null;\n }, [metric, columnConfigMap, sqlFormatMap]);\n\n const grid = {\n top: 10,\n left: 5,\n right: 10,\n bottom: 40,\n containLabel: true,\n };\n const legend = {\n bottom: 0,\n type: 'scroll',\n itemWidth: 13,\n itemStyle: {\n opacity: 0,\n },\n lineStyle: {\n width: 2,\n type: 'solid',\n },\n };\n const xAxis = {\n type: 'category',\n data: x,\n axisLine: {\n lineStyle: {\n color: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#9CA4B3',\n fontSize: 12,\n },\n axisTick: {\n alignWithLabel: true,\n },\n boundaryGap: true,\n };\n const yAxis = {\n type: 'value',\n splitNumber: 4, // 设置Y轴坐标点数量\n axisLine: {\n show: true,\n lineStyle: {\n color: '#EBEEF4',\n shadowOffsetY: -10,\n shadowColor: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#999999',\n fontSize: 12,\n padding: [0, 0, 0, 5],\n formatter: (value: number) => {\n if (yAxisFormatter === 'percent') {\n return new Decimal(value).mul(100) + '%';\n }\n if (yAxisFormatter === 'decimal') {\n return formatValue(value, yAxisFormatter);\n }\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n },\n },\n splitLine: {\n lineStyle: {\n type: [2, 3], // 虚线\n color: '#E7E7E7', // 背景线颜色\n },\n },\n axisTick: {\n show: true,\n },\n };\n const tooltipFormatter = (params: any) => {\n const title = params[0]?.axisValue ?? '';\n const tooltipDom = (\n <div className={styles.tooltip}>\n <div className={styles.title}>\n <span>{title}</span>\n <span style={{ float: 'right', paddingRight: 10 }}>\n {onlyOneMetric && metric.length === 1 ? ' ' + metric[0] : ''}\n </span>\n </div>\n <div className={styles.content}>\n {params.map((m: any) => {\n const metricName = onlyOneMetric && metric.length === 1 ? metric[0] : m.seriesName.split(',')[0];\n const columnConfig = columnConfigMap[metricName];\n const format = columnConfig?.format ?? 'string'; // 使用可选链和默认值\n let showValue = format === 'currency' ? formatNumber(m.value, true) : formatValue(m.value, format);\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metricName]?.format;\n showValue = sqlFormat(m.value, format);\n }\n const showValueText = showValue === '' || showValue[0] === '' ? '-' : showValue;\n return (\n <div className={styles.item} key={m.seriesName}>\n <div className={styles.point} style={{ background: m.color }}></div>\n <div className={styles.category}>{m.seriesName}</div>\n <div className={styles.value}>{showValueText}</div>\n </div>\n );\n })}\n </div>\n </div>\n );\n return ReactDOMServer.renderToStaticMarkup(tooltipDom);\n };\n\n const tooltip = {\n trigger: 'axis',\n padding: 0,\n confine: true,\n enterable: true,\n axisPointer: {\n type: 'line', // 设置悬浮指针为线\n lineStyle: {\n color: '#EBEEF4', // 设置线的颜色\n type: 'dashed', // 设置虚线样式\n },\n },\n formatter: tooltipFormatter,\n };\n\n // 图表配置\n const chartOptions = useMemo(() => {\n if (seriesData.length > MAX_SECTORS) {\n message.warning(`数据量过大,仅绘制前 ${MAX_SECTORS} 条数据`);\n }\n const result = {\n color: chartColors,\n grid,\n legend: {\n ...legend,\n itemWidth: 13,\n itemStyle: {\n opacity: 0,\n },\n lineStyle: {\n width: 2,\n type: 'solid',\n },\n },\n xAxis,\n yAxis,\n // 前端这里做个限制,防止数据量过大导致性能问题\n series: seriesData.length > MAX_SECTORS ? seriesData.slice(0, MAX_SECTORS) : seriesData,\n tooltip,\n };\n\n return result;\n }, [seriesData]);\n\n // 初始化图表\n useEffect(() => {\n if (!chartContainerRef.current) return;\n let chart = chartInstanceRef.current;\n if (!chart) {\n chart = echarts.init(chartContainerRef.current);\n chartInstanceRef.current = chart;\n }\n chart?.setOption(chartOptions, true);\n return () => {\n if (chartInstanceRef.current) {\n chartInstanceRef.current.dispose();\n chartInstanceRef.current = null;\n }\n };\n }, [chartOptions]);\n\n // 监听图表容器大小变化\n useEffect(() => {\n const chartElement = chartContainerRef.current;\n if (!chartElement) return;\n const resizeObserver = new ResizeObserver(() => {\n const chart = chartInstanceRef.current;\n if (chart) {\n chart.resize();\n }\n });\n resizeObserver.observe(chartElement);\n return () => {\n resizeObserver.unobserve(chartElement);\n resizeObserver.disconnect();\n };\n }, [seriesData]);\n\n return (\n <>\n {seriesData.length > 0 ? (\n <div\n ref={chartContainerRef}\n className={styles.echarts}\n style={{ width: '100%', height: height || '100%', minHeight: 220 }}\n ></div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\n// 使用 memo 包裹组件,避免不必要的重新渲染\n// 自定义比较函数,深度比较关键 props\nexport default memo(Line);\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAA+B;AAC/B,qBAAoB;AACpB,cAAyB;AACzB,oBAAwB;AACxB,mBAAiE;AACjE,oBAA2B;AAC3B,uBAA4B;AAC5B,0BAAmB;AAEnB,mBAAqD;AAiBrD,IAAM,cAAc;AAEpB,IAAM,OAAsB,CAAC;AAAA,EAC3B;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,IAAI,CAAC,GAAG,SAAS,SAAS,IAAI;AACtC,QAAM,wBAAoB,qBAA8B,IAAI;AAC5D,QAAM,uBAAmB,qBAA+B,IAAI;AAG5D,QAAM,oBAAgB,sBAAQ,MAAM;AAClC,WAAO,OAAO,WAAW;AAAA,EAC3B,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,iBAAa,sBAAQ,MAAM;AAC/B,QAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,KAAK,CAAC,MAAM,MAAM,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,WAAW,CAAC,GAAG;AACzG,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,gBAAgB,SAAS,OAAO,CAAC,MAAM,MAAM,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,SAAS,CAAC;AAC/F,UAAM,mBAAmB,cAAc,IAAI,CAAC,MAAM,EAAE,GAAG;AAEvD,QAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACtC,aAAO,CAAC;AAAA,IACV;AAGA,UAAM,mBAAmB,SAAS,OAAO,CAAC,SAAS;AACjD,aAAO,cAAc,MAAM,CAAC,MAAM;AAChC,cAAM,YAAY,OAAO,KAAK,EAAE,GAAG,KAAK,EAAE;AAC1C,eAAO,EAAE,SAAS,SAAS,SAAS;AAAA,MACtC,CAAC;AAAA,IACH,CAAC;AAGD,UAAM,eAAe,oBAAI,IAAqB;AAG9C,UAAM,uBAAuB,oBAAI,IAQ/B;AAGF,UAAM,UAAU,CAAC,UAAkB,eAAoB;AACrD,UAAI,YAAY,SAAS,SAAS,GAAG;AACnC,YAAI,eAAe;AACjB,iBAAO,SAAS,IAAI,CAAC,MAAM,WAAW,CAAC,CAAC,EAAE,KAAK,GAAG;AAAA,QACpD;AACA,eAAO,CAAC,UAAU,GAAG,SAAS,IAAI,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG;AAAA,MACnE;AACA,aAAO;AAAA,IACT;AAEA,qBAAiB,QAAQ,CAAC,SAAS;AACjC,YAAM,gBAAgB,iBAAiB,IAAI,CAAC,QAAQ,OAAO,KAAK,GAAG,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG;AAErF,aAAO,QAAQ,CAAC,QAAQ;AACtB,cAAM,MAAM,GAAG,KAAK,OAAO,KAAK,iBAAiB;AACjD,qBAAa,IAAI,KAAK,IAAI;AAE1B,cAAM,iBAAiB,GAAG,iBAAiB;AAC3C,YAAI,CAAC,qBAAqB,IAAI,cAAc,GAAG;AAE7C,gBAAM,aAAkB,EAAE,UAAU,IAAI;AACxC,2BAAiB,QAAQ,CAAC,SAAS;AACjC,uBAAW,IAAI,IAAI,KAAK,IAAI;AAAA,UAC9B,CAAC;AAED,gBAAM,OAAO,QAAQ,KAAK,UAAU;AACpC,+BAAqB,IAAI,gBAAgB;AAAA,YACvC;AAAA,YACA,UAAU;AAAA,YACV;AAAA,YACA;AAAA;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAGD,UAAM,SAAS,MAAM,KAAK,qBAAqB,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,eAAe,UAAU,KAAK,MAAM;AAElG,YAAM,OAAO,IAAI,MAAM,EAAE,MAAM;AAC/B,eAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,cAAM,OAAO,EAAE,CAAC;AAChB,cAAM,MAAM,GAAG,QAAQ,iBAAiB;AACxC,cAAM,WAAW,aAAa,IAAI,GAAG;AACrC,aAAK,CAAC,IAAI,qCAAW;AAAA,MACvB;AAEA,aAAO;AAAA,QACL;AAAA,QACA,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,WAAW;AAAA,UACT,OAAO;AAAA,QACT;AAAA,QACA,UAAU;AAAA,UACR,OAAO;AAAA,QACT;AAAA,QACA;AAAA,QACA,SAAS,KAAK,OAAO,CAAC,KAAK,QAAQ;AACjC,gBAAM,MAAM,OAAO,QAAQ,WAAW,MAAM;AAC5C,iBAAO,OAAO,MAAM,GAAG,IAAI,IAAI;AAAA,QACjC,GAAG,CAAC;AAAA,MACN;AAAA,IACF,CAAC;AAGD,UAAM,eAAe,OAAO,KAAK,CAAC,GAAG,MAAM;AACzC,YAAM,OAAO,EAAE;AACf,YAAM,OAAO,EAAE;AACf,aAAO,OAAO;AAAA,IAChB,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,QAAQ,UAAU,GAAG,SAAS,UAAU,aAAa,CAAC;AAGpE,QAAM,qBAAiB,sBAAQ,MAAM;AAjKvC;AAmKI,QAAI,KAAC,uBAAQ,YAAY,KAAK,OAAO,SAAS,GAAG;AAC/C,YAAM,UAAS,kBAAa,OAAO,CAAC,CAAC,MAAtB,mBAAyB;AACxC,WAAI,iCAAQ,UAAS,YAAY;AAC/B,eAAO;AAAA,MACT;AACA,WAAI,iCAAQ,UAAS,WAAW;AAC9B,eAAO;AAAA,MACT;AACA,WAAI,iCAAQ,YAAW,GAAG;AACxB,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AACA,QAAI,OAAO,WAAW,GAAG;AACvB,cAAO,qBAAgB,OAAO,CAAC,CAAC,MAAzB,mBAA4B;AAAA,IACrC;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,iBAAiB,YAAY,CAAC;AAE1C,QAAM,OAAO;AAAA,IACX,KAAK;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,cAAc;AAAA,EAChB;AACA,QAAM,SAAS;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,WAAW;AAAA,IACX,WAAW;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA,WAAW;AAAA,MACT,OAAO;AAAA,MACP,MAAM;AAAA,IACR;AAAA,EACF;AACA,QAAM,QAAQ;AAAA,IACZ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,MACR,WAAW;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,WAAW;AAAA,MACT,OAAO;AAAA,MACP,UAAU;AAAA,IACZ;AAAA,IACA,UAAU;AAAA,MACR,gBAAgB;AAAA,IAClB;AAAA,IACA,aAAa;AAAA,EACf;AACA,QAAM,QAAQ;AAAA,IACZ,MAAM;AAAA,IACN,aAAa;AAAA;AAAA,IACb,UAAU;AAAA,MACR,MAAM;AAAA,MACN,WAAW;AAAA,QACT,OAAO;AAAA,QACP,eAAe;AAAA,QACf,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,WAAW;AAAA,MACT,OAAO;AAAA,MACP,UAAU;AAAA,MACV,SAAS,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,MACpB,WAAW,CAAC,UAAkB;AAC5B,YAAI,mBAAmB,WAAW;AAChC,iBAAO,IAAI,eAAAA,QAAQ,KAAK,EAAE,IAAI,GAAG,IAAI;AAAA,QACvC;AACA,YAAI,mBAAmB,WAAW;AAChC,qBAAO,0BAAY,OAAO,cAAc;AAAA,QAC1C;AACA,cAAM,CAAC,QAAQ,IAAI,QAAI,2BAAa,OAAO,IAAI;AAC/C,eAAO,SAAS;AAAA,MAClB;AAAA,IACF;AAAA,IACA,WAAW;AAAA,MACT,WAAW;AAAA,QACT,MAAM,CAAC,GAAG,CAAC;AAAA;AAAA,QACX,OAAO;AAAA;AAAA,MACT;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,IACR;AAAA,EACF;AACA,QAAM,mBAAmB,CAAC,WAAgB;AA9P5C;AA+PI,UAAM,UAAQ,YAAO,CAAC,MAAR,mBAAW,cAAa;AACtC,UAAM,aACJ,6BAAAC,QAAA,cAAC,SAAI,WAAW,oBAAAC,QAAO,WACrB,6BAAAD,QAAA,cAAC,SAAI,WAAW,oBAAAC,QAAO,SACrB,6BAAAD,QAAA,cAAC,cAAM,KAAM,GACb,6BAAAA,QAAA,cAAC,UAAK,OAAO,EAAE,OAAO,SAAS,cAAc,GAAG,KAC7C,iBAAiB,OAAO,WAAW,IAAI,MAAM,OAAO,CAAC,IAAI,EAC5D,CACF,GACA,6BAAAA,QAAA,cAAC,SAAI,WAAW,oBAAAC,QAAO,WACpB,OAAO,IAAI,CAAC,MAAW;AAzQlC,UAAAC;AA0QY,YAAM,aAAa,iBAAiB,OAAO,WAAW,IAAI,OAAO,CAAC,IAAI,EAAE,WAAW,MAAM,GAAG,EAAE,CAAC;AAC/F,YAAM,eAAe,gBAAgB,UAAU;AAC/C,YAAM,UAAS,6CAAc,WAAU;AACvC,UAAI,YAAY,WAAW,iBAAa,2BAAa,EAAE,OAAO,IAAI,QAAI,0BAAY,EAAE,OAAO,MAAM;AAEjG,UAAI,KAAC,uBAAQ,YAAY,KAAK,OAAO,SAAS,GAAG;AAC/C,cAAMC,WAASD,MAAA,aAAa,UAAU,MAAvB,gBAAAA,IAA0B;AACzC,wBAAY,wBAAU,EAAE,OAAOC,OAAM;AAAA,MACvC;AACA,YAAM,gBAAgB,cAAc,MAAM,UAAU,CAAC,MAAM,KAAK,MAAM;AACtE,aACE,6BAAAH,QAAA,cAAC,SAAI,WAAW,oBAAAC,QAAO,MAAM,KAAK,EAAE,cAClC,6BAAAD,QAAA,cAAC,SAAI,WAAW,oBAAAC,QAAO,OAAO,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,GAC9D,6BAAAD,QAAA,cAAC,SAAI,WAAW,oBAAAC,QAAO,YAAW,EAAE,UAAW,GAC/C,6BAAAD,QAAA,cAAC,SAAI,WAAW,oBAAAC,QAAO,SAAQ,aAAc,CAC/C;AAAA,IAEJ,CAAC,CACH,CACF;AAEF,WAAO,cAAAG,QAAe,qBAAqB,UAAU;AAAA,EACvD;AAEA,QAAM,UAAU;AAAA,IACd,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,MACX,MAAM;AAAA;AAAA,MACN,WAAW;AAAA,QACT,OAAO;AAAA;AAAA,QACP,MAAM;AAAA;AAAA,MACR;AAAA,IACF;AAAA,IACA,WAAW;AAAA,EACb;AAGA,QAAM,mBAAe,sBAAQ,MAAM;AACjC,QAAI,WAAW,SAAS,aAAa;AACnC,0BAAQ,QAAQ,cAAc,iBAAiB;AAAA,IACjD;AACA,UAAM,SAAS;AAAA,MACb,OAAO;AAAA,MACP;AAAA,MACA,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,WAAW;AAAA,QACX,WAAW;AAAA,UACT,SAAS;AAAA,QACX;AAAA,QACA,WAAW;AAAA,UACT,OAAO;AAAA,UACP,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA,QAAQ,WAAW,SAAS,cAAc,WAAW,MAAM,GAAG,WAAW,IAAI;AAAA,MAC7E;AAAA,IACF;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,CAAC;AAGf,8BAAU,MAAM;AACd,QAAI,CAAC,kBAAkB;AAAS;AAChC,QAAI,QAAQ,iBAAiB;AAC7B,QAAI,CAAC,OAAO;AACV,cAAgB,aAAK,kBAAkB,OAAO;AAC9C,uBAAiB,UAAU;AAAA,IAC7B;AACA,mCAAO,UAAU,cAAc;AAC/B,WAAO,MAAM;AACX,UAAI,iBAAiB,SAAS;AAC5B,yBAAiB,QAAQ,QAAQ;AACjC,yBAAiB,UAAU;AAAA,MAC7B;AAAA,IACF;AAAA,EACF,GAAG,CAAC,YAAY,CAAC;AAGjB,8BAAU,MAAM;AACd,UAAM,eAAe,kBAAkB;AACvC,QAAI,CAAC;AAAc;AACnB,UAAM,iBAAiB,IAAI,eAAe,MAAM;AAC9C,YAAM,QAAQ,iBAAiB;AAC/B,UAAI,OAAO;AACT,cAAM,OAAO;AAAA,MACf;AAAA,IACF,CAAC;AACD,mBAAe,QAAQ,YAAY;AACnC,WAAO,MAAM;AACX,qBAAe,UAAU,YAAY;AACrC,qBAAe,WAAW;AAAA,IAC5B;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,SACE,6BAAAJ,QAAA,2BAAAA,QAAA,gBACG,WAAW,SAAS,IACnB,6BAAAA,QAAA;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAW,oBAAAC,QAAO;AAAA,MAClB,OAAO,EAAE,OAAO,QAAQ,QAAQ,UAAU,QAAQ,WAAW,IAAI;AAAA;AAAA,EAClE,IAED,6BAAAD,QAAA,cAAC,qBAAM,WAAW,oBAAAC,QAAO,OAAO,aAAY,QAAO,OAAO,kBAAM,wBAAwB,CAE5F;AAEJ;AAIA,IAAO,mBAAQ,mBAAK,IAAI;",
4
+ "sourcesContent": ["import { Empty, message } from 'antd';\nimport Decimal from 'decimal.js';\nimport * as echarts from 'echarts';\nimport { isEmpty } from 'lodash';\nimport React, { type FC, memo, useEffect, useMemo, useRef } from 'react';\nimport ReactDOMServer from 'react-dom/server';\nimport { chartColors } from './constants';\nimport styles from './index.module.less';\nimport type { ColumnConfig, GroupByItem, SqlMetaConfig, TableData } from './typing';\nimport { formatNumber, formatValue, sqlFormat } from './utils';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n sqlFormatMap?: { [key: string]: SqlMetaConfig };\n height?: number;\n};\n\nconst MAX_SECTORS = 500;\n\nconst Line: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n sqlFormatMap, // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n height,\n}) => {\n const { x = [], x_field, group_by } = tableData;\n const chartContainerRef = useRef<HTMLDivElement | null>(null);\n const chartInstanceRef = useRef<echarts.ECharts | null>(null);\n\n // 是否只有一个指标\n const onlyOneMetric = useMemo(() => {\n return metric.length === 1;\n }, [metric]);\n\n // 获取series数据\n const seriesData = useMemo(() => {\n if (Array.isArray(groupBys) && groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0)) {\n return [];\n }\n // 提前计算 validGroupBys 和 validGroupByKeys\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n const validGroupByKeys = validGroupBys.map((g) => g.key);\n // 如果没有 baseData,直接返回空数组\n if (!baseData || baseData.length === 0) {\n return [];\n }\n // 根据 groupBys 的 selected 过滤 baseData\n // 只保留符合所有 groupBy selected 条件的数据\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 建立 baseData 索引 Map,使用复合键 (x_field + validGroupByKeys + category) 作为 key\n // 格式: `${x_field}|${groupByKey1}|${groupByKey2}|...|${category}`\n const dataIndexMap = new Map<string, RowItem>();\n // 从 baseData 中提取实际存在的 groupBy 组合(而不是生成所有可能的组合)\n // 使用 Set 存储唯一的组合标识符,格式: `${groupByValue1}|${groupByValue2}|...|${metric}`\n const existingCombinations = new Map<\n string,\n {\n groupByValues: string;\n category: string;\n groupByObj: any;\n name: string;\n }\n >();\n\n // 预计算 name 的生成函数(提取到循环外,避免重复创建函数)\n const getName = (category: string, groupByObj: any) => {\n if (group_by && group_by.length > 0) {\n if (onlyOneMetric) {\n return group_by.map((g) => groupByObj[g]).join(',');\n }\n return [category, ...group_by.map((g) => groupByObj[g])].join(',');\n }\n return category;\n };\n\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n // 为每个 metric 建立索引和记录组合\n metric.forEach((cat) => {\n const key = `${item[x_field]}|${groupByValues}|${cat}`;\n dataIndexMap.set(key, item);\n // 记录实际存在的组合(每个 metric + groupBy 组合只记录一次)\n const combinationKey = `${groupByValues}|${cat}`;\n if (!existingCombinations.has(combinationKey)) {\n // 构建 groupBy 对象,用于后续生成 name\n const groupByObj: any = { category: cat };\n validGroupByKeys.forEach((gKey) => {\n groupByObj[gKey] = item[gKey];\n });\n // 预先计算 name,避免在 map 时重复计算\n const name = getName(cat, groupByObj);\n existingCombinations.set(combinationKey, {\n groupByValues,\n category: cat,\n groupByObj,\n name, // 预先计算好的 name\n });\n }\n });\n });\n\n // 直接从实际存在的组合生成 series,避免生成数百万个无效组合\n const result = Array.from(existingCombinations.values()).map(({ groupByValues, category, name }) => {\n // 预分配数组,避免动态扩容\n const data = new Array(x.length);\n for (let i = 0; i < x.length; i++) {\n const item = x[i];\n const key = `${item}|${groupByValues}|${category}`;\n const itemData = dataIndexMap.get(key);\n data[i] = itemData?.[category];\n }\n\n return {\n name,\n type: 'line',\n smooth: true,\n showSymbol: true,\n symbol: 'emptyCircle',\n symbolSize: 0.8,\n lineStyle: {\n width: 1.5,\n },\n emphasis: {\n scale: 8,\n },\n data,\n dataSum: data.reduce((sum, val) => {\n const num = typeof val === 'number' ? val : 0;\n return sum + (Number.isNaN(num) ? 0 : num);\n }, 0),\n };\n });\n\n // 按照 data 中数值合计从大到小排序\n const sortedResult = result.sort((a, b) => {\n const sumA = a.dataSum;\n const sumB = b.dataSum;\n return sumB - sumA; // 从大到小排序\n });\n return sortedResult;\n }, [baseData, metric, groupBys, x, x_field, group_by, onlyOneMetric]);\n\n // 获取y轴的格式化方式\n const yAxisFormatter = useMemo(() => {\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metric[0]]?.format;\n if (format?.type === 'currency') {\n return 'number';\n }\n if (format?.type === 'percent') {\n return 'percent';\n }\n if (format?.decimals > 0) {\n return 'decimal';\n }\n return 'number';\n }\n if (metric.length === 1) {\n return columnConfigMap[metric[0]]?.format;\n }\n return null;\n }, [metric, columnConfigMap, sqlFormatMap]);\n\n const grid = {\n top: 10,\n left: 5,\n right: 10,\n bottom: 40,\n containLabel: true,\n };\n const legend = {\n bottom: 0,\n type: 'scroll',\n itemWidth: 13,\n itemStyle: {\n opacity: 0,\n },\n lineStyle: {\n width: 2,\n type: 'solid',\n },\n };\n const xAxis = {\n type: 'category',\n data: x,\n axisLine: {\n lineStyle: {\n color: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#9CA4B3',\n fontSize: 12,\n },\n axisTick: {\n alignWithLabel: true,\n },\n boundaryGap: true,\n };\n const yAxis = {\n type: 'value',\n splitNumber: 4, // 设置Y轴坐标点数量\n axisLine: {\n show: true,\n lineStyle: {\n color: '#EBEEF4',\n shadowOffsetY: -10,\n shadowColor: '#EBEEF4',\n },\n },\n axisLabel: {\n color: '#999999',\n fontSize: 12,\n padding: [0, 0, 0, 5],\n formatter: (value: number) => {\n if (yAxisFormatter === 'percent') {\n return new Decimal(value).mul(100) + '%';\n }\n if (yAxisFormatter === 'decimal') {\n return formatValue(value, yAxisFormatter);\n }\n const [result, unit] = formatNumber(value, true);\n return result + unit;\n },\n },\n splitLine: {\n lineStyle: {\n type: [2, 3], // 虚线\n color: '#E7E7E7', // 背景线颜色\n },\n },\n axisTick: {\n show: true,\n },\n };\n const tooltipFormatter = (params: any) => {\n const title = params[0]?.axisValue ?? '';\n const tooltipDom = (\n <div className={styles.tooltip}>\n <div className={styles.title}>\n <span>{title}</span>\n <span style={{ float: 'right', paddingRight: 10 }}>\n {onlyOneMetric && metric.length === 1 ? ' ' + metric[0] : ''}\n </span>\n </div>\n <div className={styles.content}>\n {params.map((m: any) => {\n const metricName = onlyOneMetric && metric.length === 1 ? metric[0] : m.seriesName.split(',')[0];\n const columnConfig = columnConfigMap[metricName];\n const format = columnConfig?.format ?? 'string'; // 使用可选链和默认值\n let showValue = format === 'currency' ? formatNumber(m.value, true) : formatValue(m.value, format);\n // SQL可视化中的特殊格式化处理\n if (!isEmpty(sqlFormatMap) && metric.length > 0) {\n const format = sqlFormatMap[metricName]?.format;\n showValue = sqlFormat(m.value, format);\n }\n const showValueText = showValue === '' || showValue[0] === '' ? '-' : showValue;\n return (\n <div className={styles.item} key={m.seriesName}>\n <div className={styles.point} style={{ background: m.color }}></div>\n <div className={styles.category}>{m.seriesName}</div>\n <div className={styles.value}>{showValueText}</div>\n </div>\n );\n })}\n </div>\n </div>\n );\n return ReactDOMServer.renderToStaticMarkup(tooltipDom);\n };\n\n const tooltip = {\n trigger: 'axis',\n padding: 0,\n confine: true,\n enterable: true,\n axisPointer: {\n type: 'line', // 设置悬浮指针为线\n lineStyle: {\n color: '#EBEEF4', // 设置线的颜色\n type: 'dashed', // 设置虚线样式\n },\n },\n formatter: tooltipFormatter,\n };\n\n // 图表配置\n const chartOptions = useMemo(() => {\n if (seriesData.length > MAX_SECTORS) {\n message.warning(`数据量过大,仅绘制前 ${MAX_SECTORS} 条数据`);\n }\n const result = {\n color: chartColors,\n grid,\n legend: {\n ...legend,\n itemWidth: 13,\n itemStyle: {\n opacity: 0,\n },\n lineStyle: {\n width: 2,\n type: 'solid',\n },\n },\n xAxis,\n yAxis,\n // 前端这里做个限制,防止数据量过大导致性能问题\n series: seriesData.length > MAX_SECTORS ? seriesData.slice(0, MAX_SECTORS) : seriesData,\n tooltip,\n };\n\n return result;\n }, [seriesData]);\n\n // 初始化图表\n useEffect(() => {\n if (!chartContainerRef.current) return;\n let chart = chartInstanceRef.current;\n if (!chart) {\n chart = echarts.init(chartContainerRef.current);\n chartInstanceRef.current = chart;\n }\n chart?.setOption(chartOptions, true);\n return () => {\n if (chartInstanceRef.current) {\n chartInstanceRef.current.dispose();\n chartInstanceRef.current = null;\n }\n };\n }, [chartOptions]);\n\n // 监听图表容器大小变化\n useEffect(() => {\n const chartElement = chartContainerRef.current;\n if (!chartElement) return;\n const resizeObserver = new ResizeObserver(() => {\n const chart = chartInstanceRef.current;\n if (chart) {\n chart.resize();\n }\n });\n resizeObserver.observe(chartElement);\n return () => {\n resizeObserver.unobserve(chartElement);\n resizeObserver.disconnect();\n };\n }, [seriesData]);\n\n return (\n <>\n {seriesData.length > 0 ? (\n <div\n ref={chartContainerRef}\n className={styles.echarts}\n style={{ width: '100%', height: height || '100%', minHeight: 220 }}\n ></div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\n// 使用 memo 包裹组件,避免不必要的重新渲染\n// 自定义比较函数,深度比较关键 props\nexport default memo(Line);\n"],
5
+ "mappings": "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",
6
6
  "names": ["Decimal", "React", "styles", "_a", "format", "ReactDOMServer"]
7
7
  }
@@ -217,9 +217,13 @@ var Pies = ({
217
217
  combinationsList.forEach(({ groupByValues, category, name }) => {
218
218
  xValues.forEach((xVal) => {
219
219
  const { value, sample } = getSumAndSample(xVal, groupByValues, category);
220
+ const obj = {};
221
+ validGroupByKeys.forEach((k) => {
222
+ obj[k] = sample == null ? void 0 : sample[k];
223
+ });
220
224
  chartData.push({
221
225
  [x_field]: xVal,
222
- ...validGroupByKeys.reduce((acc, k) => ({ ...acc, [k]: sample == null ? void 0 : sample[k] }), {}),
226
+ ...obj,
223
227
  x: xVal,
224
228
  name,
225
229
  metricName: category,
@@ -259,7 +263,7 @@ var Pies = ({
259
263
  type: "pie",
260
264
  radius: ["50%", "70%"],
261
265
  label: {
262
- show: pieData.length <= 1 ? false : true,
266
+ show: !(pieData.length <= 1),
263
267
  textStyle: {
264
268
  color: "#666"
265
269
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/business/YkCharts/Pies.tsx"],
4
- "sourcesContent": ["import { Empty, message } from 'antd';\nimport React, { type FC, memo, useMemo } from 'react';\nimport type { ColumnConfig, GroupByItem, SqlMetaConfig, TableData } from './typing';\nimport { formatValue } from './utils';\nimport 'swiper/css';\nimport 'swiper/css/navigation';\nimport 'swiper/css/pagination';\nimport { Navigation, Pagination } from 'swiper/modules';\nimport { Swiper, SwiperSlide } from 'swiper/react';\nimport styles from './index.module.less';\nimport Pie from './Pie';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\n// 限制 fullData 组合数量与单饼扇区数,防止维度和选项过多时卡死\nconst FULL_DATA_MAX_COMBINATIONS = 2000;\nconst MAX_SECTORS = 500;\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n reportType: number;\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n sqlFormatMap?: { [key: string]: SqlMetaConfig }; // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n cardSize?: string;\n height?: number;\n};\n\n// 处理饼图数据(用 Map 按 name 聚合,O(n) 避免大数据量时 O(n²) 卡顿)\nconst mergeData = (data: any[], metric: string, isDistribution?: boolean, maxSectors = MAX_SECTORS) => {\n const byName = new Map<\n string,\n { name: string; value: number; format: any; formattedValue?: string; metricName?: string }\n >();\n for (let i = 0; i < data.length; i++) {\n const item = data[i];\n // 分布分析时 sortedNames 为完整 name(如 \"(-∞, 1),IOS\"),需按 name 匹配;否则按 metricName 匹配\n if (isDistribution ? item.name !== metric : item.metricName !== metric) continue;\n const name = item.name.startsWith(item.metricName) ? item.name.slice(item.metricName.length + 1).trim() : item.name;\n const val = Number(item.value) || 0;\n const existing = byName.get(name);\n if (existing) {\n existing.value += val;\n } else {\n byName.set(name, {\n name,\n value: val,\n format: item.format,\n formattedValue: formatValue(val, item.format?.format),\n ...(isDistribution ? { metricName: item.name } : {}),\n });\n }\n }\n let result = Array.from(byName.values()).map((r) => ({\n ...r,\n formattedValue: formatValue(r.value, r.format?.format),\n }));\n result.sort((a, b) => b.value - a.value);\n if (result.length > maxSectors) {\n message.warning(`数据量过大,仅绘制前 ${maxSectors} 条数据`);\n result = result.slice(0, maxSectors);\n }\n return result;\n};\n\nconst Pies: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n cardSize = 'middle', // 卡片大小\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n sqlFormatMap, // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n reportType, // 分析模型\n height,\n}) => {\n const { x = [], table_head = [], table_body = [], x_field, group_by } = tableData;\n\n const useMetric = useMemo(() => {\n if (metric.length > 0) {\n return metric;\n } else {\n return tableData.metric;\n }\n }, [metric]);\n\n const fullData = useMemo(() => {\n if (!metric || metric.length === 0) {\n return [];\n }\n // 分布分析的日期选择合计时,需要特殊处理(name 用 '合计' 便于饼图显示;避免 mergeData 把 name 裁成空串)\n if (x.length === 0 && table_head.indexOf(x_field) === -1 && reportType === 4) {\n return metric.map((m) => ({\n x: '合计',\n name: m,\n metricName: m,\n format: columnConfigMap[m],\n value: baseData.reduce((sum, item) => sum + (Number(item[m]) || 0), 0),\n }));\n }\n // x_field 在 table_head 中的索引\n const index = table_head.indexOf(x_field);\n // 存在维度时的数据处理(参照 Bar:从 baseData 提取实际组合,不做笛卡尔积)\n if (group_by && group_by.length > 0) {\n if (\n Array.isArray(groupBys) &&\n groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0) &&\n reportType !== 4 // 分布分析时,维度为空代表选了总体\n ) {\n return [];\n }\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n const validGroupByKeys = validGroupBys.map((g) => g.key);\n const onlyOneMetric = metric.length === 1;\n if (!baseData || baseData.length === 0) {\n return [];\n }\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 分布分析且维度 selected 全为空:按「总体」合计,对每个 (x, category) 在 filteredBaseData 上求和\n const isDistributionTotal = reportType === 4 && validGroupBys.length === 0;\n if (isDistributionTotal) {\n const xValues = x.length > 0 ? x : [...new Set(filteredBaseData.map((item) => String(item[x_field] ?? '')))];\n const chartData: any[] = [];\n xValues.forEach((xVal) => {\n metric.forEach((cat) => {\n const value = filteredBaseData\n .filter((item) => String(item[x_field] ?? '') === xVal)\n .reduce((sum, item) => sum + (Number(item[cat]) || 0), 0);\n chartData.push({\n [x_field]: xVal,\n x: xVal,\n name: cat,\n metricName: cat,\n value,\n format: columnConfigMap[cat],\n });\n });\n });\n return chartData;\n }\n const dataIndexMap = new Map<string, RowItem>();\n const existingCombinations = new Map<string, { groupByValues: string; category: string; name: string }>();\n const getName = (category: string, groupByObj: Record<string, string | number>) => {\n if (onlyOneMetric) {\n return group_by.map((g) => groupByObj[g]).join(',');\n }\n return [category, ...group_by.map((g) => groupByObj[g]).filter(Boolean)].join(',');\n };\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n metric.forEach((cat) => {\n const key = `${item[x_field]}|${groupByValues}|${cat}`;\n dataIndexMap.set(key, item);\n const combinationKey = `${groupByValues}|${cat}`;\n if (!existingCombinations.has(combinationKey)) {\n const groupByObj: Record<string, string | number> = { category: cat };\n validGroupByKeys.forEach((gKey) => {\n groupByObj[gKey] = item[gKey];\n });\n const name = getName(cat, groupByObj);\n existingCombinations.set(combinationKey, { groupByValues, category: cat, name });\n }\n });\n });\n // x 为空时(如仅分组、无 x 轴)从数据中取 x_field 的唯一值,否则 dataIndexMap 的 key 对不上\n const xValues = x.length > 0 ? x : [...new Set(filteredBaseData.map((item) => String(item[x_field] ?? '')))];\n const combinationsList = Array.from(existingCombinations.values());\n // 按 (xVal, groupByValues) 聚合:未选中的维度会多行共用一个 groupByValues,需求和而非取单条\n const getSumForCombination = (xVal: string, groupByValues: string, category: string) =>\n filteredBaseData\n .filter(\n (item) =>\n String(item[x_field] ?? '') === xVal &&\n validGroupByKeys.map((k) => String(item[k] ?? '')).join('|') === groupByValues,\n )\n .reduce((sum, item) => sum + (Number(item[category]) || 0), 0);\n // 按该组合在所有 x 上的合计排序,只保留前 N 个,避免维度和选项过多时 fullData 爆炸\n if (combinationsList.length > FULL_DATA_MAX_COMBINATIONS) {\n const withSum = combinationsList.map(({ groupByValues, category, name }) => {\n let sum = 0;\n for (let i = 0; i < xValues.length; i++) {\n sum += getSumForCombination(xValues[i], groupByValues, category);\n }\n return { groupByValues, category, name, sum };\n });\n withSum.sort((a, b) => b.sum - a.sum);\n combinationsList.length = 0;\n for (let i = 0; i < FULL_DATA_MAX_COMBINATIONS && i < withSum.length; i++) {\n combinationsList.push({\n groupByValues: withSum[i].groupByValues,\n category: withSum[i].category,\n name: withSum[i].name,\n });\n }\n }\n const getSumAndSample = (xVal: string, groupByValues: string, category: string) => {\n const matches = filteredBaseData.filter(\n (item) =>\n String(item[x_field] ?? '') === xVal &&\n validGroupByKeys.map((k) => String(item[k] ?? '')).join('|') === groupByValues,\n );\n const value = matches.reduce((sum, item) => sum + (Number(item[category]) || 0), 0);\n const sample = matches[0];\n return { value, sample };\n };\n const chartData: any[] = [];\n combinationsList.forEach(({ groupByValues, category, name }) => {\n xValues.forEach((xVal) => {\n const { value, sample } = getSumAndSample(xVal, groupByValues, category);\n chartData.push({\n [x_field]: xVal,\n ...validGroupByKeys.reduce((acc, k) => ({ ...acc, [k]: sample?.[k] }), {}),\n x: xVal,\n name,\n metricName: category,\n value: Number(value) || 0,\n format: columnConfigMap[category],\n });\n });\n });\n return chartData;\n } else {\n const chartData: any[] = [];\n metric.forEach((m) => {\n x.forEach((item) => {\n const row = table_body.find((d) => d[index] === item);\n const obj: any = {\n x: item,\n name: m,\n metricName: m,\n format: columnConfigMap[m],\n };\n table_head.forEach((key, i) => {\n obj[key] = row ? row[i] : 0;\n });\n obj.value = obj[m];\n chartData.push(obj);\n });\n });\n return chartData;\n }\n }, [baseData, metric, groupBys, reportType]);\n\n // 获取series\n const series = useMemo(() => {\n return useMetric.map((m) => {\n const pieData = mergeData(fullData, m);\n return {\n name: m,\n type: 'pie',\n radius: ['50%', '70%'],\n label: {\n show: pieData.length <= 1 ? false : true,\n textStyle: {\n color: '#666',\n },\n },\n data: pieData,\n ...(sqlFormatMap &&\n sqlFormatMap?.[m]?.format && {\n format: sqlFormatMap?.[m]?.format,\n }),\n };\n });\n }, [fullData, metric, count, groupBys]);\n\n // 分布分析的饼图\n const distributionPie = useMemo(() => {\n // 日期选择合计:x 为空,fullData 为「合计」数据,直接用它建一张饼图\n const isTotalCase =\n x.length === 0 && fullData.length > 0 && fullData.every((d) => d.x === '合计') && reportType === 4;\n if (isTotalCase) {\n const data = fullData.map((d) => ({\n name: d.name,\n value: Number(d.value) || 0,\n format: d.format,\n formattedValue: formatValue(Number(d.value) || 0, (d as any).format?.format),\n }));\n return {\n name: '',\n type: 'pie',\n radius: ['50%', '70%'],\n label: { textStyle: { color: '#666' } },\n data,\n };\n }\n const firstPointX = x[0];\n if (firstPointX === undefined) return [];\n const firstPointData = fullData.filter((d) => d.x === firstPointX);\n const sortedData =\n reportType === 4 ? firstPointData : firstPointData.sort((a, b) => Number(b.value) - Number(a.value));\n // 直接从数据中提取名称\n const uniqueNames = [...new Set(sortedData.map((d) => d.name))];\n // 当分析模型为分布分析时,series的顺序直接按照metric的顺序\n const sortedNames = reportType === 4 ? uniqueNames : count ? uniqueNames.slice(0, count) : uniqueNames;\n const data = sortedNames.map((item) => {\n return {\n ...mergeData(fullData, item, true)[0],\n name: item,\n };\n });\n return {\n name: '',\n type: 'pie',\n radius: ['50%', '70%'],\n label: {\n textStyle: {\n color: '#666',\n },\n },\n data: data,\n };\n }, [useMetric, fullData, reportType, groupBys, x]);\n\n return (\n <>\n {fullData.length > 0 ? (\n <div className={styles.pieLegend} style={{ height: height || '100%', width: '100%' }}>\n {reportType === 4 ? (\n // 分布分析的饼图\n <Pie item={distributionPie} />\n ) : series && series.length > 1 ? (\n <Swiper\n modules={[Navigation, Pagination]}\n navigation\n slidesPerView={cardSize === 'large' ? 2 : 1}\n spaceBetween={10}\n slidesPerGroup={cardSize === 'large' ? 2 : 1}\n className={styles.pieSlider}\n style={{ height: '100%' }}\n >\n {series?.map((item) => (\n <SwiperSlide key={item.name} className={styles.pieSlideItem} tabIndex={-1}>\n <Pie item={item} />\n </SwiperSlide>\n ))}\n </Swiper>\n ) : (\n series?.map((item) => (\n <div key={item.name} style={{ height: height || '100%', width: '100%', minHeight: 220 }}>\n <Pie item={item} />\n </div>\n ))\n )}\n </div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\nexport default memo(Pies);\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Empty, message } from 'antd';\nimport React, { type FC, memo, useMemo } from 'react';\nimport type { ColumnConfig, GroupByItem, SqlMetaConfig, TableData } from './typing';\nimport { formatValue } from './utils';\nimport 'swiper/css';\nimport 'swiper/css/navigation';\nimport 'swiper/css/pagination';\nimport { Navigation, Pagination } from 'swiper/modules';\nimport { Swiper, SwiperSlide } from 'swiper/react';\nimport styles from './index.module.less';\nimport Pie from './Pie';\n\ntype RowItem = {\n [key: string]: number | string;\n};\n\n// 限制 fullData 组合数量与单饼扇区数,防止维度和选项过多时卡死\nconst FULL_DATA_MAX_COMBINATIONS = 2000;\nconst MAX_SECTORS = 500;\n\ntype PageTypes = {\n count?: number;\n metric: string[];\n groupBys: GroupByItem[];\n reportType: number;\n tableData: TableData;\n baseData: RowItem[];\n columnConfigMap: { [key: string]: ColumnConfig };\n sqlFormatMap?: { [key: string]: SqlMetaConfig }; // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n cardSize?: string;\n height?: number;\n};\n\n// 处理饼图数据(用 Map 按 name 聚合,O(n) 避免大数据量时 O(n²) 卡顿)\nconst mergeData = (data: any[], metric: string, isDistribution?: boolean, maxSectors = MAX_SECTORS) => {\n const byName = new Map<\n string,\n { name: string; value: number; format: any; formattedValue?: string; metricName?: string }\n >();\n for (let i = 0; i < data.length; i++) {\n const item = data[i];\n // 分布分析时 sortedNames 为完整 name(如 \"(-∞, 1),IOS\"),需按 name 匹配;否则按 metricName 匹配\n if (isDistribution ? item.name !== metric : item.metricName !== metric) continue;\n const name = item.name.startsWith(item.metricName) ? item.name.slice(item.metricName.length + 1).trim() : item.name;\n const val = Number(item.value) || 0;\n const existing = byName.get(name);\n if (existing) {\n existing.value += val;\n } else {\n byName.set(name, {\n name,\n value: val,\n format: item.format,\n formattedValue: formatValue(val, item.format?.format),\n ...(isDistribution ? { metricName: item.name } : {}),\n });\n }\n }\n let result = Array.from(byName.values()).map((r) => ({\n ...r,\n formattedValue: formatValue(r.value, r.format?.format),\n }));\n result.sort((a, b) => b.value - a.value);\n if (result.length > maxSectors) {\n message.warning(`数据量过大,仅绘制前 ${maxSectors} 条数据`);\n result = result.slice(0, maxSectors);\n }\n return result;\n};\n\nconst Pies: FC<PageTypes> = ({\n count, // 指标显示数量\n metric, // 指标\n groupBys, // 维度\n cardSize = 'middle', // 卡片大小\n tableData, // 表格数据\n baseData, // 基础数据\n columnConfigMap, // 列配置\n sqlFormatMap, // 列配置(用于SQL可视化中的格式化处理,SQL中的格式化走了另一套逻辑)\n reportType, // 分析模型\n height,\n}) => {\n const { x = [], table_head = [], table_body = [], x_field, group_by } = tableData;\n\n const useMetric = useMemo(() => {\n if (metric.length > 0) {\n return metric;\n } else {\n return tableData.metric;\n }\n }, [metric]);\n\n const fullData = useMemo(() => {\n if (!metric || metric.length === 0) {\n return [];\n }\n // 分布分析的日期选择合计时,需要特殊处理(name 用 '合计' 便于饼图显示;避免 mergeData 把 name 裁成空串)\n if (x.length === 0 && table_head.indexOf(x_field) === -1 && reportType === 4) {\n return metric.map((m) => ({\n x: '合计',\n name: m,\n metricName: m,\n format: columnConfigMap[m],\n value: baseData.reduce((sum, item) => sum + (Number(item[m]) || 0), 0),\n }));\n }\n // x_field 在 table_head 中的索引\n const index = table_head.indexOf(x_field);\n // 存在维度时的数据处理(参照 Bar:从 baseData 提取实际组合,不做笛卡尔积)\n if (group_by && group_by.length > 0) {\n if (\n Array.isArray(groupBys) &&\n groupBys.some((g) => Array.isArray(g.selected) && g.selected.length === 0) &&\n reportType !== 4 // 分布分析时,维度为空代表选了总体\n ) {\n return [];\n }\n const validGroupBys = groupBys.filter((g) => Array.isArray(g.selected) && g.selected.length > 0);\n const validGroupByKeys = validGroupBys.map((g) => g.key);\n const onlyOneMetric = metric.length === 1;\n if (!baseData || baseData.length === 0) {\n return [];\n }\n const filteredBaseData = baseData.filter((item) => {\n return validGroupBys.every((g) => {\n const itemValue = String(item[g.key] ?? '');\n return g.selected.includes(itemValue);\n });\n });\n // 分布分析且维度 selected 全为空:按「总体」合计,对每个 (x, category) 在 filteredBaseData 上求和\n const isDistributionTotal = reportType === 4 && validGroupBys.length === 0;\n if (isDistributionTotal) {\n const xValues = x.length > 0 ? x : [...new Set(filteredBaseData.map((item) => String(item[x_field] ?? '')))];\n const chartData: any[] = [];\n xValues.forEach((xVal) => {\n metric.forEach((cat) => {\n const value = filteredBaseData\n .filter((item) => String(item[x_field] ?? '') === xVal)\n .reduce((sum, item) => sum + (Number(item[cat]) || 0), 0);\n chartData.push({\n [x_field]: xVal,\n x: xVal,\n name: cat,\n metricName: cat,\n value,\n format: columnConfigMap[cat],\n });\n });\n });\n return chartData;\n }\n const dataIndexMap = new Map<string, RowItem>();\n const existingCombinations = new Map<string, { groupByValues: string; category: string; name: string }>();\n const getName = (category: string, groupByObj: Record<string, string | number>) => {\n if (onlyOneMetric) {\n return group_by.map((g) => groupByObj[g]).join(',');\n }\n return [category, ...group_by.map((g) => groupByObj[g]).filter(Boolean)].join(',');\n };\n filteredBaseData.forEach((item) => {\n const groupByValues = validGroupByKeys.map((key) => String(item[key] ?? '')).join('|');\n metric.forEach((cat) => {\n const key = `${item[x_field]}|${groupByValues}|${cat}`;\n dataIndexMap.set(key, item);\n const combinationKey = `${groupByValues}|${cat}`;\n if (!existingCombinations.has(combinationKey)) {\n const groupByObj: Record<string, string | number> = { category: cat };\n validGroupByKeys.forEach((gKey) => {\n groupByObj[gKey] = item[gKey];\n });\n const name = getName(cat, groupByObj);\n existingCombinations.set(combinationKey, { groupByValues, category: cat, name });\n }\n });\n });\n // x 为空时(如仅分组、无 x 轴)从数据中取 x_field 的唯一值,否则 dataIndexMap 的 key 对不上\n const xValues = x.length > 0 ? x : [...new Set(filteredBaseData.map((item) => String(item[x_field] ?? '')))];\n const combinationsList = Array.from(existingCombinations.values());\n // 按 (xVal, groupByValues) 聚合:未选中的维度会多行共用一个 groupByValues,需求和而非取单条\n const getSumForCombination = (xVal: string, groupByValues: string, category: string) =>\n filteredBaseData\n .filter(\n (item) =>\n String(item[x_field] ?? '') === xVal &&\n validGroupByKeys.map((k) => String(item[k] ?? '')).join('|') === groupByValues,\n )\n .reduce((sum, item) => sum + (Number(item[category]) || 0), 0);\n // 按该组合在所有 x 上的合计排序,只保留前 N 个,避免维度和选项过多时 fullData 爆炸\n if (combinationsList.length > FULL_DATA_MAX_COMBINATIONS) {\n const withSum = combinationsList.map(({ groupByValues, category, name }) => {\n let sum = 0;\n for (let i = 0; i < xValues.length; i++) {\n sum += getSumForCombination(xValues[i], groupByValues, category);\n }\n return { groupByValues, category, name, sum };\n });\n withSum.sort((a, b) => b.sum - a.sum);\n combinationsList.length = 0;\n for (let i = 0; i < FULL_DATA_MAX_COMBINATIONS && i < withSum.length; i++) {\n combinationsList.push({\n groupByValues: withSum[i].groupByValues,\n category: withSum[i].category,\n name: withSum[i].name,\n });\n }\n }\n const getSumAndSample = (xVal: string, groupByValues: string, category: string) => {\n const matches = filteredBaseData.filter(\n (item) =>\n String(item[x_field] ?? '') === xVal &&\n validGroupByKeys.map((k) => String(item[k] ?? '')).join('|') === groupByValues,\n );\n const value = matches.reduce((sum, item) => sum + (Number(item[category]) || 0), 0);\n const sample = matches[0];\n return { value, sample };\n };\n const chartData: any[] = [];\n combinationsList.forEach(({ groupByValues, category, name }) => {\n xValues.forEach((xVal) => {\n const { value, sample } = getSumAndSample(xVal, groupByValues, category);\n const obj: Record<string, any> = {};\n validGroupByKeys.forEach((k) => {\n obj[k] = sample?.[k];\n });\n chartData.push({\n [x_field]: xVal,\n ...obj,\n x: xVal,\n name,\n metricName: category,\n value: Number(value) || 0,\n format: columnConfigMap[category],\n });\n });\n });\n return chartData;\n } else {\n const chartData: any[] = [];\n metric.forEach((m) => {\n x.forEach((item) => {\n const row = table_body.find((d) => d[index] === item);\n const obj: any = {\n x: item,\n name: m,\n metricName: m,\n format: columnConfigMap[m],\n };\n table_head.forEach((key, i) => {\n obj[key] = row ? row[i] : 0;\n });\n obj.value = obj[m];\n chartData.push(obj);\n });\n });\n return chartData;\n }\n }, [baseData, metric, groupBys, reportType]);\n\n // 获取series\n const series = useMemo(() => {\n return useMetric.map((m) => {\n const pieData = mergeData(fullData, m);\n return {\n name: m,\n type: 'pie',\n radius: ['50%', '70%'],\n label: {\n show: !(pieData.length <= 1),\n textStyle: {\n color: '#666',\n },\n },\n data: pieData,\n ...(sqlFormatMap &&\n sqlFormatMap?.[m]?.format && {\n format: sqlFormatMap?.[m]?.format,\n }),\n };\n });\n }, [fullData, metric, count, groupBys]);\n\n // 分布分析的饼图\n const distributionPie = useMemo(() => {\n // 日期选择合计:x 为空,fullData 为「合计」数据,直接用它建一张饼图\n const isTotalCase =\n x.length === 0 && fullData.length > 0 && fullData.every((d) => d.x === '合计') && reportType === 4;\n if (isTotalCase) {\n const data = fullData.map((d) => ({\n name: d.name,\n value: Number(d.value) || 0,\n format: d.format,\n formattedValue: formatValue(Number(d.value) || 0, (d as any).format?.format),\n }));\n return {\n name: '',\n type: 'pie',\n radius: ['50%', '70%'],\n label: { textStyle: { color: '#666' } },\n data,\n };\n }\n const firstPointX = x[0];\n if (firstPointX === undefined) return [];\n const firstPointData = fullData.filter((d) => d.x === firstPointX);\n const sortedData =\n reportType === 4 ? firstPointData : firstPointData.sort((a, b) => Number(b.value) - Number(a.value));\n // 直接从数据中提取名称\n const uniqueNames = [...new Set(sortedData.map((d) => d.name))];\n // 当分析模型为分布分析时,series的顺序直接按照metric的顺序\n const sortedNames = reportType === 4 ? uniqueNames : count ? uniqueNames.slice(0, count) : uniqueNames;\n const data = sortedNames.map((item) => {\n return {\n ...mergeData(fullData, item, true)[0],\n name: item,\n };\n });\n return {\n name: '',\n type: 'pie',\n radius: ['50%', '70%'],\n label: {\n textStyle: {\n color: '#666',\n },\n },\n data: data,\n };\n }, [useMetric, fullData, reportType, groupBys, x]);\n\n return (\n <>\n {fullData.length > 0 ? (\n <div className={styles.pieLegend} style={{ height: height || '100%', width: '100%' }}>\n {reportType === 4 ? (\n // 分布分析的饼图\n <Pie item={distributionPie} />\n ) : series && series.length > 1 ? (\n <Swiper\n modules={[Navigation, Pagination]}\n navigation\n slidesPerView={cardSize === 'large' ? 2 : 1}\n spaceBetween={10}\n slidesPerGroup={cardSize === 'large' ? 2 : 1}\n className={styles.pieSlider}\n style={{ height: '100%' }}\n >\n {series?.map((item) => (\n <SwiperSlide key={item.name} className={styles.pieSlideItem} tabIndex={-1}>\n <Pie item={item} />\n </SwiperSlide>\n ))}\n </Swiper>\n ) : (\n series?.map((item) => (\n <div key={item.name} style={{ height: height || '100%', width: '100%', minHeight: 220 }}>\n <Pie item={item} />\n </div>\n ))\n )}\n </div>\n ) : (\n <Empty className={styles.empty} description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </>\n );\n};\n\nexport default memo(Pies);\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAA+B;AAC/B,mBAA8C;AAE9C,mBAA4B;AAC5B,iBAAO;AACP,wBAAO;AACP,wBAAO;AACP,qBAAuC;AACvC,IAAAA,gBAAoC;AACpC,0BAAmB;AACnB,iBAAgB;AAOhB,IAAM,6BAA6B;AACnC,IAAM,cAAc;AAgBpB,IAAM,YAAY,CAAC,MAAa,QAAgB,gBAA0B,aAAa,gBAAgB;AAlCvG;AAmCE,QAAM,SAAS,oBAAI,IAGjB;AACF,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,OAAO,KAAK,CAAC;AAEnB,QAAI,iBAAiB,KAAK,SAAS,SAAS,KAAK,eAAe;AAAQ;AACxE,UAAM,OAAO,KAAK,KAAK,WAAW,KAAK,UAAU,IAAI,KAAK,KAAK,MAAM,KAAK,WAAW,SAAS,CAAC,EAAE,KAAK,IAAI,KAAK;AAC/G,UAAM,MAAM,OAAO,KAAK,KAAK,KAAK;AAClC,UAAM,WAAW,OAAO,IAAI,IAAI;AAChC,QAAI,UAAU;AACZ,eAAS,SAAS;AAAA,IACpB,OAAO;AACL,aAAO,IAAI,MAAM;AAAA,QACf;AAAA,QACA,OAAO;AAAA,QACP,QAAQ,KAAK;AAAA,QACb,oBAAgB,0BAAY,MAAK,UAAK,WAAL,mBAAa,MAAM;AAAA,QACpD,GAAI,iBAAiB,EAAE,YAAY,KAAK,KAAK,IAAI,CAAC;AAAA,MACpD,CAAC;AAAA,IACH;AAAA,EACF;AACA,MAAI,SAAS,MAAM,KAAK,OAAO,OAAO,CAAC,EAAE,IAAI,CAAC,MAAG;AA1DnD,QAAAC;AA0DuD;AAAA,MACnD,GAAG;AAAA,MACH,oBAAgB,0BAAY,EAAE,QAAOA,MAAA,EAAE,WAAF,gBAAAA,IAAU,MAAM;AAAA,IACvD;AAAA,GAAE;AACF,SAAO,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACvC,MAAI,OAAO,SAAS,YAAY;AAC9B,wBAAQ,QAAQ,cAAc,gBAAgB;AAC9C,aAAS,OAAO,MAAM,GAAG,UAAU;AAAA,EACrC;AACA,SAAO;AACT;AAEA,IAAM,OAAsB,CAAC;AAAA,EAC3B;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA,WAAW;AAAA;AAAA,EACX;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,IAAI,CAAC,GAAG,aAAa,CAAC,GAAG,aAAa,CAAC,GAAG,SAAS,SAAS,IAAI;AAExE,QAAM,gBAAY,sBAAQ,MAAM;AAC9B,QAAI,OAAO,SAAS,GAAG;AACrB,aAAO;AAAA,IACT,OAAO;AACL,aAAO,UAAU;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,eAAW,sBAAQ,MAAM;AAC7B,QAAI,CAAC,UAAU,OAAO,WAAW,GAAG;AAClC,aAAO,CAAC;AAAA,IACV;AAEA,QAAI,EAAE,WAAW,KAAK,WAAW,QAAQ,OAAO,MAAM,MAAM,eAAe,GAAG;AAC5E,aAAO,OAAO,IAAI,CAAC,OAAO;AAAA,QACxB,GAAG;AAAA,QACH,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,QAAQ,gBAAgB,CAAC;AAAA,QACzB,OAAO,SAAS,OAAO,CAAC,KAAK,SAAS,OAAO,OAAO,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC;AAAA,MACvE,EAAE;AAAA,IACJ;AAEA,UAAM,QAAQ,WAAW,QAAQ,OAAO;AAExC,QAAI,YAAY,SAAS,SAAS,GAAG;AACnC,UACE,MAAM,QAAQ,QAAQ,KACtB,SAAS,KAAK,CAAC,MAAM,MAAM,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,WAAW,CAAC,KACzE,eAAe,GACf;AACA,eAAO,CAAC;AAAA,MACV;AACA,YAAM,gBAAgB,SAAS,OAAO,CAAC,MAAM,MAAM,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,SAAS,CAAC;AAC/F,YAAM,mBAAmB,cAAc,IAAI,CAAC,MAAM,EAAE,GAAG;AACvD,YAAM,gBAAgB,OAAO,WAAW;AACxC,UAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACtC,eAAO,CAAC;AAAA,MACV;AACA,YAAM,mBAAmB,SAAS,OAAO,CAAC,SAAS;AACjD,eAAO,cAAc,MAAM,CAAC,MAAM;AAChC,gBAAM,YAAY,OAAO,KAAK,EAAE,GAAG,KAAK,EAAE;AAC1C,iBAAO,EAAE,SAAS,SAAS,SAAS;AAAA,QACtC,CAAC;AAAA,MACH,CAAC;AAED,YAAM,sBAAsB,eAAe,KAAK,cAAc,WAAW;AACzE,UAAI,qBAAqB;AACvB,cAAMC,WAAU,EAAE,SAAS,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,iBAAiB,IAAI,CAAC,SAAS,OAAO,KAAK,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC;AAC3G,cAAMC,aAAmB,CAAC;AAC1B,QAAAD,SAAQ,QAAQ,CAAC,SAAS;AACxB,iBAAO,QAAQ,CAAC,QAAQ;AACtB,kBAAM,QAAQ,iBACX,OAAO,CAAC,SAAS,OAAO,KAAK,OAAO,KAAK,EAAE,MAAM,IAAI,EACrD,OAAO,CAAC,KAAK,SAAS,OAAO,OAAO,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC;AAC1D,YAAAC,WAAU,KAAK;AAAA,cACb,CAAC,OAAO,GAAG;AAAA,cACX,GAAG;AAAA,cACH,MAAM;AAAA,cACN,YAAY;AAAA,cACZ;AAAA,cACA,QAAQ,gBAAgB,GAAG;AAAA,YAC7B,CAAC;AAAA,UACH,CAAC;AAAA,QACH,CAAC;AACD,eAAOA;AAAA,MACT;AACA,YAAM,eAAe,oBAAI,IAAqB;AAC9C,YAAM,uBAAuB,oBAAI,IAAuE;AACxG,YAAM,UAAU,CAAC,UAAkB,eAAgD;AACjF,YAAI,eAAe;AACjB,iBAAO,SAAS,IAAI,CAAC,MAAM,WAAW,CAAC,CAAC,EAAE,KAAK,GAAG;AAAA,QACpD;AACA,eAAO,CAAC,UAAU,GAAG,SAAS,IAAI,CAAC,MAAM,WAAW,CAAC,CAAC,EAAE,OAAO,OAAO,CAAC,EAAE,KAAK,GAAG;AAAA,MACnF;AACA,uBAAiB,QAAQ,CAAC,SAAS;AACjC,cAAM,gBAAgB,iBAAiB,IAAI,CAAC,QAAQ,OAAO,KAAK,GAAG,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG;AACrF,eAAO,QAAQ,CAAC,QAAQ;AACtB,gBAAM,MAAM,GAAG,KAAK,OAAO,KAAK,iBAAiB;AACjD,uBAAa,IAAI,KAAK,IAAI;AAC1B,gBAAM,iBAAiB,GAAG,iBAAiB;AAC3C,cAAI,CAAC,qBAAqB,IAAI,cAAc,GAAG;AAC7C,kBAAM,aAA8C,EAAE,UAAU,IAAI;AACpE,6BAAiB,QAAQ,CAAC,SAAS;AACjC,yBAAW,IAAI,IAAI,KAAK,IAAI;AAAA,YAC9B,CAAC;AACD,kBAAM,OAAO,QAAQ,KAAK,UAAU;AACpC,iCAAqB,IAAI,gBAAgB,EAAE,eAAe,UAAU,KAAK,KAAK,CAAC;AAAA,UACjF;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAED,YAAM,UAAU,EAAE,SAAS,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,iBAAiB,IAAI,CAAC,SAAS,OAAO,KAAK,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC;AAC3G,YAAM,mBAAmB,MAAM,KAAK,qBAAqB,OAAO,CAAC;AAEjE,YAAM,uBAAuB,CAAC,MAAc,eAAuB,aACjE,iBACG;AAAA,QACC,CAAC,SACC,OAAO,KAAK,OAAO,KAAK,EAAE,MAAM,QAChC,iBAAiB,IAAI,CAAC,MAAM,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG,MAAM;AAAA,MACrE,EACC,OAAO,CAAC,KAAK,SAAS,OAAO,OAAO,KAAK,QAAQ,CAAC,KAAK,IAAI,CAAC;AAEjE,UAAI,iBAAiB,SAAS,4BAA4B;AACxD,cAAM,UAAU,iBAAiB,IAAI,CAAC,EAAE,eAAe,UAAU,KAAK,MAAM;AAC1E,cAAI,MAAM;AACV,mBAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,mBAAO,qBAAqB,QAAQ,CAAC,GAAG,eAAe,QAAQ;AAAA,UACjE;AACA,iBAAO,EAAE,eAAe,UAAU,MAAM,IAAI;AAAA,QAC9C,CAAC;AACD,gBAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG;AACpC,yBAAiB,SAAS;AAC1B,iBAAS,IAAI,GAAG,IAAI,8BAA8B,IAAI,QAAQ,QAAQ,KAAK;AACzE,2BAAiB,KAAK;AAAA,YACpB,eAAe,QAAQ,CAAC,EAAE;AAAA,YAC1B,UAAU,QAAQ,CAAC,EAAE;AAAA,YACrB,MAAM,QAAQ,CAAC,EAAE;AAAA,UACnB,CAAC;AAAA,QACH;AAAA,MACF;AACA,YAAM,kBAAkB,CAAC,MAAc,eAAuB,aAAqB;AACjF,cAAM,UAAU,iBAAiB;AAAA,UAC/B,CAAC,SACC,OAAO,KAAK,OAAO,KAAK,EAAE,MAAM,QAChC,iBAAiB,IAAI,CAAC,MAAM,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG,MAAM;AAAA,QACrE;AACA,cAAM,QAAQ,QAAQ,OAAO,CAAC,KAAK,SAAS,OAAO,OAAO,KAAK,QAAQ,CAAC,KAAK,IAAI,CAAC;AAClF,cAAM,SAAS,QAAQ,CAAC;AACxB,eAAO,EAAE,OAAO,OAAO;AAAA,MACzB;AACA,YAAM,YAAmB,CAAC;AAC1B,uBAAiB,QAAQ,CAAC,EAAE,eAAe,UAAU,KAAK,MAAM;AAC9D,gBAAQ,QAAQ,CAAC,SAAS;AACxB,gBAAM,EAAE,OAAO,OAAO,IAAI,gBAAgB,MAAM,eAAe,QAAQ;AACvE,gBAAM,MAA2B,CAAC;AAClC,2BAAiB,QAAQ,CAAC,MAAM;AAC9B,gBAAI,CAAC,IAAI,iCAAS;AAAA,UACpB,CAAC;AACD,oBAAU,KAAK;AAAA,YACb,CAAC,OAAO,GAAG;AAAA,YACX,GAAG;AAAA,YACH,GAAG;AAAA,YACH;AAAA,YACA,YAAY;AAAA,YACZ,OAAO,OAAO,KAAK,KAAK;AAAA,YACxB,QAAQ,gBAAgB,QAAQ;AAAA,UAClC,CAAC;AAAA,QACH,CAAC;AAAA,MACH,CAAC;AACD,aAAO;AAAA,IACT,OAAO;AACL,YAAM,YAAmB,CAAC;AAC1B,aAAO,QAAQ,CAAC,MAAM;AACpB,UAAE,QAAQ,CAAC,SAAS;AAClB,gBAAM,MAAM,WAAW,KAAK,CAAC,MAAM,EAAE,KAAK,MAAM,IAAI;AACpD,gBAAM,MAAW;AAAA,YACf,GAAG;AAAA,YACH,MAAM;AAAA,YACN,YAAY;AAAA,YACZ,QAAQ,gBAAgB,CAAC;AAAA,UAC3B;AACA,qBAAW,QAAQ,CAAC,KAAK,MAAM;AAC7B,gBAAI,GAAG,IAAI,MAAM,IAAI,CAAC,IAAI;AAAA,UAC5B,CAAC;AACD,cAAI,QAAQ,IAAI,CAAC;AACjB,oBAAU,KAAK,GAAG;AAAA,QACpB,CAAC;AAAA,MACH,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,UAAU,QAAQ,UAAU,UAAU,CAAC;AAG3C,QAAM,aAAS,sBAAQ,MAAM;AAC3B,WAAO,UAAU,IAAI,CAAC,MAAM;AApQhC;AAqQM,YAAM,UAAU,UAAU,UAAU,CAAC;AACrC,aAAO;AAAA,QACL,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ,CAAC,OAAO,KAAK;AAAA,QACrB,OAAO;AAAA,UACL,MAAM,EAAE,QAAQ,UAAU;AAAA,UAC1B,WAAW;AAAA,YACT,OAAO;AAAA,UACT;AAAA,QACF;AAAA,QACA,MAAM;AAAA,QACN,GAAI,kBACF,kDAAe,OAAf,mBAAmB,WAAU;AAAA,UAC3B,SAAQ,kDAAe,OAAf,mBAAmB;AAAA,QAC7B;AAAA,MACJ;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,UAAU,QAAQ,OAAO,QAAQ,CAAC;AAGtC,QAAM,sBAAkB,sBAAQ,MAAM;AAEpC,UAAM,cACJ,EAAE,WAAW,KAAK,SAAS,SAAS,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,KAAK,eAAe;AACjG,QAAI,aAAa;AACf,YAAMC,QAAO,SAAS,IAAI,CAAC,MAAG;AA/RpC;AA+RwC;AAAA,UAChC,MAAM,EAAE;AAAA,UACR,OAAO,OAAO,EAAE,KAAK,KAAK;AAAA,UAC1B,QAAQ,EAAE;AAAA,UACV,oBAAgB,0BAAY,OAAO,EAAE,KAAK,KAAK,IAAI,OAAU,WAAV,mBAAkB,MAAM;AAAA,QAC7E;AAAA,OAAE;AACF,aAAO;AAAA,QACL,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ,CAAC,OAAO,KAAK;AAAA,QACrB,OAAO,EAAE,WAAW,EAAE,OAAO,OAAO,EAAE;AAAA,QACtC,MAAAA;AAAA,MACF;AAAA,IACF;AACA,UAAM,cAAc,EAAE,CAAC;AACvB,QAAI,gBAAgB;AAAW,aAAO,CAAC;AACvC,UAAM,iBAAiB,SAAS,OAAO,CAAC,MAAM,EAAE,MAAM,WAAW;AACjE,UAAM,aACJ,eAAe,IAAI,iBAAiB,eAAe,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,KAAK,CAAC;AAErG,UAAM,cAAc,CAAC,GAAG,IAAI,IAAI,WAAW,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAE9D,UAAM,cAAc,eAAe,IAAI,cAAc,QAAQ,YAAY,MAAM,GAAG,KAAK,IAAI;AAC3F,UAAM,OAAO,YAAY,IAAI,CAAC,SAAS;AACrC,aAAO;AAAA,QACL,GAAG,UAAU,UAAU,MAAM,IAAI,EAAE,CAAC;AAAA,QACpC,MAAM;AAAA,MACR;AAAA,IACF,CAAC;AACD,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM;AAAA,MACN,QAAQ,CAAC,OAAO,KAAK;AAAA,MACrB,OAAO;AAAA,QACL,WAAW;AAAA,UACT,OAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF,GAAG,CAAC,WAAW,UAAU,YAAY,UAAU,CAAC,CAAC;AAEjD,SACE,6BAAAC,QAAA,2BAAAA,QAAA,gBACG,SAAS,SAAS,IACjB,6BAAAA,QAAA,cAAC,SAAI,WAAW,oBAAAC,QAAO,WAAW,OAAO,EAAE,QAAQ,UAAU,QAAQ,OAAO,OAAO,KAChF,eAAe;AAAA;AAAA,IAEd,6BAAAD,QAAA,cAAC,WAAAE,SAAA,EAAI,MAAM,iBAAiB;AAAA,MAC1B,UAAU,OAAO,SAAS,IAC5B,6BAAAF,QAAA;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,CAAC,2BAAY,yBAAU;AAAA,MAChC,YAAU;AAAA,MACV,eAAe,aAAa,UAAU,IAAI;AAAA,MAC1C,cAAc;AAAA,MACd,gBAAgB,aAAa,UAAU,IAAI;AAAA,MAC3C,WAAW,oBAAAC,QAAO;AAAA,MAClB,OAAO,EAAE,QAAQ,OAAO;AAAA;AAAA,IAEvB,iCAAQ,IAAI,CAAC,SACZ,6BAAAD,QAAA,cAAC,6BAAY,KAAK,KAAK,MAAM,WAAW,oBAAAC,QAAO,cAAc,UAAU,MACrE,6BAAAD,QAAA,cAAC,WAAAE,SAAA,EAAI,MAAY,CACnB;AAAA,EAEJ,IAEA,iCAAQ,IAAI,CAAC,SACX,6BAAAF,QAAA,cAAC,SAAI,KAAK,KAAK,MAAM,OAAO,EAAE,QAAQ,UAAU,QAAQ,OAAO,QAAQ,WAAW,IAAI,KACpF,6BAAAA,QAAA,cAAC,WAAAE,SAAA,EAAI,MAAY,CACnB,EAGN,IAEA,6BAAAF,QAAA,cAAC,qBAAM,WAAW,oBAAAC,QAAO,OAAO,aAAY,QAAO,OAAO,kBAAM,wBAAwB,CAE5F;AAEJ;AAEA,IAAO,mBAAQ,mBAAK,IAAI;",
6
6
  "names": ["import_react", "_a", "xValues", "chartData", "data", "React", "styles", "Pie"]
7
7
  }
@@ -56,7 +56,7 @@ var formatValue = (value, format) => {
56
56
  };
57
57
  function formatNumber(num, isInteger = false) {
58
58
  const numberValue = typeof num === "string" ? parseFloat(num) : num;
59
- if (isNaN(numberValue)) {
59
+ if (Number.isNaN(numberValue)) {
60
60
  return [(num == null ? void 0 : num.toString()) || "", ""];
61
61
  }
62
62
  let result = "";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/business/YkCharts/utils.ts"],
4
- "sourcesContent": ["import Decimal from 'decimal.js';\nimport type { Format, SqlFormat } from './typing';\n\nexport const formatValue = (value: string | number, format: Format | undefined | null): string => {\n if (value === null || value === undefined || value === '-') {\n return '-';\n }\n if (!format || format === null) {\n return value.toString();\n }\n const numValue = Number(value);\n if (format === 'percent') {\n return new Decimal(numValue).mul(100).toFixed(2) + '%';\n }\n if (format === 'decimal') {\n return new Decimal(numValue).toFixed(2);\n }\n if (format === 'integer') {\n return new Intl.NumberFormat().format(numValue);\n }\n return numValue.toString();\n};\n\nexport function formatNumber(num: number | string, isInteger: boolean = false): [string, string] {\n const numberValue = typeof num === 'string' ? parseFloat(num) : num;\n if (isNaN(numberValue)) {\n return [num?.toString() || '', ''];\n }\n let result: string = '';\n let unit: string = '';\n function setFixed(v: number, dot: number) {\n const multiplier = 10 ** dot;\n return Math.floor(v * multiplier) / multiplier;\n }\n if (numberValue < 1000) {\n result = new Decimal(numberValue).toFixed(1);\n } else if (numberValue < 10000) {\n result = numberValue.toLocaleString('en-US', {\n minimumFractionDigits: isInteger ? 0 : 1,\n maximumFractionDigits: isInteger ? 0 : 1,\n });\n } else if (numberValue < 100000000) {\n const v = setFixed(numberValue / 10000, 2);\n result = v.toLocaleString('en-US', {\n minimumFractionDigits: isInteger ? 1 : 2,\n maximumFractionDigits: isInteger ? 1 : 2,\n });\n unit = ' 万';\n } else {\n const v = setFixed(numberValue / 100000000, 2);\n result = v.toLocaleString('en-US', {\n minimumFractionDigits: isInteger ? 1 : 2,\n maximumFractionDigits: isInteger ? 1 : 2,\n });\n unit = ' 亿';\n }\n if (isInteger) {\n result = result.replace(/\\.0+(?=\\D*$)/, '');\n }\n return [result, unit];\n}\n\nexport function sqlFormat(value: string | number | boolean, format: SqlFormat | undefined | null): string {\n if (value === null || value === undefined || value === '-') {\n return '-';\n }\n if (!format) {\n return value?.toString();\n }\n if (typeof value === 'boolean') {\n return value?.toString();\n }\n const { type, decimals = 0, thousand_separator = true, unit = 0, prefix = '', suffix = '' } = format;\n switch (type) {\n case 'number': {\n let result: string;\n if (thousand_separator) {\n result = value\n ? value?.toLocaleString('en-US', {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n })\n : '0';\n } else {\n result = new Decimal(value || 0).toFixed(decimals);\n }\n return `${prefix}${result}${suffix}`;\n }\n case 'percent': {\n const result = new Decimal(value || 0).mul(100).toFixed(decimals) + '%';\n return `${prefix}${result}${suffix}`;\n }\n case 'currency': {\n const numericValue = new Decimal(value || 0).div(10 ** unit).toNumber();\n const unitValue = numericValue.toLocaleString('en-US', {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n });\n const unitLabel = unit === 0 ? '' : unit === 4 ? '万' : unit === 8 ? '亿' : '';\n return `${prefix}${unitValue}${unitLabel}${suffix}`;\n }\n case 'normal':\n default:\n return value?.toString() || '-';\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import Decimal from 'decimal.js';\nimport type { Format, SqlFormat } from './typing';\n\nexport const formatValue = (value: string | number, format: Format | undefined | null): string => {\n if (value === null || value === undefined || value === '-') {\n return '-';\n }\n if (!format || format === null) {\n return value.toString();\n }\n const numValue = Number(value);\n if (format === 'percent') {\n return new Decimal(numValue).mul(100).toFixed(2) + '%';\n }\n if (format === 'decimal') {\n return new Decimal(numValue).toFixed(2);\n }\n if (format === 'integer') {\n return new Intl.NumberFormat().format(numValue);\n }\n return numValue.toString();\n};\n\nexport function formatNumber(num: number | string, isInteger: boolean = false): [string, string] {\n const numberValue = typeof num === 'string' ? parseFloat(num) : num;\n if (Number.isNaN(numberValue)) {\n return [num?.toString() || '', ''];\n }\n let result: string = '';\n let unit: string = '';\n function setFixed(v: number, dot: number) {\n const multiplier = 10 ** dot;\n return Math.floor(v * multiplier) / multiplier;\n }\n if (numberValue < 1000) {\n result = new Decimal(numberValue).toFixed(1);\n } else if (numberValue < 10000) {\n result = numberValue.toLocaleString('en-US', {\n minimumFractionDigits: isInteger ? 0 : 1,\n maximumFractionDigits: isInteger ? 0 : 1,\n });\n } else if (numberValue < 100000000) {\n const v = setFixed(numberValue / 10000, 2);\n result = v.toLocaleString('en-US', {\n minimumFractionDigits: isInteger ? 1 : 2,\n maximumFractionDigits: isInteger ? 1 : 2,\n });\n unit = ' 万';\n } else {\n const v = setFixed(numberValue / 100000000, 2);\n result = v.toLocaleString('en-US', {\n minimumFractionDigits: isInteger ? 1 : 2,\n maximumFractionDigits: isInteger ? 1 : 2,\n });\n unit = ' 亿';\n }\n if (isInteger) {\n result = result.replace(/\\.0+(?=\\D*$)/, '');\n }\n return [result, unit];\n}\n\nexport function sqlFormat(value: string | number | boolean, format: SqlFormat | undefined | null): string {\n if (value === null || value === undefined || value === '-') {\n return '-';\n }\n if (!format) {\n return value?.toString();\n }\n if (typeof value === 'boolean') {\n return value?.toString();\n }\n const { type, decimals = 0, thousand_separator = true, unit = 0, prefix = '', suffix = '' } = format;\n switch (type) {\n case 'number': {\n let result: string;\n if (thousand_separator) {\n result = value\n ? value?.toLocaleString('en-US', {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n })\n : '0';\n } else {\n result = new Decimal(value || 0).toFixed(decimals);\n }\n return `${prefix}${result}${suffix}`;\n }\n case 'percent': {\n const result = new Decimal(value || 0).mul(100).toFixed(decimals) + '%';\n return `${prefix}${result}${suffix}`;\n }\n case 'currency': {\n const numericValue = new Decimal(value || 0).div(10 ** unit).toNumber();\n const unitValue = numericValue.toLocaleString('en-US', {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n });\n const unitLabel = unit === 0 ? '' : unit === 4 ? '万' : unit === 8 ? '亿' : '';\n return `${prefix}${unitValue}${unitLabel}${suffix}`;\n }\n case 'normal':\n default:\n return value?.toString() || '-';\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["Decimal"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yoka-ui/ui",
3
- "version": "1.0.7",
3
+ "version": "1.1.0",
4
4
  "private": false,
5
5
  "description": "",
6
6
  "homepage": "",