// AVANT MARKETS — Ticker Detail screen const { useState: useStateD, useMemo, useRef, useEffect } = React; // ─── price chart ─────────────────────────────────────── function PriceChart({ data, animate }) { const W = 700; const H = 380; const padL = 28; const padR = 64; // room for price labels on right const padT = 16; const padB = 36; const min = Math.min(...data); const max = Math.max(...data); const range = (max - min) || 1; // pad axis a bit const yMin = min - range * 0.08; const yMax = max + range * 0.08; const yRange = yMax - yMin; const usableW = W - padL - padR; const usableH = H - padT - padB; const step = usableW / (data.length - 1); const xy = (i, v) => [padL + i * step, padT + usableH - ((v - yMin) / yRange) * usableH]; const linePath = data .map((v, i) => { const [x, y] = xy(i, v); return (i === 0 ? "M" : "L") + x.toFixed(2) + " " + y.toFixed(2); }) .join(" "); const lastX = padL + (data.length - 1) * step; const [, lastY] = xy(data.length - 1, data[data.length - 1]); const firstY = padT + usableH; const fillPath = `${linePath} L ${lastX.toFixed(2)} ${(padT + usableH).toFixed(2)} L ${padL} ${(padT + usableH).toFixed(2)} Z`; // Y axis labels — 5 evenly spaced const yTicks = []; for (let i = 0; i <= 4; i++) { const v = yMin + (yRange * i) / 4; const y = padT + usableH - (i / 4) * usableH; yTicks.push({ v, y }); } // X axis times (mocked but plausible session times) const xLabels = ["09:30", "11:00", "12:30", "14:00", "15:30", "16:00"]; return ( {/* grid lines + Y labels */} {yTicks.map((t, i) => ( {t.v.toFixed(2).replace(".", ",")} ))} {/* fill */} {/* line */} {/* end dot */} {/* X labels */} {xLabels.map((l, i) => { const x = padL + (i / (xLabels.length - 1)) * usableW; return ( {l} ); })} ); } // ─── news image placeholder (subtly-striped gradient) ─── function NewsImagePlaceholder({ hue, label }) { return ( {label} ); } // ─── ticker detail screen ─────────────────────────────── function TickerDetail({ tickerKey, inPortfolio, onToggleAdd }) { const t = TICKERS[tickerKey]; const [timeframe, setTimeframe] = useStateD("1D"); const series = t.series[timeframe]; const positive = t.change >= 0; // Build news for this ticker; fall back to NVRA news for others (just example data) const news = NEWS_BY_TICKER[tickerKey] || NEWS_BY_TICKER.NVRA; // Force chart re-mount on timeframe change for redraw animation const chartKey = `${tickerKey}-${timeframe}`; return (
{/* Detail header */}
{t.ticker.slice(0, 2)}

{t.name}

{t.ticker} {t.exchange} {t.sector}
{fmtMoney(t.price)} USD
{positive ? "▲" : "▼"} {fmtSigned(t.change)} ({fmtPct(t.changePct)}) Hoy
{/* Chart + metrics */}
{["1H", "4H", "1D", "1S"].map((tf) => ( ))}
Métricas clave
Capitalización{t.marketCap}
Volumen{t.volume}
P/E{t.pe}
Dividendos{t.dividend}
Beta (5A){t.beta}
{/* News */}

Noticias recientes

Ver todas
{news.map((n, i) => (
{n.tag}

{n.title}

{n.time}
))}
{/* footer */}
Los datos se muestran con fines informativos y no constituyen asesoramiento de inversión.
Fuente: Nasdaq
· Datos en tiempo real
); } Object.assign(window, { TickerDetail });