How to add radio button in highchart legend symbol - javascript

I have 3 line series in my highchart , i want to make one series fixed (user) cant disable/hide it by clicking the legend.
And other two i want to work as radio button i.e user can choose among those 2 which one to show , now i was able to make that happen , but now i want a radio button next to those two legend symbols which user can choose from .
legend should be like this.
and the radio button should toggle the series. the working code (without radio button and legend allignment) is :
drawChart(data1, data2, data3) {
let chart = Highcharts.chart("container", {
chart: {
zoomType: "xy"
},
title: {
text: null
},
plotOptions: {
series: {
events: {
show: function () {
let chart = this.chart,
series = chart.series,
i = series.length,
otherSeries;
while (i--) {
if (i != 0)
otherSeries = series[i];
if (otherSeries != this && otherSeries.visible) {
otherSeries.hide();
}
}
},
legendItemClick: function () {
if (this.visible) {
return false;
}
}
}
}
},
series: [{
name: "series1",
data: data1
}, {
name: "series2",
data: data2
}, {
name: "series3",
data: data3,
visible: false
}]
}

You need to set the plotOptions and set showCheckbox: true
plotOptions: {
line: {
marker: { enabled: false }
},
turboThreshold: 0,
series: {
cursor: 'pointer',
showCheckbox: true,
events: {
checkboxClick: function (event) {
if (event.checked) {
this.show();
this.legendSymbol.show();
} else {
this.hide();
this.legendSymbol.hide();
}
},
legendItemClick: function() {
return false;
}
}
}
},
By default the checkboxes are placed right next to series label but we can override it according to our need,
Here is a fiddle that might help !!! It's just a pointer, You can customize according to your need.

Related

Highcharts dynamically move dataLabel if it doesnt fit

Hi I am trying to present the columns values at the top of each column so it is easier for the user to compare values.
I have got this working but when some columns are very close to each other some of the values aren't being dispalyed because I'm presuming highcharts works out that it wqouldnt fit unless it overlapped so it doesnt show the value.
Here is the code for my chart -
var chart_1_Options = {
chart: {
renderTo: 'container_chart_1',
backgroundColor: '#FFFFFF'
},
credits: {
enabled: false
},
title: {
text: ''
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: null
}
},
plotOptions: {
column: {
animation: false,
borderWidth: 0,
dataLabels: {
enabled: true,
formatter: function() {
return '<p style="font-size: 8px;">' + this.y + '% </p>';
}
}
}
},
legend: {
enabled: true
}
};
Here is an image of what the chart looks like, I have circled areas where the value is missing
I just want the value to show even if it can't fit, I want it to place the value somewhere inside the column if it cant fit at the top.
Thanks for any help!
I think that you can try to find those labels and show them by doing something like code below:
events: {
load() {
let chart = this;
chart.series[0].points.forEach(p => {
setTimeout(function() {
if (p.dataLabel.translateY === -9999) {
p.dataLabel.translate(p.dataLabel.alignAttr.x, p.dataLabel.alignAttr.y + 20)
p.dataLabel.css({
opacity: 1
})
}
}, 50)
})
}
}
Demo: https://jsfiddle.net/BlackLabel/unzgsmfr/
API: https://api.highcharts.com/highcharts/chart.events.load

Highcharts: dynamically updating chart per click of a button

Note: I have already read this question: Highcharts - Dyanmic graph with no initial data
And the effect I want to achieve is similar to this: http://jsfiddle.net/7vZ5a/40/. However, instead of updating every second, I would like it to update per click of a button. This is what I get so far:
http://jsfiddle.net/7vZ5a/49/
$(function() {
var chartData = [50, 60, 70, 100, 120, 200];
var timeStamps = [];
var index = 1;
$('#b').click(function() {
timeStamps.push(new Date());
var buttonB = document.getElementById('b');
buttonB.disabled = true;
if (index < chartData.length) {
setTimeout(function() {
if (index == 1) {
$('#container').highcharts().series[0].addPoint([0, chartData[0]], true, false);
$('#container').highcharts().series[0].addPoint([index, chartData[index]], true, false);
} else {
$('#container').highcharts().series[0].addPoint([index, chartData[index]], true, true);
index++;
}
}, 1000);
}
if (index < chartData.length - 1) {
setTimeout(function() {
buttonB.disabled = false;
}, 1500);
} else {
setTimeout(function() {
buttonB.style.visibility = "hidden";
}, 1500);
}
if (index == chartData.length - 2) {
setTimeout(function() {
document.getElementById('b').innerHTML = 'Letzte Ziehung';
}, 1000);
}
console.log(timeStamps);
})
Highcharts.setOptions({
lang: {
decimalPoint: ','
},
});
$('#container').highcharts({
chart: {
type: 'line',
marginBottom: 60
},
colors: [
'#0000ff',
],
title: {
text: ''
},
xAxis: {
title: {
text: 'Time',
offset: 23
},
min: 0,
max: 1,
tickInterval: 1,
gridLineWidth: 1
},
yAxis: {
title: {
text: 'Value'
},
min: 0,
max: 200
},
plotOptions: {
line: {
marker: {
enabled: false
}
}
},
tooltip: {
formatter: function() {
return Highcharts.numberFormat(this.y, 2) + 'GE';
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
credits: {
enabled: false
},
series: [{
name: '',
data: []
}]
});
});
Why (almost) the same code could work on the case when the chart update automatically but not on the case when the update is triggered by click?
(I also tried the function with the code controlling update not in "setTimeout" block, it also did not work.)
What you want to do is create a function that adds data to a series, like:
function addData(series, data) {
series.addPoint([series.length, data], true, false);
}
This for example adds a new point with value data to the end of series (indexed series.length, which is one index higher than the last index of the series).
Then you can bind this function to the click event of your button:
$('#add-random-data').on('click', function () {
addData(chart.series[0], Math.random());
});
This adds a random value between 0 and 1 to the series. It is assumed that the chart is stored in a variable named chart, and series[0] is the series of that chart that you want to add the data to.
This fiddle shows this on the given example chart.
The reason why your code doesn't work is that you set min and max of your x-axis, as pointed out in the comments. That way the chart won't plot data that is indexed outside of your limits. You can just let the chart auto-scale its axes by removing the min and max properties. If you want the values to always be between 0 and 1 on the x-axis, you have to overwrite the points with index 0 and 1 in your series.

Remove Tooltip in Synchronized Charts, When user leaves the chart area

I am using Synchronized chart of Highcharts to demonstrate the statistics.
For reference : http://www.highcharts.com/demo/synchronized-charts.
Here, when the chart is getting plotted for the first time, no data points is selected. As, the cursor enters into the chart area, the tooltip, crosshairs and data points get highlighted. It works as expected.
The modification I need is, when the user comes out of the chart, the chart should look like as it was in the loading stage.
i.e. If the cursor is not on any of the chart,then no data points should remain selected. In other words, the tooltip, crosshair and the highlighted shadow on data point should get removed.
Thanks in advance for any help or suggestion.
use mouseleave to detect when the mouse is out of the container:
$('#container').bind('mouseleave', function(e) {
use hide method to hide the tooltip and hide Crosshair method to hide the crosshair:
chart.tooltip.hide(point);
chart.xAxis[0].hideCrosshair();
Check the example (jsfiddle):
$(function() {
$('#container').bind('mouseleave', 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);
point = chart.series[0].searchPoint(event, true);
point.onMouseOut();
chart.tooltip.hide(point);
chart.xAxis[0].hideCrosshair();
}
});
$('#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
point = chart.series[0].searchPoint(event, true); // Get the hovered point
if (point) {
point.onMouseOver(); // Show the hover marker
chart.tooltip.refresh(point); // Show the tooltip
chart.xAxis[0].drawCrosshair(event, point); // Show the crosshair
}
}
});
/**
* Override the reset function, we don't need to hide the tooltips and crosshairs.
*/
Highcharts.Pointer.prototype.reset = function() {
return undefined;
};
/**
* 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'
});
}
}
});
}
}
// Get the data. The contents of the data file can be viewed at
// https://github.com/highcharts/highcharts/blob/master/samples/data/activity.json
$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=activity.json&callback=?', function(activity) {
$.each(activity.datasets, function(i, dataset) {
// Add X values
dataset.data = Highcharts.map(dataset.data, function(val, j) {
return [activity.xData[j], val];
});
$('<div class="chart">')
.appendTo('#container')
.highcharts({
chart: {
marginLeft: 40, // Keep all charts left aligned
spacingTop: 20,
spacingBottom: 20
},
title: {
text: dataset.name,
align: 'left',
margin: 0,
x: 30
},
credits: {
enabled: false
},
legend: {
enabled: false
},
xAxis: {
crosshair: true,
events: {
setExtremes: syncExtremes
},
labels: {
format: '{value} km'
}
},
yAxis: {
title: {
text: null
}
},
tooltip: {
positioner: function() {
return {
x: this.chart.chartWidth - this.label.width, // right aligned
y: -1 // align to title
};
},
borderWidth: 0,
backgroundColor: 'none',
pointFormat: '{point.y}',
headerFormat: '',
shadow: false,
style: {
fontSize: '18px'
},
valueDecimals: dataset.valueDecimals
},
series: [{
data: dataset.data,
name: dataset.name,
type: dataset.type,
color: Highcharts.getOptions().colors[i],
fillOpacity: 0.3,
tooltip: {
valueSuffix: ' ' + dataset.unit
}
}]
});
});
});
});

How to Hide rest of the region when user clicks pie chart?

I have pie chart representation of user locations as below in figure 1,i have successfully made the representation working but how can i make the rest of users hidden as figure 2 when click any particular sector ?
Figure 1:
Figure 2:
Javascript :
$(function () {
$('#container').highcharts({
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false
},
title: {
text: 'users location'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.percentage:.1f} %',
style: {
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
}
}
}
},
series: [{
type: 'pie',
name: 'Browser share',
data: [
['Africa', 45.0],
['Asia', 26.8],
{
name: 'Australia',
y: 12.8,
sliced: true,
selected: true
},
['Europe', 8.5],
['North America', 6.2],
['Others', 0.7]
]
}]
});
});
Fiddle Link
You can use plotOptions.series.point.events.click function to tell the chart exactly what to do after the click of a slice:
series: {
point: {
events: {
click: function () {
var index = this.x;
$('.highcharts-series-group g path').toggle();
$('.highcharts-series-group g path:nth-child(' + (index+1) + ')').toggle();
$('.highcharts-data-labels path').toggle();
$('.highcharts-data-labels path:nth-child(' + (index+1) + ')').toggle();
$('.highcharts-data-labels g').toggle();
$($('.highcharts-data-labels g').get(index)).toggle();
}
}
}
}
The first two toggles are for the slices themselves. $('.highcharts-series-group g path') refers to all the colored slices in the chart, and I changed back the one user just clicked by adding :nth-child.
The second pair of toggles are for the lines coming out of the slices connecting the datalabels to them. And the third pair is for the datalabels.
Here's the DEMO.
And example in pure Highcharts. As an another answer, use pie.point.events.click handler, to hide/show elements: http://jsfiddle.net/5oLmj00L/8/
point: {
events: {
click: function() {
var _self = this,
undef,
method = _self.clicked ? "show" : "hide";
Highcharts.each(this.series.data, function(p, i) {
if(p !== _self) {
// hide/show slice
if(p.graphic) {
p.graphic[method]();
}
// hide/show label
if(p.dataLabel) {
p.dataLabel[method]();
}
// hide/show connector
if(p.connector) {
p.connector[method]();
}
}
});
// set flag for next click:
_self.clicked = _self.clicked !== undef ? !_self.clicked : true;
}
}
}

Highstocks: How to define the span colors of a line instead of the individual line color

I am creating a Gantt Chart using Highstocks(compare multiple series).
1. I want to have the First span color to be Red, the second Blue and third Green.
How can I do the same?
2. how can i set the tooltip to show the values of all the points on the line instead of all points at the time.
3. How to fix y-axis and it should add scroll as values increase.
Please check the Gantt Chart Fiddle here.
var partNumber="2724070125R Planned,2724070125RActual,5511822432R Planned,5511822432RActual";
var partNum = partNumber.split(",");
var ganttData = [
[[Date.UTC(2013,11-1,07),1], [Date.UTC(2013,11-1,29),1], [Date.UTC(2013,11-1,30),1]],
[[Date.UTC(2013,11-1,20),1.25],Date.UTC(2013,11-1,21),1.25],Date.UTC(2013,12-1,21),1.25]],
[[Date.UTC(2013,11-1,13),2],[Date.UTC(2013,12-1,10),2],[Date.UTC(2014,02-1,14),2]],
[[Date.UTC(2013,11-1,21),2.25],[Date.UTC(2013,11-1,21),2.25],[Date.UTC(2013,11-1,30),2.25]]];
$( document ).ready(function(){
$(function() {
var seriesOptions = [],
yAxisOptions = [],
seriesCounter = 0,
names = partNum,
colors = Highcharts.getOptions().colors;
var data=ganttData;
$(function () {
$.each(names, function(i, name) {
seriesOptions[i] = {
// name: data[i][1],
name:name,
step:true,
data: data[i]
};
// As we're loading the data asynchronously, we don't know what order it will arrive. So
// we keep a counter and create the chart when all the data is loaded.
seriesCounter++;
if (seriesCounter == names.length) {
createChart();
}
});
});
// create the chart when all data is loaded
function createChart() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
$('#ganttChart').highcharts('StockChart', {
chart: {
},
title: {
text: 'PPAP Cumulative Status'
},
rangeSelector: {
selected: 4
},
xAxis: {
type: 'datetime', ordinal: false //this sets the fixed time formats
},
yAxis: {
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}],
min:0 },
plotOptions: {
series: {
lineWidth: 3,
states: {
hover: {
enabled: true,
lineWidth: 3
}
}
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>',
valueDecimals: 0
},
series: seriesOptions,
exporting: {
enabled: false
}
});
}
});
});
1) You can set for series only one color. Here:
$.each(names, function(i, name) {
seriesOptions[i] = {
name: name,
step: true,
data: data[i],
color: 'yourColor'
};
...
});
2) In tooltip, you have access to series via this.points[0].series.data etc. So you can get all points.
3) Scroll is not supported.

Categories