来自:morizfree建议的stackoverflow.com/questions/42529308/synchronized-highcharts-does-not-work-when-charts-have-different-width。
上面的小提琴示例在我使用共享工具提示时起作用,但我想要的是第二个图表有两个或更多系列,而图表中的每个系列都需要有自己的工具提示。注意:使用上面的小提琴示例代码时,我可以同步工具提示,但我无法使用光标在第二个图表中切换系列。
任何帮助,将不胜感激。
/*
The purpose of this demo is to demonstrate how multiple charts on the same page can be linked
through DOM and Highcharts events and API methods. It takes a standard Highcharts config with a
small variation for each data set, and a mouse/touch event handler to bind the charts together.
*/
function highlightPoints(e) {
const container = this;
const charts = Highcharts.charts.slice();
const chartIndex = charts.findIndex(chart => chart.renderTo === container);
if (chartIndex > -1) {
const chart = charts.splice(chartIndex, 1)[0];
const event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
const point = chart.series[0].searchPoint(event, true); // Get the hovered point
if (point) {
const x = point.x;
point.highlight(e);
charts.forEach(chart => {
const caughtPoints = [];
chart.series.forEach(series => {
const points = series.points;
for (let i = 0; i < points.length; i = i + 1) {
if (points[i].x === x) {
points[i].highlight(e);
caughtPoints.push(points[i]);
break;
}
}
})
chart.tooltip.refresh(caughtPoints); // Show the tooltip
})
}
}
}
/**
* 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.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'
});
}
}
});
}
}
// Get the data. The contents of the data file can be viewed at
// https://github.com/highcharts/highcharts/blob/master/samples/data/activity.json
$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=activity.json&callback=?', function(activity) {
$.each(activity.datasets, function(i, dataset) {
// Add X values
dataset.data = Highcharts.map(dataset.data, function(val, j) {
return [activity.xData[j], val];
});
let additionalData;
if (i === 1) {
additionalData = dataset.data.map(v => [v[0], v[1] - 50]);
}
const options = {
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: {
shared: true,
positioner: function() {
return {
x: this.chart.chartWidth - this.label.width, // right aligned
y: -1 // 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
}
}]
}
if (i === 1) {
options.series.push({
data: additionalData,
name: 'addit series',
type: 'area',
color: Highcharts.getOptions().colors[i],
fillOpacity: 0.3,
tooltip: {
valueSuffix: ' ' + dataset.unit
}
})
}
$('<div class="chart-' + i + '">')
.appendTo('#container')
.highcharts(options);
});
/**
* In order to synchronize tooltips and crosshairs, override the
* built-in events with handlers defined on the parent element.
*/
$('.chart-0, .chart-1, .chart-2').on('mousemove', highlightPoints);
});
.chart-0 {
min-width: 320px;
max-width: 800px;
height: 220px;
margin: 0 auto;
}
.chart-1 {
min-width: 320px;
max-width: 550px;
height: 220px;
margin: 0 auto;
}
.chart-2 {
min-width: 300px;
max-width: 300px;
height: 220px;
margin: 0 auto;
}
</style> <!-- http: //doc.jsfiddle.net/use/hacks.html#css-panel-hack -->
<meta name="viewport" content="width=device-width, initial-scale=1" /> <style>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>
您需要修改highlightPoints
函数:
function highlightPoints(e) {
const container = this;
const charts = Highcharts.charts.slice();
const chartIndex = charts.findIndex(chart => chart.renderTo === container);
if (chartIndex > -1) {
const chart = charts.splice(chartIndex, 1)[0];
const event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
const point = chart.series[0].searchPoint(event, true); // Get the hovered point
if (point) {
const x = point.x;
charts.forEach(chart => {
let caughtPoint;
const points = chart.series[0].points;
for (let i = 0; i < points.length; i = i + 1) {
if (points[i].x === x) {
points[i].highlight(e);
caughtPoint = points[i];
break;
}
}
chart.tooltip.refresh(caughtPoint); // Show the tooltip
})
}
}
}