Making two series point in opposite directions in highcharts - javascript

I have a column chart with two series, one of which I want to go down and the other up, like this:
However both of the series have positive y-values, which I can't change, e.g.
blue = [1746181, 1884428, 2089758, 2222362, 2537431, 2507081, 2443179,
2664537, 3556505, 3680231, 3143062, 2721122, 2229181, 2227768,
2176300, 1329968, 836804, 354784, 90569, 28367, 3878];
grey = [1656154, 1787564, 1981671, 2108575, 2403438, 2366003, 2301402, 2519874,
3360596, 3493473, 3050775, 2759560, 2304444, 2426504, 2568938, 1785638,
1447162, 1005011, 330870, 130632, 21208];
Using highcharts options, is it possible to have a chart like this? The example I used for the screenshot is this jsFiddle if it's useful to anyone, however it has a series with negative values which is not an option for me. Instead my data is more like this fiddle

I would try to use two separate yAxes: http://jsfiddle.net/zares7x9/2/, where one of them is reversed:
yAxis: [{
title: {
text: null
},
top: '5%',
height: '45%',
labels: {
formatter: function () {
return (Math.abs(this.value) / 1000000) + 'M';
}
},
min: 0,
max: 4000000
}, {
title: {
text: null
},
labels: {
formatter: function () {
return (Math.abs(this.value) / 1000000) + 'M';
}
},
offset: 0,
showFirstLabel: false, // hide 0-value
reversed: true, //reverse
top: '50%',
height: '45%',
min: 0,
max: 4000000
}],
Setting top and height allows you to render axes like one. Note, that you need to set for one of the series yAxis: 1, to inform Highcharts which series belongs to which axis.

Related

Highcharts.js question: is it possible to keep some part of chart in visible area always, even if "overscoll" option is set

I need to show some empty space to far right of the chart. To do so I use "overscroll" option (https://api.highcharts.com/highstock/xAxis.overscroll). But if user zoom in chart and pans chart to far right there can be empty space without any part of candlestick chart displayed (https://screencast-o-matic.com/watch/cqnfFq3CII). Please advise is it possible to implement following chart behaviour and how to do so: to keep some part of chart in visible area always, even if "overscoll" option is set and user pans chart to the far right? Thanks!
Here is my code:
var ohlc = JSON.parse(ohlcStringified),
volume = JSON.parse(volumeStringified);
var interval = ohlc[ohlc.length - 1].x - ohlc[ohlc.length - 2].x;
var chart = Highcharts.stockChart('container', {
chart: {
borderWidth: 1,
panning: true,
},
title: {
text: 'Chart'
},
legend: {
enabled: true
},
rangeSelector: {
selected: 1,
enabled: false
},
scrollbar: {
enabled: false
},
xAxis: {
minPadding: 0.2,
overscroll: 50 * interval,
},
yAxis: [{
height: '40%'
}, {
top: '40%',
height: '30%',
offset: 0
}, {
top: '70%',
height: '30%',
offset: 0
}],
series: [{
type: 'candlestick',
id: 'candlestick',
name: 'AAPL',
data: ohlc,
tooltip: {
valueDecimals: 2
},
dataGrouping: {
enabled: false,
}
}, {
type: 'column',
id: 'volume',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
enabled: false,
}
}]
});
Here is live demo: http://jsfiddle.net/ogorobets/bfcs9gx7/2/
It's possible, however, it requires some custom logic. It can be achieved using xAxis.events.afterSetExtremes callback where you can check if the current axis minimum is greater than your limit (a value lower than maximum xData value). When it is true, set new axis extremes with your limit as a minimum value. Check the code and demo posted below.
Code:
xAxis: {
minPadding: 0.2,
overscroll: 50 * interval,
events: {
afterSetExtremes: function() {
var chart = this.chart,
xData = chart.series[0].xData,
maxValue = xData[xData.length - 5],
min = chart.xAxis[0].min,
max = chart.xAxis[0].max
if (min > maxValue) {
chart.xAxis[0].setExtremes(maxValue, max, true, false);
}
}
}
}
Demo:
https://jsfiddle.net/BlackLabel/p6d73nk8/
API reference:
https://api.highcharts.com/highcharts/xAxis.events.afterSetExtremes
https://api.highcharts.com/class-reference/Highcharts.Axis#setExtremes

