-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #34 from boostcampwm-2024/feature/layout/chart2-#3
[FE] 주가지수 chart 관련 코드 구조 개선 #3
- Loading branch information
Showing
6 changed files
with
115 additions
and
130 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { useEffect, useRef, useState } from 'react'; | ||
import { drawChart } from 'utils/chart'; | ||
|
||
const X_LENGTH = 79; | ||
|
||
type StockIndexChartProps = { | ||
name: string; | ||
}; | ||
|
||
export function Chart({ name }: StockIndexChartProps) { | ||
const [prices, setPrices] = useState<number[]>([50, 54]); | ||
const canvasRef = useRef<HTMLCanvasElement>(null); | ||
|
||
useEffect(() => { | ||
const interval = setInterval(() => { | ||
if (prices.length === X_LENGTH) { | ||
clearInterval(interval); | ||
return; | ||
} | ||
setPrices((prev) => [...prev, Math.floor(Math.random() * 50) + 25]); | ||
}, 500); | ||
|
||
return () => clearInterval(interval); | ||
}, [prices.length]); | ||
|
||
useEffect(() => { | ||
const canvas = canvasRef.current; | ||
const ctx = canvas?.getContext('2d'); | ||
if (!ctx) return; | ||
|
||
drawChart(ctx, prices); | ||
}, [prices]); | ||
|
||
return ( | ||
<div className='flex h-[200px] w-[500px] items-center rounded-lg bg-juga-grayscale-50 p-5'> | ||
<div className='flex flex-col items-start justify-center flex-1 h-full gap-1 text-sm'> | ||
<p className='text-lg font-semibold'>{name}</p> | ||
<p className='text-2xl font-bold'>2562.4</p> | ||
<p className='font-semibold text-juga-blue-40'>-31.55(-1.2%)</p> | ||
</div> | ||
<canvas | ||
id='lineChart' | ||
ref={canvasRef} | ||
width={600} | ||
height={300} | ||
className='flex-1 h-full' | ||
/> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { Chart } from './Chart'; | ||
|
||
export default function StockIndex() { | ||
return ( | ||
<div className='flex gap-2'> | ||
<Chart name='코스피' /> | ||
<Chart name='코스닥' /> | ||
</div> | ||
); | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
const X_LENGTH = 79; // 9:00 ~ 15:30 까지 5분 단위의 총 개수 | ||
const MIDDLE = 50; // 상한가, 하한가를 나누는 기준 | ||
|
||
export const drawChart = (ctx: CanvasRenderingContext2D, data: number[]) => { | ||
const canvas = ctx.canvas; | ||
const width = canvas.width; | ||
const height = canvas.height; | ||
|
||
ctx.clearRect(0, 0, width, height); | ||
|
||
const padding = { | ||
top: 10, | ||
right: 10, | ||
bottom: 10, | ||
left: 10, | ||
}; | ||
|
||
const chartWidth = width - padding.left - padding.right; | ||
const chartHeight = height - padding.top - padding.bottom; | ||
|
||
const yMax = Math.max(...data.map((d) => d)) * 1.1; | ||
const yMin = Math.min(...data.map((d) => d)) * 0.9; | ||
|
||
// 데이터 선 그리기 | ||
if (data.length > 1) { | ||
ctx.beginPath(); | ||
data.forEach((point, i) => { | ||
const x = padding.left + (chartWidth * i) / (X_LENGTH - 1); | ||
const y = | ||
padding.top + | ||
chartHeight - | ||
(chartHeight * (point - yMin)) / (yMax - yMin); | ||
|
||
console.log(point); | ||
|
||
if (i === 0) { | ||
ctx.moveTo(x, y); | ||
} else { | ||
ctx.lineTo(x, y); | ||
} | ||
}); | ||
|
||
const currentValue = data[data.length - 1]; | ||
if (currentValue >= MIDDLE) { | ||
ctx.strokeStyle = '#FF3700'; | ||
} else { | ||
ctx.strokeStyle = '#2175F3'; | ||
} | ||
ctx.lineWidth = 2; | ||
ctx.stroke(); | ||
} | ||
}; |