this may seem a noob's question but when I try to use setExtremes or showResetZoom on my xAxis, I get this in the console:
Uncaught TypeError: copt.xAxis.setExtremes is not a function
However my xAxis is correctly defined and works perfectly on plenty of other functions. I've copy-pasted code from several jsfiddler examples, but no way...
Here is my code:
Abs_ChartOptions= {
chart: {
zoomType: 'xy',
resetZoomButton: {
position: {
verticalAlign: 'top',
y: -50
},
}
},
title: { text: ''},
xAxis:{
type: 'datetime',
labels: { format: '{value: %d/%m/%Y}'},
tickInterval: 24*36e5, //24h
title:{ text: 'Date'},
crosshair: true,
},
yAxis: [{
title: { text: ''},
alternateGridColor: '#FDFFD5',
crosshair: true
}],
series: []
}
And on call site, after defining the series and the xMin/xMax values(which are correctly set on their way):
copt= clone(Abs_ChartOptions);
copt.xAxis.setExtremes(xMin,xMax);
copt.showResetZoom();
I've tried using directly Abs_ChartOptions instead of a clone, same issue.
NB: Using copt.xAxis.min= xMin; copt.xAxis.max= xMax; works fine for zooming, but I don't get the "reset zoom" buttton.
What did I miss? Is there some extra module needed or whatever ?
Thx in advance
You need to call both methods on a chart instance, not on the options configuration object.
const Abs_ChartOptions = {
...
};
const chart = Highcharts.chart('container', Abs_ChartOptions);
chart.xAxis[0].setExtremes(1, 3);
chart.showResetZoom();
Live demo: http://jsfiddle.net/BlackLabel/e81nj64v/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Chart
Related
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 a page with a variety of select menus. The select options are used in an ajax call to build a Highcharts bar graph. Every time a filter changes, the graph gets recreated. I did this instead of updating the series data, because in the past I have noticed that destroying and recreating was more efficient than updating.
I want images to show on the x-axis, so I used a nice little trick of creating two x axes, used formatter to return an image on the first axis, and linked the second axis to the first. This works on first refresh. However, every time the chart gets recreated thereafter, the image disappears. I checked my console and I don't see any errors.
And idea of what's going on here?
/**
* Whenselection changes
*/
$(document).on('change', '.filter', function(){
getChartData($params)
})
});
/**
* API call to get data that will populate charts.
* #param {obj} params
*/
function getChartData(params)
{
//Get chart data
$.ajax({
url: apiURL + '/chartdata/',
data: params,
dataType: 'json',
cache: false,
success: function(data) {
initChart(data[0]);
}
});
function initChart(chartData)
{
var chart = Highcharts.chart('container', {
chart: {
type: 'bar',
backgroundColor: 'transparent', //#E8EAF6',
height: '23%',
marginLeft: 35
},
title: {
text: null
},
xAxis: {
categories: [category1, category2],
lineColor: 'transparent',
min: 0,
tickColor: 'transparent',
title: {
text: null
},
labels: {
x: -35,
useHTML: true,
overflow: 'allow',
formatter: function () {
if(this.isFirst == true)
return '<img src="../assets/img/nat-jr-grad-gold.png"><br/>';
else
return '<img src="../assets/img/nat-jr-grad-purple.png"><br/>';
}
}
},
yAxis: {
min: 0,
title: {
useHTML: true,
text: null
},
labels: {
enabled: false
},
lineWidth: 0,
minorGridLineWidth: 0,
gridLineWidth: 0,
lineColor: 'transparent',
gridLineColor: 'transparent',
},
legend: {
enabled: false
},
series: [{
name: category1,
data: [{name: category1, y:Math.round(chartData.p_grad_nongap * 100), {y: null}],
}, {
name: category2,
data: [null, {name: category2, y: Math.round(chartData.p_grad_gap * 100)}]
}]
});
}
I reproduced your problem on a simplified example: http://jsfiddle.net/BlackLabel/sm2r684n/
For the first time, the image is loaded asynchronously and the chart does not take it into account when calculating the margins. Every next time the result is different, so you should wait until the picture is loaded:
var img = new Image();
img.onload = function() {
initChart();
}
img.src = "https://www.highcharts.com/samples/graphics/sun.png";
Live demo: http://jsfiddle.net/BlackLabel/m09ok2cg/
I think ppotaczek had the cortrect root cause of the problem; the image is loaded asynchronously and the chart does not take it into account when calculating the margins. His suggestion used setTimeout function to continuously redraw the graph, which is rather inefficient. My work-around for this was to just add the images as avg elements using chart.renderer after the chart was created.
/* Render X-Axis images */
chart.renderer.image('../assets/img/img1.png', 0, 40, 32, 36)
.css({
class: 'icon-img',
zIndex: 10
})
.add();
chart.renderer.image('../assets/img/img2.png', 0, 130, 32, 36)
.css({
class: 'icon-img',
zIndex: 10
})
.add();
I haven't been able to get my map to show any data; it just renders blank and in the console there's an error of "Uncaught TypeError: Cannot read property 'length' of undefined". I believe that the versions of Highstock and Highmaps that I use are compatible so I don't think that's the issue, however I could be wrong.
Click here for the fiddle
JS (geo_data is being fetched with AJAX)
$('#map').highcharts('Map', {
title: {
text: 'Installs Map'
},
colorAxis: {
min: 0
},
series: [{
data: geo_data,
mapData: Highcharts.maps['custom/world'],
joinBy: ['hc-key', 'country_id'],
name: 'Installs',
states: {
hover: {
color: '#BADA55'
}
}
}],
credits: {
enabled: false
}
});
Use the newest highstock master branch.
<script src="http://github.highcharts.com/highstock.js"></script>
http://jsfiddle.net/4a79s3qp/2/
http://jsfiddle.net/wtftc/cGbUh/
$(function () {
$('#container').highcharts({
chart: {
plotBorderWidth: 1
},
xAxis: {
},
yAxis: [{
startOnTick: true,
endOnTick: true,
}, {
opposite: true,
title: {
text: null,
}
}],
title: {
text: '',
},
series: [{
data: [-67900.92, 454001.7, -204238.28, 322154.52, 162814.29, 940881.87, 454987.58, -190981.9, 77289.43, -578758.66, 232812.59, -553224.3, -161440.06, 203872.86, -487226.65, 582178.18, 88564.43, 250057.57, -62186.0600000001, 377721.25, -196420.64, 38713.0099999999, 284969.83, 166221.67],
}]
});
// the button action
$('#button').click(function() {
var chart = $('#container').highcharts();
var yAxis = chart.yAxis[0];
yAxis.options.startOnTick = false;
yAxis.options.endOnTick = false;
chart.yAxis[0].setExtremes(-1034970.057, 1034970.057);
});
});
I created a jsfiddle example of what I am trying to do. I load up a chart with the data in the example, then I want to set custom values for my axis. The extremes I am setting are -1034970.057, 1034970.057 because I want my y axis values to be symmetric.
However, what I end up with in the chart is yAxis extremes of -1.5m and +3m rather than -1.5m and +1.5m. I am asking it to be symmetric, but after you push the set extremes button, you can see that it is not symmetric.
My data is dynamic and changes based on the settings on the page they are looking at, so this data is just an example of one of the many scenarios that I can encounter. This means that I can't hard code a tick interval or tick count. Is there a way to have this be symmetric?
I got it working by setting the start/endOnTick setting to false in the chart and then to true on click.
http://jsfiddle.net/uNvvk/
yAxis: [{
startOnTick: false,
endOnTick: false,
}, {
yAxis.options.startOnTick = true;
yAxis.options.endOnTick = true;
I've no idea why that works though!
I found out a problem with chart (highcharts 2.3.5) when i enter datetime series with only 1 data entry, it renders it with incorrect placement on x-axis and wrong point formatting.
here is the example: http://jsfiddle.net/LAcSw/
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container'
},
xAxis: {
type: 'datetime'
},
series: [{
data: [
[Date.UTC(2010, 0, 1), 29.9]
]
}]
});
});
Is there a fix know or something(it was fine on 2.2.5)?
Since you only have a single point HighCharts is making its best guess as to the yAxis range as well as what the label is on the point for the xAxis.
You are not defining any sort of formatting for the xAxis datetime labels - and HighCharts only has one point to work with so it defaults to time. If you assign a formatter for the xAxis labels you can get it to do what you want.
Here is some rough code to show you what this does:
xAxis: {
type: 'datetime',
labels: {
formatter: function() {
return Highcharts.dateFormat('%d %b %Y', this.value);
}
}
},
yAxis: {
min: 0,
max:50
},
And here is your jsFiddle updated.