Appearance
Tooltips and selection
Per-point metadata
The call
plot.hitTest(x: number, y: number, nearest?: boolean): Hit | nullWhat is at a pixel, relative to the canvas: the chart under it and the datum it resolves to, or
nullwhen no chart is there.With
nearest, any pixel inside a plot has an answer -- the datum drawn closest to it, which is what a tooltip wants. Without it only a pixel actually on a drawn element answers, which is what a menu wants.seriesandindexare how a page attaches its own data to a point: the index into the array it uploaded is the index it gets back. There is no per-point payload and there will not be one -- an object per point is the thing this library exists to avoid.Answered from the last drawn frame, so a plot that has not rendered yet reports
null.
const { x, y } = readings(60);
// The page's own records, in the order the points were uploaded.
const stations = Array.from(x, (_, i) => ({
name: `Station ${String.fromCharCode(65 + (i % 26))}${Math.floor(i / 26) + 1}`,
operator: ["Harbour board", "Met office", "University"][i % 3],
}));
plot.setCharts({
charts: [
{
kind: "scatter",
series: [{ x: plot.uploadBuffer(x), y: plot.uploadBuffer(y), label: "stations" }],
legend: false,
},
],
});
return {
pointer(px, py) {
const hit = plot.hitTest(px, py);
if (hit === null) return "nothing here";
const station = stations[hit.index];
return `${station.name}, ${station.operator}: ${fixed(hit.y)} at ${fixed(hit.x)}`;
},
};Also called
2 in the code above, in the order it makes them
plot.setCharts(document: ChartDocument): readonly ChartHandle[]Draw a document of charts, and get a handle for each one.
The handles come back in document order and are what names a chart afterwards:
chartView,setChartView,chartPicked, and thecharton a hover, a hit or any other event. A page linking two charts holds two handles rather than allocating ids.Replaces the charts and the series each one reads.
Throws rather than drawing a partial document, and a throw leaves the previous document in place. What it refuses: a misspelled key, a handle that names something other than a buffer, a range whose ends are the wrong way round, and a column on a chart kind that cannot read it. All four would otherwise be a chart that draws something subtly wrong, or nothing, with nothing said.
Setting a document again is the way to change one: there is no per-chart edit, and the compile is cheap because the data does not move. The buffers are named by handle, so a live chart writes to them with
writeBufferand never sets a document at all.plot.uploadBuffer(values: Float32Array | Float64Array): BufferHandleUpload a block of scalars and return a handle naming it.
A buffer keeps the precision it arrived in. Use
Float64Arrayfor time and for anything wheref32's twenty-four bits of mantissa would lose something real: a millisecond timestamp narrowed tof32rounds every sample into a five-minute bucket, and it does that silently.