Jaspers Hub

biseroff / charts

pluginReviewed★ 0↓ 0

Charts: Interactive price chart view with lines or candles and volume, backed by Yahoo, Massive, or Databento bar data.

1.7 KB
1// Labels for the chart's times. Intraday times are New York wall-clock seconds read as UTC (see plan.ts),
2// so formatting them in UTC shows New York time, daylight saving included. Dates are YYYY-MM-DD.
3
4const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
5
6type AnyTime = number | string | { year: number; month: number; day: number }
7
8function parts(time: AnyTime) {
9 if (typeof time === 'number') {
10 const d = new Date(time * 1000)
11 return { y: d.getUTCFullYear(), m: d.getUTCMonth(), d: d.getUTCDate(), hh: d.getUTCHours(), mm: d.getUTCMinutes(), hasTime: true }
12 }
13 if (typeof time === 'string') {
14 const [y, m, d] = time.split('-').map(Number)
15 return { y, m: m - 1, d, hh: 0, mm: 0, hasTime: false }
16 }
17 return { y: time.year, m: time.month - 1, d: time.day, hh: 0, mm: 0, hasTime: false }
18}
19
20const pad = (n: number) => String(n).padStart(2, '0')
21
22/** The crosshair's label: "Wed Oct 15 '26 09:30 ET" intraday, "Oct 15 '26" for a day. */
23export function crosshairLabel(time: unknown): string {
24 const p = parts(time as AnyTime)
25 const date = `${MONTHS[p.m]} ${p.d} '${String(p.y).slice(2)}`
26 if (!p.hasTime) return date
27 const weekday = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][new Date(Date.UTC(p.y, p.m, p.d)).getUTCDay()]
28 return `${weekday} ${date} ${pad(p.hh)}:${pad(p.mm)} ET`
29}
30
31/** A tick on the time axis. markType is lightweight-charts' TickMarkType: 0 year, 1 month, 2 day, 3 and 4 time. */
32export function tickLabel(time: unknown, markType: number): string {
33 const p = parts(time as AnyTime)
34 if (markType === 0) return String(p.y)
35 if (markType === 1) return MONTHS[p.m]
36 if (markType === 2 || !p.hasTime) return `${MONTHS[p.m]} ${p.d}`
37 return `${pad(p.hh)}:${pad(p.mm)}`
38}