UNPKG

graph-explorer

Version:

Graph Explorer can be used to explore and RDF graphs in SPARQL endpoints or on the web.

177 lines (162 loc) 5.41 kB
import { cloneDeep, keyBy, map, each } from "lodash"; import { DataProvider, LinkElementsParams, FilterParams } from "../provider"; import { Dictionary, ClassModel, LinkType, ElementModel, LinkModel, LinkCount, ElementIri, ElementTypeIri, LinkTypeIri, } from "../model"; export class DemoDataProvider implements DataProvider { constructor( private allClasses: ClassModel[], private allLinkTypes: LinkType[], private allElements: Dictionary<ElementModel>, private allLinks: LinkModel[] ) {} private simulateNetwork<T>(result: T) { const MEAN_DELAY = 200; const cloned = cloneDeep(result); // simulate exponential distribution const delay = -Math.log(Math.random()) * MEAN_DELAY; return new Promise<T>((resolve) => { setTimeout(() => resolve(cloned), delay); }); } classTree() { return this.simulateNetwork(this.allClasses); } classInfo(params: { classIds: ElementTypeIri[] }) { const classIds = params.classIds || []; return this.simulateNetwork( this.allClasses.filter((cl) => classIds.indexOf(cl.id)) ); } linkTypes() { return this.simulateNetwork(this.allLinkTypes); } linkTypesInfo(params: { linkTypeIds: LinkTypeIri[] }): Promise<LinkType[]> { const types = keyBy(params.linkTypeIds); const linkTypes = this.allLinkTypes.filter((type) => types[type.id]); return this.simulateNetwork(linkTypes); } elementInfo(params: { elementIds: ElementIri[]; }): Promise<Dictionary<ElementModel>> { const elements = params.elementIds .map((elementId) => this.allElements[elementId]) .filter((element) => element !== undefined); return this.simulateNetwork(keyBy(elements, (element) => element.id)); } linksInfo(params: { elementIds: ElementIri[]; linkTypeIds: LinkTypeIri[] }) { const nodes = keyBy(params.elementIds); const types = keyBy(params.linkTypeIds); const links = this.allLinks.filter( (link) => types[link.linkTypeId] && nodes[link.sourceId] && nodes[link.targetId] ); return this.simulateNetwork(links); } linkTypesOf(params: { elementId: ElementIri }) { const counts: Dictionary<LinkCount> = {}; for (const link of this.allLinks) { if ( link.sourceId === params.elementId || link.targetId === params.elementId ) { const linkCount = counts[link.linkTypeId]; const isSource = link.sourceId === params.elementId; if (linkCount) { if (isSource) { linkCount.outCount++; } else { linkCount.inCount++; } } else { counts[link.linkTypeId] = isSource ? { id: link.linkTypeId, inCount: 0, outCount: 1 } : { id: link.linkTypeId, inCount: 1, outCount: 0 }; } } } return this.simulateNetwork(map(counts)); } linkElements(params: LinkElementsParams): Promise<Dictionary<ElementModel>> { // for sparql we have rich filtering features and we just reuse filter. return this.filter({ refElementId: params.elementId, refElementLinkId: params.linkId, linkDirection: params.direction, limit: params.limit, offset: params.offset, languageCode: "", }); } filter(params: FilterParams): Promise<Dictionary<ElementModel>> { if (params.limit === undefined) { params.limit = 100; } if (params.offset > 0) { return Promise.resolve({}); } let filtered: Dictionary<ElementModel> = {}; if (params.elementTypeId) { each(this.allElements, (element) => { if (element.types.indexOf(params.elementTypeId) >= 0) { filtered[element.id] = element; } }); } else if (params.refElementId) { const filteredLinks = params.refElementLinkId ? this.allLinks.filter( (link) => link.linkTypeId === params.refElementLinkId ) : this.allLinks; const nodeId = params.refElementId; for (const link of filteredLinks) { let linkedElementId: string; if (link.sourceId === nodeId && params.linkDirection !== "in") { linkedElementId = link.targetId; } else if (link.targetId === nodeId && params.linkDirection !== "out") { linkedElementId = link.sourceId; } if (linkedElementId !== undefined) { const linkedElement = this.allElements[linkedElementId]; if (linkedElement) { filtered[linkedElement.id] = linkedElement; } } } } else if (params.text) { filtered = this.allElements; // filtering by text is done below } else { return Promise.reject( new Error("This type of filter is not implemented") ); } if (params.text) { const filteredByText: Dictionary<ElementModel> = {}; const text = params.text.toLowerCase(); each(filtered, (element) => { let found = false; if (element.id.toLowerCase().indexOf(text) >= 0) { found = true; } else { found = element.label.values.some( (label) => label.value.toLowerCase().indexOf(text) >= 0 ); } if (found) { filteredByText[element.id] = element; } }); return this.simulateNetwork(filteredByText); } else { return this.simulateNetwork(filtered); } } }