npm package: @lipme/vuenomics-visualization-components
Description: This is a compilation of visualization components made in Vue and D3 designed to display genomics data in a reactive way.
Author: Sbyi
Latest version: 0.1.46

# Vuenomics Visualization Components

This is a compilation of visualization components made in Vue and D3 designed to display genomics data in a reactive way.

## Recommended IDE Setup

[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).

## Components install

```sh
npm install @lipme/vuenomics-visualization-components
```

```typescript
import {
  Axis,
  GffViewer,
  CovViewer,
  BamViewer,
  VcfViewer,
  FastaViewer
} from 'lipme/vuenomics-visualization-components'
```

### Settings Prop

Each component has a settings prop that can be used to change the width, height, marginLeft, and marginRight of the component.

```typescript
type Settings = {
  width: number
  height: number
  marginLeft: number
  marginRight: number
}
```

**Note: Width and margins must be the same on each component to ensure proper alignment.**

### Axis Component

The `Axis` component is used to display the axis of the charts. It also ties together the different components to have the same scale. Additionally, it provides a slot for adding custom content and a screenshot function for exporting the axis as an image.

#### Props

- `domain`: The domain of the axis.

  - **Type**: `[number, number]`
  - **Description**: The start and end positions of the axis domain.

- `settings`: Configuration settings for the axis.

  - **Type**: `ConfigI`
  - **Default**:

    ```typescript
    {
      width: 800,
      height: 50,
      marginRight: 20,
      marginLeft: 20
    }
    ```

  - **Description**: An object containing the width, height, marginRight, and marginLeft for the axis layout.

- `rightBoundary`: The right boundary of the axis.

  - **Type**: `number`
  - **Description**: The right boundary value for the axis.

- `leftBoundary`: The left boundary of the axis.

  - **Type**: `number`
  - **Default**: `0`
  - **Description**: The left boundary value for the axis.

- `maxRange`: The maximum range of the axis.

  - **Type**: `number`
  - **Default**: `1000000`
  - **Description**: The maximum range value for the axis.

#### Slots

- `default`: Slot for adding custom content to the axis.

- `screenshot`: Slot for providing a button or UI element to trigger the screenshot function. The slot exposes the `screenshotFunction` as a prop.

#### Example Usage

```vue
<template>
  <Axis
    :domain="[regionStart, regionEnd]"
    :settings="axisSettings"
    :rightBoundary="rightBoundary"
    :leftBoundary="leftBoundary"
    :maxRange="maxRange"
  >
    <template v-slot:default>
      <!-- Add your components here -->
    </template>
    <template v-slot:screenshot="slotProps">
      <button @click="slotProps.screenshotFunction">Take Screenshot</button>
    </template>
  </Axis>
</template>

<script setup>
import { Axis } from '@lipme/vuenomics-visualization-components'
import { ref } from 'vue'

const regionStart = ref(1000000)
const regionEnd = ref(2000000)

const axisSettings = {
  width: 800,
  height: 50,
  marginRight: 20,
  marginLeft: 20
}

const rightBoundary = 2000000
const leftBoundary = 0
const maxRange = 1000000
</script>
```

### GffViewer

To view your genes based on the GFF3 convention, you can use the GffViewer like this:

```vue
<GffViewer :data="GenesListe" :color-liste="colorService">
</GffViewer>
```

#### Props

- `data`: Array of GFF3 feature lines.

  - **Type**: `ExtendedGFF3FeatureLine[]`
  - **Description**: The array of GFF3 feature lines to be visualized. Each feature line should include an additional `place` attribute indicating its vertical position.

- `settings`: Configuration settings for the component.

  - **Type**: `ConfigI`
  - **Default**:

    ```typescript
    {
      width: 800,
      height: 300,
      marginRight: 20,
      marginLeft: 20,
      levels: 8
    }
    ```

  - **Description**: An object containing the width, height, marginRight, marginLeft, and levels for the component layout.

- `trackName`: Name of the track to display.

  - **Type**: `string`
  - **Description**: The name of the track to be displayed above the GFF viewer.

