Images do not render in call to makeSvg or makeImage

Hi,
We have used Go diagram for process flow diagram in winforms, now going to develope the same in angular.
We just analyzed by creating some samples,
we need the diagram nodes as like below
diagram%20node
and few more customization,
For now when we exported this , the exported diagram node exported with only text not with the images.as below
image
Please let us how to export with images.
Regards
Nageswar

I still cannot tell how you defined that node template. Nor can I tell what you are doing when you “export”.

Are you using a Panel with a bunch of Shapes?

Or a Picture? If a Picture, what is it showing, and have you read GoJS Pictures -- Northwoods Software ?

Are you calling Diagram.makeImageData or Diagram.makeSvg or something else?

Here i am giving the typescript code for your reference, please check the code and let us know.

import { Component, OnInit, ViewChild, ElementRef, Input, Output, EventEmitter } from ‘@angular/core’;
import * as go from ‘gojs’;

// This requires us to include
// “node_modules/gojs/extensionsTS/*”
// in the “includes” list of this project’s tsconfig.json
import { GuidedDraggingTool } from ‘gojs/extensionsTS/GuidedDraggingTool’;
import { FishboneLink, FishboneLayout } from ‘gojs/extensionsTS/FishboneLayout’;
import { alignLeft } from ‘gojs/extensionsTS/FloorPlanEditorScript’;

@Component({
selector: ‘app-diagram-editor’,
templateUrl: ‘./diagram-editor.component.html’,
styleUrls: [’./diagram-editor.component.css’]
})
export class DiagramEditorComponent implements OnInit {
private diagram: go.Diagram = new go.Diagram();
private palette: go.Palette = new go.Palette();

@ViewChild(‘diagramDiv’)
private diagramRef: ElementRef;

@ViewChild(‘paletteDiv’)
private paletteRef: ElementRef;

@Input()
get model(): go.Model { return this.diagram.model; }
set model(val: go.Model) { this.diagram.model = val; }

@Output()
nodeSelected = new EventEmitter<go.Node|null>();

@Output()
modelChanged = new EventEmitter<go.ChangedEvent>();

constructor() {
const $ = go.GraphObject.make;

this.diagram = new go.Diagram();

this.diagram.linkTemplateMap.add("fishbone",
$(FishboneLink,  // defined above
  $(go.Shape)
));

this.diagram.nodeTemplate =
(go.Node, "Spot", // the main content: (go.Panel, “Vertical”,

   $(go.Picture,
      { width: 68, height: 48 },
      new go.Binding("source", "img")),

  ),
  // decorations:
  $(go.Picture,
    {alignment: go.Spot.LeftCenter, 
      alignmentFocus: go.Spot.LeftCenter,
      width: 10, height: 10,visible: false},
      new go.Binding("visible", "info", function(i) { return i ? true : false; }),
      new go.Binding("source", "img3")),
  $(go.Picture,
    { //margin: new go.Margin(10, 10, 10, 10),
      //position: new go.Point(2, 2),  
     alignment: go.Spot.TopLeft,
     alignmentFocus: go.Spot.TopLeft,
     width: 10, height: 10,visible: false},
      new go.Binding("visible", "info", function(i) { return i ? true : false; }),
      new go.Binding("source", "img2")),
  $(go.Picture,
    {alignment: go.Spot.TopRight, 
      alignmentFocus: go.Spot.TopRight,
      width: 10, height: 10,visible: false},
      new go.Binding("visible", "info", function(i) { return i ? true : false; }),
      new go.Binding("source", "img1")),
  $(go.Picture,
    {alignment: go.Spot.BottomRight, 
      alignmentFocus: go.Spot.BottomRight,
      width: 10, height: 10,visible: false},
      new go.Binding("visible", "info", function(i) { return i ? true : false; }),
      new go.Binding("source", "img5")),
  $(go.Picture,
    {alignment: go.Spot.BottomLeft, 
      alignmentFocus: go.Spot.BottomLeft,
      width: 10, height: 10,visible: false},
      new go.Binding("visible", "info", function(i) { return i ? true : false; }),
      new go.Binding("source", "img4")),

  $(go.TextBlock,
    {
      alignment: go.Spot.Bottom, 
      alignmentFocus:go.Spot.Top,
     
    },
        new go.Binding("text", "text"),
        new go.Binding("stroke", "error", function(err) { return err ? "red" : "black" }))
  
);

var nodeDataArray = [
// { text: "kitten", img: "https://material.angular.io/assets/img/examples/shiba2.jpg", info: "" },
{ text: "Process", 
  img: "./assets/Image/process_api.png",
  img1: "./assets/Image/lock_(16x16).png", 
  img2:"./assets/Image/Knowledge(16x16).png",
  img3:"./assets/Image/Formula(16x16).png",
  img4:"./assets/Image/Checkin_mark(16x16).png",
  img5:"./assets/Image/Hyperlink.png",
  error: true, info: "shredded curtains" }

];

var linkDataArray = [

];
// this.diagram.linkTemplate = this.diagram.linkTemplateMap.get(“fishbone”);
this.diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);

}

