Skip to content

[FE] bar&line chart 혼합 차트 구현#284

Merged
lwjmcn merged 29 commits intofeature/#194-fe-dashboard-sales-uifrom
feature/#275-fe-bar-line-chart
Feb 18, 2026
Merged

[FE] bar&line chart 혼합 차트 구현#284
lwjmcn merged 29 commits intofeature/#194-fe-dashboard-sales-uifrom
feature/#275-fe-bar-line-chart

Conversation

@lee0jae330
Copy link
Collaborator

@lee0jae330 lee0jae330 commented Feb 16, 2026

#️⃣ 변경 사항

이번 PR에서는 막대(Bar)와 꺾은선(Line)이 혼합된 BarLineChart 컴포넌트를 새롭게 추가하고, 차트 관련 공통 컴포넌트와 유틸리티의 재사용성을 높이기 위해 구조적인 리팩터링을 진행했습니다.

  • 혼합형 차트 추가: 하나의 차트 내에서 막대 그래프와 꺾은선 그래프를 동시에 렌더링할 수 있는 BarLineChartBarLineSeries 구현
  • 차트 도메인 분리: 특정 차트에 종속되어 있던 X/Y축 및 가이드라인 컴포넌트를 공통 chart 도메인으로 이동
  • 컴포넌트 세분화: LineChart 내부에서 사용되던 Dot을 별도 컴포넌트로 분리하고, 스타일 제어를 위한 className props 확장
  • 유틸리티 및 훅 고도화: 차트 좌표 계산 및 막대 너비/높이 계산 로직을 유틸리티 함수로 분리하여 코드 중복 제거

#️⃣ 작업 상세 내용

  • 혼합형 차트 관련

    • BarLineChart, BarLineSeries 컴포넌트 신규 구현
    • 혼합형 차트 전용 데이터 타입(BarLineChartSeries) 정의
    • 차트 데이터와 좌표를 계산하는 전용 커스텀 훅 useBarLineChart, useDrawBarLine 추가
    • 툴팁 트리거 영역 최적화 및 스토리북 예제(일간/월간 데이터) 추가
  • 공통 컴포넌트 리팩터링

    • XAxis, XAxisLabel, XGuideLine, YGuideLineline-chart에서 chart 폴더로 이동하여 모든 차트에서 공통 사용 가능하도록 변경
    • Dot, Line, Bar 컴포넌트에 className props를 추가하여 외부에서 스타일링을 주입할 수 있도록 개선
    • line-chartSeries 컴포넌트 명칭을 역할을 더 명확하게 나타내는 LineSeries로 변경
  • 유틸리티 및 로직 개선

    • 막대 차트 관련 너비(getBarWidth), 높이(getBarHeight), 라벨(getLabelContentText) 계산 로직을 유틸 함수로 분리
    • Y축 최댓값 계산(calculateMaximumY) 및 X좌표 계산(getXCoordinate) 유틸리티를 공통 chart 도메인으로 이동
    • getCoordinate 함수가 메인 데이터 외에 서브 데이터(subY) 기반으로도 좌표를 계산할 수 있도록 확장
  • 기타 수정 사항

    • LineChart의 그리기 애니메이션이 정상적으로 동작하지 않던 이슈 해결
    • LineChartGradient에서 배경 그라데이션의 조건부 렌더링 지원
    • 도넛 차트의 오타 수정 및 불필요한 Storybook args 제거

요청 사항

리뷰의 편의성을 PR base를 develop이 아닌 해당 branch가 분기한 브랜치를 바라보게 했습니다 ! (merge할 때, develop으로 base 변경하겠습니다.)

  • 기존 bar, line chart를 최대한 재사용했습니다. data type 또한 재사용하게 되어 mainY, subY의 형식을 그대로 가지고 가게 되었습니다..! 재사용하는 과정에서 추상화를 할 수 있는 부분을 더 고도화하였습니다. (ex: getCoordinate함수)