- `zoomZone`: Specific zone to zoom into.

  - **Type**: `DomainType` (`[number, number]`)
  - **Description**: The specific genomic positions to zoom into.

- `colorListe`: Service providing colors for different gene features.

  - **Type**: `ColorService`
  - **Description**: An instance of `ColorService` that provides colors for different features.

- `labelFunc`: Function to generate labels for genomic features.

  - **Type**: `(gene: Gff3Feature) => string`
  - **Default**:

    ```typescript
    ;(gene: Gff3Feature) => {
      return gene!.attributes!.ID[0] || ''
    }
    ```

  - **Description**: A function that takes a gene object and returns a string label for that gene.

#### Emits

- `updateDomain`: Emitted when the view domain changes.

  - **Payload**: `{ zone: [number, number]; id: number }`
  - **Description**: Contains the updated domain range and the ID of the component that triggered the update.

- `selectGene`: Emitted when a gene is selected.

  - **Payload**: `GFF3FeatureLine`
  - **Description**: Contains the selected gene feature.

- `featureHover`: Emitted when a gene is hovered over.
  - **Payload**: `GFF3FeatureLine|null`
  - **Description**: Contains the gene feature that is currently being hovered over.

#### Example Usage

```vue
<template>
  <GffViewer
    :data="GenesListe"
    :color-liste="colorService"
    :settings="viewerSettings"
    track-name="Genes"
  >
  </GffViewer>
</template>

<script setup>
import { GffViewer } from '@lipme/vuenomics-visualization-components'
import { ref } from 'vue'
import { ColorService } from '@lipme/gffcolors'

const GenesListe = ref([
  // Array of GFF3 feature lines
])

const viewerSettings = {
  width: 800,
  height: 300,
  marginRight: 20,
  marginLeft: 20,
  levels: 8
}

const colorService = new ColorService({
  // Color configuration
})
</script>
```

### CovViewer

The CovViewer component shows the coverage of BAM files.

```vue
<CovViewer
  :forward-coverage="covData"
  :reverse-coverage="reverseCovData"
  :settings="viewerSettings"
  :cov-colors="coverageColors"
  track-name="Coverage"
>
</CovViewer>
```

#### Props

- `forwardCoverage`: Array of coverage data for the forward strand.

  - **Type**: `CoverageType[]`
  - **Description**: The array of coverage data objects for the forward strand. Each object should contain `start`, `end`, and `score` properties.

- `reverseCoverage`: Array of coverage data for the reverse strand.

  - **Type**: `CoverageType[]`
  - **Description**: The array of coverage data objects for the reverse strand. Each object should contain `start`, `end`, and `score` properties.

- `settings`: Configuration settings for the component.

  - **Type**: `ConfigI`
  - **Default**:

    ```typescript
    {
      width: 800,
      height: 150,
      marginRight: 20,
      marginLeft: 20,
      levels: 10
    }
    ```

  - **Description**: An object containing the width, height, marginRight, marginLeft, and levels for the component layout.

- `covColors`: Colors for the coverage lines.

  - **Type**: `{ forward: string; reverse: string }`
  - **Description**: An object containing colors for the forward and reverse coverage lines.

- `trackName`: Name of the track to display.
  - **Type**: `string`
  - **Description**: The name of the track to be displayed above the coverage viewer.

#### Example Usage

```vue
<template>
  <CovViewer
    :forward-coverage="covData"
    :reverse-coverage="reverseCovData"
    :settings="viewerSettings"
    :cov-colors="coverageColors"
    track-name="Coverage"
  >
  </CovViewer>
</template>

<script setup>
import { CovViewer } from '@lipme/vuenomics-visualization-components'
import { ref } from 'vue'

const covData = ref([
  { start: 6260108, end: 6260152, score: 33 },
  { start: 6260152, end: 6260153, score: 32 },
  { start: 6260153, end: 6260155, score: 33 }
])

const reverseCovData = ref([
  { start: 6260108, end: 6260152, score: 30 },
  { start: 6260152, end: 6260153, score: 28 },
  { start: 6260153, end: 6260155, score: 29 }
])

const viewerSettings = {
  width: 800,
  height: 150,
  marginRight: 20,
  marginLeft: 20,
  levels: 10
}

const coverageColors = {
  forward: 'blue',
  reverse: 'red'
}
</script>
```

