Mercurial > code > home > repos > streamed-graph
diff src/layout/Layout.ts @ 108:5e6840229a05
rewrite freeStatements rendering to put more planning in layout
author | drewp@bigasterisk.com |
---|---|
date | Fri, 18 Mar 2022 11:57:38 -0700 |
parents | 2468f2227d22 |
children | 3cdbbd913f1d |
line wrap: on
line diff
--- a/src/layout/Layout.ts Sun Mar 13 22:02:30 2022 -0700 +++ b/src/layout/Layout.ts Fri Mar 18 11:57:38 2022 -0700 @@ -3,25 +3,36 @@ import Immutable from "immutable"; // mostly using this for the builtin equals() testing, since NamedNode(x)!=NamedNode(x) import { NamedNode, Quad, Store, Term } from "n3"; import { rdf } from "./namespaces"; +import { uniqueSortedTerms } from "./rdf_value"; import { TableDesc, ViewConfig } from "./ViewConfig"; type UriSet = Immutable.Set<NamedNode>; export type TypeToSubjs = Immutable.Map<NamedNode, UriSet>; -// https://github.com/rdfjs/N3.js/issues/265 -(NamedNode.prototype as any).hashCode = () => 0; - interface ColumnHeader { rdfType: NamedNode; pred: NamedNode; } + export interface AlignedTable { columnHeaders: ColumnHeader[]; rows: (Term | null)[][]; // each row is 1 wider than columnHeaders since the 1st element is the subject for that row } -interface FreeStatements { - statements: Quad[]; + +export interface PredRow { + pred: NamedNode; + objs: Term[]; } + +export interface SubjRow { + subj: NamedNode; + predRows: PredRow[]; +} + +export interface FreeStatements { + subjRows: SubjRow[]; +} + export interface LayoutResult { sections: (AlignedTable | FreeStatements)[]; } @@ -100,6 +111,34 @@ return Immutable.Set(subjectsToGather); } +function freeStatmentsSection(stmts: Quad[]): FreeStatements { + const subjs: NamedNode[] = []; + stmts.forEach((q) => { + subjs.push(q.subject as NamedNode); + }); + return { + subjRows: uniqueSortedTerms(subjs).map((subj) => { + const preds: NamedNode[] = []; + let po = Immutable.Map<NamedNode, Term[]>(); + stmts.forEach((q) => { + if (q.subject.equals(subj)) { + const p = q.predicate as NamedNode; + preds.push(p); + po = po.set(p, po.get(p, [])); + po.get(p)?.push(q.object as Term); + } + }); + + const rows: PredRow[] = []; + uniqueSortedTerms(preds).forEach((p) => { + rows.push({ pred: p, objs: uniqueSortedTerms(po.get(p, [])) }); + }); + return { subj: subj, predRows: rows }; + }), + }; +} + +// The description of how this page should look: sections, tables, etc. export class Layout { constructor(public viewConfig?: ViewConfig) {} plan(graph: Store): LayoutResult { @@ -130,7 +169,7 @@ if (table) { res.sections.push(table.value()); } - res.sections.push({ statements: ungrouped }); + res.sections.push(freeStatmentsSection(ungrouped)); return res; } }