Documentation
¶
Overview ¶
Package arrow adapts Apache Arrow data to figure's data layer.
It is a module of its own so that the core stays what it claims to be: a chart library with no dependencies. Arrow is a large dependency and most charts have nothing to do with it, so it enters only for the programs that already hold Arrow data — and for them it is the shortest possible path, because Arrow's columnar layout is the layout figure already wants.
The import path carries a major version, and it is Arrow's rather than figure's: this module adapts apache/arrow-go/v18, and its own major version follows its upstream's so that the two can never disagree about what an Arrow record is. The package name is still arrow.
import "github.com/timzifer/figure/arrow/v18"
rec := reader.Record()
src := arrow.Source(rec)
p := figure.New(figure.Title("Latency"))
p.Add(geom.Line(src, geom.X("t"), geom.Y("p99")))
What is borrowed and what is copied ¶
A float64 column with no nulls is borrowed: data.Source.Float64Column returns Arrow's own buffer, with no copy and no conversion. That is the case the two libraries agree about exactly — IEEE-754 doubles, contiguous, one per row.
Everything else is converted once, on first use, and cached: an integer or float32 column becomes float64, a timestamp becomes time.Time, a string view becomes a Go string. A column the chart never reads is never converted, so a record with forty columns and a chart that plots two pays for two.
Nulls ¶
An Arrow null becomes NaN in a numeric column, the zero time in a temporal one and the empty string in a categorical one — and the validity bitmap is offered beside the values as data.Column.Nulls, which is what tells the second two apart from a value somebody measured. NaN is what figure's missing-data policies are written against, so a null row is gapped, interpolated or rejected by the same [geom.OnMissing] setting that handles a NaN coming from anywhere else; with the mask that is true of a timestamp and a category as well, where before an absent instant was the year 1 and an absent category was a band of its own. A float64 column that has nulls is copied rather than borrowed: the nulls have to become NaN somewhere, and writing them into Arrow's buffer is not this package's memory to write. A column with no nulls offers no mask, so the borrowed path is untouched.
Lifetime and concurrency ¶
A Source borrows the record; it does not retain a reference to it beyond what it needs and does not release it. Keep the record alive — and its memory unreleased — for as long as the chart may be rendered.
Resolving a column for the first time fills a cache, so a Source is not safe for concurrent first use. Render once before sharing one across goroutines, or use Materialize, which converts everything up front and returns a Source that is read-only thereafter.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Materialize ¶
Materialize converts every column src can offer and returns a plain data.Table holding the results.
It is the escape hatch from the lazy path: the conversions happen once, here, and the result shares nothing with Arrow — so the record can be released, and the table can be read from as many goroutines as like. The cost is a copy of every column, including the float64 ones a lazy Source would have borrowed.
func Source ¶
Source returns a data.Source over one Arrow record batch.
A nil record gives an empty Source rather than a panic: an empty batch is a normal thing for a reader to hand back, and a chart over no rows is a chart with no marks.
func TableSource ¶
TableSource returns a data.Source over an Arrow table.
A table holds each column as a list of chunks, and figure's data layer is one slice per column — so a chunked column is concatenated on first use. A single-chunk column takes the same path a record does, borrowing where it can.
Types ¶
This section is empty.