이번에는 Highcharts로 만들어진 연도별 통계 차트를 수정하면서 생각보다 고민했던 부분을 정리해보려고 한다.
기존 통계 차트에는 여러 연도의 데이터가 들어가 있었고, 데이터가 많아지면 Highcharts가 X축 라벨을 적당한 간격으로 생략해서 보여주고 있었다.
예를 들어 데이터가 많으면 모든 연도를 다 보여주는 게 아니라 이런 식이다.
2008 2011 2014 2017 2020 2023
처음 봤을 때 나는 이게 딱히 문제라고 생각하지 않았다.
오히려 연도가 15개, 20개씩 있는데 그걸 전부 보여주면 X축이 복잡해지니까 Highcharts가 알아서 적당한 간격을 계산해서 보기 좋게 보여주고 있다고 생각했다.
그런데 수정 요청이 하나 들어왔다.
"마지막 연도는 사람들이 볼 수 있게 해주세요."
처음에는 조금 의문이었다.
데이터에는 마지막 연도까지 정상적으로 들어가 있고, Highcharts가 화면 크기에 맞게 알아서 라벨을 정리해주고 있는데... 굳이 마지막 연도를 억지로 보여줘야 하나?
차트만 놓고 보면 기존 방식이 더 깔끔해 보였다.
그런데 사용자 입장에서 다시 생각해보니 이유는 있었다.
통계 데이터가 2025년까지 있는데 X축의 마지막 라벨이 2023년으로 끝나면, 차트를 처음 보는 사람은 "이 통계는 2023년 자료까지밖에 없나?"라고 생각할 수도 있다.
결국 디자인적으로 깔끔하게 보이는 것과 사용자에게 최신 데이터가 어디까지 있는지 알려주는 것은 다른 문제였다.
그래서 마지막 연도는 반드시 표시하도록 수정하기로 했다.
showLastLabel이면 끝날 줄 알았다
Highcharts 옵션을 찾아보니 이름부터 딱 맞는 옵션이 있었다.
showLastLabel: true
처음에는 이거 하나면 끝날 줄 알았다.
그런데 적용해보니 원하는 것처럼 마지막 연도가 항상 표시되지는 않았다.
Highcharts가 데이터 개수와 차트 크기에 따라 X축 라벨을 자동으로 조절하고 있었기 때문이다.
결국 자동 계산에 맡기는 대신 어떤 위치의 라벨을 보여줄 것인지 직접 지정해야 했다.
tickPositions를 직접 계산해보자
Highcharts에서는 tickPositions를 사용하면 X축에서 표시할 위치를 직접 지정할 수 있다.
예를 들어
tickPositions: [0, 3, 6, 9, 12]
처럼 지정하면 해당 위치의 라벨만 표시할 수 있다.
그래서 우선 화면에 보여줄 최대 라벨 개수를 정했다.
var maxLabels = 8;
데이터가 8개 이하라면 굳이 생략할 필요가 없으므로 전부 보여준다.
if (dataLength <= maxLabels) {
for (var i = 0; i < dataLength; i++) {
tickPositions.push(i);
}
}
데이터가 더 많다면 전체 데이터 개수를 기준으로 간격을 계산했다.
var step = Math.ceil(
(dataLength - 1) / (maxLabels - 1)
);
그리고 계산된 간격에 따라 표시할 위치를 넣었다.
for (var i = 0; i < dataLength; i += step) {
tickPositions.push(i);
}
여기까지는 괜찮았다.
문제는 처음 요구사항이었던 마지막 연도였다.
계산된 위치에 마지막 인덱스가 포함되지 않을 수도 있기 때문이다.
그래서 마지막 연도가 없다면 추가하도록 했다.
if (tickPositions[tickPositions.length - 1] !== dataLength - 1) {
tickPositions.push(dataLength - 1);
}
이제 마지막 연도는 무조건 표시된다.
그런데 내가 처음 걱정했던 문제가 생겼다
기능적으로는 요구사항을 만족했다.
그런데 차트를 보니까 내가 처음에
굳이 마지막 연도를 강제로 보여줘야 하나?
라고 생각했던 이유가 바로 보였다.
예를 들어 기존에는
2008 2012 2016 2020 2024
이렇게 일정한 간격으로 깔끔하게 보였다면,
마지막 연도를 강제로 추가하면서 경우에 따라
2008 2012 2016 2020 2024 2025
처럼 보일 수 있었다.
2024와 2025가 바로 붙어버린다.
마지막 연도는 보이게 됐는데 기존보다 차트가 덜 예뻐진 것이다.
솔직히 처음에는 이게 조금 마음에 안 들었다.
Highcharts가 알아서 적당히 계산해주던 걸 굳이 직접 건드려서 오히려 어색하게 만드는 느낌이었기 때문이다.
하지만 요구사항은 명확했다.
마지막 연도는 반드시 보여야 한다.
그렇다면 단순히 마지막 연도를 하나 끼워 넣는 게 아니라, 마지막 연도가 포함된 상태에서도 최대한 자연스럽게 보이도록 전체 간격을 계산해야 했다.
처음과 마지막을 기준으로 생각하기
결국 내가 원하는 건 두 가지였다.
- X축에 너무 많은 연도가 표시되지 않을 것
- 최신 연도는 반드시 표시될 것
즉 Highcharts의 자동 계산을 완전히 포기하고 모든 연도를 보여주는 것도 아니고, 마지막 연도만 무작정 추가하는 것도 아니었다.
기존처럼 적당한 개수만 보여주되 처음과 마지막은 보장하는 방식이 필요했다.
그래서 전체 데이터 개수와 최대 라벨 개수를 기준으로 step을 계산하고, 마지막 인덱스가 포함되지 않았을 때만 마지막 위치를 추가하는 방식으로 정리했다.
최종적으로는 공통 함수로 만들었다.
function getOcnScnXAxis(nmValue) {
var maxLabels = 8;
var dataLength = nmValue.length;
var tickPositions = [];
if (dataLength <= maxLabels) {
for (var i = 0; i < dataLength; i++) {
tickPositions.push(i);
}
} else {
// 최대 8개 안에 들어오도록 일정한 간격 계산
var step = Math.ceil(
(dataLength - 1) / (maxLabels - 1)
);
for (var i = 0; i < dataLength; i += step) {
tickPositions.push(i);
}
// 마지막 연도가 포함되지 않았다면 추가
if (
tickPositions[tickPositions.length - 1]
!== dataLength - 1
) {
tickPositions.push(dataLength - 1);
}
}
return {
categories: nmValue,
crosshair: true,
tickPositions: tickPositions,
labels: {
rotation: -45
}
};
}
통계 차트가 여러 곳에서 사용되고 있었기 때문에 X축 설정을 공통 함수로 만들어 동일하게 적용했다.
개발자가 보기 좋은 화면과 사용자가 필요한 정보
이번 작업에서 기억에 남았던 건 코드 자체보다는 처음에 내가 가졌던 생각이었다.
처음에는 Highcharts가 이미 알아서 라벨 간격을 계산해주고 있었기 때문에 **굳이 마지막 연도를 강제로 표시할 필요가 있나?**라고 생각했다.
개발자인 내가 보기에는 차트가 일정한 간격으로 깔끔하게 나오는 게 더 자연스러웠다.
그런데 통계를 보는 사용자에게는 "가장 최신 데이터가 몇 년도까지 있는가"도 중요한 정보였다.
2025년 데이터가 실제로 존재하는데 X축이 2023년이나 2024년에서 끝난다면 충분히 오해할 수 있다.
결국 이번 수정은 단순히 Highcharts의 tickPositions를 조정한 작업이기도 했지만,
개발자가 보기에 깔끔한 화면과 사용자가 실제로 필요로 하는 정보가 항상 같지는 않다는 걸 느낀 작업이기도 했다.
그래도 아직 한 가지 마음에 걸리는 건 있다.
마지막 연도를 넣으면서 앞 연도와 너무 가까워지는 경우...
그건 아직도 조금 안 예뻐 보인다
'개발 > JavaScript' 카테고리의 다른 글
| HTTPS로 바꿨는데 HTTP도 접속돼야 한다... 둘 다 사용할 수 있을까? (0) | 2026.09.07 |
|---|---|
| async: true로 바꾸면 끝일까? 동기와 비동기 다시 정리하기 (0) | 2026.08.28 |