Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVG output doesn't write the link to embedded bitmap files #121

Closed
YanikTheYak opened this issue Dec 9, 2020 · 8 comments
Closed

SVG output doesn't write the link to embedded bitmap files #121

YanikTheYak opened this issue Dec 9, 2020 · 8 comments
Labels
bug An error in the library, extensions, documentation, or samples

Comments

@YanikTheYak
Copy link

YanikTheYak commented Dec 9, 2020

Following the fix to this issue: cannot render server side image that contains a Picture #80
#80

I modified the sample code you provided in this fix to use the standard template example, but added a PNG to the template (see myDiagram below). Looking at the SVG produced there is no reference to the PNG file found in the output.
I also added a Blue background, to the Picture component, as without it there is no reference to the Picture component at all.
Since the Blue rectangle displays correctly, I believe the picture reference should also be there.

 // define a simple Node template
    myDiagram.nodeTemplate =
      $(go.Node, "Auto",  // the Shape will go around the TextBlock
        $(go.Shape, "RoundedRectangle", { strokeWidth: 0 },
          new go.Binding("fill", "color")),
        $(go.TextBlock,
          { margin: 8 },
          new go.Binding("text", "key")),
        $(go.Picture, {
            desiredSize: new go.Size(55,55),
            background: "blue",
            source: "images/55x55.png"
        })          
      );

    myDiagram.model = new go.GraphLinksModel(
      [
        { key: "Alpha", color: "lightblue" },
        { key: "Beta", color: "orange" },
        { key: "Gamma", color: "lightgreen" },
        { key: "Delta", color: "pink" }
      ],
      [
        { from: "Alpha", to: "Beta" },
        { from: "Alpha", to: "Gamma" },
        { from: "Beta", to: "Beta" },
        { from: "Gamma", to: "Delta" },
        { from: "Delta", to: "Alpha" }
      ]);
@simonsarris
Copy link
Collaborator

see myDiagram below

The code you have below only has a PNG, did you mean to paste something else?

@YanikTheYak
Copy link
Author

YanikTheYak commented Dec 9, 2020

Sorry, I meant PNG. (I tried both) I'll change the text so it matches.
I'll attach the entire code too if that helps.

If you compare the original code from issue 80, with the code below. I changed it to use a local GoJS and replaced the use of myDiagram.add with a template node and a model, where the template node has an image.
Hope this is clearer.

@YanikTheYak
Copy link
Author

YanikTheYak commented Dec 9, 2020

Full code from the original sample, including the change I made:


  const puppeteer = require('puppeteer');
  const fs = require('fs');

  const parseDataUrl = (dataUrl) => {
    const matches = dataUrl.match(/^data:(.+);base64,(.+)$/);
    if (matches.length !== 3) {
      throw new Error('Could not parse data URL.');
    }
    return { mime: matches[1], buffer: Buffer.from(matches[2], 'base64') };
  };

  (async () => {
    const browser = await puppeteer.launch({
      // headless: false,
      // devtools: true
    });
    const page = await browser.newPage();
    page.setContent('<div id="myDiagramDiv"></div>');

    await page.addScriptTag({
      url: 'https://gojs.net/2.0.14/release/go.js'
      // path: 'node_modules/gojs/release/go.js'
    });

    const results = await page.evaluate(() => {
      var $ = go.GraphObject.make;
      var myDiagram = $(go.Diagram, "myDiagramDiv",
        {
          "animationManager.isEnabled": false,
          "undoManager.isEnabled": true  // enable undo & redo
        });

      // define a simple Node template
      myDiagram.nodeTemplate =
        $(go.Node, "Auto",  // the Shape will go around the TextBlock
          $(go.Shape, "RoundedRectangle", { strokeWidth: 0 },
            new go.Binding("fill", "color")),
          $(go.TextBlock,
            { margin: 8 },
            new go.Binding("text", "key")),
          $(go.Picture, {
            desiredSize: new go.Size(55, 55),
            background: "blue",
            source: "images/55x55.png"
          })
        );

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

      myDiagram.makeImageData({
        callback: function (imagedata) {
          const { buffer } = parseDataUrl(imagedata);
          fs.writeFileSync('_gojs-screenshot.png', buffer, 'base64');
        }
      });

      const getIMG = () => {
        return new Promise((resolve, reject) => {
          myDiagram.makeImageData({
            background: 'red',
            size: new go.Size(300, NaN),
            callback: function (data) {
              resolve(data);
            }
          });
        })
      }

      async function fetchIMG() {
        return await getIMG();
      }

      const getSVG = () => {
        return new Promise((resolve, reject) => {
          myDiagram.makeSVG({
            size: new go.Size(300, NaN),
            callback: function (svgdata) {
              let svgstr = new XMLSerializer().serializeToString(svgdata);
              console.log(svgstr)
              resolve(svgstr)
            }
          });
        })
      }

      async function fetchSVG() {
        return await getSVG();
      }

      // var results =  [fetchIMG(), fetchSVG()];
      return fetchSVG();
    });

    console.log(results);
    fs.writeFileSync('_gojs.svg', results);
    //const { buffer } = parseDataUrl(imagedata);
    //fs.writeFileSync('_gojs-screenshot.png', buffer, 'base64');

    await browser.close();
  })();


@YanikTheYak
Copy link
Author

The SVG output contains the blue rectangle, but not the xlink for the image:

 <rect x="0" y="0" width="55" height="55" fill="blue" stroke="none"
                    transform="matrix(1, 0, 0, 1, 2.761423749153968, 2.761423749153968)" />

I think it should include this:

xlink:href="images/55x55.png"

@simonsarris
Copy link
Collaborator

I see what you mean. I'll investigate and get back to you.

@simonsarris
Copy link
Collaborator

This is fixed and will be out with the next release, probably within a week. Thanks for reporting.

If you need a workaround in the meantime you may need to use elementFinished, something like:

elementFinished: function(obj, svg) {
  if (obj instanceof go.Picture) {
    if (svg.getAttribute("xlink:href") === null && svg.getAttribute("href") === null)
    svg.setAttribute("xlink:href", obj.source);
  }
}

should work.

@YanikTheYak
Copy link
Author

Quick work. Thanks so much!!

@simonsarris
Copy link
Collaborator

This should now be fixed in the newest release, GoJS 2.1.32.

@WalterNorthwoods WalterNorthwoods added the bug An error in the library, extensions, documentation, or samples label Dec 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug An error in the library, extensions, documentation, or samples
Projects
None yet
Development

No branches or pull requests

3 participants