feat: instrument analysis
This commit is contained in:
@@ -73,9 +73,11 @@ export default function InstrumentChart({ priceData, indicators, events = [], he
|
|||||||
const containerRef = useRef<HTMLDivElement>(null)
|
const containerRef = useRef<HTMLDivElement>(null)
|
||||||
const cleanupRef = useRef<(() => void) | null>(null)
|
const cleanupRef = useRef<(() => void) | null>(null)
|
||||||
const onHoverRef = useRef(onDateHover)
|
const onHoverRef = useRef(onDateHover)
|
||||||
|
const onChartReadyRef = useRef(onChartReady)
|
||||||
|
|
||||||
// Keep callback ref fresh without triggering chart rebuild
|
// Keep callback refs fresh without triggering chart rebuild
|
||||||
useEffect(() => { onHoverRef.current = onDateHover }, [onDateHover])
|
useEffect(() => { onHoverRef.current = onDateHover }, [onDateHover])
|
||||||
|
useEffect(() => { onChartReadyRef.current = onChartReady }, [onChartReady])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
cleanupRef.current?.()
|
cleanupRef.current?.()
|
||||||
@@ -211,9 +213,9 @@ export default function InstrumentChart({ priceData, indicators, events = [], he
|
|||||||
chart.timeScale().fitContent()
|
chart.timeScale().fitContent()
|
||||||
|
|
||||||
// Expose coordinate mapping so siblings can align with the chart x-axis
|
// Expose coordinate mapping so siblings can align with the chart x-axis
|
||||||
if (onChartReady && containerRef.current) {
|
if (onChartReadyRef.current && containerRef.current) {
|
||||||
const canvasLeft = containerRef.current.getBoundingClientRect().left
|
const canvasLeft = containerRef.current.getBoundingClientRect().left
|
||||||
onChartReady((d: string) => chart.timeScale().timeToCoordinate(d as any), canvasLeft)
|
onChartReadyRef.current((d: string) => chart.timeScale().timeToCoordinate(d as any), canvasLeft)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Star overlay — ★ icons positioned via chart coordinate API ────────
|
// ── Star overlay — ★ icons positioned via chart coordinate API ────────
|
||||||
@@ -326,7 +328,7 @@ export default function InstrumentChart({ priceData, indicators, events = [], he
|
|||||||
chart.timeScale().unsubscribeVisibleLogicalRangeChange(renderStars)
|
chart.timeScale().unsubscribeVisibleLogicalRangeChange(renderStars)
|
||||||
if (starsOverlay.parentNode) starsOverlay.parentNode.removeChild(starsOverlay)
|
if (starsOverlay.parentNode) starsOverlay.parentNode.removeChild(starsOverlay)
|
||||||
chart.remove()
|
chart.remove()
|
||||||
onChartReady?.(null as any, 0)
|
onChartReadyRef.current?.(null as any, 0)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -335,7 +337,7 @@ export default function InstrumentChart({ priceData, indicators, events = [], he
|
|||||||
cleanupRef.current?.()
|
cleanupRef.current?.()
|
||||||
cleanupRef.current = null
|
cleanupRef.current = null
|
||||||
}
|
}
|
||||||
}, [priceData, indicators, events, height, chartType, theoryCurve, onChartReady])
|
}, [priceData, indicators, events, height, chartType, theoryCurve])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-dark-900/60 rounded-xl border border-slate-700/40 overflow-hidden">
|
<div className="bg-dark-900/60 rounded-xl border border-slate-700/40 overflow-hidden">
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ import InstrumentChart, { TheoPoint } from '../components/InstrumentChart'
|
|||||||
|
|
||||||
const api = axios.create({ baseURL: '/api' })
|
const api = axios.create({ baseURL: '/api' })
|
||||||
|
|
||||||
|
// Stable empty array — prevents InstrumentChart useEffect from re-running on every render
|
||||||
|
const NO_CHART_EVENTS: never[] = []
|
||||||
|
|
||||||
// ── Types ─────────────────────────────────────────────────────────────────────
|
// ── Types ─────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
interface CausalTemplate {
|
interface CausalTemplate {
|
||||||
@@ -1283,7 +1286,7 @@ export default function InstrumentDashboard() {
|
|||||||
<InstrumentChart
|
<InstrumentChart
|
||||||
priceData={snapshot.price_data}
|
priceData={snapshot.price_data}
|
||||||
indicators={snapshot.indicators}
|
indicators={snapshot.indicators}
|
||||||
events={[]}
|
events={NO_CHART_EVENTS}
|
||||||
height={420}
|
height={420}
|
||||||
chartType={chartStyle}
|
chartType={chartStyle}
|
||||||
onDateHover={handleDateHover}
|
onDateHover={handleDateHover}
|
||||||
|
|||||||
Reference in New Issue
Block a user