image
  • 해당 디자인 요구사항을 충족하기 위해 DotBar를 감싸는 투명한 path를 추가하고 해당 path를 기준으로 tooltip이 trigger 되게 하였습니다 !

  • 추가적으로 BarChart 쪽 코드도 조금 있어서 해당 부분도 봐주시면 감사하겠습니다 !

#️⃣ 관련 이슈

📸 스크린샷 (선택)

변경 전

변경 후

2026-02-16.8.26.42.mov

📎 참고할만한 자료 (선택)

- 애니메이션 실행 이후 값들을 업데이트 하도록 변경
@lee0jae330 lee0jae330 added the ✨ feat 새로운 기능이나 서비스 로직을 추가합니다. label Feb 16, 2026
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

차트 컴포넌트의 공통 로직을 분리하고 재사용성을 높이는 방향으로 리팩토링이 진행되었습니다. 이 과정에서 새로운 BarLineChart 컴포넌트가 추가되었습니다. TooltipContent 에서 사용된 클래스에 대한 개선 의견을 제시합니다.

</TooltipTrigger>
<TooltipContent
side="top"
className="transition-duration-200 bg-black px-250! text-gray-50 [&_svg]:-translate-y-1 [&_svg]:rotate-0 [&_svg]:text-black"

Choose a reason for hiding this comment

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

medium

TooltipContent 컴포넌트의 classNamepx-250! 와 같이 하드코딩된 유틸리티 클래스가 사용되었습니다.
이 값은 Tailwind CSS 의 기본 스페이싱 스케일에 포함되지 않은 매직 넘버로 보입니다.
유지보수성을 위해 tailwind.config.jstheme.spacing 에 토큰으로 등록하여 사용하는 것을 권장합니다.

예: spacing: { '250': '2.5rem' }

또한, 스타일 충돌이 없는 경우 ! (important) 한정자는 제거하는 것이 좋습니다.

@lee0jae330 lee0jae330 self-assigned this Feb 16, 2026
Copy link

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

막대(Bar)와 꺾은선(Line)을 한 SVG에서 함께 렌더링하는 BarLineChart를 추가하고, 기존 라인/바 차트에서 재사용 가능한 축/가이드라인 컴포넌트 및 좌표/치수 계산 로직을 공통 도메인으로 분리한 PR입니다.

Changes:

  • BarLineChart / 관련 훅(useBarLineChart, useDrawBarLine) 및 스토리북/목데이터 추가
  • X/Y 축 및 가이드라인을 components/shared/chart로 이동하고 라인 차트 내부 요소(Dot, LineSeries)를 분리
  • 차트 유틸(getXCoordinate, calculateMaximumY, getBarWidth/Height, getLabelContentText, getCoordinate 시그니처 변경) 리팩터링 및 도넛 차트 타입 오타 수정

Reviewed changes

