highcharts多图表联动

798 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

官方案例:

https://www.highcharts.com.cn/demo/highcharts/synchronized-charts

官方代码:

/*
本例子的目的是为了演示通过 Dom 事件、Highcharts 事件、Highcharts API 来讲一个页面中的多个图表进行联动的。
本例通过循环创建类似的图表并绑定鼠标的滑动事件来对多个图表进行演示联动效果。
*/

let container = document.getElementById('container'),
	highlightPoint = function(e) {
		var chart,
			point,
			i,
			event;
		for (i = 0; i < Highcharts.charts.length; i = i + 1) {
			chart = Highcharts.charts[i];
			// Find coordinates within the chart
			event = chart.pointer.normalize(e);
			// Get the hovered point
			point = chart.series[0].searchPoint(event, true);
			if (point) {
				point.highlight(e);
			}
		}
	};

['mousemove', 'touchmove', 'touchstart'].forEach(function (eventType) {
	container.addEventListener(
		eventType,
		function (e) {
			highlightPoint(e);
		}
	);
});
/**
 * 重写内部的方法, 这里是将提示框即十字准星的隐藏函数关闭
 */
Highcharts.Pointer.prototype.reset = function () {
	return undefined;
};
/**
 * 高亮当前的数据点,并设置鼠标滑动状态及绘制十字准星线
 */
Highcharts.Point.prototype.highlight = function (event) {
	this.onMouseOver(); // 显示鼠标激活标识
	this.series.chart.tooltip.refresh(this); // 显示提示框
	this.series.chart.xAxis[0].drawCrosshair(event, this); // 显示十字准星线
};
/**
 * 同步缩放效果,即当一个图表进行了缩放效果,其他图表也进行缩放
 */
function syncExtremes(e) {
	var thisChart = this.chart;
	if (e.trigger !== 'syncExtremes') { 
		Highcharts.each(Highcharts.charts, function (chart) {
			if (chart !== thisChart) {
				if (chart.xAxis[0].setExtremes) { 
					chart.xAxis[0].setExtremes(e.min, e.max, undefined, false, { trigger: 'syncExtremes' });
				}
			}
		});
	}
}
// 获取 JSON 数据,数据文件地址:
//https://github.com/highcharts/highcharts/blob/master/samples/data/activity.json
Highcharts.ajax({
	url: 'https://cdn.jsdelivr.net/gh/highcharts/highcharts@v7.0.0/samples/data/activity.json',
	dataType: 'text',
	success: function (activity) {
		activity = JSON.parse(activity);
		activity.datasets.forEach(function (dataset, i) {
			// Add X values
			dataset.data = Highcharts.map(dataset.data, function (val, j) {
				return [activity.xData[j], val];
			});
			var chartDiv = document.createElement('div');
			chartDiv.className = 'chart';
			container.appendChild(chartDiv);
			
			Highcharts.chart(chartDiv, {
				chart: {
					marginLeft: 40, // Keep all charts left aligned
					spacingTop: 20,
					spacingBottom: 20
				},
				title: {
					text: dataset.name,
					align: 'left',
					margin: 0,
					x: 30
				},
				credits: {
					enabled: false
				},
				legend: {
					enabled: false
				},
				xAxis: {
					crosshair: true,
					events: {
						setExtremes: syncExtremes
					},
					labels: {
						format: '{value} km'
					}
				},
				yAxis: {
					title: {
						text: null
					}
				},
				tooltip: {
					positioner: function () {
						return {
							// right aligned
							x: this.chart.chartWidth - this.label.width,
							y: 10 // align to title
						};
					},
					borderWidth: 0,
					backgroundColor: 'none',
					pointFormat: '{point.y}',
					headerFormat: '',
					shadow: false,
					style: {
						fontSize: '18px'
					},
					valueDecimals: dataset.valueDecimals
				},
				series: [{
					data: dataset.data,
					name: dataset.name,
					type: dataset.type,
					color: Highcharts.getOptions().colors[i],
					fillOpacity: 0.3,
					tooltip: {
						valueSuffix: ' ' + dataset.unit
					}
				}]
			});
		});
	}
});

展示图:

在这里插入图片描述

vue中使用

触发:

watch: {
  chartList: {
    handler (n) {
      if (!this.mouseMove) {
        this.mouseMove = true
        setTimeout(() => {
          this.handleMouse()
          this.mouseMove = false
        }, 50)
      }
    },
    deep: false
  }
},
mounted () {
  this.handleMouse()
  const _this = this
  window.onresize = function () {
    _this.isFullScreen = document.fullscreen
  }
}

methods:

handleMouse () {
  this.$refs.chartArea.$el.removeEventListener('mousemove', this.hoverCharts, false)
  this.$refs.chartArea.$el.addEventListener('mousemove', this.hoverCharts)
},
hoverCharts (e) {
  if (!this.chartList.length) return

  this.highcharts.Pointer.prototype.reset = function () {
    return undefined
  }

  let event = null
  this.chartList.forEach(chart => {
    event = chart.pointer.normalize(e) // Find coordinates within the chart
    // 由于tooltip 设置了shared:true,所以refresh应传数组形式
    const points = []

    if (chart.series && chart.series.length) {
      chart.series.forEach((serie, index) => {
        const point = serie.searchPoint(event, true)
        if (point) {
          points.push(point)
          point.highlight(e)
        }
      })
    }

    if (points.length) {
      // chart.xAxis[0].drawCrosshair(event, this)
      chart.tooltip.refresh(points)
    }
  })

  /**
* 高亮当前的数据点,并设置鼠标滑动状态及绘制十字准星线
*/
  this.highcharts.Point.prototype.highlight = function (event) {
    this.onMouseOver() // 显示鼠标激活标识
    // this.series.chart.tooltip.refresh(this) // 显示提示框
    // this.series.chart.xAxis[0].drawCrosshair(event, this) // 显示十字准星线
  }
}