Code Monkey home page Code Monkey logo

node-export-server's Introduction

Highcharts Node.js Export Server

Convert Highcharts.JS charts into static image files.

Upgrade Notes for v3.0

In most cases, v3 should serve as a drop-in replacement for v2. However, due to changes in the browser backend, various tweaks related to process handling (e.g., worker counts, and so on) may now have different effects than before.

Significant changes have been made to the API for using the server as a Node.js module. While a compatibility layer has been created to address this, it is recommended to transition to the new API described below. It is worth noting that the compatibility layer may be deprecated at some point in the future.

An important note is that the Export Server now requires Node.js v18.12.0 or a higher version.

Additionally, with the v3 release, we transitioned from HTTP to HTTPS for export.highcharts.com, so all requests sent to our public server now must use the HTTPS protocol.

Changelog

The full change log for all versions can be viewed here.

What & Why

This Node.js application/service converts Highcharts.JS charts into static image files, supporting PNG, JPEG, SVG, and PDF output. The input can be either SVG or JSON-formatted chart options.

The application is versatile and can be used as a CLI (Command Line Interface), an HTTP server, or as a Node.js module.

Use Cases

The primary use case for the Export Server is scenarios requiring headless conversion of charts. Common cases of using include automatic report generation, static caching, and incorporating charts into presentations or other documents.

In addition, the HTTP mode enables you to run your own Export Server for users, reducing reliance on the public https://export.highcharts.com/ server, which has rate limitations.

The HTTP server can be run either independently, integrating with your other applications and services, or in a way that directs the export buttons on your charts to your customized server.

To implement the latter, include the following configuration in your chart options:

{
  exporting: {
    url: "<IP to the self-hosted Export Server>"
  }
}

For systems that generate automatic reports, using the Export Server as a Node.js module is a great fit - especially if your report generator is also written in Node.js. Check here for examples.

Install

First, make sure you have Node.js installed. If not, visit nodejs.org, download and install Node.js for your platform. For compatibility reasons, version 18.12.0 or higher is required.

Once Node.js is installed, proceed to install the Export Server by opening a terminal and typing:

npm install highcharts-export-server -g

or:

git clone https://github.com/highcharts/node-export-server
npm install
npm link

Depending on your Node.js installation method, you might need to create a symlink from nodejs to node. For example, on Linux:

ln -s `which nodejs` /usr/bin/node

Running

To use the Export Server, simply run the following command with the correct arguments:

highcharts-export-server <arguments>

Configuration

There are four main ways of loading configurations:

  • By loading default options from the lib/schemas/config.js file.
  • By loading options from a custom JSON file.
  • By providing configurations via environment variables from the .env file.
  • By passing arguments through command line interface (CLI).

...or any combination of the four. In such cases, the options from the later step take precedence (config file -> custom JSON -> envs -> CLI arguments).

Default JSON Config

The JSON below represents the default configuration stored in the lib/schemas/config.js file. If no .env file is found (more details on the file and environment variables below), these options will be used.

The format, along with its default values, is as follows (using the recommended ordering of core and module scripts below):

{
  "puppeteer": {
    "args": []
  },
  "highcharts": {
    "version": "latest",
    "cdnURL": "https://code.highcharts.com/",
    "coreScripts": [
      "highcharts",
      "highcharts-more",
      "highcharts-3d"
    ],
    "moduleScripts": [
      "stock",
      "map",
      "gantt",
      "exporting",
      "export-data",
      "parallel-coordinates",
      "accessibility",
      "annotations-advanced",
      "boost-canvas",
      "boost",
      "data",
      "data-tools",
      "draggable-points",
      "static-scale",
      "broken-axis",
      "heatmap",
      "tilemap",
      "tiledwebmap",
      "timeline",
      "treemap",
      "treegraph",
      "item-series",
      "drilldown",
      "histogram-bellcurve",
      "bullet",
      "funnel",
      "funnel3d",
      "geoheatmap",
      "pyramid3d",
      "networkgraph",
      "overlapping-datalabels",
      "pareto",
      "pattern-fill",
      "pictorial",
      "price-indicator",
      "sankey",
      "arc-diagram",
      "dependency-wheel",
      "series-label",
      "solid-gauge",
      "sonification",
      "stock-tools",
      "streamgraph",
      "sunburst",
      "variable-pie",
      "variwide",
      "vector",
      "venn",
      "windbarb",
      "wordcloud",
      "xrange",
      "no-data-to-display",
      "drag-panes",
      "debugger",
      "dumbbell",
      "lollipop",
      "cylinder",
      "organization",
      "dotplot",
      "marker-clusters",
      "hollowcandlestick",
      "heikinashi",
      "flowmap"
    ],
    "indicatorScripts": [
      "indicators-all"
    ],
    "customScripts": [
      "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js",
      "https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.34/moment-timezone-with-data.min.js"
    ],
    "forceFetch": false,
    "cachePath": ".cache"
  },
  "export": {
    "infile": false,
    "instr": false,
    "options": false,
    "outfile": false,
    "type": "png",
    "constr": "chart",
    "height": 400,
    "width": 600,
    "scale": 1,
    "globalOptions": false,
    "themeOptions": false,
    "batch": false,
    "rasterizationTimeout": 1500
  },
  "customLogic": {
    "allowCodeExecution": false,
    "allowFileResources": false,
    "customCode": false,
    "callback": false,
    "resources": false,
    "loadConfig": false,
    "createConfig": false
  },
  "server": {
    "enable": false,
    "host": "0.0.0.0",
    "port": 7801,
    "benchmarking": false,
    "proxy": {
      "host": "",
      "port": 8080,
      "timeout": 5000
    },
    "rateLimiting": {
      "enable": false,
      "maxRequests": 10,
      "window": 1,
      "delay": 0,
      "trustProxy": false,
      "skipKey": "",
      "skipToken": ""
    },
    "ssl": {
      "enable": false,
      "force": false,
      "port": 443,
      "certPath": ""
    }
  },
  "pool": {
    "minWorkers": 4,
    "maxWorkers": 8,
    "workLimit": 40,
    "acquireTimeout": 5000,
    "createTimeout": 5000,
    "destroyTimeout": 5000,
    "idleTimeout": 30000,
    "createRetryInterval": 200,
    "reaperInterval": 1000,
    "benchmarking": false
  },
  "logging": {
    "level": 4,
    "file": "highcharts-export-server.log",
    "dest": "log/"
  },
  "ui": {
    "enable": false,
    "route": "/"
  },
  "other": {
    "nodeEnv": "production",
    "listenToProcessExits": true,
    "noLogo": false
  }
}

Custom JSON Config

To load an additional JSON configuration file, use the --loadConfig <filepath> option. This JSON file can either be manually created or generated through a prompt triggered by the --createConfig option.

Environment Variables

These variables are set in your environment and take precedence over options from the lib/schemas/config.js file. They can be set in the .env file (refer to the .env.sample file). If you prefer setting these variables through the package.json, use export command on Linux/Mac OS X and set command on Windows.

