Exporting CanvasJS Chart as Image in server-side using headless browsers
Tags: datavisualization, charts, canvasjs
Published: 2023-04-18 12:40:25

[CanvasJS](https://canvasjs.com/) is a popular JavaScript charting library that allows you to create interactive and visually appealing charts for web applications. Sometimes, you may need to export the chart as an image in the server-side for various reasons such as generating reports, sharing the chart with non-technical users, or integrating with other applications. In this article, we will discuss how to export a CanvasJS chart as an image in the server-side using headless browsers.

## What is a headless browser?
A headless browser is a web browser without a graphical user interface (GUI). It can be used to automate web testing, scraping, and other tasks that require interacting with web pages programmatically. Headless browsers support most of the features of regular browsers, such as JavaScript execution, DOM manipulation, and HTTP requests, but they run in the background without displaying any windows or dialogs.

## Why use headless browsers for exporting charts?
Exporting charts as images in the server-side involves rendering the chart in a browser, taking a screenshot of the rendered chart, and saving the screenshot as an image file. Headless browsers provide a way to perform this process programmatically, without requiring any user interaction or display. Headless browsers can also handle complex charts with animations, interactivity, or dynamic data, which may not be possible using other server-side rendering techniques.

There are several headless browsers available for different programming languages, such as Puppeteer for Node.js, Playwright for Node.js and Python, and Selenium for various languages. In this article, we will use Puppeteer, a Node.js library, to export a CanvasJS chart as an image in the server-side. Here are the steps:

### Step 1: Install dependencies
Make sure you have Node.js and CanvasJS installed on your server. Install Puppeteer by running the following command in your terminal:

```
npm install puppeteer
```

### Step 2: Create an html file containing CanvasJS Chart
Create a simple html file `basic-chart.html` with the script to generate chart using CanvasJS.

```
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
window.onload = function () {

var chart = new CanvasJS.Chart("chartContainer", {
  theme: "light1", // "light2", "dark1", "dark2"
  animationEnabled: false, // change to true		
  title:{
    text: "Basic Column Chart"
  },
  data: [{
    type: "column",
    dataPoints: [
      { label: "apple",  y: 10  },
      { label: "orange", y: 15  },
      { label: "banana", y: 25  },
      { label: "mango",  y: 30  },
      { label: "grape",  y: 28  }
    ]}
  ]
});
chart.render();

}
</script>
</head>
<body>
<div id="chartContainer" style="height: 370px; width: 100%;"></div>
<!-- Replace with canvasjs script downloaded from website -->
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"> </script>
</body>
</html>
```

### Step 3: Create a server-side script
Create a JavaScript file that will load the html page generated above containing chart, render it in a headless browser, take a screenshot of the chart, and save it as an image file. Here is an example script:

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

(async () => {

 // Launch a headless browser
 const browser = await puppeteer.launch();

 // Create a new page
 const page = await browser.newPage();

 // Navigate to the page with the CanvasJS chart
 await page.goto(`file://${__dirname}/basic-chart.html`);

 // Wait for the chart to be rendered
 await page.waitForSelector('#chartContainer canvas');

 // Get the dimensions of the chart container
 const chartContainer = await page.$('#chartContainer');
 const dimensions = await chartContainer.boundingBox();

 // Take a screenshot of the chart
 const screenshot = await page.screenshot({
   clip: {
     x: dimensions.x,
     y: dimensions.y,
     width: dimensions.width,
     height: dimensions.height,
   },
   omitBackground: true,
 });

 // Save the screenshot as an image file
 require('fs').writeFileSync('chart.png', screenshot);
 // Close the browser
 await browser.close();
})();
```

In this script, we first launch a headless browser using Puppeteer. We will then navigate to the html file created above containing the CanvasJS chart. We wait for the chart to be
rendered using the `page.waitForSelector` method, which waits for a specified selector to appear in the page. Once the chart is rendered, we get the dimensions of the chart container using the `boundingBox` method of the ElementHandle object.

We then take a screenshot of the chart using the `page.screenshot` method, which takes a screenshot of the visible area of the page or a specified element. We pass the dimensions of the chart
container to the clip option of the `page.screenshot` method, which captures only the area of the chart. We also set the `omitBackground` option to true to remove the background color or image of the screenshot.

Finally, we save the screenshot as an image file using the `writeFileSync` method of the fs module. We specify the filename and path where the image file should be saved. We then close the browser using the `browser.close` method.

### Step 4: Run the script

Run the server-side script using the Node.js command:

```
node export-chart.js
```

This will launch a headless browser, load the web page with the CanvasJS chart, take a screenshot of the chart, and save it as an image file named `chart.png` in the current directory.

Exporting CanvasJS charts as images in the server-side using headless browsers can be a useful technique for generating reports or sharing charts with non-technical users. By using a headless browser like Puppeteer, we can automate the process of rendering the chart, taking a screenshot, and saving it as an image file. With some modifications to the script, you can also export the chart in different formats, such as PDF or SVG.