Highcharts multiple series combined with linkedTo hover issue - javascript

I'm using linkedTo option to link multiple additional graphs (let's call them childs) to one main graph in order to get one group of graphs.
My issue is about hover highlighting. When I hover main graph all childs are highlighted as well as main graph itself. But when I hover any child graph only this one and main are highlighted, and other childs become blurred, that is not what I want.
Highcharts.chart('container', {
series: [{
id: 'main',
color: 'black',
name: 'Main',
type: 'line',
data: [[1, 3], [1.5, 2.5], [2, 2], [2.5, 1.5], [3, 1]]
}, {
linkedTo: 'main',
color: 'black',
name: 'Child 1',
type: 'line',
data: [[2, 3], [3, 2], [4, 1]]
}, {
linkedTo: 'main',
color: 'black',
name: 'Child 2',
type: 'line',
data: [[3, 3], [4, 2], [5, 1]]
}, {
linkedTo: 'main',
color: 'black',
name: 'Child 3',
type: 'line',
data: [[4, 3], [5, 2], [6, 1]]
}]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container"/>
Is there any workaround for this case?

That issue is reported here: https://github.com/highcharts/highcharts/issues/11810 and marked as an enhancement. Currently, as a workaround you can link sibling series in afterLinkSeries event:
(function(H) {
H.addEvent(H.Chart, 'afterLinkSeries', function(e) {
this.series.forEach(function(s) {
if (s.linkedParent) {
s.linkedParent.linkedSeries.forEach(function(linkedS) {
if (linkedS !== s) {
s.linkedSeries.push(linkedS);
}
});
}
});
});
}(Highcharts));
Live demo: http://jsfiddle.net/BlackLabel/6m4e8x0y/4972/
Docs: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts
EDIT:
Due to the problem with legend item click, a better solution is to overwrite Pointer.prototype.applyInactiveState method.
Highcharts.Pointer.prototype.applyInactiveState = function(points) {
var activeSeries = [],
series;
// Get all active series from the hovered points
(points || []).forEach(function(item) {
series = item.series;
// Include itself
activeSeries.push(series);
// Include parent series
if (series.linkedParent) {
activeSeries.push(series.linkedParent);
// CHANGE
series.linkedParent.linkedSeries.forEach(function(linkedS) {
activeSeries.push(linkedS);
});
// END CHANGE
}
// Include all child series
if (series.linkedSeries) {
activeSeries = activeSeries.concat(series.linkedSeries);
}
// Include navigator series
if (series.navigatorSeries) {
activeSeries.push(series.navigatorSeries);
}
});
// Now loop over all series, filtering out active series
this.chart.series.forEach(function(inactiveSeries) {
if (activeSeries.indexOf(inactiveSeries) === -1) {
// Inactive series
inactiveSeries.setState('inactive', true);
} else if (inactiveSeries.options.inactiveOtherPoints) {
// Active series, but other points should be inactivated
inactiveSeries.setAllPointsToState('inactive');
}
});
};
Live demo: http://jsfiddle.net/BlackLabel/6m4e8x0y/4974/

Related

Keep selection in highcharts even on page refresh

I am using highcharts for generating/showcasing graph on UI(HTML with JavaScript Page)
There are multiple elements in series section that one can select or unselect to display on graph.
But after every refresh, user selected elements gets unselected and only the default selections appear. And user has to select the elements again.
Any solution to it?
One can relate the question from the picture:
In this, By default A is selected.
If user selects Ball or C then the point graph will appear for Ball and C as well but as soon as graph refreshes, graph will have point graph with A only.
You can store your visible series states in local storage. Example:
const savedStates = localStorage.getItem('seriesStates');
const seriesStates = savedStates ?
JSON.parse(savedStates) : {
A: true,
Ball: false,
C: false,
D: false
};
Highcharts.chart('container', {
series: [{
name: 'A',
data: [1, 2, 3],
visible: seriesStates.A
}, {
name: 'Ball',
data: [2, 2, 2],
visible: seriesStates.Ball
}, {
name: 'C',
data: [3, 3, 3],
visible: seriesStates.C
}, {
name: 'D',
data: [4, 4, 4],
visible: seriesStates.D
}],
plotOptions: {
series: {
events: {
legendItemClick: function() {
seriesStates[this.name] = !this.visible;
localStorage.setItem(
'seriesStates',
JSON.stringify(seriesStates)
);
}
}
}
}
});
Live demo: http://jsfiddle.net/BlackLabel/jkuc50Lf/
Docs: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

stacked column points connected with a dashed line highcharts

I tried many way and didnt get the result
may please help how can i generate this kind of chart in highchart.
That series will be available since Highcharts v8.0.0: https://github.com/highcharts/highcharts/issues/11311. For now you can use a combination of scatter and line series:
var scatterData = [2, 3, 7, 8, 9],
series = [{
type: 'scatter',
data: scatterData
}];
scatterData.forEach(function(el, i) {
series.push({
dashStyle: 'ShortDash',
data: [
[i, 5],
[i, el]
]
});
});
Highcharts.chart('container', {
series: series
});
Live demo: http://jsfiddle.net/BlackLabel/uwcL0h8b/
API Reference: https://api.highcharts.com/highcharts/series.line.dashStyle

Possible to change the height inside the highchart drilldown?

I tried to create the dynamic height in high chart's drill down. Depends on data. Then chart type is bar chart.
For example
drilldown: {
series: [{
id: 'animals',
data: [
['Cats', 4],
['Dogs', 2],
['Cows', 1],
['Sheep', 2],
['Pigs', 1]
], $("#container").css({'height':'500px'}) // here i want to change
}, {
id: 'fruits',
data: [
['Apples', 4],
['Oranges', 2]
], $("#container").css({'height':'300px'}) // here i want to change
}, {
id: 'cars',
data: [
['Toyota', 4],
['Opel', 2],
['Volkswagen', 2]
], $("#container").css({'height':'400px'}) // here i want to change
}]
}
It is possible to add the jQuery into series section. I mentioned above. Or else any possible way for to do it?
You can catch drilldown event and then call setSize function.
chart: {
type: 'bar',
events: {drilldown:function(a){ this.setSize(300, a.seriesOptions.data.length*100) }}
}
drilldown function is trigger as an when user is click on individual bar and argument "a" is holding the series data of that particular bar which user has click, and I've calculate the length of that data with "a.seriesOptions.data.length*100" and 100 is 100px, so if length is 2 then 2*100px = 200px.

HighChart dynamic drill down

I have created a chart with drilldown using sample given on fiddle
http://jsfiddle.net/gh/get/jquery/1.7.2/highslide-software/highcharts.com/tree/master/samples/highcharts/drilldown/async/
When I click on first level it is sucessfully adding chart for next level by using
chart.addSeriesAsDrilldown(e.point, series);
My problem is, now i want newly added chart also have drilldown. I dont know how to achieve this. Any help will thankful.
Regards
I found the solution to this. Actually when data is fetched from web service as json for the next level of drilldown I had to make sure the property drilldown needed to be set to true which I was not doing earlier after some research I found it. I have given some data in json format below with reference to the example on fiddle.
When first level was clicked I was going to web service and fetching data as
"{\"name\":\"Animals\",\"data\": [[\"Cows\", 2],[\"Sheep\", 3]],\"drilldown\": true}"
which was not enabling drilldown for the next level. In order to allow drill down further I had to modify the above data as below where in I have added property drilldown to be as true
(name == "Animals") resp = "{\"name\":\"Animals\",\"data\": [{\"name\":\"Cows\", \"y\": 2, \"drilldown\": \"true\"},{\"name\":\"Sheep\",\"y\": 3,\"drilldown\":\"true\"}]}";
That is all, seems simple :)
Will try to create sample on Fiddle if I get time and will update link if done so.
$(function () {
// Create the chart
$('#container').highcharts({
chart: {
type: 'column',
events: {
drilldown: function (e) {
if (!e.seriesOptions) {
var chart = this,
drilldowns = {
'Animals': {
name: 'Animals',
data: [
['Cows', 2],
['Sheep', 3]
]
},
'Fruits': {
name: 'Fruits',
data: [
['Apples', 5],
['Oranges', 7],
['Bananas', 2]
]
},
'Cars': {
name: 'Cars',
data: [
{
name: 'Toyota',
y: 4,
drilldown: true
},
['Volkswagen', 2],
['Opel', 5]
]
}
},
series = drilldowns[e.point.name];
// Show the loading label
chart.showLoading('Simulating Ajax ...');
setTimeout(function () {
chart.hideLoading();
chart.addSeriesAsDrilldown(e.point, series);
}, 1000);
}
}
}
},
title: {
text: 'Async drilldown'
},
xAxis: {
type: 'category'
},
legend: {
enabled: false
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
}
}
},
series: [{
name: 'Things',
colorByPoint: true,
data: [{
name: 'Animals',
y: 5,
drilldown: true
}, {
name: 'Fruits',
y: 2,
drilldown: true
}, {
name: 'Cars',
y: 4,
drilldown: true
}]
}],
drilldown: {
series: []
}
})
});

