@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.
Files changed (51) hide show
  1. package/dist/Bubble/AIBubble.js +32 -18
  2. package/dist/Bubble/ContentFilemapView.d.ts +14 -0
  3. package/dist/Bubble/ContentFilemapView.js +95 -0
  4. package/dist/Bubble/MessagesContent/MarkdownPreview.js +3 -2
  5. package/dist/Bubble/UserBubble.js +48 -6
  6. package/dist/Bubble/extractFilemapBlocks.d.ts +17 -0
  7. package/dist/Bubble/extractFilemapBlocks.js +23 -0
  8. package/dist/Bubble/type.d.ts +3 -0
  9. package/dist/Hooks/useLanguage.d.ts +2 -0
  10. package/dist/I18n/locales.d.ts +2 -0
  11. package/dist/I18n/locales.js +5 -1
  12. package/dist/MarkdownEditor/editor/elements/AgenticUiBlocks/agenticUiEmbedUtils.d.ts +5 -1
  13. package/dist/MarkdownEditor/editor/elements/AgenticUiBlocks/agenticUiEmbedUtils.js +10 -2
  14. package/dist/MarkdownEditor/editor/elements/Code/index.js +22 -14
  15. package/dist/MarkdownEditor/editor/parser/constants.d.ts +10 -0
  16. package/dist/MarkdownEditor/editor/parser/constants.js +46 -0
  17. package/dist/MarkdownEditor/editor/parser/parserMarkdownToSlateNode.js +3 -1
  18. package/dist/MarkdownEditor/editor/parser/parserSlateNodeToMarkdown.js +11 -0
  19. package/dist/MarkdownEditor/editor/utils/markdownToHtml.js +6 -4
  20. package/dist/MarkdownEditor/types.d.ts +6 -0
  21. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileIcon.js +3 -1
  22. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.js +2 -2
  23. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/index.js +6 -1
  24. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/style.js +11 -1
  25. package/dist/MarkdownInputField/AttachmentButton/index.d.ts +12 -0
  26. package/dist/MarkdownInputField/AttachmentButton/index.js +23 -13
  27. package/dist/MarkdownInputField/FileMapView/FileMapViewItem.js +20 -1
  28. package/dist/MarkdownInputField/FileMapView/index.d.ts +13 -1
  29. package/dist/MarkdownInputField/FileMapView/index.js +57 -18
  30. package/dist/MarkdownInputField/FileMapView/style.js +6 -0
  31. package/dist/MarkdownInputField/FileUploadManager/index.js +4 -26
  32. package/dist/MarkdownInputField/style.js +7 -0
  33. package/dist/MarkdownRenderer/MarkdownRenderer.js +10 -6
  34. package/dist/MarkdownRenderer/index.d.ts +1 -1
  35. package/dist/MarkdownRenderer/renderers/AgenticUiFileMapBlockRenderer.d.ts +4 -2
  36. package/dist/MarkdownRenderer/renderers/AgenticUiFileMapBlockRenderer.js +47 -5
  37. package/dist/MarkdownRenderer/renderers/ChartRenderer.js +9 -0
  38. package/dist/MarkdownRenderer/streaming/useStreamingMarkdownReact.js +2 -2
  39. package/dist/MarkdownRenderer/types.d.ts +45 -2
  40. package/dist/MarkdownRenderer/useMarkdownToReact.js +2 -2
  41. package/dist/Plugins/chart/ChartRender.js +30 -9
  42. package/dist/Plugins/chart/DonutChart/index.js +21 -7
  43. package/dist/Plugins/chart/HistogramChart/index.d.ts +5 -1
  44. package/dist/Plugins/chart/HistogramChart/index.js +79 -12
  45. package/dist/Plugins/chart/ScatterChart/index.d.ts +8 -0
  46. package/dist/Plugins/chart/ScatterChart/index.js +78 -8
  47. package/dist/Plugins/chart/components/ChartContainer/ChartErrorBoundary.d.ts +4 -0
  48. package/dist/Plugins/code/components/AceEditor.js +69 -8
  49. package/dist/Plugins/code/components/CodeRenderer.js +0 -1
  50. package/dist/Workspace/Browser/index.js +3 -1
  51. 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(props.children);
70
+ return extractTextContent(rest.children);
32
71
  }, [
33
- props.children
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
- * markdown 渲染模式下传给 eleRender 的元素属性,
6
- * 包含 HTML 标签名、hast 节点及所有原生 HTML 属性。
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 type = getFieldValue(row, colorLegend);
658
- var category = getFieldValue(row, groupBy);
659
- var filterLabel = getFieldValue(row, filterBy);
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
- }, type ? {
664
- type: type
665
- } : {}, category ? {
666
- category: category
667
- } : {}, filterLabel ? {
668
- filterLabel: 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 visibleData = chartData.filter(function(_, index) {
480
- return !hiddenSetForChart.has(index);
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 resolvedBackgroundColors = backgroundColors.map(function(color) {
503
- return resolveCssVariable(color);
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
- ] : resolvedBackgroundColors.slice(0, values.length),
574
+ ] : resolvedVisibleBackgroundColors.slice(0, values.length),
561
575
  borderColor: chartBorderColor,
562
576
  hoverBackgroundColor: isSingleValueMode ? [
563
577
  resolvedMainColor,
564
578
  'transparent'
565
- ] : resolvedBackgroundColors.slice(0, values.length),
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) >= 1000 || Math.abs(n) < 0.01 && n !== 0) {
207
- return n.toExponential(1);
206
+ if (Math.abs(n) < 0.01 && n !== 0) {
207
+ return n.toFixed(4);
208
208
  }
209
- return n.toFixed(2);
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 edges = calculateBinEdges(allValues, autoBinCount).edges;
406
+ var edges1 = calculateBinEdges(allValues, autoBinCount).edges;
362
407
  // 生成分箱标签
363
- var labels = [];
364
- for(var i = 0; i < edges.length - 1; i++){
365
- labels.push(formatBinLabel(edges[i], edges[i + 1]));
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: edges,
369
- labels: 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: 1,
550
- max: 12,
619
+ min: xBounds.min,
620
+ max: xBounds.max,
551
621
  ticks: {
552
- stepSize: 1,
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: 0,
583
- max: 100,
652
+ min: yBounds.min,
653
+ max: yBounds.max,
584
654
  ticks: {
585
- stepSize: 10,
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;