2026. 10. 13. 09:26ㆍVue
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
증권·금융 관련 프로젝트를 작업하다 보면 주가 변동, 투자 수익률, 자산 비중 등 다양한 데이터를 시각적으로 표현해야 하는 경우가 많다.
차트는 복잡한 수치를 직관적으로 전달하고, 데이터의 흐름과 변화를 쉽게 파악할 수 있도록 도와주는 중요한 UI 요소다.
최근 Vue3 + Nuxt 기반의 증권 프로젝트를 진행하면서 Highcharts를 활용해 막대 차트, 스택형 차트, 도넛 차트 등 다양한 데이터 시각화 UI를 구현했다.
처음에는 데이터를 차트로 출력하는 정도였지만, 디자인 시안에 맞춰 작업하다 보니 막대 너비와 간격, 그라데이션, 툴팁, SVG 라운드 처리 등 생각보다 많은 옵션을 다루게 되었다.
이번 글에서는 실제 프로젝트에서 자주 사용했던 Highcharts의 주요 속성과 커스터마이징 방법을 정리해 보려고 한다.
1. Highcharts란?
JavaScript charting library for web apps, dashboards, grids, React and more | Highcharts | Highcharts
Quick to start “Highcharts hits our sweet spot – powerful enough to present complex data, responsive, and easy enough to implement.”
www.highcharts.com
Highcharts는 JavaScript 기반의 데이터 시각화 라이브러리로, 선형 차트, 막대 차트, 영역 차트, 원형 차트 등 다양한 유형의 차트를 제공한다.
옵션을 통해 데이터와 스타일을 설정할 수 있고, SVG 기반으로 렌더링되어 차트의 크기나 디자인을 세밀하게 조정할 수 있다는 특징이 있다.
특히 증권·금융 서비스에서는 다음과 같은 데이터를 표현할 때 활용할 수 있다.
- 수익률 추이 : 기간별 투자 수익률 변화
- 자산 구성 비율 : 주식, 채권, 현금 등 자산 비중
- 투자금 현황 : 투자원금과 운용수익 비교
- 지수 비교 : KOSPI, S&P500 등 시장 지수의 흐름
- 수익률 분포 : 구간별 투자 성과 및 분포 현황
2. Highcharts 기본 옵션 구조
Highcharts는 차트의 유형, 데이터, 축, 툴팁 등을 옵션 객체로 설정한다.
| 속성 | 역할 |
| chart | 차트 유형, 크기, 배경 설정 |
| title | 차트 제목 |
| xAxis | X축 데이터와 스타일 |
| yAxis | Y축 범위와 스타일 |
| plotOptions | 차트 유형별 공통 스타일 |
| series | 실제 출력할 데이터 |
| tooltip | 데이터에 마우스를 올렸을 때 표시되는 정보 |
| legend | 데이터 범례 |
| credits | Highcharts 출처 표시 |
기본 막대 차트 예제
월별 투자원금을 막대 차트로 표현한다고 가정해 보자.
이번 예제에서는 데이터뿐 아니라 차트의 제목, 막대 색상, 데이터 라벨 등도 함께 설정했다.
const chartOptions = {
chart: {
type: 'column',
backgroundColor: 'transparent',
},
title: {
text: '월별 투자원금',
align: 'left',
},
xAxis: {
categories: ['1월', '2월', '3월', '4월', '5월'],
},
yAxis: {
min: 0,
max: 300,
tickInterval: 100,
title: {
text: undefined,
},
},
plotOptions: {
column: {
pointWidth: 72,
borderWidth: 0,
dataLabels: {
enabled: true,
},
},
},
series: [
{
type: 'column',
name: '투자원금',
color: '#7563EC',
data: [100, 150, 180, 200, 250],
},
],
legend: {
enabled: true,
verticalAlign: 'bottom',
},
credits: {
enabled: false,
},
}
chart.type을 column으로 지정하면 세로 막대 차트가 생성된다.
xAxis.categories에는 1월부터 5월까지의 항목을 설정하고, series.data에는 각 월의 투자원금 데이터를 전달한다.
또한 dataLabels.enabled를 true로 설정하면 막대 위에 데이터 값을 표시할 수 있다.
yAxis에는 최솟값과 최댓값, 눈금 간격을 지정했으며, pointWidth를 통해 막대의 너비를 조정했다.