generateSvg()
{
var imgDiv = document.getElementById(‘myImages’);
imgDiv.innerHTML = ‘’;
var db = this.diagram.documentBounds.copy();
var boundswidth = db.width;
var boundsheight = db.height;
var svg = this.diagram.makeImageData({scale:1,
size : new go.Size(boundswidth,boundsheight)
}) as HTMLElement;

imgDiv.appendChild(svg);
imgDiv.appendChild(document.createElement(‘br’));

return ;

}
generateImages(width, height)
{
// sanitize input
width = parseInt(width);
height = parseInt(height);
if (isNaN(width)) width = 100;
if (isNaN(height)) height = 100;
// Give a minimum size of 50x50
width = Math.max(width, 50);
height = Math.max(height, 50);

var imgDiv = document.getElementById(‘myImages’);
imgDiv.innerHTML = ‘’; // clear out the old images, if any

var img = this.diagram.makeImage({
scale: 1,

  });
  // Append the new HTMLImageElement to the #myImages div
  img.className = 'images';
  imgDiv.appendChild(img);
  imgDiv.appendChild(document.createElement('br'));
}

ngOnInit() {
this.diagram.div = this.diagramRef.nativeElement;
this.generateImages(400, 400);

}
}

Regards
Nageswar

Your “generateSvg” function is not calling Diagram.makeSvg.

I think you want to use a “Spot” Panel to position your Pictures around the main body object. That way the Pictures can be place outside the bounds of that main rectangular object.
https://gojs.net/latest/intro/nodes.html#DecoratedContent

Already we have tried by calling the diagram.makeSvg, still not working. so we are trying with other methods, even we tried by taking the following nodes:

