# HG changeset patch # User drewp@bigasterisk.com # Date 1647764255 25200 # Node ID 8715633f521397be90b3d2892689312f8c5b9fba # Parent c2923b20bf5c2035882001e5a8736ca7ca65ad71 fancier column sorting to bring preds from the same type together diff -r c2923b20bf5c -r 8715633f5213 src/layout/Layout.test.ts --- 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: . + @prefix rdfs: . + @prefix : . + + <> a :View; :table [ :primaryType :T1; :joinType :T2, :T3 ] . + `); + const layout = new Layout(vc); + const lr = layout.plan( + await n3Graph(` + @prefix : . + :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 () => {}); }); diff -r c2923b20bf5c -r 8715633f5213 src/layout/Layout.ts --- 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 }; } diff -r c2923b20bf5c -r 8715633f5213 src/layout/rdf_value.test.ts --- 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 = 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");