Area chart looks flat due to the fact that Y axis always starts from 0 in compare to a line chart which in the same data uses some sort of auto-fit.
Plunkr
I would like to have similar auto-fit on the area chart that works on line chart as default.
(Using yAxis[0].setExtremes is not an option really).
Is there any configuration to do so?
You can achieve it by setting xAxis.min property like that:
yAxis: {
min: 10000,
labels: {
formatter: function() {
return this.value / 1000 + 'k';
}
}
}
Demo:
https://jsfiddle.net/BlackLabel/Layfnuz4/
API reference:
https://api.highcharts.com/highcharts/xAxis.min
The second approach is to set plotOptions.area.threshold
plotOptions: {
area: {
threshold: 10000,
marker: {
enabled: false,
symbol: 'circle',
radius: 2,
states: {
hover: {
enabled: true
}
}
}
}
}
Demo:
https://jsfiddle.net/BlackLabel/r7qc1jpk/
API reference:
https://api.highcharts.com/highcharts/series.area.threshold
EDIT
Automatic approach: set series.area.softThreshold = true as line series has.
series: [{
softThreshold: true,
name: 'Data',
data: data
}]
Demo:
https://jsfiddle.net/BlackLabel/8uj3kz4a/
API reference:
https://api.highcharts.com/highcharts/series.area.softThreshold
Related
Given a max number to the yAxis, for example:
yAxis: {
min: 0,
max:5
},
The chart will look like this:
However, is it possible to render the outer part? Just like the following below:
Instead of setting yAxis.min and yAxis.max, you can define tickPositions and disable endOnTick for yAxis and set offset for xAxis. For example:
yAxis: {
endOnTick: false,
tickPositions: [0, 2, 4, 6]
},
xAxis: {
offset: 62
},
pane: {
size: '100%'
}
Live demo: http://jsfiddle.net/BlackLabel/o0w1v83e/
API Reference: https://api.highcharts.com/highcharts/yAxis
Another way is to overwrite Highcharts clipping behaviour.
(function(H) {
H.SVGElement.prototype.clip = function() {};
H.wrap(H.Series.prototype, 'isPointInside', function(proceed) {
return true;
});
}(Highcharts));
Live demo: http://jsfiddle.net/BlackLabel/otchz6vL/
Docs: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts
Using Highstock, I wish to draw a candlestick chart over a line chart.
I know it sounds weird, but I need to rotate the candlestick chart by 90 degrees clockwise.
The code I have now is:
Highcharts.getJSON('https://cdn.jsdelivr.net/gh/highcharts/highcharts#v7.0.0/samples/data/new-intraday.json', function (data) {
// create the chart
Highcharts.stockChart('container', {
title: {
text: 'AAPL stock price by minute'
},
navigator: {
enabled: false
},
rangeSelector: {
enabled: false
},
series: [{
name: 'AAPL',
type: 'candlestick',
data: data,
tooltip: {
valueDecimals: 2
}
},{
name: 'TEST',
type: 'line',
data: data
}]
});
});
JSFiddle here
What I want to get is the following (something like...):
Any (simple) idea?
Highstock is not adapted to this kind of customization. The only simple way seems to be creating two overlapping charts - one inverted and one with transparent background, but we have to take into account many limitations, like for example tooltip.
chart: {
inverted: true,
...
}
Live demo: https://jsfiddle.net/BlackLabel/nb1jyaq5/
API Reference: https://api.highcharts.com/highcharts/chart.inverted
I would like to display only the first and the last label on my xAxis. This would give enough of a »frame« for the user. However, I don't succeed in it. I am working with a synchronized chart, which can be found here. Is the second and third »column« of (smaller) graphs, I am targeting at.
I tried to work with »startOnTick« and »endOnTick«, but it won't do it.
xAxis: {
crosshair: true,
events: {
setExtremes: syncExtremes
},
visible: i === 1,
showFirstlabel: true,
showLastlabel: true,
startOnTick: true,
endOnTick: true,
labels: {
step: 500,
format: '{value}'
}
},
What is the correct way to force Highcharts to display only first and last label?
Here is a short fiddle (don't know why the line does not appear; it shows the values with mouseover...).
Thanks for any hints.
You can use the xAxis.labels.formatter callback to show wanted ticks:
Demo: https://jsfiddle.net/BlackLabel/m2Ln8sdg/
xAxis: {
tickAmount: 10,
labels: {
formatter() {
if(this.isFirst || this.isLast) {
return this.value
} else {
return ''
}
}
}
},
API: https://api.highcharts.com/highcharts/xAxis.labels.formatter
If you want to have more control about it (like hide label and tick) you can use the load callback method and proper logic to hide/show ticks:
Demo: https://jsfiddle.net/BlackLabel/fbcdskmv/
chart: {
events: {
load() {
let chart = this;
for (let i in chart.xAxis[0].ticks) {
//hide all
chart.xAxis[0].ticks[i].label.hide()
chart.xAxis[0].ticks[i].mark.hide()
// show first and last tick
if (chart.xAxis[0].ticks[i].isFirst || chart.xAxis[0].ticks[i].isLast) {
chart.xAxis[0].ticks[i].mark.show()
chart.xAxis[0].ticks[i].label.show()
}
}
}
}
API: https://api.highcharts.com/highcharts/chart.events.load
Or use the tickPositioner callback to achieve it: https://api.highcharts.com/highcharts/xAxis.tickPositioner
The above answers are good, but i just wanted to show another approach which works just fine.
In my styling i do this;
.highcharts-xaxis-labels > text:not(:first-child):not(:last-child) {
visibility: hidden !important;
}
Summing up #luftikus143 and #Sebastian Wędzel comments:
const data = [
['Jan 2020', 167],
['Feb 2020', 170],
['Mar 2020', 172]
];
xAxis: {
type: 'category',
tickPositions: [0, data.length - 1]
}
Will output only the first and last labels. #martinethyl's workaround answer might need some extra tweaks specially if you have multiple data points. Suggestions (might not work well with smaller media types):
xAxis: {
type: 'category',
labels: {
rotation: 0,
x: 5, // Optional: moves labels along the x-axis
style: {
textOverflow: 'none', // Removes ellipsis
whiteSpace: 'nowrap', // Gets the label text in one line
},
},
I have got into little trouble with hiding the markers in the navigator
The problem is that after I set marker.enabled to false. It does nothing. (JS fiddle - line 75)
navigator: {
series: {
lineWidth: 0,
marker: {
enabled: false // this should hide markers
}
}
}
It is doing nothing because I have some condition where if the condition is true I need to insert the marker at that point, like this:(JS fiddle - line 63).
Btw.. in that JSfiddle example I'm setting it for every point, but that doesn't matter.
series: [{
data: {
x: ...,
y: ...,
marker: {
enabled: true
}
}
]}
- so when I set it manually on that point, it will override the global navigator options
PROBLEM - The global navigator option for the marker is overriden by every single point.
GOAL - Hide all markers in the navigator.
JSFiddle
OLD SOLUTION
If you have only 1 serie in the graph - take the Wojciech Smiel answer.
If you have more than 1 serie in the graph - you have to first make an array of the series with the disabled marker, and then set the options like this
navigator: {
series: seriesArray // array with the series and disabled marker
}
NEW SOLUTION
My friend recently discovered better and easier solution, each serie has navigatorOptions property where you can set radius for the marker, if you set it to 0 it will be hidden.
serie.navigatorOptions = { marker: { radius: 0 } };
Quoting the Highcharts navigator documentation:
Unless data is explicitly defined on navigator.series, the data is
borrowed from the first series in the chart.
That's why navigator series has markers despite the fact that you disabled it in navigator options. However, you can add separate data for the navigator where you can disable marker for each point. Check the demo posted below.
Code:
function generateData(markers) {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -999; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: Math.round(Math.random() * 100),
marker: {
enabled: markers
}
});
}
return data;
}
// Create the chart
Highcharts.stockChart('container', {
chart: {
events: {
load: function() {
// set up the updating of the chart each second
var chart = this,
series = this.series[0],
seriesNav = this.series[1];
setInterval(function() {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], false);
seriesNav.addPoint([x, y], true, true);
}, 1000);
}
}
},
time: {
useUTC: false
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 0
},
title: {
text: 'Live random data'
},
exporting: {
enabled: false
},
plotOptions: {
series: {
marker: {
enabled: true
}
}
},
series: [{
name: 'Random data',
showInNavigator: true,
data: generateData(true)
}],
navigator: {
series: {
lineWidth: 0,
marker: {
enabled: false
},
data: generateData(false)
}
}
});
Demo:
https://jsfiddle.net/BlackLabel/1um9gs47/21/
so by reading the documents by default when you enable dataLabels on the chart it will render yAxis values, but is it possible to make it render xAxis values?
You can format labels in Highcharts in two ways:
Use dataLabels.formatter where you have access to this (point):
formatter: function () {
return this.x;
}
Demo: http://jsfiddle.net/BlackLabel/t2cek68m/1/
Use dataLabels.format, where you can put simple template:
format: "{x}"
Demo: http://jsfiddle.net/BlackLabel/t2cek68m/
Note:
You can use any property from a point, to show this in a label, both format and formatter can be used:
format: '{point.customValue}'
Or:
formatter: function () {
return this.point.customValue;
}
Where a point is defined as an object:
series: [{
data: [{
x: 10,
y: 15,
customValue: '10x10'
}]
}]
Demo: http://jsfiddle.net/BlackLabel/t2cek68m/3/
Yes it's possible just add this code :
dataLabels: {
enabled: true,
formatter: function() {
return this.x;
}
},
Fiddle