The @use-gpu/plot
package provides the ability to make graphs. <Plot>
comes with a set of matching components that go inside, such as views, axes, grids, points, lines, etc.
You can make both 2D and 3D plots, depending on the surrounding camera component (e.g. <Flat>
or <OrbitCamera>
). Plots must be placed inside a drawing pass, so the generated geometry can be rendered.
A basic chart frame looks like:
return (
<Plot>
<Cartesian range={[[min, max], [min, max]]}>
<Axis axis="x" {...} />
<Axis axis="y" {...} />
<Grid axes="xy" />
<Scale axis="x" {...}>
<Label {...} />
</Scale>
</Cartesian>
</Plot>
);
Plot components are designed for maximum convenience. This allows you to build diagrams through simple nesting.
The Plot geometry mainly consists of wrappers around the basic geometry layers. e.g. A Point
wraps PointLayer
, but hooks it up automatically to a local DataContext
.
Plot views provide a RangeContext
, used by axes, grids and scales to place themselves automatically in the view.
Views
Geometry
Frames
Sources
The default 3D coordinate system matches WebGPU. X goes left to right, Y goes bottom to top, Z goes in-to-out. The axis order may be changed using the axes
prop on a view.
The projection is normalized to -1..1
on the Y axis, and -aspect..aspect
on the X axis, where aspect = width / height
.
3D viewports are relative to world-space and always show the same view regardless of resolution.
<Flat>
will instead set up "normal" 2D pixel-sized viewport, with the origin in the top-left and Y going down. This is ideal for classic 2D layout and works well with @use-gpu/layout.
<PanControls centered>
.<Flat relative>
.Point sizes and line widths are in (logical) pixels by default. Regardless of canvas size, perspective or device DPI, the apparent size remains the same.
You can control this in several ways:
Geometry
depth
: number
- Value 0...1
- How strongly to apply perspective scaling. i.e. 0
= 2D, 0.5
= 2.5D, 1
= 3D. Default 0
.View / Perspective
focus
?: number
- Distance from camera at which the scaling factor is 1 if depth = 1
. Default 1
scale
?: number | null
- Fixed reference size. If viewport is larger/smaller than this, scale everything up/down to compensate. Default null
.Note that changing the fov
of the camera will not affect the on-screen size of lines.
When scale
is not null
, everything will be scaled proportionally, as height / scale
.
If scale
is 1080
and the canvas is 1440
pixels tall, the scale factor will be 1440/1080
.
To anchor a plot, you place a view such as Cartesian
. You give it a range
to define a mapping from its domain to world space.
It can be placed, rotated and sized like any 3D object:
<Cartesian
range={[[-1, 1], [-1, 1], [-1, 1]]}
position={[0, 0, 0]}
rotation={[0, 0, 0]}
scale={[1, 1, 1]}
>
// ...
</Cartesian>
Place an <Axis>
or <Grid>
inside to align and size it automatically.
Nest views inside other views to combine their transforms.
Non-linear transforms like Polar
have a bend
prop 0..1
. This interpolates smoothly between e.g. cartesian (0
) and polar (1
). This uses custom designed shaders that preserve conformality, scale and aspect ratio as appropriate, to provide a natural and intuitive transition.
Use <Sampled>
to automatically sample data for the entire view range, on one or more axes.
This can then be used as position data for e.g. <Point>
, <Line>
or <Surface>
, explicitly, or provided through the local DataContext
.
For more advanced uses, you can embed the underlying geometry layers directly into the plot. They will respect the coordinate transform of the surrounding view.