65 lines
1.7 KiB
TypeScript
65 lines
1.7 KiB
TypeScript
/**
|
|
* 캔들 pane 하단 시간축 — 거래량·보조지표가 아래에 있을 때 캔들 영역 바로 아래에도 시간 표시.
|
|
*/
|
|
import React, { useState, useEffect, useCallback } from 'react';
|
|
import type { ChartManager } from '../utils/ChartManager';
|
|
|
|
const AXIS_HEIGHT = 22;
|
|
|
|
interface CandlePaneTimeAxisProps {
|
|
manager: ChartManager;
|
|
containerEl: HTMLElement;
|
|
}
|
|
|
|
const CandlePaneTimeAxis: React.FC<CandlePaneTimeAxisProps> = ({ manager, containerEl }) => {
|
|
const [state, setState] = useState<ReturnType<ChartManager['getCandlePaneTimeAxisOverlay']>>(null);
|
|
|
|
const sync = useCallback(() => {
|
|
if (!containerEl.isConnected) return;
|
|
setState(manager.getCandlePaneTimeAxisOverlay());
|
|
}, [manager, containerEl]);
|
|
|
|
useEffect(() => {
|
|
sync();
|
|
const ro = new ResizeObserver(sync);
|
|
ro.observe(containerEl);
|
|
|
|
const unsubLayout = manager.subscribePaneLayout(sync);
|
|
const unsubRange = manager.subscribeViewport(sync);
|
|
|
|
const timers = [0, 50, 150, 400].map(ms => window.setTimeout(sync, ms));
|
|
return () => {
|
|
ro.disconnect();
|
|
unsubLayout();
|
|
unsubRange();
|
|
timers.forEach(clearTimeout);
|
|
};
|
|
}, [manager, containerEl, sync]);
|
|
|
|
if (!state || state.labels.length === 0) return null;
|
|
|
|
return (
|
|
<div
|
|
className="candle-pane-time-axis"
|
|
style={{
|
|
top: state.topY,
|
|
height: state.height ?? AXIS_HEIGHT,
|
|
width: state.plotWidth,
|
|
}}
|
|
aria-hidden
|
|
>
|
|
{state.labels.map((label, idx) => (
|
|
<span
|
|
key={`${label.x}-${idx}`}
|
|
className="candle-pane-time-axis__label"
|
|
style={{ left: label.x }}
|
|
>
|
|
{label.text}
|
|
</span>
|
|
))}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default CandlePaneTimeAxis;
|