emberwick 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -3
- package/index.d.ts +30 -2
- package/index.js +50 -0
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/emberwick.umd.js +1 -1
- package/umd/emberwick.umd.js.map +1 -1
package/umd/emberwick.umd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emberwick.umd.js","sources":["../../src/chart/core/Layers.js","../../src/chart/core/Loop.js","../../src/chart/motion/Tween.js","../../src/chart/core/TimeScale.js","../../src/chart/core/PriceScale.js","../../src/chart/core/palette.js","../../src/chart/motion/LiveCandle.js","../../src/chart/motion/Inertia.js","../../src/chart/core/formatters.js","../../src/chart/render/grid.js","../../src/chart/render/candles.js","../../src/chart/render/crosshair.js","../../src/chart/overlays/annotations.js","../../src/chart/render/annotations.js","../../src/chart/core/Chart.js","../../src/chart/data/DataFeed.js","../../src/chart/data/RandomFeed.js","../../src/chart/index.js"],"sourcesContent":["/**\n * Layers — stacked canvases sharing one coordinate space.\n *\n * Why: the crosshair repaints on every pointer move, the candles do not.\n * Separate canvases mean moving the cursor never touches candle pixels.\n * All contexts are pre-scaled by devicePixelRatio, so every renderer draws\n * in CSS pixels and gets crisp output on retina.\n */\nexport class Layers {\n constructor(container, names) {\n this.container = container\n this.names = names\n this.canvas = {}\n this.ctx = {}\n this.width = 0\n this.height = 0\n this.dpr = 0\n this.onResize = null\n\n if (getComputedStyle(container).position === 'static') {\n container.style.position = 'relative'\n }\n\n names.forEach((name, i) => {\n const c = document.createElement('canvas')\n Object.assign(c.style, {\n position: 'absolute',\n left: '0',\n top: '0',\n width: '100%',\n height: '100%',\n pointerEvents: 'none',\n zIndex: String(i + 1),\n })\n container.appendChild(c)\n this.canvas[name] = c\n this.ctx[name] = c.getContext('2d')\n })\n\n this._ro = new ResizeObserver(() => this.measure())\n this._ro.observe(container)\n this.measure()\n }\n\n measure() {\n const r = this.container.getBoundingClientRect()\n const w = Math.max(1, Math.floor(r.width))\n const h = Math.max(1, Math.floor(r.height))\n const dpr = Math.min(window.devicePixelRatio || 1, 2)\n if (w === this.width && h === this.height && dpr === this.dpr) return\n this.width = w\n this.height = h\n this.dpr = dpr\n for (const n of this.names) {\n const c = this.canvas[n]\n c.width = Math.floor(w * dpr)\n c.height = Math.floor(h * dpr)\n this.ctx[n].setTransform(dpr, 0, 0, dpr, 0, 0)\n }\n if (this.onResize) this.onResize(w, h)\n }\n\n /** Flatten all layers into a single canvas (for toImage/export). */\n composite() {\n const out = document.createElement('canvas')\n out.width = Math.floor(this.width * this.dpr)\n out.height = Math.floor(this.height * this.dpr)\n const c = out.getContext('2d')\n for (const n of this.names) c.drawImage(this.canvas[n], 0, 0)\n return out\n }\n\n destroy() {\n this._ro.disconnect()\n for (const n of this.names) this.canvas[n].remove()\n this.canvas = {}\n this.ctx = {}\n }\n}\n","/**\n * Loop — ONE requestAnimationFrame loop for the whole chart, driven by\n * dirty flags. 500 feed ticks between two frames still cost one repaint.\n *\n * The frame callback returns `true` while animation is in flight, which is\n * what keeps the loop running; otherwise it idles at zero CPU until something\n * calls invalidate().\n */\nexport class Loop {\n constructor(onFrame) {\n this.onFrame = onFrame\n this.fps = 0\n this._raf = 0\n this._dirty = new Set()\n this._last = 0\n this._running = false\n this._frames = 0\n this._fpsAt = 0\n this._tick = this._tick.bind(this)\n }\n\n invalidate(...layers) {\n if (!layers.length) this._dirty.add('all')\n else for (const l of layers) this._dirty.add(l)\n this._schedule()\n }\n\n start() {\n if (this._running) return\n this._running = true\n this._last = performance.now()\n this._fpsAt = this._last\n this.invalidate('all')\n }\n\n stop() {\n this._running = false\n if (this._raf) cancelAnimationFrame(this._raf)\n this._raf = 0\n }\n\n _schedule() {\n if (this._raf || !this._running) return\n this._raf = requestAnimationFrame(this._tick)\n }\n\n _tick(now) {\n this._raf = 0\n if (!this._running) return\n const dt = Math.min(Math.max(now - this._last, 1), 64)\n this._last = now\n\n this._frames++\n if (now - this._fpsAt >= 500) {\n this.fps = Math.round((this._frames * 1000) / (now - this._fpsAt))\n this._frames = 0\n this._fpsAt = now\n }\n\n const dirty = this._dirty\n this._dirty = new Set()\n\n let wantMore = false\n try {\n wantMore = this.onFrame(dirty, dt, now) === true\n } catch (e) {\n console.error('[Emberwick] frame error', e)\n }\n if (wantMore || this._dirty.size) this._schedule()\n }\n}\n","// Motion primitives. Everything animated in Emberwick goes through one of these\n// two classes so there is exactly one place that owns easing behaviour.\n\nexport const easeOutCubic = (t) => 1 - Math.pow(1 - t, 3)\nexport const easeInOutCubic = (t) =>\n t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2\n\n/**\n * Smoothed — exponential smoothing toward a target that may move every frame.\n * Frame-rate independent: the same visual speed at 30fps and 144fps.\n * Use for values that are continuously re-targeted (autoscale, live candle, zoom).\n */\nexport class Smoothed {\n constructor(value = 0, tau = 90) {\n this.value = value\n this.target = value\n this.tau = tau\n }\n\n set(target) {\n this.target = target\n }\n\n /** Snap with no animation. */\n jump(v) {\n this.value = v\n this.target = v\n }\n\n get settled() {\n const eps = 1e-9 + Math.abs(this.target) * 1e-6\n return Math.abs(this.target - this.value) <= eps\n }\n\n /** @returns {boolean} true while still moving (caller keeps the loop alive) */\n tick(dt) {\n if (this.settled) {\n this.value = this.target\n return false\n }\n this.value += (this.target - this.value) * (1 - Math.exp(-dt / this.tau))\n return true\n }\n}\n\n/**\n * Tween — fixed-duration one-shot, for discrete events (a candle being born).\n */\nexport class Tween {\n constructor(duration = 200, ease = easeOutCubic) {\n this.duration = duration\n this.ease = ease\n this.t = duration\n }\n\n restart() {\n this.t = 0\n }\n\n get done() {\n return this.t >= this.duration\n }\n\n get progress() {\n return this.ease(Math.min(1, this.t / this.duration))\n }\n\n tick(dt) {\n if (this.done) return false\n this.t += dt\n return true\n }\n}\n","import { Smoothed } from '../motion/Tween.js'\n\nconst clamp = (v, a, b) => (v < a ? a : v > b ? b : v)\n\n/**\n * TimeScale — maps bar index <-> x pixels.\n *\n * Two smoothed values define the view:\n * spacing : px per bar (zoom)\n * right : float bar index sitting at the right edge of the plot\n *\n * Both are Smoothed, so a wheel zoom eases instead of stepping, and new bars\n * glide in rather than jumping. Dragging uses jump() so the chart stays glued\n * to the pointer — easing a drag feels like lag, not smoothness.\n */\nexport class TimeScale {\n constructor({ spacing = 9, minSpacing = 0.8, maxSpacing = 160, rightOffset = 12 } = {}) {\n this.minSpacing = minSpacing\n this.maxSpacing = maxSpacing\n this.rightOffset = rightOffset\n this.width = 0\n this.barCount = 0\n this.follow = true\n this.timeframeMs = 60000\n this._spacing = new Smoothed(spacing, 65)\n this._right = new Smoothed(rightOffset, 65)\n this._initial = spacing\n }\n\n get spacing() { return this._spacing.value }\n get right() { return this._right.value }\n\n resize(w) { this.width = Math.max(1, w) }\n\n setBarCount(n) {\n const grew = n > this.barCount\n this.barCount = n\n if (this.follow) {\n // target the new last bar; Smoothed turns this into a glide\n const t = n - 1 + this.rightOffset\n if (grew) this._right.set(t)\n else this._right.jump(t)\n }\n }\n\n x(i) { return this.width - (this._right.value - i) * this._spacing.value }\n\n /** Centre-x of bar i (bars are drawn centred on their slot). */\n index(x) { return this._right.value - (this.width - x) / this._spacing.value }\n\n barWidth() {\n const s = this._spacing.value\n // leave a gap between candles, but never thinner than a hairline\n return Math.max(1, Math.floor(s * 0.72))\n }\n\n visibleRange() {\n const first = Math.floor(this.index(0)) - 1\n const last = Math.ceil(this.index(this.width)) + 1\n return {\n from: clamp(first, 0, Math.max(0, this.barCount - 1)),\n to: clamp(last, 0, Math.max(0, this.barCount - 1)),\n }\n }\n\n _clampRight(v) {\n const max = this.barCount - 1 + this.rightOffset + this.width / this._spacing.target\n const min = Math.min(4, this.barCount - 1 + this.rightOffset)\n return clamp(v, min, max)\n }\n\n /** Immediate pan, in pixels. Positive dx drags content right (back in time). */\n panBy(dxPx) {\n if (!dxPx) return false\n const next = this._clampRight(this._right.value - dxPx / this._spacing.value)\n this._right.jump(next)\n this.follow = false\n return true\n }\n\n /** Zoom by `factor`, keeping the bar under `x` pinned. */\n zoomAt(x, factor) {\n const s0 = this._spacing.target\n const s1 = clamp(s0 * factor, this.minSpacing, this.maxSpacing)\n if (Math.abs(s1 - s0) < 1e-9) return false\n\n // While following realtime, pin the right edge instead of the cursor so the\n // latest candle stays put — that is what traders expect.\n const anchorX = this.follow ? this.width : x\n const r0 = this._right.target\n const idx = r0 - (this.width - anchorX) / s0\n const r1 = idx + (this.width - anchorX) / s1\n\n this._spacing.set(s1)\n this._right.set(this._clampRight(r1))\n return true\n }\n\n snapToRealtime() {\n this.follow = true\n this._right.set(this.barCount - 1 + this.rightOffset)\n }\n\n reset() {\n this._spacing.set(this._initial)\n this.snapToRealtime()\n }\n\n /** True while the view is still easing. */\n tick(dt) {\n const a = this._spacing.tick(dt)\n const b = this._right.tick(dt)\n return a || b\n }\n\n get settled() { return this._spacing.settled && this._right.settled }\n}\n","import { Smoothed } from '../motion/Tween.js'\n\nconst clamp = (v, a, b) => (v < a ? a : v > b ? b : v)\n\n/**\n * PriceScale — maps price <-> y pixels, with animated autoscale.\n *\n * Bounds live in *transformed* space (identity for linear, log for log), so\n * switching modes is a one-line change and the easing still behaves.\n * The whole point of smoothing here: when a spike arrives the range glides to\n * its new bounds instead of the chart snapping and losing the reader.\n */\nexport class PriceScale {\n constructor({ mode = 'linear', tau = 120, marginTop = 0.12, marginBottom = 0.12 } = {}) {\n this.mode = mode\n this.marginTop = marginTop\n this.marginBottom = marginBottom\n this.auto = true\n this.top = 0\n this.height = 1\n this._lo = new Smoothed(0, tau)\n this._hi = new Smoothed(1, tau)\n this._primed = false\n }\n\n _fwd(v) { return this.mode === 'log' ? Math.log(Math.max(v, 1e-9)) : v }\n _inv(v) { return this.mode === 'log' ? Math.exp(v) : v }\n\n setMode(mode) {\n if (mode === this.mode) return\n const lo = this._inv(this._lo.value)\n const hi = this._inv(this._hi.value)\n this.mode = mode\n this._lo.jump(this._fwd(lo))\n this._hi.jump(this._fwd(hi))\n }\n\n layout(top, height) {\n this.top = top\n this.height = Math.max(1, height)\n }\n\n get lo() { return this._inv(this._lo.value) }\n get hi() { return this._inv(this._hi.value) }\n\n y(price) {\n const a = this._lo.value\n const b = this._hi.value\n const t = (this._fwd(price) - a) / (b - a || 1)\n return this.top + this.height * (1 - t)\n }\n\n price(y) {\n const a = this._lo.value\n const b = this._hi.value\n const t = 1 - (y - this.top) / this.height\n return this._inv(a + t * (b - a))\n }\n\n /** Fit visible bars. `extra` lets the forming candle influence the range. */\n fit(bars, from, to, extra) {\n if (!this.auto || !bars.length) return\n let min = Infinity\n let max = -Infinity\n for (let i = from; i <= to; i++) {\n const b = bars[i]\n if (!b) continue\n if (b.low < min) min = b.low\n if (b.high > max) max = b.high\n }\n if (extra) {\n if (extra.low < min) min = extra.low\n if (extra.high > max) max = extra.high\n }\n if (!isFinite(min) || !isFinite(max)) return\n\n let a = this._fwd(min)\n let b = this._fwd(max)\n let pad = (b - a) * this.marginTop\n if (!(pad > 0)) pad = Math.abs(b) * 0.01 || 1\n a -= pad\n b += (b - a) * 0 + pad\n\n this._lo.set(a)\n this._hi.set(b)\n if (!this._primed) {\n this._lo.jump(a)\n this._hi.jump(b)\n this._primed = true\n }\n }\n\n /** Manual axis-drag scaling around the vertical centre. */\n scaleBy(factor) {\n this.auto = false\n const a = this._lo.target\n const b = this._hi.target\n const mid = (a + b) / 2\n const half = ((b - a) / 2) * clamp(factor, 0.2, 5)\n this._lo.set(mid - half)\n this._hi.set(mid + half)\n }\n\n resetAuto() {\n this.auto = true\n }\n\n tick(dt) {\n const a = this._lo.tick(dt)\n const b = this._hi.tick(dt)\n return a || b\n }\n}\n","export const defaultTheme = {\n background: '#0b0e14',\n grid: 'rgba(255,255,255,0.045)',\n axisLine: 'rgba(255,255,255,0.10)',\n text: '#8b93a7',\n textStrong: '#e6e9ef',\n up: '#26a69a',\n down: '#ef5350',\n upFill: '#26a69a',\n downFill: '#ef5350',\n wickUp: '#26a69a',\n wickDown: '#ef5350',\n volumeUp: 'rgba(38,166,154,0.30)',\n volumeDown: 'rgba(239,83,80,0.30)',\n crosshair: 'rgba(255,255,255,0.32)',\n labelBg: '#2a3040',\n labelText: '#e6e9ef',\n tagText: '#06080d',\n font: '11px ui-sans-serif, -apple-system, \"Segoe UI\", Roboto, sans-serif',\n priceAxisWidth: 68,\n timeAxisHeight: 26,\n}\n\nexport const lightTheme = {\n ...defaultTheme,\n background: '#ffffff',\n grid: 'rgba(0,0,0,0.06)',\n axisLine: 'rgba(0,0,0,0.14)',\n text: '#6b7280',\n textStrong: '#111827',\n labelBg: '#374151',\n volumeUp: 'rgba(38,166,154,0.25)',\n volumeDown: 'rgba(239,83,80,0.25)',\n crosshair: 'rgba(0,0,0,0.35)',\n tagText: '#ffffff',\n}\n","import { Smoothed, Tween } from './Tween.js'\n\n/**\n * LiveCandle — makes the forming (rightmost) candle *flow* instead of snapping.\n *\n * A raw feed tick replaces close/high/low instantly, which reads as a jitter.\n * Here every component eases toward the incoming value, and a brand new candle\n * plays a short grow-from-centre animation as it scrolls in.\n */\nexport class LiveCandle {\n constructor(tau = 55) {\n this.enabled = true\n this.o = new Smoothed(0, tau)\n this.h = new Smoothed(0, tau)\n this.l = new Smoothed(0, tau)\n this.c = new Smoothed(0, tau)\n this.vol = new Smoothed(0, tau * 2)\n this.spawn = new Tween(240)\n this._has = false\n this._time = null\n }\n\n setTarget(bar) {\n if (!bar) {\n this._has = false\n return\n }\n if (!this._has || bar.time !== this._time) {\n // New candle: start collapsed at its open, then animate outward.\n this.o.jump(bar.open)\n this.h.jump(bar.open)\n this.l.jump(bar.open)\n this.c.jump(bar.open)\n this.vol.jump(0)\n this.spawn.restart()\n this._time = bar.time\n this._has = true\n }\n this.o.set(bar.open)\n this.h.set(bar.high)\n this.l.set(bar.low)\n this.c.set(bar.close)\n this.vol.set(bar.volume || 0)\n }\n\n reset() {\n this._has = false\n this._time = null\n }\n\n /** @returns {boolean} true while animating */\n tick(dt) {\n if (!this._has) return false\n let moving = false\n if (this.o.tick(dt)) moving = true\n if (this.h.tick(dt)) moving = true\n if (this.l.tick(dt)) moving = true\n if (this.c.tick(dt)) moving = true\n if (this.vol.tick(dt)) moving = true\n if (this.spawn.tick(dt)) moving = true\n return moving\n }\n\n /** Interpolated view of `bar`, or `bar` itself when disabled. */\n read(bar) {\n if (!this._has || !this.enabled || bar.time !== this._time) return bar\n const o = this.o.value\n const c = this.c.value\n return {\n time: bar.time,\n open: o,\n close: c,\n // keep the wick consistent while values chase each other\n high: Math.max(this.h.value, o, c),\n low: Math.min(this.l.value, o, c),\n volume: this.vol.value,\n _spawn: this.spawn.progress,\n }\n }\n}\n","/**\n * Inertia — momentum panning with friction decay.\n * sample() while dragging, release() on pointer up, then tick() each frame\n * until it returns 0.\n */\nexport class Inertia {\n constructor({ friction = 0.92, min = 0.015 } = {}) {\n this.friction = friction\n this.min = min\n this.v = 0 // px per ms\n this.active = false\n }\n\n sample(dx, dt) {\n if (dt <= 0) return\n const instant = dx / dt\n // low-pass so one jittery frame doesn't define the throw\n this.v = this.v * 0.6 + instant * 0.4\n this.active = false\n }\n\n release() {\n if (Math.abs(this.v) > this.min) this.active = true\n }\n\n stop() {\n this.v = 0\n this.active = false\n }\n\n /** @returns {number} px to pan this frame (0 when idle) */\n tick(dt) {\n if (!this.active) return 0\n const dx = this.v * dt\n this.v *= Math.pow(this.friction, dt / 16.6667)\n if (Math.abs(this.v) < this.min) this.stop()\n return dx\n }\n}\n","/** \"Nice\" step size (1/2/5 x 10^n) covering `span` in about `count` steps. */\nexport function niceStep(span, count) {\n const raw = span / Math.max(1, count)\n if (!(raw > 0) || !isFinite(raw)) return 1\n const mag = Math.pow(10, Math.floor(Math.log10(raw)))\n const n = raw / mag\n const s = n < 1.5 ? 1 : n < 3 ? 2 : n < 7 ? 5 : 10\n return s * mag\n}\n\nexport function priceTicks(lo, hi, count) {\n const step = niceStep(hi - lo, count)\n const ticks = []\n const start = Math.ceil(lo / step) * step\n for (let v = start; v <= hi + step * 1e-9; v += step) ticks.push(v)\n return { ticks, step }\n}\n\nexport function decimalsFor(step) {\n if (!isFinite(step) || step <= 0) return 2\n if (step >= 100) return 0\n if (step >= 1) return 2\n return Math.min(8, Math.ceil(-Math.log10(step)) + 1)\n}\n\n/** Bar-index step that keeps time labels at least `minPx` apart. */\nexport function niceBarStep(minBars) {\n const opts = [1, 2, 5, 10, 15, 20, 30, 60, 120, 240, 480, 960, 1920, 3840, 7680]\n for (const o of opts) if (o >= minBars) return o\n return Math.ceil(minBars / 1000) * 1000\n}\n\nconst p2 = (n) => String(n).padStart(2, '0')\n\nexport function fmtAxisTime(ms, tfMs) {\n const d = new Date(ms)\n if (tfMs >= 864e5) return `${d.getDate()} ${d.toLocaleString('en', { month: 'short' })}`\n if (d.getHours() === 0 && d.getMinutes() === 0) {\n return `${d.getDate()} ${d.toLocaleString('en', { month: 'short' })}`\n }\n return `${p2(d.getHours())}:${p2(d.getMinutes())}`\n}\n\nexport function fmtDateTime(ms) {\n const d = new Date(ms)\n return `${d.getFullYear()}-${p2(d.getMonth() + 1)}-${p2(d.getDate())} ${p2(d.getHours())}:${p2(d.getMinutes())}`\n}\n\nexport function fmtVolume(v) {\n if (!isFinite(v)) return '—'\n if (v >= 1e9) return (v / 1e9).toFixed(2) + 'B'\n if (v >= 1e6) return (v / 1e6).toFixed(2) + 'M'\n if (v >= 1e3) return (v / 1e3).toFixed(1) + 'K'\n return String(Math.round(v))\n}\n","import { priceTicks, decimalsFor, niceBarStep, fmtAxisTime } from '../core/formatters.js'\n\n/** Background, grid, and both axes. Repaints only when the view changes. */\nexport function drawGrid(ctx, s) {\n const { theme, ts, ps, plot, bars, width, height } = s\n\n ctx.clearRect(0, 0, width, height)\n ctx.fillStyle = theme.background\n ctx.fillRect(0, 0, width, height)\n\n ctx.font = theme.font\n ctx.textBaseline = 'middle'\n\n // ---- price grid + labels -------------------------------------------------\n const rows = Math.max(2, Math.floor(plot.h / 58))\n const { ticks, step } = priceTicks(ps.lo, ps.hi, rows)\n const dec = decimalsFor(step)\n\n ctx.strokeStyle = theme.grid\n ctx.lineWidth = 1\n ctx.beginPath()\n for (const v of ticks) {\n const y = Math.round(ps.y(v)) + 0.5\n if (y < plot.y || y > plot.y + plot.h) continue\n ctx.moveTo(0, y)\n ctx.lineTo(plot.w, y)\n }\n ctx.stroke()\n\n ctx.fillStyle = theme.text\n ctx.textAlign = 'left'\n for (const v of ticks) {\n const y = Math.round(ps.y(v))\n if (y < plot.y + 6 || y > plot.y + plot.h - 6) continue\n ctx.fillText(v.toFixed(dec), plot.w + 8, y)\n }\n\n // ---- time grid + labels --------------------------------------------------\n if (bars.length) {\n const minBars = Math.ceil(74 / Math.max(0.0001, ts.spacing))\n const stepBars = niceBarStep(minBars)\n const { from, to } = ts.visibleRange()\n const first = Math.ceil(from / stepBars) * stepBars\n\n ctx.strokeStyle = theme.grid\n ctx.beginPath()\n for (let i = first; i <= to; i += stepBars) {\n const x = Math.round(ts.x(i)) + 0.5\n if (x < 0 || x > plot.w) continue\n ctx.moveTo(x, 0)\n ctx.lineTo(x, plot.h)\n }\n ctx.stroke()\n\n ctx.fillStyle = theme.text\n ctx.textAlign = 'center'\n const ty = plot.h + theme.timeAxisHeight / 2\n for (let i = first; i <= to; i += stepBars) {\n const bar = bars[i]\n if (!bar) continue\n const x = Math.round(ts.x(i))\n if (x < 28 || x > plot.w - 28) continue\n ctx.fillText(fmtAxisTime(bar.time, ts.timeframeMs), x, ty)\n }\n }\n\n // ---- axis separators -----------------------------------------------------\n ctx.strokeStyle = theme.axisLine\n ctx.beginPath()\n ctx.moveTo(plot.w + 0.5, 0)\n ctx.lineTo(plot.w + 0.5, plot.h)\n ctx.moveTo(0, plot.h + 0.5)\n ctx.lineTo(width, plot.h + 0.5)\n ctx.stroke()\n}\n","import { decimalsFor, priceTicks } from '../core/formatters.js'\n\n/**\n * Candles + volume. Everything here is culled to the visible index range —\n * 500k bars loaded still costs only the ~200 on screen.\n */\nexport function drawCandles(ctx, s) {\n const { theme, ts, ps, plot, bars, width, height, live, volumeRatio } = s\n\n ctx.clearRect(0, 0, width, height)\n if (!bars.length) return\n\n const { from, to } = ts.visibleRange()\n const bw = ts.barWidth()\n const half = bw / 2\n const thin = bw <= 2\n\n // ---- volume strip --------------------------------------------------------\n const volH = plot.h * volumeRatio\n const volTop = plot.y + plot.h - volH\n let vmax = 0\n for (let i = from; i <= to; i++) {\n const b = bars[i]\n if (b && b.volume > vmax) vmax = b.volume\n }\n if (vmax > 0) {\n for (let i = from; i <= to; i++) {\n let b = bars[i]\n if (!b) continue\n if (live && i === bars.length - 1) b = live\n const x = ts.x(i)\n if (x < -bw || x > plot.w + bw) continue\n const h = (b.volume / vmax) * volH * 0.9\n ctx.fillStyle = b.close >= b.open ? theme.volumeUp : theme.volumeDown\n ctx.fillRect(Math.round(x - half), volTop + (volH - h), Math.max(1, bw), h)\n }\n }\n\n // ---- candles -------------------------------------------------------------\n for (let i = from; i <= to; i++) {\n let b = bars[i]\n if (!b) continue\n const isLast = i === bars.length - 1\n if (live && isLast) b = live\n\n const x = ts.x(i)\n if (x < -bw || x > plot.w + bw) continue\n\n const up = b.close >= b.open\n const color = up ? theme.up : theme.down\n const yO = ps.y(b.open)\n const yC = ps.y(b.close)\n const yH = ps.y(b.high)\n const yL = ps.y(b.low)\n\n // grow-from-centre on a freshly opened candle\n let scale = 1\n if (live && isLast && typeof b._spawn === 'number') scale = 0.35 + 0.65 * b._spawn\n\n const cx = Math.round(x) + (bw % 2 ? 0.5 : 0)\n\n // wick\n ctx.strokeStyle = up ? theme.wickUp : theme.wickDown\n ctx.lineWidth = Math.max(1, Math.min(2, bw * 0.16))\n ctx.beginPath()\n ctx.moveTo(cx, yH)\n ctx.lineTo(cx, yL)\n ctx.stroke()\n\n if (thin) continue\n\n // body\n const top = Math.min(yO, yC)\n const bodyH = Math.max(1, Math.abs(yC - yO))\n const w = Math.max(1, bw * scale)\n ctx.fillStyle = color\n ctx.fillRect(Math.round(x - w / 2), Math.round(top), Math.round(w), Math.round(bodyH))\n }\n\n // ---- last price line -----------------------------------------------------\n const lastBar = live || bars[bars.length - 1]\n if (lastBar) {\n const y = Math.round(ps.y(lastBar.close)) + 0.5\n if (y > plot.y && y < plot.y + plot.h) {\n const up = lastBar.close >= lastBar.open\n ctx.save()\n ctx.setLineDash([3, 3])\n ctx.strokeStyle = up ? theme.up : theme.down\n ctx.lineWidth = 1\n ctx.globalAlpha = 0.7\n ctx.beginPath()\n ctx.moveTo(0, y)\n ctx.lineTo(plot.w, y)\n ctx.stroke()\n ctx.restore()\n\n const { step } = priceTicks(ps.lo, ps.hi, Math.max(2, Math.floor(plot.h / 58)))\n const label = lastBar.close.toFixed(decimalsFor(step))\n ctx.font = theme.font\n ctx.textBaseline = 'middle'\n ctx.textAlign = 'left'\n const tw = ctx.measureText(label).width\n ctx.fillStyle = up ? theme.up : theme.down\n ctx.fillRect(plot.w + 1, y - 9, tw + 14, 18)\n ctx.fillStyle = theme.tagText\n ctx.fillText(label, plot.w + 8, y)\n }\n }\n}\n","import { decimalsFor, priceTicks, fmtDateTime } from '../core/formatters.js'\n\n/**\n * Crosshair lives alone on the top canvas: moving the pointer repaints only\n * these few pixels, never the candles underneath.\n */\nexport function drawCrosshair(ctx, s) {\n const { theme, ts, ps, plot, bars, width, height, cursor, magnet } = s\n\n ctx.clearRect(0, 0, width, height)\n if (!cursor || !bars.length) return\n if (cursor.x < 0 || cursor.x > plot.w || cursor.y < 0 || cursor.y > plot.h) return\n\n const i = Math.round(ts.index(cursor.x))\n const bar = bars[i]\n\n let x = cursor.x\n let y = cursor.y\n if (bar) {\n x = ts.x(i) // snap to the bar slot\n if (magnet) {\n // magnet to the nearest OHLC value\n const cands = [bar.open, bar.high, bar.low, bar.close]\n let best = null\n let bestD = Infinity\n for (const p of cands) {\n const py = ps.y(p)\n const d = Math.abs(py - cursor.y)\n if (d < bestD) { bestD = d; best = py }\n }\n if (bestD < 22) y = best\n }\n }\n\n ctx.save()\n ctx.setLineDash([4, 4])\n ctx.strokeStyle = theme.crosshair\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(Math.round(x) + 0.5, 0)\n ctx.lineTo(Math.round(x) + 0.5, plot.h)\n ctx.moveTo(0, Math.round(y) + 0.5)\n ctx.lineTo(plot.w, Math.round(y) + 0.5)\n ctx.stroke()\n ctx.restore()\n\n ctx.font = theme.font\n ctx.textBaseline = 'middle'\n\n // price tag\n const { step } = priceTicks(ps.lo, ps.hi, Math.max(2, Math.floor(plot.h / 58)))\n const priceLabel = ps.price(y).toFixed(decimalsFor(step))\n ctx.textAlign = 'left'\n const pw = ctx.measureText(priceLabel).width\n ctx.fillStyle = theme.labelBg\n ctx.fillRect(plot.w + 1, y - 9, pw + 14, 18)\n ctx.fillStyle = theme.labelText\n ctx.fillText(priceLabel, plot.w + 8, y)\n\n // time tag\n if (bar) {\n const t = fmtDateTime(bar.time)\n ctx.textAlign = 'center'\n const tw = ctx.measureText(t).width\n const bx = Math.min(Math.max(x, tw / 2 + 6), plot.w - tw / 2 - 6)\n ctx.fillStyle = theme.labelBg\n ctx.fillRect(bx - tw / 2 - 7, plot.h + 3, tw + 14, 18)\n ctx.fillStyle = theme.labelText\n ctx.fillText(t, bx, plot.h + 12)\n }\n}\n\n","/**\n * Annotation model — normalisation, time→index resolution and collision\n * layout for markers.\n *\n * The geometry lives here rather than in the renderer so it can be reasoned\n * about (and tested) without a canvas, and out of Chart.js so the orchestrator\n * stays about orchestration.\n */\n\nexport const MARKER_SHAPES = [\n 'arrowUp',\n 'arrowDown',\n 'triangleUp',\n 'triangleDown',\n 'circle',\n 'square',\n 'diamond',\n 'flag',\n 'label',\n]\n\nconst SHAPE_SET = new Set(MARKER_SHAPES)\n\n/** Buys sit under the bar, sells over it — the convention traders expect. */\nconst DEFAULT_POSITION = {\n arrowUp: 'belowBar',\n triangleUp: 'belowBar',\n arrowDown: 'aboveBar',\n triangleDown: 'aboveBar',\n}\n\nconst POSITIONS = new Set(['aboveBar', 'belowBar', 'inBar', 'atPrice'])\n\nexport function normalizeMarker(raw, i) {\n if (!raw || !isFinite(raw.time)) return null\n const shape = SHAPE_SET.has(raw.shape) ? raw.shape : 'circle'\n const position = POSITIONS.has(raw.position)\n ? raw.position\n : DEFAULT_POSITION[shape] || 'aboveBar'\n return {\n id: raw.id != null ? String(raw.id) : `mk${i}`,\n time: +raw.time,\n price: isFinite(raw.price) ? +raw.price : null,\n shape,\n position,\n color: raw.color || null,\n textColor: raw.textColor || null,\n text: raw.text != null ? String(raw.text) : '',\n size: isFinite(raw.size) && raw.size > 0 ? +raw.size : 1,\n /** Anything the consumer wants handed back on hover/click. */\n data: raw.data,\n index: -1,\n }\n}\n\nexport function normalizeMarkers(list) {\n if (!Array.isArray(list)) return []\n const out = []\n for (let i = 0; i < list.length; i++) {\n const m = normalizeMarker(list[i], i)\n if (m) out.push(m)\n }\n out.sort((a, b) => a.time - b.time)\n return out\n}\n\n/**\n * Index of the bar closest in time to `time`; -1 with no bars.\n * Binary search — markers are resolved again whenever the bar array shifts\n * (a history page prepended in front of them moves every index).\n */\nexport function nearestIndex(bars, time) {\n const n = bars.length\n if (!n) return -1\n if (time <= bars[0].time) return 0\n if (time >= bars[n - 1].time) return n - 1\n\n let lo = 0\n let hi = n - 1\n while (lo <= hi) {\n const mid = (lo + hi) >> 1\n const t = bars[mid].time\n if (t === time) return mid\n if (t < time) lo = mid + 1\n else hi = mid - 1\n }\n const a = Math.max(0, hi)\n const b = Math.min(n - 1, lo)\n return Math.abs(bars[a].time - time) <= Math.abs(bars[b].time - time) ? a : b\n}\n\n/** Attach a bar index to every marker, in place. */\nexport function resolveMarkers(markers, bars) {\n for (let i = 0; i < markers.length; i++) {\n markers[i].index = nearestIndex(bars, markers[i].time)\n }\n return markers\n}\n\n/**\n * Place visible markers in screen space.\n *\n * Handles the two things that make markers look amateurish when skipped:\n * several markers on one bar overlapping, and thousands of them piling onto\n * the same pixels when zoomed out.\n */\nexport function layoutMarkers(markers, s) {\n const { ts, ps, plot, bars, live } = s\n if (!markers.length || !bars.length) return []\n\n const { from, to } = ts.visibleRange()\n const lastIdx = bars.length - 1\n const dense = ts.barWidth() <= 3\n const stacks = new Map()\n const placed = []\n let lastDenseX = -Infinity\n\n for (const m of markers) {\n const i = m.index\n if (i < 0 || i < from - 2 || i > to + 2) continue\n\n // the forming candle is interpolated, so anchor to the animated values\n const bar = live && i === lastIdx ? live : bars[i]\n if (!bar) continue\n\n const x = ts.x(i)\n if (x < -48 || x > plot.w + 48) continue\n\n // Zoomed far out, markers collapse onto the same pixels: drawing them all\n // costs frames and reads as noise. One per 4px is plenty.\n if (dense) {\n if (x - lastDenseX < 4) continue\n lastDenseX = x\n }\n\n const r = 5 * m.size\n let y\n let dir = 0\n\n if (m.position === 'atPrice' && m.price != null) {\n y = ps.y(m.price)\n } else if (m.position === 'inBar') {\n y = ps.y((bar.high + bar.low) / 2)\n } else if (m.position === 'belowBar') {\n y = ps.y(bar.low) + r + 7\n dir = 1\n } else {\n y = ps.y(bar.high) - r - 7\n dir = -1\n }\n\n // Two trades on one bar must not draw on top of each other.\n if (dir !== 0) {\n const key = i + m.position\n const n = stacks.get(key) || 0\n stacks.set(key, n + 1)\n y += dir * n * (r * 2 + 5)\n }\n\n placed.push({ m, x, y, r, dir })\n }\n\n return placed\n}\n","import { decimalsFor, priceTicks } from '../core/formatters.js'\nimport { nearestIndex } from '../overlays/annotations.js'\n\n/**\n * Annotation renderers: zones (behind the candles), price lines and markers\n * (in front of them). Each is a pure draw call over prepared state.\n */\n\nconst DASH = { solid: [], dashed: [6, 4], dotted: [1, 3] }\nconst DOWN_SHAPES = new Set(['arrowDown', 'triangleDown'])\n\nfunction roundRect(ctx, x, y, w, h, r) {\n const rr = Math.max(0, Math.min(r, h / 2, w / 2))\n ctx.beginPath()\n ctx.moveTo(x + rr, y)\n ctx.lineTo(x + w - rr, y)\n ctx.quadraticCurveTo(x + w, y, x + w, y + rr)\n ctx.lineTo(x + w, y + h - rr)\n ctx.quadraticCurveTo(x + w, y + h, x + w - rr, y + h)\n ctx.lineTo(x + rr, y + h)\n ctx.quadraticCurveTo(x, y + h, x, y + h - rr)\n ctx.lineTo(x, y + rr)\n ctx.quadraticCurveTo(x, y, x + rr, y)\n ctx.closePath()\n}\n\n/* ------------------------------------------------------------------ zones -- */\n/** Shaded regions. Drawn on the base layer, over the grid and under candles. */\nexport function drawZones(ctx, s) {\n const { zones, theme, ts, ps, plot, bars } = s\n if (!zones || !zones.length) return\n\n ctx.save()\n ctx.font = theme.font\n ctx.textBaseline = 'top'\n ctx.textAlign = 'left'\n\n for (const z of zones) {\n let x\n let y\n let w\n let h\n\n if (isFinite(z.from) && isFinite(z.to)) {\n // price band: spans the full width\n y = ps.y(Math.max(z.from, z.to))\n h = Math.max(1, ps.y(Math.min(z.from, z.to)) - y)\n x = 0\n w = plot.w\n } else if (isFinite(z.fromTime) && isFinite(z.toTime) && bars.length) {\n // time band: spans the full height\n const a = ts.x(nearestIndex(bars, Math.min(z.fromTime, z.toTime)))\n const b = ts.x(nearestIndex(bars, Math.max(z.fromTime, z.toTime)))\n x = a\n w = Math.max(1, b - a)\n y = 0\n h = plot.h\n } else {\n continue\n }\n\n if (x > plot.w || x + w < 0 || y > plot.h || y + h < 0) continue\n\n ctx.fillStyle = z.color || 'rgba(38,166,154,0.10)'\n ctx.fillRect(x, y, w, h)\n\n if (z.border) {\n ctx.strokeStyle = z.border\n ctx.lineWidth = 1\n ctx.strokeRect(Math.round(x) + 0.5, Math.round(y) + 0.5, Math.round(w), Math.round(h))\n }\n\n if (z.label) {\n ctx.fillStyle = z.labelColor || theme.text\n ctx.fillText(z.label, Math.max(6, x + 6), Math.max(4, y + 4))\n }\n }\n\n ctx.restore()\n}\n\n/* ------------------------------------------------------------- price lines -- */\n/** Horizontal lines with an optional left title pill and right axis tag. */\nexport function drawPriceLines(ctx, s) {\n const { priceLines, theme, ps, plot } = s\n if (!priceLines || !priceLines.length) return\n\n const { step } = priceTicks(ps.lo, ps.hi, Math.max(2, Math.floor(plot.h / 58)))\n const dec = decimalsFor(step)\n\n ctx.save()\n ctx.font = theme.font\n ctx.textBaseline = 'middle'\n\n for (const L of priceLines) {\n if (!L || !isFinite(L.price)) continue\n const y = Math.round(ps.y(L.price)) + 0.5\n if (y < 0 || y > plot.h) continue\n\n const color = L.color || theme.textStrong\n\n ctx.setLineDash(DASH[L.lineStyle] || DASH.dashed)\n ctx.strokeStyle = color\n ctx.lineWidth = L.lineWidth || 1\n ctx.beginPath()\n ctx.moveTo(0, y)\n ctx.lineTo(plot.w, y)\n ctx.stroke()\n ctx.setLineDash([])\n\n if (L.title) {\n ctx.textAlign = 'left'\n const tw = ctx.measureText(L.title).width\n ctx.fillStyle = color\n roundRect(ctx, 6, y - 9, tw + 12, 18, 4)\n ctx.fill()\n ctx.fillStyle = L.titleColor || theme.tagText\n ctx.fillText(L.title, 12, y)\n }\n\n if (L.axisLabel !== false) {\n const label = L.price.toFixed(dec)\n ctx.textAlign = 'left'\n const lw = ctx.measureText(label).width\n ctx.fillStyle = color\n ctx.fillRect(plot.w + 1, y - 9, lw + 14, 18)\n ctx.fillStyle = L.tagTextColor || theme.tagText\n ctx.fillText(label, plot.w + 8, y)\n }\n }\n\n ctx.restore()\n}\n\n/* ---------------------------------------------------------------- markers -- */\nfunction shapePath(ctx, shape, x, y, r) {\n ctx.beginPath()\n switch (shape) {\n case 'arrowUp':\n ctx.moveTo(x, y - r)\n ctx.lineTo(x + r, y)\n ctx.lineTo(x + r * 0.45, y)\n ctx.lineTo(x + r * 0.45, y + r)\n ctx.lineTo(x - r * 0.45, y + r)\n ctx.lineTo(x - r * 0.45, y)\n ctx.lineTo(x - r, y)\n ctx.closePath()\n break\n case 'arrowDown':\n ctx.moveTo(x, y + r)\n ctx.lineTo(x + r, y)\n ctx.lineTo(x + r * 0.45, y)\n ctx.lineTo(x + r * 0.45, y - r)\n ctx.lineTo(x - r * 0.45, y - r)\n ctx.lineTo(x - r * 0.45, y)\n ctx.lineTo(x - r, y)\n ctx.closePath()\n break\n case 'triangleUp':\n ctx.moveTo(x, y - r)\n ctx.lineTo(x + r, y + r)\n ctx.lineTo(x - r, y + r)\n ctx.closePath()\n break\n case 'triangleDown':\n ctx.moveTo(x, y + r)\n ctx.lineTo(x + r, y - r)\n ctx.lineTo(x - r, y - r)\n ctx.closePath()\n break\n case 'square':\n ctx.rect(x - r, y - r, r * 2, r * 2)\n break\n case 'diamond':\n ctx.moveTo(x, y - r)\n ctx.lineTo(x + r, y)\n ctx.lineTo(x, y + r)\n ctx.lineTo(x - r, y)\n ctx.closePath()\n break\n default:\n ctx.arc(x, y, r, 0, Math.PI * 2)\n }\n}\n\nfunction drawFlag(ctx, x, y, r, color) {\n ctx.fillStyle = color\n ctx.fillRect(x - r * 0.8, y - r, Math.max(1, r * 0.3), r * 2)\n ctx.beginPath()\n ctx.moveTo(x - r * 0.5, y - r)\n ctx.lineTo(x + r, y - r * 0.55)\n ctx.lineTo(x - r * 0.5, y - r * 0.1)\n ctx.closePath()\n ctx.fill()\n}\n\n/**\n * Draws placed markers and returns their hit circles, newest first, so the\n * chart can answer \"what is under the pointer?\" without re-deriving geometry.\n */\nexport function drawMarkers(ctx, s, placed, hoverId) {\n const hits = []\n if (!placed || !placed.length) return hits\n\n const { theme } = s\n ctx.save()\n ctx.font = theme.font\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n\n for (const p of placed) {\n const { m, x, y, r, dir } = p\n const color = m.color || (DOWN_SHAPES.has(m.shape) ? theme.down : theme.up)\n const hovered = hoverId != null && m.id === hoverId\n\n if (m.shape === 'label') {\n const text = m.text || '•'\n const w = ctx.measureText(text).width + 14\n const h = 18 * m.size\n roundRect(ctx, x - w / 2, y - h / 2, w, h, 4)\n ctx.fillStyle = color\n ctx.fill()\n if (hovered) {\n ctx.strokeStyle = theme.textStrong\n ctx.lineWidth = 1.5\n ctx.stroke()\n }\n ctx.fillStyle = m.textColor || theme.tagText\n ctx.fillText(text, x, y + 0.5)\n hits.push({ id: m.id, marker: m, x, y, r: Math.max(w, h) / 2 })\n continue\n }\n\n if (hovered) {\n ctx.beginPath()\n ctx.arc(x, y, r + 4, 0, Math.PI * 2)\n ctx.fillStyle = 'rgba(255,255,255,0.14)'\n ctx.fill()\n }\n\n if (m.shape === 'flag') {\n drawFlag(ctx, x, y, r, color)\n } else {\n shapePath(ctx, m.shape, x, y, r)\n ctx.fillStyle = color\n ctx.fill()\n }\n\n if (m.text) {\n ctx.fillStyle = m.textColor || theme.text\n ctx.fillText(m.text, x, dir >= 0 ? y + r + 9 : y - r - 9)\n }\n\n hits.push({ id: m.id, marker: m, x, y, r: r + 3 })\n }\n\n ctx.restore()\n return hits\n}\n","import { Layers } from './Layers.js'\nimport { Loop } from './Loop.js'\nimport { TimeScale } from './TimeScale.js'\nimport { PriceScale } from './PriceScale.js'\nimport { defaultTheme } from './palette.js'\nimport { LiveCandle } from '../motion/LiveCandle.js'\nimport { Inertia } from '../motion/Inertia.js'\nimport { drawGrid } from '../render/grid.js'\nimport { drawCandles } from '../render/candles.js'\nimport { drawCrosshair } from '../render/crosshair.js'\nimport { drawZones, drawPriceLines, drawMarkers } from '../render/annotations.js'\nimport { normalizeMarkers, resolveMarkers, layoutMarkers } from '../overlays/annotations.js'\n\n/**\n * Chart — the orchestrator. Owns the bar store, the scales, the input\n * handling and the frame composition. Framework-free by design: this file\n * touches nothing but DOM and Canvas, which is what lets the same core ship\n * as a React component, a Web Component, or a plain script tag.\n */\nexport class Chart {\n constructor(container, options = {}) {\n if (!container) throw new Error('Chart: container element is required')\n\n this.container = container\n this.theme = { ...defaultTheme, ...(options.theme || {}) }\n this.options = {\n volumeRatio: 0.18,\n magnet: true,\n animate: true,\n ...options,\n }\n\n this.bars = []\n this.feed = null\n this._unsub = null\n this._loadingHistory = false\n this._exhausted = false\n this._listeners = {\n crosshair: new Set(),\n visibleRange: new Set(),\n markerClick: new Set(),\n markerHover: new Set(),\n }\n\n // ---- annotations --------------------------------------------------\n // Markers carry a `time`; the renderer needs an index. Resolving is a\n // binary search per marker, so it is redone only when the bar array\n // actually shifts (a prepended history page moves every index).\n this._markers = normalizeMarkers(options.markers)\n this.priceLines = Array.isArray(options.priceLines) ? options.priceLines.slice() : []\n this.zones = Array.isArray(options.zones) ? options.zones.slice() : []\n this._markerHits = []\n this._hoverMarkerId = null\n this._resolveKey = ''\n\n this.layers = new Layers(container, ['base', 'main', 'overlay'])\n this.ts = new TimeScale(options.timeScale)\n this.ps = new PriceScale(options.priceScale)\n this.live = new LiveCandle()\n this.live.enabled = this.options.animate !== false\n this.inertia = new Inertia()\n\n this.cursor = null\n this.plot = { x: 0, y: 0, w: 1, h: 1 }\n\n this.loop = new Loop((dirty, dt) => this._frame(dirty, dt))\n this.layers.onResize = () => {\n this._layout()\n this.loop.invalidate('all')\n }\n\n this._layout()\n this._bindEvents()\n this.loop.start()\n }\n\n // ---------------------------------------------------------------- layout --\n _layout() {\n const { width, height } = this.layers\n const w = Math.max(1, width - this.theme.priceAxisWidth)\n const h = Math.max(1, height - this.theme.timeAxisHeight)\n this.plot = { x: 0, y: 0, w, h }\n this.ts.resize(w)\n this.ps.layout(0, h)\n }\n\n // ------------------------------------------------------------------ data --\n setData(bars) {\n this.bars = Array.isArray(bars) ? bars.slice() : []\n this._exhausted = false\n if (this.bars.length > 1) {\n this.ts.timeframeMs = this.bars[1].time - this.bars[0].time\n }\n this.ts.setBarCount(this.bars.length)\n this.ts.snapToRealtime()\n this.live.reset()\n this.ps._primed = false\n this.loop.invalidate('all')\n }\n\n /** Merge a tick into the forming candle (animated). */\n update(bar) {\n if (!bar) return\n const n = this.bars.length\n if (n && this.bars[n - 1].time === bar.time) {\n this.bars[n - 1] = bar\n } else {\n this.append(bar)\n return\n }\n this.live.setTarget(bar)\n this.loop.invalidate('main')\n }\n\n /** Open a new candle; the previous one is now closed. */\n append(bar) {\n if (!bar) return\n const n = this.bars.length\n if (n && bar.time <= this.bars[n - 1].time) {\n this.bars[n - 1] = bar\n } else {\n this.bars.push(bar)\n this.ts.setBarCount(this.bars.length)\n }\n this.live.setTarget(bar)\n this.loop.invalidate('main')\n }\n\n async setFeed(feed) {\n this.detachFeed()\n this.feed = feed\n if (!feed) return\n this.ts.timeframeMs = feed.timeframe || this.ts.timeframeMs\n const bars = await feed.getBars({\n symbol: feed.symbol,\n timeframe: feed.timeframe,\n to: null,\n limit: this.options.initialBars || 1500,\n })\n this.setData(bars)\n if (typeof feed.prime === 'function') feed.prime(bars[bars.length - 1])\n this._unsub = feed.subscribe((msg) => {\n if (!msg || !msg.bar) return\n if (msg.type === 'append') this.append(msg.bar)\n else this.update(msg.bar)\n })\n }\n\n detachFeed() {\n if (this._unsub) this._unsub()\n this._unsub = null\n this.feed = null\n }\n\n async _maybeLoadHistory() {\n if (this._loadingHistory || this._exhausted || !this.feed) return\n const { from } = this.ts.visibleRange()\n if (from > 80 || !this.bars.length) return\n\n this._loadingHistory = true\n try {\n const oldest = this.bars[0].time\n const older = await this.feed.getBars({\n symbol: this.feed.symbol,\n timeframe: this.feed.timeframe,\n to: oldest,\n limit: 1000,\n })\n if (!older || !older.length) {\n this._exhausted = true\n } else {\n const added = older.filter((b) => b.time < oldest)\n if (!added.length) {\n this._exhausted = true\n } else {\n this.bars = added.concat(this.bars)\n // keep the view pinned to the same bars: indices all shifted right\n const wasFollowing = this.ts.follow\n this.ts.barCount = this.bars.length\n this.ts._right.jump(this.ts._right.value + added.length)\n this.ts._right.set(this.ts._right.target + added.length)\n this.ts.follow = wasFollowing\n this.loop.invalidate('all')\n }\n }\n } catch (e) {\n console.error('[Emberwick] history load failed', e)\n this._exhausted = true\n } finally {\n this._loadingHistory = false\n }\n }\n\n // ---------------------------------------------------------------- events --\n _bindEvents() {\n const el = this.container\n el.style.touchAction = 'none'\n el.style.cursor = 'crosshair'\n\n let dragging = false\n let mode = null\n let lastX = 0\n let lastY = 0\n let lastT = 0\n let moved = false\n const pointers = new Map()\n let pinchDist = 0\n\n const localPos = (e) => {\n const r = el.getBoundingClientRect()\n return { x: e.clientX - r.left, y: e.clientY - r.top }\n }\n\n this._onDown = (e) => {\n pointers.set(e.pointerId, localPos(e))\n if (pointers.size === 2) {\n const [a, b] = [...pointers.values()]\n pinchDist = Math.hypot(a.x - b.x, a.y - b.y)\n dragging = false\n return\n }\n const p = localPos(e)\n dragging = true\n moved = false\n mode = p.x > this.plot.w ? 'price' : p.y > this.plot.h ? 'time' : 'pan'\n lastX = p.x\n lastY = p.y\n lastT = performance.now()\n this.inertia.stop()\n el.setPointerCapture(e.pointerId)\n }\n\n this._onMove = (e) => {\n const p = localPos(e)\n if (pointers.has(e.pointerId)) pointers.set(e.pointerId, p)\n\n if (pointers.size === 2) {\n const [a, b] = [...pointers.values()]\n const d = Math.hypot(a.x - b.x, a.y - b.y)\n if (pinchDist > 0 && d > 0) {\n const mid = (a.x + b.x) / 2\n this.ts.zoomAt(mid, d / pinchDist)\n this.loop.invalidate('all')\n }\n pinchDist = d\n return\n }\n\n this.cursor = p\n this._emitCrosshair(p)\n this.loop.invalidate('overlay')\n\n if (!dragging) return\n const now = performance.now()\n const dt = now - lastT\n const dx = p.x - lastX\n const dy = p.y - lastY\n if (Math.abs(dx) > 1 || Math.abs(dy) > 1) moved = true\n\n if (mode === 'pan') {\n this.ts.panBy(dx)\n this.inertia.sample(dx, dt)\n this.loop.invalidate('all')\n this._maybeLoadHistory()\n } else if (mode === 'price') {\n this.ps.scaleBy(1 + dy / 220)\n this.loop.invalidate('all')\n } else if (mode === 'time') {\n this.ts.zoomAt(this.plot.w, 1 - dx / 260)\n this.loop.invalidate('all')\n }\n\n lastX = p.x\n lastY = p.y\n lastT = now\n }\n\n this._onUp = (e) => {\n pointers.delete(e.pointerId)\n if (pointers.size < 2) pinchDist = 0\n if (dragging && mode === 'pan' && moved) {\n this.inertia.release()\n this.loop.invalidate('all')\n }\n dragging = false\n mode = null\n try { el.releasePointerCapture(e.pointerId) } catch (_) {}\n }\n\n this._onLeave = () => {\n this.cursor = null\n this._emitCrosshair(null)\n this.loop.invalidate('overlay')\n }\n\n this._onWheel = (e) => {\n e.preventDefault()\n const r = el.getBoundingClientRect()\n const x = e.clientX - r.left\n const factor = Math.pow(0.999, e.deltaY)\n this.ts.zoomAt(x, factor)\n this.loop.invalidate('all')\n this._maybeLoadHistory()\n }\n\n this._onDbl = () => {\n this.ts.reset()\n this.ps.resetAuto()\n this.loop.invalidate('all')\n }\n\n this._onKey = (e) => {\n const step = e.shiftKey ? 120 : 40\n if (e.key === 'ArrowLeft') { this.ts.panBy(step); this.loop.invalidate('all'); this._maybeLoadHistory() }\n else if (e.key === 'ArrowRight') { this.ts.panBy(-step); this.loop.invalidate('all') }\n else if (e.key === '+' || e.key === '=') { this.ts.zoomAt(this.plot.w / 2, 1.2); this.loop.invalidate('all') }\n else if (e.key === '-' || e.key === '_') { this.ts.zoomAt(this.plot.w / 2, 0.8); this.loop.invalidate('all') }\n else return\n e.preventDefault()\n }\n\n this._onClick = (e) => {\n // `moved` is still set from the gesture that just ended — a pan that\n // happens to finish over a marker must not read as a click on it.\n if (moved) return\n if (!this._listeners.markerClick.size) return\n const p = localPos(e)\n const hit = this.markerAt(p.x, p.y)\n if (hit) for (const fn of this._listeners.markerClick) fn(hit)\n }\n\n el.addEventListener('click', this._onClick)\n el.addEventListener('pointerdown', this._onDown)\n el.addEventListener('pointermove', this._onMove)\n el.addEventListener('pointerup', this._onUp)\n el.addEventListener('pointercancel', this._onUp)\n el.addEventListener('pointerleave', this._onLeave)\n el.addEventListener('wheel', this._onWheel, { passive: false })\n el.addEventListener('dblclick', this._onDbl)\n el.addEventListener('keydown', this._onKey)\n if (!el.hasAttribute('tabindex')) el.setAttribute('tabindex', '0')\n }\n\n _emitCrosshair(p) {\n if (this._listeners.crosshair.size) {\n let payload = null\n if (p && this.bars.length && p.x <= this.plot.w && p.y <= this.plot.h) {\n const i = Math.round(this.ts.index(p.x))\n const bar = this.bars[i]\n if (bar) payload = { index: i, bar, price: this.ps.price(p.y) }\n }\n for (const fn of this._listeners.crosshair) fn(payload)\n }\n this._updateHover(p)\n }\n\n /**\n * Topmost marker whose hit circle contains the point, else null.\n * Hit circles come from the last render, so this costs nothing but a loop.\n */\n markerAt(x, y) {\n const hits = this._markerHits\n for (let i = hits.length - 1; i >= 0; i--) {\n const h = hits[i]\n const dx = x - h.x\n const dy = y - h.y\n if (dx * dx + dy * dy <= h.r * h.r) return h.marker\n }\n return null\n }\n\n _updateHover(p) {\n const hit = p ? this.markerAt(p.x, p.y) : null\n const id = hit ? hit.id : null\n if (id === this._hoverMarkerId) return\n this._hoverMarkerId = id\n this.container.style.cursor = hit ? 'pointer' : 'crosshair'\n // the hover ring is drawn with the markers, so that layer must repaint\n this.loop.invalidate('main')\n for (const fn of this._listeners.markerHover) fn(hit)\n }\n\n subscribe(event, fn) {\n const set = this._listeners[event]\n if (!set) throw new Error(`Chart: unknown event \"${event}\"`)\n set.add(fn)\n return () => set.delete(fn)\n }\n\n // ----------------------------------------------------------- annotations --\n /** Replace every marker. Each `time` is resolved to its nearest bar. */\n setMarkers(markers) {\n this._markers = normalizeMarkers(markers)\n this._resolveKey = '' // force re-resolution on the next frame\n this.loop.invalidate('main')\n }\n\n /** The current markers, normalised, each with its resolved bar index. */\n getMarkers() {\n return this._markers.slice()\n }\n\n addMarker(marker) {\n this.setMarkers(this._markers.concat([marker]))\n }\n\n removeMarker(id) {\n const key = String(id)\n this.setMarkers(this._markers.filter((m) => m.id !== key))\n }\n\n clearMarkers() {\n this.setMarkers([])\n }\n\n /** Horizontal lines — entries, stops, targets, alerts. */\n setPriceLines(lines) {\n this.priceLines = Array.isArray(lines) ? lines.slice() : []\n this.loop.invalidate('main')\n }\n\n /** Shaded regions: a price band ({from,to}) or a time band ({fromTime,toTime}). */\n setZones(zones) {\n this.zones = Array.isArray(zones) ? zones.slice() : []\n this.loop.invalidate('all')\n }\n\n // ----------------------------------------------------------------- frame --\n _frame(dirty, dt) {\n let animating = false\n\n if (this.ts.tick(dt)) animating = true\n\n const dx = this.inertia.tick(dt)\n if (dx) {\n this.ts.panBy(dx)\n animating = true\n this._maybeLoadHistory()\n }\n\n if (this.live.tick(dt)) animating = true\n\n const { from, to } = this.ts.visibleRange()\n const lastIdx = this.bars.length - 1\n const liveBar = this.bars.length ? this.live.read(this.bars[lastIdx]) : null\n const liveVisible = liveBar && to >= lastIdx ? liveBar : null\n\n this.ps.fit(this.bars, from, to, liveVisible)\n if (this.ps.tick(dt)) animating = true\n\n const redrawAll = animating || dirty.has('all') || dirty.has('base') || dirty.has('main')\n const state = {\n theme: this.theme,\n ts: this.ts,\n ps: this.ps,\n plot: this.plot,\n bars: this.bars,\n width: this.layers.width,\n height: this.layers.height,\n live: liveVisible,\n volumeRatio: this.options.volumeRatio,\n cursor: this.cursor,\n magnet: this.options.magnet,\n priceLines: this.priceLines,\n zones: this.zones,\n }\n\n // Marker indices only go stale when the bar array shifts: a prepended\n // history page renumbers every bar, an append does not.\n if (this._markers.length) {\n const key = this.bars.length + ':' + (this.bars.length ? this.bars[0].time : 0)\n if (key !== this._resolveKey) {\n resolveMarkers(this._markers, this.bars)\n this._resolveKey = key\n }\n }\n\n if (redrawAll) {\n drawGrid(this.layers.ctx.base, state)\n drawZones(this.layers.ctx.base, state)\n drawCandles(this.layers.ctx.main, state)\n drawPriceLines(this.layers.ctx.main, state)\n this._markerHits = drawMarkers(\n this.layers.ctx.main,\n state,\n layoutMarkers(this._markers, state),\n this._hoverMarkerId,\n )\n }\n if (redrawAll || dirty.has('overlay')) {\n drawCrosshair(this.layers.ctx.overlay, state)\n }\n\n return animating\n }\n\n // ------------------------------------------------------------------- api --\n get fps() { return this.loop.fps }\n\n setTheme(theme) {\n this.theme = { ...this.theme, ...theme }\n this._layout()\n this.loop.invalidate('all')\n }\n\n setPriceMode(mode) {\n this.ps.setMode(mode)\n this.loop.invalidate('all')\n }\n\n setAnimate(on) {\n this.live.enabled = !!on\n this.loop.invalidate('all')\n }\n\n setMagnet(on) {\n this.options.magnet = !!on\n this.loop.invalidate('overlay')\n }\n\n snapToRealtime() {\n this.ts.snapToRealtime()\n this.ps.resetAuto()\n this.loop.invalidate('all')\n }\n\n toImage() {\n return this.layers.composite().toDataURL('image/png')\n }\n\n destroy() {\n const el = this.container\n el.removeEventListener('pointerdown', this._onDown)\n el.removeEventListener('pointermove', this._onMove)\n el.removeEventListener('pointerup', this._onUp)\n el.removeEventListener('pointercancel', this._onUp)\n el.removeEventListener('pointerleave', this._onLeave)\n el.removeEventListener('wheel', this._onWheel)\n el.removeEventListener('dblclick', this._onDbl)\n el.removeEventListener('keydown', this._onKey)\n el.removeEventListener('click', this._onClick)\n this.detachFeed()\n this.loop.stop()\n this.layers.destroy()\n for (const set of Object.values(this._listeners)) set.clear()\n this._markers = []\n this._markerHits = []\n this.priceLines = []\n this.zones = []\n this.bars = []\n }\n}\n\n","/**\n * DataFeed — THE seam of this library.\n *\n * The chart core never knows where bars come from. Anything that implements\n * this interface can drive it: a REST endpoint, a WebSocket, a Lambda behind\n * API Gateway, a CSV in memory, or the bundled RandomFeed.\n *\n * Bar shape (the only contract that matters):\n * { time: number (ms epoch), open, high, low, close, volume }\n * Bars MUST be ascending by time and de-duplicated by the feed.\n *\n * Implement:\n * getBars({ symbol, timeframe, to, limit }) -> Promise<Bar[]>\n * Historical bars ENDING at `to` (exclusive). Return [] when exhausted;\n * the chart stops asking for more history once it sees an empty page.\n * subscribe(handler) -> unsubscribe fn\n * handler({ type: 'update'|'append', bar }) where\n * 'update' = the forming candle changed (animates)\n * 'append' = a new candle opened (previous one is now closed)\n */\nexport class DataFeed {\n constructor({ symbol = 'DEMO', timeframe = 60000 } = {}) {\n this.symbol = symbol\n this.timeframe = timeframe\n }\n\n // eslint-disable-next-line no-unused-vars\n async getBars({ symbol, timeframe, to, limit }) {\n throw new Error('DataFeed.getBars() not implemented')\n }\n\n // eslint-disable-next-line no-unused-vars\n subscribe(handler) {\n return () => {}\n }\n\n destroy() {}\n}\n\n/** Deterministic PRNG so a given seed always renders the same chart. */\nexport function mulberry32(seed) {\n let a = seed >>> 0\n return function () {\n a = (a + 0x6d2b79f5) | 0\n let t = Math.imul(a ^ (a >>> 15), 1 | a)\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n","import { DataFeed, mulberry32 } from './DataFeed.js'\n\n/**\n * RandomFeed — a plausible synthetic market. One implementation of DataFeed,\n * nothing more: swapping in a real provider is writing another class, with\n * zero changes to the chart core.\n *\n * Generates a GBM-ish random walk with volatility clustering and a volume\n * profile, then drives a live forming candle from sub-bar ticks.\n */\nexport class RandomFeed extends DataFeed {\n constructor({\n symbol = 'EMBR',\n timeframe = 60000,\n seed = 7,\n start = 100,\n volatility = 0.0022,\n drift = 0.00002,\n ticksPerSecond = 8,\n speed = 1,\n } = {}) {\n super({ symbol, timeframe })\n this.seed = seed\n this.start = start\n this.volatility = volatility\n this.drift = drift\n this.ticksPerSecond = ticksPerSecond\n this.speed = speed\n\n this._rnd = mulberry32(seed)\n this._handlers = new Set()\n this._timer = null\n this._forming = null\n this._last = start\n this._vol = volatility\n this._anchorTime = Math.floor(Date.now() / timeframe) * timeframe\n }\n\n _gauss() {\n // Box-Muller\n let u = 0\n let v = 0\n while (u === 0) u = this._rnd()\n while (v === 0) v = this._rnd()\n return Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v)\n }\n\n _step(price) {\n // volatility clusters: vol mean-reverts but gets kicked by shocks\n const shock = this._gauss()\n this._vol += (this.volatility - this._vol) * 0.02 + Math.abs(shock) * this.volatility * 0.015\n this._vol = Math.min(this._vol, this.volatility * 6)\n return Math.max(0.01, price * (1 + this.drift + shock * this._vol))\n }\n\n _makeBar(time, open) {\n let c = open\n const n = 14\n let hi = open\n let lo = open\n for (let i = 0; i < n; i++) {\n c = this._step(c)\n if (c > hi) hi = c\n if (c < lo) lo = c\n }\n const range = Math.max(1e-9, hi - lo)\n const volume = Math.round(\n (300 + this._rnd() * 900) * (1 + (range / open) * 260)\n )\n return { time, open, high: hi, low: lo, close: c, volume }\n }\n\n /**\n * Historical bars ending just before `to`. Walks BACKWARDS from a synthetic\n * anchor, so paging further left keeps producing coherent history.\n */\n async getBars({ to, limit = 1500, timeframe = this.timeframe } = {}) {\n const end = to == null ? this._anchorTime : to\n const bars = []\n // generate forward from an earlier point for realistic shape, then slice\n const startTime = end - limit * timeframe\n const gen = mulberry32(this.seed ^ Math.floor(startTime / timeframe))\n const saved = this._rnd\n this._rnd = gen\n\n let price = this.start * (1 + (gen() - 0.5) * 0.04)\n for (let i = 0; i < limit; i++) {\n const t = startTime + i * timeframe\n const bar = this._makeBar(t, price)\n price = bar.close\n bars.push(bar)\n }\n this._rnd = saved\n\n if (to == null) {\n this._last = bars.length ? bars[bars.length - 1].close : this.start\n }\n return bars\n }\n\n subscribe(handler) {\n this._handlers.add(handler)\n if (!this._timer) this._start()\n return () => {\n this._handlers.delete(handler)\n if (!this._handlers.size) this.stop()\n }\n }\n\n _emit(msg) {\n for (const h of this._handlers) h(msg)\n }\n\n _start() {\n const interval = Math.max(16, 1000 / this.ticksPerSecond)\n this._timer = setInterval(() => this._tick(), interval)\n }\n\n /** Seed the live candle from wherever history ended. */\n prime(lastBar) {\n if (lastBar) {\n this._last = lastBar.close\n this._forming = { ...lastBar }\n }\n }\n\n _tick() {\n const tf = this.timeframe / this.speed\n const now = Date.now()\n const slot = Math.floor(now / tf) * tf\n\n if (!this._forming || this._forming.time !== slot) {\n const open = this._last\n this._forming = { time: slot, open, high: open, low: open, close: open, volume: 0 }\n this._emit({ type: 'append', bar: { ...this._forming } })\n return\n }\n\n const next = this._step(this._last)\n this._last = next\n const f = this._forming\n f.close = next\n if (next > f.high) f.high = next\n if (next < f.low) f.low = next\n f.volume += Math.round(20 + this._rnd() * 120)\n this._emit({ type: 'update', bar: { ...f } })\n }\n\n setSpeed(s) { this.speed = s }\n\n setTicksPerSecond(n) {\n this.ticksPerSecond = n\n if (this._timer) { this.stop(); this._start() }\n }\n\n setPaused(paused) {\n if (paused) this.stop()\n else if (!this._timer && this._handlers.size) this._start()\n }\n\n get paused() { return !this._timer }\n\n stop() {\n if (this._timer) clearInterval(this._timer)\n this._timer = null\n }\n\n destroy() {\n this.stop()\n this._handlers.clear()\n }\n}\n","/**\n * Emberwick — public API surface.\n *\n * This file is the future package entry point. Nothing below imports a\n * framework, so the same build drops into React, Vue, Svelte or a script tag.\n *\n * import { createChart, RandomFeed } from './chart/index.js'\n * const chart = createChart(el, { theme: { background: '#000' } })\n * await chart.setFeed(new RandomFeed({ timeframe: 60000 }))\n */\nexport { Chart } from './core/Chart.js'\nexport { TimeScale } from './core/TimeScale.js'\nexport { PriceScale } from './core/PriceScale.js'\nexport { defaultTheme, lightTheme } from './core/palette.js'\nexport { DataFeed, mulberry32 } from './data/DataFeed.js'\nexport { RandomFeed } from './data/RandomFeed.js'\nexport { Smoothed, Tween, easeOutCubic, easeInOutCubic } from './motion/Tween.js'\nexport { Inertia } from './motion/Inertia.js'\nexport { LiveCandle } from './motion/LiveCandle.js'\n\nimport { Chart } from './core/Chart.js'\n\n/** Preferred entry point. */\nexport function createChart(container, options) {\n return new Chart(container, options)\n}\n\nexport const version = '0.2.0'\n\n"],"names":["Layers","container","names","name","i","c","r","w","h","dpr","n","out","Loop","onFrame","layers","l","now","dt","dirty","wantMore","e","easeOutCubic","t","easeInOutCubic","Smoothed","value","tau","target","v","eps","Tween","duration","ease","clamp","a","b","TimeScale","spacing","minSpacing","maxSpacing","rightOffset","grew","x","s","first","last","max","min","dxPx","next","factor","s0","s1","anchorX","r1","PriceScale","mode","marginTop","marginBottom","lo","hi","top","height","price","y","bars","from","to","extra","pad","mid","half","defaultTheme","lightTheme","LiveCandle","bar","moving","o","Inertia","friction","dx","instant","niceStep","span","count","raw","mag","priceTicks","step","ticks","start","decimalsFor","niceBarStep","minBars","opts","p2","fmtAxisTime","ms","tfMs","d","fmtDateTime","drawGrid","ctx","theme","ts","ps","plot","width","rows","dec","stepBars","ty","drawCandles","live","volumeRatio","bw","thin","volH","volTop","vmax","isLast","up","color","yO","yC","yH","yL","scale","cx","bodyH","lastBar","label","tw","drawCrosshair","cursor","magnet","cands","best","bestD","p","py","priceLabel","pw","bx","MARKER_SHAPES","SHAPE_SET","DEFAULT_POSITION","POSITIONS","normalizeMarker","shape","position","normalizeMarkers","list","m","nearestIndex","time","resolveMarkers","markers","layoutMarkers","lastIdx","dense","stacks","placed","lastDenseX","dir","key","DASH","DOWN_SHAPES","roundRect","rr","drawZones","zones","z","drawPriceLines","priceLines","L","lw","shapePath","drawFlag","drawMarkers","hoverId","hits","hovered","text","Chart","options","feed","msg","oldest","older","added","wasFollowing","el","dragging","lastX","lastY","lastT","moved","pointers","pinchDist","localPos","dy","hit","fn","payload","id","event","set","marker","lines","animating","liveBar","liveVisible","redrawAll","state","on","DataFeed","symbol","timeframe","limit","handler","mulberry32","seed","RandomFeed","volatility","drift","ticksPerSecond","speed","u","shock","open","range","volume","end","startTime","gen","saved","interval","tf","slot","f","paused","createChart","version"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"emberwick.umd.js","sources":["../../src/chart/core/Layers.js","../../src/chart/core/Loop.js","../../src/chart/motion/Tween.js","../../src/chart/core/TimeScale.js","../../src/chart/core/PriceScale.js","../../src/chart/core/palette.js","../../src/chart/motion/LiveCandle.js","../../src/chart/motion/Inertia.js","../../src/chart/core/formatters.js","../../src/chart/render/grid.js","../../src/chart/render/candles.js","../../src/chart/render/crosshair.js","../../src/chart/overlays/annotations.js","../../src/chart/render/annotations.js","../../src/chart/core/Chart.js","../../src/chart/data/DataFeed.js","../../src/chart/data/RandomFeed.js","../../src/chart/index.js"],"sourcesContent":["/**\n * Layers — stacked canvases sharing one coordinate space.\n *\n * Why: the crosshair repaints on every pointer move, the candles do not.\n * Separate canvases mean moving the cursor never touches candle pixels.\n * All contexts are pre-scaled by devicePixelRatio, so every renderer draws\n * in CSS pixels and gets crisp output on retina.\n */\nexport class Layers {\n constructor(container, names) {\n this.container = container\n this.names = names\n this.canvas = {}\n this.ctx = {}\n this.width = 0\n this.height = 0\n this.dpr = 0\n this.onResize = null\n\n if (getComputedStyle(container).position === 'static') {\n container.style.position = 'relative'\n }\n\n names.forEach((name, i) => {\n const c = document.createElement('canvas')\n Object.assign(c.style, {\n position: 'absolute',\n left: '0',\n top: '0',\n width: '100%',\n height: '100%',\n pointerEvents: 'none',\n zIndex: String(i + 1),\n })\n container.appendChild(c)\n this.canvas[name] = c\n this.ctx[name] = c.getContext('2d')\n })\n\n this._ro = new ResizeObserver(() => this.measure())\n this._ro.observe(container)\n this.measure()\n }\n\n measure() {\n const r = this.container.getBoundingClientRect()\n const w = Math.max(1, Math.floor(r.width))\n const h = Math.max(1, Math.floor(r.height))\n const dpr = Math.min(window.devicePixelRatio || 1, 2)\n if (w === this.width && h === this.height && dpr === this.dpr) return\n this.width = w\n this.height = h\n this.dpr = dpr\n for (const n of this.names) {\n const c = this.canvas[n]\n c.width = Math.floor(w * dpr)\n c.height = Math.floor(h * dpr)\n this.ctx[n].setTransform(dpr, 0, 0, dpr, 0, 0)\n }\n if (this.onResize) this.onResize(w, h)\n }\n\n /** Flatten all layers into a single canvas (for toImage/export). */\n composite() {\n const out = document.createElement('canvas')\n out.width = Math.floor(this.width * this.dpr)\n out.height = Math.floor(this.height * this.dpr)\n const c = out.getContext('2d')\n for (const n of this.names) c.drawImage(this.canvas[n], 0, 0)\n return out\n }\n\n destroy() {\n this._ro.disconnect()\n for (const n of this.names) this.canvas[n].remove()\n this.canvas = {}\n this.ctx = {}\n }\n}\n","/**\n * Loop — ONE requestAnimationFrame loop for the whole chart, driven by\n * dirty flags. 500 feed ticks between two frames still cost one repaint.\n *\n * The frame callback returns `true` while animation is in flight, which is\n * what keeps the loop running; otherwise it idles at zero CPU until something\n * calls invalidate().\n */\nexport class Loop {\n constructor(onFrame) {\n this.onFrame = onFrame\n this.fps = 0\n this._raf = 0\n this._dirty = new Set()\n this._last = 0\n this._running = false\n this._frames = 0\n this._fpsAt = 0\n this._tick = this._tick.bind(this)\n }\n\n invalidate(...layers) {\n if (!layers.length) this._dirty.add('all')\n else for (const l of layers) this._dirty.add(l)\n this._schedule()\n }\n\n start() {\n if (this._running) return\n this._running = true\n this._last = performance.now()\n this._fpsAt = this._last\n this.invalidate('all')\n }\n\n stop() {\n this._running = false\n if (this._raf) cancelAnimationFrame(this._raf)\n this._raf = 0\n }\n\n _schedule() {\n if (this._raf || !this._running) return\n this._raf = requestAnimationFrame(this._tick)\n }\n\n _tick(now) {\n this._raf = 0\n if (!this._running) return\n const dt = Math.min(Math.max(now - this._last, 1), 64)\n this._last = now\n\n this._frames++\n if (now - this._fpsAt >= 500) {\n this.fps = Math.round((this._frames * 1000) / (now - this._fpsAt))\n this._frames = 0\n this._fpsAt = now\n }\n\n const dirty = this._dirty\n this._dirty = new Set()\n\n let wantMore = false\n try {\n wantMore = this.onFrame(dirty, dt, now) === true\n } catch (e) {\n console.error('[Emberwick] frame error', e)\n }\n if (wantMore || this._dirty.size) this._schedule()\n }\n}\n","// Motion primitives. Everything animated in Emberwick goes through one of these\n// two classes so there is exactly one place that owns easing behaviour.\n\nexport const easeOutCubic = (t) => 1 - Math.pow(1 - t, 3)\nexport const easeInOutCubic = (t) =>\n t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2\n\n/**\n * Smoothed — exponential smoothing toward a target that may move every frame.\n * Frame-rate independent: the same visual speed at 30fps and 144fps.\n * Use for values that are continuously re-targeted (autoscale, live candle, zoom).\n */\nexport class Smoothed {\n constructor(value = 0, tau = 90) {\n this.value = value\n this.target = value\n this.tau = tau\n }\n\n set(target) {\n this.target = target\n }\n\n /** Snap with no animation. */\n jump(v) {\n this.value = v\n this.target = v\n }\n\n get settled() {\n const eps = 1e-9 + Math.abs(this.target) * 1e-6\n return Math.abs(this.target - this.value) <= eps\n }\n\n /** @returns {boolean} true while still moving (caller keeps the loop alive) */\n tick(dt) {\n if (this.settled) {\n this.value = this.target\n return false\n }\n this.value += (this.target - this.value) * (1 - Math.exp(-dt / this.tau))\n return true\n }\n}\n\n/**\n * Tween — fixed-duration one-shot, for discrete events (a candle being born).\n */\nexport class Tween {\n constructor(duration = 200, ease = easeOutCubic) {\n this.duration = duration\n this.ease = ease\n this.t = duration\n }\n\n restart() {\n this.t = 0\n }\n\n get done() {\n return this.t >= this.duration\n }\n\n get progress() {\n return this.ease(Math.min(1, this.t / this.duration))\n }\n\n tick(dt) {\n if (this.done) return false\n this.t += dt\n return true\n }\n}\n","import { Smoothed } from '../motion/Tween.js'\n\nconst clamp = (v, a, b) => (v < a ? a : v > b ? b : v)\n\n/**\n * TimeScale — maps bar index <-> x pixels.\n *\n * Two smoothed values define the view:\n * spacing : px per bar (zoom)\n * right : float bar index sitting at the right edge of the plot\n *\n * Both are Smoothed, so a wheel zoom eases instead of stepping, and new bars\n * glide in rather than jumping. Dragging uses jump() so the chart stays glued\n * to the pointer — easing a drag feels like lag, not smoothness.\n */\nexport class TimeScale {\n constructor({ spacing = 9, minSpacing = 0.8, maxSpacing = 160, rightOffset = 12 } = {}) {\n this.minSpacing = minSpacing\n this.maxSpacing = maxSpacing\n this.rightOffset = rightOffset\n this.width = 0\n this.barCount = 0\n this.follow = true\n this.timeframeMs = 60000\n this._spacing = new Smoothed(spacing, 65)\n this._right = new Smoothed(rightOffset, 65)\n this._initial = spacing\n }\n\n get spacing() { return this._spacing.value }\n get right() { return this._right.value }\n\n resize(w) { this.width = Math.max(1, w) }\n\n setBarCount(n) {\n const grew = n > this.barCount\n this.barCount = n\n if (this.follow) {\n // target the new last bar; Smoothed turns this into a glide\n const t = n - 1 + this.rightOffset\n if (grew) this._right.set(t)\n else this._right.jump(t)\n }\n }\n\n x(i) { return this.width - (this._right.value - i) * this._spacing.value }\n\n /** Centre-x of bar i (bars are drawn centred on their slot). */\n index(x) { return this._right.value - (this.width - x) / this._spacing.value }\n\n barWidth() {\n const s = this._spacing.value\n // leave a gap between candles, but never thinner than a hairline\n return Math.max(1, Math.floor(s * 0.72))\n }\n\n visibleRange() {\n const first = Math.floor(this.index(0)) - 1\n const last = Math.ceil(this.index(this.width)) + 1\n return {\n from: clamp(first, 0, Math.max(0, this.barCount - 1)),\n to: clamp(last, 0, Math.max(0, this.barCount - 1)),\n }\n }\n\n _clampRight(v) {\n const max = this.barCount - 1 + this.rightOffset + this.width / this._spacing.target\n const min = Math.min(4, this.barCount - 1 + this.rightOffset)\n return clamp(v, min, max)\n }\n\n /** Immediate pan, in pixels. Positive dx drags content right (back in time). */\n panBy(dxPx) {\n if (!dxPx) return false\n const next = this._clampRight(this._right.value - dxPx / this._spacing.value)\n this._right.jump(next)\n this.follow = false\n return true\n }\n\n /** Zoom by `factor`, keeping the bar under `x` pinned. */\n zoomAt(x, factor) {\n const s0 = this._spacing.target\n const s1 = clamp(s0 * factor, this.minSpacing, this.maxSpacing)\n if (Math.abs(s1 - s0) < 1e-9) return false\n\n // While following realtime, pin the right edge instead of the cursor so the\n // latest candle stays put — that is what traders expect.\n const anchorX = this.follow ? this.width : x\n const r0 = this._right.target\n const idx = r0 - (this.width - anchorX) / s0\n const r1 = idx + (this.width - anchorX) / s1\n\n this._spacing.set(s1)\n this._right.set(this._clampRight(r1))\n return true\n }\n\n snapToRealtime() {\n this.follow = true\n this._right.set(this.barCount - 1 + this.rightOffset)\n }\n\n reset() {\n this._spacing.set(this._initial)\n this.snapToRealtime()\n }\n\n /** True while the view is still easing. */\n tick(dt) {\n const a = this._spacing.tick(dt)\n const b = this._right.tick(dt)\n return a || b\n }\n\n get settled() { return this._spacing.settled && this._right.settled }\n}\n","import { Smoothed } from '../motion/Tween.js'\n\nconst clamp = (v, a, b) => (v < a ? a : v > b ? b : v)\n\n/**\n * PriceScale — maps price <-> y pixels, with animated autoscale.\n *\n * Bounds live in *transformed* space (identity for linear, log for log), so\n * switching modes is a one-line change and the easing still behaves.\n * The whole point of smoothing here: when a spike arrives the range glides to\n * its new bounds instead of the chart snapping and losing the reader.\n */\nexport class PriceScale {\n constructor({ mode = 'linear', tau = 120, marginTop = 0.12, marginBottom = 0.12 } = {}) {\n this.mode = mode\n this.marginTop = marginTop\n this.marginBottom = marginBottom\n this.auto = true\n this.top = 0\n this.height = 1\n this._lo = new Smoothed(0, tau)\n this._hi = new Smoothed(1, tau)\n this._primed = false\n }\n\n _fwd(v) { return this.mode === 'log' ? Math.log(Math.max(v, 1e-9)) : v }\n _inv(v) { return this.mode === 'log' ? Math.exp(v) : v }\n\n setMode(mode) {\n if (mode === this.mode) return\n const lo = this._inv(this._lo.value)\n const hi = this._inv(this._hi.value)\n this.mode = mode\n this._lo.jump(this._fwd(lo))\n this._hi.jump(this._fwd(hi))\n }\n\n layout(top, height) {\n this.top = top\n this.height = Math.max(1, height)\n }\n\n get lo() { return this._inv(this._lo.value) }\n get hi() { return this._inv(this._hi.value) }\n\n y(price) {\n const a = this._lo.value\n const b = this._hi.value\n const t = (this._fwd(price) - a) / (b - a || 1)\n return this.top + this.height * (1 - t)\n }\n\n price(y) {\n const a = this._lo.value\n const b = this._hi.value\n const t = 1 - (y - this.top) / this.height\n return this._inv(a + t * (b - a))\n }\n\n /** Fit visible bars. `extra` lets the forming candle influence the range. */\n fit(bars, from, to, extra) {\n if (!this.auto || !bars.length) return\n let min = Infinity\n let max = -Infinity\n for (let i = from; i <= to; i++) {\n const b = bars[i]\n if (!b) continue\n if (b.low < min) min = b.low\n if (b.high > max) max = b.high\n }\n if (extra) {\n if (extra.low < min) min = extra.low\n if (extra.high > max) max = extra.high\n }\n if (!isFinite(min) || !isFinite(max)) return\n\n let a = this._fwd(min)\n let b = this._fwd(max)\n let pad = (b - a) * this.marginTop\n if (!(pad > 0)) pad = Math.abs(b) * 0.01 || 1\n a -= pad\n b += (b - a) * 0 + pad\n\n this._lo.set(a)\n this._hi.set(b)\n if (!this._primed) {\n this._lo.jump(a)\n this._hi.jump(b)\n this._primed = true\n }\n }\n\n /** Manual axis-drag scaling around the vertical centre. */\n scaleBy(factor) {\n this.auto = false\n const a = this._lo.target\n const b = this._hi.target\n const mid = (a + b) / 2\n const half = ((b - a) / 2) * clamp(factor, 0.2, 5)\n this._lo.set(mid - half)\n this._hi.set(mid + half)\n }\n\n resetAuto() {\n this.auto = true\n }\n\n tick(dt) {\n const a = this._lo.tick(dt)\n const b = this._hi.tick(dt)\n return a || b\n }\n}\n","export const defaultTheme = {\n background: '#0b0e14',\n grid: 'rgba(255,255,255,0.045)',\n axisLine: 'rgba(255,255,255,0.10)',\n text: '#8b93a7',\n textStrong: '#e6e9ef',\n up: '#26a69a',\n down: '#ef5350',\n upFill: '#26a69a',\n downFill: '#ef5350',\n wickUp: '#26a69a',\n wickDown: '#ef5350',\n volumeUp: 'rgba(38,166,154,0.30)',\n volumeDown: 'rgba(239,83,80,0.30)',\n crosshair: 'rgba(255,255,255,0.32)',\n labelBg: '#2a3040',\n labelText: '#e6e9ef',\n tagText: '#06080d',\n font: '11px ui-sans-serif, -apple-system, \"Segoe UI\", Roboto, sans-serif',\n priceAxisWidth: 68,\n timeAxisHeight: 26,\n}\n\nexport const lightTheme = {\n ...defaultTheme,\n background: '#ffffff',\n grid: 'rgba(0,0,0,0.06)',\n axisLine: 'rgba(0,0,0,0.14)',\n text: '#6b7280',\n textStrong: '#111827',\n labelBg: '#374151',\n volumeUp: 'rgba(38,166,154,0.25)',\n volumeDown: 'rgba(239,83,80,0.25)',\n crosshair: 'rgba(0,0,0,0.35)',\n tagText: '#ffffff',\n}\n","import { Smoothed, Tween } from './Tween.js'\n\n/**\n * LiveCandle — makes the forming (rightmost) candle *flow* instead of snapping.\n *\n * A raw feed tick replaces close/high/low instantly, which reads as a jitter.\n * Here every component eases toward the incoming value, and a brand new candle\n * plays a short grow-from-centre animation as it scrolls in.\n */\nexport class LiveCandle {\n constructor(tau = 55) {\n this.enabled = true\n this.o = new Smoothed(0, tau)\n this.h = new Smoothed(0, tau)\n this.l = new Smoothed(0, tau)\n this.c = new Smoothed(0, tau)\n this.vol = new Smoothed(0, tau * 2)\n this.spawn = new Tween(240)\n this._has = false\n this._time = null\n }\n\n setTarget(bar) {\n if (!bar) {\n this._has = false\n return\n }\n if (!this._has || bar.time !== this._time) {\n // New candle: start collapsed at its open, then animate outward.\n this.o.jump(bar.open)\n this.h.jump(bar.open)\n this.l.jump(bar.open)\n this.c.jump(bar.open)\n this.vol.jump(0)\n this.spawn.restart()\n this._time = bar.time\n this._has = true\n }\n this.o.set(bar.open)\n this.h.set(bar.high)\n this.l.set(bar.low)\n this.c.set(bar.close)\n this.vol.set(bar.volume || 0)\n }\n\n reset() {\n this._has = false\n this._time = null\n }\n\n /** @returns {boolean} true while animating */\n tick(dt) {\n if (!this._has) return false\n let moving = false\n if (this.o.tick(dt)) moving = true\n if (this.h.tick(dt)) moving = true\n if (this.l.tick(dt)) moving = true\n if (this.c.tick(dt)) moving = true\n if (this.vol.tick(dt)) moving = true\n if (this.spawn.tick(dt)) moving = true\n return moving\n }\n\n /** Interpolated view of `bar`, or `bar` itself when disabled. */\n read(bar) {\n if (!this._has || !this.enabled || bar.time !== this._time) return bar\n const o = this.o.value\n const c = this.c.value\n return {\n time: bar.time,\n open: o,\n close: c,\n // keep the wick consistent while values chase each other\n high: Math.max(this.h.value, o, c),\n low: Math.min(this.l.value, o, c),\n volume: this.vol.value,\n _spawn: this.spawn.progress,\n }\n }\n}\n","/**\n * Inertia — momentum panning with friction decay.\n * sample() while dragging, release() on pointer up, then tick() each frame\n * until it returns 0.\n */\nexport class Inertia {\n constructor({ friction = 0.92, min = 0.015 } = {}) {\n this.friction = friction\n this.min = min\n this.v = 0 // px per ms\n this.active = false\n }\n\n sample(dx, dt) {\n if (dt <= 0) return\n const instant = dx / dt\n // low-pass so one jittery frame doesn't define the throw\n this.v = this.v * 0.6 + instant * 0.4\n this.active = false\n }\n\n release() {\n if (Math.abs(this.v) > this.min) this.active = true\n }\n\n stop() {\n this.v = 0\n this.active = false\n }\n\n /** @returns {number} px to pan this frame (0 when idle) */\n tick(dt) {\n if (!this.active) return 0\n const dx = this.v * dt\n this.v *= Math.pow(this.friction, dt / 16.6667)\n if (Math.abs(this.v) < this.min) this.stop()\n return dx\n }\n}\n","/** \"Nice\" step size (1/2/5 x 10^n) covering `span` in about `count` steps. */\nexport function niceStep(span, count) {\n const raw = span / Math.max(1, count)\n if (!(raw > 0) || !isFinite(raw)) return 1\n const mag = Math.pow(10, Math.floor(Math.log10(raw)))\n const n = raw / mag\n const s = n < 1.5 ? 1 : n < 3 ? 2 : n < 7 ? 5 : 10\n return s * mag\n}\n\nexport function priceTicks(lo, hi, count) {\n const step = niceStep(hi - lo, count)\n const ticks = []\n const start = Math.ceil(lo / step) * step\n for (let v = start; v <= hi + step * 1e-9; v += step) ticks.push(v)\n return { ticks, step }\n}\n\nexport function decimalsFor(step) {\n if (!isFinite(step) || step <= 0) return 2\n if (step >= 100) return 0\n if (step >= 1) return 2\n return Math.min(8, Math.ceil(-Math.log10(step)) + 1)\n}\n\n/** Bar-index step that keeps time labels at least `minPx` apart. */\nexport function niceBarStep(minBars) {\n const opts = [1, 2, 5, 10, 15, 20, 30, 60, 120, 240, 480, 960, 1920, 3840, 7680]\n for (const o of opts) if (o >= minBars) return o\n return Math.ceil(minBars / 1000) * 1000\n}\n\nconst p2 = (n) => String(n).padStart(2, '0')\n\nexport function fmtAxisTime(ms, tfMs) {\n const d = new Date(ms)\n if (tfMs >= 864e5) return `${d.getDate()} ${d.toLocaleString('en', { month: 'short' })}`\n if (d.getHours() === 0 && d.getMinutes() === 0) {\n return `${d.getDate()} ${d.toLocaleString('en', { month: 'short' })}`\n }\n return `${p2(d.getHours())}:${p2(d.getMinutes())}`\n}\n\nexport function fmtDateTime(ms) {\n const d = new Date(ms)\n return `${d.getFullYear()}-${p2(d.getMonth() + 1)}-${p2(d.getDate())} ${p2(d.getHours())}:${p2(d.getMinutes())}`\n}\n\nexport function fmtVolume(v) {\n if (!isFinite(v)) return '—'\n if (v >= 1e9) return (v / 1e9).toFixed(2) + 'B'\n if (v >= 1e6) return (v / 1e6).toFixed(2) + 'M'\n if (v >= 1e3) return (v / 1e3).toFixed(1) + 'K'\n return String(Math.round(v))\n}\n","import { priceTicks, decimalsFor, niceBarStep, fmtAxisTime } from '../core/formatters.js'\n\n/** Background, grid, and both axes. Repaints only when the view changes. */\nexport function drawGrid(ctx, s) {\n const { theme, ts, ps, plot, bars, width, height } = s\n\n ctx.clearRect(0, 0, width, height)\n ctx.fillStyle = theme.background\n ctx.fillRect(0, 0, width, height)\n\n ctx.font = theme.font\n ctx.textBaseline = 'middle'\n\n // ---- price grid + labels -------------------------------------------------\n const rows = Math.max(2, Math.floor(plot.h / 58))\n const { ticks, step } = priceTicks(ps.lo, ps.hi, rows)\n const dec = decimalsFor(step)\n\n ctx.strokeStyle = theme.grid\n ctx.lineWidth = 1\n ctx.beginPath()\n for (const v of ticks) {\n const y = Math.round(ps.y(v)) + 0.5\n if (y < plot.y || y > plot.y + plot.h) continue\n ctx.moveTo(0, y)\n ctx.lineTo(plot.w, y)\n }\n ctx.stroke()\n\n ctx.fillStyle = theme.text\n ctx.textAlign = 'left'\n for (const v of ticks) {\n const y = Math.round(ps.y(v))\n if (y < plot.y + 6 || y > plot.y + plot.h - 6) continue\n ctx.fillText(v.toFixed(dec), plot.w + 8, y)\n }\n\n // ---- time grid + labels --------------------------------------------------\n if (bars.length) {\n const minBars = Math.ceil(74 / Math.max(0.0001, ts.spacing))\n const stepBars = niceBarStep(minBars)\n const { from, to } = ts.visibleRange()\n const first = Math.ceil(from / stepBars) * stepBars\n\n ctx.strokeStyle = theme.grid\n ctx.beginPath()\n for (let i = first; i <= to; i += stepBars) {\n const x = Math.round(ts.x(i)) + 0.5\n if (x < 0 || x > plot.w) continue\n ctx.moveTo(x, 0)\n ctx.lineTo(x, plot.h)\n }\n ctx.stroke()\n\n ctx.fillStyle = theme.text\n ctx.textAlign = 'center'\n const ty = plot.h + theme.timeAxisHeight / 2\n for (let i = first; i <= to; i += stepBars) {\n const bar = bars[i]\n if (!bar) continue\n const x = Math.round(ts.x(i))\n if (x < 28 || x > plot.w - 28) continue\n ctx.fillText(fmtAxisTime(bar.time, ts.timeframeMs), x, ty)\n }\n }\n\n // ---- axis separators -----------------------------------------------------\n ctx.strokeStyle = theme.axisLine\n ctx.beginPath()\n ctx.moveTo(plot.w + 0.5, 0)\n ctx.lineTo(plot.w + 0.5, plot.h)\n ctx.moveTo(0, plot.h + 0.5)\n ctx.lineTo(width, plot.h + 0.5)\n ctx.stroke()\n}\n","import { decimalsFor, priceTicks } from '../core/formatters.js'\n\n/**\n * Candles + volume. Everything here is culled to the visible index range —\n * 500k bars loaded still costs only the ~200 on screen.\n */\nexport function drawCandles(ctx, s) {\n const { theme, ts, ps, plot, bars, width, height, live, volumeRatio } = s\n\n ctx.clearRect(0, 0, width, height)\n if (!bars.length) return\n\n const { from, to } = ts.visibleRange()\n const bw = ts.barWidth()\n const half = bw / 2\n const thin = bw <= 2\n\n // ---- volume strip --------------------------------------------------------\n const volH = plot.h * volumeRatio\n const volTop = plot.y + plot.h - volH\n let vmax = 0\n for (let i = from; i <= to; i++) {\n const b = bars[i]\n if (b && b.volume > vmax) vmax = b.volume\n }\n if (vmax > 0) {\n for (let i = from; i <= to; i++) {\n let b = bars[i]\n if (!b) continue\n if (live && i === bars.length - 1) b = live\n const x = ts.x(i)\n if (x < -bw || x > plot.w + bw) continue\n const h = (b.volume / vmax) * volH * 0.9\n ctx.fillStyle = b.close >= b.open ? theme.volumeUp : theme.volumeDown\n ctx.fillRect(Math.round(x - half), volTop + (volH - h), Math.max(1, bw), h)\n }\n }\n\n // ---- candles -------------------------------------------------------------\n for (let i = from; i <= to; i++) {\n let b = bars[i]\n if (!b) continue\n const isLast = i === bars.length - 1\n if (live && isLast) b = live\n\n const x = ts.x(i)\n if (x < -bw || x > plot.w + bw) continue\n\n const up = b.close >= b.open\n const color = up ? theme.up : theme.down\n const yO = ps.y(b.open)\n const yC = ps.y(b.close)\n const yH = ps.y(b.high)\n const yL = ps.y(b.low)\n\n // grow-from-centre on a freshly opened candle\n let scale = 1\n if (live && isLast && typeof b._spawn === 'number') scale = 0.35 + 0.65 * b._spawn\n\n const cx = Math.round(x) + (bw % 2 ? 0.5 : 0)\n\n // wick\n ctx.strokeStyle = up ? theme.wickUp : theme.wickDown\n ctx.lineWidth = Math.max(1, Math.min(2, bw * 0.16))\n ctx.beginPath()\n ctx.moveTo(cx, yH)\n ctx.lineTo(cx, yL)\n ctx.stroke()\n\n if (thin) continue\n\n // body\n const top = Math.min(yO, yC)\n const bodyH = Math.max(1, Math.abs(yC - yO))\n const w = Math.max(1, bw * scale)\n ctx.fillStyle = color\n ctx.fillRect(Math.round(x - w / 2), Math.round(top), Math.round(w), Math.round(bodyH))\n }\n\n // ---- last price line -----------------------------------------------------\n const lastBar = live || bars[bars.length - 1]\n if (lastBar) {\n const y = Math.round(ps.y(lastBar.close)) + 0.5\n if (y > plot.y && y < plot.y + plot.h) {\n const up = lastBar.close >= lastBar.open\n ctx.save()\n ctx.setLineDash([3, 3])\n ctx.strokeStyle = up ? theme.up : theme.down\n ctx.lineWidth = 1\n ctx.globalAlpha = 0.7\n ctx.beginPath()\n ctx.moveTo(0, y)\n ctx.lineTo(plot.w, y)\n ctx.stroke()\n ctx.restore()\n\n const { step } = priceTicks(ps.lo, ps.hi, Math.max(2, Math.floor(plot.h / 58)))\n const label = lastBar.close.toFixed(decimalsFor(step))\n ctx.font = theme.font\n ctx.textBaseline = 'middle'\n ctx.textAlign = 'left'\n const tw = ctx.measureText(label).width\n ctx.fillStyle = up ? theme.up : theme.down\n ctx.fillRect(plot.w + 1, y - 9, tw + 14, 18)\n ctx.fillStyle = theme.tagText\n ctx.fillText(label, plot.w + 8, y)\n }\n }\n}\n","import { decimalsFor, priceTicks, fmtDateTime } from '../core/formatters.js'\n\n/**\n * Crosshair lives alone on the top canvas: moving the pointer repaints only\n * these few pixels, never the candles underneath.\n */\nexport function drawCrosshair(ctx, s) {\n const { theme, ts, ps, plot, bars, width, height, cursor, magnet } = s\n\n ctx.clearRect(0, 0, width, height)\n if (!cursor || !bars.length) return\n if (cursor.x < 0 || cursor.x > plot.w || cursor.y < 0 || cursor.y > plot.h) return\n\n const i = Math.round(ts.index(cursor.x))\n const bar = bars[i]\n\n let x = cursor.x\n let y = cursor.y\n if (bar) {\n x = ts.x(i) // snap to the bar slot\n if (magnet) {\n // magnet to the nearest OHLC value\n const cands = [bar.open, bar.high, bar.low, bar.close]\n let best = null\n let bestD = Infinity\n for (const p of cands) {\n const py = ps.y(p)\n const d = Math.abs(py - cursor.y)\n if (d < bestD) { bestD = d; best = py }\n }\n if (bestD < 22) y = best\n }\n }\n\n ctx.save()\n ctx.setLineDash([4, 4])\n ctx.strokeStyle = theme.crosshair\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(Math.round(x) + 0.5, 0)\n ctx.lineTo(Math.round(x) + 0.5, plot.h)\n ctx.moveTo(0, Math.round(y) + 0.5)\n ctx.lineTo(plot.w, Math.round(y) + 0.5)\n ctx.stroke()\n ctx.restore()\n\n ctx.font = theme.font\n ctx.textBaseline = 'middle'\n\n // price tag\n const { step } = priceTicks(ps.lo, ps.hi, Math.max(2, Math.floor(plot.h / 58)))\n const priceLabel = ps.price(y).toFixed(decimalsFor(step))\n ctx.textAlign = 'left'\n const pw = ctx.measureText(priceLabel).width\n ctx.fillStyle = theme.labelBg\n ctx.fillRect(plot.w + 1, y - 9, pw + 14, 18)\n ctx.fillStyle = theme.labelText\n ctx.fillText(priceLabel, plot.w + 8, y)\n\n // time tag\n if (bar) {\n const t = fmtDateTime(bar.time)\n ctx.textAlign = 'center'\n const tw = ctx.measureText(t).width\n const bx = Math.min(Math.max(x, tw / 2 + 6), plot.w - tw / 2 - 6)\n ctx.fillStyle = theme.labelBg\n ctx.fillRect(bx - tw / 2 - 7, plot.h + 3, tw + 14, 18)\n ctx.fillStyle = theme.labelText\n ctx.fillText(t, bx, plot.h + 12)\n }\n}\n\n","/**\n * Annotation model — normalisation, time→index resolution and collision\n * layout for markers.\n *\n * The geometry lives here rather than in the renderer so it can be reasoned\n * about (and tested) without a canvas, and out of Chart.js so the orchestrator\n * stays about orchestration.\n */\n\nexport const MARKER_SHAPES = [\n 'arrowUp',\n 'arrowDown',\n 'triangleUp',\n 'triangleDown',\n 'circle',\n 'square',\n 'diamond',\n 'flag',\n 'label',\n]\n\nconst SHAPE_SET = new Set(MARKER_SHAPES)\n\n/** Buys sit under the bar, sells over it — the convention traders expect. */\nconst DEFAULT_POSITION = {\n arrowUp: 'belowBar',\n triangleUp: 'belowBar',\n arrowDown: 'aboveBar',\n triangleDown: 'aboveBar',\n}\n\nconst POSITIONS = new Set(['aboveBar', 'belowBar', 'inBar', 'atPrice'])\n\nexport function normalizeMarker(raw, i) {\n if (!raw || !isFinite(raw.time)) return null\n const shape = SHAPE_SET.has(raw.shape) ? raw.shape : 'circle'\n const position = POSITIONS.has(raw.position)\n ? raw.position\n : DEFAULT_POSITION[shape] || 'aboveBar'\n return {\n id: raw.id != null ? String(raw.id) : `mk${i}`,\n time: +raw.time,\n price: isFinite(raw.price) ? +raw.price : null,\n shape,\n position,\n color: raw.color || null,\n textColor: raw.textColor || null,\n text: raw.text != null ? String(raw.text) : '',\n size: isFinite(raw.size) && raw.size > 0 ? +raw.size : 1,\n /** Anything the consumer wants handed back on hover/click. */\n data: raw.data,\n index: -1,\n }\n}\n\nexport function normalizeMarkers(list) {\n if (!Array.isArray(list)) return []\n const out = []\n for (let i = 0; i < list.length; i++) {\n const m = normalizeMarker(list[i], i)\n if (m) out.push(m)\n }\n out.sort((a, b) => a.time - b.time)\n return out\n}\n\n/**\n * Index of the bar closest in time to `time`; -1 with no bars.\n * Binary search — markers are resolved again whenever the bar array shifts\n * (a history page prepended in front of them moves every index).\n */\nexport function nearestIndex(bars, time) {\n const n = bars.length\n if (!n) return -1\n if (time <= bars[0].time) return 0\n if (time >= bars[n - 1].time) return n - 1\n\n let lo = 0\n let hi = n - 1\n while (lo <= hi) {\n const mid = (lo + hi) >> 1\n const t = bars[mid].time\n if (t === time) return mid\n if (t < time) lo = mid + 1\n else hi = mid - 1\n }\n const a = Math.max(0, hi)\n const b = Math.min(n - 1, lo)\n return Math.abs(bars[a].time - time) <= Math.abs(bars[b].time - time) ? a : b\n}\n\n/** Attach a bar index to every marker, in place. */\nexport function resolveMarkers(markers, bars) {\n for (let i = 0; i < markers.length; i++) {\n markers[i].index = nearestIndex(bars, markers[i].time)\n }\n return markers\n}\n\n/**\n * Place visible markers in screen space.\n *\n * Handles the two things that make markers look amateurish when skipped:\n * several markers on one bar overlapping, and thousands of them piling onto\n * the same pixels when zoomed out.\n */\nexport function layoutMarkers(markers, s) {\n const { ts, ps, plot, bars, live } = s\n if (!markers.length || !bars.length) return []\n\n const { from, to } = ts.visibleRange()\n const lastIdx = bars.length - 1\n const dense = ts.barWidth() <= 3\n const stacks = new Map()\n const placed = []\n let lastDenseX = -Infinity\n\n for (const m of markers) {\n const i = m.index\n if (i < 0 || i < from - 2 || i > to + 2) continue\n\n // the forming candle is interpolated, so anchor to the animated values\n const bar = live && i === lastIdx ? live : bars[i]\n if (!bar) continue\n\n const x = ts.x(i)\n if (x < -48 || x > plot.w + 48) continue\n\n // Zoomed far out, markers collapse onto the same pixels: drawing them all\n // costs frames and reads as noise. One per 4px is plenty.\n if (dense) {\n if (x - lastDenseX < 4) continue\n lastDenseX = x\n }\n\n const r = 5 * m.size\n let y\n let dir = 0\n\n if (m.position === 'atPrice' && m.price != null) {\n y = ps.y(m.price)\n } else if (m.position === 'inBar') {\n y = ps.y((bar.high + bar.low) / 2)\n } else if (m.position === 'belowBar') {\n y = ps.y(bar.low) + r + 7\n dir = 1\n } else {\n y = ps.y(bar.high) - r - 7\n dir = -1\n }\n\n // Two trades on one bar must not draw on top of each other.\n if (dir !== 0) {\n const key = i + m.position\n const n = stacks.get(key) || 0\n stacks.set(key, n + 1)\n y += dir * n * (r * 2 + 5)\n }\n\n placed.push({ m, x, y, r, dir })\n }\n\n return placed\n}\n","import { decimalsFor, priceTicks } from '../core/formatters.js'\nimport { nearestIndex } from '../overlays/annotations.js'\n\n/**\n * Annotation renderers: zones (behind the candles), price lines and markers\n * (in front of them). Each is a pure draw call over prepared state.\n */\n\nconst DASH = { solid: [], dashed: [6, 4], dotted: [1, 3] }\nconst DOWN_SHAPES = new Set(['arrowDown', 'triangleDown'])\n\nfunction roundRect(ctx, x, y, w, h, r) {\n const rr = Math.max(0, Math.min(r, h / 2, w / 2))\n ctx.beginPath()\n ctx.moveTo(x + rr, y)\n ctx.lineTo(x + w - rr, y)\n ctx.quadraticCurveTo(x + w, y, x + w, y + rr)\n ctx.lineTo(x + w, y + h - rr)\n ctx.quadraticCurveTo(x + w, y + h, x + w - rr, y + h)\n ctx.lineTo(x + rr, y + h)\n ctx.quadraticCurveTo(x, y + h, x, y + h - rr)\n ctx.lineTo(x, y + rr)\n ctx.quadraticCurveTo(x, y, x + rr, y)\n ctx.closePath()\n}\n\n/* ------------------------------------------------------------------ zones -- */\n/** Shaded regions. Drawn on the base layer, over the grid and under candles. */\nexport function drawZones(ctx, s) {\n const { zones, theme, ts, ps, plot, bars } = s\n if (!zones || !zones.length) return\n\n ctx.save()\n ctx.font = theme.font\n ctx.textBaseline = 'top'\n ctx.textAlign = 'left'\n\n for (const z of zones) {\n let x\n let y\n let w\n let h\n\n if (isFinite(z.from) && isFinite(z.to)) {\n // price band: spans the full width\n y = ps.y(Math.max(z.from, z.to))\n h = Math.max(1, ps.y(Math.min(z.from, z.to)) - y)\n x = 0\n w = plot.w\n } else if (isFinite(z.fromTime) && isFinite(z.toTime) && bars.length) {\n // time band: spans the full height\n const a = ts.x(nearestIndex(bars, Math.min(z.fromTime, z.toTime)))\n const b = ts.x(nearestIndex(bars, Math.max(z.fromTime, z.toTime)))\n x = a\n w = Math.max(1, b - a)\n y = 0\n h = plot.h\n } else {\n continue\n }\n\n if (x > plot.w || x + w < 0 || y > plot.h || y + h < 0) continue\n\n ctx.fillStyle = z.color || 'rgba(38,166,154,0.10)'\n ctx.fillRect(x, y, w, h)\n\n if (z.border) {\n ctx.strokeStyle = z.border\n ctx.lineWidth = 1\n ctx.strokeRect(Math.round(x) + 0.5, Math.round(y) + 0.5, Math.round(w), Math.round(h))\n }\n\n if (z.label) {\n ctx.fillStyle = z.labelColor || theme.text\n ctx.fillText(z.label, Math.max(6, x + 6), Math.max(4, y + 4))\n }\n }\n\n ctx.restore()\n}\n\n/* ------------------------------------------------------------- price lines -- */\n/** Horizontal lines with an optional left title pill and right axis tag. */\nexport function drawPriceLines(ctx, s) {\n const { priceLines, theme, ps, plot } = s\n if (!priceLines || !priceLines.length) return\n\n const { step } = priceTicks(ps.lo, ps.hi, Math.max(2, Math.floor(plot.h / 58)))\n const dec = decimalsFor(step)\n\n ctx.save()\n ctx.font = theme.font\n ctx.textBaseline = 'middle'\n\n for (const L of priceLines) {\n if (!L || !isFinite(L.price)) continue\n const y = Math.round(ps.y(L.price)) + 0.5\n if (y < 0 || y > plot.h) continue\n\n const color = L.color || theme.textStrong\n\n ctx.setLineDash(DASH[L.lineStyle] || DASH.dashed)\n ctx.strokeStyle = color\n ctx.lineWidth = L.lineWidth || 1\n ctx.beginPath()\n ctx.moveTo(0, y)\n ctx.lineTo(plot.w, y)\n ctx.stroke()\n ctx.setLineDash([])\n\n if (L.title) {\n ctx.textAlign = 'left'\n const tw = ctx.measureText(L.title).width\n ctx.fillStyle = color\n roundRect(ctx, 6, y - 9, tw + 12, 18, 4)\n ctx.fill()\n ctx.fillStyle = L.titleColor || theme.tagText\n ctx.fillText(L.title, 12, y)\n }\n\n if (L.axisLabel !== false) {\n const label = L.price.toFixed(dec)\n ctx.textAlign = 'left'\n const lw = ctx.measureText(label).width\n ctx.fillStyle = color\n ctx.fillRect(plot.w + 1, y - 9, lw + 14, 18)\n ctx.fillStyle = L.tagTextColor || theme.tagText\n ctx.fillText(label, plot.w + 8, y)\n }\n }\n\n ctx.restore()\n}\n\n/* ---------------------------------------------------------------- markers -- */\nfunction shapePath(ctx, shape, x, y, r) {\n ctx.beginPath()\n switch (shape) {\n case 'arrowUp':\n ctx.moveTo(x, y - r)\n ctx.lineTo(x + r, y)\n ctx.lineTo(x + r * 0.45, y)\n ctx.lineTo(x + r * 0.45, y + r)\n ctx.lineTo(x - r * 0.45, y + r)\n ctx.lineTo(x - r * 0.45, y)\n ctx.lineTo(x - r, y)\n ctx.closePath()\n break\n case 'arrowDown':\n ctx.moveTo(x, y + r)\n ctx.lineTo(x + r, y)\n ctx.lineTo(x + r * 0.45, y)\n ctx.lineTo(x + r * 0.45, y - r)\n ctx.lineTo(x - r * 0.45, y - r)\n ctx.lineTo(x - r * 0.45, y)\n ctx.lineTo(x - r, y)\n ctx.closePath()\n break\n case 'triangleUp':\n ctx.moveTo(x, y - r)\n ctx.lineTo(x + r, y + r)\n ctx.lineTo(x - r, y + r)\n ctx.closePath()\n break\n case 'triangleDown':\n ctx.moveTo(x, y + r)\n ctx.lineTo(x + r, y - r)\n ctx.lineTo(x - r, y - r)\n ctx.closePath()\n break\n case 'square':\n ctx.rect(x - r, y - r, r * 2, r * 2)\n break\n case 'diamond':\n ctx.moveTo(x, y - r)\n ctx.lineTo(x + r, y)\n ctx.lineTo(x, y + r)\n ctx.lineTo(x - r, y)\n ctx.closePath()\n break\n default:\n ctx.arc(x, y, r, 0, Math.PI * 2)\n }\n}\n\nfunction drawFlag(ctx, x, y, r, color) {\n ctx.fillStyle = color\n ctx.fillRect(x - r * 0.8, y - r, Math.max(1, r * 0.3), r * 2)\n ctx.beginPath()\n ctx.moveTo(x - r * 0.5, y - r)\n ctx.lineTo(x + r, y - r * 0.55)\n ctx.lineTo(x - r * 0.5, y - r * 0.1)\n ctx.closePath()\n ctx.fill()\n}\n\n/**\n * Draws placed markers and returns their hit circles, newest first, so the\n * chart can answer \"what is under the pointer?\" without re-deriving geometry.\n */\nexport function drawMarkers(ctx, s, placed, hoverId) {\n const hits = []\n if (!placed || !placed.length) return hits\n\n const { theme } = s\n ctx.save()\n ctx.font = theme.font\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n\n for (const p of placed) {\n const { m, x, y, r, dir } = p\n const color = m.color || (DOWN_SHAPES.has(m.shape) ? theme.down : theme.up)\n const hovered = hoverId != null && m.id === hoverId\n\n if (m.shape === 'label') {\n const text = m.text || '•'\n const w = ctx.measureText(text).width + 14\n const h = 18 * m.size\n roundRect(ctx, x - w / 2, y - h / 2, w, h, 4)\n ctx.fillStyle = color\n ctx.fill()\n if (hovered) {\n ctx.strokeStyle = theme.textStrong\n ctx.lineWidth = 1.5\n ctx.stroke()\n }\n ctx.fillStyle = m.textColor || theme.tagText\n ctx.fillText(text, x, y + 0.5)\n hits.push({ id: m.id, marker: m, x, y, r: Math.max(w, h) / 2 })\n continue\n }\n\n if (hovered) {\n ctx.beginPath()\n ctx.arc(x, y, r + 4, 0, Math.PI * 2)\n ctx.fillStyle = 'rgba(255,255,255,0.14)'\n ctx.fill()\n }\n\n if (m.shape === 'flag') {\n drawFlag(ctx, x, y, r, color)\n } else {\n shapePath(ctx, m.shape, x, y, r)\n ctx.fillStyle = color\n ctx.fill()\n }\n\n if (m.text) {\n ctx.fillStyle = m.textColor || theme.text\n ctx.fillText(m.text, x, dir >= 0 ? y + r + 9 : y - r - 9)\n }\n\n hits.push({ id: m.id, marker: m, x, y, r: r + 3 })\n }\n\n ctx.restore()\n return hits\n}\n","import { Layers } from './Layers.js'\nimport { Loop } from './Loop.js'\nimport { TimeScale } from './TimeScale.js'\nimport { PriceScale } from './PriceScale.js'\nimport { defaultTheme } from './palette.js'\nimport { LiveCandle } from '../motion/LiveCandle.js'\nimport { Inertia } from '../motion/Inertia.js'\nimport { drawGrid } from '../render/grid.js'\nimport { drawCandles } from '../render/candles.js'\nimport { drawCrosshair } from '../render/crosshair.js'\nimport { drawZones, drawPriceLines, drawMarkers } from '../render/annotations.js'\nimport { normalizeMarkers, resolveMarkers, layoutMarkers } from '../overlays/annotations.js'\n\n/**\n * Chart — the orchestrator. Owns the bar store, the scales, the input\n * handling and the frame composition. Framework-free by design: this file\n * touches nothing but DOM and Canvas, which is what lets the same core ship\n * as a React component, a Web Component, or a plain script tag.\n */\nexport class Chart {\n constructor(container, options = {}) {\n if (!container) throw new Error('Chart: container element is required')\n\n this.container = container\n this.theme = { ...defaultTheme, ...(options.theme || {}) }\n this.options = {\n volumeRatio: 0.18,\n magnet: true,\n animate: true,\n ...options,\n }\n\n this.bars = []\n this.feed = null\n this._unsub = null\n this._loadingHistory = false\n this._exhausted = false\n this._listeners = {\n crosshair: new Set(),\n visibleRange: new Set(),\n markerClick: new Set(),\n markerHover: new Set(),\n }\n\n // ---- annotations --------------------------------------------------\n // Markers carry a `time`; the renderer needs an index. Resolving is a\n // binary search per marker, so it is redone only when the bar array\n // actually shifts (a prepended history page moves every index).\n this._markers = normalizeMarkers(options.markers)\n this.priceLines = Array.isArray(options.priceLines) ? options.priceLines.slice() : []\n this.zones = Array.isArray(options.zones) ? options.zones.slice() : []\n this._markerHits = []\n this._hoverMarkerId = null\n this._resolveKey = ''\n\n this.layers = new Layers(container, ['base', 'main', 'overlay'])\n this.ts = new TimeScale(options.timeScale)\n this.ps = new PriceScale(options.priceScale)\n this.live = new LiveCandle()\n this.live.enabled = this.options.animate !== false\n this.inertia = new Inertia()\n\n this.cursor = null\n this.plot = { x: 0, y: 0, w: 1, h: 1 }\n\n this.loop = new Loop((dirty, dt) => this._frame(dirty, dt))\n this.layers.onResize = () => {\n this._layout()\n this.loop.invalidate('all')\n }\n\n this._layout()\n this._bindEvents()\n this.loop.start()\n }\n\n // ---------------------------------------------------------------- layout --\n _layout() {\n const { width, height } = this.layers\n const w = Math.max(1, width - this.theme.priceAxisWidth)\n const h = Math.max(1, height - this.theme.timeAxisHeight)\n this.plot = { x: 0, y: 0, w, h }\n this.ts.resize(w)\n this.ps.layout(0, h)\n }\n\n // ------------------------------------------------------------------ data --\n setData(bars) {\n this.bars = Array.isArray(bars) ? bars.slice() : []\n this._exhausted = false\n if (this.bars.length > 1) {\n this.ts.timeframeMs = this.bars[1].time - this.bars[0].time\n }\n this.ts.setBarCount(this.bars.length)\n this.ts.snapToRealtime()\n this.live.reset()\n this.ps._primed = false\n this.loop.invalidate('all')\n }\n\n /** Merge a tick into the forming candle (animated). */\n update(bar) {\n if (!bar) return\n const n = this.bars.length\n if (n && this.bars[n - 1].time === bar.time) {\n this.bars[n - 1] = bar\n } else {\n this.append(bar)\n return\n }\n this.live.setTarget(bar)\n this.loop.invalidate('main')\n }\n\n /** Open a new candle; the previous one is now closed. */\n append(bar) {\n if (!bar) return\n const n = this.bars.length\n if (n && bar.time <= this.bars[n - 1].time) {\n this.bars[n - 1] = bar\n } else {\n this.bars.push(bar)\n this.ts.setBarCount(this.bars.length)\n }\n this.live.setTarget(bar)\n this.loop.invalidate('main')\n }\n\n async setFeed(feed) {\n this.detachFeed()\n this.feed = feed\n if (!feed) return\n this.ts.timeframeMs = feed.timeframe || this.ts.timeframeMs\n const bars = await feed.getBars({\n symbol: feed.symbol,\n timeframe: feed.timeframe,\n to: null,\n limit: this.options.initialBars || 1500,\n })\n this.setData(bars)\n if (typeof feed.prime === 'function') feed.prime(bars[bars.length - 1])\n this._unsub = feed.subscribe((msg) => {\n if (!msg || !msg.bar) return\n if (msg.type === 'append') this.append(msg.bar)\n else this.update(msg.bar)\n })\n }\n\n detachFeed() {\n if (this._unsub) this._unsub()\n this._unsub = null\n this.feed = null\n }\n\n async _maybeLoadHistory() {\n if (this._loadingHistory || this._exhausted || !this.feed) return\n const { from } = this.ts.visibleRange()\n if (from > 80 || !this.bars.length) return\n\n this._loadingHistory = true\n try {\n const oldest = this.bars[0].time\n const older = await this.feed.getBars({\n symbol: this.feed.symbol,\n timeframe: this.feed.timeframe,\n to: oldest,\n limit: 1000,\n })\n if (!older || !older.length) {\n this._exhausted = true\n } else {\n const added = older.filter((b) => b.time < oldest)\n if (!added.length) {\n this._exhausted = true\n } else {\n this.bars = added.concat(this.bars)\n // keep the view pinned to the same bars: indices all shifted right\n const wasFollowing = this.ts.follow\n this.ts.barCount = this.bars.length\n this.ts._right.jump(this.ts._right.value + added.length)\n this.ts._right.set(this.ts._right.target + added.length)\n this.ts.follow = wasFollowing\n this.loop.invalidate('all')\n }\n }\n } catch (e) {\n console.error('[Emberwick] history load failed', e)\n this._exhausted = true\n } finally {\n this._loadingHistory = false\n }\n }\n\n // ---------------------------------------------------------------- events --\n _bindEvents() {\n const el = this.container\n el.style.touchAction = 'none'\n el.style.cursor = 'crosshair'\n\n let dragging = false\n let mode = null\n let lastX = 0\n let lastY = 0\n let lastT = 0\n let moved = false\n const pointers = new Map()\n let pinchDist = 0\n\n const localPos = (e) => {\n const r = el.getBoundingClientRect()\n return { x: e.clientX - r.left, y: e.clientY - r.top }\n }\n\n this._onDown = (e) => {\n pointers.set(e.pointerId, localPos(e))\n if (pointers.size === 2) {\n const [a, b] = [...pointers.values()]\n pinchDist = Math.hypot(a.x - b.x, a.y - b.y)\n dragging = false\n return\n }\n const p = localPos(e)\n dragging = true\n moved = false\n mode = p.x > this.plot.w ? 'price' : p.y > this.plot.h ? 'time' : 'pan'\n lastX = p.x\n lastY = p.y\n lastT = performance.now()\n this.inertia.stop()\n el.setPointerCapture(e.pointerId)\n }\n\n this._onMove = (e) => {\n const p = localPos(e)\n if (pointers.has(e.pointerId)) pointers.set(e.pointerId, p)\n\n if (pointers.size === 2) {\n const [a, b] = [...pointers.values()]\n const d = Math.hypot(a.x - b.x, a.y - b.y)\n if (pinchDist > 0 && d > 0) {\n const mid = (a.x + b.x) / 2\n this.ts.zoomAt(mid, d / pinchDist)\n this.loop.invalidate('all')\n }\n pinchDist = d\n return\n }\n\n this.cursor = p\n this._emitCrosshair(p)\n this.loop.invalidate('overlay')\n\n if (!dragging) return\n const now = performance.now()\n const dt = now - lastT\n const dx = p.x - lastX\n const dy = p.y - lastY\n if (Math.abs(dx) > 1 || Math.abs(dy) > 1) moved = true\n\n if (mode === 'pan') {\n this.ts.panBy(dx)\n this.inertia.sample(dx, dt)\n this.loop.invalidate('all')\n this._maybeLoadHistory()\n } else if (mode === 'price') {\n this.ps.scaleBy(1 + dy / 220)\n this.loop.invalidate('all')\n } else if (mode === 'time') {\n this.ts.zoomAt(this.plot.w, 1 - dx / 260)\n this.loop.invalidate('all')\n }\n\n lastX = p.x\n lastY = p.y\n lastT = now\n }\n\n this._onUp = (e) => {\n pointers.delete(e.pointerId)\n if (pointers.size < 2) pinchDist = 0\n if (dragging && mode === 'pan' && moved) {\n this.inertia.release()\n this.loop.invalidate('all')\n }\n dragging = false\n mode = null\n try { el.releasePointerCapture(e.pointerId) } catch (_) {}\n }\n\n this._onLeave = () => {\n this.cursor = null\n this._emitCrosshair(null)\n this.loop.invalidate('overlay')\n }\n\n this._onWheel = (e) => {\n e.preventDefault()\n const r = el.getBoundingClientRect()\n const x = e.clientX - r.left\n const factor = Math.pow(0.999, e.deltaY)\n this.ts.zoomAt(x, factor)\n this.loop.invalidate('all')\n this._maybeLoadHistory()\n }\n\n this._onDbl = () => {\n this.ts.reset()\n this.ps.resetAuto()\n this.loop.invalidate('all')\n }\n\n this._onKey = (e) => {\n const step = e.shiftKey ? 120 : 40\n if (e.key === 'ArrowLeft') { this.ts.panBy(step); this.loop.invalidate('all'); this._maybeLoadHistory() }\n else if (e.key === 'ArrowRight') { this.ts.panBy(-step); this.loop.invalidate('all') }\n else if (e.key === '+' || e.key === '=') { this.ts.zoomAt(this.plot.w / 2, 1.2); this.loop.invalidate('all') }\n else if (e.key === '-' || e.key === '_') { this.ts.zoomAt(this.plot.w / 2, 0.8); this.loop.invalidate('all') }\n else return\n e.preventDefault()\n }\n\n this._onClick = (e) => {\n // `moved` is still set from the gesture that just ended — a pan that\n // happens to finish over a marker must not read as a click on it.\n if (moved) return\n if (!this._listeners.markerClick.size) return\n const p = localPos(e)\n const hit = this.markerAt(p.x, p.y)\n if (hit) for (const fn of this._listeners.markerClick) fn(hit)\n }\n\n el.addEventListener('click', this._onClick)\n el.addEventListener('pointerdown', this._onDown)\n el.addEventListener('pointermove', this._onMove)\n el.addEventListener('pointerup', this._onUp)\n el.addEventListener('pointercancel', this._onUp)\n el.addEventListener('pointerleave', this._onLeave)\n el.addEventListener('wheel', this._onWheel, { passive: false })\n el.addEventListener('dblclick', this._onDbl)\n el.addEventListener('keydown', this._onKey)\n if (!el.hasAttribute('tabindex')) el.setAttribute('tabindex', '0')\n }\n\n _emitCrosshair(p) {\n if (this._listeners.crosshair.size) {\n let payload = null\n if (p && this.bars.length && p.x <= this.plot.w && p.y <= this.plot.h) {\n const i = Math.round(this.ts.index(p.x))\n const bar = this.bars[i]\n if (bar) payload = { index: i, bar, price: this.ps.price(p.y) }\n }\n for (const fn of this._listeners.crosshair) fn(payload)\n }\n this._updateHover(p)\n }\n\n /**\n * Topmost marker whose hit circle contains the point, else null.\n * Hit circles come from the last render, so this costs nothing but a loop.\n */\n markerAt(x, y) {\n const hits = this._markerHits\n for (let i = hits.length - 1; i >= 0; i--) {\n const h = hits[i]\n const dx = x - h.x\n const dy = y - h.y\n if (dx * dx + dy * dy <= h.r * h.r) return h.marker\n }\n return null\n }\n\n _updateHover(p) {\n const hit = p ? this.markerAt(p.x, p.y) : null\n const id = hit ? hit.id : null\n if (id === this._hoverMarkerId) return\n this._hoverMarkerId = id\n this.container.style.cursor = hit ? 'pointer' : 'crosshair'\n // the hover ring is drawn with the markers, so that layer must repaint\n this.loop.invalidate('main')\n for (const fn of this._listeners.markerHover) fn(hit)\n }\n\n subscribe(event, fn) {\n const set = this._listeners[event]\n if (!set) throw new Error(`Chart: unknown event \"${event}\"`)\n set.add(fn)\n // 'visibleRange' is a state event, not a notification: a new subscriber is\n // told the CURRENT window straight away, so it never has to wait for the\n // user to pan before it knows what is on screen.\n if (event === 'visibleRange') {\n const payload = this.visibleRange()\n this._rangeKey = this._rangeIdentity(payload)\n fn(payload)\n }\n return () => set.delete(fn)\n }\n\n // ------------------------------------------------------------------ range --\n /**\n * The window currently on screen. Cheap enough to poll, though\n * subscribe('visibleRange', fn) is the better way to track it.\n */\n visibleRange() {\n const { from, to } = this.ts.visibleRange()\n return this._rangePayload(from, to)\n }\n\n _rangePayload(from, to) {\n const n = this.bars.length\n return {\n from,\n to,\n fromTime: n ? this.bars[from].time : null,\n toTime: n ? this.bars[to].time : null,\n barCount: n,\n spacing: this.ts.spacing,\n settled: this.ts.settled,\n }\n }\n\n _rangeIdentity(p) {\n return `${p.from}:${p.to}:${p.fromTime}:${p.toTime}:${p.settled ? 1 : 0}`\n }\n\n /**\n * Fires only when the window actually changed, so a consumer can hang a\n * fetch off it without debouncing. Two deliberate choices:\n *\n * - `spacing` is NOT part of the identity. It is a float that moves on every\n * frame of an eased zoom, so keying on it would make this a 60/sec\n * firehose. It is still reported, for level-of-detail decisions.\n * - `settled` IS part of the identity, so the final event of a gesture\n * always arrives with settled:true. Without it, code that defers expensive\n * work until the view stops moving would wait forever.\n */\n _emitVisibleRange(from, to) {\n const set = this._listeners.visibleRange\n if (!set.size) return\n const payload = this._rangePayload(from, to)\n const key = this._rangeIdentity(payload)\n if (key === this._rangeKey) return // undefined on the first frame, so it emits\n this._rangeKey = key\n for (const fn of set) fn(payload)\n }\n\n // ----------------------------------------------------------- annotations --\n /** Replace every marker. Each `time` is resolved to its nearest bar. */\n setMarkers(markers) {\n this._markers = normalizeMarkers(markers)\n this._resolveKey = '' // force re-resolution on the next frame\n this.loop.invalidate('main')\n }\n\n /** The current markers, normalised, each with its resolved bar index. */\n getMarkers() {\n return this._markers.slice()\n }\n\n addMarker(marker) {\n this.setMarkers(this._markers.concat([marker]))\n }\n\n removeMarker(id) {\n const key = String(id)\n this.setMarkers(this._markers.filter((m) => m.id !== key))\n }\n\n clearMarkers() {\n this.setMarkers([])\n }\n\n /** Horizontal lines — entries, stops, targets, alerts. */\n setPriceLines(lines) {\n this.priceLines = Array.isArray(lines) ? lines.slice() : []\n this.loop.invalidate('main')\n }\n\n /** Shaded regions: a price band ({from,to}) or a time band ({fromTime,toTime}). */\n setZones(zones) {\n this.zones = Array.isArray(zones) ? zones.slice() : []\n this.loop.invalidate('all')\n }\n\n // ----------------------------------------------------------------- frame --\n _frame(dirty, dt) {\n let animating = false\n\n if (this.ts.tick(dt)) animating = true\n\n const dx = this.inertia.tick(dt)\n if (dx) {\n this.ts.panBy(dx)\n animating = true\n this._maybeLoadHistory()\n }\n\n if (this.live.tick(dt)) animating = true\n\n const { from, to } = this.ts.visibleRange()\n const lastIdx = this.bars.length - 1\n const liveBar = this.bars.length ? this.live.read(this.bars[lastIdx]) : null\n const liveVisible = liveBar && to >= lastIdx ? liveBar : null\n\n this.ps.fit(this.bars, from, to, liveVisible)\n if (this.ps.tick(dt)) animating = true\n\n const redrawAll = animating || dirty.has('all') || dirty.has('base') || dirty.has('main')\n const state = {\n theme: this.theme,\n ts: this.ts,\n ps: this.ps,\n plot: this.plot,\n bars: this.bars,\n width: this.layers.width,\n height: this.layers.height,\n live: liveVisible,\n volumeRatio: this.options.volumeRatio,\n cursor: this.cursor,\n magnet: this.options.magnet,\n priceLines: this.priceLines,\n zones: this.zones,\n }\n\n // Marker indices only go stale when the bar array shifts: a prepended\n // history page renumbers every bar, an append does not.\n if (this._markers.length) {\n const key = this.bars.length + ':' + (this.bars.length ? this.bars[0].time : 0)\n if (key !== this._resolveKey) {\n resolveMarkers(this._markers, this.bars)\n this._resolveKey = key\n }\n }\n\n if (redrawAll) {\n drawGrid(this.layers.ctx.base, state)\n drawZones(this.layers.ctx.base, state)\n drawCandles(this.layers.ctx.main, state)\n drawPriceLines(this.layers.ctx.main, state)\n this._markerHits = drawMarkers(\n this.layers.ctx.main,\n state,\n layoutMarkers(this._markers, state),\n this._hoverMarkerId,\n )\n }\n if (redrawAll || dirty.has('overlay')) {\n drawCrosshair(this.layers.ctx.overlay, state)\n }\n\n // Emitted after drawing, deliberately: a handler is free to call\n // setData() or setMarkers(), and by this point the renderers have\n // finished reading the state it would mutate.\n this._emitVisibleRange(from, to)\n\n return animating\n }\n\n // ------------------------------------------------------------------- api --\n get fps() { return this.loop.fps }\n\n setTheme(theme) {\n this.theme = { ...this.theme, ...theme }\n this._layout()\n this.loop.invalidate('all')\n }\n\n setPriceMode(mode) {\n this.ps.setMode(mode)\n this.loop.invalidate('all')\n }\n\n setAnimate(on) {\n this.live.enabled = !!on\n this.loop.invalidate('all')\n }\n\n setMagnet(on) {\n this.options.magnet = !!on\n this.loop.invalidate('overlay')\n }\n\n snapToRealtime() {\n this.ts.snapToRealtime()\n this.ps.resetAuto()\n this.loop.invalidate('all')\n }\n\n toImage() {\n return this.layers.composite().toDataURL('image/png')\n }\n\n destroy() {\n const el = this.container\n el.removeEventListener('pointerdown', this._onDown)\n el.removeEventListener('pointermove', this._onMove)\n el.removeEventListener('pointerup', this._onUp)\n el.removeEventListener('pointercancel', this._onUp)\n el.removeEventListener('pointerleave', this._onLeave)\n el.removeEventListener('wheel', this._onWheel)\n el.removeEventListener('dblclick', this._onDbl)\n el.removeEventListener('keydown', this._onKey)\n el.removeEventListener('click', this._onClick)\n this.detachFeed()\n this.loop.stop()\n this.layers.destroy()\n for (const set of Object.values(this._listeners)) set.clear()\n this._markers = []\n this._markerHits = []\n this.priceLines = []\n this.zones = []\n this.bars = []\n }\n}\n\n","/**\n * DataFeed — THE seam of this library.\n *\n * The chart core never knows where bars come from. Anything that implements\n * this interface can drive it: a REST endpoint, a WebSocket, a Lambda behind\n * API Gateway, a CSV in memory, or the bundled RandomFeed.\n *\n * Bar shape (the only contract that matters):\n * { time: number (ms epoch), open, high, low, close, volume }\n * Bars MUST be ascending by time and de-duplicated by the feed.\n *\n * Implement:\n * getBars({ symbol, timeframe, to, limit }) -> Promise<Bar[]>\n * Historical bars ENDING at `to` (exclusive). Return [] when exhausted;\n * the chart stops asking for more history once it sees an empty page.\n * subscribe(handler) -> unsubscribe fn\n * handler({ type: 'update'|'append', bar }) where\n * 'update' = the forming candle changed (animates)\n * 'append' = a new candle opened (previous one is now closed)\n */\nexport class DataFeed {\n constructor({ symbol = 'DEMO', timeframe = 60000 } = {}) {\n this.symbol = symbol\n this.timeframe = timeframe\n }\n\n // eslint-disable-next-line no-unused-vars\n async getBars({ symbol, timeframe, to, limit }) {\n throw new Error('DataFeed.getBars() not implemented')\n }\n\n // eslint-disable-next-line no-unused-vars\n subscribe(handler) {\n return () => {}\n }\n\n destroy() {}\n}\n\n/** Deterministic PRNG so a given seed always renders the same chart. */\nexport function mulberry32(seed) {\n let a = seed >>> 0\n return function () {\n a = (a + 0x6d2b79f5) | 0\n let t = Math.imul(a ^ (a >>> 15), 1 | a)\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n","import { DataFeed, mulberry32 } from './DataFeed.js'\n\n/**\n * RandomFeed — a plausible synthetic market. One implementation of DataFeed,\n * nothing more: swapping in a real provider is writing another class, with\n * zero changes to the chart core.\n *\n * Generates a GBM-ish random walk with volatility clustering and a volume\n * profile, then drives a live forming candle from sub-bar ticks.\n */\nexport class RandomFeed extends DataFeed {\n constructor({\n symbol = 'EMBR',\n timeframe = 60000,\n seed = 7,\n start = 100,\n volatility = 0.0022,\n drift = 0.00002,\n ticksPerSecond = 8,\n speed = 1,\n } = {}) {\n super({ symbol, timeframe })\n this.seed = seed\n this.start = start\n this.volatility = volatility\n this.drift = drift\n this.ticksPerSecond = ticksPerSecond\n this.speed = speed\n\n this._rnd = mulberry32(seed)\n this._handlers = new Set()\n this._timer = null\n this._forming = null\n this._last = start\n this._vol = volatility\n this._anchorTime = Math.floor(Date.now() / timeframe) * timeframe\n }\n\n _gauss() {\n // Box-Muller\n let u = 0\n let v = 0\n while (u === 0) u = this._rnd()\n while (v === 0) v = this._rnd()\n return Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v)\n }\n\n _step(price) {\n // volatility clusters: vol mean-reverts but gets kicked by shocks\n const shock = this._gauss()\n this._vol += (this.volatility - this._vol) * 0.02 + Math.abs(shock) * this.volatility * 0.015\n this._vol = Math.min(this._vol, this.volatility * 6)\n return Math.max(0.01, price * (1 + this.drift + shock * this._vol))\n }\n\n _makeBar(time, open) {\n let c = open\n const n = 14\n let hi = open\n let lo = open\n for (let i = 0; i < n; i++) {\n c = this._step(c)\n if (c > hi) hi = c\n if (c < lo) lo = c\n }\n const range = Math.max(1e-9, hi - lo)\n const volume = Math.round(\n (300 + this._rnd() * 900) * (1 + (range / open) * 260)\n )\n return { time, open, high: hi, low: lo, close: c, volume }\n }\n\n /**\n * Historical bars ending just before `to`. Walks BACKWARDS from a synthetic\n * anchor, so paging further left keeps producing coherent history.\n */\n async getBars({ to, limit = 1500, timeframe = this.timeframe } = {}) {\n const end = to == null ? this._anchorTime : to\n const bars = []\n // generate forward from an earlier point for realistic shape, then slice\n const startTime = end - limit * timeframe\n const gen = mulberry32(this.seed ^ Math.floor(startTime / timeframe))\n const saved = this._rnd\n this._rnd = gen\n\n let price = this.start * (1 + (gen() - 0.5) * 0.04)\n for (let i = 0; i < limit; i++) {\n const t = startTime + i * timeframe\n const bar = this._makeBar(t, price)\n price = bar.close\n bars.push(bar)\n }\n this._rnd = saved\n\n if (to == null) {\n this._last = bars.length ? bars[bars.length - 1].close : this.start\n }\n return bars\n }\n\n subscribe(handler) {\n this._handlers.add(handler)\n if (!this._timer) this._start()\n return () => {\n this._handlers.delete(handler)\n if (!this._handlers.size) this.stop()\n }\n }\n\n _emit(msg) {\n for (const h of this._handlers) h(msg)\n }\n\n _start() {\n const interval = Math.max(16, 1000 / this.ticksPerSecond)\n this._timer = setInterval(() => this._tick(), interval)\n }\n\n /** Seed the live candle from wherever history ended. */\n prime(lastBar) {\n if (lastBar) {\n this._last = lastBar.close\n this._forming = { ...lastBar }\n }\n }\n\n _tick() {\n const tf = this.timeframe / this.speed\n const now = Date.now()\n const slot = Math.floor(now / tf) * tf\n\n if (!this._forming || this._forming.time !== slot) {\n const open = this._last\n this._forming = { time: slot, open, high: open, low: open, close: open, volume: 0 }\n this._emit({ type: 'append', bar: { ...this._forming } })\n return\n }\n\n const next = this._step(this._last)\n this._last = next\n const f = this._forming\n f.close = next\n if (next > f.high) f.high = next\n if (next < f.low) f.low = next\n f.volume += Math.round(20 + this._rnd() * 120)\n this._emit({ type: 'update', bar: { ...f } })\n }\n\n setSpeed(s) { this.speed = s }\n\n setTicksPerSecond(n) {\n this.ticksPerSecond = n\n if (this._timer) { this.stop(); this._start() }\n }\n\n setPaused(paused) {\n if (paused) this.stop()\n else if (!this._timer && this._handlers.size) this._start()\n }\n\n get paused() { return !this._timer }\n\n stop() {\n if (this._timer) clearInterval(this._timer)\n this._timer = null\n }\n\n destroy() {\n this.stop()\n this._handlers.clear()\n }\n}\n","/**\n * Emberwick — public API surface.\n *\n * This file is the future package entry point. Nothing below imports a\n * framework, so the same build drops into React, Vue, Svelte or a script tag.\n *\n * import { createChart, RandomFeed } from './chart/index.js'\n * const chart = createChart(el, { theme: { background: '#000' } })\n * await chart.setFeed(new RandomFeed({ timeframe: 60000 }))\n */\nexport { Chart } from './core/Chart.js'\nexport { TimeScale } from './core/TimeScale.js'\nexport { PriceScale } from './core/PriceScale.js'\nexport { defaultTheme, lightTheme } from './core/palette.js'\nexport { DataFeed, mulberry32 } from './data/DataFeed.js'\nexport { RandomFeed } from './data/RandomFeed.js'\nexport { Smoothed, Tween, easeOutCubic, easeInOutCubic } from './motion/Tween.js'\nexport { Inertia } from './motion/Inertia.js'\nexport { LiveCandle } from './motion/LiveCandle.js'\n\nimport { Chart } from './core/Chart.js'\n\n/** Preferred entry point. */\nexport function createChart(container, options) {\n return new Chart(container, options)\n}\n\nexport const version = '0.2.0'\n\n"],"names":["Layers","container","names","name","i","c","r","w","h","dpr","n","out","Loop","onFrame","layers","l","now","dt","dirty","wantMore","e","easeOutCubic","t","easeInOutCubic","Smoothed","value","tau","target","v","eps","Tween","duration","ease","clamp","a","b","TimeScale","spacing","minSpacing","maxSpacing","rightOffset","grew","x","s","first","last","max","min","dxPx","next","factor","s0","s1","anchorX","r1","PriceScale","mode","marginTop","marginBottom","lo","hi","top","height","price","y","bars","from","to","extra","pad","mid","half","defaultTheme","lightTheme","LiveCandle","bar","moving","o","Inertia","friction","dx","instant","niceStep","span","count","raw","mag","priceTicks","step","ticks","start","decimalsFor","niceBarStep","minBars","opts","p2","fmtAxisTime","ms","tfMs","d","fmtDateTime","drawGrid","ctx","theme","ts","ps","plot","width","rows","dec","stepBars","ty","drawCandles","live","volumeRatio","bw","thin","volH","volTop","vmax","isLast","up","color","yO","yC","yH","yL","scale","cx","bodyH","lastBar","label","tw","drawCrosshair","cursor","magnet","cands","best","bestD","p","py","priceLabel","pw","bx","MARKER_SHAPES","SHAPE_SET","DEFAULT_POSITION","POSITIONS","normalizeMarker","shape","position","normalizeMarkers","list","m","nearestIndex","time","resolveMarkers","markers","layoutMarkers","lastIdx","dense","stacks","placed","lastDenseX","dir","key","DASH","DOWN_SHAPES","roundRect","rr","drawZones","zones","z","drawPriceLines","priceLines","L","lw","shapePath","drawFlag","drawMarkers","hoverId","hits","hovered","text","Chart","options","feed","msg","oldest","older","added","wasFollowing","el","dragging","lastX","lastY","lastT","moved","pointers","pinchDist","localPos","dy","hit","fn","payload","id","event","set","marker","lines","animating","liveBar","liveVisible","redrawAll","state","on","DataFeed","symbol","timeframe","limit","handler","mulberry32","seed","RandomFeed","volatility","drift","ticksPerSecond","speed","u","shock","open","range","volume","end","startTime","gen","saved","interval","tf","slot","f","paused","createChart","version"],"mappings":"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"}
|