Highcharts Config

  • HIGHCHARTS_VERSION: Highcharts version to use (defaults to latest).
  • HIGHCHARTS_CDN_URL: Highcharts CDN URL of scripts to be used (defaults to https://code.highcharts.com/).
  • HIGHCHARTS_CORE_SCRIPTS: Highcharts core scripts to fetch (defaults to ``).
  • HIGHCHARTS_MODULE_SCRIPTS: Highcharts module scripts to fetch (defaults to ``).
  • HIGHCHARTS_INDICATOR_SCRIPTS: Highcharts indicator scripts to fetch (defaults to ``).
  • HIGHCHARTS_FORCE_FETCH: The flag that determines whether to refetch all scripts after each server rerun (defaults to false).
  • HIGHCHARTS_CACHE_PATH: In which directory should the fetched Highcharts scripts be placed (defaults to .cache).
  • HIGHCHARTS_ADMIN_TOKEN: An authentication token that is required to switch the Highcharts version on the server at runtime (defaults to ``).

Export Config

  • EXPORT_TYPE: The format of the file to export to. Can be jpeg, png, pdf or svg (defaults to png).
  • EXPORT_CONSTR: The constructor to use. Can be chart, stockChart, mapChart or ganttChart (defaults to chart).
  • EXPORT_DEFAULT_HEIGHT: The default height of the exported chart. Used when not found any value set (defaults to 400).
  • EXPORT_DEFAULT_WIDTH: The default width of the exported chart. Used when not found any value set (defaults to 600).
  • EXPORT_DEFAULT_SCALE: The default scale of the exported chart. Ranges between 0.1 and 5.0 (defaults to 1).
  • EXPORT_RASTERIZATION_TIMEOUT: The specified duration, in milliseconds, to wait for rendering a webpage (defaults to 1500).

Custom Logic Config

  • CUSTOM_LOGIC_ALLOW_CODE_EXECUTION: Controls whether the execution of arbitrary code is allowed during the exporting process (defaults to false).
  • CUSTOM_LOGIC_ALLOW_FILE_RESOURCES: Controls the ability to inject resources from the filesystem. This setting has no effect when running as a server (defaults to false).

Server Config

  • SERVER_ENABLE: If set to true, the server starts on 0.0.0.0 (defaults to false).
  • SERVER_HOST: The hostname of the server. Additionally, it starts a server listening on the provided hostname (defaults to 0.0.0.0).
  • SERVER_PORT: The port to be used for the server when enabled (defaults to 7801).
  • SERVER_BENCHMARKING: Indicates whether to display a message with the duration, in milliseconds, of specific actions that occur on the server while serving a request (defaults to false).

Server Proxy Config

  • SERVER_PROXY_HOST: The host of the proxy server to use, if it exists (defaults to ``).
  • SERVER_PROXY_PORT: The port of the proxy server to use, if it exists (defaults to ``).
  • SERVER_PROXY_TIMEOUT: The timeout for the proxy server to use, if it exists (defaults to ``).

Server Rate Limiting Config

  • SERVER_RATE_LIMITING_ENABLE: Enables rate limiting for the server (defaults to false).
  • SERVER_RATE_LIMITING_MAX_REQUESTS: The maximum number of requests allowed in one minute (defaults to 10).
  • SERVER_RATE_LIMITING_WINDOW: The time window, in minutes, for the rate limiting (defaults to 1).
  • SERVER_RATE_LIMITING_DELAY: The delay duration for each successive request before reaching the maximum limit (defaults to 0).
  • SERVER_RATE_LIMITING_TRUST_PROXY: Set this to true if the server is behind a load balancer (defaults to false).
  • SERVER_RATE_LIMITING_SKIP_KEY: Allows bypassing the rate limiter and should be provided with the skipToken argument (defaults to ``).
  • SERVER_RATE_LIMITING_SKIP_TOKEN: Allows bypassing the rate limiter and should be provided with the skipKey argument (defaults to ``).

Server SSL Config

  • SERVER_SSL_ENABLE: Enables or disables the SSL protocol (defaults to false).
  • SERVER_SSL_FORCE: If set to true, the server is forced to serve only over HTTPS (defaults to false).
  • SERVER_SSL_PORT: The port on which to run the SSL server (defaults to 443).
  • SERVER_SSL_CERT_PATH: The path to the SSL certificate/key file (defaults to ``).

Pool Config

  • POOL_MIN_WORKERS: The number of minimum and initial pool workers to spawn (defaults to 4).
  • POOL_MAX_WORKERS: The number of maximum pool workers to spawn (defaults to 8).
  • POOL_WORK_LIMIT: The number of work pieces that can be performed before restarting the worker process (defaults to 40).
  • POOL_ACQUIRE_TIMEOUT: The duration, in milliseconds, to wait for acquiring a resource (defaults to 5000).
  • POOL_CREATE_TIMEOUT: The duration, in milliseconds, to wait for creating a resource (defaults to 5000).
  • POOL_DESTROY_TIMEOUT: The duration, in milliseconds, to wait for destroying a resource (defaults to 5000).
  • POOL_IDLE_TIMEOUT: The duration, in milliseconds, after which an idle resource is destroyed (defaults to 30000).
  • POOL_CREATE_RETRY_INTERVAL: The duration, in milliseconds, to wait before retrying the create process in case of a failure (defaults to 200).
  • POOL_REAPER_INTERVAL: The duration, in milliseconds, after which the check for idle resources to destroy is triggered (defaults to 1000).
  • POOL_BENCHMARKING: Indicates whether to show statistics for the pool of resources or not (defaults to false).

Logging Config

  • LOGGING_LEVEL: The logging level to be used. Can be 0 - silent, 1 - error, 2 - warning, 3 - notice, 4 - verbose or 5 benchmark (defaults to 4).
  • LOGGING_FILE: The name of a log file. The logDest option also needs to be set to enable file logging (defaults to highcharts-export-server.log).
  • LOGGING_DEST: The path to store log files. This also enables file logging (defaults to log/).

UI Config

  • UI_ENABLE: Enables or disables the user interface (UI) for the Export Server (defaults to true).
  • UI_ROUTE: The endpoint route to which the user interface (UI) should be attached (defaults to /).

Other Config

  • OTHER_NODE_ENV: The type of Node.js environment. The value controls whether to include the error's stack in a response or not. Can be development or production (defaults to production).
  • OTHER_LISTEN_TO_PROCESS_EXITS: Decides whether or not to attach process.exit handlers (defaults to true).
  • OTHER_NO_LOGO: Skip printing the logo on a startup. Will be replaced by a simple text (defaults to false).

Command Line Arguments

To supply command line arguments, add them as flags when running the application: highcharts-export-server --flag1 value --flag2 value ...

Available options:

  • --infile: The input file should include a name and a type (.json or .svg) and must be a correctly formatted JSON or SVG file (defaults to false).
  • --instr: An input in a form of a stringified JSON or SVG file. Overrides the --infile option (defaults to false).
  • --options: An alias for the --instr option (defaults to false).
  • --outfile: The output filename, accompanied by a type (jpeg, png, pdf, or svg). Ignores the --type flag (defaults to false).
  • --type: The format of the file to export to. Can be jpeg, png, pdf, or svg (defaults to png).
  • --constr: The constructor to use. Can be chart, stockChart, mapChart or ganttChart (defaults to chart).
  • --height: The height of the exported chart. Overrides the option in the chart settings (defaults to 400).
  • --width: The width of the exported chart. Overrides the option in the chart settings (defaults to 600).
  • --scale: The scale of the exported chart. Ranges between 0.1 and 5.0 (defaults to 1).
  • --globalOptions: Either a stringified JSON or a filename containing global options to be passed into the Highcharts.setOptions (defaults to false).
  • --themeOptions: Either a stringified JSON or a filename containing theme options to be passed into the Highcharts.setOptions (defaults to false).
  • --batch: Initiates a batch job with a string containing input/output pairs: "in=out;in=out;.." (defaults to false).
  • --rasterizationTimeout: The specified duration, in milliseconds, to wait for rendering a webpage (defaults to 1500).
  • --allowCodeExecution: Controls whether the execution of arbitrary code is allowed during the exporting process (defaults to false).
  • --allowFileResources: Controls the ability to inject resources from the filesystem. This setting has no effect when running as a server (defaults to false).
  • --customCode: Custom code to execute before chart initialization. It can be a function, code wrapped within a function, or a filename with the .js extension (defaults to false).
  • --callback: JavaScript code to run during construction. It can be a function or a filename with the .js extension (defaults to false).
  • --resources: Additional resources in the form of a stringified JSON. It may contain files (array of JS filenames), js (stringified JS), and css (stringified CSS) sections (defaults to false).
  • --loadConfig: A file containing a pre-defined configuration to use (defaults to false).
  • --createConfig: Enables setting options through a prompt and saving them in a provided config file (defaults to false).
  • --enableServer: If set to true, the server starts on 0.0.0.0 (defaults to false).
  • --host: The hostname of the server. Additionally, it starts a server listening on the provided hostname (defaults to 0.0.0.0).
  • --port: The port to be used for the server when enabled (defaults to 7801).
  • --serverBenchmarking: Indicates whether to display the duration, in milliseconds, of specific actions that occur on the server while serving a request (defaults to false).
  • --proxyHost: The host of the proxy server to use, if it exists (defaults to false).
  • --proxyPort: The port of the proxy server to use, if it exists (defaults to false).
  • --proxyTimeout: The timeout for the proxy server to use, if it exists (defaults to 5000).
  • --enableRateLimiting: Enables rate limiting for the server (defaults to false).
  • --maxRequests: The maximum number of requests allowed in one minute (defaults to 10).
  • --window: The time window, in minutes, for the rate limiting (defaults to 1).
  • --delay: The delay duration for each successive request before reaching the maximum limit (defaults to 0).
  • --trustProxy: Set this to true if the server is behind a load balancer (defaults to false).
  • --skipKey: Allows bypassing the rate limiter and should be provided with the --skipToken argument (defaults to ``).
  • --skipToken: Allows bypassing the rate limiter and should be provided with the --skipKey argument (defaults to ``).
  • --enableSsl: Enables or disables the SSL protocol (defaults to false).
  • --sslForce: If set to true, the server is forced to serve only over HTTPS (defaults to false).
  • --sslPort: The port on which to run the SSL server (defaults to 443).
  • --certPath: The path to the SSL certificate/key file (defaults to ``).
  • --minWorkers: The number of minimum and initial pool workers to spawn (defaults to 4).
  • --maxWorkers: The number of maximum pool workers to spawn (defaults to 8).
  • --workLimit: The number of work pieces that can be performed before restarting the worker process (defaults to 40).
  • --acquireTimeout: The duration, in milliseconds, to wait for acquiring a resource (defaults to 5000).
  • --createTimeout: The duration, in milliseconds, to wait for creating a resource (defaults to 5000).
  • --destroyTimeout: The duration, in milliseconds, to wait for destroying a resource (defaults to 5000).
  • --idleTimeout: The duration, in milliseconds, after which an idle resource is destroyed (defaults to 30000).
  • --createRetryInterval: The duration, in milliseconds, to wait before retrying the create process in case of a failure (defaults to 200).
  • --reaperInterval: The duration, in milliseconds, after which the check for idle resources to destroy is triggered (defaults to 1000).
  • --poolBenchmarking: Indicate whether to show statistics for the pool of resources or not (defaults to false).
  • --logLevel: The logging level to be used. Can be 0 - silent, 1 - error, 2 - warning, 3 - notice, 4 - verbose or 5 - benchmark (defaults to 4).
  • --logFile: The name of a log file. The --logDest option also needs to be set to enable file logging (defaults to highcharts-export-server.log).
  • --logDest: The path to store log files. This also enables file logging (defaults to log/).
  • --enableUi: Enables or disables the user interface (UI) for the Export Server (defaults to false).
  • --uiRoute: The endpoint route to which the user interface (UI) should be attached (defaults to /).
  • --nodeEnv: The type of Node.js environment (defaults to production).
  • --listenToProcessExits: Decides whether or not to attach process.exit handlers (defaults to true).
  • --noLogo: Skip printing the logo on a startup. Will be replaced by a simple text (defaults to false).

HTTP Server

Apart from using as a CLI tool, which allows you to run one command at a time, it is also possible to configure the server to accept POST requests. The simplest way to enable the server is to run the command below:

highcharts-export-server --enableServer 1

Server Test

To test if the server is running correctly, you can send a simple POST request, e.g. by using Curl:

curl -H "Content-Type: application/json" -X POST -d '{"infile":{"title": {"text": "Chart"}, "xAxis": {"categories": ["Jan", "Feb", "Mar"]}, "series": [{"data": [29.9, 71.5, 106.4]}]}}' 127.0.0.1:7801 -o chart.png

The above should result in a chart being generated and saved in a file named chart.png.

SSL

To enable SSL support, add --certPath <path to key/crt> when running the server. Note that the certificate files needs to be named as such:

  • server.crt
  • server.key

HTTP Server POST Arguments

The server accepts the following arguments in a POST request body:

  • infile: Chart options in the form of JSON or stringified JSON.
  • options: An alias for the infile option.
  • data: Another alias for the infile option.
  • svg: A string containing SVG representation to render as a chart.
  • type: The format of an exported chart (can be png, jpeg, pdf or svg). Mimetypes can also be used.
  • constr: The constructor to use (can be chart, stockChart, mapChart or ganttChart).
  • height: The height of the exported chart.
  • width: The width of the exported chart.
  • scale: The scale factor of the exported chart. Use it to improve resolution in PNG and JPEG, for example setting scale to 2 on a 600px chart will result in a 1200px output.
  • globalOptions: Either a JSON or a stringified JSON with global options to be passed into Highcharts.setOptions.
  • themeOptions: Either a JSON or a stringified JSON with theme options to be passed into Highcharts.setOptions.
  • resources: Additional resources in the form of a JSON or a stringified JSON. It may contain files (array of JS filenames), js (stringified JS), and css (stringified CSS) sections.
  • callback: Stringified JavaScript function to execute in the Highcharts constructor.
  • customCode: Custom code to be executed before the chart initialization. This can be a function, code wrapped within a function, or a filename with the .js extension. Both allowFileResources and allowCodeExecution must be set to true for the option to be considered.
  • b64: Boolean flag, set to true to receive the chart in the base64 format instead of the binary.
  • noDownload: Boolean flag, set to true to exclude attachment headers from the response.

The server responds to application/json, multipart/form-data, and URL encoded requests.

CORS is enabled for the server.

It is recommended to run the server using pm2 unless running in a managed environment/container. Please refer to the pm2 documentation for details on how to set this up.

Available Endpoints

  • POST

    • /: An endpoint for exporting charts.
    • /:filename - An endpoint for exporting charts with a specified filename parameter to save the chart to. The file will be downloaded with the {filename}.{type} name (the noDownload must be set to false).
    • /change_hc_version/:newVersion: An authenticated endpoint allowing the modification of the Highcharts version on the server through the use of a token.
  • GET

    • /: An endpoint to perform exports through the user interface the server allows it.
    • /health: An endpoint for outputting basic statistics for the server.

Switching Highcharts Version at Runtime

If the HIGHCHARTS_ADMIN_TOKEN is set, you can use the POST /change_hc_version/:newVersion route to switch the Highcharts version on the server at runtime, ie. without restarting or redeploying the application.

A sample request to change the version to 10.3.3 is as follows:

curl -H 'hc-auth: <YOUR AUTH TOKEN>' -X POST <SERVER URL>/change_hc_version/10.3.3

e.g.

curl -H 'hc-auth: 12345' -X POST 127.0.0.1:7801/change_hc_version/10.3.3

This is useful to e.g. upgrade to the latest HC version without downtime.

Node.js Module

Finally, the Export Server can also be used as a Node.js module to simplify integrations:

// Import the Highcharts Export Server module
const exporter = require('highcharts-export-server');

// Export options correspond to the available CLI/HTTP arguments described above
const options = {
  export: {
    type: 'png',
    options: {
      title: {
        text: 'My Chart'
      },
      xAxis: {
        categories: ["Jan", "Feb", "Mar", "Apr"]
      },
      series: [
        {
          type: 'line',
          data: [1, 3, 2, 4]
        },
        {
          type: 'line',
          data: [5, 3, 4, 2]
        }
      ]
    }
  }
};

// Initialize export settings with your chart's config
const exportSettings = exporter.setOptions(options);

// Must initialize exporting before being able to export charts
await exporter.initExport(exportSettings);

// Perform an export
await exporter.startExport(exportSettings, async (error, info) => {
  // The export result is now in info
  // It will be base64 encoded (info.data)

  // Kill the pool when we are done with it
  await exporter.killPool();
});

CommonJS support

This package supports both CommonJS and ES modules.

Node.js API Reference

highcharts-export-server module

  • server: The server instance which offers the following functions:

    • async startServer(serverConfig): The same as startServer describe below.

    • closeServers(): Closes all servers associated with Express app instance.

    • getServers(): Get all servers associated with Express app instance.

    • enableRateLimiting(options): Enable rate limiting for the server.

      • {Object} limitConfig: Configuration object for rate limiting.
    • getExpress(): Get the Express instance.

    • getApp(): Get the Express app instance.

    • use(path, ...middlewares): Apply middleware(s) to a specific path.

      • {string} path: The path to which the middleware(s) should be applied.
      • {...Function} middlewares: The middleware functions to be applied.
    • get(path, ...middlewares): Set up a route with GET method and apply middleware(s).

      • {string} path: The route path.
      • {...Function} middlewares: The middleware functions to be applied.
    • post(path, ...middlewares): Set up a route with POST method and apply middleware(s).

      • {string} path: The route path.
      • {...Function} middlewares: The middleware functions to be applied.
  • async startServer(serverConfig): Starts an HTTP server based on the provided configuration. The serverConfig object contains all server related properties (see the server section in the lib/schemas/config.js file for a reference).

    • {Object} serverConfig: The server configuration object.
  • async initExport(options): Initializes the export process. Tasks such as configuring logging, checking cache and sources, and initializing the pool of resources happen during this stage. Function that is required to be called before trying to export charts or setting a server. The options is an object that contains all options.

    • {Object} options: All export options.
  • async singleExport(options): Starts a single export process based on the specified options. Runs the startExport underneath.

    • {Object} options: The options object containing configuration for a single export.
  • async batchExport(options): Starts a batch export process for multiple charts based on the information in the batch option. The batch is a string in the following format: "infile1.json=outfile1.png;infile2.json=outfile2.png;...". Runs the startExport underneath.

    • {Object} options: The options object containing configuration for a batch export.
  • async startExport(settings, endCallback): Starts an export process. The settings contains final options gathered from all possible sources (config, env, cli, json). The endCallback is called when the export is completed, with an error object as the first argument and the second containing the base64 respresentation of a chart.

    • {Object} settings: The settings object containing export configuration.
    • {function} endCallback: The callback function to be invoked upon finalizing work or upon error occurance of the exporting process.
  • setOptions(userOptions, args): Initializes and sets the general options for the server instace, keeping the principle of the options load priority. It accepts optional userOptions and args from the CLI.

    • {Object} userOptions: User-provided options for customization.
    • {Array} args: Command-line arguments for additional configuration (CLI usage).
  • async shutdownCleanUp(exitCode): Clean up function to trigger before ending process for the graceful shutdown.

    • {number} exitCode: An exit code for the process.exit() function.
  • log(...args): Logs a message. Accepts a variable amount of arguments. Arguments after level will be passed directly to console.log, and/or will be joined and appended to the log file.

    • {any} args: An array of arguments where the first is the log level and the rest are strings to build a message with.
  • logWithStack(level, error, customMessage): Logs an error message with its stack trace. Optionally, a custom message can be provided.

    • {number} level: The log level.
    • {Error} error: The error object.
    • {string} customMessage: An optional custom message to be logged along with the error.
  • setLogLevel(newLevel): Sets the log level to the specified value. Log levels are (0 = no logging, 1 = error, 2 = warning, 3 = notice, 4 = verbose or 5 = benchmark).

    • {number} newLevel: The new log level to be set.
  • enableFileLogging(logDest, logFile): Enables file logging with the specified destination and log file.

    • {string} logDest: The destination path for log files.
    • {string} logFile: The log file name.
  • mapToNewConfig(oldOptions): Maps old-structured (PhantomJS) options to a new configuration format (Puppeteer).

    • {Object} oldOptions: Old-structured options to be mapped.
  • async manualConfig(configFileName): Allows manual configuration based on specified prompts and saves the configuration to a file.

    • {string} configFileName: The name of the configuration file.
  • printLogo(noLogo): Prints the Highcharts Export Server logo and version information.

    • {boolean} noLogo: If true, only prints version information without the logo.
  • printUsage(): Prints the usage information for CLI arguments. If required, it can list properties recursively.

Examples

Samples and tests for every mentioned export method can be found in the ./samples and ./tests folders. Detailed descriptions are available in their corresponding sections on the Wiki.

Tips, Tricks & Notes

Note about Deprecated Options

At some point during the transition process from the PhantomJS solution, certain options were deprecated. Here is a list of options that no longer work with the server based on Puppeteer:

  • async
  • asyncRendering
  • tmpdir
  • dataOptions
  • queueSize

Additionally, some options are now named differently due to the new structure and categorization. Here is a list of old names and their corresponding new names (old name -> new name):

  • fromFile -> loadConfig
  • sslOnly -> force or sslForce
  • sslPath -> certPath
  • rateLimit -> maxRequests
  • workers -> maxWorkers

If you depend on any of the above options, the optimal approach is to directly change the old names to the new ones in the options. However, you don't have to do it manually, as there is a utility function called mapToNewConfig that can easily transfer the old-structured options to the new format. For an example, refer to the ./samples/module/options_phantomjs.js file.

Note about Chart Size

If you need to set the height or width of the chart, it can be done in two ways:

Set it in the chart config under:

Set it in the exporting config under:

The latter is preferred, as it allows you to set separate sizing when exporting and when displaying the chart on your web page.

Like previously mentioned, there are multiple ways to set and prioritize options, and the height, width and scale are no exceptions here. The priority goes like this:

  1. Options from the export section of the provided options (CLI, JSON, etc.).
  2. The sourceHeight, sourceWidth and scale from the chart.exporting section of chart's Highcharts options.
  3. The height and width from the chart section of chart's Highcharts options.
  4. The sourceHeight, sourceWidth and scale from the chart.exporting section of chart's Highcharts global options, if provided.
  5. The height and width from the chart section of chart's Highcharts global options, if provided.
  6. If no options are found to this point, the default values will be used (height = 400, width = 600 and scale = 1).

Note about Event Listeners

The Export Server attaches event listeners to process.exit, uncaughtException and signals such as SIGINT, SIGTERM and SIGHUP. This is to make sure that there are no memory leaks or zombie processes if the application is unexpectedly terminated.

Listeners are also attached to handle uncaught exceptions. If an exception occurs, the entire pool and browser instance are terminated, and the application is shut down.

If you do not want this behavior, start the server with --listenToProcessExits 0 or --listenToProcessExits false.

Be aware though, that if you disable this and you do not take great care to manually kill the pool of resources along with a browser instance, your server will bleed memory when the app is terminated.

Note about Resources

If --resources argument is not set and a file named resources.json exists in the folder from which the CLI tool was ran, it will use the resources.json file.

Note about Worker Count & Work Limit

The Export Server utilizes a pool of workers, where each worker is a Puppeteer process (browser instance's page) responsible for the actual chart rasterization. The pool size can be set with the --minWorkers and --maxWorkers options, and should be tweaked to fit the hardware on which you are running the server.

It is recommended that you start with the default 4, and work your way up (or down if 8 is too many for your setup, and things are unstable) gradually. The tests/other/stress-test.js script can be used to test the server and expects the server to be running on port 7801.

Each of the workers has a maximum number of requests it can handle before it restarts itself to keep everything responsive. This number is 40 by default, and can be tweaked with --workLimit. As with --minWorkers and --maxWorkers, this number should also be tweaked to fit your use case. Also, the --acquireTimeout option is worth to mention as well, in case there would be problems with acquiring resources. It is set in miliseconds with 5000 as a default value. Lastly, the --createTimeout and --destroyTimeout options are similar to the --acquireTimeout but for resource's create and destroy actions.

Usage

Injecting the Highcharts Dependency

In order to use the Export Server, Highcharts needs to be injected into the export template (see the ./templates folder for reference).

Since version 3.0.0, Highcharts is fetched in a Just-In-Time manner, making it easy to switch configurations. It is no longer required to explicitly accept the license, as in older versions. However, the Export Server still requires a valid Highcharts license to be used.

Using in Automated Deployments

Since version 3.0.0, when using in automated deployments, the configuration can be loaded either using environment variables or a JSON configuration file.

For a reference on available variables, refer to the configuration section above.

If you are using the Export Server as a dependency in your application, depending on your setup, it may be possible to set the environment variables in the package.json file as follows:

On Linux/Mac OS X:

{
  "scripts": {
    "preinstall": "export <variable1>=<value1>&&<variable2>=<value2>&&..."
  }
}

On Windows:

{
  "scripts": {
    "preinstall": "set <variable1>=<value1>&&<variable2>=<value2>&&..."
  }
}

Library Fetches

When fetching the built Highcharts library, the default behaviour is to fetch them from code.highcharts.com.

Installing Fonts

Does your Linux server not have Arial or Calibri? Puppeteer uses the system installed fonts to render pages. Therefore the Highcharts Export Server requires fonts to be properly installed on the system in order to use them to render charts.

Note that the default font-family config in Highcharts is "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif".

Fonts are installed differently depending on your system. Please follow the below guides for font installation on most common systems.

Mac OS X

Install your desired fonts with the Font Book app, or place it in /Library/Fonts/ (system) or ~/Library/Fonts/ (user).

Linux

Copy or move the TTF file to the /usr/share/fonts/truetype (may require sudo privileges):

mkdir -p /usr/share/fonts/truetype
cp yourFont.ttf /usr/share/fonts/truetype/
fc-cache -fv

Windows

Copy or move the TTF file to C:\Windows\Fonts\:

copy yourFont.ttf C:\Windows\Fonts\yourFont.ttf

Google fonts

If you need Google Fonts in your custom installation, they can be had here: https://github.com/google/fonts.

Download them, and follow the above instructions for your OS.

Performance Notice

In cases of batch exports, using the HTTP server is faster than the CLI. This is due to the overhead of starting Puppeteer for each job when using the CLI.

So it is better to write a bash script that starts the server and then performs a set of POSTS to it through e.g. Curl if not wanting to host the Export Server as a service.

Alternatively, you can use the --batch switch if the output format is the same for each of the input files to process:

highcharts-export-server --batch "infile1.json=outfile1.png;infile2.json=outfile2.png;..."

Other switches can be combined with this switch.

System Requirements

The system requirements largely depend on your use case.

The application is largely CPU and memory bound, so for heavy-traffic situations, it needs a fairly beefy server. It is recommended that the server has at least 1GB of memory regardless of traffic, and more than one core.

License

MIT. Note that a valid Highcharts License is also required to do exports.

node-export-server's People

Contributors

actions-user avatar antonai avatar astronaut1712 avatar beck24 avatar blalasaadri avatar cvasseng avatar davidroyapp avatar denyllon avatar dependabot[bot] avatar goransle avatar jeffkenney avatar jszuminski avatar kamilkulig avatar larsac07 avatar madepiet avatar markathomas avatar pauldalek avatar pawl-bb avatar tonylukasavage avatar torsteinhonsi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-export-server's Issues

Does endOnTick have any issue?

Hey guys,

I have the exact same chart object (copies/pasted) that is actually not exact the same result when I export with this package. I'm using startOnTick: true and endOnTick: true on my object.

Here is it on the web page:
highcharts_web

And here is the same object exported by node-export-server:
highcharts_server

Is that a bug or is something I have to do to fix?

Google fonts won't load

Phantom/WebKit apparently won't actually load google fonts unless there's a reference to them in the DOM.

This is problematic both in the sense that the required font won't be loaded, but even more so because the reference to the included font is in place regardless, causing it to think that the font is loaded too. The result is that all text is invisible.

Maps module

Hi,

This project looks very promising! I don't see all modules loaded, for our project we need the maps module. Will this also be included?

Thanks and keep up the great work!
J.

highcharts-export-server server mode does not work

Steps followed:
> sudo npm install highcharts-export-server -g
> highcharts-export-server --enableServer 1
> curl -H "Content-Type: application/json" -X POST -d '{"infile":{"title": {"text": "Steep Chart"}, "xAxis": {"categories": ["Jan", "Feb", "Mar"]}, "series": [{"data": [29.9, 71.5, 106.4]}]}}' 127.0.0.1:7801 -o mychart.png

Now I get the following error in the highcharts export server and it quits immediately:

uncaughtException: [TypeError: undefined is not a function]

Also the phantomjs instances created are not killed.

Fonts are not loading despite being loaded

I'm running the node-export-server on a docker container on RHEL 7.2 and am having trouble exporting anything other than an SVG. PDF's, PNG's and JPEG's are all missing the text that exists in the SVG. I assumed that this would be due to missing fonts, but I have installed arial (one of the required fonts?) and I am still getting no text on my exports. I have run fc-cache -fv to update the cache, and fc-list shows /usr/share/fonts/truetype/arial.ttf: Arial:style=Regular,Normal,obyฤejnรฉ,Standard,ฮšฮฑฮฝฮฟฮฝฮนฮบฮฌ,Normaali,Normรกl,Normale,Standaard,Normalny,ะžะฑั‹ั‡ะฝั‹ะน,Normรกlne,Navadno,thฦฐแปng,Arrunta.

The highcharts log is not particularly helpful as it only sees the SVG come in and then parses and finishes. Log level 3:
Mon Feb 13 2017 18:25:50 GMT+0000 (UTC) [verbose] got incoming HTTP request 7205a409487b46c79144861969f37023 Mon Feb 13 2017 18:25:50 GMT+0000 (UTC) [verbose] starting export Mon Feb 13 2017 18:25:50 GMT+0000 (UTC) [verbose] parsing input as svg Mon Feb 13 2017 18:25:50 GMT+0000 (UTC) [verbose] phantom - received work, finding available worker Mon Feb 13 2017 18:25:50 GMT+0000 (UTC) [verbose] phantom - found available worker Mon Feb 13 2017 18:25:50 GMT+0000 (UTC) [verbose] phantom 4 - starting work Mon Feb 13 2017 18:25:51 GMT+0000 (UTC) [notice] phantom worker 4 finished work 7205a409487b46c79144861969f37023 in 130 ms

The SVG uses font-family: <text x="2" y="14" style="font-size:12px;font-family:&quot;lucida grande&quot;, &quot;lucida sans unicode&quot;, arial, helvetica, sans-serif;color:#666666;fill:#666666;">From</text>

Any idea on other steps I could take to debug?

1.0.15 broke exporting

Export doesn't work:
curl -H "Content-Type: application/json" -X POST -d '{"infile":{"title": {"text": "Steep Chart"}, "xAxis": {"categories": ["Jan", "Feb", "Mar"]}, "series": [{"data": [29.9, 71.5, 106.4]}]}}' 127.0.0.1:7801 -o mychart.png

By the way version 1.0.14 is working

mychart2222

Export Map bubble

Hello,

There is a way to allow export server to correctly export map bubble, at the moment I got only the map without bubble, any suggestion ?

tnx in advance

Can't get the export tool to run!

If I have nodejs-legacy installed, I get this

/usr/local/lib/node_modules/highcharts-export-server/node_modules/express-form-data/express-form-data.js:3
let multipart = require('connect-multiparty');
^^^
SyntaxError: Unexpected strict mode reserved word
at Module._compile (module.js:439:25)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object. (/usr/local/lib/node_modules/highcharts-export-server/lib/server.js:36:18)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)

if I uninstall it, and then 'apt-get install node' and run highcharts-export-server, I get no errors, it doesn't matter what parameters I pass, it just does nothing
agent@xxx:$ highcharts-export-server --enableServer 1
agent@xxx:
$

What am I doing wrong?

PNG image export adds {{js}} tag

I am using node-export-server in my node js app to export highchart graphs to png. But, there is a slight bug that writes {{js}} on top of image.

One thing that I have found out is, while exporting svg this problem does not occur and highcaharts.com link gets placed at bottom, but in png the link disappears and {{js}} tag gets written.

Unable to export chart using HTTP server

I'm new to this, but I cannot seem to get the HTTP server to return an actual chart. All i get are (image) files with the text "Chart input data error - TypeError: Request keys of a value that is not an object"

I've tried nodejs v4 and v6
I've tried highcharts-export-server v1.0.10, v1.0.14 and v1.0.15

Once starting the server, I've tried two charts:

curl -H "Content-Type: application/json" -X POST -d '{"infile":{"title": {"text": "Steep Chart"}, "xAxis": {"categories": ["Jan", "Feb", "Mar"]}, "series": [{"data": [29.9, 71.5, 106.4]}]}}' localhost:1337 -o mychart1.png

curl -H "Content-Type: application/json" -X POST -d '{"scale":1,"constr":"Chart","width":600,"infile":{"chart":{"type":"bar"},"title":{"text":"Fruit Consumption"},"xAxis":{"categories":["Apples","Bananas","Oranges"]},"yAxis":{"title":{"text":"Fruit eaten"}},"series":[{"name":"Jane","data":[1,0,4]},{"name":"John","data":[5,7,3]}]}}' localhost:1337 -o mychart2.png

Perhaps the problem is in the way I'm installing everything? Working on Ubuntu 14.04, installed the whole lot using:

curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install nodejs
sudo ln -s /usr/bin/nodejs /usr/bin/node
sudo ln -s /usr/bin/nodejs /usr/sbin/node
sudo npm install [email protected] -g

Finally, starting the HTTP server itself using:

highcharts-export-server --enableServer 1 --host localhost --port 1337 --logLevel 4

Since the server runs --logLevel 4, this is the output produced by the server process for each of the two chart generation attempts above:

{ outfile: 'tmp/chart.3d33ee22cb254ecd941e8d058ef7b89d.png',
instr:
{ title: { text: 'Steep Chart' },
xAxis: { categories: [Object] },
series: [ [Object] ],
chart: { width: 600, height: 400 },
exporting: { enabled: false } },
constr: undefined,
type: 'png',
scale: undefined,
width: false,
svg: undefined,
resources: false,
callback: false,
styledMode: false,
asyncRendering: false,
globalOptions: false,
themeOptions: 'false',
customCode: false,
dataOptions: false,
async: false,
reqID: '3d33ee22cb254ecd941e8d058ef7b89d' }

{ outfile: 'tmp/chart.d65b4964f13a420290c2b22fa801a366.png',
instr:
{ chart: { type: 'bar', width: 600, height: 400 },
title: { text: 'Fruit Consumption' },
xAxis: { categories: [Object] },
yAxis: { title: [Object] },
series: [ [Object], [Object] ],
exporting: { enabled: false } },
constr: 'Chart',
type: 'png',
scale: 1,
width: 600,
svg: undefined,
resources: false,
callback: false,
styledMode: false,
asyncRendering: false,
globalOptions: false,
themeOptions: 'false',
customCode: false,
dataOptions: false,
async: false,
reqID: 'd65b4964f13a420290c2b22fa801a366' }

Fresh out of ideas, so anything welcome.

Can't install highcharts server.

Hey,

I had previously been able to install the highcharts-export-server. Today, I tried to install using the commands mentioned here.

I've added the complete stacktrace below. Let me know if I'm doing anything wrong.

> [email protected] install /home/parse/node-export-server/node_modules/phantomjs-prebuilt
> node install.js

module.js:327
    throw err;
    ^

Error: Cannot find module 'is-property'
    at Function.Module._resolveFilename (module.js:325:15)
    at Function.Module._load (module.js:276:25)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (/home/parse/node-export-server/node_modules/request/node_modules/har-validator/node_modules/is-my-json-valid/node_modules/generate-object-property/index.js:1:80)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)