Copilot reviewed 41 out of 46 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
frontend/src/utils/shared/line-chart/index.ts line-chart 유틸 export 정리(getXCoordinate 제거)
frontend/src/utils/shared/index.ts chart/bar-chart 유틸 export 재구성
frontend/src/utils/shared/getCoordinate.ts 좌표 계산 유틸 인자 구조 변경(시리즈 의존 제거)
frontend/src/utils/shared/doughnut-chart/doughnutChart.ts 도넛 차트 타입명 오타 수정 반영
frontend/src/utils/shared/chart/index.ts 공통 chart 유틸 배럴 추가
frontend/src/utils/shared/chart/getXCoordinate.ts getXCoordinate 공통 도메인으로 이동
frontend/src/utils/shared/chart/calculateMaximumY.ts Y 최댓값 계산 유틸 신규 추가
frontend/src/utils/shared/bar-chart/index.ts bar-chart 유틸 배럴 export 확장
frontend/src/utils/shared/bar-chart/getLabelContentText.ts 바 라벨 텍스트 생성 유틸 분리
frontend/src/utils/shared/bar-chart/getBarWidth.ts 바 너비 계산 유틸 분리
frontend/src/utils/shared/bar-chart/getBarHeight.ts 바 높이 계산 유틸 분리
frontend/src/types/shared/index.ts 공유 타입 export 업데이트(도넛 오타/바라인 타입 추가)
frontend/src/types/shared/doughnutChartItem.ts 도넛 차트 타입명 오타 수정
frontend/src/types/shared/bar-line-chart/index.ts 바-라인 차트 타입 배럴 추가
frontend/src/types/shared/bar-line-chart/barLineChartDataType.ts 바-라인 차트 데이터/시리즈 타입 정의
frontend/src/mocks/data/storybook/index.ts 스토리북 목데이터 export 확장
frontend/src/mocks/data/storybook/barLineChartStoryData.ts 바-라인 차트 목데이터 신규 추가
frontend/src/mocks/data/index.ts mocks index에서 바-라인 목데이터 재노출
frontend/src/hooks/shared/line-chart/useLineChart.ts getCoordinate 새 시그니처 적용
frontend/src/hooks/shared/line-chart/useLineAnimation.ts 라인 애니메이션 로직 안정화(참조/의존성 정리)
frontend/src/hooks/shared/index.ts bar-line-chart 훅 export 추가
frontend/src/hooks/shared/doughnut-chart/useDoughnutSegments.ts 도넛 차트 타입명 오타 수정 반영
frontend/src/hooks/shared/bar-line-chart/useDrawBarLine.ts 바/라인 혼합 툴팁 트리거 영역 계산 훅 추가
frontend/src/hooks/shared/bar-line-chart/useBarLineChartId.ts BarLineChart 접근성용 id 생성 훅 추가
frontend/src/hooks/shared/bar-line-chart/useBarLineChart.ts 바/라인 좌표 및 축 영역 계산 훅 추가
frontend/src/hooks/shared/bar-line-chart/index.ts bar-line-chart 훅 배럴 추가
frontend/src/hooks/shared/bar-chart/useBarChart.ts getCoordinate 새 시그니처 적용 및 타입 정리
frontend/src/components/shared/line-chart/index.ts line-chart 배럴 export 재정의(축 컴포넌트 제거/요소 분리 반영)
frontend/src/components/shared/line-chart/LineSeries.tsx Series → LineSeries로 명칭/타입 정리
frontend/src/components/shared/line-chart/LineChartGradient.tsx backgroundGradientId 조건부 렌더링 지원
frontend/src/components/shared/line-chart/LineChart.tsx 공통 chart 컴포넌트 사용 및 LineSeries 적용
frontend/src/components/shared/line-chart/Dots.tsx Dot 컴포넌트로 분리 적용
frontend/src/components/shared/line-chart/Dot.tsx 점 렌더링 공통 컴포넌트 신규 추가(className/hover 제어)
frontend/src/components/shared/chart/index.ts 공통 chart 컴포넌트 배럴 신규 추가
frontend/src/components/shared/chart/YGuideLine.tsx Y 가이드라인 공통 컴포넌트로 분리
frontend/src/components/shared/chart/XGuideLine.tsx X 가이드라인 공통 컴포넌트로 분리
frontend/src/components/shared/chart/XAxisLabel.tsx X축 라벨 공통 컴포넌트로 분리
frontend/src/components/shared/chart/XAxis.tsx X축 공통 컴포넌트로 분리
frontend/src/components/shared/bar-line-chart/index.ts BarLineChart 배럴 export 추가
frontend/src/components/shared/bar-line-chart/BarLineSeries.tsx 바+라인 단일 인덱스 렌더/툴팁 트리거 시리즈 추가
frontend/src/components/shared/bar-line-chart/BarLineChart.tsx 혼합 차트 본체 컴포넌트 신규 추가
frontend/src/components/shared/bar-line-chart/BarLineChart.stories.tsx 스토리북 예제(주간/월간/실시간) 추가
frontend/src/components/shared/bar-chart/index.ts Bar 컴포넌트 export 추가
frontend/src/components/shared/bar-chart/BarSeries.tsx 바 관련 계산 로직 유틸로 분리 적용
frontend/src/components/shared/bar-chart/BarChart.tsx 공통 chart 컴포넌트 사용으로 import 변경
frontend/src/components/shared/bar-chart/Bar.tsx Bar에 className 주입 지원 추가

