Skip to content

feat(chart): plotLine/plotBand 라벨에 valueFormatter 옵션 추가#2317

Open
jhee564 wants to merge 1 commit into
3.4from
feat/plot-label-value-formatter
Open

feat(chart): plotLine/plotBand 라벨에 valueFormatter 옵션 추가#2317
jhee564 wants to merge 1 commit into
3.4from
feat/plot-label-value-formatter

Conversation

@jhee564

@jhee564 jhee564 commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

배경

plotLine/plotBand 라벨의 값(showValue: true)은 항상 축 formatter로 포맷된다. 그래서 축 Decimal 옵션(소수점 자리수)이 라벨 값에도 그대로 적용되어, 축과 다른 정밀도로 값을 표시할 수 없다.

소비 측 요구사항: 축은 소수점 2자리를 유지하되 임계선 라벨은 반올림 없이 원본 값을 표시. 기존 구조로는 라벨만 축과 다르게 포맷할 방법이 없었다.

변경

  • 라벨 옵션에 valueFormatter?: (value) => string 추가.
    • showValue: true일 때 값 포맷을 이 함수로 override.
    • 미지정(null)이면 기존처럼 축 formatter 사용 → 완전 하위호환.
  • value-only / hover 이름 표시 / hideBelow 등 반응형 동작은 showValue 경로를 그대로 타므로 모두 유지된다.
  • plotBand는 showValue 시 from/to 양 끝 라벨 각각에 valueFormatter가 적용된다.

변경 파일

파일 내용
src/components/chart/helpers/helpers.constant.js PLOT_LINE_LABEL_OPTIONvalueFormatter: null 기본값
src/components/chart/scale/scale.js getNormalizedLabelOptions에서 함수면 valueFormatter, 아니면 getLabelFormat 사용
src/components/chart/scale/scale.spec.js 테스트 3개 추가(폴백 / override / value-only 상태 적용)
docs/specs/plotline-plotband-label-spec.md, docs/views/lineChart/api/lineChart.md 옵션 문서화

테스트

  • scale 스펙 171개 통과, eslint clean.
  • 기본값 null이라 기존 차트 라벨 동작은 변화 없음(하위호환).

사용 예

plotLines: [{
  value: 81.9999,
  label: {
    show: true,
    showValue: true,
    text: '임계치',
    valueFormatter: (v) => `${v}%`, // 축 Decimal 과 무관하게 원본 값 표시
  },
}]

🤖 Generated with Claude Code

showValue=true 라벨의 값 포맷을 축 formatter 대신 라벨별
valueFormatter 로 override 할 수 있게 한다. 미지정 시 기존처럼
축 formatter 를 사용해 완전 하위호환.

축과 다른 정밀도/단위로 임계선 값을 표시할 때 사용한다
(예: 축은 소수점 2자리, 임계선 라벨은 원본 정밀도).
value-only/hover 등 반응형 동작은 showValue 경로 그대로 유지된다.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
merged.showValue && hasValue
? String(
typeof merged.valueFormatter === 'function'
? merged.valueFormatter(value)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Bug] valueFormatter 결과를 String()으로 무조건 감싸므로, formatter가 문자열이 아닌 값을 반환하면 그대로 문자열화됩니다. return을 빠뜨리거나(예: (v) => { `${v}%` } — 중괄호만 쓰고 return 누락) 조건부로만 반환하면 undefined가 반환되어 라벨에 리터럴 "undefined"(null 반환 시 "null")가 그려집니다.

같은 저장소의 축 formatter(scale.linear.js:31-33 getLabelFormat)는 typeof formattedLabel === 'string' 가드로 비문자열 반환 시 기본 포맷으로 폴백하는데, 이 새 경로는 그 컨벤션을 따르지 않습니다. 계약이 (value) => string인 만큼 비문자열 반환을 어떻게 다룰지 정하는 것이 좋겠습니다. 트레이드오프가 있어 결정을 여쭙니다:

  • A. 축과 완전 일관: 비문자열(undefined/null/number 전부) → 축 formatter 폴백. 단, (v) => v * 2처럼 숫자를 반환하는 formatter도 폴백되어 계산값이 무시됩니다.
  • B. 외과적(추천): null/undefined만 폴백하고 숫자 등은 기존처럼 String() 강제변환 유지 → custom == null ? String(this.getLabelFormat(value)) : String(custom).
  • C. 현행 유지: 계약 위반은 사용자 책임(별도 가드 없음).

어느 쪽이든 의도를 스펙(§4.1)에 한 줄 남겨두면 좋겠습니다. 개인적으로는 "undefined"/"null" 리터럴 노출만 막는 B가 축 컨벤션과 숫자 반환 허용 사이의 절충으로 무난해 보입니다.

재현: valueFormatterreturn을 누락하거나 조건부로만 반환 → undefined 반환 → 라벨에 리터럴 "임계치 undefined" 렌더.

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.

2 participants