From 1a102dbbf14586b661046e1b0fd25470c88707b0 Mon Sep 17 00:00:00 2001 From: Till Prochaska Date: Fri, 2 Jun 2023 15:39:45 +0200 Subject: [PATCH] Refactor: Make inheritance graph reusable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For example to display a full graph of the model on the explorer index pageā€¦ --- .../explorer/InheritanceGraph.astro | 31 +++++++++++++ .../explorer/SchemaInheritance.astro | 45 ++++--------------- docs/src/util/ftm.ts | 37 +++++---------- 3 files changed, 52 insertions(+), 61 deletions(-) create mode 100644 docs/src/components/explorer/InheritanceGraph.astro diff --git a/docs/src/components/explorer/InheritanceGraph.astro b/docs/src/components/explorer/InheritanceGraph.astro new file mode 100644 index 000000000..530fbdec0 --- /dev/null +++ b/docs/src/components/explorer/InheritanceGraph.astro @@ -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}`); +} +--- + + + graph BT + {graph.join('\n')} + diff --git a/docs/src/components/explorer/SchemaInheritance.astro b/docs/src/components/explorer/SchemaInheritance.astro index feadc001d..dcf269c4a 100644 --- a/docs/src/components/explorer/SchemaInheritance.astro +++ b/docs/src/components/explorer/SchemaInheritance.astro @@ -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)); ---

Inheritance

- - - graph BT - {graphDef.join('\n')} - +
diff --git a/docs/src/util/ftm.ts b/docs/src/util/ftm.ts index 3f38f103c..0c8dd95b4 100644 --- a/docs/src/util/ftm.ts +++ b/docs/src/util/ftm.ts @@ -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 = []; - const visited: Set = new Set(); - queue.push(schema); +export function getInheritanceEdges(schemata: Array): Edges { + const nodes = new Set(schemata); + const edges: Set = 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)]; + }); }