3. 막대 차트 너비와 간격 조정하기
프로젝트에서 가장 자주 수정했던 부분 중 하나가 막대의 너비와 간격이었다.
특히 모바일 360px 디자인을 기준으로 막대 너비를 18px로 맞추고, 막대 사이의 간격을 조정해야 하는 경우가 있었다.
주요 속성
| 속성 | 설명 |
| pointWidth | 막대 너비를 px 단위로 고정 |
| maxPointWidth | 막대 최대 너비 제한 |
| pointPadding | 각 막대에 적용되는 상대적인 좌우 여백 |
| groupPadding | 카테고리 그룹의 좌우 여백 |
| grouping | 같은 카테고리의 여러 시리즈를 그룹화 |
| borderWidth | 막대 테두리 두께 |
적용 예제
plotOptions: {
column: {
pointWidth: 18,
pointPadding: 0.1,
groupPadding: 0.1,
borderWidth: 0,
},
},
pointWidth는 막대 너비를 고정하는 속성으로, 디자인 시안에 맞춰 정확한 너비를 지정할 때 유용하다.
여기서 주의할 점은 pointPadding과 groupPadding이 px 단위가 아니라 상대적인 비율이라는 것이다.
따라서 pointWidth: 18을 설정했다고 해서 막대 사이 간격까지 정확하게 고정되는 것은 아니다.
막대 간격을 세밀하게 조정해야 한다면 차트 전체 너비, 카테고리 개수, 시리즈 개수 등을 함께 고려해야 한다.

4. 스택형 막대 차트 구현하기
투자원금과 운용수익처럼 여러 데이터를 하나의 막대에 누적해서 표현해야 하는 경우에는 stacking 옵션을 사용한다.
주요 속성
| 속성 | 설명 |
| stacking | 데이터를 누적하는 방식 |
| stack | 누적 그룹 구분 |
| grouping | 여러 시리즈를 그룹으로 배치 |
| pointPlacement | 데이터 포인트의 표시 위치 조정 |
| reversedStacks | 스택의 표시 순서 조정 |
적용 예제
plotOptions: {
column: {
stacking: 'normal',
grouping: true,
},
},
series: [
{
type: 'column',
name: '투자원금',
data: [100, 150, 200],
stack: 'A',
},
{
type: 'column',
name: '운용수익',
data: [20, 30, 40],
stack: 'B',
},
],stacking 옵션의 차이
- normal : 실제 데이터 값을 누적
- percent : 전체 합계를 100%로 환산하여 누적
- 미설정 : 누적하지 않고 개별 데이터로 표시
stack 속성 활용하기
stack은 같은 카테고리 안에서 여러 누적 그룹을 구분할 때 사용한다.
예를 들어 크루 A와 크루 B의 투자원금과 운용수익을 각각 누적해서 나란히 보여주려면 stack: 'A', stack: 'B'처럼 구분할 수 있다.
실제 작업에서는 pointPlacement로 위치를 직접 조정했다가 막대가 겹치는 문제가 있었다.
이런 경우에는 불필요한 위치 조정을 제거하고 stack, grouping, pointPadding 등의 옵션을 함께 확인하는 것이 좋다.

5. 막대 차트에 border-radius 적용하기
Highcharts는 막대를 SVG로 렌더링하기 때문에, 일반적인 HTML 요소처럼 CSS border-radius를 적용하는 방식과는 차이가 있다.
기본 borderRadius 적용
plotOptions: {
column: {
borderRadius: 8,
borderWidth: 0,
},
},
borderRadius를 사용하면 막대에 라운드를 적용할 수 있다.
지원되는 버전에서는 객체 형태로도 설정할 수 있다.
plotOptions: {
column: {
borderRadius: {
radius: 8,
scope: 'stack',
where: 'end',
},
},
},
| 속성 | 설명 |
| radius | 라운드 크기 |
| scope | 개별 데이터 또는 전체 스택 기준 |
| where | 라운드를 적용할 위치 |
scope: 'stack'은 누적 막대 전체를 하나의 형태로 보고 외곽에 라운드를 적용할 때 유용하다.

스택 중간 막대에도 라운드를 적용하려면?
프로젝트에서는 전체 스택의 맨 위뿐 아니라 중간에 쌓인 막대의 상단 모서리도 둥글게 처리해야 했다.
이런 디자인은 기본 borderRadius 옵션만으로 구현하기 어려워 SVG path를 커스터마이징하는 방법을 검토했다.
SVG 경로를 수정하면 원하는 곡선을 만들 수 있지만, 라운드로 잘려 나간 영역에 뒤쪽 배경이 보이는 문제가 발생할 수 있다.
이 경우 backgroundColor: 'transparent'만으로는 해결되지 않을 수 있으며, 막대가 겹치는 구조와 SVG 경로를 함께 확인해야 한다.
이처럼 SVG를 직접 수정하는 작업은 라이브러리 버전이나 렌더링 구조에 영향을 받을 수 있으므로 기본 옵션으로 해결할 수 있는지 먼저 확인하는 것이 좋다.