Comment on lines +23 to +33
return (
<circle
cx={x}
cy={y}
r={DOT_RADIUS}
fill={color}
stroke="none"
role="graphics-symbol"
tabIndex={-1}
aria-label={ariaLabel}
className={cn(
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

Dot이 항상 tabIndex={-1}로 렌더링되어 키보드 포커스로 접근이 불가능합니다. 기존 Dots 구현에서는 tooltip이 활성화될 때 tabIndex={0}로 포커스 가능하게 처리했던 것으로 보여(툴팁 접근성) 회귀가 될 수 있습니다. 최소한 TooltipTrigger로 사용되는 경우에는 tabIndex를 0으로 두거나, tabIndex를 props로 받아 상황에 따라 조절할 수 있게 해 주세요.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

rechart를 참고했는데, rechart는 tooltip이 활성화 되어도 각 점마다 tabIndex=-1로 설정되어 있어, llm에 물어보니 명확한 인터렉션이 없는 경우, 사용자에게 혼동을 줄 수 있다고해서 제거했습니다.

@lee0jae330 lee0jae330 linked an issue Feb 16, 2026 that may be closed by this pull request
2 tasks
d={interactionPathD}
fill="transparent"
stroke="transparent"
className="peer z-1"
Copy link
Collaborator

Choose a reason for hiding this comment

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

[p5] peer를 습득하셨군요ㅎㅎ 좋습니다

const labelRefs = useRef<(SVGTextElement | null)[]>([]);

const chartDataWithPercentage: DoughtnutChartItemWithPercentage[] = useMemo(
const chartDataWithPercentage: DoughnutChartItemWithPercentage[] = useMemo(
Copy link
Collaborator

Choose a reason for hiding this comment

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

[p5] 감사합니다...

const { XAXIS_Y_OFFSET, XAXIS_STROKE_WIDTH } = BAR_CHART;
if (hasXAxis) {
// x축이 있을 때는 x축의 y위치 만큼을 빼고 축 높이의 0.5배 만큼 더 빼줘야 함
return viewBoxHeight - XAXIS_Y_OFFSET - y - XAXIS_STROKE_WIDTH / 2; // x축이 있을 때 바 높이는 y좌표 ~ x 축까지 거리
Copy link
Collaborator

Choose a reason for hiding this comment

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

[p4] 주석 통일해주세요! 그리고 설명이 조금 더 자세하면 좋을 것 같습니다

Copy link
Collaborator Author

@lee0jae330 lee0jae330 Feb 18, 2026

Choose a reason for hiding this comment

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

아 이건 민선님이 작업해주신 부분이라서.. 의도가 반영될지는 모르겠지만 일단 AI의 도움과 함께 반영해놓겠습니다

}: BarLineSeriesProps) => {
return (
<g>
<path
Copy link
Collaborator

Choose a reason for hiding this comment

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

[p4] tooltip을 띄우기 위한 용도임을 주석으로라도 표시해주면 좋을 것 같습니다

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

반영해놓겠습니다 !

Copy link
Collaborator

@lwjmcn lwjmcn left a comment

Choose a reason for hiding this comment

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

차트가 전체적으로 리팩터링 된 느낌이네요.
props가 많아서 컴포넌트 구조를 파악하기 조금 어려운 것 같아요. 나중에 코드 설명 한 번 해주시거나 구조 문서화 해주시면 좋을 것 같습니다.

고생하셨어요~!

@lwjmcn lwjmcn merged commit 3caa461 into feature/#194-fe-dashboard-sales-ui Feb 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ feat 새로운 기능이나 서비스 로직을 추가합니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FE] 막대, 꺾은선 혼합형 그래프 구현

2 participants