### BamViewer

The BamViewer component visualizes BAM file alignments.

```vue
<BamViewerCanvas
  :data="bamData"
  :alignment-colors="bamColors"
  :settings="viewerSettings"
  track-name="BamViewer"
  @updateDomain="handleDomainUpdate"
  @selectAlignement="handleAlignmentSelect"
/>
```

##### Props

- `data`: Object containing BAM alignments, indels, mismatches, and gaps.
  - **Type**: `{ bams: BamVisInterface[]; indels?: IndelInterface[]; mismatches?: IndelInterface[]; gaps?: IndelInterface[] }`
  - **Description**: The object containing BAM alignments and optional indels, mismatches, and gaps to be visualized.
- `settings`: Configuration settings for the component.

  - **Type**: `ConfigI`
  - **Default**:

    ```typescript
    {
      width: 800,
      height: 300,
      marginRight: 20,
      marginLeft: 20,
      levels: 8
    }
    ```

- `alignmentColors`: Colors for the BAM alignments.

  - **Type**: `{ alignments: string; inserts: string; dels: string; mismatches: string }`
  - **Default**:

    ```typescript
    {
      alignments: 'steelblue',
      inserts: 'silver',
      dels: 'black',
      mismatches: 'crimson'
    }
    ```

- `trackName`: Name of the track to display.
  - **Type**: `string`
  - **Description**: The name of the track to be displayed above the BAM viewer.
- `tooltip`: Function to generate tooltip content for alignments.
  - **Type**: `(alignement: BamVisInterface) => string`
  - **Default**: Shows alignment name and coordinates.

##### Events

- `updateDomain`: Emitted when the view domain changes (e.g., after zoom).
  - **Payload**: `{ zone: [number, number]; id: number }`
- `selectAlignement`: Emitted when an alignment is selected (clicked).
  - **Payload**: `BamVisInterface`
- `featureHover`: Emitted when an alignment is hovered.
  - **Payload**: `BamVisInterface|null`
  - **Description**: Contains the alignment that is currently being hovered over or null if no alignment is hovered.

##### Example Usage

```vue
<template>
  <BamViewerCanvas
    :data="bamData"
    :alignment-colors="bamColors"
    :settings="viewerSettings"
    track-name="BamViewer"
    @updateDomain="handleDomainUpdate"
    @selectAlignement="handleAlignmentSelect"
  />
</template>

<script setup>
import { BamViewerCanvas } from '@lipme/vuenomics-visualization-components'
import { ref } from 'vue'

const bamData = ref({
  bams: [
    // Array of BAM alignments
  ],
  indels: [
    // Array of indels
  ],
  mismatches: [
    // Array of mismatches
  ],
  gaps: [
    // Array of gaps
  ]
})

const viewerSettings = {
  width: 800,
  height: 300,
  marginRight: 20,
  marginLeft: 20,
  levels: 8
}

const bamColors = {
  alignments: 'steelblue',
  inserts: 'silver',
  dels: 'black',
  mismatches: 'crimson'
}

function handleDomainUpdate({ zone, id }) {
  // Handle domain update (e.g., fetch more data)
}

function handleAlignmentSelect(alignment) {
  console.log('Selected alignment:', alignment)
}
</script>
```

#### BamViewer (SVG)

For smaller datasets, you can use the SVG-based `BamViewer`:

```vue
<BamViewer :data="bamData" :colors="bamColors" :settings="viewerSettings" track-name="BamViewer">
</BamViewer>
```

### VcfViewer

The VcfViewer component visualizes VCF file variants.

```vue
<VcfViewer
  :data="vcfData"
  :settings="vcfViewerSettings"
  :vcf-colors="vcfColors"
  track-name="VCF Viewer"
>
</VcfViewer>
```

