Server-side images of diagrams with pictures using PhantomJS


I’ve started from the sample here

This works great except I am having trouble getting the images in our diagram out to the generated image. I’ve changed the node template in the sample to the following

  myDiagram.nodeTemplate =
    $(go.Node, "Auto",
      $(go.Shape, "RoundedRectangle",
        // Shape.fill is bound to
        new go.Binding("fill", "color")),
      $(go.Picture, {
        source: "about.png",
        width: 48, height: 48

I’ve run this in a web page and the images appear but when running in PhantomJS none of the images appear. I suspect this is due to cross origin issues but am not sure how to fix it in GoJS or PhantomJS. Is there an example of generating images of diagrams that contain an image?

Actually I don’t think this is related to PhantomJS. If I add the call to makeImageData in my web page and show it in an image, it works fine when I’m browsing via my local web server, but doesn’t show the images in the generated image when I’m looking at the page via the local file system, which I guess is equivalent to what PhantomJS is doing.

Is this a bug?

Are those images are actually visible in the Pictures in your Diagram, at the time that you call Diagram.makeImageData?

Is the behavior different in different browsers? If I recall correctly, browsers have slightly different security behaviors when dealing with the local file system, and not only when dealing with images.

The images appear in the diagram and I added a delay before calling makeImageData just to be sure. But yes, it is browser specific. It’s only in Chrome that the images don’t appear, FireFox and IE display them. I don’t have Safari installed since it’s so old on Windows

If you search the web, it appears that many developers have had this problem with Chrome for many years. I believe Google would consider any good solution (i.e. not modifying how Chrome is started) to be a security hole.

Yes, it seems that PhantomJS suffers from the same problem. I’ve kludged together something that appears to work. Rather than build the web page on the fly as your example does, I’ve got a page on the web server that loads up the diagram and generates the image. Then PhantomJS loads up the page and saves the generated image. Looks like it will fix the issue. In case anyone else faces the same issue here is the HTML


And PhantomJS script

var page = require('webpage').create();
page.viewportSize = { width: 1024, height: 768 };"http://localhost/TestPhantom/HtmlPage1.html", function () {
  // We want to ensure that the image is done loading before we render
  setInterval(function () {
    var imgComplete = page.evaluate(function () {
      return (document.getElementById('myImg')).complete;

    if (imgComplete) {
      // PhantomJS renders the entire page, and we just want to output the ,
      // so we must clip to its bounding rect:
      var clipRect = page.evaluate(function () {
        return document.getElementById('myImg').getBoundingClientRect();
      page.clipRect = {
        left: clipRect.left,
        width: clipRect.width,
        height: clipRect.height
  }, 100);

Thanks for the suggestion and code.

hi Doogal,
this issue is a bug? i also encounter this error,has any anther answer? i could not use the suggestion

I’ve heard that you can use headless Chrome instead. However I have not had any experience with that. We’re thinking about changing our Intro page, Server-Side Images with GoJS -- Northwoods Software, not to use PhantomJS any more.

We’ve been using the above code without too many problems for a while now. PhantomJS probably isn’t the best option since it’s been abandoned by the developers, although it looks like someone may have started working on it

Look at our updated page: Server-Side Images with GoJS -- Northwoods Software