@ant-design/agentic-ui 2.30.12 → 2.30.14
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.
- package/dist/Bubble/AIBubble.js +32 -18
- package/dist/Bubble/ContentFilemapView.d.ts +14 -0
- package/dist/Bubble/ContentFilemapView.js +95 -0
- package/dist/Bubble/MessagesContent/MarkdownPreview.js +3 -2
- package/dist/Bubble/UserBubble.js +48 -6
- package/dist/Bubble/extractFilemapBlocks.d.ts +17 -0
- package/dist/Bubble/extractFilemapBlocks.js +23 -0
- package/dist/Bubble/type.d.ts +3 -0
- package/dist/Hooks/useLanguage.d.ts +2 -0
- package/dist/I18n/locales.d.ts +2 -0
- package/dist/I18n/locales.js +5 -1
- package/dist/MarkdownEditor/editor/elements/AgenticUiBlocks/agenticUiEmbedUtils.d.ts +5 -1
- package/dist/MarkdownEditor/editor/elements/AgenticUiBlocks/agenticUiEmbedUtils.js +10 -2
- package/dist/MarkdownEditor/editor/elements/Code/index.js +22 -14
- package/dist/MarkdownEditor/editor/parser/constants.d.ts +10 -0
- package/dist/MarkdownEditor/editor/parser/constants.js +46 -0
- package/dist/MarkdownEditor/editor/parser/parserMarkdownToSlateNode.js +3 -1
- package/dist/MarkdownEditor/editor/parser/parserSlateNodeToMarkdown.js +11 -0
- package/dist/MarkdownEditor/editor/utils/markdownToHtml.js +6 -4
- package/dist/MarkdownEditor/types.d.ts +6 -0
- package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileIcon.js +3 -1
- package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.js +2 -2
- package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/index.js +6 -1
- package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/style.js +11 -1
- package/dist/MarkdownInputField/AttachmentButton/index.d.ts +12 -0
- package/dist/MarkdownInputField/AttachmentButton/index.js +23 -13
- package/dist/MarkdownInputField/FileMapView/FileMapViewItem.js +20 -1
- package/dist/MarkdownInputField/FileMapView/index.d.ts +13 -1
- package/dist/MarkdownInputField/FileMapView/index.js +57 -18
- package/dist/MarkdownInputField/FileMapView/style.js +6 -0
- package/dist/MarkdownInputField/FileUploadManager/index.js +4 -26
- package/dist/MarkdownInputField/style.js +7 -0
- package/dist/MarkdownRenderer/MarkdownRenderer.js +10 -6
- package/dist/MarkdownRenderer/index.d.ts +1 -1
- package/dist/MarkdownRenderer/renderers/AgenticUiFileMapBlockRenderer.d.ts +4 -2
- package/dist/MarkdownRenderer/renderers/AgenticUiFileMapBlockRenderer.js +47 -5
- package/dist/MarkdownRenderer/renderers/ChartRenderer.js +9 -0
- package/dist/MarkdownRenderer/streaming/useStreamingMarkdownReact.js +2 -2
- package/dist/MarkdownRenderer/types.d.ts +45 -2
- package/dist/MarkdownRenderer/useMarkdownToReact.js +2 -2
- package/dist/Plugins/chart/ChartRender.js +30 -9
- package/dist/Plugins/chart/DonutChart/index.js +21 -7
- package/dist/Plugins/chart/HistogramChart/index.d.ts +5 -1
- package/dist/Plugins/chart/HistogramChart/index.js +79 -12
- package/dist/Plugins/chart/ScatterChart/index.d.ts +8 -0
- package/dist/Plugins/chart/ScatterChart/index.js +78 -8
- package/dist/Plugins/chart/components/ChartContainer/ChartErrorBoundary.d.ts +4 -0
- package/dist/Plugins/code/components/AceEditor.js +69 -8
- package/dist/Plugins/code/components/CodeRenderer.js +0 -1
- package/dist/Workspace/Browser/index.js +3 -1
- package/package.json +1 -1
|
@@ -1,3 +1,39 @@
|
|
|
1
|
+
function _object_without_properties(source, excluded) {
|
|
2
|
+
if (source == null) return {};
|
|
3
|
+
var target = {}, sourceKeys, key, i;
|
|
4
|
+
if (typeof Reflect !== "undefined" && Reflect.ownKeys) {
|
|
5
|
+
sourceKeys = Reflect.ownKeys(source);
|
|
6
|
+
for(i = 0; i < sourceKeys.length; i++){
|
|
7
|
+
key = sourceKeys[i];
|
|
8
|
+
if (excluded.indexOf(key) >= 0) continue;
|
|
9
|
+
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|
10
|
+
target[key] = source[key];
|
|
11
|
+
}
|
|
12
|
+
return target;
|
|
13
|
+
}
|
|
14
|
+
target = _object_without_properties_loose(source, excluded);
|
|
15
|
+
if (Object.getOwnPropertySymbols) {
|
|
16
|
+
sourceKeys = Object.getOwnPropertySymbols(source);
|
|
17
|
+
for(i = 0; i < sourceKeys.length; i++){
|
|
18
|
+
key = sourceKeys[i];
|
|
19
|
+
if (excluded.indexOf(key) >= 0) continue;
|
|
20
|
+
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|
21
|
+
target[key] = source[key];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return target;
|
|
25
|
+
}
|
|
26
|
+
function _object_without_properties_loose(source, excluded) {
|
|
27
|
+
if (source == null) return {};
|
|
28
|
+
var target = {}, sourceKeys = Object.getOwnPropertyNames(source), key, i;
|
|
29
|
+
for(i = 0; i < sourceKeys.length; i++){
|
|
30
|
+
key = sourceKeys[i];
|
|
31
|
+
if (excluded.indexOf(key) >= 0) continue;
|
|
32
|
+
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|
33
|
+
target[key] = source[key];
|
|
34
|
+
}
|
|
35
|
+
return target;
|
|
36
|
+
}
|
|
1
37
|
import json5 from "json5";
|
|
2
38
|
import React, { useMemo } from "react";
|
|
3
39
|
import { normalizeFileMapPropsFromJson } from "../../MarkdownEditor/editor/elements/AgenticUiBlocks/agenticUiEmbedUtils";
|
|
@@ -27,10 +63,13 @@ var parseJsonBody = function parseJsonBody(code) {
|
|
|
27
63
|
/**
|
|
28
64
|
* ```agentic-ui-filemap``` 代码块 → FileMapView
|
|
29
65
|
*/ export var AgenticUiFileMapBlockRenderer = function AgenticUiFileMapBlockRenderer(props) {
|
|
66
|
+
var fileMapConfig = props.fileMapConfig, rest = _object_without_properties(props, [
|
|
67
|
+
"fileMapConfig"
|
|
68
|
+
]);
|
|
30
69
|
var code = useMemo(function() {
|
|
31
|
-
return extractTextContent(
|
|
70
|
+
return extractTextContent(rest.children);
|
|
32
71
|
}, [
|
|
33
|
-
|
|
72
|
+
rest.children
|
|
34
73
|
]);
|
|
35
74
|
var parsed = useMemo(function() {
|
|
36
75
|
return parseJsonBody(code);
|
|
@@ -38,9 +77,10 @@ var parseJsonBody = function parseJsonBody(code) {
|
|
|
38
77
|
code
|
|
39
78
|
]);
|
|
40
79
|
var _useMemo = useMemo(function() {
|
|
41
|
-
return normalizeFileMapPropsFromJson(parsed);
|
|
80
|
+
return normalizeFileMapPropsFromJson(parsed, fileMapConfig === null || fileMapConfig === void 0 ? void 0 : fileMapConfig.normalizeFile);
|
|
42
81
|
}, [
|
|
43
|
-
parsed
|
|
82
|
+
parsed,
|
|
83
|
+
fileMapConfig === null || fileMapConfig === void 0 ? void 0 : fileMapConfig.normalizeFile
|
|
44
84
|
]), fileList = _useMemo.fileList, className = _useMemo.className;
|
|
45
85
|
var fileMap = useMemo(function() {
|
|
46
86
|
return new Map(fileList.map(function(f) {
|
|
@@ -73,7 +113,9 @@ var parseJsonBody = function parseJsonBody(code) {
|
|
|
73
113
|
}
|
|
74
114
|
}, /*#__PURE__*/ React.createElement(FileMapView, {
|
|
75
115
|
fileMap: fileMap,
|
|
76
|
-
className: className
|
|
116
|
+
className: className,
|
|
117
|
+
onPreview: fileMapConfig === null || fileMapConfig === void 0 ? void 0 : fileMapConfig.onPreview,
|
|
118
|
+
itemRender: fileMapConfig === null || fileMapConfig === void 0 ? void 0 : fileMapConfig.itemRender
|
|
77
119
|
}));
|
|
78
120
|
};
|
|
79
121
|
AgenticUiFileMapBlockRenderer.displayName = 'AgenticUiFileMapBlockRenderer';
|
|
@@ -158,6 +158,7 @@ var extractTextContent = function extractTextContent1(children) {
|
|
|
158
158
|
* 支持两种格式:
|
|
159
159
|
* 1. 完整格式:{ config: [...], dataSource: [...], columns: [...] }
|
|
160
160
|
* 2. 简单格式:{ chartType, x, y, data: [...] }
|
|
161
|
+
* 3. algTypes 格式:{ type: "histogram", value: { data: [...], dataMetaMap: {...} } }
|
|
161
162
|
*/ var parseChartData = function parseChartData(code) {
|
|
162
163
|
try {
|
|
163
164
|
var parsed = JSON.parse(code.trim());
|
|
@@ -167,6 +168,14 @@ var extractTextContent = function extractTextContent1(children) {
|
|
|
167
168
|
config: parsed
|
|
168
169
|
};
|
|
169
170
|
}
|
|
171
|
+
// Handle { type: "histogram", value: { data: [...], dataMetaMap: {...} } } format
|
|
172
|
+
if (typeof parsed.type === 'string' && parsed.value && Array.isArray(parsed.value.data)) {
|
|
173
|
+
return {
|
|
174
|
+
chartType: parsed.type,
|
|
175
|
+
data: parsed.value.data,
|
|
176
|
+
dataMetaMap: parsed.value.dataMetaMap
|
|
177
|
+
};
|
|
178
|
+
}
|
|
170
179
|
return parsed;
|
|
171
180
|
} catch (unused) {
|
|
172
181
|
return null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JINJA_DOLLAR_PLACEHOLDER } from "../../MarkdownEditor/editor/parser/constants";
|
|
1
|
+
import { JINJA_DOLLAR_PLACEHOLDER, preprocessNormalizeLeafToContainerDirective } from "../../MarkdownEditor/editor/parser/constants";
|
|
2
2
|
import React, { useMemo, useRef } from "react";
|
|
3
3
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
import { buildEditorAlignedComponents, createHastProcessor, splitMarkdownBlocks } from "../markdownReactShared";
|
|
@@ -38,7 +38,7 @@ import { shouldResetRevisionProgress } from "./revisionPolicy";
|
|
|
38
38
|
}
|
|
39
39
|
prevRevisionRef.current = revisionSource;
|
|
40
40
|
try {
|
|
41
|
-
var preprocessed = content.replace(new RegExp(JINJA_DOLLAR_PLACEHOLDER, 'g'), '$');
|
|
41
|
+
var preprocessed = preprocessNormalizeLeafToContainerDirective(content.replace(new RegExp(JINJA_DOLLAR_PLACEHOLDER, 'g'), '$'));
|
|
42
42
|
var blocks = splitMarkdownBlocks(preprocessed);
|
|
43
43
|
if (blocks.length === 0) return null;
|
|
44
44
|
var gen = revisionGenerationRef.current;
|
|
@@ -1,10 +1,48 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import type { MarkdownRemarkPlugin, MarkdownToHtmlConfig } from '../MarkdownEditor/editor/utils/markdownToHtml';
|
|
3
3
|
import type { MarkdownEditorPlugin } from '../MarkdownEditor/plugin';
|
|
4
|
+
import type { AttachmentFile } from '../MarkdownInputField/AttachmentButton/types';
|
|
5
|
+
import type { FileMapViewProps } from '../MarkdownInputField/FileMapView';
|
|
4
6
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
+
* FileMapView 相关配置,透传给 agentic-ui-filemap 代码块渲染器,
|
|
8
|
+
* 方便在 markdownRenderConfig 中统一配置图片回显行为。
|
|
7
9
|
*/
|
|
10
|
+
export interface FileMapConfig {
|
|
11
|
+
/**
|
|
12
|
+
* 预览文件回调,透传给 FileMapView.onPreview。
|
|
13
|
+
* 对图片:点击缩略图时触发,传入则阻止 antd Image 内置灯箱;
|
|
14
|
+
* 对视频:传入则阻止内置弹窗;对普通文件:传入则阻止默认 window.open。
|
|
15
|
+
*/
|
|
16
|
+
onPreview?: (file: AttachmentFile) => void;
|
|
17
|
+
/**
|
|
18
|
+
* 自定义每个媒体条目(图片/视频)的渲染,透传给 FileMapView.itemRender,
|
|
19
|
+
* 常用于回显场景。
|
|
20
|
+
*/
|
|
21
|
+
itemRender?: FileMapViewProps['itemRender'];
|
|
22
|
+
/**
|
|
23
|
+
* 自定义文件数据规范化函数,用于将 agentic-ui-filemap 代码块中的原始 JSON 条目
|
|
24
|
+
* 转换为 AttachmentFile 对象。
|
|
25
|
+
*
|
|
26
|
+
* 适用于服务端返回的字段名与 AttachmentFile 不一致(如 fileUrl → url、
|
|
27
|
+
* fileId → uuid)或需要在数据层补充额外字段的场景。
|
|
28
|
+
*
|
|
29
|
+
* @param raw - 代码块 JSON 中的原始文件对象(未经处理)
|
|
30
|
+
* @param defaultFile - 由内置逻辑生成的默认 AttachmentFile,可在此基础上做局部覆盖
|
|
31
|
+
* @returns 转换后的 AttachmentFile;返回 null 时该条目将被过滤掉
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* fileMapConfig={{
|
|
36
|
+
* normalizeFile: (raw, defaultFile) => ({
|
|
37
|
+
* ...defaultFile,
|
|
38
|
+
* url: raw.fileUrl as string,
|
|
39
|
+
* uuid: raw.fileId as string,
|
|
40
|
+
* }),
|
|
41
|
+
* }}
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
normalizeFile?: (raw: Record<string, unknown>, defaultFile: AttachmentFile) => AttachmentFile | null;
|
|
45
|
+
}
|
|
8
46
|
export interface MarkdownRendererEleProps {
|
|
9
47
|
/** HTML tag name, e.g. 'p', 'h1', 'blockquote', 'pre' */
|
|
10
48
|
tagName: string;
|
|
@@ -92,6 +130,11 @@ export interface MarkdownRendererProps {
|
|
|
92
130
|
/** 自定义渲染函数,接收解析后的 JSON value,返回 React 节点 */
|
|
93
131
|
render?: (value: any) => React.ReactNode;
|
|
94
132
|
};
|
|
133
|
+
/**
|
|
134
|
+
* FileMapView 配置,透传给 agentic-ui-filemap 代码块渲染器。
|
|
135
|
+
* 可在 markdownRenderConfig 中统一配置图片 onPreview 和 itemRender。
|
|
136
|
+
*/
|
|
137
|
+
fileMapConfig?: FileMapConfig;
|
|
95
138
|
/**
|
|
96
139
|
* 自定义元素渲染函数(markdown 渲染模式)
|
|
97
140
|
* 与 Slate 模式的 eleItemRender 对应,允许拦截并替换任意块级/行内元素的渲染结果。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { toJsxRuntime } from "hast-util-to-jsx-runtime";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { JINJA_DOLLAR_PLACEHOLDER } from "../MarkdownEditor/editor/parser/constants";
|
|
3
|
+
import { JINJA_DOLLAR_PLACEHOLDER, preprocessNormalizeLeafToContainerDirective } from "../MarkdownEditor/editor/parser/constants";
|
|
4
4
|
import { buildEditorAlignedComponents, createHastProcessor } from "./markdownReactShared";
|
|
5
5
|
import { useStreamingMarkdownReact } from "./streaming/useStreamingMarkdownReact";
|
|
6
6
|
export var useMarkdownToReact = useStreamingMarkdownReact;
|
|
@@ -10,7 +10,7 @@ export var useMarkdownToReact = useStreamingMarkdownReact;
|
|
|
10
10
|
if (!content) return null;
|
|
11
11
|
try {
|
|
12
12
|
var processor = createHastProcessor(remarkPlugins, htmlConfig);
|
|
13
|
-
var preprocessed = content.replace(new RegExp(JINJA_DOLLAR_PLACEHOLDER, 'g'), '$');
|
|
13
|
+
var preprocessed = preprocessNormalizeLeafToContainerDirective(content.replace(new RegExp(JINJA_DOLLAR_PLACEHOLDER, 'g'), '$'));
|
|
14
14
|
var mdast = processor.parse(preprocessed);
|
|
15
15
|
var hast = processor.runSync(mdast);
|
|
16
16
|
var userComps = components || {};
|
|
@@ -652,20 +652,41 @@ import { debounce, getDataHash, isConfigEqual, isNotEmpty, toNumber } from "./ut
|
|
|
652
652
|
var _ref8;
|
|
653
653
|
var _config_rest10;
|
|
654
654
|
// 直方图数据转换:提取原始值
|
|
655
|
+
// 同时支持预分箱格式:groupKey.DIM_LEFT / groupKey.DIM_RIGHT + MEASURE_PROB[0].actualValue
|
|
655
656
|
var histogramData = (chartData || []).map(function(row) {
|
|
657
|
+
var _row_groupKey, _row_groupKey1, _row_MEASURE_PROB_;
|
|
658
|
+
var dimLeft = row === null || row === void 0 ? void 0 : (_row_groupKey = row.groupKey) === null || _row_groupKey === void 0 ? void 0 : _row_groupKey.DIM_LEFT;
|
|
659
|
+
var dimRight = row === null || row === void 0 ? void 0 : (_row_groupKey1 = row.groupKey) === null || _row_groupKey1 === void 0 ? void 0 : _row_groupKey1.DIM_RIGHT;
|
|
660
|
+
var measureProb = Array.isArray(row === null || row === void 0 ? void 0 : row.MEASURE_PROB) ? (_row_MEASURE_PROB_ = row.MEASURE_PROB[0]) === null || _row_MEASURE_PROB_ === void 0 ? void 0 : _row_MEASURE_PROB_.actualValue : undefined;
|
|
661
|
+
if (typeof dimLeft === 'number' && typeof dimRight === 'number' && typeof measureProb === 'number') {
|
|
662
|
+
var type = getFieldValue(row, colorLegend);
|
|
663
|
+
var category = getFieldValue(row, groupBy);
|
|
664
|
+
var filterLabel = getFieldValue(row, filterBy);
|
|
665
|
+
return _object_spread({
|
|
666
|
+
value: measureProb,
|
|
667
|
+
left: dimLeft,
|
|
668
|
+
right: dimRight
|
|
669
|
+
}, type ? {
|
|
670
|
+
type: type
|
|
671
|
+
} : {}, category ? {
|
|
672
|
+
category: category
|
|
673
|
+
} : {}, filterLabel ? {
|
|
674
|
+
filterLabel: filterLabel
|
|
675
|
+
} : {});
|
|
676
|
+
}
|
|
656
677
|
var value = getFieldValueSafely(row, config === null || config === void 0 ? void 0 : config.y);
|
|
657
|
-
var
|
|
658
|
-
var
|
|
659
|
-
var
|
|
678
|
+
var type1 = getFieldValue(row, colorLegend);
|
|
679
|
+
var category1 = getFieldValue(row, groupBy);
|
|
680
|
+
var filterLabel1 = getFieldValue(row, filterBy);
|
|
660
681
|
var numValue = typeof value === 'number' ? value : toNumber(value, Number.NaN);
|
|
661
682
|
return _object_spread({
|
|
662
683
|
value: Number.isFinite(numValue) ? numValue : 0
|
|
663
|
-
},
|
|
664
|
-
type:
|
|
665
|
-
} : {},
|
|
666
|
-
category:
|
|
667
|
-
} : {},
|
|
668
|
-
filterLabel:
|
|
684
|
+
}, type1 ? {
|
|
685
|
+
type: type1
|
|
686
|
+
} : {}, category1 ? {
|
|
687
|
+
category: category1
|
|
688
|
+
} : {}, filterLabel1 ? {
|
|
689
|
+
filterLabel: filterLabel1
|
|
669
690
|
} : {});
|
|
670
691
|
});
|
|
671
692
|
return /*#__PURE__*/ React.createElement(HistogramChart, {
|
|
@@ -476,8 +476,22 @@ import { useStyle } from "./style";
|
|
|
476
476
|
];
|
|
477
477
|
}
|
|
478
478
|
var hiddenSetForChart = hiddenDataIndicesByChart[idx] || new Set();
|
|
479
|
-
var
|
|
480
|
-
return
|
|
479
|
+
var visibleDataWithIndex = chartData.map(function(d, index) {
|
|
480
|
+
return {
|
|
481
|
+
d: d,
|
|
482
|
+
originalIndex: index
|
|
483
|
+
};
|
|
484
|
+
}).filter(function(param) {
|
|
485
|
+
var originalIndex = param.originalIndex;
|
|
486
|
+
return !hiddenSetForChart.has(originalIndex);
|
|
487
|
+
});
|
|
488
|
+
var visibleData = visibleDataWithIndex.map(function(param) {
|
|
489
|
+
var d = param.d;
|
|
490
|
+
return d;
|
|
491
|
+
});
|
|
492
|
+
var visibleOriginalIndices = visibleDataWithIndex.map(function(param) {
|
|
493
|
+
var originalIndex = param.originalIndex;
|
|
494
|
+
return originalIndex;
|
|
481
495
|
});
|
|
482
496
|
var toNum = function toNum(v) {
|
|
483
497
|
return typeof v === 'number' ? v : Number(v);
|
|
@@ -498,9 +512,9 @@ import { useStyle } from "./style";
|
|
|
498
512
|
return sum + (Number.isFinite(v) ? v : 0);
|
|
499
513
|
}, 0);
|
|
500
514
|
var backgroundColors = cfg.backgroundColor || defaultColorList;
|
|
501
|
-
// 解析 CSS 变量为实际颜色值(Canvas
|
|
502
|
-
var
|
|
503
|
-
return resolveCssVariable(
|
|
515
|
+
// 解析 CSS 变量为实际颜色值(Canvas 需要实际颜色值),按原始索引取色保证与图例颜色一致
|
|
516
|
+
var resolvedVisibleBackgroundColors = visibleOriginalIndices.map(function(originalIndex) {
|
|
517
|
+
return resolveCssVariable(backgroundColors[originalIndex % backgroundColors.length]);
|
|
504
518
|
});
|
|
505
519
|
var mainColor = (_ref = (_cfg_backgroundColor = cfg.backgroundColor) === null || _cfg_backgroundColor === void 0 ? void 0 : _cfg_backgroundColor[0]) !== null && _ref !== void 0 ? _ref : defaultColorList[idx % defaultColorList.length];
|
|
506
520
|
var resolvedMainColor = resolveCssVariable(mainColor);
|
|
@@ -557,12 +571,12 @@ import { useStyle } from "./style";
|
|
|
557
571
|
backgroundColor: isSingleValueMode ? [
|
|
558
572
|
resolvedMainColor,
|
|
559
573
|
'transparent'
|
|
560
|
-
] :
|
|
574
|
+
] : resolvedVisibleBackgroundColors.slice(0, values.length),
|
|
561
575
|
borderColor: chartBorderColor,
|
|
562
576
|
hoverBackgroundColor: isSingleValueMode ? [
|
|
563
577
|
resolvedMainColor,
|
|
564
578
|
'transparent'
|
|
565
|
-
] :
|
|
579
|
+
] : resolvedVisibleBackgroundColors.slice(0, values.length),
|
|
566
580
|
hoverBorderColor: chartHoverBorderColor,
|
|
567
581
|
borderWidth: cfg.chartStyle === 'pie' ? 0 : isMobile ? 1 : 1,
|
|
568
582
|
spacing: isSingleValueMode ? 0 : cfg.chartStyle === 'pie' ? 0 : isDarkTheme ? isMobile ? 4 : 8 : isMobile ? 3 : 6,
|
|
@@ -6,8 +6,12 @@ import type { ChartClassNames, ChartStyles } from '../types/classNames';
|
|
|
6
6
|
* 直方图数据项接口
|
|
7
7
|
*/
|
|
8
8
|
export interface HistogramChartDataItem {
|
|
9
|
-
/**
|
|
9
|
+
/** 原始数据值(自动分箱时为原始数值;预分箱时为该箱的 y 轴值) */
|
|
10
10
|
value: number;
|
|
11
|
+
/** 预分箱左边界(设置后与 right 一起跳过自动分箱) */
|
|
12
|
+
left?: number;
|
|
13
|
+
/** 预分箱右边界 */
|
|
14
|
+
right?: number;
|
|
11
15
|
/** 数据系列(用于分组显示) */
|
|
12
16
|
type?: string;
|
|
13
17
|
/** 分类(用于筛选) */
|
|
@@ -200,13 +200,18 @@ var histogramChartComponentsRegistered = false;
|
|
|
200
200
|
};
|
|
201
201
|
}
|
|
202
202
|
/**
|
|
203
|
-
*
|
|
203
|
+
* 格式化分箱标签,对超出范围的数字使用普通计数格式而非科学记数法
|
|
204
204
|
*/ function formatBinLabel(start, end) {
|
|
205
205
|
var formatNum = function formatNum(n) {
|
|
206
|
-
if (Math.abs(n)
|
|
207
|
-
return n.
|
|
206
|
+
if (Math.abs(n) < 0.01 && n !== 0) {
|
|
207
|
+
return n.toFixed(4);
|
|
208
208
|
}
|
|
209
|
-
|
|
209
|
+
if (Number.isInteger(n)) {
|
|
210
|
+
return n.toLocaleString('en-US', {
|
|
211
|
+
useGrouping: false
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return parseFloat(n.toFixed(2)).toString();
|
|
210
215
|
};
|
|
211
216
|
return "".concat(formatNum(start), " - ").concat(formatNum(end));
|
|
212
217
|
}
|
|
@@ -345,6 +350,14 @@ var HistogramChart = function HistogramChart(_0) {
|
|
|
345
350
|
}, [
|
|
346
351
|
filteredData
|
|
347
352
|
]);
|
|
353
|
+
// 判断是否为预分箱数据(所有项都有 left 和 right 字段)
|
|
354
|
+
var isPreBinned = useMemo(function() {
|
|
355
|
+
return filteredData.length > 0 && filteredData.every(function(item) {
|
|
356
|
+
return typeof item.left === 'number' && typeof item.right === 'number';
|
|
357
|
+
});
|
|
358
|
+
}, [
|
|
359
|
+
filteredData
|
|
360
|
+
]);
|
|
348
361
|
// 计算分箱
|
|
349
362
|
var binning = useMemo(function() {
|
|
350
363
|
if (filteredData.length === 0) {
|
|
@@ -354,24 +367,57 @@ var HistogramChart = function HistogramChart(_0) {
|
|
|
354
367
|
binCount: 0
|
|
355
368
|
};
|
|
356
369
|
}
|
|
370
|
+
if (isPreBinned) {
|
|
371
|
+
// 预分箱模式:按 left 排序,直接生成区间标签
|
|
372
|
+
var sorted = _to_consumable_array(filteredData).sort(function(a, b) {
|
|
373
|
+
return a.left - b.left;
|
|
374
|
+
});
|
|
375
|
+
var uniqueEdgePairs = sorted.reduce(function(acc, item) {
|
|
376
|
+
var l = item.left;
|
|
377
|
+
var r = item.right;
|
|
378
|
+
if (!acc.some(function(p) {
|
|
379
|
+
return p.left === l && p.right === r;
|
|
380
|
+
})) {
|
|
381
|
+
acc.push({
|
|
382
|
+
left: l,
|
|
383
|
+
right: r
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
return acc;
|
|
387
|
+
}, []);
|
|
388
|
+
var edges = _to_consumable_array(uniqueEdgePairs.map(function(p) {
|
|
389
|
+
return p.left;
|
|
390
|
+
})).concat([
|
|
391
|
+
uniqueEdgePairs[uniqueEdgePairs.length - 1].right
|
|
392
|
+
]);
|
|
393
|
+
var labels = uniqueEdgePairs.map(function(p) {
|
|
394
|
+
return formatBinLabel(p.left, p.right);
|
|
395
|
+
});
|
|
396
|
+
return {
|
|
397
|
+
edges: edges,
|
|
398
|
+
labels: labels,
|
|
399
|
+
binCount: labels.length
|
|
400
|
+
};
|
|
401
|
+
}
|
|
357
402
|
var allValues = filteredData.map(function(item) {
|
|
358
403
|
return item.value;
|
|
359
404
|
});
|
|
360
405
|
var autoBinCount = customBinCount || calculateBinCount(allValues.length);
|
|
361
|
-
var
|
|
406
|
+
var edges1 = calculateBinEdges(allValues, autoBinCount).edges;
|
|
362
407
|
// 生成分箱标签
|
|
363
|
-
var
|
|
364
|
-
for(var i = 0; i <
|
|
365
|
-
|
|
408
|
+
var labels1 = [];
|
|
409
|
+
for(var i = 0; i < edges1.length - 1; i++){
|
|
410
|
+
labels1.push(formatBinLabel(edges1[i], edges1[i + 1]));
|
|
366
411
|
}
|
|
367
412
|
return {
|
|
368
|
-
edges:
|
|
369
|
-
labels:
|
|
413
|
+
edges: edges1,
|
|
414
|
+
labels: labels1,
|
|
370
415
|
binCount: autoBinCount
|
|
371
416
|
};
|
|
372
417
|
}, [
|
|
373
418
|
filteredData,
|
|
374
|
-
customBinCount
|
|
419
|
+
customBinCount,
|
|
420
|
+
isPreBinned
|
|
375
421
|
]);
|
|
376
422
|
// 计算每个分箱的频率/计数
|
|
377
423
|
var histogramData = useMemo(function() {
|
|
@@ -380,6 +426,26 @@ var HistogramChart = function HistogramChart(_0) {
|
|
|
380
426
|
return {};
|
|
381
427
|
}
|
|
382
428
|
var result = {};
|
|
429
|
+
if (isPreBinned) {
|
|
430
|
+
// 预分箱模式:直接将 value 映射到对应区间
|
|
431
|
+
types.forEach(function(type) {
|
|
432
|
+
if (!type) return;
|
|
433
|
+
var typeData = filteredData.filter(function(item) {
|
|
434
|
+
return (item.type || '默认') === type;
|
|
435
|
+
});
|
|
436
|
+
var counts = new Array(labels.length).fill(0);
|
|
437
|
+
typeData.forEach(function(item) {
|
|
438
|
+
var l = item.left;
|
|
439
|
+
var r = item.right;
|
|
440
|
+
var idx = labels.indexOf(formatBinLabel(l, r));
|
|
441
|
+
if (idx !== -1) {
|
|
442
|
+
counts[idx] += showFrequency ? item.value : item.value;
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
result[type] = counts;
|
|
446
|
+
});
|
|
447
|
+
return result;
|
|
448
|
+
}
|
|
383
449
|
types.forEach(function(type) {
|
|
384
450
|
if (!type) return; // Skip undefined types
|
|
385
451
|
var typeData = filteredData.filter(function(item) {
|
|
@@ -411,7 +477,8 @@ var HistogramChart = function HistogramChart(_0) {
|
|
|
411
477
|
filteredData,
|
|
412
478
|
types,
|
|
413
479
|
binning,
|
|
414
|
-
showFrequency
|
|
480
|
+
showFrequency,
|
|
481
|
+
isPreBinned
|
|
415
482
|
]);
|
|
416
483
|
// 构建 Chart.js 数据结构
|
|
417
484
|
var processedData = useMemo(function() {
|
|
@@ -58,6 +58,14 @@ export interface ScatterChartProps extends ChartContainerProps {
|
|
|
58
58
|
loading?: boolean;
|
|
59
59
|
/** 自定义样式对象(支持对象格式,为每层DOM设置样式) */
|
|
60
60
|
styles?: ChartStyles;
|
|
61
|
+
/** X 轴最小值,不传则从数据自动计算 */
|
|
62
|
+
xMin?: number;
|
|
63
|
+
/** X 轴最大值,不传则从数据自动计算 */
|
|
64
|
+
xMax?: number;
|
|
65
|
+
/** Y 轴最小值,不传则从数据自动计算 */
|
|
66
|
+
yMin?: number;
|
|
67
|
+
/** Y 轴最大值,不传则从数据自动计算 */
|
|
68
|
+
yMax?: number;
|
|
61
69
|
}
|
|
62
70
|
declare const ScatterChart: React.FC<ScatterChartProps>;
|
|
63
71
|
export default ScatterChart;
|
|
@@ -6,6 +6,9 @@ function _array_like_to_array(arr, len) {
|
|
|
6
6
|
function _array_with_holes(arr) {
|
|
7
7
|
if (Array.isArray(arr)) return arr;
|
|
8
8
|
}
|
|
9
|
+
function _array_without_holes(arr) {
|
|
10
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
11
|
+
}
|
|
9
12
|
function _define_property(obj, key, value) {
|
|
10
13
|
if (key in obj) {
|
|
11
14
|
Object.defineProperty(obj, key, {
|
|
@@ -19,6 +22,9 @@ function _define_property(obj, key, value) {
|
|
|
19
22
|
}
|
|
20
23
|
return obj;
|
|
21
24
|
}
|
|
25
|
+
function _iterable_to_array(iter) {
|
|
26
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
27
|
+
}
|
|
22
28
|
function _iterable_to_array_limit(arr, i) {
|
|
23
29
|
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
24
30
|
if (_i == null) return;
|
|
@@ -46,6 +52,9 @@ function _iterable_to_array_limit(arr, i) {
|
|
|
46
52
|
function _non_iterable_rest() {
|
|
47
53
|
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
48
54
|
}
|
|
55
|
+
function _non_iterable_spread() {
|
|
56
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
57
|
+
}
|
|
49
58
|
function _object_spread(target) {
|
|
50
59
|
for(var i = 1; i < arguments.length; i++){
|
|
51
60
|
var source = arguments[i] != null ? arguments[i] : {};
|
|
@@ -124,6 +133,9 @@ function _object_without_properties_loose(source, excluded) {
|
|
|
124
133
|
function _sliced_to_array(arr, i) {
|
|
125
134
|
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
126
135
|
}
|
|
136
|
+
function _to_consumable_array(arr) {
|
|
137
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
138
|
+
}
|
|
127
139
|
function _type_of(obj) {
|
|
128
140
|
"@swc/helpers - typeof";
|
|
129
141
|
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
@@ -149,7 +161,7 @@ import { hexToRgba, resolveCssVariable } from "../utils";
|
|
|
149
161
|
import { useStyle } from "./style";
|
|
150
162
|
var scatterChartComponentsRegistered = false;
|
|
151
163
|
var ScatterChart = function ScatterChart(_0) {
|
|
152
|
-
var data = _0.data, _0_width = _0.width, width = _0_width === void 0 ? 600 : _0_width, _0_height = _0.height, height = _0_height === void 0 ? 400 : _0_height, className = _0.className, classNamesProp = _0.classNames, title = _0.title, toolbarExtra = _0.toolbarExtra, _0_renderFilterInToolbar = _0.renderFilterInToolbar, renderFilterInToolbar = _0_renderFilterInToolbar === void 0 ? false : _0_renderFilterInToolbar, dataTime = _0.dataTime, _0_xUnit = _0.xUnit, xUnit = _0_xUnit === void 0 ? '月' : _0_xUnit, yUnit = _0.yUnit, xAxisLabel = _0.xAxisLabel, yAxisLabel = _0.yAxisLabel, _0_xPosition = _0.xPosition, xPosition = _0_xPosition === void 0 ? 'bottom' : _0_xPosition, _0_yPosition = _0.yPosition, yPosition = _0_yPosition === void 0 ? 'left' : _0_yPosition, _0_hiddenX = _0.hiddenX, hiddenX = _0_hiddenX === void 0 ? false : _0_hiddenX, _0_hiddenY = _0.hiddenY, hiddenY = _0_hiddenY === void 0 ? false : _0_hiddenY, _0_showGrid = _0.showGrid, showGrid = _0_showGrid === void 0 ? true : _0_showGrid, _0_theme = _0.theme, theme = _0_theme === void 0 ? 'light' : _0_theme, color = _0.color, statisticConfig = _0.statistic, _0_textMaxWidth = _0.textMaxWidth, textMaxWidth = _0_textMaxWidth === void 0 ? 80 : _0_textMaxWidth, _0_loading = _0.loading, loading = _0_loading === void 0 ? false : _0_loading, props = _object_without_properties(_0, [
|
|
164
|
+
var data = _0.data, _0_width = _0.width, width = _0_width === void 0 ? 600 : _0_width, _0_height = _0.height, height = _0_height === void 0 ? 400 : _0_height, className = _0.className, classNamesProp = _0.classNames, title = _0.title, toolbarExtra = _0.toolbarExtra, _0_renderFilterInToolbar = _0.renderFilterInToolbar, renderFilterInToolbar = _0_renderFilterInToolbar === void 0 ? false : _0_renderFilterInToolbar, dataTime = _0.dataTime, _0_xUnit = _0.xUnit, xUnit = _0_xUnit === void 0 ? '月' : _0_xUnit, yUnit = _0.yUnit, xAxisLabel = _0.xAxisLabel, yAxisLabel = _0.yAxisLabel, _0_xPosition = _0.xPosition, xPosition = _0_xPosition === void 0 ? 'bottom' : _0_xPosition, _0_yPosition = _0.yPosition, yPosition = _0_yPosition === void 0 ? 'left' : _0_yPosition, _0_hiddenX = _0.hiddenX, hiddenX = _0_hiddenX === void 0 ? false : _0_hiddenX, _0_hiddenY = _0.hiddenY, hiddenY = _0_hiddenY === void 0 ? false : _0_hiddenY, _0_showGrid = _0.showGrid, showGrid = _0_showGrid === void 0 ? true : _0_showGrid, _0_theme = _0.theme, theme = _0_theme === void 0 ? 'light' : _0_theme, color = _0.color, statisticConfig = _0.statistic, _0_textMaxWidth = _0.textMaxWidth, textMaxWidth = _0_textMaxWidth === void 0 ? 80 : _0_textMaxWidth, _0_loading = _0.loading, loading = _0_loading === void 0 ? false : _0_loading, xMinProp = _0.xMin, xMaxProp = _0.xMax, yMinProp = _0.yMin, yMaxProp = _0.yMax, props = _object_without_properties(_0, [
|
|
153
165
|
"data",
|
|
154
166
|
"width",
|
|
155
167
|
"height",
|
|
@@ -172,7 +184,11 @@ var ScatterChart = function ScatterChart(_0) {
|
|
|
172
184
|
"color",
|
|
173
185
|
"statistic",
|
|
174
186
|
"textMaxWidth",
|
|
175
|
-
"loading"
|
|
187
|
+
"loading",
|
|
188
|
+
"xMin",
|
|
189
|
+
"xMax",
|
|
190
|
+
"yMin",
|
|
191
|
+
"yMax"
|
|
176
192
|
]);
|
|
177
193
|
useMemo(function() {
|
|
178
194
|
if (scatterChartComponentsRegistered) {
|
|
@@ -304,6 +320,60 @@ var ScatterChart = function ScatterChart(_0) {
|
|
|
304
320
|
}
|
|
305
321
|
}, "暂无有效数据")));
|
|
306
322
|
}
|
|
323
|
+
// 从数据中自动计算坐标轴范围,加 10% 边距,方便查看边界点
|
|
324
|
+
var computeAxisBounds = function computeAxisBounds(values, overrideMin, overrideMax, fallbackMin, fallbackMax) {
|
|
325
|
+
var _Math, _Math1;
|
|
326
|
+
if (overrideMin !== undefined && overrideMax !== undefined) {
|
|
327
|
+
return {
|
|
328
|
+
min: overrideMin,
|
|
329
|
+
max: overrideMax
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
if (values.length === 0) {
|
|
333
|
+
return {
|
|
334
|
+
min: fallbackMin,
|
|
335
|
+
max: fallbackMax
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
var dataMin = (_Math = Math).min.apply(_Math, _to_consumable_array(values));
|
|
339
|
+
var dataMax = (_Math1 = Math).max.apply(_Math1, _to_consumable_array(values));
|
|
340
|
+
var range = dataMax - dataMin || 1;
|
|
341
|
+
var padding = range * 0.1;
|
|
342
|
+
return {
|
|
343
|
+
min: overrideMin !== undefined ? overrideMin : Math.floor(dataMin - padding),
|
|
344
|
+
max: overrideMax !== undefined ? overrideMax : Math.ceil(dataMax + padding)
|
|
345
|
+
};
|
|
346
|
+
};
|
|
347
|
+
var allXValues = filteredData.map(function(item) {
|
|
348
|
+
var v = typeof item.x === 'number' ? item.x : Number(item.x);
|
|
349
|
+
return Number.isFinite(v) ? v : null;
|
|
350
|
+
}).filter(function(v) {
|
|
351
|
+
return v !== null;
|
|
352
|
+
});
|
|
353
|
+
var allYValues = filteredData.map(function(item) {
|
|
354
|
+
var v = typeof item.y === 'number' ? item.y : Number(item.y);
|
|
355
|
+
return Number.isFinite(v) ? v : null;
|
|
356
|
+
}).filter(function(v) {
|
|
357
|
+
return v !== null;
|
|
358
|
+
});
|
|
359
|
+
var xBounds = computeAxisBounds(allXValues, xMinProp, xMaxProp, 1, 12);
|
|
360
|
+
var yBounds = computeAxisBounds(allYValues, yMinProp, yMaxProp, 0, 100);
|
|
361
|
+
var computeStepSize = function computeStepSize(min, max) {
|
|
362
|
+
var targetTicks = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 10;
|
|
363
|
+
var range = max - min;
|
|
364
|
+
if (range <= 0) return 1;
|
|
365
|
+
var rawStep = range / targetTicks;
|
|
366
|
+
var magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));
|
|
367
|
+
var normalized = rawStep / magnitude;
|
|
368
|
+
var step;
|
|
369
|
+
if (normalized <= 1) step = magnitude;
|
|
370
|
+
else if (normalized <= 2) step = 2 * magnitude;
|
|
371
|
+
else if (normalized <= 5) step = 5 * magnitude;
|
|
372
|
+
else step = 10 * magnitude;
|
|
373
|
+
return step;
|
|
374
|
+
};
|
|
375
|
+
var xStepSize = computeStepSize(xBounds.min, xBounds.max);
|
|
376
|
+
var yStepSize = computeStepSize(yBounds.min, yBounds.max);
|
|
307
377
|
// 构建数据集,添加更强的安全检查
|
|
308
378
|
var datasets = datasetTypes.map(function(type, index) {
|
|
309
379
|
var typeData = filteredData.filter(function(item) {
|
|
@@ -546,10 +616,10 @@ var ScatterChart = function ScatterChart(_0) {
|
|
|
546
616
|
weight: 500
|
|
547
617
|
}
|
|
548
618
|
},
|
|
549
|
-
min:
|
|
550
|
-
max:
|
|
619
|
+
min: xBounds.min,
|
|
620
|
+
max: xBounds.max,
|
|
551
621
|
ticks: {
|
|
552
|
-
stepSize:
|
|
622
|
+
stepSize: xStepSize,
|
|
553
623
|
color: axisTextColor,
|
|
554
624
|
font: {
|
|
555
625
|
size: isMobile ? 8 : 10
|
|
@@ -579,10 +649,10 @@ var ScatterChart = function ScatterChart(_0) {
|
|
|
579
649
|
},
|
|
580
650
|
align: 'center'
|
|
581
651
|
},
|
|
582
|
-
min:
|
|
583
|
-
max:
|
|
652
|
+
min: yBounds.min,
|
|
653
|
+
max: yBounds.max,
|
|
584
654
|
ticks: {
|
|
585
|
-
stepSize:
|
|
655
|
+
stepSize: yStepSize,
|
|
586
656
|
color: axisTextColor,
|
|
587
657
|
font: {
|
|
588
658
|
family: 'PingFang SC',
|
|
@@ -351,6 +351,8 @@ declare class ChartErrorBoundary extends React.Component<ChartErrorBoundaryProps
|
|
|
351
351
|
'suggestion.select': string;
|
|
352
352
|
'suggestion.followUp': string;
|
|
353
353
|
'input.fileUpload': string;
|
|
354
|
+
'input.attachmentListTitle': string;
|
|
355
|
+
'chat.fileMapTitle': string;
|
|
354
356
|
'input.voiceInput': string;
|
|
355
357
|
'input.voiceInputting': string;
|
|
356
358
|
'input.placeholder': string;
|
|
@@ -745,6 +747,8 @@ declare class ChartErrorBoundary extends React.Component<ChartErrorBoundaryProps
|
|
|
745
747
|
'suggestion.select': string;
|
|
746
748
|
'suggestion.followUp': string;
|
|
747
749
|
'input.fileUpload': string;
|
|
750
|
+
'input.attachmentListTitle': string;
|
|
751
|
+
'chat.fileMapTitle': string;
|
|
748
752
|
'input.voiceInput': string;
|
|
749
753
|
'input.voiceInputting': string;
|
|
750
754
|
'input.placeholder': string;
|