Build powerful, interactive data visualizations using Chart.js in Lightning Web Components—ideal for comparing multiple metrics on a single chart.
This implementation delivers a reusable multi-axis chart component for Lightning Web Components, designed to visualize multiple data sets with distinct Y-axes. Ideal for dashboards and analytics use cases, the component:
The template defines the chart container and canvas element:
<!-- multiAxisChart.html -->
<template>
<div class="chart-container" lwc:dom="manual"></div>
</template>
The controller handles chart initialization and data processing:
// multiAxisChart.js
import { LightningElement, track, api } from 'lwc';
import chartjs from '@salesforce/resourceUrl/ChartJs';
import { loadScript } from 'lightning/platformResourceLoader';
/**
* MultiAxisChart - A Lightning Web Component that renders a configurable multi-axis chart using Chart.js.
* Supports dynamic datasets and multiple y-axes configuration.
*/
export default class MultiAxisChart extends LightningElement {
// Chart instance reference
chartInstance;
// Configuration properties exposed to parent components
@api initChart = false; // Flag to initialize chart
@api isChildComponent = false; // Flag indicating if used as child component
@api chartDataset = {}; // Dataset for the chart
@api yAxesConfig = {}; // Y-axes configuration
// Chart data properties
@track monthLabels = []; // Labels for x-axis (months)
@track chartDataValues = []; // Values for chart data points
// Style configuration
@api canvasStyle = "height: 200px !important; width: 99% !important;";
/**
* Lifecycle hook - Called when component is inserted into the DOM
* Initializes the chart
*/
connectedCallback() {
this.initializeChart();
}
/**
* Initializes and renders the Chart.js multi-axis chart
*/
initializeChart() {
Promise.all([
loadScript(this, chartjs)
]).then(() => {
// Clear previous chart instance if exists
if (this.chartInstance) {
this.chartInstance.destroy();
}
// Prepare chart data configuration
const chartConfig = this.prepareChartConfig();
// Set canvas dimensions based on component usage (parent/child)
this.setCanvasDimensions();
// Get canvas context and create new chart instance
const canvasContext = this.template
.querySelector('canvas.multi-axis-chart')
.getContext('2d');
this.chartInstance = new window.Chart(canvasContext, chartConfig);
}).catch(error => {
console.error('Error loading Chart.js:', error);
// Note: Add proper error handling here (e.g., show toast message)
});
}
/**
* Prepares the complete configuration object for Chart.js
* @returns {Object} Complete chart configuration
*/
prepareChartConfig() {
// Sample data - Replace with dynamic data from props in actual implementation
const sampleData = {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
label: 'Dataset 1',
backgroundColor: 'transparent',
borderColor: 'green',
yAxisID: 'y-axis-1',
data: this.generateRandomData(7, -100, 100)
}, {
label: 'Dataset 2',
backgroundColor: 'transparent',
yAxisID: 'y-axis-2',
borderColor: 'red',
data: this.generateRandomData(7, -100, 100)
}]
};
return {
type: 'line',
data: sampleData,
options: {
responsive: true,
title: {
display: true,
text: 'Multi-Axis Chart'
},
tooltips: {
mode: 'index',
intersect: true
},
bezierCurve: false,
interaction: {
mode: 'index',
intersect: false,
},
stacked: false,
elements: {
line: {
tension: 0
}
},
scales: {
yAxes: [{
type: 'linear',
display: true,
position: 'left',
id: 'y-axis-1',
}, {
type: 'linear',
display: true,
position: 'right',
id: 'y-axis-2',
gridLines: {
drawOnChartArea: false // Prevents grid lines for right axis
}
}],
}
}
};
}
/**
* Sets the canvas dimensions based on whether component is used as child
*/
setCanvasDimensions() {
const chartContainer = this.template.querySelector('.chart-container');
const height = this.isChildComponent ? '400px' : '250px';
chartContainer.innerHTML = `<canvas class="multi-axis-chart" style="height: ${height}; width: 99% !important;"></canvas>`;
}
/**
* Generates an array of random numbers
* @param {number} count - Number of data points to generate
* @param {number} min - Minimum value
* @param {number} max - Maximum value
* @returns {Array} Array of random numbers
*/
generateRandomData(count, min, max) {
return Array.from({ length: count }, () =>
Math.round(Math.random() * (max - min) + min)
);
}
/**
* Generates random RGB color string
* @returns {string} RGB color string
*/
generateRandomColor() {
const r = Math.floor(Math.random() * 255);
const g = Math.floor(Math.random() * 255);
const b = Math.floor(Math.random() * 255);
return `rgb(${r}, ${g}, ${b})`;
}
}
Optional CSS for custom chart appearance:
/* multiAxisChart.css */
.chart-container {
position: relative;
width: 100%;
min-height: 300px;
}
This multi-axis chart component offers a robust, reusable solution for advanced data visualization in Salesforce.
To implement this component:
Chart.js as a static resource
To customize the chart type (e.g., bar, line, or area), simply update the type property within your dataset.
Example: type: 'line' or type: 'bar'