#### Props

- `data`: Array of VCF variants.
  - **Type**: `Array<Variant>`
  - **Description**: The array of variant objects to be visualized. Each variant object should follow the structure defined by the VCF format.
- `settings`: Configuration settings for the component.

  - **Type**: `ConfigI`
  - **Default**:

    ```typescript
    {
      width: 800,
      height: 300,
      marginRight: 20,
      marginLeft: 20,
      levels: 0
    }
    ```

  - **Description**: An object containing the width, height, marginRight, marginLeft, and levels for the component layout.

- `vcfSettings`: Specific settings for the VCF viewer.

  - **Type**: `VCFSettings`
  - **Default**:

    ```typescript
    {
      vcfHeight: 10,
      dataConcentration: 15,
      fontSize: 12,
      color: 'goldenrod',
      textColor: 'black',
      labelPosition: 20,
      vcfMinWidth: 2
    }
    ```

  - **Description**: An object containing settings specific to the VCF viewer, such as the height of the VCF bars, data concentration, font size, colors, and label position.

- `trackName`: Name of the track to display.

  - **Type**: `string`
  - **Description**: The name of the track to be displayed above the VCF viewer.

- `variantColors`: Colors for different types of variants.

  - **Type**: `{ snv: string; del: string; ins: string; unknown: string }`
  - **Description**: An object containing colors for different types of variants (e.g., snv, del, ins, unknown).

- `coloringStrategy`: Strategy for coloring variants.

  - **Type**: `ColoringStrategy|undefined`
  - **Description**: The strategy used to color the variants, the colors labels and matching value . **if not provided, the default coloring will be applied based on the `variantColors` prop.**. two strategier are provided by default:
    - `colorByThreshold`: Colors variants based on a threshold value.
    - `colorByValue`: Colors variants based on specific values in the variant data.

- `labelFunc`: Function to generate labels for variants.

  - **Type**: `(variant: ModifiedVariant) => string`
  - **Default**:

    ```typescript
    ;(variant: ModifiedVariant) => {
      if (variant.REF && variant.ALT && variant.op)
        return `${variant.op} ${variant.REF}->${variant.ALT?.join(', ')}`
      return ''
    }
    ```

  - **Description**: A function that takes a variant object and returns a string label for that variant.

#### Events

- `chosenVariant`: Emitted when a variant is selected.
  - **Payload**: `{ value: Variant }`
  - **Description**: Emitted when a variant is clicked, passing the selected variant object.

#### Example Usage

```vue
<template>
  <VcfViewer
    :data="vcfData"
    :settings="viewerSettings"
    :vcf-settings="vcfViewerSettings"
    :variant-colors="variantColors"
    track-name="VCF Viewer"
    @chosenVariant="handleVariantSelection"
  />
</template>

<script setup>
import { VcfViewer } from '@lipme/vuenomics-visualization-components'
import { ref } from 'vue'

const vcfData = ref([
  { POS: 100, REF: 'A', ALT: ['T'], QUAL: 50, FILTER: 'PASS' },
  { POS: 200, REF: 'G', ALT: ['C'], QUAL: 60, FILTER: 'PASS' }
])

const viewerSettings = {
  width: 800,
  height: 300,
  marginRight: 20,
  marginLeft: 20,
  levels: 0
}

const vcfViewerSettings = {
  vcfHeight: 10,
  dataConcentration: 15,
  fontSize: 12,
  color: 'goldenrod',
  textColor: 'black',
  labelPosition: 20,
  vcfMinWidth: 2
}

const variantColors = {
  snv: 'green',
  del: 'red',
  ins: 'blue',
  unknown: 'black'
}

function handleVariantSelection(variant) {
  console.log('Selected variant:', variant)
}
</script>
```

using the `coloringStrategy` prop, you can also apply different coloring strategies to the VCF viewer. Here is an example of how to use two different coloring strategies:

