Classes and instances in ontology menu
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -141,25 +141,20 @@
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-pills" id="content-tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="layer-tab" data-bs-toggle="tab" data-bs-target="#layer" type="button" role="tab" aria-controls="layer" aria-selected="false">
|
||||
<button class="nav-link active" id="layer-tab" data-bs-toggle="tab" data-bs-target="#layer" type="button" role="tab" aria-controls="layer" aria-selected="true">
|
||||
<i class="bi bi-boxes me-1"></i> Elementi 3D
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="content-tab" data-bs-toggle="tab" data-bs-target="#content" type="button" role="tab" aria-controls="media" aria-selected="true">
|
||||
<i class="bi bi-diagram-3 me-1"></i> Contenuti
|
||||
<button class="nav-link" id="content-tab" data-bs-toggle="tab" data-bs-target="#content" type="button" role="tab" aria-controls="media" aria-selected="false">
|
||||
<i class="bi bi-diagram-3 me-1"></i> Ontologia
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content ps-2 ms-2 overflow-y-auto">
|
||||
<div class="tab-pane active ps-3 pt-0 mt-4 ms-0" data-menu-target="layers" id="layer" role="tabpanel" aria-labelledby="layer-tab" tabindex="0"></div>
|
||||
<div class="tab-pane pt-3" data-menu-target="ontology" id="content" role="tabpanel" aria-labelledby="media-tab" tabindex="0">
|
||||
<!-- Temporary -->
|
||||
<ul class="list-group me-4 ms-0">
|
||||
<li class="list-group-item pt-2 pb-2" id="ontology-list"></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-pane pt-3" data-menu-target="ontology" id="content" role="tabpanel" aria-labelledby="media-tab" tabindex="0"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
// Global ATON
|
||||
import { Controller } from "@hotwired/stimulus";
|
||||
import AppState from "../state.js";
|
||||
import { traverseOntology } from "../ontology.js";
|
||||
import { loadOntology, traverseOntology, Ontology } from "../ontology.js";
|
||||
|
||||
const html = String.raw;
|
||||
const domParser = new DOMParser;
|
||||
// TODO: hard-coded, but follows a convention...
|
||||
const ontologyJsonPath = '/a/scaenae/scenes/BaroqueTheatreOntology_BT_EN_v1_7_UI_by_domain_v3.json';
|
||||
const ontologyJsonPath = '/a/scaenae/scenes/BaroqueTheatreOntology_BT_v1_8_ATON_by_domain_with_instances.json';
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ['trigger', 'layers', 'ontology'];
|
||||
|
||||
connect() {
|
||||
async connect() {
|
||||
console.log('#menu controller connected');
|
||||
this.ontologyObject = await loadOntology(ontologyJsonPath);
|
||||
}
|
||||
/**
|
||||
* Open settings panel
|
||||
@@ -22,7 +23,7 @@ export default class extends Controller {
|
||||
ATON.UI.showSidePanel({header: 'Menu'});
|
||||
this.#buildMenuPanel(ATON.UI.elSidePanel);
|
||||
this.#buildLayersMenu(AppState.treeNodes, this.layersTarget);
|
||||
this.#buildOntologyMenu(await traverseOntology(ontologyJsonPath), this.ontologyTarget);
|
||||
this.#buildOntologyMenu(await traverseOntology(this.ontologyObject), this.ontologyTarget);
|
||||
}
|
||||
/**
|
||||
* @param {Event} event
|
||||
@@ -229,24 +230,31 @@ export default class extends Controller {
|
||||
* @param {HTMLElement} tab Tab content element
|
||||
*/
|
||||
#buildOntologyMenu(domains, tab) {
|
||||
const mainNode = tab.querySelector('#ontology-list');
|
||||
mainNode.classList.add('pb-3');
|
||||
const ontology = new Ontology;
|
||||
ontology.data = this.ontologyObject;
|
||||
|
||||
const tabs = this.#createOntologyTabs().tabs;
|
||||
const content = this.#createOntologyTabs().content;
|
||||
|
||||
tab.appendChild(tabs);
|
||||
tab.appendChild(content);
|
||||
|
||||
const classesTab = content.querySelector('#classes');
|
||||
const instancesTab = content.querySelector('#instances');
|
||||
|
||||
for (let domain of domains) {
|
||||
const heading = document.createElement('span');
|
||||
heading.className ="fs-5 fw-bold";
|
||||
heading.textContent = domain.id;
|
||||
mainNode.appendChild(heading);
|
||||
classesTab.appendChild(heading);
|
||||
|
||||
let domainList = document.createElement('div');
|
||||
|
||||
console.debug(domain.tree);
|
||||
|
||||
// Traverse class trees for each domain
|
||||
for (let item of domain.tree) {
|
||||
const domainItem = document.createElement('div');
|
||||
domainItem.className = 'border-start border-bottom rounded';
|
||||
domainItem.textContent = item.label;
|
||||
domainItem.className = 'border-start border-bottom rounded border-1 border-light-subtle';
|
||||
domainItem.textContent = item.label.it ?? item.label.en;
|
||||
// Indentation...
|
||||
domainItem.classList.add(`ms-${item.depth}`, `ps-${item.depth}`, 'py-2');
|
||||
|
||||
@@ -255,7 +263,48 @@ export default class extends Controller {
|
||||
domainList.appendChild(domainItem);
|
||||
}
|
||||
|
||||
mainNode.appendChild(domainList);
|
||||
classesTab.appendChild(domainList);
|
||||
}
|
||||
|
||||
const sortedItLabels = ontology.getInstanceLabels().map(l => l.it).sort();
|
||||
|
||||
for (let label of sortedItLabels) {
|
||||
const instanceItem = document.createElement('div');
|
||||
instanceItem.className = 'border-bottom ps-3 py-2';
|
||||
instanceItem.textContent = label;
|
||||
|
||||
instancesTab.appendChild(instanceItem);
|
||||
}
|
||||
|
||||
console.debug(ontology.getInstanceById('ex:SSGJP_StructuralBackdrop'), ontology.getInstanceLabels());
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {{tabs: HTMLUListElement, content: HTMLDivElement}}
|
||||
*/
|
||||
#createOntologyTabs() {
|
||||
const tabs = html`
|
||||
<ul class="nav nav-pills" role="tablist" id="ontoTabs">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="classes-tab" data-bs-toggle="tab" data-bs-target="#classes" type="button"
|
||||
role="tab" aria-controls="classes-tab-pane" aria-selected="true">Classi</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="instances-tab" data-bs-toggle="tab" data-bs-target="#instances" type="button"
|
||||
role="tab" aria-controls="instances-tab-pane" aria-selected="true">Istanze</button>
|
||||
</li>
|
||||
</ul>
|
||||
`;
|
||||
const content = html`
|
||||
<div class="tab-content" id="ontoTabsContent">
|
||||
<div class="tab-pane fade p-3 show active" id="classes" role="tabpanel" aria-labelledby="classes-tab" tabindex="0"></div>
|
||||
<div class="tab-pane fade" id="instances" role="tabpanel" aria-labelledby="instances-tab" tabindex="0"></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
return {
|
||||
tabs: domParser.parseFromString(tabs, 'text/html').querySelector('ul'),
|
||||
content: domParser.parseFromString(content, 'text/html').querySelector('div'),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,47 @@
|
||||
* @module Ontology
|
||||
*/
|
||||
|
||||
export class Ontology {
|
||||
#data;
|
||||
|
||||
/**
|
||||
* @param {Object} data The parsed ontology object (from JSON)
|
||||
*/
|
||||
set data(data) {
|
||||
this.#data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} id
|
||||
*/
|
||||
getInstanceById(id) {
|
||||
return this.#data.instancesById[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Array<{en: string, it: string}>} The bloody array of label objects
|
||||
*/
|
||||
getInstanceLabels() {
|
||||
const data = this.#data;
|
||||
const instances = [];
|
||||
|
||||
for (const key of Object.keys(data.instancesById)) {
|
||||
instances.push(data.instancesById[key]?.label);
|
||||
}
|
||||
|
||||
return instances;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Temporarily returns domains and ontology labels only
|
||||
* Traverse an ontology from its JSON description
|
||||
* @param {String} jsonPath The path (URI) of the ontology JSON file
|
||||
* @param {Object} ontologyObject The parsed ontology JSON
|
||||
* @returns {Object}
|
||||
*/
|
||||
export async function traverseOntology(jsonPath) {
|
||||
const ontology = await loadOntology(jsonPath);
|
||||
const modules = ontology.modules;
|
||||
export async function traverseOntology(ontologyObject) {
|
||||
//const ontology = await loadOntology(jsonPath);
|
||||
const modules = ontologyObject.domains;
|
||||
|
||||
const domains = [];
|
||||
|
||||
@@ -20,7 +52,7 @@ export async function traverseOntology(jsonPath) {
|
||||
traverseClasses(classTree, tree);
|
||||
}
|
||||
domains.push({
|
||||
id: module.id,
|
||||
id: module.label.it ?? module.label.en,
|
||||
tree
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user