• Demos
    • JavaScript Charts
    • JavaScript StockCharts
  • Download/NPM
    • Download CanvasJS
    • Install via NPM
  • Integrations
    Front End Technology Samples
    • React Charts
    • Angular Charts
    • Vue.js Charts New!
    • jQuery Charts
    • Dashboards
    Server Side Technology Samples
    • PHP Charts
    • Python Charts New!
    • ASP.NET MVC Charts
    • Spring MVC Charts
    • JSP Charts
  • License
  • Blog
  • Docs
    • Chart Documentation
    • StockChart Documentation
  • Support Forum
    • Chart Support
    • StockChart Support
  • My Account
My Account
  • KEY FEATURES
    • Chart with Index / Data Label
    • Chart with Zooming & Panning
    • Multi Series Chart
    • Chart with Multiple Axes
    • Combination Charts
    • Chart with Animation
    • Chart with Logarithmic Axis
    • Dynamic Chart
    • Chart with Data from AJAX
    • Drilldown Chart
    • Responsive Chart
    • Synchronized Charts
  • LINE CHARTS
    • Line Chart with Date-Time Axis
    • Dashed Line Chart
    • Multi Series Line Chart
    • Spline Chart
    • Multi Series Spline Chart
    • Step Line Chart
    • Multi Series Step Line Chart
  • BAR CHARTS
    • Bar Chart with Category Axis
    • Multi Series Bar Chart
    • Stacked Bar Chart
    • Stacked Bar 100% Chart
    • Stacked Bar 100% Chart with Indexlabels
  • COLUMN CHARTS
    • Column Chart with Numeric Axis
    • Multi Series Column Chart
    • Stacked Column Chart
    • Stacked Column 100% Chart
    • Stacked Column 100% Chart with Indexlabel
    • Waterfall Chart
    • Waterfall Chart with Indexlabels
    • Multi Series Waterfall Chart
  • PIE & DOUGHNUT CHARTS
    • Pie Chart with Index Labels
    • Pie Chart in Dark Theme
    • Doughnut Chart with Index Labels
    • Doughnut Chart in Dark Theme
  • AREA CHARTS
    • Area Chart with Indexlabels
    • Multi Series Area Chart
    • Spline Area Chart
    • Multi Series Spline Area Chart
    • Step Area Chart
    • Stacked Area Chart
    • Stacked Area 100% Chart
  • RANGE CHARTS
    • Range Column Chart
    • Multi Series Range Column Chart
    • Range Bar Chart
    • Multi Series Range Bar Chart
    • Range Area Chart
    • Multi Series Range Area Chart
    • Range Spline Area Chart
    • Multi Series Range Spline Area Chart
  • BUBBLE & SCATTER CHARTS
    • Bubble Chart with Indexlabels
    • Bubble Chart with 3 Dimensional Data
    • Multi Series Scatter Chart
  • FUNNEL & PYRAMID CHARTS
    • Funnel Chart with Index Labels
    • Funnel Chart without Neck
    • Pyramid Chart with Index Labels
  • FINANCIAL CHARTS
    • Candlestick Chart
    • Multi Series Candlestick Chart
    • OHLC Chart
    • OHLC Chart from JSON data
    • Box & Whisker Chart
  • COMBINATION CHARTS
    • Error Bar Chart
    • Pareto Chart
    • Range Area & Line Chart
    • Candlestick & Line Chart
    • OHLC Chart with Trend
  • DYNAMIC CHARTS
    • Dynamic / Live Line Chart
    • Dynamic / Live Column Chart
    • Dynamic / Live Multi Series Chart
  • STOCKCHARTS
    • StockChart with Numeric Axis
    • StockChart with Date-Time Axis
    • StockChart with Navigator & Range Selector
  • JAVASCRIPT, REACT, VUE.JS, JQUERY
    • JavaScript Charts
    • React Charts
    • Vue.js Charts
    • jQuery Charts
  • SERVER SIDE TECHNOLOGIES
    • ASP.NET MVC Charts
    • JSP Charts
    • PHP Charts
    • Python Charts
    • Spring MVC Charts

Angular Synchronized Charts

