Changelog¶
All notable changes to OntoInk are documented here. This project follows Semantic Versioning.
View all releases on PyPI View all tags on GitHub
[0.7.7] — 2026-08-11¶
Added — SHACL shape recommendation¶
- OntoInk can now propose the shapes you haven't written.
recommend_shapes: trueon a fence adds a Shapes panel listing ash:NodeShapefor every class with no coverage, each constraint shown with the evidence behind it, plus Copy and Add to editor buttons. It runs at build time, so it works on GitHub Pages. - Two induction methods, folded in from a benchmark of eight:
baselineprofiles instance data (Mihindukulasooriya et al. 2018),astreaderives constraints from OWL axioms alone — the only one that says anything about a documentation ontology that ships no individuals.autoruns both and merges them, recording which method proposed each constraint. The other six either over-predicted, produced output identical to the baseline on real ontologies, or were never fully implemented. - Confidence survives serialisation. Emitted shapes carry
sh:descriptionplusoi:confidence/oi:support/oi:population/oi:method. They are annotations, so the file still validates withpyshaclunchanged. - Right-click a class → Induce shape from this class. Proposals appear as dashed edges whose opacity is mapped from their confidence, with a trust slider that fades out the weakly-evidenced ones. Clicking a ghost edge accepts it: it becomes a real constraint edge and its Turtle lands in the Edit & Validate buffer, where Validate is one click away.
- The
no-shacl-coveragesmell now generates the shape it asks for — a ready-to-paste skeleton per uncovered class, with a copy button, instead of prose pointing at another tool. - New
POST /recommend-shapesendpoint in the API mode, so the fence, the SHACL editor and the graph context menu all run one implementation.
Added — closing the loop back into CI¶
shape_drift: warncompares committed shapes against what the data implies today: constraints the data supports that the file omits, committed constraints almost nothing satisfies (with a concrete relaxation), and classes with no shape. Findings go through the MkDocs logger, somkdocs build --strictfails the build.- Competency questions are executable. A new
ontoink-cqfence pairs each question with SPARQL and an expectation and renders pass/fail cards with the query and bindings;reasoning: truemerges inferred triples first, so a question can assert what the ontology entails. Show on graph selects a question's bound terms on the nearest diagram, without needing to know its id. ontoink-report.jsonand README badges are written on every build — SHACL conformance, the OntoSniff score, consistency, drift and CQ results in one machine-readable artefact. Badges are rendered locally, with no request to an external badge service. Aquality_gate:config block fails the build on score regressions, new violations, inconsistency or drift.
Added — trust and provenance¶
- "Explain this inference." Right-click an inferred edge for a proof tree: which OWL-RL rule fired, on which premises, down to asserted facts. Only the in-page reasoner can do this — Konclude, HermiT and the server backends return proof-free triples, and the panel says so rather than inventing a derivation.
- Cite this ontology — license badge, version, creators and a generated BibTeX block read from the
owl:Ontologyheader. - Deprecated terms read as retired (dimmed, dashed border) and the deprecation smell now names the successor declared via IAO:0100001 or
dcterms:isReplacedBy. - Findings are actionable: quality-smell chips and competency-question results can select their terms on the canvas, revealing anything the current LOD level had hidden.
Fixed¶
- Literal node ids are stable across builds. They were
abs(hash(str)) % 999999, and Python salts string hashing per process, so the same literal got a new id on every build. - Build-time SHACL validation failures are no longer silent. A bare
exceptturned a broken or missing shapes file into an unvalidated diagram with nothing in the build log. /reason's reasoner override no longer mutates the environment, which two concurrent requests could race on.- Build-time and server validation agreed to disagree —
noneversusrdfsinference, so the same file could conform on the page and fail in CI. Both now share one default, withvalidation_inference:to opt in. - The
predicates:policy is reachable at last —hide_predicates/fold_into_badge/badge_predicateshave been implemented since 0.7.0 but nothing ever passed them from the fence YAML. - Style presets are matched case-insensitively, so choosing "Style: Ontoink" after another preset restores the default instead of warning about an unknown preset.
- One version, everywhere.
pyproject.tomlreads it fromontoink/__init__.py, the API reports it instead of a hard-coded0.7.2, and the page exposeswindow.ONTOINK_VERSIONin place of a header comment that had been stale since 0.7.4. - The wheel shipped the entire repository —
tests/,scripts/, the shape-recommender research project and the paper draft were all installed as top-level packages, because package discovery defaulted to namespace mode. - Three buttons were silently dead. The no-eval attribute shim understood strings and numbers but not lists, and split argument lists at commas inside brackets — so any button passing a set of IRIs was mangled before it ran. That covered "Show class", the select action on OntoSniff chips, and "Show on graph" on competency-question results. Lists now parse, and a new test runs the real shim under Node against every call shape the plugin emits.
- An apostrophe in a label broke its button — Alzheimer's disease closed the single-quoted attribute argument early.
- The axiom-driven method found nothing on an ontology with no instances — the one case it exists for. It discovered properties by looking at which ones were used in the data; in a documentation ontology a property appears as the subject of
rdfs:domainand is never used, so the whole domain/range branch silently produced nothing. None of the five research benchmarks could catch this, because every one of them ships instance data that exercises its properties. automode threw away evidence it had already found: when both induction methods derived the same constraint, the axiom-derived one won and its empty instance counts were what got serialised. Colliding derivations now merge.
[0.7.6] — 2026-08-06¶
Fixed — rendering and export resolution¶
- Diagrams rendered at half resolution on HiDPI screens.
pixelRatio: 1arrived in 0.7.4 as a large-ontology optimization but was applied to every graph, pinning the canvas to one device pixel per CSS pixel — on a retina or 4K display the whole diagram was drawn at half the available resolution. The ratio now follows the display (capped at 2) and drops to 1 only for graphs of 500+ nodes; the motion optimizations became conditional for the same reason.pixel_ratio: Nin the fence YAML overrides the choice either way. - PNG exports are sized for print. The fixed
scale: 2meant a compact diagram exported at ~1400 px on its long edge; the scale is now derived so the result lands near 3000 px, clamped to the browser's canvas limits.ontoink.exportPNG(id, 4)still forces an explicit scale.
Changed — documentation¶
- The site is branded OntoInk (the package, module and fence name stay
ontoink), the navigation collapsed from thirteen tabs to five, and the tab bar stays visible while scrolling. - The landing page leads with the live diagram rather than prose; new Architecture and Docker & self-hosting pages carry the material that used to sit in the README.
[0.7.5] — 2026-08-06¶
Added — Size & Typography in Edit Layout¶
- Edit Layout can now change how big the shapes are and which font they use. A master Scale slider (40–300 %) moves shape size, node labels and edge labels together; below it sit explicit px boxes for each, a font family picker (Inter, Helvetica/Arial, Verdana, Georgia, Times, Mono), a weight picker and an italic toggle. Each node-type row also gained per-type size and font boxes that override the global values.
- Size is expressed as padding around the label rather than a fixed width/height, because every OntoInk stylesheet sizes nodes with
width/height: "label"— so shapes grow with the scale and labels never clip. - Typography values live in element data and are read through function mappers installed on every stylesheet — the fence, the playground, the live editor and all four style presets — so the settings survive layout changes, LOD sweeps, element re-creation and a switch to Chowlk/Graffoo/VOWL, and they are baked into PNG/SVG exports.
- New API:
ontoink.setTypography(id, key, value, scope),applyTypography(id),resetTypography(id),getInstance(id).
Added — Multi-selection and a right-click context menu¶
- Ctrl/Cmd+click and Shift+click extend the selection, Ctrl/Shift+drag rubber-bands, and dragging any selected node moves the whole selection. The node popup no longer fires during a multi-select gesture, and the selection renders with a cyan halo.
- Right-click opens a context menu with inline-SVG icons: align left/centre/right/top/middle/bottom; distribute horizontally/vertically with equal gaps; arrange as a grid or circle; snap to a 20 px grid; tidy as taxonomy (rows derived from
rdfs:subClassOfdepth); bigger/smaller/match size; pin & unpin (layout runs skip pinned nodes); colour the selection. - Ontology-specific verbs beyond the drawing ones: select same type · same namespace · grow to neighbours · sub-class tree · super-classes · instances of the selected classes · SHACL shapes constraining them · connected component; isolate / hide / show hidden; path between exactly two selected nodes; copy IRIs, labels, the selection as TTL or as a Markdown table; download the selection as
.ttl; export the selection as PNG. - Edge menu — select both endpoints, select every use of this predicate, hide all edges of this type, copy the predicate IRI, copy the triple. Cluster menu — expand/collapse and select members.
- Undo/redo (
Ctrl+Z/Ctrl+Shift+Z, 25 steps) for every position, size, pin and visibility verb. - Keyboard:
Ctrl+A,Escape(close menu, then clear selection),Deletehides the selection, arrow keys nudge it (Shift= 10×),Shift+F10/ the Context-Menu key opens the menu with roving-tabindex arrow navigation androle="menu"semantics. Shortcuts are scoped to the graph under the pointer or keyboard focus, never stolen from the TTL editor.
Fixed¶
- The fonts never actually applied. Every stylesheet asked for
"'Inter','Segoe UI',system-ui,sans-serif"in CSS syntax, but Cytoscape validatesfont-familyagainst a regex that forbids quotes — a quoted stack fails silently and falls back to the Cytoscape default (Helvetica Neue). All 25 declarations are now unquoted, so diagrams finally render in the font they always asked for. - The Konclude WASM reasoner bundle now actually ships in the wheel. The package-data glob pointed at
resources/reasoner/*while the vendored files live inresources/assets/reasoner/*, sobundle.mjs,konclude.mjs,konclude.wasmandworker.jswere absent from every distribution and the plugin'son_fileshook found an empty directory — everypip install ontoinksite kept 404-ing on/assets/reasoner/bundle.mjs, the exact failure 0.7.4 set out to fix (it only ever worked from a source checkout). - SVG export cropped anything outside the viewport — precisely what the new align/distribute verbs encourage. It now fits first when the graph extends past the viewport, then restores your zoom and pan.
- "Copy selection as TTL" dropped
rdfs:subClassOfwhenever the parent wasn't selected. It now emits every triple asserted by a selected subject, skips overlay-only edges (inferred / SHACL) and quotes literal objects. - Selection and pinned-node styling is re-appended to every style preset instead of vanishing on a preset switch; manual arrangements are saved to the position cache (programmatic moves never fire
dragfree); geometry verbs run insidecy.batch(). - The live DSL editor had no selection layer at all — it is now wired like the fence and playground paths.
[0.7.4] — 2026-07-21¶
Added — Plugin auto-installs the browser reasoner bundle¶
- The plugin ships a pre-built vendored
rdf-reasoner-koncludebundle (bundle.mjs,konclude.mjs,konclude.wasm,worker.js) and copies it to<site>/assets/reasoner/at build time. OntoInk's browser reasoner imports it same-origin — browsers reject cross-origin module Workers even with COEP credentialless, so without a same-origin copy the WASM Worker refused to spawn and the panel died with "Worker error — the WASM worker died during init". (See 0.7.5: a packaging glob bug meant this only worked from a source checkout until then.) coi-serviceworker.jsis copied to the site root and injected at the top of every OntoInk page, soSharedArrayBufferis available for the WASM reasoner on static hosts (GitHub Pages) that cannot send COOP/COEP headers.
Added — Style presets¶
- Chowlk, Graffoo and VOWL stylesheets are selectable from the toolbar, alongside the OntoInk default. Presets approximate the canonical notations where Cytoscape can express them.
Fixed¶
- Blank nodes are styled as blank nodes — rdflib emits blank subjects as
_:bN…, which the parser tagged as Individuals; they now render as small dashed grey diamonds. - Exported figures explain their purple dotted edges — overlay edge types that live only in Cytoscape (the inferred overlay) are now seeded into the export legend.
- Viewport optimizations for large ontologies — edges and labels hide during pan/zoom and the scene is bitmap-cached, with finer-grained wheel zoom.
[0.7.3] — 2026-07-20¶
Fixed — Reasoning panel¶
- "0 inferences from a successful build-time reasoner" no longer falls through to the runtime reasoner. When owlready2/HermiT runs in the build container, reports
consistent, and returns an empty inferred list — typical for pure SHACL shape files with no OWL-DL entailments — the panel used to punt to the runtime reasoner, which on a static host has no/reasonendpoint and errored with "No reasoner available". The panel now distinguishes the two cases viadata.consistency.status: a reasoner that ran gets a "Build-time OWL reasoning: 0 new triples inferred" panel with a consistency badge and a re-run link, whilestatus: "unknown"keeps the old fall-through so a local server or acrossOriginIsolatedbrowser can still pick up the work.
[0.7.2] — 2026-07-15¶
Added — Embeddable, CSP-safe build¶
ontoink.embed(el, {ttl, shape, layout, height, editor, reasoning})— mount an interactive OntoInk diagram from a Turtle string into any element on any page, no MkDocs required. It builds the toolbar/canvas/panels, parses the TTL client-side (the same path asontoink.playground), and returns the container id.shapeoverlays SHACL constraints;layoutsets the initial layout. See the new Embedding guide.scripts/build_embed_bundle.py— bundles the vendored libraries + the OntoInk runtime into a single self-containeddist/ontoink.embed.js(+dist/ontoink.embed.css). Drop the two files next to your page, add a<div class="ontoink-embed">, and callontoink.embed().
Changed — CSP-safe by default (no inline handlers, no CDN)¶
- Every event handler is now CSP-safe. All inline
on*=handlers — in the fence toolbar and the runtime-generated panels/popups — are emitted asdata-oi-on*attributes and attached withaddEventListenerby a small, eval-free interpreter (plus aMutationObserverfor dynamically-created UI). OntoInk now runs under a strictContent-Security-Policy(script-src 'self', no'unsafe-inline'), both embedded and on its own MkDocs pages. - Third-party libraries are self-hosted, not loaded from a CDN. Cytoscape, dagre, cytoscape-dagre, cytoscape-svg and CodeMirror (+ turtle mode) are vendored under
ontoink/resources/vendor/; the plugin copies them into the built site (on_files→<site>/vendor/) and injects local<script>tags. Pages now build and run fully offline and behind strict CSPs.
Fixed¶
- API version drift —
ontoink.api(/health, the FastAPI app title, and the derefUser-Agent) reported0.6.3while the package had moved to0.7.x; it now reports the current version.
[0.7.1] — 2026-07-10¶
Fixed — Live-editor DSL parser¶
@prefix ee: <http://ex#>no longer reports "unterminated" — the line-comment stripper treated any#as a comment start, so@prefixlines whose namespace ended in#(the canonical form for RDFS / OWL) were silently truncated and the closing>disappeared. Fixed by tracking<IRI>context in the stripper. User-declared prefixes now surface correctly in the Prefixes overlay and the generated Turtle.- Empty-prefix CURIE
:Personis accepted — the parser used to silently drop any triple that started with a:(Turtle default namespace);:Localis now a first-class CURIE. - Typo detector for arrow shortcuts —
-is->,-A->,-chian->, and any bare-identifier arrow within Levenshtein distance ≤ 2 of a known shortcut now emits an error suggesting the correct one (did you mean -isa-> ?) plus the shortcut vocabulary. - Every parser error now carries a plain-English hint — a second line under the error explains what an IRI, a CURIE, or a predicate arrow is, so non-experts learn how to fix it, not just where it broke.
Fixed — Type inference¶
- Rank-tiered strength: an explicit
rdf:type(or a vocabulary-position class) beats an inferred kind from a predicate signature; no moreowl:ObjectPropertydemoted toDatatypePropertybecause someone hangsrdfs:labeloff it. - All conflict pairs reported, not just the first-seen one.
- Well-known annotation properties (
rdfs:label,rdfs:comment,skos:definition,dc:title,dcterms:description) are typed asowl:AnnotationPropertywhen they take a literal. - SHACL predicates feed the inference table:
sh:path,sh:targetClass,sh:datatype,sh:class,sh:target[Objects|Subjects]Of,sh:node,sh:property. - Datatype ⊑ Class subsumption accepted in
_kindsCompatible, soxsd:integeron a range doesn't fire a spurious conflict. undefined:undefinedgone from evidence labels — full-IRI subjects now get a short label from the trailing path segment.xsd:*onrdfs:domaintypes the subject asowl:DatatypeProperty, notowl:ObjectProperty.
Fixed — Rendering¶
- Property chains and boolean class expressions collapse
rdf:Listscaffolding.owl:propertyChainAxiom,owl:intersectionOf, andowl:unionOfno longer leak_:list0/_:list1/rdf:first/rdf:rest/rdf:nilbubbles into the diagram. Chain axioms render aschain 1..N, intersections asand 1..N, unions asor 1..N.
Changed — Live editor UX¶
- Line-number gutter next to the DSL editor — errors that reference "line 12, column 5" are now visually locatable, and clicking an error row jumps the caret to that position.
- Warnings are amber, not red — the diagnostic strip distinguishes hard parse errors from type-inference warnings with a coloured kind pill and a hint line under the message.
- Playground-parity super-node + hull expand/collapse taps — clustered views behave the same everywhere.
- Prefixes overlay filters to referenced prefixes only.
- Widened live-editor layout — the mkdocs content column is widened via a
:has(#live-editor-app)guard (leaves other docs pages untouched), the right-hand TOC is hidden on this page, and pane heights useclamp()so tall monitors give the graph more room without breaking mobile stacking. - Node / Edge popups + Legend + Prefixes overlays wired into the live editor — the same panels the fence graphs use.
[0.7.0] — 2026-07-09¶
Added¶
- Big-ontology mode — Semantic-Tile bundle — a coordinated set of build-time + runtime knobs that lets one OntoInk diagram scale from a tiny example to a 100 000-triple ontology without swamping the browser. Opt-in: a fence with no YAML config still renders exactly the same graph 0.6.1 rendered.
- Build-time literal-fold + predicate-policy YAML config —
predicates: { hide_predicates, fold_into_badge, badge_predicates }(CURIEs resolve against the source graph's own prefixes;prov:*wildcards match by namespace URI). Folded literals migrate intonode_badges; hidden predicates are dropped wholesale. - Leiden clustering with LLM-titled super-nodes and JSON side-store — needs
ontoink[cluster](python-igraph + leidenalg).ontoink[topic](anthropic + openai) additionally names each community; a missing library or missing API key falls back to a deterministic synthetic title. - Element-removing semantic zoom (L0..L6) slider — new toolbar slider, default L2. L0 = super-nodes + top-K central classes only, L6 = everything (SHACL + inferred).
- Attic side panel for reversible progressive disclosure — every element hidden by the LOD slider is snapshotted into a per-diagram Attic; a pin button re-adds it to the canvas regardless of the slider.
- SPARQL endpoint result graphs get the same LOD slider + Attic — SELECT rows projecting
?s ?p ?onow materialise into the live graph, are sanitised through the samepredicates:policy, and settle into the Attic when hidden. Community detection stays build-time only.
- Build-time literal-fold + predicate-policy YAML config —
- Optional dependency groups —
[cluster](python-igraph + leidenalg) for community detection,[topic](anthropic + openai) for super-node titling. Neither is required for the default rendering path.
Changed¶
- Fence toolbar gains a new group between search and export: LOD slider + LOD value badge + Attic button + Super checkbox.
- Super-node styling — hexagon with a double 3-px cyan border, chunkier font, and a
·Nmember count in the label. Clicking a super-node expands / collapses its community; the ordinary node popup does not fire. - CSS design tokens — new
--ov-attic-*,--ov-super-*,--ov-badge-*,--ov-restriction-*tokens make every new control themable via Edit Layout.
Fixed¶
- No-config regression — the predicate policy compiles to empty sets when no policy is given, so
parse_ttl_to_cytoscape(path)returns the exact triple-by-triple output shape 0.6.1 emitted. Verified by the existing test suite (83 passed, 4 skipped, no test changes). - Attic z-index isolation — the panel sits inside
.ontoink-container(which isisolation: isolatesince 0.6.1) so itsz-index: 400cannot escape over the host site's sticky chrome.
[0.6.3] — 2026-06-10¶
Added¶
- Full in-browser SHACL validation — interactive Validate now runs a standards-compliant SHACL Core engine (
rdf-validate-shacl) entirely in the browser, replacing the old cardinality-only checker. It catchessh:datatype,sh:class,sh:nodeKind,sh:pattern, value ranges,sh:in/sh:hasValue/closed, logical/shape-based constraints, property paths and inline blank-node shapes — verified against pyshacl. Ships as a committed same-origin bundle (assets/shacl/shacl.mjs), so it works on the static demo with no server. (SHACL-SPARQL constraints and SHACL-AFsh:rulestill need the server/build-time pyshacl.) - Server-side ontology dereference proxy (
/deref) — a generic, CORS-free, SSRF-guarded alternative to the hard-coded mirror registry; the "More…" dereference prefers it when a server is reachable and works for any ontology (including FOAF)
Fixed¶
- Dead ontology-mirror URLs — the BFO and IAO entries in the known-ontology registry returned 404 (files moved); nfdicore is now version-less. Browser dereferencing of those namespaces works again
- Legend edge arrowheads — the legend ignored the pointer shape chosen in Edit Layout and always drew a triangle; it now renders tee / vee / diamond / circle to match the graph
- Playground "Edit & Validate" now has a SHACL Shapes pane — the playground's editor was missing the shapes editor, so an uploaded or
?shape=-linked SHACL file was never shown and validation ran against empty shapes. The panel now matches the fence-rendered editor (Source | SHACL Shapes + Validation Report), and validation falls back to the loaded shapes so?data=…&shape=…links validate even before the editor is opened
[0.6.2] — 2026-06-08¶
Fixed¶
- All four OWL reasoner backends now return inferences —
owlready2/HermiT, nativekonclude, andkonclude-wasmeach failed silently before (Turtle vs RDF/XML, OWL-XML output parsed as RDF/XML, N-Quads vs N-Triples), so onlyowlrlever produced results. All four now work on OWL 2 property-restriction ontologies owl:equivalentClass(andintersectionOf-nested) restrictions are now visualised — previously onlyrdfs:subClassOfrestrictions were drawn. The two are distinguished:⊑(solid triangle) for a necessary condition vs≡(hollow diamond) for a definition- Browser (in-page) Konclude WASM
Error: unwind— the Emscripten exit sentinel is now caught and the inferred graph harvested - Edit & Validate → Update Graph (and the playground) no longer destroy restrictions — a new blank-node-aware client-side parser collapses
owl:Restrictioninto the same⊑/≡edges as the server-rendered diagrams, instead of exploding into raw[ ]/owl:Restrictionnodes
Added¶
reasoner:fence option — set a diagram's default reasoner backend, e.g.reasoner: owlrl- Comprehensive Reasoning & Inference demo — examples/reasoning-demo.md now walks every RDF/RDFS/OWL/OWL2 reasoning feature with a small self-contained example each
Changed¶
- OLS IRI-dereference link — dropped the "Found in: N ontologies" line; the cross-ontology link now reads "Ontologies using this IRI on OLS"
[0.6.1] — 2026-06-04¶
Added¶
- SHACL Shapes editor pane in Edit & Validate — two-column editor (data TTL + SHACL shapes) with CodeMirror Turtle highlighting and a constraint-count in the report line
- Resizable popups — drag the bottom-right corner to enlarge a popup
Fixed¶
- "Ontologies reusing this IRI on OLS" link returned zero results — now derives the OBO short ID (e.g.
IAO:0000300) so OLS search matches - Sticky toolbar bleeding over host-page chrome —
.ontoink-containernow isolates its stacking context
[0.6.0] — 2026-05-17¶
Added¶
- Browser-side reasoning in the playground — Reasoning button with backend dropdown (Auto / Browser Konclude WASM / Server backends). Browser option enabled when cross-origin isolated; server options enabled when
/healthreachable - COOP/COEP service worker so the playground's WASM Konclude works on GitHub Pages without server-side header support
- Per-request
reasoneroverride onPOST /reason— clients can choose the backend without restarting the server - Playground parity — Abstract View and reasoning panel match the MkDocs fence path
- Production Docker image with
ONTOINK_MODEenv switch (serve/build/api/all) andONTOINK_REASONERselector. The newallmode builds the docs once and serves them via FastAPI on the same origin as/reason— so the playground's "Server" reasoner works without a reverse proxy - Konclude two-pass reasoning — native Konclude wrapper runs both
classificationandrealization. Note: Konclude expects OWL/XML input; for TTL input useowlready2orkonclude-wasm - Native Konclude reasoner (
ONTOINK_REASONER=konclude) — upstream Konclude C++ tableau binary, downloaded into the production Docker image - rdf-reasoner-konclude (
ONTOINK_REASONER=konclude-wasm) — WASM Konclude port for browsers and Node.js, no Java required - FastAPI mode —
/reason,/validate,/healthendpoints whenONTOINK_MODE=api - SHACL constraint edges in the playground — shapes now render as cyan dashed cardinality-labelled edges, matching the MkDocs build path
- SHACL shape IRI dereferencing — labels and axioms auto-fetched for
sh:path,sh:targetClass,sh:class,sh:datatype,sh:nodeIRIs on graph load - GitHub Actions workflow to build & push the Docker image to GHCR on each
v*tag - TESTING.md with end-to-end manual test plan (Python, JS, MkDocs, playground, Docker)
.env.sample,NOTICE, andCITATION.cfffiles for deployment config and third-party attribution
Fixed¶
- Reasoning UI lock state — the Reasoning button and dropdown disable while reasoning runs, with a visible Cancel button. Server requests are aborted via
AbortController - SPARQL autocomplete on macOS — added
Alt+/as a universal trigger; macOS reservesCtrl+Spacefor input source switching by default - Browser WASM reasoner module loading — switched from jsdelivr's
/+esmtoesm.sh - Demo pages looked unstyled in
allmode — switchedCross-Origin-Embedder-Policyfromrequire-corptocredentialless - Legend and namespace overlay now refresh when the layout is switched
- Edit Layout customizations propagate to the legend — node color / node shape / edge color / line style / arrow shape changes immediately update the on-page legend
- PNG and SVG exports now embed Edit Layout customizations in the legend (previously the export legend always showed default styles)
Changed¶
- Reasoner selection is now user-configurable via env var
[0.5.2] — 2026-04-17¶
Fixed¶
- Broken parsing of TTL with periods inside strings — the statement splitter now respects quoted strings, so descriptions like
"...time frame. Every batch..."no longer break parsing - Hyphenated prefixes not recognized — prefixes like
samm-c:,ext-built:,ext-classification:are now correctly captured
[0.5.1] — 2026-04-17¶
Fixed¶
- Playground hang on non-HTTP namespaces —
urn:,oid:, and other non-HTTP URI schemes are skipped during auto-dereference
[0.5.0] — 2026-04-10¶
Highlight: Automatic Ontology Label Resolution¶
OntoInk now automatically fetches and resolves human-readable labels from referenced ontologies. When your shape graph uses IRIs from nfdicore, BFO, IAO, or other ontologies, OntoInk fetches the ontology source files and extracts rdfs:label, rdfs:comment, type information, and more — so you see "contributor role" instead of NFDI_0000118 everywhere.
This works across:
- Click popups — "More..." shows label, comment, type, subclass, deprecation status
- SPARQL autocomplete — Ctrl+Space shows both human label and IRI local name
- SPARQL class/property dropdowns —
contributor role (NFDI_0000118)instead of justNFDI_0000118 - Query results — IRIs rendered as
label (prefixed:name) - SPARQL Explorer — when the endpoint lacks labels, fetches ontology source files as fallback
Added¶
- Automatic ontology label resolution — background fetch of all referenced ontology namespaces on graph init
- Known ontology URL registry bypasses CORS-broken redirects for nfdicore, BFO, IAO, RO, FOAF, Schema.org, SKOS
- Robust line-based OWL TTL parser handles Protégé-style files with nested blank nodes, collections, and
"""strings - Dual parser strategy: merges results from minimal + robust parsers for maximum coverage
- Enhanced IRI dereferencing — "More..." button shows label, comment, type, subClassOf, deprecation, SKOS definitions, editorial notes
- Scrollable popups — popup containers capped at 70vh with overflow scroll; deref results independently scrollable
- Sticky toolbar — toolbar stays fixed at viewport top while scrolling
- SPARQL Explorer ontology fallback — fetches nfdicore, BFO, IAO, FOAF, etc. when endpoint lacks rdfs:label
- SPARQL results with labels — query result IRIs shown as
label (prefixed:name) - SPARQL dropdowns always fresh — class/property selects rebuild with latest labels every time panel opens
- OntoSniff — ontology smell detector with 9 anti-patterns, quality score (0-100), standalone page
- SPARQL Explorer — endpoint connection, schema discovery, query builder, Ctrl+Space autocomplete
- Abstract Model View, Search & Highlight, Layout Switcher, Graph Statistics, Path Finder, Minimap, Neighborhood Focus, Playground, SHACL Editor
Fixed¶
- IRI dereferencing for nfdicore and ontologies with CORS-broken 302 redirects
- SPARQL Explorer label fetching with batch loading and ontology source fallback
- SPARQL dropdowns refresh labels on every panel open (not just first build)
- PNG/SVG export: minimap hidden, scale 2x, reliable overlay positioning
[0.3.0] — 2026-04-09¶
Added¶
- OWL Reasoning — HermiT reasoner (via owlready2) runs at build time for full OWL DL reasoning, with owlrl fallback for OWL-RL profile
- Reasoning toolbar button opens an inferences panel showing all inferred triples in a table
- "Show on graph" checkbox overlays inferred triples as purple dotted edges and nodes
- "Validate with Inferences" button runs SHACL validation with inferred triples included
- Smart filtering removes reflexive triples, built-in namespace noise, and domain/range propagation
- Configuration option:
reasoning: true/falseper diagram
- OWL Reasoning demo — new example with class hierarchy, inverse, transitive, and symmetric properties
- Draggable popups — node and edge popups can be repositioned by dragging the header
- Collapsible popup sections — Connections and SHACL Constraints are collapsed by default (click to expand)
- IRI dereferencing — "More…" button in popups fetches structured data from the IRI via content negotiation
- Prefix editing — toggle prefix visibility from the Edit Layout panel
Fixed¶
- Prefix overlay only shows prefixes declared in the TTL source (not rdflib built-ins like dc, dcterms, skos, etc.)
- Popup toggle sections work correctly for all node types (fixed special character issue in IRI-based IDs)
- PNG/SVG export captures the exact viewport with overlays at their on-screen positions
[0.2.0] — 2026-04-08¶
Added¶
- Edge click popup — click any edge to see its label, type, IRI, source/target nodes, cardinality, and copy buttons
- Edit Layout panel — renamed from "Colors"; now includes:
- Node shape selector (rectangle, ellipse, diamond, hexagon, triangle, star, and more)
- Edge line style selector (solid, dashed, dotted)
- Edge arrow shape selector (triangle, vee, circle, diamond, chevron, none, and more)
- Color pickers for node types, edge types, and namespace groups
- Documentation site — full Material for MkDocs documentation with getting started guide, examples, contributing guide, citation info, and changelog
Fixed¶
- Export layout fidelity — PNG and SVG exports now capture the exact viewport the user sees (zoom, pan, node positions) instead of re-fitting all elements
- Export overlay positioning — legend and namespace prefix boxes are drawn at their actual on-screen positions (respects user dragging)
- Export overlay sizing — legend and prefix boxes match their DOM dimensions; font sizes aligned to CSS (11px entries, 12px titles, 10px prefixes)
Changed¶
- Toolbar button renamed from "Colors" to "Edit Layout"
- Package renamed to
ontoink(fromontoviz)
[0.1.0] — 2026-04-07¶
Initial public release.
Added¶
- Interactive ontology visualization using Cytoscape.js with dagre layout
- Formal visual notation: classes (rectangles), individuals (ellipses), literals (dashed ellipses), datatypes (diamonds)
- Edge styles: object properties (blue), data properties (green), rdf:type (grey dashed), rdfs:subClassOf (black), SHACL constraints (cyan dashed bold)
- SHACL constraint overlay with cardinality badges
[min..max] - Click popup for nodes with IRI, type badge, ontology source, connections, copy buttons
- Inline TTL editor with CodeMirror and Turtle syntax highlighting
- Live SHACL validation with constraint checking (browser-side)
- Build-time SHACL validation using pySHACL
- Publication-ready PNG (3x hi-DPI) and SVG export with legend and namespace boxes
- Auto-generated interactive legend (draggable, resizable)
- Namespace prefix overlay with "show all" toggle
- Toolbar: zoom in/out, fit, fullscreen, export PNG/SVG/TTL, colors
- Color coding by ontology source (BFO, IAO, nfdicore, RO, OBI, PMD, QUDT, Schema.org, FOAF)
- Color customization panel for node types and namespace groups
- MkDocs plugin with
pymdownx.superfencescustom fence integration - Configuration options: source, shape, height, editor, legend, namespaces
- Demo site with GitHub Pages deployment
- Comprehensive test suite with pytest (20 tests)