Change HighCharts plotLine-value and -label - highcharts

I have implemented a plot line that's showing an average of all values:
"yAxis": {
plotLines: [{
color: 'red',
value: 22,
width: '1',
label: {
text: 'Average: 22'
}
}]
},
I want to change the average-value on legendItemClick. Is it possible to change some plotLine-properties programatically?
What I tried so far is this:
plotOptions: {
series: {
events: {
legendItemClick: function (event) {
var average = 15;
event.target.chart.userOptions.yAxis.plotLines[0].value = average;
event.target.chart.userOptions.yAxis.plotLines[0].label.text = 'Average: ' + average;
}
},
}
},
The value and the label-text aren't changing in the chart. Also I tried to redraw the chart but it still isn't changing the plot line. Is there a way to accomplish this?

I now have found an acceptable answer to my own question:
var average = 15;
event.target.chart.yAxis[0].removePlotLine('average');
event.target.chart.yAxis[0].addPlotLine({
id: 'average',
color: 'red',
width: 1,
value: average,
zIndex: 200,
label: {
text: 'Average: ' + average
}
});
I have to specify an ID for the plotLine, destroy it and create a new one.

Related

How to set alignment of individual x-axis labels in Highcharts

I have a chart where basically I want to set the alignment of the first/last labels on the x-axis to be left/right and any labels in between would be the default center. From what I can tell there is only a way to set the Labels.alignment property to apply to all labels and no clear way to individually align them
here is a before and after pic of what I am trying to achieve:
xAxis: {
title: {
enabled: false,
text: ''
},
crosshair: {
width: 2,
color: '#C4C4C4',
dashStyle: 'shortdot'
},
lineColor: 'transparent',
tickLength: 1,
labels: {
//overflow: 'justify',
step: 1,
formatter: function() {
console.log(this.value)
//if(this.value == 0 || this.value == 9)
return Highcharts.dateFormat("%b<br/>%Y", new Date(chartData.Dates[this.value]));
},
//align: 'center',
style: {
fontSize: '14px'
}
},
//tickPositions: [0,3,5,7,9]
},
any help would be appreciated, here is my working fiddle:
fiddle
You can use the render callback to find those labels and use the translate feature to move them.
chart: {
height: 300,
events: {
render() {
const xAxis = this.xAxis[0];
const ticksPositions = xAxis.tickPositions;
const ticks = xAxis.ticks;
const firstTickLabel = ticks[0].label;
const lastTickLabel = ticks[ticksPositions.length - 1].label;
firstTickLabel.translate(firstTickLabel.getBBox().width / 2, 0)
lastTickLabel.translate(-lastTickLabel.getBBox().width / 2, 0)
}
}
},
Demo: https://jsfiddle.net/BlackLabel/krL5ey1o/
API: https://api.highcharts.com/highcharts/chart.events.render
API: https://api.highcharts.com/class-reference/Highcharts.SVGElement#translate

Negative bar chart of highcharts in chartjs

