Using Webpack

amCharts 4 has excellent support for Webpack. This tutorial will show you every step you need to use Webpack with amCharts 4.

Important note about import

There is a bug in Webpack version 4.29.x which causes dynamic import() to error when using amCharts. The error looks like this:

ERROR in ./node_modules/@amcharts/amcharts4/.internal/core/export/Export.js 67:24
Module parse failed: Unexpected token (67:24)
You may need an appropriate loader to handle this file type.
| switch (_a.label) {
| case 0: return [4 /*yield*/, Promise.all([
> import(/* webpackChunkName: "pdfmake" */ "pdfmake/build/pdfmake.js"),
| import(/* webpackChunkName: "pdfmake" */ "../../pdfmake/vfs_fonts")
| ])];

This is a bug in Webpack, not amCharts, so there is nothing we can do to fix it.

You can downgrade to Webpack version 4.28.4 to fix the problem. Alternatively, you can add "acorn": "^6.1.1" to the "dependencies" in your package.json.

Setting up

First, create a package.json file, like this:

{
  "name": "my-custom-project",
  "version": "0.1.0",
  "devDependencies": {
    "@amcharts/amcharts4": "^4.0.0-beta.64",
    "webpack": "^4.6.0",
    "webpack-cli": "^3.1.2",
    "source-map-loader": "0.2.3"
  },
  "scripts": {
    "prepare": "webpack"
  }
}

Then create a webpack.config.js file, like this:

var $path = require("path");

module.exports = {
  mode: "production",

  devtool: "source-map",

  entry: {
    index: "./index.js"
  },

  output: {
    path: $path.join(__dirname, "dist"),
    filename: "[name].js",
    chunkFilename: "[name].js"
  },

  module: {
    rules: [{
      test: /.js$/,
      use: ["source-map-loader"],
      enforce: "pre"
    }]
  }
};

Now create an index.js file which uses amCharts V4:

import * as am4core from "@amcharts/amcharts4/core";
import * as am4charts from "@amcharts/amcharts4/charts";
import am4themes_animated from "@amcharts/amcharts4/themes/animated";

am4core.useTheme(am4themes_animated);

let chart = am4core.create("chartdiv", am4charts.XYChart);
chart.paddingRight = 20;

let data = [];
let visits = 10;
for (let i = 1; i < 366; i++) {
    visits += Math.round((Math.random() < 0.5 ? 1 : -1) * Math.random() * 10);
    data.push({ date: new Date(2018, 0, i), name: "name" + i, value: visits });
}

chart.data = data;

let dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.renderer.grid.template.location = 0;

let valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.tooltip.disabled = true;
valueAxis.renderer.minWidth = 35;

let series = chart.series.push(new am4charts.LineSeries());
series.dataFields.dateX = "date";
series.dataFields.valueY = "value";

series.tooltipText = "{valueY.value}";
chart.cursor = new am4charts.XYCursor();

let scrollbarX = new am4charts.XYChartScrollbar();
scrollbarX.series.push(series);
chart.scrollbarX = scrollbarX;

Lastly you can use npm install to build your project! The code will be inside the dist folder.

You can now use <script src="dist/index.js"></script> in an HTML page to display the chart. You will also need to create a <div id="chartdiv"></div> HTML element, like this:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <style>
      #chartdiv {
        width: 100%;
        height: 400px;
      }
    </style>
  </head>
  <body>
    <div id="chartdiv"></div>
    <script src="dist/index.js"></script>
  </body>
</html>

NOTE If you want to support older browsers, make sure you set up polyfills. Click here for detailed instructions.

If your index.html isn't in the same directory as the dist/index.js file, you will need to change the output.publicPath property in webpack.config.js:

{
  output: {
    publicPath: "/dist/"
  }
}

This is needed so that Webpack can know where to load the files from.

You can further customize the index.js, webpack.config.js, and package.json files as you wish, but this is a good starting point.

Large file sizes

By default amCharts contains support for exporting charts.

This will create some files in your bundle directory (canvg.js, pdfmake.js, and xlsx.js).

These files are harmless: they are dynamically loaded only when they are needed, so they do not increase the download size.

However, they do increase the compilation times a bit, so if you do not need them you can disable them by adding this to your webpack.config.js:

{
externals: function (context, request, callback) {
if (/xlsx|canvg|pdfmake/.test(request)) {
return callback(null, "commonjs " + request);
}
callback();
}
}