Skip to content

@graphty/graphty-element / session / StylesApi

Interface: StylesApi ​

Defined in: graphty-element/src/session/styles/StylesApi.ts:229

The style stack, the verbs that change it, and the three questions a reader asks of it.

Everything on this surface addresses a layer by its id. Nothing on it takes an index, and nothing on it returns one.

Extended by ​

Methods ​

add() ​

add(spec, at?, options?): Run<Layer>

Defined in: graphty-element/src/session/styles/StylesApi.ts:275

Add a layer.

The element mints the id. A specification naming an element source is refused: only the element owns element layers.

Parameters ​

spec ​

LayerSpec

The layer to add.

at? ​

LayerPosition

Which neighbour to sit next to. Neither means the top of the stack; both is refused, because a layer sits in one place.

options? ​

RunOptions

A signal to cancel with, and a progress handler.

Returns ​

Run<Layer>

A run that resolves with the layer as the stack now holds it, and rejects with a GraphtyError when the specification, the position or the source is refused.


agreement() ​

agreement(scope, channel?): StyleAgreement

Defined in: graphty-element/src/session/styles/StylesApi.ts:451

How several elements look, channel by channel: whether they agree, and on what.

The several-elements counterpart of StylesApi.explain, read through the same walk over the stack, so it says about each element what an explanation of that element says. Two elements agree on a channel only when they carry the same value AND the same layer decided it. The answer is counts, never lists of ids, and it costs one pass over the scope.

Parameters ​

scope ​

Scope

The elements to read: the selection, a kept set, a list of node ids, or any other scope the session resolves.

channel? ​

Channel

One channel to restrict the answer to. Absent, every channel something painted is answered.

Returns ​

StyleAgreement

Per channel, the value and deciding layer they all share or how they split, and how many elements nothing painted on it.

Throws ​

A GraphtyError with code E_UNKNOWN_CHANNEL when channel names no channel.


applyTemplate() ​

applyTemplate(document, options?): Run<TemplateReport>

Defined in: graphty-element/src/session/styles/StylesApi.ts:515

Add a saved stack of layers to this one.

THREE OUTCOMES PER LAYER, AND ALL THREE ARE REPORTED. A layer whose paths this session answers is applied and paints. A layer whose paths nothing answers is added DISABLED and reported in unbound with what it needs -- never dropped in silence, and never left enabled to match nothing, because a confident empty screen reads exactly like a correct answer of zero. A layer the element would refuse outright takes the whole document down, so an import either lands or leaves the stack exactly as it was.

Parameters ​

document ​

StyleDocument

The layers to add, bottom first, as StylesApi.toDocument writes them.

options? ​

TemplateOptions

What to record as the template, a signal to cancel with, and a progress handler.

Returns ​

Run<TemplateReport>

A run that resolves with what bound and what did not, and rejects with E_BAD_LAYER for a malformed layer, E_PROTECTED for one claiming to be the element's own, and E_UNSUPPORTED for a palette this element does not have.


encode() ​

encode(spec, options?): Run<Layer>

Defined in: graphty-element/src/session/styles/StylesApi.ts:361

Paint a run's measurement onto a channel. The one path an analysis layer takes.

The layer writes itself: the path of the field, the selector that scopes the layer to exactly the elements the run measured, the kind, the name and the source that records which run, which algorithm and which parameters produced it. A caller supplies the run, the channel and its taste, and cannot get the rest wrong.

IT REPLACES RATHER THAN STACKS. A layer already painting this channel from this run is taken over in place, keeping its id and its position, so a run that was encoded twice leaves one layer and one legend block rather than two. Any other layer writing that channel is left alone: an encoding replaces a derived layer, not a decision somebody made.

A PLAIN DATA COLUMN is encoded the same way, with column in place of run. Whatever the spec leaves off is chosen from what the column measures (session.data.declare) and written into the new layer: one color per value for a categorical column, a ramp or a size range of 1 to 3 for a quantitative one, the declared order for an ordinal one. A later declaration or a new file never changes a layer that already exists. A column encoding adds a layer; it does not replace one.

ts
await session.styles.encode({ column: { kind: "node", name: "department" }, channel: "node.color" });

Parameters ​

spec ​

EncodingSpec | ColumnEncodingSpec

The run or the column, the channel and the taste.

options? ​

RunOptions