```vue
<template>
  <VcfViewer
    :data="vcfData"
    :settings="viewerSettings"
    :vcf-settings="vcfViewerSettings"
    :coloring-strategy="vcfColorREFThershold"
    track-name="VCF Viewer"
    @chosenVariant="handleVariantSelection"
  />
  <VcfViewer
    :data="vcfData"
    :settings="viewerSettings"
    :vcf-settings="vcfViewerSettings"
    :coloring-strategy="vcfColorREFbyValue"
    track-name="VCF Viewer"
    @chosenVariant="handleVariantSelection"
  />
</template>

<script setup>
import { colorByValue, colorByThreshold } from '@lipme/vuenomics-visualization-components/utils'
import { VcfViewer } from '@lipme/vuenomics-visualization-components'
import { ref, reactive } from 'vue'

const vcfData = ref([
  { POS: 100, REF: 'A', ALT: ['T'], QUAL: 50, FILTER: 'PASS' },
  { POS: 200, REF: 'G', ALT: ['C'], QUAL: 60, FILTER: 'PASS' }
])

const viewerSettings = {
  width: 800,
  height: 300,
  marginRight: 20,
  marginLeft: 20,
  levels: 0
}

const vcfViewerSettings = {
  vcfHeight: 10,
  dataConcentration: 15,
  fontSize: 12,
  color: 'goldenrod',
  textColor: 'black',
  labelPosition: 20,
  vcfMinWidth: 2
}

const vcfColorREFThershold = reactive({
  colorInfo: { HET: 'green', HOM: 'blue', NC: 'black', WT: 'red' },
  strategy: colorByThreshold
})
const vcfColorREFbyValue = reactive({
  colorInfo: {
    moderate: { regex: '|moderate|', color: 'purple' },
    low: { regex: '|low|', color: 'fuschia' },
    high: { regex: '|high|', color: 'crimson' }
  },
  field: 'ANN',
  strategy: colorByValue
})

function handleVariantSelection(variant) {
  console.log('Selected variant:', variant)
}
</script>
```

---

### VcfMatrixViewer

The `VcfMatrixViewer` component visualizes VCF variants as a matrix, showing genotypes for multiple samples.

```vue
<VcfMatrixViewer
  :data="vcfData"
  :samples-name="samplesName"
  :settings="matrixSettings"
  :colors="matrixColors"
  track-name="VCF Matrix"
  @chosenVariant="handleVariantSelection"
/>
```

#### Props

- `data`: Array of VCF variants.

  - **Type**: `Array<Variant>`
  - **Description**: The array of variant objects to be visualized.

- `samplesName`: List of sample names to display as matrix rows.

  - **Type**: `string[]`
  - **Description**: The names of the samples for which genotypes are shown.

- `settings`: Configuration settings for the component.

  - **Type**: `ConfigI`
  - **Default**:

    ```typescript
    {
      width: 800,
      height: 300,
      marginRight: 20,
      marginLeft: 20,

    }
    ```

- `vcfSettings`: Specific settings for the VCF matrix viewer.

  - **Type**: `VCFSettings`
  - **Default**:

    ```typescript
    {
      vcfHeight: 20,
      dataConcentration: 30,
      fontSize: 12,
      color: 'goldenrod',
      textColor: 'black',
      labelPosition: 20,
      vcfMinWidth: 2
    }
    ```

- `colors`: Colors for different genotype states.

  - **Type**: `{
  '0/0': string;,
  './.': string,
  '1/1': string,
  '0/1': string,
  unknown: 'black'
}`
  - **Description**: An object mapping genotype states to colors.

- `trackName`: Name of the track to display.

  - **Type**: `string`
  - **Description**: The name of the track to be displayed above the matrix viewer.

- `labelFunc`: Function to generate labels for variants.

  - **Type**: `(variant: ModifiedVariant) => string`
  - **Default**:

    ```typescript
    ;(variant: ModifiedVariant) => {
      if (variant.REF && variant.ALT && variant.op)
        return `${variant.op} ${variant.REF}->${variant.ALT?.join(', ')}`
      return ''
    }
    ```

#### Events

- `chosenVariant`: Emitted when a variant is selected.
  - **Payload**: `{ value: Variant }`
  - **Description**: Emitted when a variant is clicked, passing the selected variant object.