diagram.nodeTemplate =
$(go.Node, “Spot”,
// the main content:
$(go.Panel, “Vertical”,
$(go.Picture,
{ maxSize: new go.Size(50, 50) },
new go.Binding(“source”, “img”)),
$(go.TextBlock,
{ margin: new go.Margin(3, 0, 0, 0) },
new go.Binding(“text”, “text”),
new go.Binding(“stroke”, “error”, function(err) { return err ? “red” : “black” }))
),
// decorations:
$(go.Shape, “TriangleUp”,
{ alignment: go.Spot.TopLeft,
fill: “yellow”, width: 14, height: 14,
visible: false },
new go.Binding(“visible”, “info”, function(i) { return i ? true : false; })),
$(go.Shape, “StopSign”,
{ alignment: go.Spot.TopRight,
fill: “red”, width: 14, height: 14,
visible: false },
new go.Binding(“visible”, “error”)),
{
toolTip:
$(go.Adornment, “Auto”,
$(go.Shape, { fill: “#FFFFCC” },
new go.Binding(“visible”, “info”, function(i) { return i ? true : false; })),
$(go.TextBlock, { margin: 4 },
new go.Binding(“text”, “info”))
)
}
);

diagram.model.nodeDataArray = [
{ text: “kitten”, img: “images/50x40.png”, info: “” },
{ text: “kitten”, img: “images/50x40.png”, error: true, info: “shredded curtains” }
];

which the above code taken from following url
https://gojs.net/latest/intro/nodes.html#DecoratedContent

Still it is exporting only text and both triangles only not the image/picture.

Please give us any sample which is exporting/printing node with any image/picture.

Regards
Nageswar

Depending on where your images are and your server, you may need to add a cross origin rule. The most common one to add to a go.Picture is:

sourceCrossOrigin: function(pict) { return "anonymous"; }

Here’s an example: https://codepen.io/simonsarris/pen/QYVZzO?editors=1011

Hi Simon,

We went through the given sample, its working fine in your environment(https://codepen.io/simonsarris/pen/QYVZzO?editors=1011), But the same code we tried in our environment with Visual studio code,we facing the same issue (Images are not getting printed/exported), Please let us know if any solution is available to proceed further.

FYI, here is more information about CORS: Cross-Origin Resource Sharing (CORS) - HTTP | MDN

Hi Walter,

I gone throug the given link Cross-Origin Resource Sharing (CORS) - HTTP | MDN, the “cors”: “^2.8.5”, configuration is available in dependencies of packege.json and i have installd the cors packege with command “npm install cors”, still while exporting/prnting images are not coming. Not sure how to proceed further to get the images while exporting/prnting. Can you please help on this.

Regards
Nageswar

So you are using Node Express. How did you set up the middleware and how is your Picture defined?

Hi Walter,

Here i didn’t get any option to attach the sample project, Is there any possibility to share my sample project with you to resolve?

Regards
Nageswar

I don’t think we can debug your project for you. How do you call cors on the server, and what is your Picture element?

following is the node template:

this.diagram.nodeTemplate =
      $(go.Node, "Vertical",
      new go.Binding("location", "loc", go.Point.parse),
        $(go.Shape, "RoundedRectangle", { width: 15, height: 15, strokeWidth: 0, fill: "red" },
          new go.Binding("fill", "color")),
        $(go.Picture, "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d8/NASA_Mars_Rover.jpg/225px-NASA_Mars_Rover.jpg", 
        {
         
          
         width: 68, height: 47, background: 'lime',
         sourceCrossOrigin: function(pict) { return "anonymous"; },
        //  params: {'LAYERS': 'topp:states', 'TILED': true},
          // serverType: 'geoserver',
         
        } )
      );

This i have defined it in diagram-editor.component.ts file.
Not sure on the following question, where to call?

“How do you call cors on the server?”

and the following is packege.json file:

{
“name”: “my-app”,
“version”: “0.0.0”,
“license”: “MIT”,
“scripts”: {
“ng”: “ng”,
“start”: “ng serve --proxy-config proxy.json --ssl true”,
“build”: “ng build”,
“test”: “ng test”,
“lint”: “ng lint”,
“e2e”: “ng e2e”
},
“private”: true,
“dependencies”: {
@angular/animations”: “^7.2.0”,
@angular/common”: “^7.2.0”,
@angular/compiler”: “^7.2.0”,
@angular/core”: “^7.2.0”,
@angular/forms”: “^7.2.0”,
@angular/http”: “^7.2.0”,
@angular/platform-browser”: “^7.2.0”,
@angular/platform-browser-dynamic”: “^7.2.0”,
@angular/router”: “^7.2.0”,
“core-js”: “^2.6.2”,
“gojs”: “^2.0.0”,
“ng”: “0.0.0”,
“rxjs”: “^6.3.3”,
“zone.js”: “^0.8.27”
},
“devDependencies”: {
@angular-devkit/build-angular”: “^0.12.1”,
@angular/cli”: “^7.2.1”,
@angular/compiler-cli”: “^7.2.0”,
@angular/language-service”: “^7.2.0”,
@types/jasmine”: “^3.3.5”,
@types/jasminewd2”: “~2.0.6”,
@types/node”: “^10.12.18”,
“codelyzer”: “^4.5.0”,
“cors”: “^2.8.5”,
“jasmine-core”: “^3.3.0”,
“jasmine-spec-reporter”: “~4.2.1”,
“karma”: “^3.1.4”,
“karma-chrome-launcher”: “~2.2.0”,
“karma-cli”: “^2.0.0”,
“karma-coverage-istanbul-reporter”: “^2.0.4”,
“karma-jasmine”: “^2.0.1”,
“karma-jasmine-html-reporter”: “^1.4.0”,
“protractor”: “^5.4.2”,
“ts-node”: “~7.0.1”,
“tslint”: “^5.12.1”,
“typescript”: “^3.2.0”
}
}

Your node definition looks OK.

Your package.json file does not show how you are calling cors as middleware.

oh, can you please help me, how do i initiate the call in package.json file for cors.

Regards
Nageswar

Have you read the documentation for that package? That tells you how to call it for several different scenarios. It also wouldn’t hurt to learn about Express middleware.

Also, if you have read the general description for CORS, I hope the web server that you are modifying to support CORS requests for images is running on the domain that is serving those images, not your app’s web server.

I gone through the documentation, nowhere its explained about the angular part, i got the following the reference to add update the configurations:

But in my sample project i am not using any web api/services to configure with. even i downloaded the code(html and js) from the given path:

In this only the “sourceCrossOrigin: function(pict) { return “anonymous”; }” is available, otherthan this cors related configuration is not available.

note: we are trying to use images which are available in the my local system, not using any URL based image like https://upload.wikimedia.org/wikipedia/commons/thumb/d/d8/NASA_Mars_Rover.jpg/225px-NASA_Mars_Rover.jpg. In this case also do i need use CORS Configuration?

Please provide any angular related sample for reference.

Thanks & Regards
Nageswar

It is the web server that is delivering the image files that needs to enable CORS. I thought you were trying to do that because your images are on a different server that is implemented using Node.js Express, which is the only reason to import the cors package from npm.

So you need to set up your local web server to deliver those local image files. But then they will probably be coming from the same domain, so you won’t have any Cross-Origin Resource Sharing security problem.

Please check the following code which i have used :

function init() {
if (window.goSamples) goSamples(); // init for these samples – you don’t need to call this

var $ = go.GraphObject.make;  // for conciseness in defining templates

myDiagram = $(go.Diagram, "myDiagramDiv", { });

// define a simple Node template
myDiagram.nodeTemplate =
  $(go.Node, "Vertical",
    $(go.Shape, "RoundedRectangle", { width: 15, height: 15, strokeWidth: 0, fill: "red" },
      new go.Binding("fill", "color")),
    $(go.Picture, "http://localhost/aspnet_client/process_api.png", {
     width: 50, height: 50, background: 'lime',
  //sourceCrossOrigin: function(pict) { return "anonymous"; }
                                                                                                                             } )
  );


myDiagram.model = new go.GraphLinksModel(
[
  { key: "Alpha", color: "lightblue" },
  { key: "Beta", color: "orange" },
  { key: "Gamma", color: "lightgreen" },
  { key: "Delta", color: "pink" }
],
[
]);



document.getElementById('b1').addEventListener('click', function() {
  document.body.appendChild(myDiagram.makeImage());
})

}

init();

output is coming as :

Is your page also being served from localhost and using HTTP? Otherwise it would obviously be a different origin, because origin means the combination of protocol, host name, and port number.