Hello,
I’ve been trying to make it where the Diagram’s layout is a TableLayout using the TableLayout extension, I keep receiving the same error while starting from the GoJS Angular basic on GitHub.
The code does work when I don’t use TableLayout, when I add TableLayout as a layout
const dia = $(go.Diagram, {
layout: $(TableLayout),
It gives me the error below, specifically pointing to $(TableLayout)
.
I have tried to do change parts to how it is done in JS where I add the ID of <gojs-diagram/>
when creating the Diagram, but this still results in the same error.
My diagram inside visualisation.component.html looks like this:
<div id="canvas-diagram">
<gojs-diagram #diagram [initDiagram]="initDiagram" [nodeDataArray]="state.diagramNodeData"
[linkDataArray]="state.diagramLinkData"
[divClassName]="diagramDivClassName" [modelData]="state.diagramModelData"
[skipsDiagramUpdate]="state.skipsDiagramUpdate"
(modelChange)="diagramModelChange($event)"></gojs-diagram>
</div>
Part of my visualisation.component.ts looks like this:
import { ChangeDetectorRef, Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import * as go from 'gojs';
import { TableLayout } from 'gojs/extensionsTS/TableLayout';
import { DataSyncService, DiagramComponent, PaletteComponent } from 'gojs-angular';
import produce from 'immer';
@Component({
selector: 'app-visualisation',
templateUrl: './visualisation.component.html',
styleUrls: ['./visualisation.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class VisualisationComponent implements OnInit {
@ViewChild('diagram', { static: true}) public diagramComponent: DiagramComponent;
observedDiagram = null;
selectedNodeData: go.ObjectData = null;
public state = {
diagramNodeData: [],
diagramLinkData: [],
diagramModelData: { prop: 'value' },
skipsDiagramUpdate: false,
selectedNodeData: null,
};
public diagramDivClassName = 'diagramDiv';
public initDiagram(): go.Diagram {
const $ = go.GraphObject.make;
const dia = $(go.Diagram, {
layout: $(TableLayout),
mouseDragOver: e => { e.diagram.currentCursor = 'not-allowed'; },
mouseDrop: e => { e.diagram.currentTool.doCancel(); },
'animationManager.isInitial': false,
'undoManager.isEnabled': true,
'clickCreatingTool.archetypeNodeData': { text: 'new node' },
'draggingTool.isGridSnapEnabled': true,
grid: $(go.Panel, 'Grid',
{ gridCellSize: new go.Size(88, 88) },
$(go.Shape, 'LineH', { stroke: 'lightgray'}),
$(go.Shape, 'LineV', { stroke: 'lightgray'})),
model: $(go.GraphLinksModel,
{
nodeKeyProperty: 'id',
linkKeyProperty: 'key' // IMPORTANT! must be defined for merges and data sync when using GraphLinksModel
}
)
});
dia.commandHandler.archetypeGroupData = { key: 'Group', isGroup: true};
dia.toolManager.draggingTool.isGridSnapEnabled = true;
dia.nodeTemplate =
$(go.Node, 'Vertical', { desiredSize: new go.Size(88, 88), resizeObjectName: 'FBNODE'
/*mouseDragEnter: (e, node) => {
e.handled = true;
node.findObject('FBNODE').fill = 'red';
e.diagram.currentCursor = 'not-allowed';
}
mouseDrop: (e, node) => node.diagram.currentTool.doCancel()*/},
$(go.Panel, 'Auto',
{ background: 'white', maxSize: new go.Size(88, 88) },
$(go.Shape, 'Rectangle',
{ fill: '#FFFFFF', stroke: 'rgba(0, 0, 0, 0.15)', width: 88, height: 88 }),
$(go.Panel, 'Vertical', // Everything within the border
$(go.Picture,
{ desiredSize: new go.Size(64, 64), scale: 1, margin: new go.Margin(4,12,0,12) },
new go.Binding('source', 'type', type => 'assets/functionblocks/outputs/' + type.toLowerCase() + '/0/_black.svg')),
$(go.TextBlock,
{ stretch: go.GraphObject.Horizontal, textAlign: 'center', font: '12pt', wrap: go.TextBlock.WrapDesiredSize, overflow: go.TextBlock.OverflowEllipsis },
new go.Binding('text', 'name'))
)
)
);
dia.nodeTemplateMap.add('col_head',
$(go.Part, 'Spot',
{
row: 0, rowSpan: 9999, column: 1,
size: new go.Size(88, 88),
movable: false,
resizable: false,
},
new go.Binding('column', 'col'),
$(go.Panel, 'Auto',
{ // this is positioned above the Shape, in row 1
alignment: go.Spot.Top, alignmentFocus: go.Spot.Bottom,
stretch: go.GraphObject.Horizontal,
height: 88
},
$(go.Shape, { fill: 'transparent', strokeWidth: 0 }),
$(go.TextBlock,
{
font: '12pt', isMultiline: false,
wrap: go.TextBlock.None, overflow: go.TextBlock.OverflowEllipsis
},
new go.Binding('text'))
)));
dia.nodeTemplateMap.add('row_head', // for each row header
$(go.Part, 'Spot',
{
row: 1, column: 0, columnSpan: 9999,
height: 88,
movable: false,
resizable: false,
},
new go.Binding('row'),
$(go.Panel, 'Auto',
{ // this is positioned to the left of the Shape, in column 1
alignment: go.Spot.Left, alignmentFocus: go.Spot.Right,
height: 88
},
$(go.Shape, { fill: 'transparent', strokeWidth: 0 }),
$(go.TextBlock,
{
font: '12pt', isMultiline: false,
wrap: go.TextBlock.None, overflow: go.TextBlock.OverflowEllipsis
},
new go.Binding('text'))
)
));
return dia;
}
constructor(private cdr: ChangeDetectorRef) { }
ngOnInit() {
// TEMP TILL VISUALISATION CAN BE REQUESTED FROM DATABASE
const visualisationExists = false;
if(visualisationExists) {
} else {
this.state.diagramNodeData = [
// Column and row headers
{ key: 'header_1', text: 'Change Me!', col: 1, category: 'col_head'},
{ key: 'row_1', text: 'Change Me!', row: 1, category: 'row_head'},
// Cells
//{ key: 'cell_1_1', row: 2, col: 2, isGroup: true } // TODO: Check why isGroup is needed
];
}
}
}
core.mjs:6485 ERROR Error: Uncaught (in promise): Error: GraphObject.make requires a class function or GoJS class name or name of an object builder, not: undefined
Error: GraphObject.make requires a class function or GoJS class name or name of an object builder, not: undefined
at C (go-module.js:13:65)
at Bl (go-module.js:929:306)
at DiagramComponent.initDiagram (visualisation.component.ts:34:15)
at DiagramComponent.ngAfterViewInit (gojs-angular.js:224:1)
at callHook (core.mjs:2542:1)
at callHooks (core.mjs:2511:1)
at executeInitAndCheckHooks (core.mjs:2462:1)
at refreshView (core.mjs:9555:1)
at refreshComponent (core.mjs:10655:1)
at refreshChildComponents (core.mjs:9280:1)
at resolvePromise (zone.js:1262:1)
at resolvePromise (zone.js:1216:1)
at zone.js:1329:1
at _ZoneDelegate.push.3484._ZoneDelegate.invokeTask (zone.js:443:1)
at Object.onInvokeTask (core.mjs:25535:1)
at _ZoneDelegate.push.3484._ZoneDelegate.invokeTask (zone.js:442:1)
at Zone.push.3484.Zone.runTask (zone.js:214:1)
at drainMicroTaskQueue (zone.js:632:1)
I’m using Ionic using Angular, inside an Electron application:
"@angular/common": "~13.2.2",
"@angular/core": "~13.2.2",
"@ionic/angular": "^6.0.0",
"electron": "^17.1.2",
"gojs": "^2.2.6",
"gojs-angular": "^2.0.4",
My end goal is basically where I can drag node’s from a palette into a diagram that is a TableLayout, where I would be able to add column’s & cells by clicking on a button. Each cell would then only be able to have one node. No node’s can be placed outside the table.
Could you please guide me to the right approach?