@lipme/vuenomics-visualization-components
| Install | |
|---|---|
npm install @lipme/vuenomics-visualization-components |
|
| Latest Version: | 1.0.0 |
| Vue: | 3 |
| Last Updated: | Oct 20, 2026 |
| Links: | Repository · npm |
Vuenomics Visualization Components
Vue 3 and D3 components to display genomics data (genes, coverage, alignments, variants, sequences, BED regions) as synchronized, zoomable tracks.
Upgrading from 0.x? See MIGRATION.md.
Install
npm install @lipme/vuenomics-visualization-components
Requirements: Vue 3.5+ (peer dependency). The package is published as ES modules only; Node.js 20.19+ can also require() it.
import {
GenomeAxis,
GffViewer,
CovViewer,
BamViewer,
VcfViewer,
VcfMatrixViewer,
FastaViewer,
BedViewer
} from '@lipme/vuenomics-visualization-components'
import '@lipme/vuenomics-visualization-components/style.css'
Or register every component globally with the plugin:
import VuenomicsComponents from '@lipme/vuenomics-visualization-components'
app.use(VuenomicsComponents)
The types of the props, events and loaders (Variant, GffFeature, CoverageData, BedFeature, AxisSettings…) are exported from the package root.
Quick start
Tracks are placed inside a GenomeAxis, which draws the coordinates, gives the tracks their width and margins, and keeps their zoom in sync:
<template>
<GenomeAxis
:domain="[6380000, 6420000]"
:right-boundary="7000000"
:settings="{ width: 1000 }"
@update-domain="(domain) => console.log('displayed region', domain)"
>
<GffViewer :data="genes" :height="200" track-name="Genes" />
<CovViewer :data="{ forward: coverage }" track-name="Coverage" />
<VcfViewer :data="variants" track-name="Variants" />
</GenomeAxis>
</template>
- Tracks zoom with the mouse wheel and pan by dragging; ctrl+drag on the axis selects a region.
- Each
GenomeAxissynchronizes only its own tracks: several independent browsers can live on the same page. - Every track has a
heightprop (in pixels) and an optionaltrackName. Their width and margins are those of the axis.
Common events
| Event | Payload | Emitted by |
|---|---|---|
updateDomain |
[start, end] |
the axis and every track, at the end of a zoom, pan or brush gesture (the axis for gestures made on any of its tracks, a track for gestures made on it) |
featureSelect |
the feature | GffViewer (ctrl+click, since a click starts a pan), BamViewer, VcfViewer, VcfMatrixViewer, BedViewer |
featureHover |
the feature, or null |
the same tracks |
Loading data from indexed files
The loaders read a region from bgzipped, indexed files served over HTTP (range requests). Each file is opened once: its index and header are downloaded on the first request only, and the readers are only loaded when a loader is first used.
import { getVcf, getFasta, getGff, clearDataCache } from '@lipme/vuenomics-visualization-components'
// coordinates: 0-based start, end excluded
const variants = await getVcf('https://example.org/data.vcf.gz', 'chr1', 10000, 20000)
const sequence = await getFasta('https://example.org/genome.fa.gz', 'chr1', 10000, 20000)
const features = await getGff('https://example.org/genes.gff3.gz', 'chr1', 10000, 20000)
clearDataCache() // forget the opened files, e.g. after they changed on the server
The last argument is an optional options object:
tbiUrl(getVcf,getGff),faiUrlandgziUrl(getFasta): URLs of the indexes. They default to the file URL followed by.tbi,.faiand.gzi.signal: anAbortSignal, to cancel the load of a region that is no longer displayed.
const controller = new AbortController()
getVcf(url, 'chr1', 10000, 20000, { tbiUrl: `${url}.tbi`, signal: controller.signal })
controller.abort()
Serve the files without Content-Encoding: gzip (some servers add it for .gz files, which breaks range requests): the .bgz extension avoids it.
getGff returns the GFF3 features with their child features. The GffViewer also needs the level (row) of each feature, in its place field.
Components
GenomeAxis
| Prop | Type | Default | Description |
|---|---|---|---|
domain |
[number, number] |
required | Displayed region. Setting it again resets the view after a zoom. |
rightBoundary |
number |
required | End of the sequence: panning stops there. |
leftBoundary |
number |
0 |
Start of the sequence. |
maxRange |
number |
1000000 |
Largest region displayed by zooming out. |
settings |
Partial<AxisSettings> |
{ width: 800, height: 40, marginLeft: 20, marginRight: 20 } |
Size of the axis; width and the margins are also those of its tracks. |
Slots: default (the tracks) and screenshot, whose screenshotFunction prop saves the axis and its tracks as a PNG image.
<GenomeAxis :domain="region" :right-boundary="chromosomeLength">
<!-- tracks -->
<template #screenshot="{ screenshotFunction }">
<button @click="screenshotFunction">Take a screenshot</button>
</template>
</GenomeAxis>
GffViewer
Displays GFF3 features and their child features (mRNA, CDS, UTRs…).
| Prop | Type | Default | Description |
|---|---|---|---|
data |
PlacedGffFeature[] |
required | GFF3 features (as returned by getGff) with their level in place. |
colorService |
FeatureColors |
colors by feature type | Colors of the features, e.g. a ColorService of @lipme/gffcolors, which colors the CDS from the annotations. TypeColors (exported) takes custom colors by type. |
labelFunc |
(feature: PlacedGffFeature) => string |
the ID, or the Name |
Label of the features. |
height |
number |
300 |
<GffViewer
:data="genes"
:color-service="new TypeColors({ gene: 'teal', mRNA: 'orange', unknown: 'gray' })"
/>
CovViewer
Displays the coverage of the forward strand, and optionally of the reverse strand (negative scores).
| Prop | Type | Default | Description |
|---|---|---|---|
data |
{ forward: CoverageType[]; reverse?: CoverageType[] } |
required | Intervals { start, end, score } (0-based start, end excluded). |
coverageColors |
{ forward: string; reverse: string } |
{ forward: 'blue', reverse: 'red' } |
|
height |
number |
150 |
BamViewer
Draws alignments on a canvas, with their insertions, deletions and mismatches.
| Prop | Type | Default | Description |
|---|---|---|---|
data |
BamData |
required | { bams, indels?, mismatches?, gaps? }, each item with its level in place. |
alignmentColors |
AlignmentColors |
{ alignments: 'steelblue', inserts: 'silver', dels: 'black', mismatches: 'crimson' } |
|
height |
number |
300 |
VcfViewer
Displays variants, colored by type (SNV, insertion, deletion) or by a coloring strategy.
| Prop | Type | Default | Description |
|---|---|---|---|
data |
Variant[] |
required | Variants, e.g. returned by getVcf. |
vcfSettings |
Partial<VCFSettings> |
{ vcfHeight: 10, dataConcentration: 15, fontSize: 12, labelPosition: 20, vcfMinWidth: 2, maxConcentration: 100, textColor: 'black' } |
dataConcentration: number of levels, as a percentage of the number of variants; labels are displayed below maxConcentration visible variants. |
variantColors |
VariantColors |
{ snv: 'green', del: 'red', ins: 'blue', unknown: 'black' } |
|
coloringStrategy |
ColoringStrategyType |
Colors from the INFO fields, see below. Variants without a color from the strategy keep their type color. | |
labelFunc |
(variant: ModifiedVariant) => string |
type, REF and ALT | |
height |
number |
300 |
Two coloring strategies are provided:
import { colorByThreshold, colorByValue } from '@lipme/vuenomics-visualization-components'
// color of the largest of the HET, HOM, NC and WT INFO fields
const byGenotypes = {
colorInfo: { HET: 'green', HOM: 'blue', NC: 'black', WT: 'red' },
strategy: colorByThreshold
}
// color of the first regular expression matching the value of an INFO field
const byEffect = {
field: 'ANN',
colorInfo: {
high: { regex: '\\|HIGH\\|', color: 'crimson' },
low: { regex: '\\|LOW\\|', color: 'gray' }
},
strategy: colorByValue
}
VcfMatrixViewer
Displays the genotype of each sample for each variant.
| Prop | Type | Default | Description |
|---|---|---|---|
data |
Variant[] |
required | Variants with a GENOTYPES() method, like those returned by getVcf. |
samplesName |
string[] |
required | Samples displayed, one per row. |
genotypeColors |
MatrixColorsSettings |
{ '0/0': 'orange', './.': 'red', '1/1': 'indigo', '0/1': 'green', unknown: 'black' } |
Color of each genotype, with the color of the others (unknown). |
vcfSettings |
Partial<VcfMatrixSettings> |
{ vcfHeight: 10, vcfMinWidth: 2, textColor: 'black' } |
|
height |
number |
300 |
FastaViewer
Displays a sequence and its complement when the visible region is small enough.
| Prop | Type | Default | Description |
|---|---|---|---|
data |
string |
required | Sequence, e.g. returned by getFasta. |
fastaSettings |
Partial<FastaSettings> |
{ startPosition: 0, maxSize: 1000, warningMessage: 'Fasta data is too big to be displayed' } |
startPosition: 1-based position of the first base of data; the sequence is displayed when the visible region is shorter than maxSize, and warningMessage otherwise. |
nucleotideColors |
NucleotideColors |
{ A: 'red', T: 'blue', C: 'green', G: 'yellow', N: 'white' } |
|
height |
number |
300 |
BedViewer
Displays BED regions, colored by score (or by strand without score), with strand arrows.
| Prop | Type | Default | Description |
|---|---|---|---|
data |
BedFeature[] |
required | { chromStart, chromEnd, name, strand, score?, place } (0-based start, end excluded; strand 1, -1 or unknown). |
bedSettings |
Partial<BedSettings> |
{ minScore: 0, maxScore: 1000, textColor: 'black', fontSize: 12, labelPosition: 20, minWidth: 2, bedHeight: 10 } |
Scores from minScore to maxScore get the colors of scoreColors. |
scoreColors |
[string, string] |
['blue', 'yellow'] |
|
strandColors |
{ '+': string; '-': string; unknown: string } |
{ '+': 'green', '-': 'red', unknown: 'gray' } |
|
labelFunc |
(feature: BedFeature) => string |
the name | |
height |
number |
300 |
Development
VSCode with the Vue extension is recommended.
| Command | |
|---|---|
npm run dev |
Demo page (src/views/BaseView.vue) with every component and mock data. |
npm run preview |
Builds the demo into dist-demo and serves it. |
npm run build |
Type-checks and builds the library into dist. |
npm run lint / lint:check |
|
npm run test:unit |
Vitest. |
npm run test:component |
Cypress component tests. |
npm run test:e2e |
Cypress tests of the built demo. |
npm run generate-mock-data |
Regenerates public/mock-data (requires bgzip, tabix and samtools). |
Mock data:
src/mocks/*.json: genes, coverage, alignments and GFF colors.public/mock-data/: a synthetic bgzipped FASTA (.fai,.gzi), a tabix-indexed VCF and a tabix-indexed GFF3, read through HTTP range requests with the same loaders as an application. Restartnpm run devafter regenerating them.
The bgzipped files use the .bgz extension: static servers usually send Content-Encoding: gzip for .gz files, which makes the browser decompress the requested byte ranges and breaks the indexed readers. The public/ folder is not copied into the library build.
Related Packages
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.0.0 | ^3.5.0 | ||
| 0.2.0 | ^3.4.29 | ||
| 0.1.46 | ^3.4.29 | ||
| 0.1.45 | ^3.4.29 | ||
| 0.1.44 | ^3.4.29 | ||
| 0.1.43 | ^3.4.29 | ||
| 0.1.42 | ^3.4.29 | ||
| 0.1.41 | ^3.4.29 | ||
| 0.1.39 | ^3.4.29 | ||
| 0.1.38 | ^3.4.29 | ||
| 0.1.37 | ^3.4.29 | ||
| 0.1.36 | ^3.4.29 | ||
| 0.1.35 | ^3.4.29 | ||
| 0.1.34 | ^3.4.29 | ||
| 0.1.33 | ^3.4.29 | ||
| 0.1.32 | ^3.4.29 | ||
| 0.1.31 | ^3.4.29 | ||
| 0.1.30 | ^3.4.29 | ||
| 0.1.29 | ^3.4.29 | ||
| 0.1.28 | ^3.4.29 | ||
| 0.1.27 | ^3.4.29 | ||
| 0.1.26 | ^3.4.29 | ||
| 0.1.25 | ^3.4.29 | ||
| 0.1.24 | ^3.4.29 | ||
| 0.1.23 | ^3.4.29 | ||
| 0.1.22 | ^3.4.29 | ||
| 0.1.21 | ^3.4.29 | ||
| 0.1.20 | ^3.4.29 | ||
| 0.1.19 | ^3.4.29 | ||
| 0.1.18 | ^3.4.29 |
Showing the latest 30 of 73. See every release on npm