changeset 119:8715633f5213

fancier column sorting to bring preds from the same type together
author drewp@bigasterisk.com
date Sun, 20 Mar 2022 01:17:35 -0700
parents c2923b20bf5c
children a7519d92dbc6
files src/layout/Layout.test.ts src/layout/Layout.ts src/layout/rdf_value.test.ts
diffstat 3 files changed, 75 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/layout/Layout.test.ts	Sun Mar 20 00:54:19 2022 -0700
+++ b/src/layout/Layout.test.ts	Sun Mar 20 01:17:35 2022 -0700
@@ -155,7 +155,6 @@
 
         <> a :View; :table [ :primaryType :T1; :joinType :T2 ] .
       `);
-      vc.graph.forEach((q) => console.log("vc", q), null, null, null, null);
       const layout = new Layout(vc);
       const lr = layout.plan(
         await n3Graph(`
@@ -178,6 +177,32 @@
         [[], [EX("big")]],
       ]);
     });
+    it("groups columns by type", async()=>{
+      const vc = new ViewConfig();
+      await vc.readFromGraph(`
+        @prefix ex: <http://example.com/> .
+        @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+        @prefix : <http://example.com/> .
+
+        <> a :View; :table [ :primaryType :T1; :joinType :T2, :T3 ] .
+      `);
+      const layout = new Layout(vc);
+      const lr = layout.plan(
+        await n3Graph(`
+        @prefix : <http://example.com/> .
+        :g1 {
+          :a a :T1; :p1 :red; :p3 :green .
+          :b a :T2; :p2 :blue .
+        }
+      `)
+      );
+      const section0 = lr.sections[0] as AlignedTable;
+      expect(section0.columnHeaders).toEqual([
+        { rdfTypes: [EX("T1")], pred: EX("p1") },
+        { rdfTypes: [EX("T1")], pred: EX("p3") },
+        { rdfTypes: [EX("T2")], pred: EX("p2") },
+      ]);
+    })
   });
   it.skip("makes a table out of ungrouped triples with the same type", async () => {});
 });
--- a/src/layout/Layout.ts	Sun Mar 20 00:54:19 2022 -0700
+++ b/src/layout/Layout.ts	Sun Mar 20 01:17:35 2022 -0700
@@ -90,13 +90,36 @@
       return !p.equals(rdf.type);
     });
     const tagged = preds.map((p, i) => {
-      if (p.equals(rdfs.label)) {
-        i = -1;
-      }
-      return { sort: i, val: p };
+      const types = this.typesSeenWithPred(p);
+      return {
+        sort: [
+          p.equals(rdfs.label) ? 0 : 1,
+          types.length == 1 ? 0 : 1,
+          types[0].equals(this.primaryType) ? 0 : 1,
+          types[0],
+          i,
+        ],
+        val: p,
+      };
     });
     tagged.sort((a, b) => {
-      return a.sort - b.sort;
+      let ib = 0;
+      for (let k1 of a.sort) {
+        const k2 = b.sort[ib];
+        if (!Immutable.is(k1, k2)) {
+          if (typeof k1 === "number") {
+            if (typeof k2 === "number") {
+              return k1 - k2;
+            } else {
+              throw new Error(`${k1} vs ${k2}`);
+            }
+          } else {
+            return (k1 as NamedNode).id.localeCompare((k2 as NamedNode).id);
+          }
+        }
+        ib++;
+      }
+      return 0;
     });
     preds = tagged.map((e) => e.val);
     return preds;
@@ -106,6 +129,17 @@
     return !this.subjSet.isEmpty();
   }
 
+  private typesSeenWithPred(pred: NamedNode): NamedNode[] {
+    const subs = this.subjsSeenWithPred.get(pred, []);
+    const types: NamedNode[] = [];
+    subs.forEach((s) => {
+      this.typesSeenForSubj.get(s, []).forEach((t) => {
+        types.push(t);
+      });
+    });
+    return uniqueSortedTerms(types);
+  }
+
   value(): AlignedTable {
     const subjs = uniqueSortedTerms(this.subjSet);
     const preds = this._displayedPreds();
@@ -121,15 +155,7 @@
     }
 
     const headers: ColumnHeader[] = preds.map((pred) => {
-      const subs = this.subjsSeenWithPred.get(pred, []);
-      const types: NamedNode[] = [];
-      subs.forEach((s) => {
-        this.typesSeenForSubj.get(s, []).forEach((t) => {
-          types.push(t);
-        });
-      });
-
-      return { rdfTypes: uniqueSortedTerms(types), pred: pred };
+      return { rdfTypes: this.typesSeenWithPred(pred), pred: pred };
     });
     return { columnHeaders: headers, rowHeaders: subjs, rows: outputGrid };
   }
--- a/src/layout/rdf_value.test.ts	Sun Mar 20 00:54:19 2022 -0700
+++ b/src/layout/rdf_value.test.ts	Sun Mar 20 01:17:35 2022 -0700
@@ -3,6 +3,7 @@
 import { EX } from "./namespaces";
 import { uniqueSortedTerms } from "./rdf_value";
 const { namedNode, literal } = DataFactory;
+
 describe("Immutable.Set", () => {
   it("contains", () => {
     const s = Immutable.Set([EX("e1")]);
@@ -11,6 +12,14 @@
   });
 });
 
+describe("Immutable.Map", () => {
+  it("gets", () => {
+    let m: Immutable.Map<NamedNode, number> = Immutable.Map();
+    m = m.set(EX("e1"), 5);
+    expect(m.get(EX("e1"))).toEqual(5);
+  });
+});
+
 const uri1 = namedNode("http://example.com/1");
 const uri2 = namedNode("http://example.com/2");
 const lit1 = literal("lit1");