- `featureHover`: Emitted when an Variant is hovered.
  - **Payload**: `variant|null`
  - **Description**: Contains the Variant that is currently being hovered over or null if no alignment is hovered.

#### Example Usage

```vue
<template>
  <VcfMatrixViewer
    :data="vcfData"
    :samples-name="samplesName"
    :settings="matrixSettings"
    :colors="matrixColors"
    track-name="VCF Matrix"
    @chosenVariant="handleVariantSelection"
  />
</template>

<script setup>
import { VcfMatrixViewer } from '@lipme/vuenomics-visualization-components'
import { ref } from 'vue'

const vcfData = ref([
  // Array of VCF variant objects
])

const samplesName = ['Sample1', 'Sample2', 'Sample3']

const matrixSettings = {
  width: 800,
  height: 300,
  marginRight: 20,
  marginLeft: 20,
  levels: 0
}

const matrixColors = {
  '0/0': 'orange',
  './.': 'red',
  '1/1': 'indigo',
  '0/1': 'green',
  unknown: 'black'
}

function handleVariantSelection(variant) {
  console.log('Selected variant:', variant)
}
</script>
```

### FastaViewer

The FastaViewer component visualizes DNA sequences from FASTA files.

```vue
<FastaViewer
  :data="fastaData"
  :settings="viewerSettings"
  :fasta-settings="fastaSettings"
  :nucleotide-colors="nucleotideColors"
  track-name="Fasta Viewer"
>
</FastaViewer>
```

#### Props

- `data`: String representing the DNA sequence.

  - **Type**: `string`
  - **Description**: The DNA sequence to be visualized.

- `settings`: Configuration settings for the component.

  - **Type**: `ConfigI`
  - **Default**:

    ```typescript
    {
      width: 800,
      height: 300,
      marginRight: 20,
      marginLeft: 20,
      levels: 0
    }
    ```

  - **Description**: An object containing the width, height, marginRight, marginLeft, and levels for the component layout.

- `fastaSettings`: Specific settings for the FASTA viewer.

  - **Type**: `FastaSettings`
  - **Default**:

    ```typescript
    {
      startPosition: 1,
      maxSize: 1000
    }
    ```

  - **Description**: An object containing settings specific to the FASTA viewer, such as the start position and maximum size of the sequence to be displayed.

- `nucleotideColors`: Colors for each nucleotide.

  - **Type**: `{ A: string; T: string; C: string; G: string; N: string }`
  - **Description**: An object containing colors for each nucleotide (A, T, C, G, N).

- `trackName`: Name of the track to display.
  - **Type**: `string`
  - **Description**: The name of the track to be displayed above the FASTA viewer.

#### Example Usage

```vue
<template>
  <xAxis :domain="[regionStart, regionEnd]">
    <FastaViewer
      :data="fastaData"
      :settings="viewerSettings"
      :fasta-settings="fastaSettings"
      :nucleotide-colors="nucleotideColors"
      track-name="Fasta Viewer"
    >
    </FastaViewer>
  </xAxis>
</template>

<script setup>
import { FastaViewer } from '@lipme/vuenomics-visualization-components'
import { ref } from 'vue'

const fastaData = ref('ATCGATCGATCG')

const viewerSettings = {
  width: 800,
  height: 300,
  marginRight: 20,
  marginLeft: 20,
  levels: 0
}

const fastaSettings = {
  startPosition: 1,
  maxSize: 1000
}

const nucleotideColors = {
  A: 'red',
  T: 'blue',
  C: 'green',
  G: 'yellow',
  N: 'white'
}
</script>
```

### Bed Viewer

The BedViewer component visualizes BED file regions, allowing you to display genomic intervals, scores, and strand information interactively.

#### Props

- `data`: Array of BED features.

  - **Type**:

    ```typescript
    Array<{
      chromStart: number
      chromEnd: number
      name: string
      strand: number // 1 for '+', -1 for '-', 0 or undefined for unknown
      score?: number
      place: number // vertical stacking index
    }>
    ```

  - **Description**: The BED features to display. Each feature should include `chromStart`, `chromEnd`, `name`, `strand`, and `place`. `score` is optional and used for color scaling.