Highcharts Tick Positions are not aligned on multiple Y-axises

I have multiple charts on the same page, and the goal was to have same max values for each of the metrics on all charts to make comparison of charts easier ( https://www.screencast.com/t/vtF6h5ZRWS )
I've tried with max values and min values, but it doesn't works, probably because of multiple y-axises.
Now I'm trying to use tickpositions (which I'm calculating in backend) and passing it to chart. But here is the problem with tick alignment on opposite axes and it appears as shown https://www.screencast.com/t/iwnGOhJFb
Below is the small part of code how I set the tick positions and the fiddle of simpler version of chart that I have (I had more y axis's)
yAxis: [{ // Primary yAxis
labels: {
format: '{value}',
style: {
color: Highcharts.getOptions().colors[2]
}
},
title: {
text: 'Impressions',
style: {
color: Highcharts.getOptions().colors[2]
}
},
tickPositions: [0, 5500000, 11000000, 15000000]
}
http://jsfiddle.net/j82oen9c/8/
How can I achieve tick alignments on all y-axis's ?
In order to align the ticks on both axes, you can use two different approaches.
FIrst one is by define your own Axis.tickPositioner function which returns calculated array of tickcs adjusted to your needs.
Moving on, you need to get the same amount of ticks on both axes, and they should lay on the same positions on axes, so the positioner function should receive two arguments - maxValueOfCurrentAxis and tickAmount. I wrote the function like that:
var positioner = function(tAmount, axisMax) {
var positions = []
for (var i = 0; i < tAmount; i++) {
positions.push(Math.round(((axisMax / tAmount) * i) * 100) / 100)
}
positions.push(axisMax)
return function() {
return positions
}
}
and now, we need to assign this function with specific parameters as the Axis.tickPositioner, and define the amount of ticks and max values of both axes:
var tickAmount = 3
var firstAxisMax = 15000000
var secondAxisMax = 2
yAxis: [{ // Primary yAxis
labels: {
format: '{value}',
style: {
color: Highcharts.getOptions().colors[2]
}
},
title: {
text: 'Impressions',
style: {
color: Highcharts.getOptions().colors[2]
}
},
tickPositioner: positioner.apply(this, [tickAmount, firstAxisMax]),
}, { // Secondary yAxis
gridLineWidth: 0,
tickPositioner: positioner.apply(this, [tickAmount, secondAxisMax]),
title: {
text: 'eCPM',
style: {
color: Highcharts.getOptions().colors[0]
}
},
labels: {
format: '{value} $',
style: {
color: Highcharts.getOptions().colors[0]
}
},
opposite: true
}],
Live example: http://jsfiddle.net/vL324nqx/
The second way out of that issue, but not so much adjusted to your needs, is by using Axis.tickPixelInterval property on both axes. There is no need to explain it more precisely, because there are clear informations about that in API.
Live example: http://jsfiddle.net/mqget4hb/
API Reference:
https://api.highcharts.com/highcharts/yAxis.tickPositioner
https://api.highcharts.com/highcharts/yAxis.tickPixelInterval

Label distance in polar chart is not equal on each angle

Who's gonna tell me, how to make correction of label positioning depends on value and angle in Highcharts Polar chart?
Please take a look at pictures:
Example 1: Here you can see, that angle values are displayed on bottom half is not positioned well - labels aren't have so much distance from the circle of outer graph line like the top ones.
Example 2: Angle values labels are displayed like they are moved a little bit to the right and labels at down is moved up a little bit too - the same as in example 1.
I'm using library Highstock v5.0.12. and here is fragment of my js code:
xAxis: {
tickInterval: 30,
min: 0,
max: 360,
labels: {
formatter: function() {
return this.value + '°';
},
style: {
"fontSize": "1.1vw",
},
distance: 15,
}
},
Creating solution using documented example and updating with existing code.
Solution is to update with useHTML and align property
xAxis: {
tickInterval: 30,
min: 0,
max: 360,
labels: {
formatter: function() {
return this.value + '°';
},
style: {
"fontSize": "1.1vw",
},
distance: 15,
useHTML: true,
align: 'center'
}
},
Fiddle
You can you xAxis.labels.y option for this:
labels: {
y: 6,
formatter: function() {
return this.value + '°';
},
style: {
fontSize: '20px'
}
}
Live demo: http://jsfiddle.net/kkulig/36k19Lhp/
API reference: https://api.highcharts.com/highcharts/xAxis.labels.y

Chart.js two Y-Axis, one with negative values

I've got two Y-axis in my line chart. One of the charts can show negative values between -1 and 1 (left axis). The other one has values from 0 to X (right axis). Problem is, that the left has the 0 point in the middle, the right axis shows 0 at the bottom.
Is there any fix to it? Some thing like set the negative max value as min value for the right axis would solve it. But I don't know how to perform this.
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: dates,
datasets: [{
label: 'Sentiment',
yAxisID: 'left',
data: normalizedSentiment // contains from -1 to 1
}, {
label: 'Count',
yAxisID: 'right',
data: count // only positive
}]
},
options: {
scales: {
yAxes: [{
id: 'left',
type: 'linear',
position: 'left',
}, {
id: 'right',
type: 'linear',
position: 'right'
}]
}
}
});
I basically used this solution: https://stackoverflow.com/a/38094165/1193235
If the left chart is always -1 to 1, then you need the right chart to be from -z to z.
Given your dataset, calculate the max value (if your right set included negative numbers you'd also need the least number, then take the absolute value of both and see which is greater, but your code says it's only positive).
Something like const yMax = Math.max(...dataset.map(d => d.y));
Set your options up like this
options: {
scales: {
yAxes: [{
id: 'left',
type: 'linear',
position: 'left',
}, {
id: 'right',
type: 'linear',
position: 'right'
ticks: {
min: -yMax,
max: yMax
}
}]
}
}