A signal to cancel with, and a progress handler.

Returns ​

Run<Layer>

A run that resolves with the layer, and rejects with E_UNKNOWN_RUN for a run this session does not hold, E_UNKNOWN_ATTRIBUTE for a field or column that does not exist, E_BAD_COMMAND when the result has nothing per element to bind a channel to, and with the refusal's code (see StylesApi.proposeEncoding) when a column cannot be drawn on the channel by default.


explain() ​

explain(target): StyleExplanation

Defined in: graphty-element/src/session/styles/StylesApi.ts:435

Why one element looks the way it does: what it is painted, which layer painted each part of it, and whether a person may change any of it where they are looking.

SYNCHRONOUS. It walks the stack once for one element with the same closures the repaint ran, so it is not a second reading of the merge that can drift from the first.

Parameters ​

target ​

ExplainTarget

The node or the edge to explain.

Returns ​

StyleExplanation

The merged style, who contributed what, and which channels are editable.

Throws ​

A GraphtyError with code E_BAD_COMMAND when the session holds no such element.


get() ​

get(id): Layer | undefined

Defined in: graphty-element/src/session/styles/StylesApi.ts:247

One layer, by id.

Parameters ​

id ​

string

The layer id.

Returns ​

Layer | undefined

The layer, or undefined when the stack holds none with that id.


highlight() ​

highlight(spec, options?): Run<readonly Layer[]>

Defined in: graphty-element/src/session/styles/StylesApi.ts:393

Paint the elements a run chose: a route, a chosen set of nodes, a chosen set of edges.

EXCLUSIVE. Every highlight layer already in the stack is taken away first, because a second route replaces the first rather than being painted over it. Which layers count as highlights is read from the run's shape, so an algorithm cannot opt out of it by being called something else, and an element-owned layer is never swept.

A route publishes its membership on nodes AND on edges, and one layer never paints both, so this adds one layer per half the run chose. That is why it resolves with a list.

Parameters ​

spec ​

HighlightSpec

The run, the field that says which elements it chose, and what they look like.

options? ​

RunOptions

A signal to cancel with, and a progress handler.

Returns ​

Run<readonly Layer[]>

A run that resolves with the layers it added, bottom first, and rejects with E_UNKNOWN_RUN for a run this session does not hold and E_BAD_COMMAND when the run measured every element rather than choosing some, which is encode()'s work.


legend() ​

legend(): readonly LegendBlock[]

Defined in: graphty-element/src/session/styles/StylesApi.ts:403

What the picture is telling a reader, derived from the encoding model and never from the canvas.

SYNCHRONOUS, and it measures nothing: every figure in it was worked out when the bindings were prepared. It therefore exists headlessly, in a Node test, and at any export scale.

Returns ​

readonly LegendBlock[]

One block per channel a layer paints from the data, BOTTOM FIRST -- the same order StylesApi.list returns. Empty when nothing is bound to paint.


list() ​

list(): readonly Layer[]

Defined in: graphty-element/src/session/styles/StylesApi.ts:241

Every layer in the stack, BOTTOM FIRST.

Index 0 is the bottom, which is paint order: a layer later in the list paints over a layer earlier in it. The array and the layers in it are frozen, and the same array comes back until the stack changes, so previous === next is a valid staleness test.

The index a layer happens to sit at is NOT its identity. Read Layer.id for that, and pass the id to every other verb.

Returns ​

readonly Layer[]

The layers, bottom first.


move() ​

move(id, before, options?): Run<void>

Defined in: graphty-element/src/session/styles/StylesApi.ts:311

Move a layer to another place in the stack.

before names the layer this one is to sit IMMEDIATELY BELOW, in the bottom-first order StylesApi.list returns -- the same reading as insertBefore in the DOM. null means the top of the stack, where nothing sits above it.

Parameters ​

id ​

string

The layer to move.

before ​

string | null

The layer to sit below, or null for the top of the stack.

options? ​

RunOptions

A signal to cancel with, and a progress handler.

Returns ​

Run<void>

A run that resolves when the layer has moved, and rejects with E_PROTECTED for an element-owned layer and E_UNKNOWN_LAYER when either id is not in the stack.


proposeEncoding() ​

proposeEncoding(spec): EncodingProposal

Defined in: graphty-element/src/session/styles/StylesApi.ts:376

