# Recorded numeric inspection
Query the committed observations from numeric and point series with explicit units and interpolation.

## APIs demonstrated

- [anchorInsideClips](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [firstSourceObservation](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [lastSourceObservation](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [nearestRecordedPoint](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [nearestRecordedX](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [sampleRecordedX](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [useNumericInspection](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [usePointInspection](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [InspectionCandidate](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [NearestRecordedPointHit](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [NearestRecordedPointOptions](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [NearestRecordedXHit](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [NearestRecordedXOptions](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [NumericDomainInterpolation](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [NumericDuplicateResolver](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [NumericInspectionRef](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [NumericRenderedAnchors](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [NumericRenderedFilter](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [NumericRenderedObservation](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [NumericRenderedSeries](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [PointInspectionRef](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [PointRenderedSeries](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [RecordedNumericHit](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [RecordedXSample](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [RenderedSeries](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [RenderedSeriesPoint](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`
- [SampleRecordedXOptions](/reference/functions/rendered-series-inspection/) from `@pibbl/core/viz/inspection`

## Complete example

[Plain source](/minimal/viz/inspection-recorded.tsx). Run as a browser module after the document body exists. TSX uses `jsx: "react-jsx"` and `jsxImportSource: "@pibbl/core"`.

```tsx
import { Group, Rectangle, Text, pibbl, useSignal } from "@pibbl/core";
import {
  LinearScale,
  LineSeries,
  PointSeries,
  defineSeries,
  linearInterpolation,
} from "@pibbl/core/viz";
import {
  anchorInsideClips,
  firstSourceObservation,
  lastSourceObservation,
  nearestRecordedPoint,
  nearestRecordedX,
  sampleRecordedX,
  useNumericInspection,
  usePointInspection,
  type InspectionCandidate,
  type NearestRecordedPointHit,
  type NearestRecordedPointOptions,
  type NearestRecordedXHit,
  type NearestRecordedXOptions,
  type NumericDomainInterpolation,
  type NumericDuplicateResolver,
  type NumericInspectionRef,
  type NumericRenderedAnchors,
  type NumericRenderedFilter,
  type NumericRenderedObservation,
  type NumericRenderedSeries,
  type PointInspectionRef,
  type PointRenderedSeries,
  type RecordedNumericHit,
  type RecordedXSample,
  type RenderedSeries,
  type RenderedSeriesPoint,
  type SampleRecordedXOptions,
} from "@pibbl/core/viz/inspection";

type Price = { time: number; price: number };
const data: readonly Price[] = [
  { time: 0, price: 10 },
  { time: 5, price: 15 },
  { time: 10, price: 12 },
];
const series = defineSeries({ data, x: "time", y: "price" });

function Chart() {
  const numeric: NumericInspectionRef<Price> = useNumericInspection(series);
  const points: PointInspectionRef<Price> = usePointInspection(series);
  const message = useSignal("Click the plot to inspect time 6.");
  const inspect = () => {
    const rendered: NumericRenderedSeries<Price> | undefined =
      numeric.rendered();
    const pointRendered: PointRenderedSeries<Price> | undefined =
      points.rendered();
    const alias: RenderedSeries<Price> | undefined = rendered;
    if (!alias) return;
    const candidateFilter: NumericRenderedFilter<Price> = (
      candidate: InspectionCandidate<Price>,
    ) => anchorInsideClips(candidate);
    const xOptions: NearestRecordedXOptions<Price> = {
      domainX: 6,
      filter: candidateFilter,
    };
    const nearest: NearestRecordedXHit<Price> | undefined = nearestRecordedX(
      alias,
      xOptions,
    );
    const rootPoint: RenderedSeriesPoint = { x: 170, y: 100 };
    const pointOptions: NearestRecordedPointOptions<Price> = { rootPoint };
    const nearestPoint: NearestRecordedPointHit<Price> | undefined =
      pointRendered && nearestRecordedPoint(pointRendered, pointOptions);
    const interpolation: NumericDomainInterpolation = linearInterpolation();
    const resolver: NumericDuplicateResolver<Price> = lastSourceObservation;
    const sampleOptions: SampleRecordedXOptions<Price> = {
      domainX: 6,
      interpolation,
      resolveDuplicate: resolver,
    };
    const sample: RecordedXSample<Price> | undefined = sampleRecordedX(
      alias,
      sampleOptions,
    );
    const observed: RecordedNumericHit<Price> | undefined = nearest;
    const row: NumericRenderedObservation<Price> | undefined =
      alias.observations[0];
    const anchors: NumericRenderedAnchors | undefined =
      row && alias.anchorAtDomain(row);
    const first =
      row && alias.observations[1]
        ? firstSourceObservation(row, alias.observations[1])
        : row;
    message.set(
      `Recorded ${observed?.datum.price ?? "none"}; estimate ${sample?.domainY ?? "none"}; point row ${nearestPoint?.sourceIndex ?? "none"}; anchor ${anchors?.anchorRoot.x ?? "none"}; first row ${first?.sourceIndex ?? "none"}`,
    );
  };
  return (
    <>
      <Group onClick={inspect}>
        <Rectangle style={{ width: 300, height: 170, fill: "#f5f8f5" }} />
        <LineSeries
          {...series}
          xScale="time"
          yScale="price"
          inspection={numeric}
          style={{ stroke: "#147b68" }}
        />
        <PointSeries
          {...series}
          xScale="time"
          yScale="price"
          inspection={points}
          style={{ radius: 6, fill: "#cf6b4c" }}
        />
      </Group>
      <Text
        pointerEvents="none"
        style={{ left: 8, top: 195, font: "12px sans-serif", fill: "#173a35" }}
      >
        {message.get()}
      </Text>
    </>
  );
}

const canvas = document.createElement("canvas");
canvas.width = 320;
canvas.height = 230;
document.body.append(canvas);
const controller = pibbl(
  canvas,
  <LinearScale id="time" domain={[0, 10]} range={[30, 280]}>
    <LinearScale id="price" domain={[0, 20]} range={[150, 20]}>
      <Chart />
    </LinearScale>
  </LinearScale>,
);
window.addEventListener("pagehide", () => controller.dispose(), { once: true });

```

## Usage notes



## Documentation version

Documentation built with @pibbl/core 0.0.2, revision dd39ce2. ALPHA — NOT FOR PRODUCTION USE.
