Runtime State¶
Named data¶
Named data sources allow data to be provided at runtime instead of loading it
from a URL or embedding it directly in the specification. In the view
specification, declare a named data source with the data.name property:
{
"data": {
"name": "myResults"
},
...
}
There are two ways to provide the data:
updateNamedData()¶
Call updateNamedData(name, data) when your application provides updated data
explicitly.
const api = await embed("#container", spec);
api.updateNamedData("myResults", [
{ x: 1, y: 2 },
{ x: 2, y: 3 },
]);
namedDataProvider¶
The namedDataProvider embed option lets GenomeSpy load named data on demand.
const api = await embed("#container", spec, {
namedDataProvider(name) {
if (name == "myResults") {
return [
{ x: 1, y: 2 },
{ x: 2, y: 3 },
];
}
},
});
If updateNamedData(name) is called without the second argument, GenomeSpy
retrieves the data from the provider instead.
Named data can be updated dynamically, but it does not automatically react to user interactions. For practical examples, see the embed-examples package.
Named scales¶
A scale resolution is the scale instance shared by one or more view encodings. Composition settings determine whether child views share a scale resolution or use independent ones. See Scale, Axis, and Legend Resolution.
Name a scale resolution with scale.name to access it from the embed API with
getScaleResolutionByName(name). The name identifies the resolved scale, not an
individual view encoding. Shared encodings can use the same scale.name, while
independent scale resolutions must have unique names.
getScaleResolutionByName(name) returns undefined when the name is not
registered.
Named scales are useful when host application code needs to read the current domain, zoom a view programmatically, or synchronize domains between embedded GenomeSpy instances. See also Scale.
{
"encoding": {
"x": {
"field": "x",
"type": "quantitative",
"scale": {
"name": "detailScale",
"domain": [0, 100],
"zoom": true
}
}
}
}
const detailScale = api.getScaleResolutionByName("detailScale");
if (!detailScale) {
throw new Error("Missing named scale: detailScale");
}
console.log(detailScale.getDomain());
await detailScale.zoomTo([25, 50]);
Domains¶
getDomain() returns the current domain used by the scale. For locus scales,
this is the linearized numeric domain.
getComplexDomain() returns the current domain converted back to complex
domain values when available, such as genomic loci for locus scales. See
Specifying the domain for locus
domain syntax.
const genomeScale = api.getScaleResolutionByName("genomeScale");
if (!genomeScale) {
throw new Error("Missing named scale: genomeScale");
}
console.log(genomeScale.getDomain());
console.log(genomeScale.getComplexDomain());
For a locus scale, zoomTo() accepts either a linearized numeric interval or a
complex genomic interval:
await genomeScale.zoomTo([{ chrom: "chr8" }, { chrom: "chr10" }]);
await genomeScale.zoomTo([400_000_000, 500_000_000]);
Pass { duration: true } or { duration: milliseconds } to animate the zoom:
await genomeScale.zoomTo([{ chrom: "chr1" }, { chrom: "chrM" }], {
duration: true,
});
Domain events¶
Named scales emit a "domain" event when their domain changes. Listen to the
event when external UI must reflect zoom or pan state:
const genomeScale = api.getScaleResolutionByName("genomeScale");
if (!genomeScale) {
throw new Error("Missing named scale: genomeScale");
}
const listener = (event) => {
console.log(event.scaleResolution.getComplexDomain());
};
genomeScale.addEventListener("domain", listener);
Remove listeners when they are no longer needed:
genomeScale.removeEventListener("domain", listener);
Domain events can also drive application-level linking. For example, a brush
parameter in one embed can call zoomTo() on a named scale in another embed.
For examples, see the scaleApi, brushLinkingApi, and linkedEmbeds pages
in the
embed-examples
package.
Parameters¶
Named parameters can be accessed through getParam(). The returned handle can
read and write the parameter value and subscribe to changes:
const api = await embed(container, spec);
const threshold = api.getParam("threshold");
console.log(threshold.getValue());
threshold.setValue(5);
const unsubscribe = threshold.subscribe((value) => {
console.log("threshold changed", value);
});
Variable parameters and interval selections can be read and written.
intervalSelection() constructs interval selection values:
import { embed, intervalSelection } from "@genome-spy/core";
const brush = api.getParam("brush");
brush.setValue(intervalSelection({ x: [10, 20] }));
Current limitations:
- Parameters are addressed by name only. If the name resolves to multiple
independent parameters,
getParam()throws an ambiguity error. - Parameters declared with
push: "outer"are resolved as aliases of the outer parameter they write to. - Computed
exprparameters are readable but cannot be written. - Point selections are readable but cannot be written through the API because valid values require GenomeSpy-generated datum ids.
- Projected selections are not supported.
For spec-side parameter behavior, including input bindings, selections, and
push: "outer" for linking scale domains, see
Parameters.
For examples, see the paramApi and brushLinkingApi pages in the
embed-examples
package.