Mercurial > code > home > repos > streamed-graph
comparison 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 |
comparison
equal
deleted
inserted
replaced
107:042bd3361339 | 108:5e6840229a05 |
---|---|
1 // Organize graph data into tables (column orders, etc) for the view layer. | 1 // Organize graph data into tables (column orders, etc) for the view layer. |
2 | 2 |
3 import Immutable from "immutable"; // mostly using this for the builtin equals() testing, since NamedNode(x)!=NamedNode(x) | 3 import Immutable from "immutable"; // mostly using this for the builtin equals() testing, since NamedNode(x)!=NamedNode(x) |
4 import { NamedNode, Quad, Store, Term } from "n3"; | 4 import { NamedNode, Quad, Store, Term } from "n3"; |
5 import { rdf } from "./namespaces"; | 5 import { rdf } from "./namespaces"; |
6 import { uniqueSortedTerms } from "./rdf_value"; | |
6 import { TableDesc, ViewConfig } from "./ViewConfig"; | 7 import { TableDesc, ViewConfig } from "./ViewConfig"; |
7 | 8 |
8 type UriSet = Immutable.Set<NamedNode>; | 9 type UriSet = Immutable.Set<NamedNode>; |
9 export type TypeToSubjs = Immutable.Map<NamedNode, UriSet>; | 10 export type TypeToSubjs = Immutable.Map<NamedNode, UriSet>; |
10 | |
11 // https://github.com/rdfjs/N3.js/issues/265 | |
12 (NamedNode.prototype as any).hashCode = () => 0; | |
13 | 11 |
14 interface ColumnHeader { | 12 interface ColumnHeader { |
15 rdfType: NamedNode; | 13 rdfType: NamedNode; |
16 pred: NamedNode; | 14 pred: NamedNode; |
17 } | 15 } |
16 | |
18 export interface AlignedTable { | 17 export interface AlignedTable { |
19 columnHeaders: ColumnHeader[]; | 18 columnHeaders: ColumnHeader[]; |
20 rows: (Term | null)[][]; // each row is 1 wider than columnHeaders since the 1st element is the subject for that row | 19 rows: (Term | null)[][]; // each row is 1 wider than columnHeaders since the 1st element is the subject for that row |
21 } | 20 } |
22 interface FreeStatements { | 21 |
23 statements: Quad[]; | 22 export interface PredRow { |
24 } | 23 pred: NamedNode; |
24 objs: Term[]; | |
25 } | |
26 | |
27 export interface SubjRow { | |
28 subj: NamedNode; | |
29 predRows: PredRow[]; | |
30 } | |
31 | |
32 export interface FreeStatements { | |
33 subjRows: SubjRow[]; | |
34 } | |
35 | |
25 export interface LayoutResult { | 36 export interface LayoutResult { |
26 sections: (AlignedTable | FreeStatements)[]; | 37 sections: (AlignedTable | FreeStatements)[]; |
27 } | 38 } |
28 | 39 |
29 class AlignedTableBuilder { | 40 class AlignedTableBuilder { |
98 null | 109 null |
99 ); | 110 ); |
100 return Immutable.Set(subjectsToGather); | 111 return Immutable.Set(subjectsToGather); |
101 } | 112 } |
102 | 113 |
114 function freeStatmentsSection(stmts: Quad[]): FreeStatements { | |
115 const subjs: NamedNode[] = []; | |
116 stmts.forEach((q) => { | |
117 subjs.push(q.subject as NamedNode); | |
118 }); | |
119 return { | |
120 subjRows: uniqueSortedTerms(subjs).map((subj) => { | |
121 const preds: NamedNode[] = []; | |
122 let po = Immutable.Map<NamedNode, Term[]>(); | |
123 stmts.forEach((q) => { | |
124 if (q.subject.equals(subj)) { | |
125 const p = q.predicate as NamedNode; | |
126 preds.push(p); | |
127 po = po.set(p, po.get(p, [])); | |
128 po.get(p)?.push(q.object as Term); | |
129 } | |
130 }); | |
131 | |
132 const rows: PredRow[] = []; | |
133 uniqueSortedTerms(preds).forEach((p) => { | |
134 rows.push({ pred: p, objs: uniqueSortedTerms(po.get(p, [])) }); | |
135 }); | |
136 return { subj: subj, predRows: rows }; | |
137 }), | |
138 }; | |
139 } | |
140 | |
141 // The description of how this page should look: sections, tables, etc. | |
103 export class Layout { | 142 export class Layout { |
104 constructor(public viewConfig?: ViewConfig) {} | 143 constructor(public viewConfig?: ViewConfig) {} |
105 plan(graph: Store): LayoutResult { | 144 plan(graph: Store): LayoutResult { |
106 const typesToGatherSet = findTypesNeededForTables(this.viewConfig); | 145 const typesToGatherSet = findTypesNeededForTables(this.viewConfig); |
107 | 146 |
128 ); | 167 ); |
129 const res: LayoutResult = { sections: [] }; | 168 const res: LayoutResult = { sections: [] }; |
130 if (table) { | 169 if (table) { |
131 res.sections.push(table.value()); | 170 res.sections.push(table.value()); |
132 } | 171 } |
133 res.sections.push({ statements: ungrouped }); | 172 res.sections.push(freeStatmentsSection(ungrouped)); |
134 return res; | 173 return res; |
135 } | 174 } |
136 } | 175 } |
137 | 176 |
138 // interface ISP { | 177 // interface ISP { |