How to smoothly zoom in and out of the chart using buttons?
Below I gave the code approximation of the graph.
(If this is important: I have Data every second.)
var min = chart.xAxis[0].getExtremes().min,
max = chart.xAxis[0].getExtremes().max;
chart.xAxis[0].setExtremes((min + 12 * 2000),(max - 12 * 2000));
Zoom smoothness depends on the amount of rendered points on the chart. I have noticed that if dataGrouping is disabled and points amount is less than 250 animation works fine.
Demo: https://jsfiddle.net/BlackLabel/hj5Lyda7/
var chart = Highcharts.stockChart('container', {
chart: {
animation: true
},
title: {
text: 'AAPL Stock Price'
},
series: [{
name: 'AAPL',
data: data,
dataGrouping: {
enabled: false
}
}]
});
document.getElementById("btn").addEventListener('click', function() {
var min = chart.xAxis[0].getExtremes().min,
max = chart.xAxis[0].getExtremes().max;
chart.xAxis[0].setExtremes((min + 24 * 3600 * 1000), (max - 24 * 3600 * 1000), true, {
duration: 2000
}); //12 hrs on min and 12hrs on max, summarised it is one day.
})
I am afraid that for more points it is impossible to keep this smoothness and displayed range must be changed by using the rangeSelector feature.
Related
I have created a spline real time chart where I want to show points at regular intervals.
Every point is an event taking place after one minute. However I am having a hard time trying to understand all the moving pieces:
the interval function on the highchart demo I referred updated every 1 second, I have made that 6000.
the dummy updating in the javascript just takes the latest time and appends it, is there supposed to be some delay introduced there?
the dummy initialization data in series has a for loop which again I could not understand. I understand that javascript produces a UNIX timestamp and its millisecond manipulation however the default code (again slightly modified from a highchart demo) runs from -9999 to 0 and multiples by a number.
I want to understand these parts and make sure that every time my x axis 'ticks' towards the right, I have a one minute gap and only one point on the graph.
PS: Please forgive any missing brackets, they might have been missed while posting the question, but I assure you that it isnt a problem.
Here is my code for series:
series: [{
type: 'spline',
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -9999; i <= 0; i += 1) {
data.push([
time + i * 60000,
Math.round(Math.random() * 100) + 10
]);
}
return data;
}())
}]
Here is my code for the chart:
chart: {
events: {
load: function () {
// Set up the updating
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100) + 10
series.addPoint([x, y], true, true);
}, 6000);
}
}
}
As to your questions:
If you want to have 1 minute data interval, you need to use 60000 value (60 * 1000), 6000 milliseconds is 6 seconds.
Current date in the interval function is taking every 6000 milliseconds, which causes gaps in the data every 6000 milliseconds.
That data initialization depends on subtracting multiples of six seconds from the current timestamp:
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -9999; i <= 0; i += 1) {
if (i === -500) {
console.log(time, i, 60000); // 1560941909847 + (-500 * 60000)
console.log(time + i * 60000); // 1560911909847
} else if (i === -499) {
console.log(time, i, 60000); // 1560941909847 + (-499 * 60000)
console.log(time + i * 60000); // 1560911969847
} else if (i === 0) {
console.log(time, i, 60000); // 1560941909847 + (0 * 60000)
console.log(time + i * 60000); // 1560941909847 = actual time
}
data.push([
time + i * 60000,
Math.round(Math.random() * 100) + 10
]);
}
return data;
}())
I have a 3D stacked column chart.
If there is some larger values in the data, the small values will not be shown in the chart.
As you can see in
http://jsfiddle.net/43pv1a2q/6/
series: [{
name: 'John',
data: [500, 3, 4, 7, 2], //If change 500 to 5, all blocks will be shown
stack: 'male'
}, {
name: 'Joe',
data: [300, 4, 4, 2, 5], //change 300 to 3
stack: 'male'
},
{
name: 'Tom',
data: [500, 3, 4, 7, 2], // change 500 to 5
stack: 'male'
}]
The minPointLength works with bar chart, but not with stacked column chart.
https://api.highcharts.com/highcharts/series.columnrange.minPointLength
How do you set a minimum height for the block in a stacked column?
It seems to be a bug. You can report it here: https://github.com/highcharts/highcharts/issues
Workaround:
I update every point using a new value if its original y value is less than 50 (threshold) and save the original value in realValue property. Then I manually compute the cumulative values for every stack in tooltip.pointFormatter so that the viewer sees proper values:
events: {
load: function() {
var chart = this,
minColHeightVal = 50;
chart.series.forEach(function(s) {
s.points.forEach(function(p) {
if (p.y < minColHeightVal) {
p.update({
y: minColHeightVal,
realValue: p.y
}, false);
}
});
});
chart.redraw();
}
}
// (...)
pointFormatter: function() {
var stackSum = 0,
point = this,
chart = point.series.chart;
chart.series.forEach(function(s) {
s.points.forEach(function(p) {
if (p.x === point.x) {
stackSum += p.realValue ? p.realValue : p.y
}
});
});
return '<span style="color:' + this.color + '">\u25CF</span> ' + this.series.name + ': ' + (point.realValue ? point.realValue : point.y) + ' / ' + stackSum;
}
Live demo: http://jsfiddle.net/kkulig/j3toufk9/
The solution might be to set the y-axis to type: logarithmic, like so: http://jsfiddle.net/43pv1a2q/8/
yAxis: {
type: 'logarithmic',
allowDecimals: false,
title: {
text: 'Number of fruits',
skew3d: true
}
},
The only change I've made is to set "type: 'logarithmic' and removed "min: 0". I can't think of any other way to achieve what you're looking for when working with such hugely different numbers.
EDIT: Of course, you can still use "min: X" to set minimum value on the y-axis; I just removed it because it was unnecessary when I wanted minimum to default.
Using jquery UI Slider I just wonder if there is a way to calculate the CSS length(width) of between steps in UI Slider? For example at following code I need to calculate the actual width between step1 (min) and step2 and so on!
$( function() {
$('#slider').slider({
min: 1,
max: 5,
range: "min",
animate:"slow",
value: 0
});
} );
Not sure why you'd need this detail. It can be calculated.
http://api.jqueryui.com/slider/#option-step
step
Type: Number
Default: 1
Determines the size or amount of each interval or step the slider takes between the min and max. The full specified value range of the slider (max - min) should be evenly divisible by the step.
JavaScript
$(function() {
$('#slider').slider({
min: 1,
max: 5,
range: "min",
animate:"slow",
value: 0
});
// Collect full width
var slideWidth = $("#slider").width();
// Collect number of steps in slider
var sliderSteps = $("#slider").slider("option", "step");
var stepWidth = slideWidth / sliderSteps;
console.log("The Slider Width: " + slideWidth + "px, with " + sliderSteps + " steps, and each steps is " + stepWidth + "px wide.");
});
I am using highcharts to graph some datas. I can select two dates and the graph will show the datas between those 2 dates.
I have the following code:
options.xAxis[0] = {
type: 'datetime',
tickInterval: 3600 * 1000, // one hour
tickWidth: 5,
gridLineWidth: '1',
gridLineColor: gridLineColor,
labels: {
align: 'center',
x: -3,
y: 20,
formatter: function() {
return '<b style=\"font-size:120%\">' + Highcharts.dateFormat('%d-%m', this.value) + '<b>' + '<br>' + Highcharts.dateFormat('%l%p', this.value);
}
},
opposite: false
}
My problem is that if I have 1 day, I see all the hours and if I have selected 5 days for example, I see the 5 days on the axis but if I select 3 months, I see all the days within those 3 months. And this is unreadable.
Is it possible to say that you don't want to have more than 10 intervals shown on the axis?
Many thanks,
John.
You have a couple of options:
Set your tickInterval dynamically. Set the interval depending on time frame of your data
use the tickPixlInterval option. This decides on logical tick intervals that fall somewhere close to the pixel value you specify.
http://api.highcharts.com/highcharts#xAxis.tickPixelInterval
I have to make a series as shown in the image.
The Dates and the values are dynamically generating based on the user selection. The Time is in 24 hrs format. Please tell me how can i create the series for this. Also how to put the duration 1 hour for the time value.
Image for Reference:
In your series data you are using data: [Date.UTC(2012, 10, 01, 12,11,10)] you can simply change that to: data: [90 *60 * 1000] //For 90 Minute
Here is the LIVE DEMO
If you want to plot other series for other days then you should add categories in xAxies. for example for showing 3 days:
xAxis: {
categories: ['01/10/2012', '01/11/2012', '01/2/2012']
},
And in series-data use equal number of parameters as you have in your categories for 3 categories:
data: [ 50 *60 * 1000, 100 *60 * 1000, 50 *60 * 1000 ]
See the LIVE DEMO
Use formatter in tooltip to see a correct hour:minutes when you hover the series.
tooltip: {
formatter: function() {
var ms = this.y;
var x = ms / 1000;
var seconds = x % 60;
x = x / 60;
var minutes = x % 60;
x = x / 60;
var hours = parseInt(x % 24);
x = (x / 24);
var days = parseInt(x);
if(days == 0)
{
return '<b>' + this.series.name +'</b> ->' + this.x + '<br/>' + hours +':' + minutes;
} else {
return '<b>' + this.series.name +'</b><br/>' + days + ' Day ' + hours +':' + minutes;
}
}
},
See the LIVE DEMO