I am using Puppeteersharp on the server side in a .net core application to do server side rendering (Server-Side Images with GoJS -- Northwoods Software) and generate images of the diagram.
The SVG images are not showing up in the generated diagram image. Below is my javascript code Im using in the server invoked from PuppeteerSharp (https://www.puppeteersharp.com/).
the same way of creating the blob url from svg image string and appending it to a simple html div element is working fine but it is not working in the GoJS diagram. What am I missing?
function getImageDataForReport() {
var div = document.createElement("div");
div.id = 'summary' + 'flowchartId';
var modelJson = '{"class":"GraphLinksModel","linkKeyProperty":"key","linkFromPortIdProperty":"fromPort","linkToPortIdProperty":"toPort","nodeDataArray":[{"category":"Process","text":"Step 1","color":"","key":"1","loc":"-200 100","isComplete":false},{"category":"Process","text":"Step 2","color":"","key":"2","loc":"400 300","isComplete":false}],"linkDataArray":[]}';
var diagram = go.GraphObject.make(go.Diagram, div, {
"animationManager.isEnabled": false,
"undoManager.isEnabled": false,
"LayoutCompleted": (e) => { e.diagram.findTopLevelGroups().each((g) => { /*if (g.visible) dTemplates.locateGroup(g)*/ }) },
});
diagram.nodeTemplateMap.add("Process", processTemplate(false, [], false));
var graphModel = new go.GraphLinksModel();
graphModel = new go.GraphLinksModel(go.Model.fromJson(modelJson)["nodeDataArray"], go.Model.fromJson(modelJson)["linkDataArray"]);
diagram.model.setDataProperty(graphModel, "linkKeyProperty", "key");
diagram.model.setDataProperty(graphModel, "nodeKeyProperty", "key");
graphModel.linkFromPortIdProperty = "fromPort";
graphModel.linkToPortIdProperty = "toPort";
diagram.model = graphModel;
return diagram.makeImageData({
scale: 1,
background: "White"
});
}
function processTemplate() {
var imgElm = getProcessImage();
var imgUrl = getProcessImage(true);
return go.GraphObject.make(go.Node, "Spot",
{
avoidableMargin: new go.Margin(3, 3, 3, 3), locationSpot: go.Spot.Center, visible: true
},
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
go.GraphObject.make(go.Picture,
{
name: "ProcessStep",
desiredSize: new go.Size(150, 100),
element: imgElm,
visible: true,
source: imgUrl ? imgUrl : getProcessImage(true)
}
),
new go.Binding('source', '', (layer, trgtObj) => { return imgUrl ? imgUrl : getProcessImage(true); }).ofObject(),
new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify),
new go.Binding("element", "isComplete", (state) => { return imgElm; }),
go.GraphObject.make(go.TextBlock,
{ font: "14px Helvetica Neue", stroke: "#000000" },
{
editable: false, maxLines: 4, wrap: go.TextBlock.WrapFit, overflow: go.TextBlock.OverflowEllipsis, margin: new go.Margin(0, 24, 0, 24), alignment: go.Spot.Center,
verticalAlignment: go.Spot.Center, textAlign: 'center', stretch: go.GraphObject.Fill
},
new go.Binding("text").makeTwoWay()
),
makePort("T", go.Spot.Top, go.Spot.TopSide, true, true, false),
makePort("B", go.Spot.Bottom, go.Spot.BottomSide, true, true, false),
makePort("L", go.Spot.Left, go.Spot.LeftSide, true, true, false),
makePort("R", go.Spot.Right, go.Spot.RightSide, true, true, false),
);
}
function getProcessImage(onlyUrl) {
var svgStr = `<?xml version="1.0" encoding="UTF-8"?>
<svg width="173px" height="125px" viewBox="0 0 173 125" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Process</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="50%" y1="26.3513514%" x2="50%" y2="90.020587%" id="linearGradient-1">
<stop stop-color="#EFF8FE" offset="0%"></stop>
<stop stop-color="#E0F1FD" offset="100%"></stop>
</linearGradient>
<rect id="path-2" x="12" y="12" width="150" height="100"></rect>
</defs>
<g id="Flowchart-/-Shapes-/-Process-Step" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Process-Shape">
<use fill="url(#linearGradient-1)" fill-rule="evenodd" xlink:href="#path-2"></use>
<rect stroke="#B3DCF9" stroke-width="1" x="11.5" y="11.5" width="151" height="101"></rect>
<rect stroke="#FFFFFF" stroke-width="1" stroke-linejoin="square" x="12.5" y="12.5" width="149" height="99"></rect>
</g>
</g>
</svg>`;
var blb = new Blob([svgStr], { type: 'image/svg+xml' });
var imgurl = URL.createObjectURL(blb);
if (onlyUrl) return imgurl;
var image = document.createElement('img');
image.src = imgurl;
return image;
}
function makePort(name, align, spot, output, input, editable) {
const horizontal =
align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom);
return go.GraphObject.make(go.Shape, {
fill: "transparent",
strokeWidth: 0,
width: horizontal ? NaN : 8,
height: !horizontal ? NaN : 8,
alignment: align,
stretch: horizontal ? go.GraphObject.Horizontal : go.GraphObject.Vertical,
portId: name,
fromSpot: spot,
fromLinkable: editable ? output : editable,
toSpot: spot,
toLinkable: editable ? input : editable,
cursor: "pointer",
mouseEnter: editable ?
function (e, port) {
if (!e.diagram.isReadOnly && port instanceof go.Shape)
port.fill = "rgba(255,0,255,0.5)";
}
:
function (e, port) {
if (port instanceof go.Shape) port.fill = "transparent"
}
,
mouseLeave: function (e, port) {
if (port instanceof go.Shape) port.fill = "transparent";
}
});
}