|
|
@@ -60,12 +60,13 @@ async function getCXPC(ticker: string, cx: string): Promise<PriceChartPoint[]> {
|
|
|
function renderPriceChart(cx: string, dateRange: [Date, Date], maxPrice: number, maxTraded: number, cxpc: PriceChartPoint[]):
|
|
|
SVGSVGElement | HTMLElement {
|
|
|
const chartsWidth = charts.getBoundingClientRect().width;
|
|
|
+ const numFormat = Plot.formatNumber();
|
|
|
return Plot.plot({
|
|
|
grid: true,
|
|
|
width: chartsWidth < 600 ? chartsWidth : chartsWidth / 2 - 10,
|
|
|
height: 400,
|
|
|
- marginLeft: 12 + 7 * Math.log10(maxPrice),
|
|
|
- marginRight: 12 + 7 * Math.log10(maxTraded),
|
|
|
+ marginLeft: 26 + 7 * Math.log10(maxPrice),
|
|
|
+ marginRight: 26 + 7 * Math.log10(maxTraded),
|
|
|
x: {domain: dateRange},
|
|
|
y: {axis: 'left', label: cx, domain: [0, maxPrice * 1.1]},
|
|
|
marks: [
|
|
|
@@ -97,8 +98,20 @@ function renderPriceChart(cx: string, dateRange: [Date, Date], maxPrice: number,
|
|
|
Plot.crosshairX(cxpc, {
|
|
|
x: (p) => new Date(p.DateEpochMs),
|
|
|
y: (p) => p.Volume / p.Traded,
|
|
|
- textStrokeWidth: 0,
|
|
|
- })
|
|
|
+ textStroke: '#111',
|
|
|
+ }),
|
|
|
+ Plot.text(cxpc, Plot.pointerX({
|
|
|
+ px: (p) => new Date(p.DateEpochMs),
|
|
|
+ py: (p) => p.Volume / p.Traded,
|
|
|
+ dy: -20,
|
|
|
+ frameAnchor: "top-right",
|
|
|
+ fontVariant: "tabular-nums",
|
|
|
+ text: (p) => `${Plot.formatIsoDate(new Date(p.DateEpochMs))}\n` +
|
|
|
+ `avg: $${numFormat(p.Volume / p.Traded)}\n` +
|
|
|
+ `high: ${numFormat(p.High)}\n` +
|
|
|
+ `low: ${numFormat(p.Low)}\n` +
|
|
|
+ `traded: ${numFormat(p.Traded)}`
|
|
|
+ })),
|
|
|
]
|
|
|
});
|
|
|
}
|