Releases: timzifer/figure
Release list
v0.9.0
v0.8.1 — the browser backend's tests compile
A test-only patch over v0.8.0, whose release notes describe everything in this release.
go get github.com/timzifer/figure@v0.8.1The library code is identical to v0.8.0. What changed is four calls in
backend/canvas's own tests, which open a target and had not followed
ir.Target.Open to ir.Surface. That package is behind //go:build js && wasm, so a build on any other platform does not compile its tests and the
sweep that updated every other call site could not see them.
Nothing a caller imports is affected, and nothing needs migrating from v0.8.0.
The tag exists so that every published version of this module passes the checks
the repository gates on, GOOS=js GOARCH=wasm included.
The nested modules are unchanged and keep their v0.8.0 tags:
backend/gg/v0.8.0, backend/window/v0.8.0, backend/gg/gpu/v0.3.0,
arrow/v18.0.4.
v0.8.0 — the first release under this name
The first release under this name, and a deliberate v0.x.
go get github.com/timzifer/figure@v0.8.0| Module | Tag |
|---|---|
github.com/timzifer/figure |
v0.8.0 |
github.com/timzifer/figure/backend/gg |
backend/gg/v0.8.0 |
github.com/timzifer/figure/backend/window |
backend/window/v0.8.0 |
github.com/timzifer/figure/backend/gg/gpu |
backend/gg/gpu/v0.3.0 |
github.com/timzifer/figure/arrow/v18 |
arrow/v18.0.4 |
Why v0.x
The model is settled and the API is not frozen. Three seams take positional
scale arguments and are the wrong shape for a chart that gains a dimension
(ADR 0056).
Correcting them is free while nobody has to migrate, and v0.x says plainly
that it has happened rather than promising a freeze that would break in the
next release. v1.0.0 returns when the reshaping is done
(ADR 0059).
Every seam an outsider implements now takes one growable value
An interface a third party implements never gains a method — and under that
rule a method with positional parameters can never gain one either, so each is
a future break or a future optional interface. Three optional interfaces in the
tree existed for exactly that reason. They are gone, and the seams that
produced them take a struct
(ADR 0060).
| Seam | Before | After |
|---|---|---|
geom.Geom |
Train(x, y scale.Scale) error |
Train(t geom.Training) error |
render.Observer |
Panel(i, area, x, y, cd) |
Panel(p render.PanelInfo) |
render.Observer |
Layer(i int, label string) |
Layer(l render.LayerInfo) |
render.Observer |
— | gains End() |
render.LayerAxes, render.EndData |
optional interfaces | removed — fields on LayerInfo, and Observer.End |
render.LegendEntry / ColorbarEntry / SizeKeyEntry |
positional arguments | LegendInfo / ColorbarInfo / SizeKeyInfo |
coord.Coord |
Frame(area, x, y) |
Frame(f coord.Framing) |
coord.Coord |
Furniture(dst, area, m, xTicks, yTicks) |
Furniture(dst, req coord.FurnitureRequest) |
coord.Opposite |
FurnitureY2 + FurnitureX2 |
FurnitureOpposite(dst, req) |
ir.Target / ir.Resizer |
Open(w, h int, dpr float64) / Resize(…) |
Open(s ir.Surface) / Resize(s ir.Surface) |
mathtext.Typesetter |
Typeset(src, font, m) |
Typeset(req mathtext.Request) |
geom.Rows |
Marks(at []ir.Point, rows []int) |
Marks(m geom.MarkRows) |
scale.Scale |
Ticks(want int) []Tick |
Ticks(req scale.TickRequest) []Tick |
The migration is mechanical: a method's parameters become field reads, and the
compiler finds every site.
LayerAxes and EndData are removed rather than restructured because an
implementation that omits either is wrong rather than narrower — one indexes
furniture as data, the other reads a secondary axis through the wrong scale.
The three guide reports stay optional, because an observer that does not care
where the legend was drawn is only narrower.
A column is one value, and an identifier is exact
data.Source had three typed accessors and a promise that a fourth kind of
column would arrive as an optional interface. It has one accessor returning a
growable data.Column
(ADR 0061).
type Source interface {
Len() int
Columns() []string
Column(name string) (Column, bool)
}data.KindInt64— exact integers. Afloat64stops counting exactly at
2^53, and the column that holds large integers is the column that holds
identifiers. Keys are compared as their spelling, so two ids one apart above
2^53 used to be one key, one facet panel and one row — and printed as
9.007199254740992e+15.data.Table.Int64and the Arrow adapter's integer
path keep them exact. A position still converts tofloat64: a pixel cannot
show the difference, and the exactness that matters is where identity is
compared.Column.Nullsreplaces thedata.Nullsinterface. Absence travels with
the values it describes. It had to: two wrapping Sources in this repository
did not forward the old method, so a marked row silently lost its mark
through a transition and the blend interpolated a value nobody measured.Column.Textis an optional per-row spelling. It is what lets a Source
carry values figure has no type for — a physical quantity plots asfloat64
positions and spells as"2.5 bar"— with figure knowing nothing about units.spec.ParseIntegercarries an exact column through the JSON round trip,
decoded viajson.Numberso the digits survive.
Every backend draws the same marker
ir.MarkerPath is exported. Marker outlines were internal, so backend/gg
carried a hand-maintained copy and a backend written outside this repository
would draw a marker added later as a circle — silently. ir.Marker grows at
the end, and MarkerPath appends a circle for a shape it does not know, so a
backend stays correct across that growth. Not a breaking change.
Documentation
The README is a quarter of its former length: what the library is, how to
install it, one working program, the feature surface, and where the seams are.
The walkthroughs moved into linked files under docs/ — the gallery, chart
forms, interaction, scaling out, reading, the JSON dialect — each cross-linked
so the set reads as one document.
The version archaeology is gone with it: no struck-out lines, no "shipped in
vX.Y". The record of how each capability arrived, with the argument that shaped
it, is docs/milestones.md.
Compatibility
Anything written against github.com/timzifer/refract keeps working on its own
tags and receives nothing new. There is no automated migration and none is
claimed: change the import path, then let the compiler find the seams in the
table above.