6. Area 차트에 그라데이션 적용하기
증권 프로젝트에서는 KOSPI, S&P500 등의 지수 변화나 기간별 수익률을 표현하기 위해 선형 차트와 영역 차트를 활용했다.
특히 선 아래 영역에 그라데이션을 적용하면 데이터의 흐름을 강조하면서도 시각적으로 부드러운 차트를 구현할 수 있다.
Highcharts에서는 area 차트와 fillColor 옵션을 활용해 이러한 형태를 구현할 수 있다.
주요 속성
| 속성 | 설명 |
| type: 'area' | 선 아래 영역이 채워지는 차트 유형 |
| lineColor | 차트 선 색상 |
| lineWidth | 차트 선 두께 |
| fillColor | 선 아래 영역의 채우기 색상 |
| linearGradient | 그라데이션 방향 설정 |
| stops | 그라데이션 색상과 위치 설정 |
| marker | 데이터 포인트 표시 설정 |
적용 예제
const chartOptions = {
chart: {
type: 'area',
backgroundColor: 'transparent',
},
plotOptions: {
area: {
lineWidth: 2,
marker: {
enabled: false,
},
fillColor: {
linearGradient: {
x1: 0,
y1: 0,
x2: 0,
y2: 1,
},
stops: [
[0, 'rgba(117, 85, 255, 0.4)'],
[1, 'rgba(117, 85, 255, 0)'],
],
},
},
},
series: [
{
type: 'area',
name: 'KOSPI',
color: '#7555FF',
data: [10, 15, 12, 20, 25, 30],
},
],
}linearGradient와 stops 이해하기
linearGradient는 그라데이션 방향을 정의한다.
- x1, y1 : 시작 좌표
- x2, y2 : 종료 좌표
- stops : 위치와 색상 정보
위 예제는 위에서 아래로 색상이 점차 투명해지는 형태다.
stops 배열의 첫 번째 값은 위치를 나타내며, 0은 시작점, 1은 끝점을 의미한다.
또한 fillColor는 선 아래 영역에 적용되고, lineColor 또는 시리즈의 color는 선 색상을 설정할 때 사용한다.
이때 선 색상과 영역의 그라데이션을 별도로 설정하면 디자인 시안에 맞게 조정하기 쉽다.

7. Tooltip 커스터마이징하기
차트의 특정 데이터에 마우스를 올렸을 때 표시되는 정보 영역을 Tooltip이라고 한다.
Highcharts는 기본 툴팁을 제공하지만, 프로젝트에서는 디자인 시안에 맞는 UI를 구현하기 위해 formatter를 활용했다.
주요 속성
| 속성 | 설명 |
| enabled | 툴팁 사용 여부 |
| shared | 같은 X축의 여러 시리즈 정보 표시 |
| useHTML | HTML 기반 툴팁 렌더링 |
| formatter | 툴팁 내용 직접 구성 |
| backgroundColor | 툴팁 배경색 |
| borderWidth | 툴팁 테두리 두께 |
| shadow | 그림자 설정 |
적용 예제
tooltip: {
shared: true,
useHTML: true,
backgroundColor: 'transparent',
borderWidth: 0,
shadow: false,
formatter: function () {
const points = this.points ?? []
return `
<div class="chart-tooltip">
<strong>${this.x}</strong>
${points
.map(
(point) => `
<div class="chart-tooltip__item">
<span>${point.series.name}</span>
<strong>${point.y}</strong>
</div>
`,
)
.join('')}
</div>
`
},
},
shared: true를 설정하면 같은 X축에 위치한 여러 시리즈의 데이터를 함께 표시할 수 있다.
formatter는 툴팁을 자유롭게 구성할 수 있다는 장점이 있지만, Highcharts 버전에 따라 this의 구조가 다를 수 있으므로 확인이 필요하다.