npm ERR! Linux 4.4.0-53-generic
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "install"
npm ERR! node v4.7.2
npm ERR! npm  v2.15.11
npm ERR! code ELIFECYCLE

npm ERR! [email protected] install: `node install.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script 'node install.js'.
npm ERR! This is most likely a problem with the phantomjs-prebuilt package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node install.js
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs phantomjs-prebuilt
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!
npm ERR!     npm owner ls phantomjs-prebuilt
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /home/parse/node-export-server/npm-debug.log

Node-uuid is deprecated

There's a uuid module. If the old module is required, the documentation should mention that you'll get a warning when installing the server.

Issues with json infiles that contain functions

Hi, I would like to use json infiles that contain functions, e.g. for formatting labels. It seems that currently this is not possible, I get the following error when exporting to svg:

uncaughtException: [TypeError: Cannot read property 'trim' of undefined]

I use this chart config file and call the exporter via node as you stated here. If I remove the functions, everything works fine.

On export.highcharts.com, however, the chart is rendered correctly. Thanks for your help!

cannot loop trigger the exporting

i have an issue regarding of this

the code is
`// i want only 2 table this is as example
//Export settings
var exportSettings = {
type: 'png',
options: {
title: {
text: 'My Chart'
},
xAxis: {
categories: ["Jan", "Feb", "Mar", "Apr", "Mar", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
},
series: [
{
type: 'line',
data: [1, 3, 2, 4]
},
{
type: 'line',
data: [5, 3, 4, 2]
}
]
}
};

//Set up a pool of PhantomJS workers

for(var i = 0; i < chart.length; i++) {
exporter.initPool();

//Perform an export
/*
Export settings corresponds to the available CLI arguments described
above.
*/
exporter.export(exportSettings, function (err, res) {
chart[0].image = res.data
console.log(i)
exporter.killPool();
});
}
`
expectation : it should loop twice

reality : it just rendering final array data

anybody had an idea for this ?

script for automatic installation

Installing this module with NPM npm install -g highcharts-export-server needs human interaction at the middle of the process:

When these questions appear:

Agree to the license terms? y/n:  (no)
Select your Highcharts version (e.g. 4.2.2)::  (latest)
Include Maps? (requires Maps license):  (no)
Enable styled mode? (requires Highcharts/Highstock 5 license):  (no)

I wonder if it's possible to automate these part to be installed within a fully automated script?

Export Server not rendering images

I have been experimenting with various ways to embed images in HighCharts, and none of them seem to work on the highcharts-export-server.

For example, the following chart renders, but without the images:
http://jsfiddle.net/ZZ7Kd/135/
I have also tried data URIs with formatter(), local images, etc.

Should it be possible for it to render images, or is this an insurmountable permissions issue?
Thanks!

Export CLI : --batch is not working

when i pass only one json input file as parameter with --batch, it is not giving any error but it is also not generating output file. when i pass multiple input=output files with --batch. following is the error i am getting.
image

[Windows] No success in getting export server to accept input via custom server

I have no issues running the highcharts-export-server module when producing charts without the --exportServer flag. The issues arise if I attempt to set up my own export server.

I have been trying to test the server as described by the ReadMe on main page using curl, i.e.

curl -H "Content-Type: application/json" -X POST -d '{"infile":{"title": {"text": "Steep Chart"}, "xAxis": {"categories": ["Jan", "Feb", "Mar"]}, "series": [{"data": [29.9, 71.5, 106.4]}]}}' 127.0.0.1:7801 -o mychart.png

I am starting the highcharts server:

highcharts-export-server --enableServer 1

I know that the server is getting the input due to the errors (stated below), so it isn't an issue with communicating with the server. The issue seems to be that no matter what I've tried, the JSON string doesn't get accepted due to parsing errors. Here are the errors returned from using the curl command as stated in the readme:

highcharts:

SyntaxError: Unexpected token '
at parse (C:\highcharts\export\node_modules\highcharts-export-server\node_mo
dules\body-parser\lib\types\json.js:83:15)
at C:\highcharts\export\node_modules\highcharts-export-server\node_modules\b
ody-parser\lib\read.js:116:18
at invokeCallback (C:\highcharts\export\node_modules\highcharts-export-serve
r\node_modules\raw-body\index.js:262:16)
at done (C:\highcharts\export\node_modules\highcharts-export-server\node_mod
ules\raw-body\index.js:251:7)
at IncomingMessage.onEnd (C:\highcharts\export\node_modules\highcharts-expor
t-server\node_modules\raw-body\index.js:307:7)
at emitNone (events.js:86:13)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickCallback (internal/process/next_tick.js:104:9)

So I attempted to write the JSON string escaped, since Windows may have an issue, so here is my second attempt using curl:

curl -H "Content-Type: application/json" -X POST -d "{"infile":"{"title": {"text": "Steep Chart"}, "xAxis": {"categories": ["Jan", "Feb", "Mar"]}, "series": [{"data": [29.9, 71.5, 1
06.4]}]}"}" 127.0.0.1:7801 -o mychart.png

This time, curl returned "good" information, (I was getting "globbing" errors before):

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1266 100 1128 100 138 18193 2225 --:--:-- --:--:-- --:--:-- 18193

However highcharts server now returns these errors:

SyntaxError: Unexpected token t in JSON at position 13
at Object.parse (native)
at parse (C:\highcharts\export\node_modules\highcharts-export-server\node_mo
dules\body-parser\lib\types\json.js:88:17)
at C:\highcharts\export\node_modules\highcharts-export-server\node_modules\b
ody-parser\lib\read.js:116:18
at invokeCallback (C:\highcharts\export\node_modules\highcharts-export-serve
r\node_modules\raw-body\index.js:262:16)
at done (C:\highcharts\export\node_modules\highcharts-export-server\node_mod
ules\raw-body\index.js:251:7)
at IncomingMessage.onEnd (C:\highcharts\export\node_modules\highcharts-expor
t-server\node_modules\raw-body\index.js:307:7)
at emitNone (events.js:86:13)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)

I even took the time to write a small Java program (on Windows) to set up a simple http POST call to see if I can successfully send JSON data to the server. Again, server responds, but with same errors as above. The content header is "application/json", as stated in the documentation.

Unless I am doing something obviously wrong, there seems to be something inconsistent or not being explicitly stated as to how to successfully produce a chart using the export server in Windows using a simple HTTP post (note: I am not using JavaScript -- it's either Java or from command-line (using curl)). The stumbling block seems to the the JSON string and a parsing failure.

Thanks for looking into this.

console.log in 1.0.15 release

There is a console.log(exportOptions) in the most recent version. I was unable to find it in the source code, but it definitely exists in the NPM package.

In highcharts-export-server/lib/chart.js Line 143

export server very low

Hello,
Export server not working when i start server with forever.

module.js:471
throw err;
^

Error: Cannot find module 'colors'
at Function.Module._resolveFilename (module.js:469:15)
at Function.Module._load (module.js:417:25)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object. (/home/ubuntu/highcharts/node-export-server/lib/index.js:28:1)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
error: Forever detected script exited with code: 1

I solve this first issue by creating repo node_module and copy all module needed.
After that, server start, but it very slow when query server

Thanks

[Guidance/Question] HTTP server performance and PhantomJS workers

I'm trying to wrap my head around the basics I guess. Some background:

We've been running separate PhantomJS instances proxied by nginx to create charts using highcharts-convert.js and done some performance testing. The end result has been that as PhantomJS is nodejs, there's only one thread running and doing the heavy lifting. So generally you are always limited by the number of cores the machine has. We've run tests by having say 100 large charts generated using 4 core machine with both 4 and 8 PhantomJS instances. The end result is the same, you won't get results any faster when you add more PhantomJS processes than you have CPU cores.

So now when looking at the defaults and them having 25 default workers it seems quite excessive. Are the workers just a way to create (memory-expensive) work queue?

I would think that ideally one would want to host about the same amount of workers (or say 1.5x due to killing/cleaning them) as there are CPU cores available. But if I remember correctly you start to get timeouts from export server because there's a timeout https://github.com/highcharts/node-export-server/blob/master/lib/phantompool.js#L78.

Thanks for creating this version of exporter, it's looking pretty promising for us!

Can't render chinese character

possible to render chinese ?

image

{"data":{"chart":{"type":"area"},"title":{"text":"\u4f60\u597d"},"subtitle":{"text":"Source: Wikipedia.org"},"xAxis":{"categories":["1750","1800","1850","1900","1950","1999","2050"],"tickmarkPlacement":"on","title":{"enabled":false}},"yAxis":{"title":{"text":"Percent"}},"plotOptions":{"area":{"stacking":"percent","lineColor":"#ffffff","lineWidth":1,"marker":{"lineWidth":1,"lineColor":"#ffffff"}}},"series":[{"name":"\u65e5","data":[502,635,809,947,1402,3634,5268]},{"name":"Africa","data":[106,107,111,133,221,767,1766]},{"name":"Europe","data":[163,203,276,408,547,729,628]},{"name":"America","data":[18,31,54,156,339,818,1201]},{"name":"Oceania","data":[2,2,2,6,13,30,46]}]}}

Highcharts export server log does not log in docker container

I have not tested this outside of a container but I have found that when the export server is put into a docker container it will not write to the log when a request is made. It does have permissions to write to the log file (it writes to it saying that the server has started).

Command run to start server on the container: highcharts-export-server --enableServer 1 --host <domain_name> --port 80 --logDest /var/log --styledMode 1 --logLevel 3

I will make a request to the server and receive a document back but nothing is written to the log file.

Exception: no input given

Its seems even trying the example as node.js client, with all necessary options passed, the returned callback returns no input given

Some debugging logs:

Payload:

screen shot 2016-12-16 at 12 58 15 pm

Response:

screen shot 2016-12-16 at 12 58 27 pm

This goes through

log(1, 'no input specified', JSON.stringify(exportOptions, undefined, ' '));
.

forever example

The docs suggest using https://github.com/foreverjs/forever but there's no example of how to do that.

I'm fairly new to nodejs and although I was able to get the server installed and working it's not clear how to do that in the context of forever.

This is what I've tried

create a file highcharts-node.js

// include the exporter module
const exporter = require('highcharts-export-server');

exporter.startServer(7801);

Then try to run it with forever:

forever start -l forever-highcharts.log -a -o highcharts.log -e error.log highcharts-node.js

I see it attempt to start the process then it fails. The error is shown in the logs as

Error: Cannot find module 'highcharts-export-server'
    at Function.Module._resolveFilename (module.js:470:15)
    at Function.Module._load (module.js:418:25)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/vagrant/netfloimg/highcharts-server.js:2:18)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
error: Forever detected script exited with code: 1

When I run require('highcharts-export-server'); in the node command prompt I get a "cannot find module" error.

Invalid object in cli.js

In cli.js, theres this snippet:

optionsMeta[option] = { default: def, help };

The line with help gives an error which, I think, is because its not a valid json. When I changed to "help":help, it works fine.

Exporting with setted -callback parameter throws an error

Hi,
if I add a callback-file I get folllowing error with the cli:
phantom worker 1 unexpected data - SyntaxError: Unexpected token ':'
undefined:1 in appendChild
:15
:16

Command:
highcharts-export-server -infile 'c:\temp\input.js' -outfile 'c:\temp\test.png' -callback 'c:\temp\callback.js

input.js:

{
    "xAxis": {
        "categories": [
            "Jan",
            "Feb"
        ]
    },
    "series": [
        {
            "data": [1,3],
            "type": "line"
        }
    ]
}

callback.js:

function(chart) {
    chart.renderer.label('This label is added in the callback', 100, 100)
    .attr({
        fill : '#90ed7d',
        padding: 10,
        r: 10,
        zIndex: 10
    })
    .css({
        color: 'black',
        width: '100px'
    })
    .add();
}

OS: Windows 10

Let me know, if you need further information.

UUID has minimum version

My project has UUID version 2.0.1 installed, and because this project's package.json requires any uuid version, it won't install its own version of UUID. I get the following error:

uncaughtException: { Error: Cannot find module 'uuid/v4'
    at Function.Module._resolveFilename (module.js:469:15)
    at Function.Module._load (module.js:417:25)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (./node_modules/highcharts-export-server/lib/server.js:38:14)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3) code: 'MODULE_NOT_FOUND' }

After I upgrade my project's version of UUID, I was able to successfully run the highcharts export server.

I'm not sure which version of UUID added the uuid/v4 option, so I'm not sure what the absolute minimum is. UUID version 3.0.1 (the current latest) worked for me though.

Additionally, to prevent other potential breaking changes from other libraries, you may also want to specify minimum version of the other dependencies that are listed as "*".

Exporting as base64

Rather than use an outfile, I would like to get the base64 encoded version of the image returned from the server. When I POST to the server without the outfile option, the response is not base64 (I don't know how it is encoded but I can't read it properly in any text editor).

Is there a way to specify base64 encoded string as a response?

HTTP mode - use of batch and output file name

How to use batch option and output file name with HTTP mode?

For below example outfile is not working.
{"infile":{"title": {"text": "Steep Chart"}, "xAxis": {"categories": ["Jan", "Feb", "Mar"]}, "series": [{"data": [29.9, 71.5, 106.4]}]}
,"outfile":"graph","async":true}

Callback option not working

I try use the callback option as described here: http://www.highcharts.com/docs/export-module/render-charts-serverside. But its seems this options work another at your package.

My code:

//Include the exporter module
const exporter = require('highcharts-export-server');

//Export settings
var exportSettings = {
  type: 'pdf',
  instr: {
    title: {
      text: 'My Chart'
    },
    xAxis: {
      categories: ["Jan", "Feb", "Mar", "Apr", "Mar", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
    },
    series: [
      {
        type: 'line',
        data: [1, 3, 2, 4]
      },
      {
        type: 'line',
        data: [5, 3, 4, 2]
      }
    ]
  },
  callback: function (chart) { chart.renderer.arc(200, 150, 100, 50, -Math.PI, 0).attr({ fill: '#FCFFC5', stroke: 'black', 'stroke-width': 1 }).add(); },
  outfile: 'test.pdf',
};

//Set up a pool of PhantomJS workers
exporter.initPool();

/*
 Export settings corresponds to the available CLI arguments described
 above.
 */
exporter.export(exportSettings, function (err, res) {
  exporter.killPool();
});

Additional documentation

Is there any additional documentation about running it as a server? The readme simply says to run

highcharts-export-server --enableServer

Which gives me this output:

__  ___       __         __               __
   / / / (_)___ _/ /_  _____/ /_  ____ ______/ /______
  / /_/ / / __ `/ __ \/ ___/ __ \/ __ `/ ___/ __/ ___/
 / __  / / /_/ / / / / /__/ / / / /_/ / /  / /_(__  )
/_/ /_/_/\__, /_/ /_/\___/_/ /_/\__,_/_/   \__/____/
        ____//___/                  __     _____
       / ____/  ______  ____  _____/ /_   / ___/___  ______   _____  _____
      / __/ | |/_/ __ \/ __ \/ ___/ __/   \__ \/ _ \/ ___/ | / / _ \/ ___/
     / /____>  </ /_/ / /_/ / /  / /_    ___/ /  __/ /   | |/ /  __/ /
    /_____/_/|_/ .___/\____/_/   \__/   /____/\___/_/    |___/\___/_/
              /_/

Fri Dec 02 2016 20:05:54 GMT-0800 (PST) [error] no input specified {
  "infile": false,
  "outfile": false,
  "instr": false,
  "options": false,
  "styledMode": false,
  "allowFileResources": true,
  "type": "png",
  "scale": 1,
  "resources": false,
  "callback": false,
  "width": false,
  "constr": "Chart",
  "tmpdir": "tmp/",
  "enableServer": false,
  "host": "",
  "port": 7801,
  "rateLimit": false,
  "logLevel": 2,
  "workers": false,
  "logDest": false,
  "batch": false,
  "sslPath": false,
  "fromFile": false,
  "async": true
}

Then it says to test with this command:

curl -H "Content-Type: application/json" -X POST -d '{"infile":{"title": {"text": "Steep Chart"}, "xAxis": {"categories": ["Jan", "Feb", "Mar"]}, "series": [{"data": [29.9, 71.5, 106.4]}]}}' 127.0.0.1:7801 -o mychart.png

Which fails to connect:

curl -H "Content-Type: application/json" -X POST -d '{"infile":{"title": {"text": "Steep Chart"}, "xAxis": {"categories": ["Jan", "Feb", "Mar"]}, "series": [{"data": [29.9, 71.5, 106.4]}]}}' 127.0.0.1:7801 -o mychart.png
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (7) Failed to connect to 127.0.0.1 port 7801: Connection refused

Best way to export same chart in multiple themes and filetypes?

Apologies if this is covered somewhere, but I'm new to the library and still wrapping my head around things. ๐Ÿ™‚

I'm working on a project where we have the same set of data, but we want to export charts in two formats (SVG and PNG) and two styles (for separate websites with different brand guidelines). Ideally this would happen in Node rather than via the CLI, as the rest of our project is Node-based so it'll be a bit easier to maintain.

As an example, my project directory looks a little like this:

โ”œโ”€โ”€ charts
โ”‚   โ”œโ”€โ”€ chart1.json
โ”‚   โ”œโ”€โ”€ chart2.json
โ”‚   โ””โ”€โ”€ chart3.json
โ””โ”€โ”€ themes
    โ”œโ”€โ”€ theme1.json
    โ””โ”€โ”€ theme2.json

I'm unclear from the documentation and issues I've read if it's actually possible to set the theme in this way, or if I need to compile the themes as JS files in resources that assign Highcharts.theme.

Thanks in advance for your help!

Running node-export-server on AWS Lambda

We are attempting to run this from AWS Lambda.

However, it runs into an EPIPE exception. Here are the logs:

  • attaching exit listeners to the process..
  • Pool started:
    maxWorkers: 1
    initialWorkers: 1
    workLimit: 60
  • listening to process exit: true
  • phantom 1 - spawning worker
  • starting export
  • attempting to export from raw input
  • phantom - received work, finding available worker
  • phantom - found available worker
  • phantom 1 - starting work
  • Error: write EPIPE
    at Object.exports._errnoException (util.js:870:11)
    at exports._exceptionWithHostPort (util.js:893:20)
    at WriteWrap.afterWrite (net.js:763:14)
  • terminating, killing all running phantom processes

Your README specifically mentions Beanstalk as a way to run this. Do you know why the EPIPE exception happens on Lambda, and if it is possible to run it there?

If not, then we will put it on Beanstalk. Thank you!

Export Server Returning : "Chart input data error"

i am running Export server by --enableServer=true.
i am sending the same request data on server that is given as example. sending a curl request as follow :
curl -H "Content-Type: application/json" -X POST -d '{"infile":{"title":{"text":"Steep Chart"},"xAxis":{"categories":["Jan","Feb","Mar"]},"series":[{"data":[29.9, 71.5, 106.4]}]}}' 127.0.0.1:8088 -o mychart.png

following the error output i am getting instead of chart's png image :
image

Using highcharts theme

Hi,

I use your great application as node module and have couple of questions.

It is possible to use highcharts theme like dark-unica for my charts?

How can I exit from node script after done all tasks?

Thanks and keep up the good work

Batch export errors

Hi, While i use highcharts-export-server with --batch options for multiple export, it's run out errors

  1. ReferenceError: func is not defined

qq 20170224161339

it can be fixed by change func to funs in your code bin\cli.js line 229

async.waterfall(func, function() {    // func should change to funs as defined above
  main.killPool();
});
  1. while i fixed error 1, it's run out 'uncaughtException: [TypeError: worker.ondone is not a function]'

qq 20170224161933

I think you should test batch export, thanks

CLI documentation

Hi,

I setup the npm globally

npm install highcharts-export-server -g

Now, I want to call from the CLI the code...
highcharts-export-server --logLevel 4 --logDest '/path/to/CLI/highcharts.log' --width 1200 --type 'png' --constr 'Chart' --instr '{"internal-key":"freeHighChart","credits":{"enabled":false},"chart":{"type":"bubble","plotBorderWidth":1,"zoomType":"xy","resetZoomButton":{"theme":{"display":"none"},"position":{"align":"left","verticalAlign":"bottom","x":-50,"y":25},"relativeTo":"plot"}},"plotOptions":{"bubble":{"minSize":25,"maxSize":50},"series":{"allowPointSelect":true,"dataLabels":{"format":"{point.name}","enabled":true},"marker":{"states":{"select":{"fillColor":"red","lineWidth":0}}},"point":{"events":{"click":"function(e){ var obj = e.point; doZoom(subsetHighChart, obj.x-1, obj.x+1, obj.y-1, obj.y+1, obj.index, obj.name, obj.nonstopstem.ideafreq);}","select":"function(e){ doZoom(subsetHighChart, e.target.x-1, e.target.x+1, e.target.y-1, e.target.y+1, e.target.index, e.target.name, e.target.nonstopstem.ideafreq); $(\"#idea-tab-free-highchart-search-box\").combobox(\"setText\",e.name); }"}}}},"title":{"text":""},"subtitle":{"text":""},"xAxis":{"min":0,"max":100,"startOnTick":false,"endOnTick":false,"gridLineWidth":1,"maxPadding":0.2,"title":{"text":"Commonality (Percentile) based on document occurrencee"},"labels":{"format":""}},"yAxis":{"min":0,"max":100,"startOnTick":false,"endOnTick":false,"gridLineWidth":1,"maxPadding":0.2,"title":{"text":"Commonality (Percentile) based on total occurrence"},"labels":{"format":""}},"tooltip":{"useHTML":true,"followPointer":true,"headerFormat":"<table border=0 cellpadding=5 cellspacing=0>","pointFormat":"<tr><th colspan=\"2\" align=\"center\"><h3 style=\"margin: 0; padding: 2;\">{point.title}<\/h3><\/th><\/tr><tr><th colspan=\"2\" align=\"center\" style=\"font-size: 50%;\">{point.variants}<\/th><\/tr><tr><th title=\"Based on How Many Documents This Appeared In\">Commonality (Document Occurrence):<\/th><td align=\"center\">{point.nonstopstem.docquantile} %ile<\/td><\/tr><tr><th title=\"Based on How Many Times This Appeared In All Documents\">Commonality (Total Occurrence):<\/th><td align=\"center\">{point.nonstopstem.totalquantile} %ile<\/td><\/tr><tr><th>Within-Idea Occurrence:<\/th><td align=\"center\">{point.nonstopstem.ideafreq} times<\/td><\/tr>","footerFormat":"<\/table>"},"series":[{"name":"words in idea (1-grams)","data":[{"x":25,"y":35,"z":24,"name":"w-3...","title":"word-3","variants":"[word-3, word-3a]","nonstopstem":{"docquantile":25,"totalquantile":35,"ideafreq":24}}]}],"colors":["#7cb5ec","#f15c80","#B789B6","#7cb5ec","#f15c80","#B789B6","#7cb5ec","#f15c80","#B789B6","#f7a35c","#8085e9","#f15c80","#e4d354","#2b908f","#f45b5b","#91e8e1"],"legend":{"enabled":true},"exporting":{"buttons":{"contextButton":{"align":"left","x":80,"y":0}}}}' --outfile '/path/to/CLI/test.png' 2>&1

When I copy and paste to the CLI, it works as expected... with the same user that did the global install of the server...

npm install highcharts-export-server -g

When I try to run via "www-data" as a shell script, I get the error:

sh: 1: highcharts-export-server: not found

I don't get it... why can my user run it, but www-data cannot?

Remove process.exit handles (at least for usage as a module)

In lib/phantompool.js there are calls to process.exit() that terminate the server. When integrating this package as a node module in a server we wan't to control the termination of the server ourselves.

The calls mentioned:

process.on('SIGINT', function (code) {
    process.exit(code);
});

process.on('uncaughtException', function (e) {
    console.log('uncaughtException:', e);
    process.exit(0);
});

I think the SIGINT handle could be replaced with a doTerminate call like the exit handle.
The uncaughtException handle, could be removed completely.

Batch in Node.js Module

Hey guys,

Could someone provide some guidance to how exporting multiples charts at once using Node.js Module?

I have an array of charts objects that I'd like to loop through and export them one by one.

I'm getting stuck on that initPool / killPool and basically I'm getting only my last export.

Thanks in advance,

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.