Download Angular Chart Samples
  • Angular Chart Samples
  • JavaScript Chart Samples
  • React Chart Samples
  • Vue.js Chart Samples
  • jQuery Chart Samples
  • PHP Chart Samples
  • Python Django Chart Samples
  • ASP.NET Chart Samples
  • JSP Chart Samples
  • Spring MVC Chart Samples
  • Dashboard Samples
  • JavaScript StockChart Samples

Example demonstrates our Angular Chart's feature that synchronizes tooltip, crosshair, zooming & panning across multiple charts. i.e. When you move mouse over one chart, it automatically updates tooltip / crosshair across all other charts. This feature is commonly used in dashboards to visualize related data.

  • Component Code
  • Module Code
  • HTML Code
/* app.component.ts */
import { Component } from '@angular/core';
import * as data from '../assets/server-metrics.json';

/* Tutorial: https://www.javatpoint.com/display-data-from-json-file-in-angular */
interface JsonData { "read": number, "time": number, "used": number, "user": number, "wait": number, "cache": number, "write": number, "system": number, "buffers": number, "inbound": number, "outbound": number }

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent{
	dps1: any = []; dps2: any = []; dps3: any = []; charts: any = [];
	
	toolTip = {
		shared: true
	};
	legend = {
		cursor: "pointer",
		itemclick: function (e: any) {
		  if (typeof (e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
			e.dataSeries.visible = false;
		  } else {
			e.dataSeries.visible = true;
		  }
		  e.chart.render();
		}
	};
	
	systemDps: any = []; userDps: any = []; waitDps: any = []; buffersDps: any = []; cacheDps: any = []; usedDps: any = []; inboundDps: any = []; outboundDps: any = []; writeDps: any= []; readDps: any = [];
	onToolTipUpdated: any; onToolTipHidden: any; onCrosshairUpdated: any; onCrosshairHidden: any; onRangeChanged: any;

	cpuChartOptions = {
		animationEnabled: true,
		theme: "light2", // "light1", "light2", "dark1", "dark2"
		title:{
		  text: "CPU Utilization"
		},
		toolTip: this.toolTip,
		axisY: {
		  valueFormatString: "#0.#%",
		},
		legend: this.legend,
		data: [{
		  type: "splineArea", 
		  showInLegend: "true",
		  name: "User",
		  yValueFormatString: "#0.#%",
		  color: "#64b5f6",
		  xValueType: "dateTime",
		  xValueFormatString: "DD MMM YY HH:mm",
		  legendMarkerType: "square",
		  dataPoints: this.userDps
		},{
		  type: "splineArea", 
		  showInLegend: "true",
		  name: "System",
		  yValueFormatString: "#0.#%",
		  color: "#2196f3",
		  xValueType: "dateTime",
		  xValueFormatString: "DD MMM YY HH:mm",
		  legendMarkerType: "square",
		  dataPoints: this.systemDps
		},{
		  type: "splineArea", 
		  showInLegend: "true",
		  name: "Wait",
		  yValueFormatString: "#0.#%",
		  color: "#1976d2",
		  xValueType: "dateTime",
		  xValueFormatString: "DD MMM YY HH:mm",
		  legendMarkerType: "square",
		  dataPoints: this.waitDps
		}]
	};
	memoryChartOptions = {
		animationEnabled: true,
		theme: "light2",
		title:{
		  text: "Memory Usage"
		},
		axisY: {
		  suffix: " GB"
		},
		toolTip: this.toolTip,
		legend: this.legend,
		data: [{
		  type: "splineArea", 
		  showInLegend: "true",
		  name: "Cache",
		  color: "#e57373",
		  xValueType: "dateTime",
		  xValueFormatString: "DD MMM YY HH:mm",
		  yValueFormatString: "#.## GB",
		  legendMarkerType: "square",
		  dataPoints: this.cacheDps
		},{
		  type: "splineArea", 
		  showInLegend: "true",
		  name: "Buffers",
		  color: "#f44336",
		  xValueType: "dateTime",
		  xValueFormatString: "DD MMM YY HH:mm",
		  yValueFormatString: "#.## GB",
		  legendMarkerType: "square",
		  dataPoints: this.buffersDps
		},{
		  type: "splineArea", 
		  showInLegend: "true",
		  name: "Used",
		  color: "#d32f2f",
		  xValueType: "dateTime",
		  xValueFormatString: "DD MMM YY HH:mm",
		  yValueFormatString: "#.## GB",
		  legendMarkerType: "square",
		  dataPoints: this.usedDps
		}]
	}
	networkChartOptions = {
		animationEnabled: true,
		theme: "light2",
		title:{
		  text: "Network Traffic"
		},
		axisY: {
		  suffix: " Kb/s"
		},
		toolTip: this.toolTip,
		legend: this.legend,
		data: [{
		  type: "splineArea", 
		  showInLegend: "true",
		  name: "Outbound",
		  color: "#81c784",
		  xValueType: "dateTime",
		  xValueFormatString: "DD MMM YY HH:mm",
		  yValueFormatString: "#.## Kb/s",
		  legendMarkerType: "square",
		  dataPoints: this.outboundDps
		},{
		  type: "splineArea", 
		  showInLegend: "true",
		  name: "Inbound",
		  color: "#388e3c",
		  xValueType: "dateTime",
		  xValueFormatString: "DD MMM YY HH:mm",
		  yValueFormatString: "#.## Kb/s",
		  legendMarkerType: "square",
		  dataPoints: this.inboundDps
		}]
	}
	diskChartOptions = {
		animationEnabled: true,
		theme: "light2",
		title:{
		  text: "Disk I/O (IOPS)"
		},
		axisY: {},
		toolTip: this.toolTip,
		legend: this.legend,
		data: [{
		  type: "splineArea", 
		  showInLegend: "true",
		  name: "Write",
		  color: "#ffb74d",
		  xValueType: "dateTime",
		  xValueFormatString: "DD MMM YY HH:mm",
		  yValueFormatString: "#.## ops/second",
		  legendMarkerType: "square",
		  dataPoints: this.writeDps
		},{
		  type: "splineArea", 
		  showInLegend: "true",
		  name: "Read",
		  color: "#f57c00",
		  xValueType: "dateTime",
		  xValueFormatString: "DD MMM YY HH:mm",
		  yValueFormatString: "#.## ops/second",
		  legendMarkerType: "square",
		  dataPoints: this.readDps
		}]
	}

	getChartInstance = (chart: any) => {		
		this.charts.push(chart);
	}
	
	jsonData: JsonData[] = (data as any).default;

	ngOnInit(){
		for(var i = 0; i < this.jsonData.length; i++) {
			this.systemDps.push({x: Number(this.jsonData[i].time), y: Number(this.jsonData[i].system)});
			this.userDps.push({x: Number(this.jsonData[i].time), y: Number(this.jsonData[i].user)});
			this.waitDps.push({x: Number(this.jsonData[i].time), y: Number(this.jsonData[i].wait)});
			this.buffersDps.push({x: Number(this.jsonData[i].time), y: Number(this.jsonData[i].buffers)});
			this.cacheDps.push({x: Number(this.jsonData[i].time), y: Number(this.jsonData[i].cache)});
			this.usedDps.push({x: Number(this.jsonData[i].time), y: Number(this.jsonData[i].used)});
			this.inboundDps.push({x: Number(this.jsonData[i].time), y: Number(this.jsonData[i].inbound)});
			this.outboundDps.push({x: Number(this.jsonData[i].time), y: Number(this.jsonData[i].outbound)});
			this.writeDps.push({x: Number(this.jsonData[i].time), y: Number(this.jsonData[i].write)});
			this.readDps.push({x: Number(this.jsonData[i].time), y: Number(this.jsonData[i].read)});
		}
	}
	ngAfterViewInit() {
		this.syncCharts(this.charts, true, true, true);
	}

	syncCharts = (charts: any, syncToolTip: any, syncCrosshair: any, syncAxisXRange: any) => {
		if(!this.onToolTipUpdated){
		  this.onToolTipUpdated = function(e: any) {
			for (var j = 0; j < charts.length; j++) {
			  if (charts[j] != e.chart)
				charts[j].toolTip.showAtX(e.entries[0].xValue);
			}
		  }
		}

		if(!this.onToolTipHidden){
		  this.onToolTipHidden = function(e: any) {
			for( var j = 0; j < charts.length; j++){
			  if(charts[j] != e.chart)
				charts[j].toolTip.hide();
			}
		  }
		}

		if(!this.onCrosshairUpdated){
		  this.onCrosshairUpdated = function(e: any) {
			for(var j = 0; j < charts.length; j++){
			  if(charts[j] != e.chart)
				charts[j].axisX[0].crosshair.showAt(e.value);
			}
		  }
		}

		if(!this.onCrosshairHidden){
		  this.onCrosshairHidden =  function(e: any) {
			for( var j = 0; j < charts.length; j++){
			  if(charts[j] != e.chart)
				charts[j].axisX[0].crosshair.hide();
			}
		  }
		}

		if(!this.onRangeChanged){
		  this.onRangeChanged = function(e: any) {
			for (var j = 0; j < charts.length; j++) {
			  if (e.trigger === "reset") {
				charts[j].options.axisX.viewportMinimum = charts[j].options.axisX.viewportMaximum = null;
				charts[j].options.axisY.viewportMinimum = charts[j].options.axisY.viewportMaximum = null;
				charts[j].render();
			  } else if (charts[j] !== e.chart) {
				charts[j].options.axisX.viewportMinimum = e.axisX[0].viewportMinimum;
				charts[j].options.axisX.viewportMaximum = e.axisX[0].viewportMaximum;
				charts[j].render();
			  }
			}
		  }
		}

		for(var i = 0; i < charts.length; i++) { 

		  //Sync ToolTip
		  if(syncToolTip) {
			if(!charts[i].options.toolTip)
			  charts[i].options.toolTip = {};

			charts[i].options.toolTip.updated = this.onToolTipUpdated;
			charts[i].options.toolTip.hidden = this.onToolTipHidden;
		  }

		  //Sync Crosshair
		  if(syncCrosshair) {
			if(!charts[i].options.axisX)
			  charts[i].options.axisX = { labelAngle: 0, crosshair: { enabled: true, snapToDataPoint: true, valueFormatString: "HH:mm" }};
			
			charts[i].options.axisX.crosshair.updated = this.onCrosshairUpdated; 
			charts[i].options.axisX.crosshair.hidden = this.onCrosshairHidden; 
		  }

		  //Sync Zoom / Pan
		  if(syncAxisXRange) {
			charts[i].options.zoomEnabled = true;
			charts[i].options.rangeChanged = this.onRangeChanged;
		  }
		  
		  charts[i].render();
		}
	} 
}                              
/* app.module.ts */
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

import { CanvasJSAngularChartsModule } from '@canvasjs/angular-charts';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    CanvasJSAngularChartsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }                        
/* app.component.html */
<div>
    <canvasjs-chart [options]="cpuChartOptions" (chartInstance)="getChartInstance($event)" [styles]="{width: '50%', height: '300px', 'float': 'left' }"></canvasjs-chart>
	<canvasjs-chart [options]="memoryChartOptions" (chartInstance)="getChartInstance($event)" [styles]="{width: '50%', height: '300px', 'float': 'left'}"></canvasjs-chart>
	<canvasjs-chart [options]="networkChartOptions" (chartInstance)="getChartInstance($event)" [styles]="{width: '50%', height: '300px', 'float': 'left'}"></canvasjs-chart>
	<canvasjs-chart [options]="diskChartOptions" (chartInstance)="getChartInstance($event)" [styles]="{width: '50%', height: '300px', 'float': 'left'}"></canvasjs-chart>	
</div>                        

Chart Customizations

In the above example, we are using the below listed events and methods.
Chart - rangeChanging, rangeChanged
ToolTip - updated, hidden, showAtX, hide
Crosshair - updated, hidden, showAt, hide

Note   For step by step instructions, follow our Angular Integration Tutorial

Quick Links

  • Chart Docs
  • StockChart Docs
  • About Us
  • FAQs

Server Side Technologies

  • ASP.NET MVC Charts
  • PHP Charts
  • JSP Charts
  • Spring MVC Charts

Front Side Technologies

  • JavaScript Charts
  • jQuery Charts
  • React Charts
  • Angular Charts
  • JavaScript StockCharts

Contact

  • Fenopix, Inc.
  • 2093 Philadelphia Pike,
  • #5678, Claymont,
  • Delaware 19703
  • United States Of America

©2025 Fenopix Privacy Policy Cookies Policy Careers