How to synchronize the Highchart Sunburst behavior - javascript

As shown in the image, I want to show two sunbursts next to each other. I want to implement it with Highchart and react in such a way where,
If user mouse over on any data point on one sunburst, same data point should get highlighted on another chart, while other data points just goes into disabled mode or changes their color to white

In mouseOver event, by using references to the charts, you can programmatically set 'hover' state at the right point:
point: {
events: {
mouseOver: function() {
const chart1 = component.highchartsChart1.current.chart;
const chart2 = component.highchartsChart2.current.chart;
function clearState(chart) {
Highcharts.each(chart.series[0].points, function(p) {
p.setState("");
});
}
if (this.series.chart === chart1) {
clearState(chart2);
chart2.series[0].points[this.index].setState("hover");
} else {
clearState(chart1);
chart1.series[0].points[this.index].setState("hover");
}
}
}
}
Live demo: https://codesandbox.io/s/nn54z2234m
API: https://api.highcharts.com/class-reference/Highcharts.Point#setState

Related

How to synchronise shared tooltip and crosshair in highcharts?

I have a couple of charts, some with a single series, others with multiple series. I show shared tooltips for charts with multiple series. I show a vertical crosshair on each chart.
Now I would like to synchronise the charts. Moving the mouse in one chart should show the described features (crosshair and toolip) on the correct place in all charts, with updated data.
As you can see in fiddle, this does not work completely. The x position is synchronised correctly. Tooltips are updated. But mouseover on the second chart shows a tooltip in the first chart with only one y value instead of two. [Edit: I've found a way to update crosshairs; but it does not not work in every chart, when I set
tooltip: {
shared: true,
maybe there is a better solution?]
https://jsfiddle.net/hbaed859/1/
let highlightFunction = function (point) {
Highcharts.charts.forEach(chart => {
chart.series.forEach(s => {
if (point.series.name != s.name) {
s.points.forEach(p => {
if (p.index === point.index) {
p.setState('hover')
p.series.chart.tooltip.refresh(p)
// shows tooltip, but ignores "shared: true"
chart.xAxis[0].drawCrosshair(null, p);
...
chart = Highcharts.chart('chart1', {
series: [{
point: {
events: {
mouseOver(e) {
let point = this;
highlightFunction(point)
}
...
[edit] ... and the method is nice for small datasets, for large one it needs too long to recalculute the crossjair positions for all the charts.
You are really close to achieve the wanted result. Use the hideCrosshair method for crosshair visibility and add points from all chart's series to the tooltip.refresh method call. Optimized code below:
function setHighlightState() {
const point = this;
Highcharts.charts.forEach(chart => {
if (point.series.chart !== chart) {
const matchedPoints = [];
chart.series.forEach(s => {
const matchedPoint = s.points[point.index];
matchedPoints.push(matchedPoint);
matchedPoint.setState('hover');
});
chart.tooltip.refresh(matchedPoints)
chart.xAxis[0].drawCrosshair(null, matchedPoints[0]);
}
});
}
function hideHighlightState() {
const point = this;
Highcharts.charts.forEach(chart => {
if (point.series.chart !== chart) {
chart.series.forEach(s => {
s.points[point.index].setState('');
});
chart.tooltip.hide();
chart.xAxis[0].hideCrosshair();
}
});
}
Live demo: https://jsfiddle.net/BlackLabel/nwj3co0a/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Axis#hideCrosshair

How to change one point color on click in Highcharts

I'm trying to change the color of scatterplot points, one at a time. I have the code below which works, but I'm not sure how to change the color back when you click on a second point.
For example, I'd like it to work so if all the points are yellow by default and you click point A, point A alone turns black. Then when you click point B, point B turns black and point A turns back to yellow.
plotOptions: {
series: {
point: {
events: {
click: function() {
var thisPoint = this.options;
thisPoint.color = 'black';
this.update(thisPoint, true);
}
}
}
}
},
You could store a variable containing the last clicked point, for example (in an outer scope):
let previousPoint;
And then in your click event:
plotOptions: {
series: {
point: {
events: {
click: function() {
// If we have a previous point, reset its color
if(previousPoint)
previousPoint.update({color: previousPoint.originalColor});
// Set this points color to black
this.update({color: 'black', originalColor: this.color});
// Make it our previous point
previousPoint = this;
}
}
}
}
}
See this JSFiddle demonstration of it in use.
If you don't want to clutter the Point with the extra variable (originalColor) you can also put a previousColor in your outer scope along with the previousPoint.

how to hide series data in combination high charts

I am using combine high charts. I need to hide a particular pie chart and column chart data while clicking a particular legend. If i use:
series[i].data[index].remove()
That removes the value but not able to show that value again while clicking the legend.
series[i].data[index].hide()
Refer to this JSFidddle - Example which I tried but I get an error like This is not function. How do I solve this?
You can use hide method on point SVG graphic element:
events: {
legendItemClick: function(e) {
var index = this.index;
var chart = this.series.chart;
var series = chart.series;
var len = series.length - 1;
if (this.visible) {
series[0].points[index].graphic.hide();
} else {
series[0].points[index].graphic.show();
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/d8uaxefo/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGElement#hide

Highcharts 6.0 Synchronization Bug

I'm trying to use Highcharts Synchronization for a slightly complex chart. I've gotten synchronization to work just fine on graphs with just 1 series for other plots.
You can check out the example here: http://jsfiddle.net/nhng5827/o9uh2jqy/42/
I've dumbed down my complex chart to just a few points, and usually the chart has 6 lines as opposed to 4. As you can see, the tooltip only appears on the right side of the graph, and everything is delayed. I also do not want the callout box to have any numbers read out if the tooltip is not hovered the specific lines.
I've done a fair bit of research and have implemented some code I've seen that allows for charts with 2 series to be synchronized (http://jsfiddle.net/mjsdnngq/72/), however I think the biggest difference in mine is that the series only go to about half of the actual chart.
$('#container').bind('mousemove touchmove touchstart', function (e) {
var chart,
points,
i,
secSeriesIndex = 1;
for (i = 0; i < Highcharts.charts.length; i++) {
chart = Highcharts.charts[i];
e = chart.pointer.normalize(e); // Find coordinates within the chart
points = [chart.series[0].searchPoint(e, true), chart.series[1].searchPoint(e, true),chart.series[2].searchPoint(e, true),chart.series[3].searchPoint(e, true)]; // Get the hovered point
if (points[0] && points[1]&& points[2]&& points[3]) {
// if (!points[0].series.visible) {
// points.shift();
// secSeriesIndex = 0;
// }
// if (!points[secSeriesIndex].series.visible) {
// points.splice(secSeriesIndex,1);
// }
if (points.length) {
chart.tooltip.refresh(points); // Show the tooltip
chart.xAxis[0].drawCrosshair(e, points[0]); // Show the crosshair
chart.xAxis[0].drawCrosshair(e, points[3]); // Show the crosshair
}
}
}
});
/**
* Override the reset function, we don't need to hide the tooltips and crosshairs.
*/
Highcharts.Pointer.prototype.reset = function () {
return undefined;
};
Highcharts.Point.prototype.highlight = function (event) {
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh([points[0],points[1],points[2],points[3]]); // 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' });
}
}
});
}
}
Any help would be immensely appreciated.
To correctly synchronize charts, you have to clear points state on every mousemove event:
Highcharts.each(chart.series, function(s) {
Highcharts.each(s.points, function(p) {
p.setState('');
});
});
Live demo: http://jsfiddle.net/BlackLabel/cvb6pwsu/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Point#setState
Also, please take a look at this example: http://jsfiddle.net/BlackLabel/6f37b42q/, it can be useful for you.

Chart Area and Legend Area automatically updates

I have a chart and implemented seriesClick event. When User clicks it loads dataA, when user click again it loads dataB. It is fully implemented and it is functional. However my question is how to fix chart area and legend area.
Legend length differs in dataA and dataB, therefore when user click on series, chart is not stay stable, it adjusts automatically. I do not want my chart to adjust automatically.
my SeriesClick event implementation is as follows:
function clickEvent (e) {
if (!isHover) {
chart.options.series = dataSeries2;
chart.redraw();
isHover = true;
}
else if (isHover) {
var chart = $("#chart").data("kendoChart");
chart.options.series = dataSeries;
chart.redraw();
isHover = false;
}
}
Here is the jsfiddle:
http://jsfiddle.net/3yhbyy2g/72/
There is no API yet for setting plot area to have fixed width, all you can do right now is give an escape character (\n) in your legend label.
stats = stats.map(function(x) {
return { x: x[0], y: x[1], k: x[2],name:"my title\nis too\nlengty" };
});
I found this in their forum, hope that will help you out.

Categories

Resources