Based on your comment, Highcharts will work as an alternative to Plotly.
Here is a solution to creating two charts side by side with synchronized tooltips regardless of whether you hover on the left or right chart.

Hey you; greetings from the States! BTW, if you don't spell the tag name (Kat) correctly, SO won't notify me. I just happened to come across your question again.
I ended up having some failsafe code added that will likely only really work if you only have two plots side by side. There is so much data in economics
, that many times the two tips would be off by up to a year. The extra code just makes sure that they match.
Since I'm sure that using economics
isn't your end goal, let me know if whatever configuration you're using doesn't work with this code.
I've added a lot of comments to the Javascript coding quoted in tags$script
. I hope that this information is enough for you to understand what's happening.
There are two different plotting methods in Highcharts for R.
- If you're familiar with Python's Plotly, there are two versions: express and go. That's kind of what happens in R's Highcharts. (
hchart()
is more like express; highchart()
is more like go)
- If you're not familiar with Python's Plotly, then it's good to know that plots either start with
hchart()
or highchart()
. They don't work quite the same way.
If you want to learn more about Highcharts for R, read more about it here.
This answer uses economics
(as you did in your question), which comes from the library ggplot2
. The other libraries used in this answer are highcharter
and htmltools
. The graphs are set exactly as your question established for Plotly, only they're rendered in Highcharter.
library(highcharter)
library(htmltools)
data(economics, package = 'ggplot2')
(hc1 <- highchart(elementId = "myChart") %>%
hc_xAxis(categories = economics$date, type = "datetime") %>%
hc_add_series(name = "Unemployed", data = economics$unemploy) %>%
hc_tooltip(useHTML = T))
(hc2 <- highchart(elementId = "myChart2") %>%
hc_xAxis(categories = economics$date, type = "datetime") %>%
hc_add_series(name = "Unemployment Duration",
data = economics$uempmed) %>%
hc_tooltip(useHTML = T))
This next chunk of code aligns these two plots laterally and establishes the synchronized tooltip.
browsable(tagList(
tags$script(HTML("
setTimeout(function() { /* using id from div */
$('#hc_container').bind('mousemove touchmove touchstart', function(e) {
var chart, point, i, event;
for (i = 0; i < Highcharts.charts.length; i++) { /* loop through both charts */
chart = Highcharts.charts[i]; /* identify the chart */
event = chart.pointer.normalize(e.originalEvent); /* find chart coordinates */
/* evaluate for synchronization, to address lateral charts */
event.chartX = (event.chartX + $('[id$=Chart]').width()) % $('[id$=Chart]').width();
point = chart.series[0].searchPoint(event, true); /* get closest point */
if (point) { /* if point found, tip it */
point.highlight(e); /* trigger tooltip */
}
} /* this code is to ensure the tooltips match */
var gr = $('div.highcharts-label.highcharts-tooltip');/* collect visible tooltips */
var gr0 = gr[0].firstChild.firstChild.textContent; /* collect 1st x-axis tooltip text */
var gr1 = gr[1].firstChild.firstChild.textContent; /* collect 2nd x-axis tooltip text */
if(gr0 !== gr1) { /* the tips don't match due to data point proximity, fix it */
var p = Highcharts.charts[1].series[0].points; /* find all points in chart 1 */
point = p.find(o => o.category === gr0); /* get point matching chart 0 tip */
if(point) { /* if point found, tip it */
point.highlight(e); /* trigger tooltip */
}
}
});
}, 500);
Highcharts.Pointer.prototype.reset = function() { /* reset tooltip */
return null;
};
Highcharts.Point.prototype.highlight = function(event) { /* executes tooltip from trigger */
event = this.series.chart.pointer.normalize(event); /* capture that event occurred */
this.onMouseOver(); /* show marker */
this.series.chart.tooltip.refresh(this); /* show tooltip */
this.series.chart.xAxis[0].drawCrosshair(event, this); /* show crosshair */
};
")),
div(id = "hc_container", # this id is used in the JQuery/Javascript above
div(hc1, style = 'height:100%; width: 50%; float:left;'), # first plot
div(hc2, style = 'height:100%; width: 50%; float:left;'), # second plot
style = "height:100%; width:100%; float:left;"))) # container styles
