Keep selection in highcharts even on page refresh - javascript

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

Related

Chart.js zoom instantly zooms in fully on first point no matter what type of zoom used

After adding zoom to my line chart no matter what I do it instantly zooms in to the first point without the option to zoom back out (outside of the reset zoom function). The zoom out function also doesnt work, zoom in function results in the same problem.
Normal
After any attempt to zoom
const pdmdata = JSON.parse(document.getElementById('div_pdmdata').dataset.chart);
const ctx = document.getElementById('canvasChart_1').getContext("2d");
const radars = {'hidden': 'hidden'};
let linechartData = {
datasets: [{
label: 'Constant',
data: pdmdata[0],
borderWidth: 1
}]
};
for (let i = 0; i < Object.keys(pdmdata[1]).length; i++) {
linechartData.datasets.push({
label: radars[Object.keys(pdmdata[1])[i]],
data: pdmdata[1][Object.keys(pdmdata[1])[i]],
borderWidth: 1,
tension: 0.1
});
}
const config = {
type: 'line',
data: linechartData,
options: {
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
stacked: false,
plugins: {
title: {
display: true,
text: 'Mode S'
},
zoom: {
zoom: {
drag: {
enabled: true,
// mode: 'x',
threshold: 24
},
mode: 'x'
}
}
},
scales: {
x: {
reverse: true
}
},
elements: {
point: {
radius: 0
}
}
},
};
myChart = new Chart(ctx, config);
function resetZoom(){
myChart.resetZoom();
}
I've tried all the zoom types; zoom, drag and pan. Even using drag in the middle of the chart makes it end up like the zoomed image above. No errors in console whatsoever. I've also tried setting the speed to 0.001 but to no avail. Weirdest thing is when I make a duplicate of this chart below it that one does zoom as intended. I have no idea why it would though.
Okay so I found my issue, chartjs-zoom does not like objects as data without also setting labels yourself. Here's an example: (Only used 1 dataset while testing to make it easier to test)
This works:
let linechartData = {
label: ['one', 'two', 'three', 'four', 'five'],
datasets: [{
label: 'Constant',
data: [1, 2, 3, 4, 5],
borderWidth: 1
}]
};
This does not work:
let linechartData = {
datasets: [{
label: 'Constant',
data: {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5},
borderWidth: 1
}]
};
But this does:
let linechartData = {
label: ['one', 'two', 'three', 'four', 'five'],
datasets: [{
label: 'Constant',
data: {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5},
borderWidth: 1
}]
};
So conclusion, when using chartjs-zoom always assign the labels beforehand instead of letting a dataset data object assign them automatically, which works just fine for normal charts without zoom. Never figured out why if I made a 2nd chart with the exact same config that chart did work though.

Highcharts multiple series combined with linkedTo hover issue

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/

Highcharts Bar Chart Without Column

i'm new to highcharts.
I already browse in highcharts example. but, every time I look for the sample, it came with the column bar chart like this :
All I want is like this :
But I dont know how. Maybe you can help me figured it out.
Thank you.
You can simply set x/y pairs for each of points. Then set column.grouping to false: http://jsfiddle.net/27u9zuhj/
plotOptions: {
column: {
grouping: false
}
},
series: [{
name: 'John',
data: [ [0, 5], [1, 3], [2, 4]]
}, {
name: 'Jane',
data: [ [3, 2], [4, 2]]
}]

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: []
}
})
});

Loading Javascript Highcharts series data issues

Server is sending back data like this:
{"barData":
[
{"Accepted":[0,0,0]},
{"Rejected":[0,0,0]},
{"In_Process":[0,1,0]}]
}
In the browser, it shows up as such:
My perhaps (and very likely) incorrect belief was that this was the correct structure to populate a Highcharts stacked bar chart as seen here:
Example Stacked Bar in jsFiddle
The example in the documentation shows a fixed data set that appears like this:
series: [{
name: 'John',
data: [5, 3, 4, 7, 2]
}, {
name: 'Jane',
data: [2, 2, 3, 2, 1]
}, {
name: 'Joe',
data: [3, 4, 4, 2, 5]
}]
This is what I was attempting to emulate. So, at the end of all that, I get a zero plot. My Javascript looks like this:
$.ajax({
url : 'http://localhost:8080/afta/report/transfersbynetwork',
success : function(point) {
data = [];
$.each(point.barData, function(itemNo, item) {
data.push([ item[0], parseInt(item[1][0]), parseInt(item[1][1]), parseInt(item[1][2])]);
});
barchart = new Highcharts.Chart(baroptions);
baroptions.series[0].data = data;
},
cache : false
});
So where did I bone this up? I'm getting no plot and am quite convinced the problem is either in my presentation of the data from the server (possible) or in the javascript that's parsing the data structure and loading the series (highly likely).
Any insight would be appreciated.
Based on your structure, you need to change your function to process the data:
$(function () {
var point = {
"barData": [{
"Accepted": [1, 2, 3]
}, {
"Rejected": [3, 4, 5]
}, {
"In_Process": [0, 1, 0]
}]
},
data = [];
$.each(point.barData, function (itemNo, item) {
for (var prop in item) {
data.push({
name: prop,
data: [parseInt(item[prop][0]), parseInt(item[prop][1]), parseInt(item[prop][2])]
});
}
});
$('#container').highcharts({
chart: {
type: 'bar'
},
title: {
text: 'Stacked bar chart'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
}
},
legend: {
backgroundColor: '#FFFFFF',
reversed: true
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: data
});
});
http://jsfiddle.net/9jVJb/

Categories

Resources