Skip to content

Commit

Permalink
Refactor: Make inheritance graph reusable
Browse files Browse the repository at this point in the history
For example to display a full graph of the model on the explorer index page…
  • Loading branch information
tillprochaska committed Jun 2, 2023
1 parent c363bd6 commit 1a102db
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 61 deletions.
31 changes: 31 additions & 0 deletions docs/src/components/explorer/InheritanceGraph.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
import Mermaid from '@components/common/Mermaid.astro';
import { getInheritanceEdges } from '@util/ftm';
import { schemaLink } from '@util/links';
const { schemata, activeSchema } = Astro.props;
const base = Astro.site?.pathname;
const edges = getInheritanceEdges(schemata);
const graph = [];
for (const schema of schemata) {
graph.push(`${schema.name}(${schema.label})`);
if (schema !== activeSchema) {
graph.push(`click ${schema.name} "${schemaLink(base, schema)}"`);
}
}
if (activeSchema) {
graph.push(`class ${activeSchema.name} node-primary`);
}
for (const [child, parent] of edges) {
graph.push(`${child.name}-->${parent.name}`);
}
---

<Mermaid>
graph BT
{graph.join('\n')}
</Mermaid>
45 changes: 9 additions & 36 deletions docs/src/components/explorer/SchemaInheritance.astro
Original file line number Diff line number Diff line change
@@ -1,48 +1,21 @@
---
import { RichContent } from 'astro-theme-docs/components';
import SchemaLink from '@components/explorer/SchemaLink.astro';
import Mermaid from '@components/common/Mermaid.astro';
import { getInheritanceAdjacency } from '@util/ftm';
import { schemaLink } from '@util/links';
import InheritanceGraph from '@components/explorer/InheritanceGraph.astro';
const { schema, ...rest } = Astro.props;
const base = Astro.site?.pathname;
const parents = schema.getExtends();
const edges = getInheritanceAdjacency(schema);
const nodes = new Set();
nodes.add(schema);
for (const [child, parent] of edges) {
nodes.add(child);
nodes.add(parent);
}
const graphDef = [];
for (const node of nodes) {
graphDef.push(`${node.name}(${node.label})`);
if (node !== schema) {
graphDef.push(`click ${node.name} "${schemaLink(base, node)}"`);
}
}
graphDef.push(`class ${schema.name} node-primary`);
for (const [child, parent] of edges) {
graphDef.push(`${child.name}-->${parent.name}`);
}
const parents = schema.getParents();
const children = schema
.getChildren()
.filter((child) => child.getExtends().includes(schema));
---

<div class="schema-inheritance" {...rest}>
<RichContent>
<h2 class="beta">Inheritance</h2>

<Mermaid>
graph BT
{graphDef.join('\n')}
</Mermaid>
<InheritanceGraph
schemata={[schema, ...parents, ...children]}
activeSchema={schema}
/>
</RichContent>
</div>
37 changes: 12 additions & 25 deletions docs/src/util/ftm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,22 @@ import { Model, Schema } from '@alephdata/followthemoney';

export const model = new Model(defaultModel);

export function getInheritanceAdjacency(
schema: Schema
): Array<[Schema, Schema]> {
const tuples: Array<[Schema, Schema]> = [];
type Edges = Array<[Schema, Schema]>;

// Get all parent schemata
const queue: Array<Schema> = [];
const visited: Set<Schema> = new Set();
queue.push(schema);
export function getInheritanceEdges(schemata: Array<Schema>): Edges {
const nodes = new Set(schemata);
const edges: Set<string> = new Set();

while (queue.length > 0) {
const child = queue.shift();
visited.add(child);

for (const parent of child.getExtends()) {
tuples.push([child, parent]);

if (!visited.has(parent) && !queue.includes(parent)) {
queue.push(parent);
for (const node of nodes) {
for (const parent of node.getExtends()) {
if (nodes.has(parent)) {
edges.add([node.name, parent.name].join(':'));
}
}
}

// Get first level child schemata
for (const child of model.getSchemata()) {
if (child.getExtends().includes(schema)) {
tuples.push([child, schema]);
}
}

return tuples;
return Array.from(edges).map((edge) => {
const [child, parent] = edge.split(':');
return [model.getSchema(child), model.getSchema(parent)];
});
}

0 comments on commit 1a102db

Please sign in to comment.