I need to dynamically sync the xAxis crosshairs across multiple HighStocks charts.
The example http://jsfiddle.net/BlackLabel/hh90ps4c/28/ demonstrates how to sync the controls inside one chart. I cloned the demo into this http://jsfiddle.net/jakobvinther/ayf5gst2/ ...and replaced the single chart by a table with two charts. The JavaScript code was almost just duplicated for the second chart.
Out of the box, zooming, panning and the rangeSelector sliders in the two charts are nicely synced (I did not change any code to achieve that).
The problem is that the xAxis crosshairs in the two charts are not synced, they work inside each chart individually. How can that be done?
/* thanks */
If the charts are not in one column, the problem is the mouse event x coordinate. You can refer to the first chart in the column to get the coordinates you need:
$('#container1').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];
// Find coordinates within the chart
event = Highcharts.charts[0].pointer.normalize(e);
// Get the hovered point
point = chart.series[0].searchPoint(event, true);
if (point) {
point.highlight(e);
}
}
});
Live demo: http://jsfiddle.net/BlackLabel/8krwuof9/
Related
The current data is displayed in the form of a line chart through dimple.js. If the same value data appears for the year, the points overlap. In this case, I want to display the tooltips for all the overlapping data when I move the mouse over that point. What should I do?
You need to handle mouseover event of Series object like this,
mySeries.addEventHandler("mouseover", function (e){
var xValue = e.xValue; // e.xValue returns X Axis value of hovered data point
var yValue = e.yValue; // e.yValue returns Y Axis value of hovered data point
// Filter your data with both xValue and yValue, to find overlapped `series` data.
});
This sample demonstrates how to override default tooltip and might be helpful for you too
http://dimplejs.org/advanced_examples_viewer.html?id=advanced_custom_styling
I'm trying to implement synchronised charts in my application using the example code from Highcharts here:
https://www.highcharts.com/demo/synchronized-charts
I have a column layout using the Materialize framework and the charts are positioned side by side in a row. After doing some playing around with the Highcharts example, it seems the charts don't behave the same horizontally as they do vertically. The labels are not synced across the charts and the crosshairs don't move in sync either.
After doing some reading I've found a similar question has been asked before:
Highcharts Sync charts horizontally
However, as someone pointed out in the comments on the "marked correct" answer, the solution doesn't work for responsive charts like mine. This person was advised to ask a separate SO question, but as I can't find it, I'm asking it.
So far this is the closest I can get to my charts properly working:
https://jsfiddle.net/6h7aL2rw/1/
However, as you can see as you move the cursor to the end of the first chart, the tooltip and crosshairs are not fully synchronised and are behind by a few points on each chart.
The code I've changed from the original example is the following:
$('#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
event.chartX = (event.chartX + 3 * $('.chart').width()) % $('.chart').width();
point = chart.series[0].searchPoint(event, true); // Get the hovered point
if (point) {
point.highlight(e);
}
}
});
As was pointed out in the original question though, I don't understand the significance of this:
event.chartX + 3 * $('.chart').width()
But I feel that it's this bit of code that is the problem preventing the charts from being in sync.
That problem is caused by the gaps between the charts, please check an example without them: https://jsfiddle.net/BlackLabel/5Lgrc08z/
As a solution you can set event.chartX to e.offsetX:
$('#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
event.chartX = e.offsetX;
point = chart.series[0].searchPoint(event, true); // Get the hovered point
if (point) {
point.highlight(e);
}
}
});
Live demo: https://jsfiddle.net/BlackLabel/ts7w4kxu/
function chart (data, selector) {
// generate chart with zoom feature. it scales the X domain and update the chart accordingly.
}
chart(dataset1, "#chart1")
chart(dataset2, "#chart2")
chart(datasetn, "#chartn")
the code above is a chart generator function which I give it different datasets to make me charts. in all charts, the dataset has the same X values but different Y values.
problem:
lets say we have 3 charts, all the X axis ranges are between 0-100. In the first chart, I drag mouse and create a zoombox between 30-60 and the first chart updates, now it is scaled between 30-60. But the second and third chart are intact. I need them to be updated as well between 30-60.
similarly if I do the same for second chart, I need the first and third one get updated.
here is jsfiddle to illustration
I made not so big modification to make this works.
First of all we remember globally the information about single chart in var charts array. This is done during creation of charts
charts.push(lineChart(data1,"#chart1"));
charts.push(lineChart(data2,"#chart2"));
charts.push(lineChart(data3,"#chart3"));
Next we can use this array in function zoomdrag and update.
This work maybe not perfect (reset of chart is missing) but show how to handle it and get the same zoom in all charts.
Here is jsfiddle
I am working on a web application displaying multiple charts over the same categories. If you want an example, think population for different cities over time. The charts all have crosshairs enabled for the X axis.
I've been asked if, when a user hovers over a chart and moves the mouse - therefore moving the crosshairs - it is possible to have the crosshairs of all the other charts as well, in parallel, kinda mirroring the movement.
Off the top of my head it should not be impossible - capture the position on the X axis whenever the mouse is moved, then set/move the crosshairs on all charts to the same value for all the other charts - but that would work only if moving crosshairs programmatically is possible.
Is this possible in a non trivial way?
Edit: I created a partially working version on jsfiddle, based on the jsfiddle linked to in the answer, and replicating the two column layout of the charts in our web app: http://jsfiddle.net/basiliosz/sgc8jg34/
The crosshairs are moved only in charts directly above and below the one where the user is hovering the mouse cursor, but not in the other column. This is the crucial code snippet from the event handler:
for (i = 0; i < noOfCharts; i = i + 1) {
chart = separateCharts[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(event);
}
}
where Point.prototype.highlight is defined as this:
Highcharts.Point.prototype.highlight = function (ev) {
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh(this); // Show the tooltip
this.series.chart.xAxis[0].drawCrosshair(ev, this); // Show the crosshair
};
There is an internal function for drawing crosshair which can be used (it is not part of the official API)
/**
* Draw the crosshair
*
* #param {Object} e The event arguments from the modified pointer event
* #param {Object} point The Point object
*/
Axis.prototype.drawCrosshair: function(e, point) {}
example: http://jsfiddle.net/6rbhxmrp/
You can also the official demo with synchronizing charts https://www.highcharts.com/demo/synchronized-charts
The example with a disabled tooltip: http://jsfiddle.net/vwm4oe6k/
I am attempting to replot a chart when the user selects the tab to display the chart(initially it is set to visibility:hidden). Once it plots the graphs again, I don't see any of the lines or bars in the graphs, I only see the legend. I want to see all of the data again. When I don't hide the element and just plot it, it works fine, but I need to hide the element so that data can be grouped together in a logical order.
Here is the code I use to plot the charts while it's hidden, jqPlots is an array which contains the variables used for plotting.
var plot = $.jqplot (DATA GOES IN HERE)
jqPlots.push(plot)
Then within the handler for displaying the div I have
for(var i = 0; i<jqPlots.length; i++)
{
jqPlots[i].replot();
}