Skip to content

Commit e54424b

Browse files
committed
호버 삭제, 윤년 문제 수정
1 parent 064ab5b commit e54424b

2 files changed

Lines changed: 99 additions & 26 deletions

File tree

src/components/blocks/goal/EtfCandidateCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ export const EtfCandidateCard = ({
174174

175175
return (
176176
<div
177-
className="bg-white rounded-3xl w-full px-16 py-16 shadow-lg transition-transform duration-300 hover:scale-105"
177+
className="bg-white rounded-3xl w-full px-16 py-16 shadow-lg transition-transform duration-300"
178178
style={{ borderRadius: "4rem" }}
179179
>
180180
{/* ETF 기본 정보 */}

src/components/blocks/goal/MonthlyPathsChart.tsx

Lines changed: 98 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
LineSeries,
1010
AreaData,
1111
AreaSeries,
12+
Time, // Time 타입 추가
1213
} from "lightweight-charts";
1314
import { TrendingUp } from "lucide-react";
1415

@@ -50,20 +51,90 @@ const getCurrentDate = () => {
5051
)}-${String(now.getDate()).padStart(2, "0")}`;
5152
};
5253

53-
// 현재 날짜부터 시작하는 날짜 배열 생성
54-
const generateDateArray = (months: number) => {
55-
const dates = [];
56-
const startDate = new Date();
54+
// 현재 날짜부터 시작하는 날짜 배열 생성 (Time 타입 반환)
55+
const generateDateArray = (months: number): Time[] => {
56+
const dates: Time[] = [];
57+
const startDate = new Date(); // 오늘 날짜 유지
58+
startDate.setHours(0, 0, 0, 0); // 시간만 정규화
59+
60+
console.log("🔍 generateDateArray 시작:", {
61+
months,
62+
startDate: startDate.toISOString(),
63+
startDateMonth: startDate.getMonth(),
64+
startDateDay: startDate.getDate(),
65+
});
5766

5867
for (let i = 0; i < months; i++) {
5968
const date = new Date(startDate);
60-
date.setMonth(date.getMonth() + i);
61-
dates.push(
62-
`${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-01`
63-
);
69+
const originalDay = date.getDate();
70+
71+
// 월을 더함
72+
date.setMonth(startDate.getMonth() + i);
73+
74+
// 날짜가 변경되었다면 (존재하지 않는 날짜였던 경우)
75+
if (date.getDate() !== originalDay) {
76+
// 해당 월의 마지막 날로 조정
77+
const lastDayOfMonth = new Date(
78+
date.getFullYear(),
79+
date.getMonth() + 1,
80+
0
81+
);
82+
date.setDate(lastDayOfMonth.getDate());
83+
}
84+
85+
const timestamp = Math.floor(date.getTime() / 1000) as Time;
86+
87+
console.log(`📅 월 ${i + 1}:`, {
88+
originalDay,
89+
finalDate: date.toISOString(),
90+
timestamp,
91+
month: date.getMonth(),
92+
day: date.getDate(),
93+
});
94+
95+
dates.push(timestamp);
6496
}
6597

66-
return dates;
98+
// 중복 제거 및 정렬
99+
const uniqueDates = [...new Set(dates)].sort((a, b) => Number(a) - Number(b));
100+
101+
console.log("🔍 최종 날짜 배열:", {
102+
originalLength: dates.length,
103+
uniqueLength: uniqueDates.length,
104+
removedDuplicates: dates.length - uniqueDates.length,
105+
firstDate: new Date(Number(uniqueDates[0]) * 1000).toISOString(),
106+
lastDate: new Date(
107+
Number(uniqueDates[uniqueDates.length - 1]) * 1000
108+
).toISOString(),
109+
});
110+
111+
return uniqueDates;
112+
};
113+
114+
// 데이터 검증 함수 추가
115+
const validateChartData = <T extends { time: Time; value: number }>(
116+
data: T[],
117+
seriesName: string
118+
): T[] => {
119+
// 중복 제거 및 정렬
120+
const uniqueData = data.filter(
121+
(item, index, self) =>
122+
index === 0 || Number(item.time) !== Number(self[index - 1].time)
123+
);
124+
125+
const sortedData = uniqueData.sort((a, b) => Number(a.time) - Number(b.time));
126+
127+
console.log(`🔍 ${seriesName} 데이터 검증:`, {
128+
originalLength: data.length,
129+
finalLength: sortedData.length,
130+
removedDuplicates: data.length - sortedData.length,
131+
firstTime: sortedData[0] ? Number(sortedData[0].time) : null,
132+
lastTime: sortedData[sortedData.length - 1]
133+
? Number(sortedData[sortedData.length - 1].time)
134+
: null,
135+
});
136+
137+
return sortedData;
67138
};
68139

69140
export const MonthlyPathsChart = ({
@@ -214,12 +285,12 @@ export const MonthlyPathsChart = ({
214285

215286
const area95Data: AreaData[] = data.fan_bands.p95.map(
216287
(value, index) => ({
217-
time: dateArray[index],
288+
time: dateArray[index] as Time, // 타입 캐스팅 추가
218289
value: value,
219290
})
220291
);
221292

222-
area95Series.setData(area95Data);
293+
area95Series.setData(validateChartData(area95Data, "Fan 95%"));
223294
seriesRef.current.push(area95Series);
224295

225296
// 25%~75% 영역 (더 진한 파랑)
@@ -232,12 +303,12 @@ export const MonthlyPathsChart = ({
232303

233304
const area75Data: AreaData[] = data.fan_bands.p75.map(
234305
(value, index) => ({
235-
time: dateArray[index],
306+
time: dateArray[index] as Time, // 타입 캐스팅 추가
236307
value: value,
237308
})
238309
);
239310

240-
area75Series.setData(area75Data);
311+
area75Series.setData(validateChartData(area75Data, "Fan 75%"));
241312
seriesRef.current.push(area75Series);
242313

243314
// 중앙값 라인 (굵은 선)
@@ -251,12 +322,12 @@ export const MonthlyPathsChart = ({
251322

252323
const medianData: LineData[] = data.fan_bands.p50.map(
253324
(value, index) => ({
254-
time: dateArray[index],
325+
time: dateArray[index] as Time, // 타입 캐스팅 추가
255326
value: value,
256327
})
257328
);
258329

259-
medianSeries.setData(medianData);
330+
medianSeries.setData(validateChartData(medianData, "Median"));
260331
seriesRef.current.push(medianSeries);
261332
}
262333

@@ -273,12 +344,12 @@ export const MonthlyPathsChart = ({
273344

274345
const principalData: LineData[] = data.principal_line.map(
275346
(value, index) => ({
276-
time: dateArray[index],
347+
time: dateArray[index] as Time, // 타입 캐스팅 추가
277348
value: value,
278349
})
279350
);
280351

281-
principalSeries.setData(principalData);
352+
principalSeries.setData(validateChartData(principalData, "Principal"));
282353
seriesRef.current.push(principalSeries);
283354
}
284355

@@ -295,12 +366,12 @@ export const MonthlyPathsChart = ({
295366

296367
const bestData: LineData[] = data.representative.p95.map(
297368
(value, index) => ({
298-
time: dateArray[index],
369+
time: dateArray[index] as Time, // 타입 캐스팅 추가
299370
value: value,
300371
})
301372
);
302373

303-
bestSeries.setData(bestData);
374+
bestSeries.setData(validateChartData(bestData, "Best"));
304375
seriesRef.current.push(bestSeries);
305376

306377
// 최악 성과 (하위 5%)
@@ -314,12 +385,12 @@ export const MonthlyPathsChart = ({
314385

315386
const worstData: LineData[] = data.representative.p05.map(
316387
(value, index) => ({
317-
time: dateArray[index],
388+
time: dateArray[index] as Time, // 타입 캐스팅 추가
318389
value: value,
319390
})
320391
);
321392

322-
worstSeries.setData(worstData);
393+
worstSeries.setData(validateChartData(worstData, "Worst"));
323394
seriesRef.current.push(worstSeries);
324395
}
325396

@@ -337,11 +408,13 @@ export const MonthlyPathsChart = ({
337408
});
338409

339410
const lineData: LineData[] = path.map((value, monthIndex) => ({
340-
time: dateArray[monthIndex],
411+
time: dateArray[monthIndex] as Time, // 타입 캐스팅 추가
341412
value: value,
342413
}));
343414

344-
lineSeries.setData(lineData);
415+
lineSeries.setData(
416+
validateChartData(lineData, `Random Sample ${index + 1}`)
417+
);
345418
seriesRef.current.push(lineSeries);
346419
});
347420
}
@@ -382,14 +455,14 @@ export const MonthlyPathsChart = ({
382455
const dateIndex = yearStartMonth;
383456
if (dateIndex < dateArray.length) {
384457
data.push({
385-
time: dateArray[dateIndex],
458+
time: dateArray[dateIndex] as Time, // 타입 캐스팅 추가
386459
value: yearAverage,
387460
});
388461
}
389462
}
390463
}
391464

392-
lineSeries.setData(data);
465+
lineSeries.setData(validateChartData(data, `Path ${index + 1}`));
393466
seriesRef.current.push(lineSeries);
394467
});
395468
}

0 commit comments

Comments
 (0)