Skip to content

Feat continuous legend handler text style function#2052

Merged
xuefei1313 merged 4 commits intodevelopfrom
feat-continuous-legend-handler-text-style-function
Mar 23, 2026
Merged

Feat continuous legend handler text style function#2052
xuefei1313 merged 4 commits intodevelopfrom
feat-continuous-legend-handler-text-style-function

Conversation

@xuefei1313
Copy link
Copy Markdown
Contributor

[中文版模板 / Chinese template]

🤔 This is a ...

  • New feature
  • Bug fix
  • TypeScript definition update
  • Bundle size optimization
  • Performance optimization
  • Enhancement feature
  • Refactoring
  • Update dependency
  • Code style optimization
  • Test Case
  • Branch merge
  • Site / documentation update
  • Demo update
  • Workflow
  • Release
  • Other (about what?)

🔗 Related issue link

🐞 Bugserver case id

💡 Background and solution

📝 Changelog

Language Changelog
🇺🇸 English
🇨🇳 Chinese

☑️ Self-Check before Merge

⚠️ Please check all items below before requesting a reviewing. ⚠️

  • Doc is updated/provided or not needed
  • Demo is updated/provided or not needed
  • TypeScript definition is updated/provided or not needed
  • Changelog is provided or not needed

🚀 Summary

copilot:summary

🔍 Walkthrough

copilot:walkthrough

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for computing slider/continuous-legend handler text styles dynamically via a callback, enabling per-value/per-handle styling at render and update time.

Changes:

  • Extends handlerText.style to accept a callback with (value, position, context) for dynamic text styling.
  • Refactors slider handler-text rendering/updating to reuse a shared attribute builder and invoke the callback when provided.
  • Adds unit tests for the new callback behavior in Slider and continuous legends.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

File Description
packages/vrender-components/src/slider/type.ts Introduces handler text style callback/context types; reuses layout/align type aliases.
packages/vrender-components/src/slider/slider.ts Implements callback evaluation and refactors handler text attribute computation for render/update paths.
packages/vrender-components/tests/unit/slider.test.ts Adds a unit test covering style callback invocation on render and setValue.
packages/vrender-components/tests/unit/legend/continuous.test.ts Adds unit tests ensuring continuous legends evaluate the style callback on render and setSelected.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +199 to +211
expect(style).toHaveBeenLastCalledWith(
78,
'start',
expect.objectContaining({
layout: 'horizontal',
align: 'bottom',
railWidth: 200,
railHeight: 10
})
);
expect(startHandlerText.attribute.fill).toBe('red');
expect(startHandlerText.attribute.dx).toBe(-6);
});
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new test asserts that the style callback is called with position: 'start' after slider.setValue(78), but the initial render in this same test expects position: 'end'. For a single-handler slider, the callback position should be consistent across render and updates; once the implementation is fixed, update the expectation (and the asserted dx) to match the intended consistent position.

Copilot uses AI. Check for mistakes.
} from '@visactor/vrender-core';

type Text = string | number;
type SliderLayout = 'horizontal' | 'vertical' | string;
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type SliderLayout = 'horizontal' | 'vertical' | string collapses to just string, so consumers lose the literal union benefits (autocomplete/narrowing) while still implying there are special cases. If the goal is “allow any string but prefer these literals”, consider using a literal-union pattern (e.g. 'horizontal' | 'vertical' | (string & {})) or remove | string if only these two are supported.

Suggested change
type SliderLayout = 'horizontal' | 'vertical' | string;
type SliderLayout = 'horizontal' | 'vertical' | (string & {});

Copilot uses AI. Check for mistakes.
Comment on lines 1043 to 1048
const updateHandlerText =
handler.name === SLIDER_ELEMENT_NAME.startHandler ? this._startHandlerText : this._endHandlerText;
if (updateHandlerText) {
const { handlerText = {} } = this.attribute as SliderAttributes;
updateHandlerText.setAttributes({
text: handlerText.formatter ? handlerText.formatter(value) : value.toFixed(handlerText.precision ?? 0),
[isHorizontal ? 'x' : 'y']: position
});
const handlerPosition = handler.name === SLIDER_ELEMENT_NAME.startHandler ? 'start' : 'end';
updateHandlerText.setAttributes(this._getHandlerTextAttributes(value, handlerPosition));
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In single-handler mode (range falsy), _renderHandlers calls _renderHandlerText(startValue, 'end'), but _updateHandler derives handlerPosition from the handler name and passes 'start' for startHandler. That makes the handlerText.style callback receive different position values between initial render and subsequent updates. Consider deriving the callback position based on range (e.g., treat startHandler as 'end' when range is false) so render/update are consistent.

Copilot uses AI. Check for mistakes.
[isHorizontal ? 'x' : 'y']: position,
text: handlerTextAttr.formatter ? handlerTextAttr.formatter(value) : value.toFixed(handlerTextAttr.precision ?? 0)
});
const handlerPosition = handlerText.name === SLIDER_ELEMENT_NAME.startHandlerText ? 'start' : 'end';
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_updateHandlerText infers the callback position solely from handlerText.name (start => 'start', end => 'end'). In single-handler mode the only text element is startHandlerText but it is rendered with position 'end' (_renderHandlers(... range ? 'start' : 'end')). This causes handlerText.style callbacks to see inconsistent positions between render and drag/update paths. Suggest aligning this logic with _renderHandlers by also checking this.attribute.range when determining 'start' | 'end'.

Suggested change
const handlerPosition = handlerText.name === SLIDER_ELEMENT_NAME.startHandlerText ? 'start' : 'end';
// 对齐 _renderHandlers 中对 position 的推断:
// range 模式下根据名称区分 start/end;非 range(单滑块)模式下统一视为 'end'
const handlerPosition =
this.attribute.range && handlerText.name === SLIDER_ELEMENT_NAME.startHandlerText ? 'start' : 'end';

Copilot uses AI. Check for mistakes.
@xuefei1313 xuefei1313 merged commit 5fe76e4 into develop Mar 23, 2026
5 of 8 checks passed
@xuefei1313 xuefei1313 deleted the feat-continuous-legend-handler-text-style-function branch March 23, 2026 07:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants