Highcharts Zoom in Logarithmic Scale - javascript

I was toying around with the Logarithmic Scale in Highcharts.
Noticed that the zoom behaves in a weird manner when close to minValue.
The fiddle here is a slightly modified example of the original fiddle that Highcharts had for demonstrating a line chart over log scale.
Here is the code in full for a column chart that utilizes a log scale.
$(function () {
$('#container').highcharts({
chart: {
type:'column',
zoomType:'xy'
},
title: {
text: 'Logarithmic axis demo'
},
xAxis: {
tickInterval: 1
},
yAxis: {
type: 'logarithmic',
minorTickInterval: 0.1
},
tooltip: {
headerFormat: '<b>{series.name}</b><br />',
pointFormat: 'x = {point.x}, y = {point.y}'
},
series: [{
data: [1, 2, 4, 8, 16, 32, 64, 128, 256, 512],
pointStart: 1
}]
});
});
Try zooming between .1 and 1 and you'll see that everything disappears but the chart seems to have zoomed somewhere.
Is there an explanation for this behavior?

You need to set minRange parameter
yAxis: {
type: 'logarithmic',
minRange:0.1,
minorTickInterval: 0.1
},
http://jsfiddle.net/G6ALa/1/

Related

In highcharts, is it possible to make a bar in a column chart with its top bordering the edge of the chart area "on top" of the chart border?

This is the JSFiddle for demonstration.
In the two bars shown in the above JSFiddle, the respective top and the bottom side of the two bars are not black, but grey, since that is the color of the chart border/border of plot area. Would it be possible to make the two bars to be "on top" of the chart border (so that all their sides are black)? I have tried with zIndex in "series". But that does not work.
These are the most relevant javascript code:
Highcharts.chart('container', {
chart: {
type: 'column',
borderWidth: 1,
plotBorderWidth: 1,
marginBottom: 100
},
plotOptions: {
series: {
borderColor: 'black',
animation: false
},
},
xAxis: {
categories: ['1', '2']
},
yAxis: {
tickInterval: 10,
min: -50,
max: 50
},
series: [{
data: [50, -50],
zIndex: 300
}]
});
To achieve this effect, you can set series.column.clip: false.
Disabling this option allows series rendering over plotArea borders.
series: [{
clip: false,
data: [50, -50]
}]
Live demo:
https://jsfiddle.net/BlackLabel/2kyc4dbu/
API reference:
https://api.highcharts.com/highcharts/series.column.clip

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

How to display x and y axis values of where the crosshair line intersects in series using Highcharts?

I have been working on a project that uses highchart to draw multiple line charts. With that, I have already achieved some configuration (eg. x-axis crosshair, fixed tooltip, zooming) for my chart in accordance to the business requirements. As such, one requirement is that when x-axis crosshair moves from left to right (or vice versa) within the plotted chart, the selected values on y-axis and dates and time on x-axis will be displayed in the fixed tooltip.
Example:
Series CDT158 has a value of 100.46 (as shown in Chart 1) on 27 Apr 2017 20:49:48 pm. When I move the x-axis crosshair to the right, it jumps directly to the next point which has a value of 103.47 (as shown in Chart 2) on 27 Apr 2017 20:50:38 pm.
Is it possible when the crosshair passes through the series (from one point to the next point), the y-axis values between 100.46 and 103.47 as well the datetime values on x-axis will be rendered in the fixed tooltip? I also want to display the CDEP158 y-axis values simultaneously in the fixed tooltip. How can I achieve this?
[Chart 1]
[Chart 2]
This is the Highchart initialization.
myChart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
zoomType: 'xy',
panning: true,
panKey: 'shift',
plotBorderWidth: 1
},
title: {
text: ''
},
legend: {
layout: 'horizontal',
align: 'left',
itemDistance: 10,
borderWidth: 0,
itemMarginTop: 0,
itemMarginBottom: 0,
padding: 20
},
plotOptions: {
series: {
states: {
hover: {
enabled: false
}
},
dataLabels: {
enabled: false,
format: '{y}'
},
allowPointSelect: false
}
},
xAxis: {
type: 'datetime',
labels: {
rotation: -65,
style: {
fontSize: '9px',
fontFamily: 'Verdana, sans-serif'
}
},
crosshair: true,
dateTimeLabelFormats: {
second: '%d %b %Y <br/> %H:%M:%S %P',
}
},
yAxis: {
gridLineColor: '#DDDDDD',
gridLineWidth: 0.5
},
tooltip: {
positioner: function () {
return {
x: this.chart.plotLeft,
y: this.chart.plotTop
}
},
useHTML: true,
formatter: function (tooltip) {
var formattedDate = Highcharts.dateFormat('%d %b %Y <br/> %H:%M:%S %P', new Date(this.x));
const header = `<span style="font-size: 8px">${formattedDate}</span><br/>`;
let body = this.points.reduce((body, p) => body + `<small><font color="${p.series.color}"><strong>${p.series.name}</strong></font>: <strong>${p.y}</strong></small><br/>`, '');
return header + body;
},
shared: true,
valueDecimals: 2,
//followPointer: true,
shadow: false,
borderWidth: 0,
backgroundColor: 'rgba(255,255,255,0.8)'
},
series: [{
name: 'CDT158',
data: [
[1493326164493, 87.54],
[1493326174018, 97.09],
[1493326188245, 100.46],
[1493326238635, 103.47],
[1493326284930, 106.12]
]
},{
name: 'CDEP158',
data: [
[1493326165993, 94.34],
[1493326174772, 88.87],
[1493326188895, 98.25],
[1493326272411, 96.48],
[1493326299520, 100.13]
]
}]
});
I'm pretty sure that this can be achieved through Highcharts but, my limited knowledge and experience in Highchart stops me to figure it out.
I have posted a sample fiddle that illustrate the above scenario.
Any help is greatly appreciated.

How do I remove padding from both sides of Highcharts area category chart?

There's too much padding on either side of the area chart and minPadding/maxPadding doesn't work with categories.
I want the area chart to start and end without any padding.
My code is below:
http://jsfiddle.net/nx4xeb4k/1/
$('#container').highcharts({
chart: {
type: 'area',
inverted: false
},
title: {
text: 'Too Much Padding On Either Side'
},
plotOptions: {
series: {
fillOpacity: 0.1
}
},
xAxis: {
type: 'category'
},
yAxis: {
title: {
text: 'Data Point'
}
},
legend: {
enabled: false
},
tooltip: {
pointFormat: '<b>{point.y}</b> points'
},
series: [{
name: 'Visits',
data: [
["Monday", 58],
["Tuesday", 65],
["Wednesday", 55],
["Thursday", 44],
["Friday", 56],
["Saturday", 65],
["Sunday", 69]
],
dataLabels: {
enabled: false,
rotation: -90,
color: '#FFFFFF',
align: 'right',
format: '{point.y:.1f}',
y: 10,
style: {
fontSize: '14px',
fontFamily: 'Verdana, sans-serif'
}
}
}]
});
A colleague of mine solved this very situation for some of my charts. Their solution was to remove the type: 'category' from the x-axis (making it a linear type instead) and instead replace the axis labels from an array.
Here's what's been changed:
First, I added an array of your x-axis labels.
var categoryLabels = ["Monday","Tuesday","Wednesday","Thursday","Friday",
"Saturday","Sunday"];
Next, I updated your series values to hold only the y-axis values.
series: [{
name: 'Visits',
data: [58, 65, 55, 44, 56, 65, 69],
Then, for your x-axis, I included a formatter function to pull in the labels from the array as substitutes for the default linear values.
xAxis: {
labels: {
formatter: function(){
return categoryLabels[this.value];
}
}
},
Lastly, I updated the tooltip options to show the values from the labels array.
tooltip: {
formatter: function () {
return categoryLabels[this.x] + ': ' + Highcharts.numberFormat(this.y,0);
}
},
I updated your fiddle with this tweaks: http://jsfiddle.net/brightmatrix/nx4xeb4k/4/
I hope you'll find this solution as useful as I have!
According to API, the default value of highcharts.xAxis.tickmarkPlacement is between and this is why the point of each category drops between two ticks on xAxis in your chart.
By setting highcharts.xAxis.tickmarkPlacement to on and playing around the value of highcharts.xAxis.min and highcharts.xAxis.max like this, you should be able to achieve what you want.
You can declare the min / max values to fix the problem.
var categoryLabels = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"];
//....
xAxis: {
min: 0.49,
max: categoryLabels.length - 1.49,
categories: categoryLabels,
type: 'category'
},
Example:
http://jsfiddle.net/fo04m7k7/

HighCharts - timeseries chart - irregular datetime interval on xAxis

I need to make a chart on which xAxis is of type 'datetime', but have irregular intervals:
http://jsfiddle.net/cz6rL/
this is the code:
$(function () {
$('#chart1').highcharts({
chart: {
zoomType: 'x',
spacingRight: 20
},
title: {
text: 'Incomes/Outcomes'
},
subtitle: {
text: document.ontouchstart === undefined ?
'Click and drag in the plot area to zoom in' :
'Pinch the chart to zoom in'
},
xAxis: {
type: 'datetime',
minRange: 15 * 24 * 3600000,
title: {
text: null
}
},
yAxis: {
title: {
text: 'Euro(€)'
}
},
tooltip: {
shared: true
},
legend: {
enabled: true
},
plotOptions: {
area: {
fillColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1},
stops: [
[0, Highcharts.getOptions().colors[9]],
[1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
]
},
//lineWidth: 1,
marker: {
enabled: false
},
shadow: false,
states: {
hover: {
lineWidth: 1
}
},
threshold: null
}
},
series: [{
type: 'area',
pointInterval: 24 * 3600 * 1000,
pointStart: Date.UTC(2014, 0, 01),
data: [["31/12/2013", 345.2], ["09/01/2014", 494.79999999999995], ["20/01/2014", 137.2], ["22/01/2014", 210.0],
["23/01/2014", 220.4], ["24/01/2014", 871.0], ["28/01/2014", 420.0], ["30/01/2014", 420.0], ["31/01/2014", 2057.15],
["05/02/2014", 191.2], ["06/02/2014", 81.6], ["07/02/2014", 295.2], ["11/02/2014", 135.12], ["12/02/2014", 189.2],
["13/02/2014", 210.0], ["14/02/2014", 315.2], ["17/02/2014", 462.79999999999995], ["18/02/2014", 544.4],
["19/02/2014", 715.4399999999999], ["20/02/2014", 971.2], ["21/02/2014", 418.0], ["02/02/2015", 366.0]]
}]
});
});
you can see that series values do not correspond to xAxis values. How can I fix it: having same days on xAxis or having months corresponding to series values days?
thanks
Luke
You can remove the pointStart assignment, highcharts will determine the range based on trhe values you provide it. Highcharts will take a look at the range of data you supply it and auto generate the tick marks based on your tickInterval settings, and the available dimensions of your chart. If you need the tick marks on the axis to be specifically the dates you have in you data, you should not used the datetime type axis.
Highcharts handles all date data value in unix/epoch time (number of seconds since 1/1/1970). If you want to use datetime axis, you must supply your data in that format.
Change all your date values such as
["31/12/2013", 345.2]
to
[Date.UTC(2013, 11, 31), 345.2]

Categories