• Demos
    • JavaScript Charts
    • JavaScript StockCharts
  • Download
    • Download Chart
    • Download StockChart
  • 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 Label
    • Multi Series Chart
    • Chart with Zooming & Panning
    • Synchronized Charts
    • Chart with Animation
    • Chart With Image Overlay
    • Chart with Secondary Axis
    • Chart with Null Data
    • Chart with Dynamic Data
    • Column Chart with Reversed Axis
    • Chart with Logarithmic Axis
    • Chart using JSON Data
    • Performance With 50,000 Data Points
    • Draggable Column Chart
    • Chart with Axis / Scale Break
    • Chart with Crosshair
    • Chart with Customized Legends
    • Drilldown Chart
    • Responsive Chart
    • Chart with Axis Labels & Ticks inside Plot Area
    • Sync ToolTip across Multiple Charts
  • LINE CHARTS
    • Line Chart
    • Dashed Line Chart
    • Multi Series Line Chart
    • Line Chart with Zoom and Pan
    • Line Chart with Data Marker
    • Line Chart with Logarithmic Axis
    • Line Chart with Axis / Scale Break
    • Line Chart with Multiple Axes
    • Spline Chart
    • Multi Series Spline Chart
    • Dynamic Spline Chart
    • Spline Chart with Secondary Axis
    • Spline Chart with Legends
    • Step Line Chart
    • Multi Series Step Line Chart with Null Data
  • AREA CHARTS
    • Area Chart
    • Multi Series Area Charts
    • Spline Area Chart
    • Multi Series Spline Area Charts
    • Step Area Chart
    • Range Area Chart
    • Multi Series Range Area Charts
    • Range Spline Area Chart
    • Stacked Area Chart
    • Stacked Area 100% Chart
    • Stacked Area 100% Chart with Date-Time Axis
  • COLUMN & BAR CHARTS
    • Column Chart
    • Column Charts with Multiple Axes
    • Bar Chart
    • Multi Series Bar Chart
    • Bar Chart with Axis / Scale Break
    • Range Column Chart
    • Multi Series Range Column Chart
    • Stacked Column Chart
    • Stacked Column 100% Chart
    • Range Bar Chart
    • Stacked Bar Chart
    • Stacked Bar 100% Chart
    • Waterfall Chart
    • Multi Series Waterfall Chart
    • Waterfall Chart with Custom Colors
  • PIE & FUNNEL CHARTS
    • Pie Chart
    • Pie Chart with Legends
    • Pie Chart with Custom Radius
    • Doughnut Chart
    • Doughnut Chart with Custom Inner Radius
    • Funnel Chart
    • Funnel Chart with Custom Neck
    • Inverted Funnel Chart
    • Pyramid Chart
    • Pyramid Chart with Values represented by Area
    • Pyramid Chart With Index Labels Placed Inside
  • FINANCIAL CHARTS
    • Candlestick Chart
    • Multi Series Candlestick Chart
    • Combination of Candlestick & Line Chart
    • OHLC Chart
    • OHLC Chart from JSON Data using AJAX
  • SCATTER & BUBBLE CHARTS
    • Scatter / Point Chart
    • Multi Series Scatter / Point Chart
    • Scatter Chart with Custom Markers
    • Bubble Chart
    • Bubble Chart with Zoom & Pan
    • Bubble Chart with Custom Markers
  • BOX & WHISKER CHARTS
    • Box And Whisker Chart
    • Box and Whisker Chart with Color Customization
    • Box And Whisker Chart with Outliers
  • COMBINATION CHARTS
    • Error Chart
    • Error Line Chart
    • Error Bar Chart
    • Pareto Chart
    • Pareto Chart with Index / Data Label
    • Combination of Range Area and Line Charts
    • Combination of Column, Line and Area Chart
    • Combination of OHLC and Line Chart
  • DYNAMIC CHARTS
    • Dynamic / Live Column Chart
    • Dynamic / Live Line Chart
    • Dynamic / Live Multi Series Chart
  • ANGULAR, REACT, VUE.JS, JQUERY
    • Angular Charts
    • React Charts
    • Vue.js Charts
    • jQuery Charts
  • SERVER SIDE TECHNOLOGIES
    • ASP.NET MVC Charts
    • PHP Charts
    • Python Charts
    • JSP Charts
    • Spring MVC Charts