I been playing with Chartjs to generate something like highcharts but couldn't bring it close. The application is finished and it seems a waste to buy highcharts, migrate from chartjs for this single chart.
Is there a way Chartjs can output something like that? I did try creating two horizontal bar charts side-by-side in separate canvas; while i saw the output; the behavior is not what I want.
You could use a horizontal stacked barchart with two datasets. Add negative values to the dataset on the left (male) but display the absolute value in the callbacks of the xAxis and the tooltip.
var ctx = document.getElementById('myChart').getContext('2d');
var data = {
labels: ["20-30", "10-20", "0-10"],
datasets: [{
label: "Male",
backgroundColor: "rgba(54, 162, 235, 0.2)",
borderColor: "rgb(54, 162, 235)",
borderWidth: 2,
data: [-65, -59, -20],
}, {
label: "Female",
backgroundColor: "rgba(255,99,132,0.2)",
borderColor: "rgba(255,99,132,1)",
borderWidth: 2,
data: [72, 45, 18],
},
]
};
var myBarChart = new Chart(ctx, {
type: 'horizontalBar',
data: data,
options: {
scales: {
yAxes: [{
stacked: true
}],
xAxes: [{
ticks: {
callback: function(value, index, values) {
return Math.abs(value);
}
}
}]
},
tooltips: {
callbacks: {
label: function(tooltipItems, data) {
return data.datasets[tooltipItems.datasetIndex].label + ": " + Math.abs(tooltipItems.xLabel);
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<canvas id="myChart"></canvas>

How to extend a line series as dotted only when checkbox is clicked?

I have a line series from say 0-t1 interval of x.
i want to show an extended dashed line from t1-t2(in the same series) if user click on the checkup next to legend.
Can anyone suggest how to go about it?
You should be able to use checkboxClick function for updating your series on checkbox click:
http://api.highcharts.com/highcharts/plotOptions.series.events.checkboxClick
http://api.highcharts.com/highcharts/Series.update
You can use zones for changing style of your line from some value:
http://api.highcharts.com/highcharts/plotOptions.series.zones
series: [{
data: [-10, -5, 0, 5, 10, 15, 10, 10, 5, 0, -5],
showCheckbox: true,
events: {
checkboxClick: function() {
var checkbox = this.checkbox;
var newData = $.extend([], true, data);
for (var i = 0; i < 14; i++) {
newData.push(20 * Math.random());
}
if (checkbox.checked) {
this.update({
zones: [{
value: data.length - 1,
}, {
dashStyle: 'dash'
}],
selected: false,
zoneAxis: 'x',
data: newData
})
} else {
this.update({
zones: [],
data: data,
selected: true
});
}
}
}
}]
Live example of a chart with zones:
http://jsfiddle.net/yavvLvea/3/

Auto chart height

The default highstock chart has height = 400px.
How can height chart be set for auto size based on chart axis and its sizes ?
See the example bellow, the navigation bar is over the volume panel.
http://jsfiddle.net/BYNsJ/
I know that I can set the height for the div but I have a solution that insert/remove axis/series dynamically in the chart and would be nice an auto height chart.
The example is the same Candlestick/Volume demo from Highchart site, but without height property in the div container.
// split the data set into ohlc and volume
var ohlc = [],
volume = [],
dataLength = data.length;
for (i = 0; i < dataLength; i++) {
ohlc.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4] // close
]);
volume.push([
data[i][0], // the date
data[i][5] // the volume
])
}
// set the allowed units for data grouping
var groupingUnits = [[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]];
// create the chart
$('#container').highcharts('StockChart', {
rangeSelector: {
selected: 1
},
title: {
text: 'AAPL Historical'
},
yAxis: [{
title: {
text: 'OHLC'
},
height: 200,
lineWidth: 2
}, {
title: {
text: 'Volume'
},
top: 300,
height: 100,
offset: 0,
lineWidth: 2
}],
series: [{
type: 'candlestick',
name: 'AAPL',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
});
});
});
Regards.
here is one example which is resize chart according screen.
http://jsfiddle.net/davide_vallicella/LuxFd/2/
Just don't set the height property in HighCharts and it will handle it dynamically for you so long as you set a height on the chart's containing element. It can be a fixed number or a even a percent if position is absolute.
http://api.highcharts.com/highcharts/chart.height
By default the height is calculated from the offset height of the containing element
find example here:- http://jsfiddle.net/wkkAd/149/
#container {
width:100%;
height:100%;
position:absolute;
}
hey I was using angular 2+ and highchart/highstock v.5, I think it will work in JS or jQuery also, here is a easy solution
HTML
<div id="container">
<chart type="StockChart" [options]="stockValueOptions"></chart>
</div>
CSS
#container{
height: 90%;
}
TS
this.stockValueOptions = {
chart: {
renderTo: 'container'
},
yAxis: [{
height: '60%'
},{
top: '65%',
height: '35%'
}]
}
Its working, and a easy one. Remove chart height add height in '%' for the yAxis.
Highcharts does not support dynamic height, you can achieve it by $(window).resize event:
$(window).resize(function()
{
chart.setSize(
$(document).width(),
$(document).height()/2,
false
);
});
See demo fiddle here.
You can set chart.height dynamically with chart.update method.
http://api.highcharts.com/highcharts/Chart.update
function resizeChartFromValues (chart) {
const pixelsForValue = 10
const axis = chart.yAxis[0]
chart.update({ chart: { height: (axis.max - axis.min) * pixelsForValue } })
}
const options = {
chart: {
events: {
load () {resizeChartFromValues(this)}
}
},
series: [{
data: [30, 70, 100],
}]
}
const chart = Highcharts.chart('container', options)
setTimeout(() => {
chart.series[0].setData([10, 20, 30])
resizeChartFromValues(chart)
}, 1000)
Live example: https://jsfiddle.net/a97fgsmc/
I had the same problem and I fixed it with:
<div id="container" style="width: 100%; height: 100%; position:absolute"></div>
No special options to the chart. The chart fits perfect to the browser even if I resize it.

Changing color of spline lines based on values in HighCharts

I can change the marker color based on if it's above (red) or below (green) or between (yellow), but cannot change the color of the line in between the markers. Is this possible? Right now, it just displays as a blue line.
function makeRun(divId, last, current, goal, title, yAxisTitle) {
var width = 1000; var SizeOfFont = '14px';
var min = checkMinMaxArray(current, last, goal, 'min') * 995 / 1000; //sets min closely below the real min. **consider changing to 4/5 digits**
var max = checkMinMaxArray(current, last, goal, 'max') * 1005 / 1000; //sets max closely above the real max
//if there are projections, color code the columns here
preprocessData = function (data, last, goal) {
var nData = [];
var colorGood = 'green'; var colorBad = '#E42217'; var colorUse;
for (var i = 0; i < data.length; i++) {
if (data[i] <= goal[i]) { colorUse = colorGood; }
else if (data[i] > last[i]) { colorUse = colorBad; }
else { colorUse = '#FFE303'; }
nData.push({
y: data[i],
x: i,
fillColor: colorUse,
color: colorUse
});
}
return nData;
};
var chart = new Highcharts.Chart({
chart: {
renderTo: divId,
height: 275, //little bigger than alotted height to make more readable
width: width //dependent on #gauges
},
title: {
text: title, //should all be the same, can make a parameter if need to be different
style: { //size of text above
fontSize: SizeOfFont
}
},
xAxis: {
//categories: xAxisTitles,
labels: { //size of the Text above^^
style: {
fontSize: SizeOfFont
}
}
},
yAxis: {
min: min,
max: max,
title: {
text: yAxisTitle, //parameter since some are days, percents, etc
style: {//size of y axis title
fontSize: SizeOfFont
}
},
labels: {
style: {//size of the y axis tick labels
fontSize: SizeOfFont
}
}
},
credits: {//gets rid of the highcharts logo in bottom right
enabled: false
},
legend: {//the legend at the bottom
style: {
fontSize: '12px'
}
},
series: [{
type: 'spline',
name: '2012',
data: last,
color: 'orange',
marker: {
symbol: 'diamond'
}
}, {
type: 'spline',
name: '2013',
data: preprocessData(current, last, goal),
marker: {
symbol: 'diamond'
}
}, {
type: 'spline',
name: 'Goal',
data: goal,
color: 'blue',
marker: {
symbol: 'diamond'
}
}]
});
}
It is not possible in one serie, you should prepare two separate serie with different colors.

Resources