Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ to install dependencies and start the local development server.

Tests run under [Vitest](https://vitest.dev/) with a `jsdom` DOM environment. All APIs (`describe`, `it`, `expect`, `vi`, …) must be imported explicitly from `'vitest'` — `globals` is off.

A small setup file at `src/__spec__/setup.ts` filters out jsdom's benign "Could not parse CSS stylesheet" warnings; jsdom's CSS parser is CSS2-era and chokes on the nested-selector syntax used in `src/protvista-styles.ts`. The stylesheet still attaches correctly — it's log noise only. Every other `console.error` passes through untouched. Remove the filter if we ever migrate to happy-dom (which parses modern CSS natively) or jsdom gains native-nesting support.

```bash
# Run the full pipeline (lint + types + unit)
yarn test
Expand All @@ -117,20 +119,20 @@ Every push and pull request runs the same three steps as `yarn test` via [`.gith

Captured 2026-04-20 via `yarn test:coverage` (v8 instrumentation, 29 tests across 3 spec files):

| Metric | Coverage |
| ---------- | -------- |
| Statements | 10.33% |
| Branches | 5.99% |
| Functions | 13.19% |
| Lines | 9.66% |
| Metric | Coverage % |
| ---------- | ---------- |
| Statements | 71.41 |
| Branches | 70.77 |
| Functions | 68.63 |
| Lines | 71.78 |

## Configuration

You can pass your own configuration to the component using the `config` attribute/property.

```json
{
"categories": [
"groups": [
{
"name": "string",
"label": "string",
Expand Down
6 changes: 3 additions & 3 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Year 1 is fully funded by the SSI RSMF grant. Every milestone below maps directl

- Conduct a thorough code audit to identify hardcoded assumptions, obsolete code, and legacy browser workarounds that can be removed.
- Conduct a security audit to determine if any NPM package dependencies have known security vulnerabilities.
- Begin refactoring ProtVista's data-loading layer to accept user-supplied data via a documented configuration model, decoupling the tool from EBI-specific API endpoints. As part of this work, define the first version of the viewer configuration schema covering categories, tracks, data sources, and rendering options.
- Begin refactoring ProtVista's data-loading layer to accept user-supplied data via a documented configuration model, decoupling the tool from EBI-specific API endpoints. As part of this work, define the first version of the viewer configuration schema covering groups, tracks, data sources, and rendering options.
- Explicitly separate the architectural contracts for (a) viewer configuration and (b) track payloads/data.
- Implement Canvas and/or WebGL-based rendering for improved performance, targeting smooth interaction with dense annotation sets on resource-limited hardware. _Note: rendering is handled by the upstream @nightingale-elements packages and will require coordinated changes in addition to this project._
- Establish a testing baseline for the main component, which currently has minimal coverage (one adapter test file and a filter-config test file). Record a baseline snapshot: number of unit tests, statement coverage percentage for key modules, and CI pass/fail status. Set up the testing infrastructure so that tests are written alongside each refactoring task from Q1 onwards, rather than retrofitted later. This directly supports our CI/CD goals: external contributors need a passing test suite to verify their changes against.
Expand All @@ -54,7 +54,7 @@ Year 1 is fully funded by the SSI RSMF grant. Every milestone below maps directl

**Architecture and usability**

- Complete the configurable data-loading framework: ProtVista should mount tracks dynamically based on a user-provided configuration file rather than hardcoded category lists. Publish a formal viewer configuration schema (JSON Schema) defining the supported structure of categories, tracks, data sources, and rendering options, so that users and integrators can validate configuration files before use. In parallel, document the expected payload shapes for the initial built-in track types and adapters. The objective is to support the track and feature elements currently supported by ProtVista (i.e. not additional elements).
- Complete the configurable data-loading framework: ProtVista should mount tracks dynamically based on a user-provided configuration file rather than hardcoded group lists. Publish a formal viewer configuration schema (JSON Schema) defining the supported structure of groups, tracks, data sources, and rendering options, so that users and integrators can validate configuration files before use. In parallel, document the expected payload shapes for the initial built-in track types and adapters. The objective is to support the track and feature elements currently supported by ProtVista (i.e. not additional elements).
- The configuration JSON schema should handle the majority of standard visualisation needs, while exposing a modular API (escape hatches) that allows advanced users to inject custom logic for their specific edge cases.
- Modernise the styling architecture, using native web standards like CSS ::part and custom properties, to reduce technical debt and allow library users to customise the interface.
- Implement track-configuration UI features (reordering, selective toggling) so that non-technical users can customise the display without editing code.
Expand Down Expand Up @@ -159,7 +159,7 @@ Year 3 is intended to deepen ProtVista’s interoperability with the MSS ecosyst

## 1\. Architectural Sustainability (Reducing Technical Debt)

The core Year 1 deliverable is transforming ProtVista from a tightly coupled, EBI-specific tool into a data-agnostic, configuration-driven component. By replacing hardcoded API endpoints and category lists with a documented JSON schema, we drastically lower the barrier for external labs and industry partners to adapt ProtVista for their own data. Every new adopter becomes a potential contributor and stakeholder, naturally scaling the pool of people invested in the tool's maintenance.
The core Year 1 deliverable is transforming ProtVista from a tightly coupled, EBI-specific tool into a data-agnostic, configuration-driven component. By replacing hardcoded API endpoints and group lists with a documented JSON schema, we drastically lower the barrier for external labs and industry partners to adapt ProtVista for their own data. Every new adopter becomes a potential contributor and stakeholder, naturally scaling the pool of people invested in the tool's maintenance.

Furthermore, the configuration-first, modular architecture will be highly compatible with emerging AI coding tools. By defining clear boundaries and machine-readable JSON schemas, we ensure that post-grant maintenance, bug fixes, and the development of custom tracks can be achieved with significantly reduced developer overhead.

Expand Down
70 changes: 70 additions & 0 deletions docs/data-tooltip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Authoring `dataTooltip`

`dataTooltip` controls the per-datapoint tooltip shown when a user clicks a feature on a track. It has three authoring forms, listed here from least to most expressive. Pick the simplest one that works — the rendering pipeline is the same for all three.

For the underlying semantics (security model, field-escape rules, URL-scheme allowlist, fallback behaviour when a track has no `dataTooltip` at all), see the "Tooltips" section in `specs/config-approach.md`.

## Bare-string form

A one-line Markdoc template. The YAML value is a string, so no quoting with nested maps needed. Shorthand for `{ kind: markdown, template: "…" }`. Fields on the datapoint are in scope as `$field`.

```yaml
tracks:
- id: signal
label: Signal peptide
kind: features
filter: SIGNAL
data: features
dataTooltip: '**Signal peptide** {% $begin %}–{% $end %}'
```

## `kind: fields` form

A declarative list of labelled rows. Each entry renders as `<h5>label</h5><p>value</p>`. Use this when the tooltip is a flat property sheet without prose or conditional content.

`path` is a dotted path against the item (e.g. `association.0.name`). Missing or empty values drop out silently rather than rendering an empty row. An optional `render:` opts a row into the `tooltipHelpers` registry — use it for xref badges, evidence icons, and similar small helpers the library already knows how to draw.

```yaml
tracks:
- id: compbias
label: Compositional bias
kind: features
filter: COMPBIAS
data: features
dataTooltip:
kind: fields
fields:
- { path: type, label: Type }
- { path: description, label: Description }
- { path: begin, label: Start }
- { path: end, label: End }
```

## `kind: markdown` form

A full Markdoc template. Use this when the tooltip needs prose, conditional fragments, or built-in tags. Field interpolation uses `{% $field %}`; flow control uses Markdoc's `{% if %}` / `{% else %}` / `{% /if %}`.

Three built-in tags ship with the viewer:

- `{% xrefs xrefs=$field /%}` — renders a cross-reference list from an `xrefs` array.
- `{% evidence codes=$field /%}` — renders an ECO evidence list from an `evidences` array.
- `{% link source=… id=… label=… /%}` — renders an anchor resolved through the library's URL-template registry. Use this instead of a raw Markdown link when the target URL is a template keyed by source name.

```yaml
tracks:
- id: domain
label: Domain
kind: features
filter: DOMAIN
data: features
dataTooltip:
kind: markdown
template: |
### {% $description %}
**Position:** {% $begin %}–{% $end %}
{% if $evidences %}{% evidence codes=$evidences /%}{% /if %}
```

## When to leave `dataTooltip` off

For every track in the default config, no `dataTooltip` is set. Each semantic `kind` carries a sensible tooltip default — authors who just want the canonical UniProt look get it for free. Only set `dataTooltip` when you want a track-specific override, or when you're authoring a track that doesn't match an existing kind's default.
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

<body>
<div>
<!-- NOTE: for all of the following with no config-src → falls back to bundled src/default-config.yaml -->
<!-- Good default -->
<protvista-uniprot accession="P05067"></protvista-uniprot>
<!-- Good multimer -->
Expand Down
Loading
Loading