Place
The Place family holds the ways a label can find its spot on the mark it labels. A place is a value of the position option of .label(), beside the position strings ("outset-top", "center", ...). A position string puts the label at one spot by the mark's box. A place reads the mark's outline and tries spots in order.
import { Place, Unit, chart, group, line, scatter } from "gofish-graphics";
import data from "vega-datasets";
const yearlyStocks = async () => {
const rows = (await data["stocks.csv"]()) as any[];
const acc = new Map<
string,
{ symbol: string; date: string; sum: number; n: number }
>();
for (const d of rows) {
const year = new Date(d.date).getFullYear();
const key = `${d.symbol}${year}`;
const e = acc.get(key) ?? {
symbol: d.symbol,
date: `${year}-07-01`,
sum: 0,
n: 0,
};
e.sum += +d.price;
e.n += 1;
acc.set(key, e);
}
return [...acc.values()].map((e) => ({
symbol: e.symbol,
date: e.date,
price: Math.round((e.sum / e.n) * 100) / 100,
}));
};
(async () => {
const loaded = { stocks: await yearlyStocks() };
const context = { loaded };
const container = document.getElementById("app");
chart(context.loaded.stocks, { schema: { date: Unit.time() }, w: 560, h: 320 })
.flow(
group({ by: "symbol" }),
scatter({ by: "date", x: "date", y: "price" })
)
.mark(
line({ stroke: "symbol", strokeWidth: 2 }).label("symbol", {
position: Place.along({ at: 0.6, orient: "sloped" }),
halo: {},
fontWeight: 600,
})
)
.render(container, { axes: true, legend: false });
})();Signature
Place.around; // or Place.around({ directions?, side?, offset? })
Place.along; // or Place.along({ at?, side?, orient?, offset? })
Place.start; // or Place.start({ offset? })
Place.end; // or Place.end({ offset? })
Place.interior;No place has a required option, so each member is a place as it is, and calling it sets options: Place.end and Place.end() are the same place. A place is a plain object, { kind, ...params }, of type Place.Place, for example { kind: "along", at: 0.6, orient: "sloped" }. The same object is the place's wire form.
The family is also a module of its own:
import { Place } from "gofish-graphics";
import { along } from "gofish-graphics/place"; // the same value as Place.alongMembers
| Member | Reads | Where the label goes | Default for |
|---|---|---|---|
Place.around() | the outline's extreme points | Just outside the mark, in each of eight screen directions. | a dot (circle) |
Place.along() | an open path or a region's outline | On or beside the outline, sliding along it from at. | |
Place.start() | an open path's first point | Just before the path's start, level. | |
Place.end() | an open path's last point | Just past the path's end, level. | a line, an arrow |
Place.interior() | a filled region | Inside the region, where the label's box can grow largest. | a band, a polygon |
With no position, a label takes the default for its mark's kind of geometry, and "outset" for any other mark.
How the labels of one call are placed
The labels of one .label() call are placed together, in data order. Each takes its first spot that stays inside the plot and covers no labeled mark, no label already placed, and no node in the label's avoiding option. A label with no free spot is hidden, and the render prints how many labels each call hid. A label of Place.start() or Place.end() has one spot, past its path's end, which may be outside the plot. Labels there that would cover each other slide apart vertically, and a label that still covers a mark, a label or a node in avoiding is hidden.
A position string ignores avoiding, and is never hidden.
In a polar or other curved coordinate space, a place is an error, and a label's default is "outset" (#1201).
Place.around()
| Option | Type | Default | Description |
|---|---|---|---|
directions | "top-right" | "top-left" | "bottom-right" | "bottom-left" | "right" | "left" | "top" | "bottom"[] | ["top-right", "top-left", "bottom-right", "bottom-left", "right", "left", "top", "bottom"] | The directions to try, in order. |
side | "outset" | "inset" | "outset" | "inset"[] | "outset" | Outside the outline ("outset") or inside it ("inset"), or a list tried in order at each direction: ["outset", "inset"] with directions ["top"] puts a bar's value above it, or inside its top when there is no room above. |
offset | number | Pixels between the outline and the label. Default: the label's offset, or 3. |
Place.along()
| Option | Type | Default | Description |
|---|---|---|---|
at | number | "start" | "middle" | "end" | "x-min" | "x-max" | "y-min" | "y-max" | "middle" | Where along the outline: a fraction of its length, 0 to 1 (the label is centered there); "start" or "end" (the label's start or end is flush with the path's); "middle"; or an edge of a box, "x-min", "x-max", "y-min" or "y-max", named by axis in the mark's own frame (the label stays within that edge, or is hidden). |
side | "on" | "above" | "below" | "left" | "right" | "inset" | "outset" | "on" | "above" | "below" | "left" | "right" | "inset" | "outset"[] | "on" | Which side of the outline: "on" straddles it. On an open path, "above" and "below" are the screen's (a stretch steeper than about 75 degrees has neither, so it gives no spot), and "left" and "right" are the path's own, of its direction of travel. On a closed outline, "inset" and "outset" are inside and outside. A list is tried in order at each spot. |
orient | "horizontal" | "sloped" | "horizontal" | "horizontal" keeps the label level. "sloped" turns it to the chord of the outline across the label's width, kept upright, and skips a spot where the outline bends away from the chord by more than about a third of the text's height, so it suits smooth lines. |
offset | number | Pixels between the outline and the label. Default: the label's offset, or 3. |
Place.start()
| Option | Type | Default | Description |
|---|---|---|---|
offset | number | Pixels between the outline and the label. Default: the label's offset, or 4. |
Place.end()
| Option | Type | Default | Description |
|---|---|---|---|
offset | number | Pixels between the outline and the label. Default: the label's offset, or 4. |
Place.interior()
| Option | Type | Default | Description |
|---|
See also
- How to place labels
- Labels, the essay on how labels are placed