Synchronized Charts in JavaScript

Download JavaScript Chart Samples
  • JavaScript Chart Samples
  • React Chart Samples
  • Angular 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

While rendering data across multiple charts, you can better visualize the same by using Synchronized Charts - where tooltip, crosshair & axis range are synced across charts. For example, if you zoom/pan any one of the charts, it'll automatically zoom/pan other charts. Same goes for ToolTip & Crosshair as well. Below example shows a Synchronized JavaScript Chart along with source code that you can run on your machine.

Try Editing The Code

window.onload = function () {
  var charts = [];
  var toolTip = {
    shared: true
  },
  legend = {
    cursor: "pointer",
    itemclick: function (e) {
      if (typeof (e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
        e.dataSeries.visible = false;
      } else {
        e.dataSeries.visible = true;
      }
      e.chart.render();
    }
  };  

  var systemDps = [], userDps=[], waitDps = [], buffersDps = [], cacheDps = [], usedDps=[], inboundDps = [], outboundDps = [], writeDps = [], readDps = [];

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

  charts.push(new CanvasJS.Chart("chartContainer1", cpuChartOptions));
  charts.push(new CanvasJS.Chart("chartContainer2", memoryChartOptions));
  charts.push(new CanvasJS.Chart("chartContainer3", networkChartOptions));
  charts.push(new CanvasJS.Chart("chartContainer4", diskChartOptions));

  $.get("https://canvasjs.com/data/gallery/javascript/server-matrics.json", function(data) {
    for (var i = 1; i < data.length; i++) {
      systemDps.push({x: parseInt(data[i].time), y: parseFloat(data[i].system)});
      userDps.push({x: parseInt(data[i].time), y: parseFloat(data[i].user)});
      waitDps.push({x: parseInt(data[i].time), y: parseFloat(data[i].wait)});
      buffersDps.push({x: parseInt(data[i].time), y: parseFloat(data[i].buffers)});
      cacheDps.push({x: parseInt(data[i].time), y: parseFloat(data[i].cache)});
      usedDps.push({x: parseInt(data[i].time), y: parseFloat(data[i].used)});
      inboundDps.push({x: parseInt(data[i].time), y: parseFloat(data[i].inbound)});
      outboundDps.push({x: parseInt(data[i].time), y: parseFloat(data[i].outbound)});
      writeDps.push({x: parseInt(data[i].time), y: parseFloat(data[i].write)});
      readDps.push({x: parseInt(data[i].time), y: parseFloat(data[i].read)});
    }
    for( var i = 0; i < charts.length; i++){
      charts[i].options.axisX = {
        labelAngle: 0,
        crosshair: {
          enabled: true,
          snapToDataPoint: true,
          valueFormatString: "HH:mm"
        }
      }
    }

    syncCharts(charts, true, true, true); // syncCharts(charts, syncToolTip, syncCrosshair, syncAxisXRange)

    for( var i = 0; i < charts.length; i++){
      charts[i].render();
    }

  });  

  function syncCharts(charts, syncToolTip, syncCrosshair, syncAxisXRange) {

    if(!this.onToolTipUpdated){
      this.onToolTipUpdated = function(e) {
        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) {
        for( var j = 0; j < charts.length; j++){
          if(charts[j] != e.chart)
            charts[j].toolTip.hide();
        }
      }
    }

    if(!this.onCrosshairUpdated){
      this.onCrosshairUpdated = function(e) {
        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) {
        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) {
        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 = { crosshair: { enabled: true }};
		
        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;
      }
    }
  }  

}                            

Chart Customizations

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

© fenopix
  • About Us
  • FAQs
  • Careers
  • Privacy Policy
Server Side Technologies
  • ASP.NET MVC Charts
  • PHP Charts
  • JSP Charts
  • Spring MVC Charts
Front End 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