8. X축과 Y축 커스터마이징
차트의 축과 눈금도 디자인 시안에 맞게 조정해야 하는 경우가 많았다.
특히 금융 차트에서는 데이터의 범위와 단위가 중요하기 때문에 축의 눈금과 라벨을 적절하게 설정해야 한다.
적용 예제
xAxis: {
categories: ['1월', '2월', '3월'],
lineWidth: 0,
tickLength: 0,
labels: {
style: {
color: '#999999',
fontSize: '12px',
},
},
},
yAxis: {
title: {
text: undefined,
},
gridLineWidth: 0,
labels: {
enabled: false,
},
},주요 속성
| 속성 | 설명 |
| min, max | 축의 최솟값과 최댓값 |
| tickInterval | 눈금 간격 |
| tickPositions | 눈금 위치를 배열로 직접 지정 |
| tickPositioner | 눈금 위치를 함수로 계산 |
| minPadding, maxPadding | 축 양끝의 상대적인 여백 |
| crosshair | 데이터 위치를 따라 표시되는 기준선 |
| plotLines | 축의 특정 값에 기준선 표시 |
특히 수익률 차트처럼 기간에 따라 데이터 범위가 달라지는 경우에는 tickPositioner를 활용해 눈금 위치를 직접 계산할 수 있다.
축의 눈금을 직접 지정할 때는 데이터의 최솟값과 최댓값이 잘리지 않는지도 함께 확인해야 한다.
9. 모바일에서 차트 스크롤 처리하기
모바일 화면에서 데이터 개수가 많아지면 막대가 지나치게 좁아지거나 X축 라벨이 겹치는 문제가 발생할 수 있다.
프로젝트에서는 모바일 화면에서도 막대의 너비를 유지하면서 데이터를 가로로 확인할 수 있도록 스크롤 처리를 검토했다.
Highcharts 자체의 scrollablePlotArea 옵션을 사용하는 방법도 있지만, 이번 프로젝트에서는 차트를 감싸는 부모 요소에 overflow-x: auto를 적용하고 차트 영역에 min-width를 설정하는 CSS 방식을 사용했다.
적용 예제
<template>
<div class="cashflow-chart__el-wrap">
<div
ref="chartEl"
class="cashflow-chart__el cashflow-chart__el--expand"
></div>
</div>
</template>
overflow-x: auto는 내부 콘텐츠가 부모 너비를 초과했을 때 가로 스크롤을 발생시키는 속성이다.
min-width는 차트가 일정 너비 이하로 줄어들지 않도록 하며, 화면이 좁아져도 막대와 데이터 사이의 간격을 유지하는 데 도움이 된다.
예를 들어 부모 영역이 360px이고 차트의 최소 너비가 680px이라면, 화면에는 360px만 표시되고 나머지는 가로 스크롤로 확인할 수 있다.
.cashflow-chart {
&__el-wrap {
overflow-x: auto;
margin-top: 1.2rem;
&::-webkit-scrollbar {
display: none;
}
}
&__el {
width: 100%;
min-height: 18rem;
&--expand {
min-width: 68rem;
}
}
}

10. 도넛 차트 구현하기
자산 비중이나 투자 구성 비율처럼 전체에서 각 항목이 차지하는 비율을 표현할 때는 도넛 차트를 활용할 수 있다.
Highcharts에서는 pie 차트에 innerSize를 지정해 도넛 형태를 구현한다.
적용 예제
const chartOptions = {
chart: {
type: 'pie',
backgroundColor: 'transparent',
},
plotOptions: {
pie: {
innerSize: '75%',
size: 130,
borderWidth: 0,
dataLabels: {
enabled: false,
},
},
},
series: [
{
type: 'pie',
data: [
{ name: 'A', y: 20 },
{ name: 'B', y: 80 },
],
},
],
}주요 속성
| 속성 | 설명 |
| innerSize | 가운데 비어 있는 영역의 크기 |
| size | 차트 크기 |
| dataLabels | 데이터 라벨 설정 |
| borderWidth | 각 조각의 테두리 두께 |
| startAngle | 차트 시작 각도 |
| endAngle | 차트 종료 각도 |
프로젝트에서는 130px 크기의 도넛 차트를 구현하고, 퍼센트 텍스트의 위치를 조정하는 작업도 진행했다.
도넛 중앙에 별도의 텍스트를 배치해야 한다면 차트 옵션뿐 아니라 HTML 요소를 활용하는 방법도 고려할 수 있다.

11. 다크모드에 따라 차트 스타일 변경하기
프로젝트에서는 라이트모드와 다크모드를 함께 지원해야 했다.
Highcharts는 SVG 요소에 색상이 직접 적용되는 경우가 많아 CSS만으로는 테마 변경이 제대로 반영되지 않을 수 있다.
이번 프로젝트에서는 상위 요소의 data-theme 속성 변경을 감지하기 위해 MutationObserver를 활용하고, 변경된 테마에 따라 차트의 색상 옵션을 갱신하는 방식을 사용했다.
MutationObserver를 활용한 다크모드 처리 방법은 별도 포스팅에서 자세히 다뤄보려고 한다.
12. 정리

이번 포스팅에서는 실무에서 자주 사용했던 Line, Donut, Column 차트를 중심으로 주요 속성과 커스터마이징 방법을 정리해 보았다.
Highcharts는 이 외에도 Area, Bar, Scatter 등 다양한 차트 유형과 옵션을 제공한다. 차트마다 활용할 수 있는 속성과 표현 방식이 다르기 때문에, 필요한 기능이 있다면 Highcharts 공식문서를 참고해 보는 것을 추천한다.
'Vue' 카테고리의 다른 글
| [Vue] Vue3 + TypeScript 컴포넌트 기초 정리 | Props, Slot, v-if, v-for 이해하기 (1) | 2026.10.09 |
|---|