What encode() would store for a spec, without storing anything: the binding, or why the column or field cannot be drawn on that channel by default.

SYNCHRONOUS and cheap: it reads the cached attribute descriptors, never the column, so a menu can ask it for every column and channel on every render.

A refusal is a coded fact whose codes EncodingRefusalCode lists; a run spec's refusal carries the code E_BAD_COMMAND that encode() would reject with.

Parameters ​

spec ​

EncodingSpec | ColumnEncodingSpec

What encode() would be asked.

Returns ​

EncodingProposal

{ ok: true, binding } or { ok: false, refusal }.

Throws ​

A GraphtyError with E_UNKNOWN_ATTRIBUTE, E_UNKNOWN_RUN or E_UNKNOWN_CHANNEL for something that does not exist.


remove() ​

remove(id, options?): Run<void>

Defined in: graphty-element/src/session/styles/StylesApi.ts:298

Take a layer out of the stack.

Parameters ​

id ​

string

The layer to remove.

options? ​

RunOptions

A signal to cancel with, and a progress handler.

Returns ​

Run<void>

A run that resolves when the layer is gone, and rejects with E_PROTECTED for an element-owned layer and E_UNKNOWN_LAYER for an id the stack does not hold.


removeBySource() ​

removeBySource(predicate, options?): Run<readonly string[]>

Defined in: graphty-element/src/session/styles/StylesApi.ts:329

Take away every layer whose source the predicate accepts.

This is how a consumer sweeps up after itself -- every layer a run produced, every layer a template applied -- without keeping its own list of what it added, which is the list that goes stale.

An element-owned layer is NEVER swept, whatever the predicate says, and no refusal is raised for one: a sweep names a category rather than a layer, and failing the whole sweep because the element happens to own a layer the caller never asked about would make the verb unusable. Naming one outright with StylesApi.remove is E_PROTECTED, because that call did ask about it.

Parameters ​

predicate ​

(source) => boolean

Which sources to sweep.

options? ​

RunOptions

A signal to cancel with, and a progress handler.

Returns ​

Run<readonly string[]>

A run that resolves with the ids that were removed, bottom first. An empty list when nothing matched, which is not a failure.


resolveToStatic() ​

resolveToStatic(id, channel, at?, options?): Run<Layer>

Defined in: graphty-element/src/session/styles/StylesApi.ts:469

Turn a rule into the fixed value it currently produces, so a person can then edit it.

THE PAIRED VERB OF StylesApi.explain, which reports a channel worked out from the data as not editable: a control offered there would take a value, write it, and be painted over by the rule on the same repaint. This takes the value the rule produces and writes it as a literal, which is what makes the control honest.

Parameters ​

id ​

string

The layer carrying the rule.

channel ​

Channel

The channel the rule paints.

at? ​

ExplainTarget

The element whose painted value to fix on. Absent, the rule is asked about the largest group it found or the middle of the extent it measured, so the fixed value is a value out of this picture rather than an invented one.

options? ​

RunOptions

A signal to cancel with, and a progress handler.

Returns ​

Run<Layer>

A run that resolves with the layer as it now stands, and rejects with E_PROTECTED for an element-owned layer, E_UNKNOWN_LAYER for an id the stack does not hold, and E_BAD_COMMAND when that layer works the channel out from nothing.


setDefaultPalettes() ​

setDefaultPalettes(palettes, options?): void

Defined in: graphty-element/src/session/styles/StylesApi.ts:541

Choose the palette a colour binding uses when it names none, one per palette kind: a binding on groups takes the categorical default, one on amounts the sequential default, and one with a midpoint the diverging default. A kind left out keeps its current default.

RESOLVED WHEN A LAYER IS WRITTEN: a binding that names no palette records the default's id, so a saved document always names a concrete palette. The call therefore belongs before the layers are added. A later call leaves the layers that took the previous default as they are and writes a warning naming them; with reapply: true it re-resolves those layers instead. A layer that names its palette is never touched.

Parameters ​

palettes ​

DefaultPalettes

The palette id per kind. Each must name a palette of that kind.

options? ​

How a late call treats the layers already written.

reapply? ​

boolean

True re-resolves the layers that took the previous default.

Returns ​

void

Throws ​

E_UNKNOWN_PALETTE for an id no palette answers to, E_BAD_COMMAND for a palette of the wrong kind or a slot that is not a palette kind.


