Mercurial > code > home > repos > streamed-graph
annotate src/layout/Layout.ts @ 115:84551452a9c9
rm dead code
author | drewp@bigasterisk.com |
---|---|
date | Sat, 19 Mar 2022 16:37:29 -0700 |
parents | 4b33a479dc2f |
children | dd3325cc023e |
rev | line source |
---|---|
88
ac7ad087d474
graph view rewrites and fixes for the multi-subject table
drewp@bigasterisk.com
parents:
diff
changeset
|
1 // Organize graph data into tables (column orders, etc) for the view layer. |
ac7ad087d474
graph view rewrites and fixes for the multi-subject table
drewp@bigasterisk.com
parents:
diff
changeset
|
2 |
ac7ad087d474
graph view rewrites and fixes for the multi-subject table
drewp@bigasterisk.com
parents:
diff
changeset
|
3 import Immutable from "immutable"; // mostly using this for the builtin equals() testing, since NamedNode(x)!=NamedNode(x) |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
4 import { NamedNode, Quad, Store, Term } from "n3"; |
110 | 5 import { rdf, rdfs } from "./namespaces"; |
114
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
6 import { uniqueSortedTerms, UriPairMap } from "./rdf_value"; |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
7 import { TableDesc, ViewConfig } from "./ViewConfig"; |
88
ac7ad087d474
graph view rewrites and fixes for the multi-subject table
drewp@bigasterisk.com
parents:
diff
changeset
|
8 |
ac7ad087d474
graph view rewrites and fixes for the multi-subject table
drewp@bigasterisk.com
parents:
diff
changeset
|
9 type UriSet = Immutable.Set<NamedNode>; |
ac7ad087d474
graph view rewrites and fixes for the multi-subject table
drewp@bigasterisk.com
parents:
diff
changeset
|
10 export type TypeToSubjs = Immutable.Map<NamedNode, UriSet>; |
ac7ad087d474
graph view rewrites and fixes for the multi-subject table
drewp@bigasterisk.com
parents:
diff
changeset
|
11 |
103 | 12 interface ColumnHeader { |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
13 rdfType: NamedNode; |
103 | 14 pred: NamedNode; |
15 } | |
108
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
16 |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
17 export interface AlignedTable { |
103 | 18 columnHeaders: ColumnHeader[]; |
110 | 19 rowHeaders: NamedNode[]; |
20 rows: Term[][][]; | |
103 | 21 } |
108
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
22 |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
23 export interface PredRow { |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
24 pred: NamedNode; |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
25 objs: Term[]; |
103 | 26 } |
108
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
27 |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
28 export interface SubjRow { |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
29 subj: NamedNode; |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
30 predRows: PredRow[]; |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
31 } |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
32 |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
33 export interface FreeStatements { |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
34 subjRows: SubjRow[]; |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
35 } |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
36 |
103 | 37 export interface LayoutResult { |
38 sections: (AlignedTable | FreeStatements)[]; | |
88
ac7ad087d474
graph view rewrites and fixes for the multi-subject table
drewp@bigasterisk.com
parents:
diff
changeset
|
39 } |
ac7ad087d474
graph view rewrites and fixes for the multi-subject table
drewp@bigasterisk.com
parents:
diff
changeset
|
40 |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
41 class AlignedTableBuilder { |
110 | 42 subjSet = Immutable.Set<NamedNode>(); |
43 predSet = Immutable.Set<NamedNode>(); | |
114
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
44 cell = new UriPairMap(); |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
45 constructor( |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
46 public rdfType: NamedNode /* plus join types, sort instructions */ |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
47 ) {} |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
48 |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
49 addQuad(q: Quad) { |
110 | 50 const subj = q.subject as NamedNode; |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
51 const pred = q.predicate as NamedNode; |
110 | 52 this.subjSet = this.subjSet.add(subj); |
53 this.predSet = this.predSet.add(pred); | |
114
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
54 this.cell.add(subj, pred, q.object); |
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
55 } |
110 | 56 |
114
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
57 _displayedPreds(): NamedNode[] { |
110 | 58 let preds = uniqueSortedTerms(this.predSet); |
114
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
59 preds = preds.filter((p) => { |
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
60 return !p.equals(rdf.type); |
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
61 }); |
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
62 const tagged = preds.map((p, i) => { |
110 | 63 if (p.equals(rdfs.label)) { |
114
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
64 i = -1; |
110 | 65 } |
114
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
66 return { sort: i, val: p }; |
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
67 }); |
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
68 tagged.sort((a, b) => { |
110 | 69 return a.sort - b.sort; |
70 }); | |
114
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
71 preds = tagged.map((e) => e.val); |
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
72 return preds; |
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
73 } |
110 | 74 |
114
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
75 value(): AlignedTable { |
110 | 76 const subjs = uniqueSortedTerms(this.subjSet); |
114
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
77 const preds = this._displayedPreds(); |
110 | 78 const outputGrid: Term[][][] = []; |
79 for (let subj of subjs) { | |
80 const row: Term[][] = []; | |
81 preds.forEach((pred) => { | |
114
4b33a479dc2f
fix layout test to match new layout return types. clean up UriPairMap
drewp@bigasterisk.com
parents:
110
diff
changeset
|
82 const objs = this.cell.get(subj, pred); |
110 | 83 const uniq = uniqueSortedTerms(objs); |
84 row.push(uniq); | |
85 }); | |
86 outputGrid.push(row); | |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
87 } |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
88 |
110 | 89 const headers = preds.map((pred) => { |
90 return { rdfType: this.rdfType, pred: pred }; | |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
91 }); |
110 | 92 return { columnHeaders: headers, rowHeaders: subjs, rows: outputGrid }; |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
93 } |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
94 } |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
95 |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
96 function findTypesNeededForTables(viewConfig?: ViewConfig): UriSet { |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
97 const typesToGather: NamedNode[] = []; |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
98 if (viewConfig) { |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
99 viewConfig.tables.forEach((t: TableDesc) => { |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
100 typesToGather.push(t.primary); |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
101 }); |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
102 } |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
103 return Immutable.Set(typesToGather); |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
104 } |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
105 |
110 | 106 function findSubjectsWithTypes(graph: Store, typesToGather: UriSet): UriSet { |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
107 const subjectsToGather: NamedNode[] = []; |
110 | 108 const ft = typesToGather.toArray()[0]; |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
109 graph.forEach( |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
110 (q: Quad) => { |
110 | 111 if (q.object.equals(ft)) { |
112 //typesToGather.has(q.object as NamedNode)) { | |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
113 subjectsToGather.push(q.subject as NamedNode); |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
114 } |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
115 }, |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
116 null, |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
117 rdf.type, |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
118 null, |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
119 null |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
120 ); |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
121 return Immutable.Set(subjectsToGather); |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
122 } |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
123 |
108
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
124 function freeStatmentsSection(stmts: Quad[]): FreeStatements { |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
125 const subjs: NamedNode[] = []; |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
126 stmts.forEach((q) => { |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
127 subjs.push(q.subject as NamedNode); |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
128 }); |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
129 return { |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
130 subjRows: uniqueSortedTerms(subjs).map((subj) => { |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
131 const preds: NamedNode[] = []; |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
132 let po = Immutable.Map<NamedNode, Term[]>(); |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
133 stmts.forEach((q) => { |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
134 if (q.subject.equals(subj)) { |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
135 const p = q.predicate as NamedNode; |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
136 preds.push(p); |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
137 po = po.set(p, po.get(p, [])); |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
138 po.get(p)?.push(q.object as Term); |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
139 } |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
140 }); |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
141 |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
142 const rows: PredRow[] = []; |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
143 uniqueSortedTerms(preds).forEach((p) => { |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
144 rows.push({ pred: p, objs: uniqueSortedTerms(po.get(p, [])) }); |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
145 }); |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
146 return { subj: subj, predRows: rows }; |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
147 }), |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
148 }; |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
149 } |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
150 |
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
151 // The description of how this page should look: sections, tables, etc. |
103 | 152 export class Layout { |
153 constructor(public viewConfig?: ViewConfig) {} | |
154 plan(graph: Store): LayoutResult { | |
110 | 155 const typesToTable = findTypesNeededForTables(this.viewConfig); |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
156 |
110 | 157 const subjectsToTable = findSubjectsWithTypes(graph, typesToTable); |
103 | 158 const ungrouped: Quad[] = []; |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
159 const vc = this.viewConfig; |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
160 const table = |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
161 vc && vc.tables.length > 0 |
110 | 162 ? new AlignedTableBuilder(vc.tables[0].primary) //todo multiple tables |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
163 : null; |
88
ac7ad087d474
graph view rewrites and fixes for the multi-subject table
drewp@bigasterisk.com
parents:
diff
changeset
|
164 |
103 | 165 graph.forEach( |
166 (q: Quad) => { | |
110 | 167 let contains = false; |
168 subjectsToTable.forEach((s) => { | |
169 if (s.equals(q.subject)) { | |
170 contains = true; | |
171 } | |
172 }); | |
173 | |
174 // if (subjectsToTable.has(q.subject as NamedNode) && table) { // not working | |
175 if (contains && table) { | |
176 table.addQuad(q); | |
177 } else { | |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
178 ungrouped.push(q); |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
179 } |
103 | 180 }, |
181 null, | |
182 null, | |
183 null, | |
184 null | |
185 ); | |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
186 const res: LayoutResult = { sections: [] }; |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
187 if (table) { |
110 | 188 console.log("table value"); |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
189 res.sections.push(table.value()); |
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
190 } |
108
5e6840229a05
rewrite freeStatements rendering to put more planning in layout
drewp@bigasterisk.com
parents:
106
diff
changeset
|
191 res.sections.push(freeStatmentsSection(ungrouped)); |
104
1aea03d306af
WIP Layout. tests are passing but they're a little wrong
drewp@bigasterisk.com
parents:
103
diff
changeset
|
192 return res; |
103 | 193 } |
88
ac7ad087d474
graph view rewrites and fixes for the multi-subject table
drewp@bigasterisk.com
parents:
diff
changeset
|
194 } |