- `bedSettings`: Configuration for the BED track.

  - **Type**:

    ```typescript
    {
      maxScore: number
      minScore?: number
      textColor: string
      fontSize: number
      labelPosition: number
      minWidth: number
      bedHeight: number
    }
    ```

  - **Description**: Controls the appearance of the BED track, including score range, text color, font size, label position, minimum width, and feature height.

- `settings`: General layout settings (optional).

  - **Type**: `ConfigI`
  - **Default**:

    ```typescript
    {
      width: 800,
      height: 300,
      marginRight: 20,
      marginLeft: 20,
      levels: 0
    }
    ```

- `trackName`: Name of the track to display (optional).

  - **Type**: `string`
  - **Description**: The name of the track to be displayed above the BED viewer.

- `scoreColors`: Colors for the score gradient (optional).

  - **Type**: `[string, string]`
  - **Default**: `['blue', 'yellow']`
  - **Description**: Used to color features by their score (low to high).

- `strandColors`: Colors for strand direction (optional).

  - **Type**: `{ '+': string; '-': string; unknown: string }`
  - **Default**: `{ '+': 'green', '-': 'red', unknown: 'gray' }`
  - **Description**: Used to color features by strand if no score is provided.

- `labelFunc`: Function to generate labels for features (optional).
  - **Type**: `(feature) => string`
  - **Default**: `feature.name || ' unknown'`
  - **Description**: Customizes the label shown for each feature.

#### Events

- `chosenFeature`: Emitted when a feature is clicked.

  - **Payload**: `feature`
  - **Description**: The selected BED feature.

- `featureHover`: Emitted when a feature is hovered.
  - **Payload**: `feature | null`
  - **Description**: The feature being hovered, or null if none.

#### Functionality

- **Score-based coloring**: If `score` is provided, features are colored using a linear gradient between `scoreColors[0]` (low) and `scoreColors[1]` (high).
- **Strand arrows**: Features with strand information display an arrow at the start or end, colored by `strandColors`.
- **Zoom and pan**: Fully integrated with the axis zoom/pan system.
- **Labels**: Feature labels are customizable and positioned according to `labelPosition` and `fontSize`.
- **Responsive**: Respects the `settings` prop for width, height, and margins.

#### Example Usage

```vue
<template>
  <XAxis :domain="[6400000, 6500000]">
    <BedViewer
      :data="[
        {
          chromStart: 6400000,
          chromEnd: 6500000,
          name: 'Example Bed Feature',
          strand: -1,
          score: 30,
          place: 0
        },
        {
          chromStart: 6405000,
          chromEnd: 6410000,
          name: 'Another Feature',
          strand: 1,
          score: 80,
          place: 1
        }
      ]"
      :bed-settings="{
        maxScore: 100,
        textColor: 'black',
        fontSize: 12,
        labelPosition: 20,
        minWidth: 2,
        bedHeight: 10
      }"
      :track-name="'Bed Viewer'"
      @feature-hover="(feature) => console.log('hovered variant', feature)"
      @chosen-feature="(feature) => console.log('chosen feature', feature)"
    />
  </XAxis>
</template>
```

**Tip:** You can use the `labelFunc` prop to customize the label for each feature, for example to show both name and score:

```vue
<BedViewer
  :data="bedData"
  :bed-settings="bedSettings"
  :label-func="(feature) => `${feature.name} (${feature.score})`"
/>
```

**Integration:** BedViewer is designed to work seamlessly with the axis and other tracks. Ensure that the `settings` prop (width, margins) matches across all tracks for proper alignment.

## Conclusion

The Vuenomics Visualization Components library provides powerful tools for visualizing genomic data in a reactive and interactive way. Each component is designed to handle specific types of genomic data, offering advanced features such as zooming, panning, and interactive selection. By integrating these components into your Vue application, you can create rich and dynamic genomic data visualizations.