Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Treat Thing label as Reified to fix #150 #157

Merged
merged 1 commit into from
Nov 11, 2024
Merged
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
34 changes: 17 additions & 17 deletions dist_plainjs/terminology-service-suite.js

Large diffs are not rendered by default.

66 changes: 33 additions & 33 deletions dist_plainjs/terminology-service-suite.min.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/api/HierarchyBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {EntityTypeName} from "../model/ModelTypeCheck";
import {Hierarchy, TreeNode} from "../model/interfaces/Hierarchy";
import {EntityDataForHierarchy} from "../app/types"
import {EntityData} from "../app/types";

export type HierarchyQueryProps = {
/**
Expand Down Expand Up @@ -64,5 +64,5 @@ export type LoadHierarchyChildrenProps = HierarchyQueryProps & {

export interface HierarchyBuilder {
buildHierarchyWithIri(props: BuildHierarchyProps & HierarchyIriProp): Promise<Hierarchy>
loadHierarchyChildren(props: LoadHierarchyChildrenProps): Promise<EntityDataForHierarchy[]>
loadHierarchyChildren(props: LoadHierarchyChildrenProps): Promise<EntityData[]>
}
29 changes: 15 additions & 14 deletions src/api/OlsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import {
EntityTypeName, ThingTypeName,
isClassTypeName, isEntityTypeName, isIndividualTypeName, isOntologyTypeName
} from "../model/ModelTypeCheck";
import { EntityDataForHierarchy, Hierarchy, ParentChildRelation, TreeNode } from "../model/interfaces/Hierarchy";
import { Hierarchy, ParentChildRelation, TreeNode } from "../model/interfaces/Hierarchy";
import Reified from "../model/Reified";
import { BuildHierarchyProps, HierarchyBuilder, HierarchyIriProp, LoadHierarchyChildrenProps } from "./HierarchyBuilder";
import { OLSSelect } from "../model/ols-model/OLSSelect";
import { Select } from "../model/interfaces/Select";
import { OLSSelectResult } from "../model/ols-model/OLSSelectResult";
import { Ts4nfdiSearchResult } from "../model/ts4nfdi-model/Ts4nfdiSearchResult";
import { EntityData } from "../app/types";

// used to filter entities not be shown in hierarchy
function isTop(iri: string): boolean {
Expand Down Expand Up @@ -691,7 +692,7 @@ export class OlsApi implements HierarchyBuilder {
}
}

public jsTreeNodeToEntityDataForHierarchy(jsTreeNode: JSTreeNode): EntityDataForHierarchy {
public jsTreeNodeToEntityData(jsTreeNode: JSTreeNode): EntityData {
return {
iri: jsTreeNode.iri,
label: jsTreeNode.text,
Expand All @@ -700,7 +701,7 @@ export class OlsApi implements HierarchyBuilder {
};
}

public entityToEntityDataForHierarchy(entity: Entity): EntityDataForHierarchy {
public entityToEntityData(entity: Entity): EntityData {
return {
iri: entity.getIri(),
label: asArray(entity.getLabel())[0],
Expand Down Expand Up @@ -728,13 +729,13 @@ export class OlsApi implements HierarchyBuilder {

/* QUERY root entities */
const rootEntitiesData = (await this.getRootEntities(entityType, ontologyId, preferredRoots, includeObsoleteEntities, useLegacy))
.map((entity) => this.entityToEntityDataForHierarchy(entity))
.map((entity) => this.entityToEntityData(entity))
.filter((root) => !isTop(root.iri));
/* --- */

/* INITIALIZE entitiesData, parentChildRelations */
const parentChildRelations: Map<string, ParentChildRelation[]> = new Map<string, ParentChildRelation[]>();
const entitiesData: Map<string, EntityDataForHierarchy> = new Map<string, EntityDataForHierarchy>();
const entitiesData: Map<string, EntityData> = new Map<string, EntityData>();
for (const entityData of rootEntitiesData) {
parentChildRelations.set(entityData.iri, []); // initialize with empty array
entitiesData.set(entityData.iri, entityData);
Expand Down Expand Up @@ -774,7 +775,7 @@ export class OlsApi implements HierarchyBuilder {
} = props;

/* LOAD ancestors */
let entities: EntityDataForHierarchy[] = [];
let entities: EntityData[] = [];

if (useLegacy) {
// TODO: JSTree sometimes returns smaller trees than would be possible via querying hierarchical ancestors and all children of those (e.g. http://purl.obolibrary.org/obo/UBERON_2001747 -> strange and not really useful hierarchy because many entities are both sibling and children of other entities (is it wrong to take hierarchicalParent instead of directParent in entityToEntityDataToHierarchy? EMBL-EBI does it like that as well))
Expand Down Expand Up @@ -803,15 +804,15 @@ export class OlsApi implements HierarchyBuilder {
if (!inArr.has(jsTreeNode.iri)) {
inArr.add(jsTreeNode.iri);

entities.push(this.jsTreeNodeToEntityDataForHierarchy(jsTreeNode));
entities.push(this.jsTreeNodeToEntityData(jsTreeNode));
const par = parents.get(jsTreeNode.iri);
if (par != undefined) entities[entities.length - 1].parents = Reified.fromJson(Array.from(par.values())) || [];
}
}
}
else {
const ancestors = await this.getAncestors(mainEntity.getIri(), entityType, ontologyId || mainEntity.getOntologyId(), includeObsoleteEntities);
entities = [this.entityToEntityDataForHierarchy(mainEntity), ...ancestors.map((entity) => this.entityToEntityDataForHierarchy(entity))]
entities = [this.entityToEntityData(mainEntity), ...ancestors.map((entity) => this.entityToEntityData(entity))]
}

// filter top entities
Expand All @@ -821,7 +822,7 @@ export class OlsApi implements HierarchyBuilder {
/* BUILD parentChildRelations */
const parentChildRelations: Map<string, ParentChildRelation[]> = new Map<string, ParentChildRelation[]>();
const allChildrenPresent: Set<string> = new Set<string>();
const entitiesData: Map<string, EntityDataForHierarchy> = new Map<string, EntityDataForHierarchy>();
const entitiesData: Map<string, EntityData> = new Map<string, EntityData>();

// initialize parentChildRelations & entitiesData
for (const entityData of entities) {
Expand All @@ -838,7 +839,7 @@ export class OlsApi implements HierarchyBuilder {
for (const entityData of entities) {
if (entityData.iri != mainEntity.getIri()) {
promises.push(new Promise((resolve) =>
this.getChildren(entityData.iri, entityTypeForQuery, ontologyId, includeObsoleteEntities, useLegacy).then((children) => children.map((child) => this.entityToEntityDataForHierarchy(child))).then((children) => {
this.getChildren(entityData.iri, entityTypeForQuery, ontologyId, includeObsoleteEntities, useLegacy).then((children) => children.map((child) => this.entityToEntityData(child))).then((children) => {
const parChildRel: ParentChildRelation[] = [];
for (const child of children) {
entitiesData.set(child.iri, child);
Expand All @@ -859,7 +860,7 @@ export class OlsApi implements HierarchyBuilder {
if (realEntityType == "individual") {
for (const parentReified of mainEntity.getParents()) {
const children = (await this.getChildren(parentReified.value, realEntityType, ontologyId, includeObsoleteEntities))
.map((child) => this.entityToEntityDataForHierarchy(child))
.map((child) => this.entityToEntityData(child))

const parChildRel: ParentChildRelation[] = [];
for (const child of children) {
Expand Down Expand Up @@ -909,7 +910,7 @@ export class OlsApi implements HierarchyBuilder {
}
/* --- */

function createTreeNode(entityData: EntityDataForHierarchy, cycleCheck: Set<string>, childRelationToParent?: string): TreeNode {
function createTreeNode(entityData: EntityData, cycleCheck: Set<string>, childRelationToParent?: string): TreeNode {
cycleCheck.add(entityData.iri); // add current entity to cycle check set

const node = new TreeNode(entityData);
Expand Down Expand Up @@ -951,10 +952,10 @@ export class OlsApi implements HierarchyBuilder {
})
}

public async loadHierarchyChildren(props: LoadHierarchyChildrenProps): Promise<EntityDataForHierarchy[]> {
public async loadHierarchyChildren(props: LoadHierarchyChildrenProps): Promise<EntityData[]> {
if (props.entityType == undefined) throw Error("EntityType has to be provided to load children in OLS.");

return (await this.getChildren(props.nodeToExpand.entityData.iri, props.entityType, props.ontologyId, props.includeObsoleteEntities, props.useLegacy))
.map((entity) => this.entityToEntityDataForHierarchy(entity))
.map((entity) => this.entityToEntityData(entity))
}
}
16 changes: 8 additions & 8 deletions src/api/OntoPortalApi.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {BuildHierarchyProps, HierarchyBuilder, HierarchyIriProp, LoadHierarchyChildrenProps} from "./HierarchyBuilder";
import axios, {AxiosInstance, AxiosRequestConfig} from "axios";
import {EntityDataForHierarchy, Hierarchy, ParentChildRelation, TreeNode} from "../model/interfaces/Hierarchy";
import { Hierarchy, ParentChildRelation, TreeNode} from "../model/interfaces/Hierarchy";
import {pluralizeType} from "../app/util";
import {useLegacyArgType} from "../stories/storyArgs";
import {EntityData} from "../app/types";

type HierarchyNode = {
prefLabel: string
Expand All @@ -20,7 +20,7 @@ type HierarchyNode = {
}
}

function HierarchyNodeToEntityDataForHierarchy(hierarchyNode: HierarchyNode) : EntityDataForHierarchy {
function HierarchyNodeToEntityData(hierarchyNode: HierarchyNode) : EntityData {
return {
iri: hierarchyNode["@id"],
label: hierarchyNode["prefLabel"],
Expand Down Expand Up @@ -69,13 +69,13 @@ export class OntoPortalApi implements HierarchyBuilder{
if(!entityType) throw Error("entityType has to be specified for OntoPortal API.");

const rootEntities: string[] = [];
const entitiesData: Map<string, EntityDataForHierarchy> = new Map<string, EntityDataForHierarchy>();
const entitiesData: Map<string, EntityData> = new Map<string, EntityData>();
const parentChildRelations: Map<string, ParentChildRelation[]> = new Map<string, ParentChildRelation[]>();
const allChildrenPresent: Set<string> = new Set<string>();
const onInitialPath: Set<string> = new Set<string>(); // only used if showSiblingsOnInit == false

function buildRelations(currNode: HierarchyNode) {
entitiesData.set(currNode["@id"], HierarchyNodeToEntityDataForHierarchy(currNode))
entitiesData.set(currNode["@id"], HierarchyNodeToEntityData(currNode))
if(currNode.hasChildren && currNode.children.length > 0) {
parentChildRelations.set(currNode["@id"], currNode.children.map((c) => {return {childIri: c["@id"]}}));

Expand Down Expand Up @@ -111,7 +111,7 @@ export class OntoPortalApi implements HierarchyBuilder{
}
}

function createTreeNode(entityData: EntityDataForHierarchy, cycleCheck: Set<string>): TreeNode {
function createTreeNode(entityData: EntityData, cycleCheck: Set<string>): TreeNode {
cycleCheck.add(entityData.iri); // add current entity to cycle check set

const node = new TreeNode(entityData);
Expand Down Expand Up @@ -165,7 +165,7 @@ export class OntoPortalApi implements HierarchyBuilder{
});
}

public async loadHierarchyChildren(props: LoadHierarchyChildrenProps): Promise<EntityDataForHierarchy[]> {
public async loadHierarchyChildren(props: LoadHierarchyChildrenProps): Promise<EntityData[]> {
const {
nodeToExpand,
ontologyId,
Expand All @@ -179,6 +179,6 @@ export class OntoPortalApi implements HierarchyBuilder{
{params: {include: "@id,prefLabel,hasChildren"}}
))["collection"];

return children.map((child) => HierarchyNodeToEntityDataForHierarchy(child));
return children.map((child) => HierarchyNodeToEntityData(child));
}
}
29 changes: 15 additions & 14 deletions src/api/SkosApi.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import axios, {AxiosInstance, AxiosRequestConfig} from "axios";
import {BuildHierarchyProps, HierarchyBuilder, HierarchyIriProp, LoadHierarchyChildrenProps} from "./HierarchyBuilder";
import {EntityDataForHierarchy, Hierarchy, ParentChildRelation, TreeNode} from "../model/interfaces/Hierarchy";
import { Hierarchy, ParentChildRelation, TreeNode} from "../model/interfaces/Hierarchy";
import Reified from "../model/Reified";
import { EntityData } from "../app/types";

type TopConcept = {
uri: string,
Expand Down Expand Up @@ -33,8 +34,8 @@ type PrefAndUriAndChildren = {
notation?: string
}

abstract class SkosEntityDataForHierarchyBuilder {
static fromTopConcept(obj: TopConcept) : EntityDataForHierarchy {
abstract class SkosEntityDataBuilder {
static fromTopConcept(obj: TopConcept) : EntityData {
return {
iri: obj.uri,
label: obj.label,
Expand All @@ -43,7 +44,7 @@ abstract class SkosEntityDataForHierarchyBuilder {
};
}

static fromHierarchyResult(obj: HierarchyResult) : EntityDataForHierarchy {
static fromHierarchyResult(obj: HierarchyResult) : EntityData {
return {
iri: obj.uri,
label: obj.prefLabel,
Expand All @@ -52,7 +53,7 @@ abstract class SkosEntityDataForHierarchyBuilder {
}
}

static fromPrefAndUriAndChildren(obj: PrefAndUriAndChildren, parents?: string[]) : EntityDataForHierarchy {
static fromPrefAndUriAndChildren(obj: PrefAndUriAndChildren, parents?: string[]) : EntityData {
return {
iri: obj.uri,
label: obj.prefLabel,
Expand All @@ -61,7 +62,7 @@ abstract class SkosEntityDataForHierarchyBuilder {
};
}

static fromLabelAndUriAndChildren(obj: LabelAndUriAndChildren, parents?: string[]) : EntityDataForHierarchy {
static fromLabelAndUriAndChildren(obj: LabelAndUriAndChildren, parents?: string[]) : EntityData {
return {
iri: obj.uri,
label: obj.label,
Expand Down Expand Up @@ -99,7 +100,7 @@ export class SkosApi implements HierarchyBuilder{

const rootEntities: string[] = []
const parentChildRelations: Map<string, ParentChildRelation[]> = new Map<string, ParentChildRelation[]>();
const entitiesData: Map<string, EntityDataForHierarchy> = new Map<string, EntityDataForHierarchy>();
const entitiesData: Map<string, EntityData> = new Map<string, EntityData>();
const allChildrenPresent: Set<string> = new Set<string>();
const onInitialPath: Set<string> = new Set<string>(); // only used if showSiblingsOnInit == false

Expand All @@ -108,10 +109,10 @@ export class SkosApi implements HierarchyBuilder{
.then((obj) => Object.keys(obj["broaderTransitive"]).map((key) => obj["broaderTransitive"][key]))

// stores all entities appearing in broaderTransitive
//const entities: Map<string, EntityDataForHierarchy> = new Map<string, EntityDataForHierarchy>()
//const entities: Map<string, EntityData> = new Map<string, EntityData>()

for(const node of broaderTransitive) {
const nodeData: EntityDataForHierarchy = SkosEntityDataForHierarchyBuilder.fromHierarchyResult(node);
const nodeData: EntityData = SkosEntityDataBuilder.fromHierarchyResult(node);

entitiesData.set(nodeData.iri, nodeData);
if(node.top) rootEntities.push(nodeData.iri);
Expand All @@ -120,12 +121,12 @@ export class SkosApi implements HierarchyBuilder{
}
for(const node of broaderTransitive) {
if(node.narrower != undefined) {
const children: EntityDataForHierarchy[] = [];
const children: EntityData[] = [];

for(const childNode of node.narrower) {
let childNodeData = entitiesData.get(childNode.uri);
if(childNodeData == undefined) {
childNodeData = SkosEntityDataForHierarchyBuilder.fromLabelAndUriAndChildren(childNode, [node.uri]);
childNodeData = SkosEntityDataBuilder.fromLabelAndUriAndChildren(childNode, [node.uri]);

entitiesData.set(childNodeData.iri, childNodeData);
}
Expand All @@ -151,7 +152,7 @@ export class SkosApi implements HierarchyBuilder{
}
}

function createTreeNode(entityData: EntityDataForHierarchy, cycleCheck: Set<string>): TreeNode {
function createTreeNode(entityData: EntityData, cycleCheck: Set<string>): TreeNode {
cycleCheck.add(entityData.iri); // add current entity to cycle check set

const node = new TreeNode(entityData);
Expand Down Expand Up @@ -206,15 +207,15 @@ export class SkosApi implements HierarchyBuilder{
});
}

public async loadHierarchyChildren(props: LoadHierarchyChildrenProps): Promise<EntityDataForHierarchy[]> {
public async loadHierarchyChildren(props: LoadHierarchyChildrenProps): Promise<EntityData[]> {
const {
nodeToExpand,
ontologyId
} = props;

const narrower: PrefAndUriAndChildren[] = (await this.makeCall(`/${ontologyId}/children`, {params: {uri: nodeToExpand.entityData.iri, lang: "en", format: "application/json"}}))["narrower"];

return narrower.map((obj) => SkosEntityDataForHierarchyBuilder.fromPrefAndUriAndChildren(obj, [nodeToExpand.entityData.iri]));
return narrower.map((obj) => SkosEntityDataBuilder.fromPrefAndUriAndChildren(obj, [nodeToExpand.entityData.iri]));
}

}
12 changes: 6 additions & 6 deletions src/model/interfaces/Hierarchy.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {EntityTypeName} from "../ModelTypeCheck";
import {HierarchyBuilder} from "../../api/HierarchyBuilder";
import {EntityDataForHierarchy} from "../../app/types";
import {EntityData} from "../../app/types";

export type ParentChildRelation = {
childIri: string,
childRelationToParent?: string
}

export class TreeNode {
entityData: EntityDataForHierarchy;
entityData: EntityData;
childRelationToParent?: string;
loadedChildren: TreeNode[];
expanded: boolean;
Expand All @@ -18,7 +18,7 @@ export class TreeNode {
* @param entityData
* @param childRelationToParent
*/
constructor(entityData: EntityDataForHierarchy, childRelationToParent?: string) {
constructor(entityData: EntityData, childRelationToParent?: string) {
this.entityData = entityData;
this.loadedChildren = [];
this.expanded = false;
Expand All @@ -36,7 +36,7 @@ const DEFAULT_KEEP_EXPANSION_STATE: boolean = true as const;

export class Hierarchy {
parentChildRelations: Map<string, ParentChildRelation[]>;
entitiesData: Map<string, EntityDataForHierarchy>;
entitiesData: Map<string, EntityData>;
allChildrenPresent: Set<string>;
roots: TreeNode[]; // stores the tree hierarchy
protected api: HierarchyBuilder;
Expand All @@ -51,7 +51,7 @@ export class Hierarchy {

constructor(props: {
parentChildRelations: Map<string, ParentChildRelation[]>,
entitiesData: Map<string, EntityDataForHierarchy>,
entitiesData: Map<string, EntityData>,
allChildrenPresent: Set<string>,
roots: TreeNode[],
api: HierarchyBuilder,
Expand Down Expand Up @@ -158,7 +158,7 @@ export class Hierarchy {
if(!allChildrenPresent || nodeToExpand.loadedChildren.length <= nodeParentChildRelations.length) {
if(!allChildrenPresent) {
// dynamically load children from api
const children: EntityDataForHierarchy[] = (await this.api.loadHierarchyChildren({
const children: EntityData[] = (await this.api.loadHierarchyChildren({
nodeToExpand: nodeToExpand,
entityType: this.entityType,
ontologyId: this.ontologyId,
Expand Down
2 changes: 1 addition & 1 deletion src/model/ols4-model/OLS4Thing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export abstract class OLS4Thing implements Thing {
}

getLabel(): string | undefined {
return this.properties["label"];
return Reified.fromJson<string>(this.properties["label"])[0].value;
}

// TODO: Is curie / obo_id meant?
Expand Down
Loading