44 lines
1.6 KiB
TypeScript
44 lines
1.6 KiB
TypeScript
import { useEffect, useRef } from 'react'
|
|
import { createChart, IChartApi, ISeriesApi } from 'lightweight-charts'
|
|
|
|
type Point = { time: number; value: number }
|
|
|
|
export default function SimpleLineChart({ title, data }: { title: string; data: Point[] }) {
|
|
const containerRef = useRef<HTMLDivElement | null>(null)
|
|
const chartRef = useRef<IChartApi | null>(null)
|
|
const seriesRef = useRef<ISeriesApi<'Line'> | null>(null)
|
|
|
|
useEffect(() => {
|
|
if (!containerRef.current) return
|
|
const chart = createChart(containerRef.current, {
|
|
layout: { background: { color: '#0f172a' }, textColor: '#e2e8f0' },
|
|
grid: { vertLines: { color: '#1f2937' }, horzLines: { color: '#1f2937' } },
|
|
rightPriceScale: { borderColor: '#1f2937' },
|
|
timeScale: { borderColor: '#1f2937', timeVisible: true, secondsVisible: false },
|
|
height: 280,
|
|
width: containerRef.current.clientWidth,
|
|
})
|
|
chartRef.current = chart
|
|
const series = chart.addLineSeries({ color: '#3b82f6', lineWidth: 2 })
|
|
seriesRef.current = series
|
|
|
|
const onResize = () => {
|
|
if (!containerRef.current || !chartRef.current) return
|
|
chartRef.current.applyOptions({ width: containerRef.current.clientWidth })
|
|
}
|
|
window.addEventListener('resize', onResize)
|
|
return () => { window.removeEventListener('resize', onResize); chart.remove() }
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
if (!seriesRef.current) return
|
|
seriesRef.current.setData(data.map(d => ({ time: d.time as any, value: d.value })))
|
|
}, [data])
|
|
|
|
return (
|
|
<div className="card">
|
|
<div className="title">{title}</div>
|
|
<div ref={containerRef} className="chart" />
|
|
</div>
|
|
)
|
|
} |