highcharts / node-export-server

Highcharts Node.js export server
Other
355 stars 260 forks source link

Render/load images example #137

Closed anrus closed 2 years ago

anrus commented 6 years ago

Expected behaviour

Server should render images in chart

Actual behaviour

Sometimes images are rendered, but not always

Reproduction steps

JSON to post :

{ "asyncRendering": "true", "infile":{ "chart":{ "type":"column" }, "title":{ "text":null }, "xAxis":{ "categories":[ "UK ", ] }, "yAxis":{ "min":0, "title":{ "text":null }, "stackLabels":{ "enabled":true } }, "plotOptions":{ "column":{ "stacking":"normal" } }, "series":[ { "name":"count", "data":[ 44, ] } ] }, "resources":{ "files":"highstock.js,highcharts-more.js,data.js,drilldown.js,funnel.js,heatmap.js,treemap.js,highcharts-3d.js,no-data-to-display.js,map.js,solid-gauge.js,broken-axis.js,http://my-site/js/script.js" } }

my script.js file

`window.onload = function() { Highcharts.setOptions({ chart: { borderWidth: 2, plotBackgroundColor: 'rgba(255, 255, 255, .9)', plotShadow: true, plotBorderWidth: 1, events: { render: function(){ this.renderer.image('https://www.highcharts.com/demo/gfx/sun.png', 170, 120, 20, 20).add(); // return true; } } } });

highexp.done();

};`

command to start server highcharts-export-server --host 127.0.0.1 --port 3003 --logLevel 4

OS: windows 10 node: 8.9.3

cvasseng commented 6 years ago

Hi,

you need to call the highexp.done() function when it's actually done loading the image. Right now you're calling it when the page has been loaded. So you need to listen to the onload event on the image you're loading, and call it in there instead.

You also don't need to supply the highcharts files/modules in the resources list - they're always included. :)

anrus commented 6 years ago

Can you give an example, please. It's not clear for me :(

cvasseng commented 6 years ago

Try something like this:

json:

{ "asyncRendering": "true", "infile":{ "chart":{ "type":"column" }, "title":{ "text":null }, "xAxis":{ "categories":[ "UK ", ] }, "yAxis":{ "min":0, "title":{ "text":null }, "stackLabels":{ "enabled":true } }, "plotOptions":{ "column":{ "stacking":"normal" } }, "series":[ { "name":"count", "data":[ 44, ] } ] }, "resources":{ "files":"http://my-site/js/script.js" } }

script.js:

Highcharts.setOptions({
  chart: {
    borderWidth: 2,
    plotBackgroundColor: 'rgba(255, 255, 255, .9)',
    plotShadow: true,
    plotBorderWidth: 1,
    events: {
    render: function() {
        var image =  this.renderer.image('https://www.highcharts.com/demo/gfx/sun.png', 170, 120, 20, 20);
        image.add();
        image.on('load', function () {
          highexp.done();
        });
    }}
  }
});
KacperMadej commented 6 years ago

@cvasseng Could this work on https://export.highcharts.com/ ? When setting the script.js as JavaScript and with Async Rendering enabled I'm getting Error when processing chart: 0x04 error when performing chart generation: please check your input data in Result Preview after the Preview button click.

cvasseng commented 6 years ago

When using the public export server it should be done in the callback rather as a resource include. It should work regardless though. 0x04 is a weird error to get for it however, as it means that a worker has been restarted while it was processing the request. It could have been caused by a timeout, as in if 'highexp.done wasn't called until the global processing timeout, which is 2.5 seconds IIRC.

KacperMadej commented 6 years ago

I mean in the form on the https://export.highcharts.com/

Async Rendering:

If enabled, the page rendering will wait for any of the included JavaScript resources to call highexp.done(); before rendering the chart. If the function isn't called within 6 seconds, the rendering will timeout.

Load event on images never fires regardless of place used - JavaScript input, Callback input (just the function from render event) and sometimes the image is added, so I guess was loaded and yet no event fired.

cvasseng commented 6 years ago

Sorry, I didn't realize you were talking about the form - I see the error there now. It works on a local instance of the export server, which is strange. There's definitely something not quite right, and it does look like, as you say, that the done function isn't called, causing the processing to time out.

anrus commented 6 years ago

I also have this problem

KacperMadej commented 6 years ago

+1 @cvasseng

Tolerisk commented 6 years ago

+1 @Tolerisk

fcwheeler commented 5 years ago

Sorry, I didn't realize you were talking about the form - I see the error there now. It works on a local instance of the export server, which is strange. There's definitely something not quite right, and it does look like, as you say, that the done function isn't called, causing the processing to time out.

Any update on this?

KacperMadej commented 4 years ago

The problem is only on the public export server, so at exporting.highcharts.com, and when setting up the server from this repo the problem could be resolved as explained in the above comments. It's recommended to set up a custom exporting server for production-ready applications that are using the exporting feature of the node export server.

Should we move these issues about the export.highcharts.com to a better fitting place (if there's any such place)? @cvasseng

fcwheeler commented 4 years ago

@KacperMadej I disagree that this is just related to the export.highcharts.com server. I have been having this issue using the node export server and having the same issue.

KacperMadej commented 4 years ago

@fcwheeler You asked about the server on export.highcharts.com issue status and the info was provided. If you have a problem with an instance of the export server then please go through the comments in this thread and if the suggested solutions are not working for you please provide details for your problems - how to recreate the issue, what have you tried, etc. Local instance issue was recently commented as It works on a local instance of the export server, which is strange., so the issue looks like is only about the export.highcharts.com, so please provide more info if this is not true.

sesolaga commented 4 years ago

Setting "asyncRendering": "true" and using Highcharts.setOptions with highexp.done(); inside doesn't work - highexp.done(); never gets called. Moreover, even the following code (when highexp.done(); is called directly inside render doesn't work:

Highcharts.setOptions({
    chart: {
        borderWidth: 2,
        plotBackgroundColor: 'rgba(255, 255, 255, .9)',
        plotShadow: true,
        plotBorderWidth: 1,
        events: {
            render: function () {
                    highexp.done();
                });
            }
        }
    }
});

Even in this case highexp.done() doesn't get called.

PaulDalek commented 2 years ago

In the new version of export server based on the Puppeteer, options such as asyncRendering or highexp.done() don't occur since the Puppeteer waits for the async code to execute. The easiest way to display the image now is to use customCode option which works a little bit different now but it comes down to the same, which is to run piece of a code before the chart execution. You can test it using the puppeteer related branch: https://github.com/highcharts/node-export-server/tree/enhancement/puppeteer. Here is an example:

options.json

{
  "infile": {
    "chart": {
      "type": "column"
    },
    "series": [{
      "data": [1, 2, 3, 4]
    }]
  },
  "customCode": "./customCode.js"
}

customCode.js

function () {
  Highcharts.setOptions({
    chart: {
      events: {
        render: function() {
          this.renderer.image('https://www.highcharts.com/samples/graphics/sun.png', 170, 120, 20, 20).add();
        }
      }
    }
  });
};

All you need to do is to run the server and then, for example using curl, send a request: curl -H "Content-Type: application/json" -X POST --data-binary @chart.json 127.0.0.1:8080 -o chart.png