diff --git a/hugo/assets/scripts/domainmodel/d3tree.tsx b/hugo/assets/scripts/domainmodel/d3tree.tsx
index ade317a3..bbc7e442 100644
--- a/hugo/assets/scripts/domainmodel/d3tree.tsx
+++ b/hugo/assets/scripts/domainmodel/d3tree.tsx
@@ -22,22 +22,22 @@ export default function D3Tree({ data }: TreeProps) {
useEffect(() => {
if (!svgRef.current) return;
- // get the size of the tree
- const getChildSize = (child: TreeNode): number => {
+ // get the leaf nodes of the tree
+ const getLeafNodes = (child: TreeNode): number => {
if (!child.children) return 1;
- let amount = child.children.length;
-
- // fastest way to iterate over an array
- const length = child.children.length;
- for (let i = 0; i < length; i++) {
- amount += getChildSize(child.children[i]);
- }
- return amount;
+ if(child.children.length === 0) return 1;
+ return child.children.map(getLeafNodes).reduce((a, b) => a + b);
};
- const size = getChildSize(data);
- const height = size * 20;
- const width = size * 18;
+ // get the longest path in the tree
+ const getLongestPath = (child: TreeNode): number => {
+ if (!child.children) return 1;
+ if(child.children.length === 0) return 1;
+ return 1 + Math.max(...child.children.map(getLongestPath));
+ };
+
+ const height = getLeafNodes(data) * 60;
+ const width = getLongestPath(data) * 120;
const svg = d3.select(svgRef.current);
svg.selectAll('*').remove();
@@ -51,10 +51,10 @@ export default function D3Tree({ data }: TreeProps) {
g.attr('transform', event.transform);
});
- svg.call(zoom, d3.zoomIdentity.translate(50, 50));
-
// zoom to show the whole tree
- svg.call(zoom.transform, d3.zoomIdentity.translate(width / size * 3, height / size * 2).scale(3 / (0.1 * size)));
+ svg.call(zoom.transform, d3.zoomIdentity.translate(width / 20, height / 30).scale(0.5));
+
+ svg.call(zoom, d3.zoomIdentity.translate(50, 50));
// draw the links
g.selectAll('.link')
diff --git a/hugo/assets/scripts/domainmodel/domainmodel-tools.ts b/hugo/assets/scripts/domainmodel/domainmodel-tools.ts
index 30052e19..c174eb44 100644
--- a/hugo/assets/scripts/domainmodel/domainmodel-tools.ts
+++ b/hugo/assets/scripts/domainmodel/domainmodel-tools.ts
@@ -3,17 +3,8 @@ import { AstNode } from "../langium-utils/langium-ast";
import { TreeNode } from "./d3tree";
-export function getTreeNode(ast: AstNode): TreeNode {
+export function getMainTreeNode(ast: AstNode): TreeNode {
const astNode = getDomainModelAst(ast as DomainModelAstNode);
-
- // create a TreeNode from all PackageDeclarations in the ast
- const packageDeclarations = astNode.packageDeclarations.map(p => {
- return {
- ...p,
- children: p.elements
- } as TreeNode;
- });
-
// create a TreeNode a DataType
const getDataTypeTreeNode = (d: DataType): TreeNode => {
return {
@@ -22,6 +13,24 @@ export function getTreeNode(ast: AstNode): TreeNode {
}
}
+ // create a TreeNode from a PackageDeclaration
+ const getPackageDeclarationTreeNode = (p: PackageDeclaration): TreeNode => {
+ return {
+ ...p,
+ children: p.elements.map(e => getTreeNode(e))
+ }
+ }
+
+ // create a TreeNode from any DomainModelElement
+ const getTreeNode = (e: DomainModelElement): TreeNode => {
+ switch(e.$type) {
+ case 'DataType': return getDataTypeTreeNode(e as DataType);
+ case 'Entity': return getEntityTreeNode(e as Entity);
+ case 'PackageDeclaration': return getPackageDeclarationTreeNode(e as PackageDeclaration);
+ default: return e as TreeNode;
+ }
+ }
+
// create a TreeNode from an Entity
const getEntityTreeNode = (entity: Entity): TreeNode => {
@@ -58,16 +67,28 @@ export function getTreeNode(ast: AstNode): TreeNode {
// create a TreeNode from all Entities in the ast
const entities = astNode.entities.flatMap(e => getEntityTreeNode(e));
-
// create a TreeNode from all DataTypes in the ast
const datatypes = astNode.dataTypes.map(d => getDataTypeTreeNode(d));
-
- // combine them all to a single TreeNode
- const children: TreeNode[] = [
- {name: 'DataTypes', $type: 'DataType', children: datatypes},
- {name: 'Entities', $type: 'Entity', children: entities},
- {name: 'Packages', $type: 'PackageDeclaration', children: packageDeclarations},
- ];
+ // create a TreeNode from all PackageDeclarations in the ast
+ const packageDeclarations = astNode.packageDeclarations.map(p => getPackageDeclarationTreeNode(p));
+
+ const children: TreeNode[] = [];
+
+ // if datatypes exist, add them to the children
+ if(datatypes.length > 0) {
+ children.push({ name: 'DataTypes', $type: 'DataType', children: datatypes });
+ }
+
+ // if entities exist, add them to the children
+ if(entities.length > 0) {
+ children.push({name: 'Entities', $type: 'Entity', children: entities});
+ }
+
+ // if packageDeclarations exist, add them to the children
+ if(packageDeclarations.length > 0) {
+ children.push({name: 'Packages', $type: 'PackageDeclaration', children: packageDeclarations});
+ }
+
// return the root TreeNode
return {
@@ -103,7 +124,7 @@ export interface DomainModelAstNode extends AstNode, DomainModelElement {
export interface PackageDeclaration extends DomainModelElement {
$type: 'PackageDeclaration';
- elements: DataType[];
+ elements: DomainModelElementType[];
}
export interface Entity extends DomainModelElement {
diff --git a/hugo/assets/scripts/domainmodel/domainmodel.tsx b/hugo/assets/scripts/domainmodel/domainmodel.tsx
index 0a3e3d89..c07a4ab4 100644
--- a/hugo/assets/scripts/domainmodel/domainmodel.tsx
+++ b/hugo/assets/scripts/domainmodel/domainmodel.tsx
@@ -3,7 +3,8 @@ import { buildWorkerDefinition } from "monaco-editor-workers";
import React from "react";
import { createRoot } from "react-dom/client";
import { Diagnostic, DocumentChangeResponse, LangiumAST } from "../langium-utils/langium-ast";
-import { DomainModelAstNode, example, getTreeNode, syntaxHighlighting } from "./domainmodel-tools";
+import { DomainModelAstNode, example, getMainTreeNode, syntaxHighlighting } from "./domainmodel-tools";
+
import D3Tree from "./d3tree";
addMonacoStyles('monaco-styles-helper');
@@ -85,7 +86,7 @@ class App extends React.Component<{}, AppState> {
// if there are no errors, render the tree
if (this.state.diagnostics == null || this.state.diagnostics.filter((i) => i.severity === 1).length == 0) {
return (
-
+
);
}
diff --git a/package-lock.json b/package-lock.json
index c89c8563..155d8ee0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,6 +18,7 @@
}
},
"core": {
+ "name": "langium-website-core",
"version": "1.0.0",
"license": "MIT",
"dependencies": {