fix: show TA-lib pattern spans on chart and add delete all annotations button
- Fix SpanAnnotationManager price range calculation: use direct candle filtering by time range instead of dummy Candle objects that fell back to 0/0 high/low, causing invisible rectangles - Add handleDeleteAllAnnotations in page.tsx (deletes all span annotations and regular annotations for current chart) - Add 'Delete All Annotations' button in sidebar below TA-Lib panel
This commit is contained in:
parent
7901a1a257
commit
d416aa409c
3 changed files with 50 additions and 5 deletions
|
|
@ -405,6 +405,21 @@ export default function Home() {
|
|||
}
|
||||
};
|
||||
|
||||
const handleDeleteAllAnnotations = async () => {
|
||||
if (!activeChartId) return;
|
||||
await Promise.all([
|
||||
fetch(`/api/span-annotations?chartId=${activeChartId}`, { method: 'DELETE' }),
|
||||
fetch(`/api/annotations?all=true&chartId=${activeChartId}`, { method: 'DELETE' }),
|
||||
]);
|
||||
await Promise.all([
|
||||
fetchSpanAnnotations(activeChartId),
|
||||
fetchAnnotations(activeChartId),
|
||||
chartRef.current?.refreshData(),
|
||||
]);
|
||||
setSelectedSpanId(null);
|
||||
setSelectedLabelId(null);
|
||||
};
|
||||
|
||||
const handleLabelDelete = async (id: number) => {
|
||||
setAnnotations(annotations.filter((a) => a.id !== id));
|
||||
if (selectedLabelId === id) {
|
||||
|
|
@ -778,6 +793,17 @@ export default function Home() {
|
|||
/>
|
||||
</div>
|
||||
|
||||
{/* Delete all annotations */}
|
||||
<div className="px-3 py-2 border-t border-sidebar-border">
|
||||
<button
|
||||
onClick={handleDeleteAllAnnotations}
|
||||
disabled={!activeChartId}
|
||||
className="w-full px-2 py-1 text-[10px] text-destructive border border-destructive/30 rounded hover:bg-destructive/10 transition-colors disabled:opacity-50"
|
||||
>
|
||||
Delete All Annotations
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Training Panel */}
|
||||
<div className="px-3 py-2 border-t border-sidebar-border">
|
||||
<TrainingPanel />
|
||||
|
|
|
|||
|
|
@ -112,12 +112,31 @@ export default function SpanAnnotationManager({
|
|||
|
||||
// Create primitives for each span annotation
|
||||
spanAnnotations.forEach((span) => {
|
||||
const { max_high, min_low } = calculatePriceRange(
|
||||
{ time: span.start_time, open: 0, high: 0, low: 0, close: 0 },
|
||||
{ time: span.end_time, open: 0, high: 0, low: 0, close: 0 }
|
||||
// Find candles within span time range for price calculation
|
||||
const spanCandles = candles.filter(
|
||||
(c) => c.time >= span.start_time && c.time <= span.end_time
|
||||
);
|
||||
let max_high: number;
|
||||
let min_low: number;
|
||||
if (spanCandles.length > 0) {
|
||||
max_high = Math.max(...spanCandles.map((c) => c.high));
|
||||
min_low = Math.min(...spanCandles.map((c) => c.low));
|
||||
} else {
|
||||
// Fallback: find nearest candles to span boundaries
|
||||
const nearest = candles.reduce(
|
||||
(acc, c) => {
|
||||
const distStart = Math.abs(c.time - span.start_time);
|
||||
const distEnd = Math.abs(c.time - span.end_time);
|
||||
if (distStart < acc.startDist) acc = { ...acc, startCandle: c, startDist: distStart };
|
||||
if (distEnd < acc.endDist) acc = { ...acc, endCandle: c, endDist: distEnd };
|
||||
return acc;
|
||||
},
|
||||
{ startCandle: candles[0], startDist: Infinity, endCandle: candles[0], endDist: Infinity }
|
||||
);
|
||||
max_high = Math.max(nearest.startCandle?.high ?? 0, nearest.endCandle?.high ?? 0);
|
||||
min_low = Math.min(nearest.startCandle?.low ?? 0, nearest.endCandle?.low ?? 0);
|
||||
}
|
||||
|
||||
// If we can't calculate price range from candles, use sensible defaults
|
||||
const spanData: SpanData = {
|
||||
id: span.id,
|
||||
start_time: span.start_time,
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue