Custom artefact displays
The GUI asks the imported artefact instance for display(context). Rendering
does not depend on the class name. An artefact package on Python’s import path
can reuse a built-in view or supply its own JavaScript renderer, without changing
Collectra’s GUI or copying files into its installation.
Reusing built-in views
Return a JSON-compatible dictionary from display(context):
{"kind": "text", "format": "plain", "text": "...", "editable": False}shows text. Formatsmarkdownandxmlare also supported. Seteditableonly when the artefact supports the text update API.context.image(self)renders anImagesubclass, with zooming, rotation, child crop boxes and child segmentation masks.{"kind": "properties", "data": {...}}shows structured properties. This is the default forArtefact.
ImageCrop and ImageSegmentation inherit the image view and render their
own cropped or masked image. Link delegates to its target’s display.
Providing a renderer
For example, place these files in an importable my_artefacts package.
measurement.py:
from dataclasses import dataclass
from pathlib import Path
from collectra.types.base import Artefact
@dataclass
class Measurement(Artefact):
value: float = 0
def __call__(self):
return self.value
def display(self, context):
return {
"kind": "measurement",
"value": self.value,
"renderer": context.renderer(
Path(__file__).with_name("measurement.js")
),
}
measurement.js:
export default function render({element, view, identity, api, signal}) {
const label = document.createElement('p');
label.textContent = `${identity.id}: ${view.value}`;
element.appendChild(label);
// Return cleanup for subscriptions, timers, charts, etc.
return () => label.remove();
}
Reference the class in results as my_artefacts.measurement.Measurement.
Include the JavaScript file as package data when distributing your package.
context.renderer reads that local file and publishes it as an ES module;
it does not require an HTTP server or a browser-accessible filesystem path.
The module must be self-contained: bundle dependencies into it rather than
using relative imports. Use context.publish_image(pil_image) to include
image data in the view, and context.path(value) to resolve result-relative
paths on the Python side.
Renderer contract
The module exports a default function receiving:
element: a dedicated DOM container for this rendering. Only modify this container; several panels may display artefacts at the same time.view: the dictionary returned by Python, withtarget_iddefaulting to the displayed artefact ID.identity: the displayed artefact’sidand Pythontype.api: the GUI’swindow.pywebview.apibridge.signal: anAbortSignalaborted when the display is cleared, the tab changes, or the panel is closed. Check it after asynchronous work.
The function may be asynchronous and may return a synchronous cleanup function. Cleanup runs once on leaving the display, including when navigation happens before asynchronous rendering completes. Each rendering has its own container, so late work cannot replace the next artefact’s content. Modules are imported once per source; keep per-panel state inside the render function, not at module scope. Errors appear in the panel using the GUI’s normal display error handling.
Renderer code runs with the same GUI access as Collectra’s built-in code; it is code supplied by the installed artefact package.
Built-in implementation
collectra/gui/artefactDisplay.js dispatches views and manages custom module
loading and cleanup. Built-in implementations live in collectra/gui/displays:
image.js: image viewer, zoom, rotation, annotation lifecycle.imageCrop.js: crop geometry and drawing controls.imageSegmentation.js: coloured instance mask overlays.imageInteractions.js: shared child hit testing and double-click navigation.segmentationEditor.jsandsegmentationEditor.css: dimmed context, circular mask brushes and autosave.text.js: plain text, Markdown and XML editors, toolbar and autosave.properties.js: structured property display.
index.html owns the panel layout and calls these renderers. It does not need
to know about an extension’s artefact type or view kind.
Python’s shared DisplayContext delegates built-in descriptor construction
to collectra/displays/images.py and collectra/displays/texts.py. The
context’s public methods remain available to custom artefact types.
collectra/displays/image_segmentation.py supplies mask-editing descriptors;
collectra/gui/segmentation.py validates strokes and writes binary masks
atomically.