同步多个图表的x轴

时间:2017-02-17 06:16:25

标签: javascript angularjs highcharts highcharts-ng

Angular Highcharts中,我想在仪表板中的多个图表中同步X轴。我找到了两个图表的x轴同步解决方案(粘贴在下面)。但我坚持使用多图表同步。我的仪表板中有8个图表。我想同步所有这些。

highcharts-ng

中两个图表的现有代码
$scope.chart1 = {
    options: {
        chart: {
            events: {
                selection: function(event) {
                    self.onZoomHandler(event, 'chart2');
                }
            }
        }
    }
}

self.onZoomHandler = function(event, chartToUpdate) {
    var chart = $scope[chartToUpdate].getHighcharts();
    if (event.xAxis) {
        chart.xAxis[0].setExtremes(event.xAxis[0].min, event.xAxis[0].max);
        if (!chart.resetZoomButton) {
            chart.showResetZoom();
        }
    } else {
        chart.xAxis[0].setExtremes(null, null);
        if (chart.resetZoomButton) {
            chart.resetZoomButton = chart.resetZoomButton.destroy();
        }
    }
};

我们怎样才能在多个图表中执行此操作?

2 个答案:

答案 0 :(得分:1)

您可以同步工具提示并缩放包含id="container"的元素内的任意数量的图表:

<div id="container">
  <div class="row">
    <highchart id="chart1" config="chartConfig" class="span10"></highchart>
  </div>
  <div class="row">
    <highchart id="chart2" config="chartConfig2" class="span10"></highchart>
  </div>
  <div class="row">
    <highchart id="chart3" config="chartConfig3" class="span10"></highchart>
  </div>
</div>

使用以下JS函数:

/**
 * In order to synchronize tooltips and crosshairs, override the
 * built-in events with handlers defined on the parent element.
 */
$('#container').bind('mousemove touchmove touchstart', function(e) {
  var chart,
    point,
    i,
    event;

  for (i = 0; i < Highcharts.charts.length; i = i + 1) {
    chart = Highcharts.charts[i];
    event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
    point = chart.series[0].searchPoint(event, true); // Get the hovered point

    if (point) {
      point.highlight(e);
    }
  }
});

/**
 * Override the reset function, we don't need to hide the tooltips and crosshairs.
 */
Highcharts.Pointer.prototype.reset = function() {
  return undefined;
};

/**
 * Highlight a point by showing tooltip, setting hover state and draw crosshair
 */
Highcharts.Point.prototype.highlight = function(event) {
  this.onMouseOver(); // Show the hover marker
  this.series.chart.tooltip.refresh(this); // Show the tooltip
  this.series.chart.xAxis[0].drawCrosshair(event, this); // Show the crosshair
};
/**
 * Synchronize zooming through the setExtremes event handler.
 */
function syncExtremes(e) {
  var thisChart = this.chart;

  if (e.trigger !== 'syncExtremes') { // Prevent feedback loop
    Highcharts.each(Highcharts.charts, function(chart) {
      if (chart !== thisChart) {
        if (chart.xAxis[0].setExtremes) { // It is null while updating
          chart.xAxis[0].setExtremes(e.min, e.max, undefined, false, {
            trigger: 'syncExtremes'
          });
        }
      }
    });
  }
}

(来自http://www.highcharts.com/demo/synchronized-charts

然后只需在syncExtremes回调中设置setExtremes功能。

$scope.chartConfig = {
  ...
  xAxis: {
    events: {
      setExtremes: syncExtremes
    },
  ...
}

这是一个包含3个图表的jsfiddle示例:http://jsfiddle.net/nLguvp7m/4/

答案 1 :(得分:0)

稍微修改你的函数,以便它可以处理一组图表配置并循环调用它setExtremes()onZoomHandler应设置在所有图表中 - 因此所有图表都可以触发其他图表的缩放。

$scope.chartConfig = {
  chart: {
    zoomType: 'x',
    events: {
     selection: function (e) {
      e.preventDefault();
      self.onZoomHandler(e, ['chartConfig', 'chartConfig2', 'chartConfig3'])
    }
  }
},

self.onZoomHandler = function (event, chartsToUpdate) {
  chartsToUpdate.forEach(config => {
    zoomHandler($scope[config].getChartObj());
  });

  function zoomHandler(chart) {     
    if (event.xAxis) {
      chart.xAxis[0].setExtremes(event.xAxis[0].min, event.xAxis[0].max);
      if (!chart.resetZoomButton) {
        chart.showResetZoom();
      }
    } else {
      chart.xAxis[0].setExtremes(null, null);
      if (chart.resetZoomButton) {
        chart.resetZoomButton = chart.resetZoomButton.destroy();
      }
    }
  }
}