settled() ​

settled(): Promise<void>

Defined in: graphty-element/src/session/styles/StylesApi.ts:424

Resolve once the element has finished painting everything it started for itself.

WHY A CONSUMER NEEDS THIS. The element paints a run's suggested encoding on the run's first completion, and it does so WITHOUT making the caller await the picture -- a reader who asked for a measurement is waiting on the numbers, not on the repaint. The consequence is that await runs.start(...) hands back the result while the paint is still on its way, so a consumer that reads StylesApi.list or StylesApi.legend in the same turn sees the picture as it stood a moment earlier and can reasonably conclude the element painted nothing.

Working that out by counting turns is coordination code, and coordination code is exactly what a consumer should never have to write against this element. So the element answers the question instead.

Every style edit is queued on the session's own queue, so this is the queue being empty rather than a per-run promise: after it resolves there is no element-initiated painting outstanding, whoever started it.

Returns ​

Promise<void>

A promise that resolves when nothing the element started is still in flight.


setValueHidden() ​

setValueHidden(id, channel, value, hidden, options?): Run<Layer>

Defined in: graphty-element/src/session/styles/StylesApi.ts:491

Hide or show the paint of one value of a layer's encoding -- one group of a community run's colours, say -- as one undoable step that is saved with the project.

The value is hidden in channel and in every other channel of the layer that reads the same field, so a group drawn by colour and shape disappears from both; a channel reading another field is left alone, because a value of one field is not the same value in another. An element carrying it is drawn as the layers beneath paint it, as an unmeasured element is. The legend keeps the value's row, marked hidden, with the colour it comes back in. Values are compared as the legend spells them, so 0 and "0" are the same group; pass the channel and a swatch value of a legend block, or the group of a run summary's group.

Parameters ​

id ​

string

The layer, such as the one encode() returned.

channel ​

Channel

The channel whose value it is, such as a legend block's channel.

value ​

string | number | boolean

The value to hide or show.

hidden ​

boolean

True to hide it, false to paint it again.

options? ​

RunOptions

A signal to cancel with, and a progress handler.

Returns ​

Run<Layer>

A run that resolves with the layer as it now stands (its bindings' hidden lists), and rejects with E_PROTECTED for an element-owned layer, E_UNKNOWN_LAYER for an id the stack does not hold, and E_BAD_COMMAND when the layer does not encode channel from the data.


toDocument() ​

toDocument(): StyleDocument

Defined in: graphty-element/src/session/styles/StylesApi.ts:524

The stack as a portable document, for saving, sharing and applying to another dataset.

SYNCHRONOUS. The element's own layers are NOT in it: they come with the element, they cannot be added by a consumer, and a document carrying them would either duplicate them or be refused wherever it was applied. What a document holds is what somebody chose.

Returns ​

StyleDocument

The document, bottom first.


update() ​

update(id, patch, options?): Run<Layer>

Defined in: graphty-element/src/session/styles/StylesApi.ts:290

Change a layer, keeping its id.

The patch is applied over the layer's current specification, one key deep. A key present with undefined CLEARS it, so { set: undefined } drops the literal values; a key absent leaves what was there. The merged specification is checked exactly as a new one would be, so an update cannot leave a layer in a state add would have refused.

Parameters ​

id ​

string

The layer to change.

patch ​

Partial<LayerSpec>

What to change about it.

options? ​

RunOptions

A signal to cancel with, and a progress handler.

Returns ​

Run<Layer>

A run that resolves with the layer as it now stands, and rejects with E_PROTECTED for an element-owned layer and E_UNKNOWN_LAYER for an id the stack does not hold.


validate() ​

validate(spec): ValidationResult

Defined in: graphty-element/src/session/styles/StylesApi.ts:262

Check a layer specification without adding it.

SYNCHRONOUS, and it writes nothing: this is what a form calls on every keystroke and before a person presses Apply. It reports every problem it finds rather than the first, each with a path into the specification and, for an expression, the character offset -- and reports separately the paths that parsed but that nothing in this session answers, which are not errors.

It deliberately does not say how many elements would match. Counting is a pass over the graph; that question is session.plan(), which is a command and says so.

Parameters ​

spec ​

LayerSpec

The layer as it would be added.

Returns ​

ValidationResult

The verdict.