diff src/layout/Layout.ts @ 116:dd3325cc023e

multiple table support in Layout
author drewp@bigasterisk.com
date Sat, 19 Mar 2022 17:23:04 -0700
parents 84551452a9c9
children 069c1f70afa5
line wrap: on
line diff
--- a/src/layout/Layout.ts	Sat Mar 19 16:37:29 2022 -0700
+++ b/src/layout/Layout.ts	Sat Mar 19 17:23:04 2022 -0700
@@ -4,7 +4,7 @@
 import { NamedNode, Quad, Store, Term } from "n3";
 import { rdf, rdfs } from "./namespaces";
 import { uniqueSortedTerms, UriPairMap } from "./rdf_value";
-import { TableDesc, ViewConfig } from "./ViewConfig";
+import { ViewConfig } from "./ViewConfig";
 
 type UriSet = Immutable.Set<NamedNode>;
 export type TypeToSubjs = Immutable.Map<NamedNode, UriSet>;
@@ -71,7 +71,9 @@
     preds = tagged.map((e) => e.val);
     return preds;
   }
-
+  gotStatements(): boolean {
+    return !this.subjSet.isEmpty();
+  }
   value(): AlignedTable {
     const subjs = uniqueSortedTerms(this.subjSet);
     const preds = this._displayedPreds();
@@ -93,32 +95,36 @@
   }
 }
 
-function findTypesNeededForTables(viewConfig?: ViewConfig): UriSet {
-  const typesToGather: NamedNode[] = [];
-  if (viewConfig) {
-    viewConfig.tables.forEach((t: TableDesc) => {
-      typesToGather.push(t.primary);
-    });
-  }
-  return Immutable.Set(typesToGather);
-}
+type SubjectTableBuilders = Immutable.Map<
+  NamedNode<string>,
+  AlignedTableBuilder[]
+>;
 
-function findSubjectsWithTypes(graph: Store, typesToGather: UriSet): UriSet {
-  const subjectsToGather: NamedNode[] = [];
-  const ft = typesToGather.toArray()[0];
+function subjectsToTablesMap(
+  graph: Store,
+  tableBuilders: AlignedTableBuilder[]
+): SubjectTableBuilders {
+  let out: SubjectTableBuilders = Immutable.Map();
   graph.forEach(
     (q: Quad) => {
-      if (q.object.equals(ft)) {
-        //typesToGather.has(q.object as NamedNode)) {
-        subjectsToGather.push(q.subject as NamedNode);
-      }
+      const s = q.subject as NamedNode;
+      tableBuilders.forEach((tb) => {
+        if (tb.rdfType.equals(q.object)) {
+          let cur = out.get(s);
+          if (cur === undefined) {
+            cur = [];
+            out = out.set(s, cur);
+          }
+          cur.push(tb);
+        }
+      });
     },
     null,
     rdf.type,
     null,
     null
   );
-  return Immutable.Set(subjectsToGather);
+  return out;
 }
 
 function freeStatmentsSection(stmts: Quad[]): FreeStatements {
@@ -151,29 +157,16 @@
 // The description of how this page should look: sections, tables, etc.
 export class Layout {
   constructor(public viewConfig?: ViewConfig) {}
-  plan(graph: Store): LayoutResult {
-    const typesToTable = findTypesNeededForTables(this.viewConfig);
-
-    const subjectsToTable = findSubjectsWithTypes(graph, typesToTable);
-    const ungrouped: Quad[] = [];
-    const vc = this.viewConfig;
-    const table =
-      vc && vc.tables.length > 0
-        ? new AlignedTableBuilder(vc.tables[0].primary) //todo multiple tables
-        : null;
-
+  _groupAllStatements(
+    graph: Store,
+    tablesWantingSubject: SubjectTableBuilders,
+    ungrouped: Quad[]
+  ) {
     graph.forEach(
       (q: Quad) => {
-        let contains = false;
-        subjectsToTable.forEach((s) => {
-          if (s.equals(q.subject)) {
-            contains = true;
-          }
-        });
-
-        // if (subjectsToTable.has(q.subject as NamedNode) && table) { // not working
-        if (contains && table) {
-          table.addQuad(q);
+        const tables = tablesWantingSubject.get(q.subject as NamedNode);
+        if (tables && tables.length) {
+          tables.forEach((t: AlignedTableBuilder) => t.addQuad(q));
         } else {
           ungrouped.push(q);
         }
@@ -183,12 +176,25 @@
       null,
       null
     );
+  }
+  plan(graph: Store): LayoutResult {
+    const ungrouped: Quad[] = [];
+
+    const tableBuilders = this.viewConfig
+      ? this.viewConfig.tables.map((t) => new AlignedTableBuilder(t.primary))
+      : [];
+
+    const tablesWantingSubject = subjectsToTablesMap(graph, tableBuilders);
+    this._groupAllStatements(graph, tablesWantingSubject, ungrouped);
     const res: LayoutResult = { sections: [] };
-    if (table) {
-      console.log("table value");
-      res.sections.push(table.value());
+    for (const t of tableBuilders) {
+      if (t.gotStatements()) {
+        res.sections.push(t.value());
+      }
     }
-    res.sections.push(freeStatmentsSection(ungrouped));
+    if (ungrouped.length) {
+      res.sections.push(freeStatmentsSection(ungrouped));
+    }
     return res;
   }
 }