Calling makeSvg from another Vue component

Hi!

Currently, I am working on a project which lets people draw dataflows on a canvas.

I use the Vue framework, which lets me chop up the application into components. One of the components is called diagram.vue which contains a GoJS diagram. There is another component called toolbar.vue which contains a button called ‘Print’. Quite obvious, I would like to be able to print the diagram as shown in the diagram.vue component.

What I did was make sure that on every change in the GoJS diagram the diagram.model object is stored in the Vue framework (the store, more specifically).

In the toolbar.vue component I try to recreate the GoJS diagram, get the data from the Vue framework and then use the makeSvg function.

let diagram = $(go.Diagram, ‘diagramHolder’, {});
let storeModel = JSON.parse(JSON.parse(this.diagramSVG));

diagram.model = $(go.GraphLinksModel);

diagram.model.nodeDataArray = storeModel.nodeDataArray;
diagram.model.linkDataArray = storeModel.linkDataArray;

console.log(diagram.model.nodeDataArray); // shows the correct nodes, each with a loc property { class: "go.Point, x: , y: }
console.log(diagram.model.linkDataArray); // shows the correct links, each with a from, to and points property

let newWindow = window.open("",“newWindow”);
let newDocument = newWindow.document;

newDocument.body.innerHTML = ‘’;

let newSVG = diagram.makeSvg({
// Scale 1 to make all of the diagram show
scale: 1
});

newDocument.body.appendChild(newSVG);

The new windows opens, it shows the correct nodes and links, but they are all placed in top left corner.

What am I overlooking? Why isn’t makeSvg using the node loc properties?

You need to initialize your diagram’s templates too. Typically that is done by sharing the Diagram.nodeTemplateMap, Diagram.linkTemplateMap, and Diagram.groupTemplateMap (if you have any groups).

Although I suggest that instead of creating a new diagram that you ask the original diagram to create the SVG snapshot for you and show that in your print dialog.

Thank you for your quick reply.

I changed the following:

let diagram = $(go.Diagram, ‘diagramHolder’, {});

To

let diagram = $(go.Diagram, ‘diagramHolder’, {});

diagram.nodeTemplateMap = templateMap;
diagram.nodeTemplate.selectionAdornmentTemplate = selectionTemplate;
diagram.linkTemplate = linkTemplate;

These are the templates:

const dataModelTemplate = $(go.Node, ‘Auto’,
new go.Binding(“location”, “loc”),
$(go.Shape, “Ellipse”,
{
fill: ‘#F9F9F9’,
stroke: ‘#3794FF’,
strokeWidth: 3,
width: 100,
height: 100,
// toSpot: go.Spot.Center,
// fromSpot: go.Spot.Center,
fromLinkable: true,
fromLinkableSelfNode: false,
fromLinkableDuplicates: false,
toLinkable: true,
toLinkableSelfNode: false,
toLinkableDuplicates: false,
portId: ‘’, // this Shape is the Node’s port, not the whole Node
cursor: ‘pointer’
}),
$(go.TextBlock,
new go.Binding(‘text’, ‘title’),
{
stroke: ‘#3794FF’,
width: 100,
font: ‘14px/1.2 FF Mark, sans-serif’,
textAlign: ‘center’
}
),
$(go.TextBlock,
new go.Binding(‘text’, ‘buildNumber’),
{
stroke: ‘#3794FF’,
width: 100,
font: ‘12px/1 FF Mark, sans-serif’,
textAlign: ‘center’
}
)
);

// Template for how the selection of a node looks
const selectionTemplate = $(go.Adornment, ‘Spot’,
$(go.Panel, ‘Auto’,
$(go.Shape, {
figure: ‘RoundedRectangle’,
fill: null,
stroke: ‘lightgray’,
strokeWidth: 0.75,
strokeDashArray: [10, 2],
}),
$(go.Placeholder, {
padding: 5
}) // a Placeholder sizes itself to the selected Node
)
); // end Adornment

// Template for how the links elements look
// (line with arrow head)
const linkTemplate = $(go.Link,
{
curve: go.Link.JumpGap,
adjusting: go.Link.Stretch,
reshapable: false,
relinkableFrom: true,
relinkableTo: true,
toShortLength: 3,
corner: 15
},
$(go.Shape, // the link shape
{ strokeWidth: 3, stroke: ‘black’ }),
$(go.Shape, // the arrowhead
{ scale: 2, toArrow: ‘Feather’, stroke: ‘black’, strokeWidth: 1.5 })
);

const templateMap = new go.Map(‘string’, go.Node);

templateMap.add(‘dataModel’, dataModelTemplate);
templateMap.add(’’, dataModelTemplate);

Still doesn’t work though

I suggest that you not create a new diagram at all, but show an SVG snapshot that the original diagram generates.

Ok, what way(s) would I accomplish that? Which GoJS functionalities should I use?

Call Diagram.makeSvg on the original Diagram.

Thank you so much for your help.

I tried using the makeSvg method. The Vue framework won’t let me use data or methods from one Vue component in another Vue component. So when I tried to capture the output of the makeSvg into a common data variable (Vuex), it resulted into a maximum call stack size exceeded error. My next move was to store the diagram.model in a common data variable. That worked, but now I only have the model to work with.

Any thoughts on how to proceed?

Add a method on the diagram-containing component that returns the SVG for that diagram.