Mercurial > code > home > repos > streamed-graph
view src/Layout.ts @ 103:f12feced00ce
WIP rewriting Layout
author | drewp@bigasterisk.com |
---|---|
date | Sat, 12 Mar 2022 00:42:00 -0800 |
parents | src/tabulate.ts@26c55d5d5202 |
children | 1aea03d306af |
line wrap: on
line source
// Organize graph data into tables (column orders, etc) for the view layer. import Immutable from "immutable"; // mostly using this for the builtin equals() testing, since NamedNode(x)!=NamedNode(x) import { DataFactory, NamedNode, Quad, Quad_Object, Store, Term, Util, } from "n3"; import { ViewConfig } from "./ViewConfig"; const { namedNode } = DataFactory; // // import ns from 'n3/src/IRIs'; // // const { rdf } = ns; type UriSet = Immutable.Set<NamedNode>; export type TypeToSubjs = Immutable.Map<NamedNode, UriSet>; // https://github.com/rdfjs/N3.js/issues/265 if ((NamedNode.prototype as any).hashCode === undefined) { (NamedNode.prototype as any).hashCode = () => 0; } interface ColumnHeader { rdfType?: NamedNode; // could be more than one column that introduces an rdf:type for a join pred: NamedNode; } interface AlignedTable { columnHeaders: ColumnHeader[]; rows: (Term | null)[][]; // each row is 1 wider than columnHeaders since the 1st element is the subject for that row } interface FreeStatements { statements: Quad[]; } export interface LayoutResult { sections: (AlignedTable | FreeStatements)[]; } export class Layout { constructor(public viewConfig?: ViewConfig) {} plan(graph: Store): LayoutResult { const ungrouped: Quad[] = []; graph.forEach( (q: Quad) => { ungrouped.push(q); }, null, null, null, null ); return { sections: [{ statements: ungrouped }] }; } } // function getType(graph: Store, subj: NamedNode): NamedNode | null { // let subjType: NamedNode | null = null; // graph.forObjects( // (o: Quad_Object) => { // subjType = o as NamedNode; // }, // subj, // rdf.type, // null // ); // return subjType; // } // // When there are multiple types, an arbitrary one is used. // export function groupByRdfType( // graph: Store // ): { // byType: TypeToSubjs; // typesPresent: NamedNode[]; // untypedSubjs: NamedNode[]; // } { // let byType: TypeToSubjs = Immutable.Map(); // let untyped: UriSet = Immutable.Set(); // subjs // const internSubjs = new Map<string, NamedNode>(); // graph.forEach( // (q) => { // if (!Util.isNamedNode(q.subject)) { // throw new Error("unsupported " + q.subject.value); // } // const subj = q.subject as NamedNode; // const subjType = getType(graph, subj); // if (subjType !== null) { // // (subj, rdf:type, subjType) in graph // const oldKeys = Array.from(byType.keys()); // const oldVal = byType.get(subjType, Immutable.Set<NamedNode>()); // const newVal = oldVal.add(subj); // byType = byType.set(subjType, newVal); // } else { // untyped = untyped.add(subj); // } // }, // null, // null, // null, // null // ); // const typesPresent = Array.from(byType.keys()); // typesPresent.sort(); // const untypedSubjs = Array.from(untyped.values()); // untypedSubjs.sort(); // return { // byType: byType, // typesPresent: typesPresent, // untypedSubjs: untypedSubjs, // }; // } // export function predsForSubj(graph: Store, typeUri: NamedNode): NamedNode[] { // const predsSet: Set<NamedNode> = new Set(); // graph.forEach( // (q: Quad) => { // predsSet.add(q.predicate as NamedNode); // }, // typeUri, // null, // null, // null // ); // const preds = Array.from(predsSet.values()); // preds.sort(); // return preds; // } // interface ISP { // subj: NamedNode; // pred: NamedNode; // } // const SP = Immutable.Record<ISP>({ // subj: new NamedNode(""), // pred: new NamedNode(""), // }); // // One table of rows with a common rdf:type. // export class MultiSubjsTypeBlockLayout { // subjs: NamedNode[]; // preds: NamedNode[]; // graphCells: Immutable.Map<ISP, Immutable.Set<Term>>; // constructor(graph: Store, byType: TypeToSubjs, table: TableDesc) { // const subjSet = byType.get(table.primary); // this.subjs = subjSet ? Array.from(subjSet) : []; // this.subjs.sort(); // let preds = Immutable.Set<NamedNode>(); // this.graphCells = Immutable.Map<ISP, Immutable.Set<Term>>().withMutations( // (mutGraphCells) => { // this.subjs.forEach((subj: NamedNode) => { // graph.forEach( // (q: Quad) => { // if (!Util.isNamedNode(q.predicate)) { // throw new Error(); // } // const pred = q.predicate as NamedNode; // if (pred.equals(rdf.type)) { // // the whole block is labeled with the type // return; // } // preds = preds.add(pred); // const cellKey = this.makeCellKey(subj, pred); // mutGraphCells.set( // cellKey, // mutGraphCells.get(cellKey, Immutable.Set<Term>()).add(q.object) // ); // }, // subj, // null, // null, // null // ); // }); // } // ); // this.preds = Array.from(preds); // this.preds.splice(this.preds.indexOf(rdf.type), 1); // // also pull out label, which should be used on 1st column // this.preds.sort(); // } // makeCellKey(subj: NamedNode, pred: NamedNode): ISP { // return SP({ // subj: subj, // pred: pred, // }); // } // }