Highchart datetime graph x-axis unable to get data on plot when min and max is on

$(function () {
$('#container').highcharts({
chart: {
showAxes : true,
type: 'line',
marginRight: 130,
marginBottom: 25
},
tooltip: {
crosshairs: [true],
shared : true
},
title: {
text: '',
x: -20 //center
},
subtitle: {
text: '',
x: -20
},
xAxis: {
type :'datetime',
tickInterval : 12*30*24*3600* 1000,
min : Date.UTC(2011, 0, 1),
max : Date.UTC(2020, 0, 1),
label : {
align : 'left'
}
},
yAxis: {
title: {
text: 'PRICE Rs. / SQ.FT.'
},
lineWidth: 2,
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
series: [{
data:[2165,1831,2798,2200,2237,2799,2400,2500,2865,2850]
}]
});
});
My x-axis having Years and data series having information which i want to show on Y axis.
When i remove the interval from 2010 to 2022 i . e comment min and max option highcharts draws a graph starting from 1970 , but no points afterwards.
http://jsfiddle.net/R8kx7/3/ here is the link
Based on your comments to #SteveP answer, if you don't want to explicitly pair x values to each y for each series, use the plotOptions.series pointStart and pointInterval properties.
plotOptions: {
series: {
pointStart: Date.UTC(2011, 0, 1),
pointInterval : 12*30*24*3600* 1000
}
},
series: [{
data:[2165,1831,2798,2200,2237,2799,2400,2500,2865,2850]
}]
Updated fiddle here.
Although you are specifying min and max, your data has no x values specified, so it is assuming that the date time values are starting at 0. There are several ways to render the chart you want.
Firstly, you could specify x values in your data points e.g.
{x:Date.UTC(2011, 0, 1),y:2165}
Another way is to not use a datetime axis type, and just specify the categories you want in the x-axis:
categories:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
The second option is probably a bit simpler http://jsfiddle.net/K6xxz/

Categories