This tutorial will show you every step you need to use amCharts 5 with React + Vite.
Creating a project
npm create vite@latest my-project -- --template react cd my-project npm install npm install @amcharts/amcharts5
Create a new src/Chart.jsx file:
import { useLayoutEffect } from 'react';
import * as am5 from "@amcharts/amcharts5";
import * as am5xy from "@amcharts/amcharts5/xy";
import am5themes_Animated from "@amcharts/amcharts5/themes/Animated";
function Chart(props) {
useLayoutEffect(() => {
let root = am5.Root.new("chartdiv");
root.setThemes([
am5themes_Animated.new(root)
]);
let chart = root.container.children.push(
am5xy.XYChart.new(root, {
panY: false,
layout: root.verticalLayout
})
);
// Define data
let data = [{
category: "Research",
value1: 1000,
value2: 588
}, {
category: "Marketing",
value1: 1200,
value2: 1800
}, {
category: "Sales",
value1: 850,
value2: 1230
}];
// Create Y-axis
let yAxis = chart.yAxes.push(
am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {})
})
);
// Create X-Axis
let xAxis = chart.xAxes.push(
am5xy.CategoryAxis.new(root, {
renderer: am5xy.AxisRendererX.new(root, {}),
categoryField: "category"
})
);
xAxis.data.setAll(data);
// Create series
let series1 = chart.series.push(
am5xy.ColumnSeries.new(root, {
name: "Series",
xAxis: xAxis,
yAxis: yAxis,
valueYField: "value1",
categoryXField: "category"
})
);
series1.data.setAll(data);
let series2 = chart.series.push(
am5xy.ColumnSeries.new(root, {
name: "Series",
xAxis: xAxis,
yAxis: yAxis,
valueYField: "value2",
categoryXField: "category"
})
);
series2.data.setAll(data);
// Add legend
let legend = chart.children.push(am5.Legend.new(root, {}));
legend.data.setAll(chart.series.values);
// Add cursor
chart.set("cursor", am5xy.XYCursor.new(root, {}));
return () => {
root.dispose();
};
}, []);
return (
<div id="chartdiv" style={{ width: "500px", height: "500px" }}></div>
);
}
export default Chart;
You can now import and use the Chart component inside of src/App.jsx:
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import Chart from './Chart';
import './App.css';
function App() {
return (
<>
<Chart />
</>
)
}
export default App
Updating the chart
You can update the chart by storing the amCharts objects inside of a useRef, and then using useLayoutEffect multiple times to update it:
import { useRef, useLayoutEffect } from 'react';
import * as am5 from "@amcharts/amcharts5";
import * as am5xy from "@amcharts/amcharts5/xy";
import am5themes_Animated from "@amcharts/amcharts5/themes/Animated";
function Chart(props) {
const chartRef = useRef(null);
// Creates the chart, this code only runs one time
useLayoutEffect(() => {
let root = am5.Root.new("chartdiv");
root.setThemes([
am5themes_Animated.new(root)
]);
let chart = root.container.children.push(
am5xy.XYChart.new(root, {
panY: false,
layout: root.verticalLayout
})
);
// Define data
let data = [{
category: "Research",
value1: 1000,
value2: 588
}, {
category: "Marketing",
value1: 1200,
value2: 1800
}, {
category: "Sales",
value1: 850,
value2: 1230
}];
// Create Y-axis
let yAxis = chart.yAxes.push(
am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {})
})
);
// Create X-Axis
let xAxis = chart.xAxes.push(
am5xy.CategoryAxis.new(root, {
renderer: am5xy.AxisRendererX.new(root, {}),
categoryField: "category"
})
);
xAxis.data.setAll(data);
// Create series
let series1 = chart.series.push(
am5xy.ColumnSeries.new(root, {
name: "Series",
xAxis: xAxis,
yAxis: yAxis,
valueYField: "value1",
categoryXField: "category"
})
);
series1.data.setAll(data);
let series2 = chart.series.push(
am5xy.ColumnSeries.new(root, {
name: "Series",
xAxis: xAxis,
yAxis: yAxis,
valueYField: "value2",
categoryXField: "category"
})
);
series2.data.setAll(data);
// Add legend
let legend = chart.children.push(am5.Legend.new(root, {}));
legend.data.setAll(chart.series.values);
// Add cursor
chart.set("cursor", am5xy.XYCursor.new(root, {}));
chartRef.current = chart;
return () => {
root.dispose();
};
}, []);
// When the paddingRight prop changes it will update the chart
useLayoutEffect(() => {
chartRef.current.set("paddingRight", props.paddingRight);
}, [props.paddingRight]);
return (
<div id="chartdiv" style={{ width: "500px", height: "500px" }}></div>
);
}
export default Chart;
And then you can pass in props to the Chart component:
<Chart paddingRight={20} />