Using different symbols for plotting data not working

I am attempting to use a different symbol for one of my data series on my flot graph as it is at a much larger scale then the rest of the data. I am using this example as reference: http://www.flotcharts.org/flot/examples/symbols/index.html
Here is what I have so far:
My includes:
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.flot.js"></script>
<script type="text/javascript" src="jquery.flot.symbol.js"></script>
I then configure my flot options like so:
var options = {
grid: {hoverable : true},
xaxis: { mode: "time", timeformat: "%H:%M", tickLength: 1},
series: { points : { show: true } }
};
I then actually plot the data:
$.plot('#placeholder', [{
data: my_data,
lines: { show : true},
points: { symbol: "square"},
color: '#CB4B4B',
label: 'My Data'
}], options);
}
However, flot is still graphing the points as the default circle. I get no error messages in firebug and I have even tried adding a logging message in the jquery.flot.symbol.js library itself to see if the "square" handler is even being called like so:
var handlers = {
square: function (ctx, x, y, radius, shadow) {
console.log("Square handler was called");
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
var size = radius * Math.sqrt(Math.PI) / 2;
ctx.rect(x - size, y - size, size + size, size + size);
},
I am getting no console messages so I am assuming the handler is not getting called correctly. Am I missing something here?
EDIT:
Example of data I am trying to plot:
var d1 = [
[1364342400000, 208],
[1364346000000, 107],
[1364353200000, 42],
[1364371200000, 1680],
[1364360400000, 52],
[1364349600000, 67],
[1364385600000, 1118],
[1364367600000, 163],
[1364382000000, 1359],
[1364378400000, 1468],
[1364389200000, 1023],
[1364356800000, 63],
[1364374800000, 1601],
[1364392800000, 556],
[1364364000000, 84],
],
d2 = [
[1364342400000, 86],
[1364346000000, 42],
[1364353200000, 13],
[1364371200000, 458],
[1364360400000, 10],
[1364349600000, 22],
[1364385600000, 453],
[1364367600000, 45],
[1364382000000, 369],
[1364378400000, 379],
[1364389200000, 358],
[1364356800000, 17],
[1364374800000, 471],
[1364392800000, 147],
[1364364000000, 16],
],
d3 = [
[1364342400000, 7],
[1364346000000, 5],
[1364382000000, 11709],
[1364371200000, 58336],
[1364360400000, 1],
[1364349600000, 1],
[1364367600000, 2],
[1364389200000, 1191],
[1364378400000, 9085],
[1364385600000, 4688],
[1364374800000, 9386],
[1364392800000, 1140],
[1364364000000, 1],
];
I have also edited my options parameter and how the plot function is called:
var options = {
grid: {hoverable : true},
xaxis: { mode: "time", timeformat: "%H:%M", tickLength: 1}
};
$.plot("#placeholder", [{
data: d1,
lines: { show : true },
points: { show: true},
color: '#EDC240',
label: "d1"
}, {
data: d2,
lines: { show : true },
points: { show : true},
color: '#AFD8F8',
label: "d2"
}, {
data: d3,
yaxis: 2,
lines: { show : true},
points: { show: true, symbol: "square"},
color: '#CB4B4B',
label: "d3"
}], options);
I am also sure that the symbol library is being included because I have added some logging itself to the library and that is showing up fine.
I see no issue with what you've done. I made a quick working example here: http://jsfiddle.net/ryleyb/shLtU/1/
I would guess that you haven't included the symbol library (even though you say you have).
Or show your data, might somehow be an issue there (doubtful?).
This is the full flot code I ran to make a working example (plus including flot and the symbol library):
$.plot('#placeholder', [{
data: [
[1, 1],
[2, 3],
[4, 4],
[5, 9]
],
lines: {
show: true
},
points: {
show: true,
symbol: "square"
},
color: '#CB4B4B',
label: 'My Data'
}]);

Categories

Resources