-
Notifications
You must be signed in to change notification settings - Fork 219
feat: support area enlargement (linear axis custom distribution) #4441
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
xuefei1313
wants to merge
7
commits into
develop
Choose a base branch
from
003-area-enlargement
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
231fe75
feat: support area enlargement (linear axis custom distribution)
xuefei1313 401ced3
feat: add documents of customDistribution
xuefei1313 b8361fc
feat: optimiz with comment
xuefei1313 3c7c04d
feat: support area enlargement (linear axis custom distribution)
xuefei1313 27dd0ac
feat: support area enlargement (linear axis custom distribution)
xuefei1313 910e270
feat: merge the breaks capability into piecewise
xuefei1313 a27dd0d
feat: optimiz breaks in domain
xuefei1313 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| # VChart 项目规则 for TRAE | ||
|
|
||
| 为了确保在 VChart Monorepo 环境中高效、正确地执行任务,你(TRAE 智能体)必须遵循以下规则。 | ||
|
|
||
| ## 核心规则 | ||
|
|
||
| 1. **【禁止】直接运行通用测试命令** | ||
| - **禁止**在仓库的**任何目录**(尤其是根目录)下,直接执行 `npm test`, `pnpm test`, `yarn test`, `npx jest`, `npm run test` 等通用测试命令。这些命令会因缺少 Monorepo 上下文而失败。 | ||
|
|
||
| 2. **【必须】使用 Rush 执行测试** | ||
| - 如需执行测试,**必须**使用 `rush` 命令,并在指定包的上下文中进行。 | ||
| - **标准命令格式**: `rush run -p <package-name> -s test` | ||
| - **示例**: `rush run -p @visactor/vchart -s test` | ||
| - **测试特定文件**: 如需测试单个文件,**必须**使用 `--` 将文件路径作为参数传递。 | ||
| - **示例**: `rush run -p @visactor/vchart -s test -- __tests__/unit/some.test.ts` | ||
|
|
||
| 3. **【应该】在明确指示时才运行测试** | ||
| - **默认禁止**自动运行任何测试。只在我明确要求“运行测试”、“验证代码”或类似指令时,才执行测试流程。 | ||
|
|
||
| 4. **【必须】使用 Rush 管理依赖与构建** | ||
| - **依赖安装**: **必须**只使用 `rush install` 命令。 | ||
| - **项目构建**: 如需构建,**必须**使用 `rush build`。可以配合 `-p <package-name>` 参数指定构建目标。 | ||
|
|
||
| 5. **【应该】在不确定时提问** | ||
| - 如果不确定**包名** (`@visactor/vchart` 是否正确)、**测试文件路径**、或**是否需要构建**,**应该**先向我提问确认,而不是自行猜测。 | ||
|
|
||
| 6. **【必须】提供详细的失败报告** | ||
| - 如果任何命令执行失败,**必须**向我汇报以下信息: | ||
| - **Node.js 版本**: (`node -v` 的输出) | ||
| - **执行的完整命令**: (例如: `rush run -p @visactor/vchart ...`) | ||
| - **执行目录**: (确认是在项目根目录) | ||
| - **退出码 (Exit Code)**: (如果可用) | ||
| - **关键日志片段**: (包含 `ERROR`, `FAIL` 或堆栈跟踪的核心部分) | ||
|
|
||
| ## Auto Run 黑名单建议 | ||
|
|
||
| 为了防止智能体在 `SOLO` 或 `Builder` 模式下自动执行错误的测试命令,建议项目管理员或用户在 TRAE 的设置中采取以下措施: | ||
|
|
||
| - **选项一 (推荐)**: 在智能体的 "Auto Run" 配置中,将以下命令前缀**加入黑名单**: | ||
| - `npm test` | ||
| - `pnpm test` | ||
| - `yarn test` | ||
| - `npx jest` | ||
|
|
||
| - **选项二**: 直接**关闭 "Auto Run" 功能**,所有由 AI 生成的命令都需要用户手动点击“运行”来确认。 | ||
|
|
||
| 采纳这些建议可以有效避免因环境不匹配导致的自动测试失败,提升协作效率。 |
5 changes: 5 additions & 0 deletions
5
.trae/specs/refactor-axis-breaks-to-custom-distribution/checklist.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| - [ ] `computeLinearDomain` 中优先判断 `customDistribution` | ||
| - [ ] `computeLinearDomain` 中正确将 `breaks` 转换为 `customDistribution` 格式 | ||
| - [ ] `getNewScaleRange` 中移除 `breaks` 逻辑 | ||
| - [ ] 验证仅配置 `breaks` 时,坐标轴断点效果正常 | ||
| - [ ] 验证同时配置 `breaks` 和 `customDistribution` 时,`breaks` 不生效 |
40 changes: 40 additions & 0 deletions
40
.trae/specs/refactor-axis-breaks-to-custom-distribution/spec.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| # 优化坐标轴 Breaks 和 CustomDistribution 逻辑 | ||
|
|
||
| ## Why | ||
| 目前的 `breaks` 和 `customDistribution` 是两套独立的逻辑,虽然都用于控制坐标轴的分布,但缺乏统一性。`customDistribution` 功能更通用,应该能够包含 `breaks` 的场景。通过将 `breaks` 转化为 `customDistribution`,可以简化代码逻辑,并明确两者的优先级关系。 | ||
|
|
||
| ## What Changes | ||
| 1. **优先级调整**:明确 `customDistribution` 的优先级高于 `breaks`。当用户配置了 `customDistribution` 时,忽略 `breaks` 配置。 | ||
| 2. **统一实现**:不再独立处理 `breaks` 的逻辑,而是将其转换为 `customDistribution` 的配置(`domain` 和 `ratio`),复用 `customDistribution` 的处理流程。 | ||
| 3. **代码重构**: | ||
| - 在 `linear-axis-mixin.ts` 的 `computeLinearDomain` 方法中,如果存在 `breaks` 且无 `customDistribution`,则调用 `breakData` 计算分段,并将结果转换为 `customDistribution` 格式。 | ||
| - 在 `linear-axis.ts` 的 `getNewScaleRange` 方法中,移除独立的 `breaks` 处理逻辑,完全依赖 `customDistribution`。 | ||
|
|
||
| ## Impact | ||
| - **Affected Specs**: `IAxis` 接口虽然不变,但在运行时 `breaks` 的表现将通过 `customDistribution` 实现。 | ||
| - **Affected Code**: | ||
| - `packages/vchart/src/component/axis/mixin/linear-axis-mixin.ts` | ||
| - `packages/vchart/src/component/axis/cartesian/linear-axis.ts` | ||
| - **Breaking Changes**: 无。对于仅使用 `breaks` 的用户,表现应保持一致。对于同时配置了 `breaks` 和 `customDistribution` 的用户,现在明确以 `customDistribution` 为准(此前行为可能未定义或混合)。 | ||
|
|
||
| ## ADDED Requirements | ||
| ### Requirement: CustomDistribution Priority | ||
| 系统 SHALL 优先使用 `customDistribution` 配置。 | ||
|
|
||
| #### Scenario: Both Configured | ||
| - **WHEN** 用户同时配置了 `breaks` 和 `customDistribution` | ||
| - **THEN** 系统忽略 `breaks` 配置,仅应用 `customDistribution`。 | ||
|
|
||
| ### Requirement: Breaks as CustomDistribution | ||
| 系统 SHALL 将 `breaks` 配置转换为 `customDistribution` 配置。 | ||
|
|
||
| #### Scenario: Only Breaks Configured | ||
| - **WHEN** 用户仅配置了 `breaks` | ||
| - **THEN** 系统计算断点分段,生成对应的 `domain` 和 `ratio`,并应用 `customDistribution` 逻辑。 | ||
|
|
||
| ## MODIFIED Requirements | ||
| ### Requirement: Linear Domain Computation | ||
| 修改 `computeLinearDomain` 方法,整合 `breaks` 到 `customDistribution` 的转换逻辑。 | ||
|
|
||
| ### Requirement: Scale Range Computation | ||
| 修改 `getNewScaleRange` 方法,移除对 `breaks` 的独立处理。 |
11 changes: 11 additions & 0 deletions
11
.trae/specs/refactor-axis-breaks-to-custom-distribution/tasks.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # Tasks | ||
| - [ ] Task 1: 重构 `linear-axis-mixin.ts` 中的 `computeLinearDomain` 方法 | ||
| - [ ] SubTask 1.1: 优先判断 `customDistribution`,若存在则跳过 `breaks` 处理 | ||
| - [ ] SubTask 1.2: 仅在无 `customDistribution` 且有 `breaks` 时,计算断点数据 | ||
| - [ ] SubTask 1.3: 将 `breaks` 的计算结果(`breakDomains` 和 `breakScopes`)转换为 `customDistribution` 的 `domain` 和 `ratio` | ||
| - [ ] Task 2: 重构 `linear-axis.ts` 中的 `getNewScaleRange` 方法 | ||
| - [ ] SubTask 2.1: 移除 `getNewScaleRange` 中对 `breaks` 的独立判断逻辑 | ||
| - [ ] SubTask 2.2: 确保 `customDistribution` 逻辑能正确处理从 `breaks` 转换来的配置(包含间隙) | ||
| - [ ] Task 3: 验证修改 | ||
| - [ ] SubTask 3.1: 验证 `breaks` 独立配置是否正常工作 | ||
| - [ ] SubTask 3.2: 验证 `customDistribution` 优先级是否高于 `breaks` |
11 changes: 11 additions & 0 deletions
11
common/changes/@visactor/vchart/feat-area-enlargement.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "changes": [ | ||
| { | ||
| "packageName": "@visactor/vchart", | ||
| "comment": "feat: support area enlargement (linear axis custom distribution)", | ||
| "type": "minor" | ||
| } | ||
| ], | ||
| "packageName": "@visactor/vchart", | ||
| "email": "lixuef1313@163.com" | ||
| } |
39 changes: 39 additions & 0 deletions
39
docs/assets/demos/builtin-theme/charts/area-enlargement.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import { IChartInfo } from './interface'; | ||
|
|
||
| const spec = { | ||
| type: 'line', | ||
| data: [ | ||
| { | ||
| id: 'line', | ||
| values: [ | ||
| { x: '1', y: 1 }, | ||
| { x: '2', y: 5 }, | ||
| { x: '3', y: 7 }, | ||
| { x: '4', y: 8 }, | ||
| { x: '5', y: 8.5 }, | ||
| { x: '6', y: 9 }, | ||
| { x: '7', y: 9.5 }, | ||
| { x: '8', y: 10 } | ||
| ] | ||
| } | ||
| ], | ||
| xField: 'x', | ||
| yField: 'y', | ||
| axes: [ | ||
| { | ||
| orient: 'left', | ||
| type: 'linear', | ||
| customDistribution: { | ||
| domain: [0, 7, 9, 10], | ||
| ratio: [0.2, 0.6, 0.2] | ||
| } | ||
| } | ||
| ] | ||
| }; | ||
|
|
||
| const areaEnlargement: IChartInfo = { | ||
| name: 'Area Enlargement', | ||
| spec | ||
| }; | ||
|
|
||
| export default areaEnlargement; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
142 changes: 142 additions & 0 deletions
142
packages/vchart/__tests__/unit/component/cartesian/axis/linear-axis-piecewise.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| import { GlobalScale } from '../../../../../src/scale/global-scale'; | ||
| import { DataSet, csvParser } from '@visactor/vdataset'; | ||
| import { dimensionStatistics } from '../../../../../src/data/transforms/dimension-statistics'; | ||
| import type { CartesianLinearAxis } from '../../../../../src/index'; | ||
| // eslint-disable-next-line no-duplicate-imports | ||
| import { CartesianAxis } from '../../../../../src/index'; | ||
| import { ComponentTypeEnum, type IComponent, type IComponentOption } from '../../../../../src/component/interface'; | ||
| import { EventDispatcher } from '../../../../../src/event/event-dispatcher'; | ||
| import { getTestCompiler } from '../../../../util/factory/compiler'; | ||
| import { getTheme, initChartDataSet } from '../../../../util/context'; | ||
| import { getCartesianAxisInfo } from '../../../../../src/component/axis/cartesian/util'; | ||
|
|
||
| const dataSet = new DataSet(); | ||
| initChartDataSet(dataSet); | ||
| dataSet.registerParser('csv', csvParser); | ||
| dataSet.registerTransform('dimensionStatistics', dimensionStatistics); | ||
|
|
||
| const ctx: IComponentOption = { | ||
| type: ComponentTypeEnum.cartesianLinearAxis, | ||
| eventDispatcher: new EventDispatcher({} as any, { addEventListener: () => {} } as any) as any, | ||
| dataSet, | ||
| map: new Map(), | ||
| mode: 'desktop-browser', | ||
| globalInstance: { | ||
| isAnimationEnable: () => true, | ||
| getContainer: () => ({}), | ||
| getTooltipHandlerByUser: (() => undefined) as () => undefined | ||
| } as any, | ||
| getCompiler: getTestCompiler, | ||
| getAllRegions: () => [], | ||
| getRegionsInIndex: () => [], | ||
| getChart: () => ({ getSpec: () => ({}) } as any), | ||
| getRegionsInIds: () => [], | ||
| getRegionsInUserIdOrIndex: () => [], | ||
| getAllSeries: () => [], | ||
| getSeriesInIndex: () => [], | ||
| getSeriesInIds: () => [], | ||
| getSeriesInUserIdOrIndex: () => [], | ||
| getAllComponents: () => [], | ||
| getComponentByIndex: () => undefined, | ||
| getComponentsByKey: () => [], | ||
| getComponentsByType: () => [], | ||
| getChartLayoutRect: () => ({ width: 0, height: 0, x: 0, y: 0 }), | ||
| getChartViewRect: () => ({ width: 500, height: 500 } as any), | ||
| globalScale: new GlobalScale([], { getAllSeries: () => [] as any[] } as any), | ||
| getTheme: getTheme, | ||
| getComponentByUserId: () => undefined, | ||
| animation: false, | ||
| onError: () => {}, | ||
| getSeriesData: () => undefined | ||
| }; | ||
|
|
||
| const getAxisSpec = (spec: any) => ({ | ||
| sampling: 'simple', | ||
| ...spec | ||
| }); | ||
|
|
||
| describe('LinearAxis piecewise', () => { | ||
| beforeAll(() => { | ||
| // @ts-ignore | ||
| jest.spyOn(CartesianAxis.prototype, 'collectData').mockImplementation(() => { | ||
| return [{ min: 0, max: 10 }]; | ||
| }); | ||
| }); | ||
|
|
||
| test('should create piecewise domain and range from piecewise', () => { | ||
| // Mock getNewScaleRange to return [0, 100] | ||
| // @ts-ignore | ||
| jest.spyOn(CartesianAxis.prototype, 'getNewScaleRange').mockReturnValue([0, 100]); | ||
|
|
||
| let spec = getAxisSpec({ | ||
| orient: 'left', | ||
| piecewise: { | ||
| domain: [0, 5, 10], | ||
| ratio: [0.8, 0.2] | ||
| } | ||
| }); | ||
|
|
||
| const transformer = new CartesianAxis.transformerConstructor({ | ||
| type: 'cartesianAxis-linear', | ||
| getTheme: getTheme, | ||
| mode: 'desktop-browser' | ||
| }); | ||
| spec = transformer.transformSpec(spec, {}).spec; | ||
| const linearAxis = CartesianAxis.createComponent( | ||
| { | ||
| type: getCartesianAxisInfo(spec).componentName, | ||
| spec | ||
| }, | ||
| ctx | ||
| ) as CartesianLinearAxis; | ||
|
|
||
| linearAxis.created(); | ||
| linearAxis.init({}); | ||
|
|
||
| // Test Domain | ||
| // @ts-ignore | ||
| linearAxis.updateScaleDomain(); | ||
| const scale = linearAxis.getScale(); | ||
| expect(scale.domain()).toEqual([0, 5, 10]); | ||
|
|
||
| // Test Range | ||
| // @ts-ignore | ||
| const newRange = linearAxis.getNewScaleRange(); | ||
| // 0 -> 0 | ||
| // 5 -> 0 + 0.8 * 100 = 80 | ||
| // 10 -> 80 + 0.2 * 100 = 100 | ||
| expect(newRange).toEqual([0, 80, 100]); | ||
| }); | ||
|
|
||
| test('should handle gaps in piecewise', () => { | ||
| let spec = getAxisSpec({ | ||
| orient: 'left', | ||
| piecewise: { | ||
| domain: [0, 5, 8, 10], | ||
| ratio: [0.4, 0.4] | ||
| } | ||
| }); | ||
|
|
||
| const transformer = new CartesianAxis.transformerConstructor({ | ||
| type: 'cartesianAxis-linear', | ||
| getTheme: getTheme, | ||
| mode: 'desktop-browser' | ||
| }); | ||
| spec = transformer.transformSpec(spec, {}).spec; | ||
| const linearAxis = CartesianAxis.createComponent( | ||
| { | ||
| type: getCartesianAxisInfo(spec).componentName, | ||
| spec | ||
| }, | ||
| ctx | ||
| ) as CartesianLinearAxis; | ||
|
|
||
| linearAxis.created(); | ||
| linearAxis.init({}); | ||
|
|
||
| // @ts-ignore | ||
| linearAxis.updateScaleDomain(); | ||
| const scale = linearAxis.getScale(); | ||
| expect(scale.domain()).toEqual([0, 5, 8, 10]); | ||
| }); | ||
| }); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P2] 示例使用的
customDistribution不会被当前实现读取,实际支持的字段已经是piecewise。中英文公开文档仍将它写成customDistribution(Array),与实现的{ domain: number[], ratio: number[] }结构也不一致。按这个 demo 的字段配置,真实渲染中 [7,9] 仍占普通线性轴的 20%,没有得到配置要求的 60%。请统一实现、类型、公开文档、demo 和 PR 描述中的 API 名称与结构,并用实际公开示例验证放大比例。