npm package: @lipme/vue-iprscan-gff3-svg
Description: A Vue 3 component and CLI to display InterProScan GFF3 files as SVG
Latest version: 1.0.2

# vue-iprscan-gff3-svg

Vue 3 component and CLI tooling to visualize InterProScan GFF3 `protein_match` annotations as an SVG domain map.

## What this project provides

- **Interactive Vue component** for browser display with hover tooltips and amino-acid ruler.
- **Reusable core renderer** to parse GFF3 and build a shared display model.
- **CLI generator** to produce static SVG from GFF3 files.
- **Packaged native binary build** target for `node18-linux-x64`.

## Features

- Parses GFF3 rows and attributes (`Name`, `signature_desc`, etc.).
- Displays `polypeptide` baseline and grouped `protein_match` domains.
- Automatically packs overlapping domains in lanes per source.
- Normalizes all SignalP source variants to a single `SignalP` group.
- Supports default source colors with optional per-source overrides.
- Static SVG output includes in-rectangle domain labels using complementary text color.

## Requirements

- Node.js + npm
- Linux, macOS, or Windows for development scripts

## Install

```bash
npm install
```

## Development and build commands

```bash
npm run dev
npm run test -- --run
npm run build
npm run build:cli
npm run build:all
```

### Script reference

- `npm run dev`: Start Vite dev server.
- `npm run test -- --run`: Run Vitest once.
- `npm run build`: Build Vue app (`dist/` web assets).
- `npm run build:cli`: Build JS CLI artifact at `dist/iprscan-gff3-svg.js`.
- `npm run build:all`: Run web build + CLI build.
- `npm run package:cli`: Build packaged binary `dist/iprscan-gff3-svg-node18-linux-x64`.

## Vue component usage

Component: `src/components/IprscanGff3Display.vue`

### Props

- `gff3Data: string` (required): Raw GFF3 content.
- `sourceColors?: Record<string, string>` (optional): Per-source color overrides.

### Basic example

```vue
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import IprscanGff3Display from './components/IprscanGff3Display.vue'

const gff3Data = ref('')

onMounted(async () => {
  const response = await fetch('/ATHTS1_Chr4g041860.gff3')
  gff3Data.value = await response.text()
})
</script>

<template>
  <IprscanGff3Display :gff3Data="gff3Data" />
</template>
```

### With custom source colors

```vue
<IprscanGff3Display
  :gff3Data="gff3Data"
  :sourceColors="{
    Pfam: '#1f77b4',
    SMART: '#d62728',
    SignalP: '#2ca02c'
  }"
/>
```

### Automatic xref links

The Vue component automatically loads `src/conf/Xrefs.json` to generate clickable links on domains.  
When a domain's `Name` attribute matches a database entry in the xref configuration, the domain becomes a clickable link that opens the corresponding database record in a new tab.

Example: A `Pfam` domain with Name `PF05903` will link to the Pfam database record for that domain.

**Note:** Links are only generated if:
- The GFF3 file includes the `Name` attribute for the domain
- The source database (Pfam, SMART, CDD, etc.) has an entry in `Xrefs.json`
- The entry includes a `url_syntax` template

## CLI usage

CLI entry: `src/cli.ts`

### Help

```bash
node dist/iprscan-gff3-svg.js --help
```

### Generate SVG (flags)

```bash
node dist/iprscan-gff3-svg.js --gff3 data/ATHTS1_Chr4g041860.gff3 --svg output.svg
```

### SVG output example

After running the CLI, you can open `output.svg` directly in a browser.

Example preview file in this repo:

![Example static SVG output](output.svg)

Example SVG fragment:

```xml
<svg width="800" height="200" xmlns="http://www.w3.org/2000/svg">
  <text x="160" y="30" class="title">ATHTS1_Chr4g041860 (255 aa)</text>
  <line x1="160" y1="50" x2="750" y2="50" stroke="black" stroke-width="2" />
  <rect x="166.94" y="73" width="349.37" height="14" fill="#469990" rx="5" ry="5" />
  <text x="170.94" y="83" class="domain-label" fill="#B9666F">PF05903: PPPDE putative peptidase…</text>
</svg>
```

### Generate SVG (positional args)

```bash
node dist/iprscan-gff3-svg.js data/ATHTS1_Chr4g041860.gff3 output.svg
```

### Defaults

If not provided, CLI defaults to:

- `--gff3 data/ATHTS1_Chr4g041860.gff3`
- `--svg output.svg`

## Packaged binary (real executable)

Build binary:

```bash
npm run package:cli
```

Run binary:

```bash
./dist/iprscan-gff3-svg-node18-linux-x64 --gff3 data/ATHTS1_Chr4g041860.gff3 --svg output.svg
```

Target configured:

- `node18-linux-x64`

## Library API (shared core)

Main utility module: `src/gff3-display.ts`

- `parseGff3Data(gff3Data: string): GFF3Row[]`
- `buildDisplayModel(rows: GFF3Row[], sourceColorOverrides?): DisplayModel`
- `renderStaticSvg(displayModel: DisplayModel): string`
- `makeTickAAs(totalLength: number, step = 50): number[]`

Programmatic SVG generator: `src/index.ts`

- `generateStaticSvg(gff3Data: string, sourceColors?: Record<string, string>): string`

## Project structure

```text
src/
  cli.ts                     # CLI interface
  index.ts                   # Programmatic entrypoint
  gff3-display.ts            # Shared parser/layout/static SVG renderer
  conf/
    Xrefs.json               # Database cross-reference URL templates for clickable links
  components/
    IprscanGff3Display.vue   # Interactive Vue SVG component
scripts/
  build-cli.mjs              # Cross-platform CLI JS build script
  package-cli.mjs            # Native binary packaging script (pkg)
```

## Notes

- The web component and CLI share the same parsing/layout core, so output stays consistent.
- Static SVG output is intentionally non-interactive (no browser tooltip behavior).