When looking at the Highstock documentation, it says there is a softMin and softMax for the xAxis, but if i leverage dates, it doesnt seem to properly represent the date ranges requested.
I have been needing to do the following: find the interval of the xAxis data, then padd the front/end of the array with null data at those timepoints to properly convey the info.
This works, but I figured HighStock's soft values should be able to handle this.
In a sample use case: you can set the following:
{
chart: {
type: this.type || 'line',
},
title: {
text: this.title || ''
},
credits: {
enabled: false
},
rangeSelector: {
inputEnabled: false, // Specific to the Date Range Picker.
enabled: false // Specific to the Quick Selects for YTD, 6 mo, zoom.
},
navigator: {
adaptToUpdatedData: true
},
scrollbar: {
enabled: false
},
legend: {
enabled: true
},
xAxis: {
min: undefined,
max: undefined,
softMin: undefined,
softMax: undefined,
type: 'datetime',
dateTimeLabelFormats: {
day: '%b %e'
}
},
// yAxis: {
// title: { text: ''}, opposite: true, type: 'linear'
// },
plotOptions: {
series: {
dataGrouping: {
approximation: 'sum',
groupPixelWidth: 25,
forced: true,
units: [
['minute', [30]],
['day', [1, 7, 15]],
['month', [1, 3, 6]]
]
}
}
},
series: []
}
So I look at the dates as if they are numbers, new Date().getTime() but if i want to set the softMin and softMax, I wanted to do something like:
xAxis: {
softMin: new Date().getTime() - 1000 * 3600 * 24 * days_back
softMax: new Date().getTime()
}
where days_back is a user defined variable for how many days previously to look.
The way i pad out the series info is as follows:
const endtime = new Date().getTime(); //The current definition of endtime is now as there is no data for the future.
const starttime = endtime - 1000 * 3600 * 24 * days;
opts.series = dataset.map((item, idx, arr) => {
const name: string = item.name || '';
const data: any[] = item.data || []; // data is a list of lists. ][time_as_number, value],...]
if (data.length > 1) {
/// The purpose of this code block is to padd out the dataset to the start and end ranges.
/// While there is a softMin and softMax, it doesnt work too when with regards to dates.
/// This will padd the data to be represenative of the users base selection.
/// If the list of data has 0 or 1 points, there is not enough data to define an interval for the target range.
const difference = data[1][0] - data[0][0];
let low = data[1][0];
while (low > starttime) {
low -= difference;
data.unshift([low, null]);
}
let high = data[data.length - 1][0];
while (high < endtime) {
high += difference;
data.push([high, null]);
}
}
return {
marker: { enabled: true },
showInNavigator: true,
type: 'line',
name,
data
};
});
Is there something I am missing which i should be taking into account? min/max/minRange/maxRange according to the docs are not the correct keys i wanted to assign to.
For ease of understanding, HighStock Documentation is located here: https://api.highcharts.com/highstock/xAxis.softMin
Here is a sample: https://jsfiddle.net/sp18efkb/
You will see in this sample i set the softMin but it is not reflected. If i use a chart object though, it works. It seems that while it is valid according to the API, is not a valid or monitored property.
When looking at HighStock charts, there is an additional variable which needs to be set if you are looking at this.
In the xAxis you need to set the property ordinal property to false. In order to get the navigator to function in the same way, you need to use that property, set the softmin and soft max as the same, and also turn off ordinal.
It would look something like this:
...
navigator: {
adaptToUpdatedData: true,
xAxis: {
ordinal: false,
min: undefined,
max: undefined,
softMin: new Date().getTime() - 1000 * 3600 * 24 * 5,
softMax: undefined
}
},
xAxis: {
ordinal: false,
min: undefined,
max: undefined,
softMin: new Date().getTime() - 1000 * 3600 * 24 * 5,
softMax: undefined,
type: 'datetime',
dateTimeLabelFormats: {
day: '%b %e'
}
},
...
Related
I have a chart with two yAxis. And I want both to be grouped by date. But in my chart the last value of both series are ending up in differnt xAxis line. I assume this is because of the time differences. I need to group these points based on the date so that the last points of both series will align in the same line of xAxis. This is my javascript code.
Highcharts.stockChart('container', {
yAxis: [{
title: {
text: 'y axis 1',
},
opposite: false,
showEmpty: false,
},
{
title: {
text: 'y axis 2',
},
opposite: true,
showEmpty: false,
},
],
series: [{
yAxis: 0,
data: series1,
},
{
yAxis: 1,
data: series2,
},
],
});
And this is my jsfiddle. Can anyone please help me?
You can loop through your data and round timestamps to the nearest date:
function roundDate(timeStamp) {
timeStamp -= timeStamp % (24 * 60 * 60 * 1000); //subtract amount of time since midnight
return new Date(timeStamp).getTime();
}
function loopThroughData(data) {
data.forEach(function(el) {
el[0] = roundDate(el[0])
});
}
loopThroughData(series1);
loopThroughData(series2);
Live demo: https://jsfiddle.net/BlackLabel/zhbt4gmw/
Useful thread: Round a timestamp to the nearest date
I'm not able to set the xAxis min and max without screwing with the data. I tried using plotOptions and setting pointStart: Date.UTC(2016, 3, 1) but doing that screws with the data. The series ends up on the far right and doesn't load properly.
Is it possible to set a min and a max and make the data obey whatever is set? It loads properly when I don't set min and max. I need it to start in April 2016 and end on April 2018 with a tick every month.
Fiddle: https://jsfiddle.net/omaraziz/h5jsk7a3/5/
Here is an almost working version that just needs the xAxis dates and the tick (data is not exactly the same, but the same exact setting of the json:
The data is coming from a JSON file (data.json):
{
"(1)": [1,2,3,4,5],
"(2)": [6,7,8,9,0]
"(3)": [1,4,7,2,0]
}
Setting the options:
var myChart = function() drawChart() {
$("#container").highcharts("StockChart", {
rangeSelector: {
enabled: false
},
xAxis: {
type: 'datetime',
tickInterval: (24 * 3600 * 1000) * 30, // every month
min: Date.UTC(2016, 3, 1),
max: Date.UTC(2018, 3, 4)
},
series: processedData, // from the data loaded below
});
};
Loading JSON:
processedData = [];
$(function () {
$getJSON("data.json", function(data) {
for(let value in data) {
if(data.hasOwnProperty(value)) {
processedData.push({
name: value,
data: data[value],
})
}
myChart(); // after the data has loaded
});
});
If Your are recording your data at each hour, I hope your problem would be solved by using these two lines of code:
pointStart:Date.UTC(2016, 3, 1),
pointInterval: 3600 * 1000
Here is example:
var myChart = function drawChart() {
$("#container").highcharts("StockChart", {
rangeSelector: {
enabled: false,
},
xAxis: {
type: 'datetime',
ordinal: false,
min: Date.UTC(2016, 3, 1),
max: Date.UTC(2018, 3, 4)
},
plotOptions:{
series:{
pointStart:Date.UTC(2016, 3, 1),
pointInterval: 3600 * 1000
}
},
series: processedData,
});
};
const processedData = [];
$(function () {
$.getJSON("https://omaraziz.me/CC-chart/new-activity.json", function (data) {
for(let value in data) {
if(data.hasOwnProperty(value)) {
processedData.push({
//pointStart: Date.UTC(2016, 3, 1),
name: value,
data: data[value],
})
}
}
myChart();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/stock/highstock.src.js"></script>
<div id="container"></div>
I am trying to plot a line graph, using timestamps from the past 24 hours (plotting data for each 1 hour interval), to show a decreasing and increasing value in flot. When I set my minTickSize, min, and max values, the line no longer plots.
Complete code (also in this fiddle):
$(function () {
var d = [
[1443903422000, 4994],
[1443903429000, 4993],
[1443910918000, 4999]
];
var epochT = (new Date).getTime(); // time right now in js epoch
$.plot("#placeholder", [d], {
xaxis: {
mode: "time",
timeformat: "%I:%M",
minTickSize: [1, "hour"],
min: epochT - 2 * 86400000,
max: epochT,
timezone: "browser",
},
series: {
lines: {
show: true
},
points: {
show: true
},
},
grid: {
hoverable: true,
clickable: true,
},
});
});
Can anyone point me in the right direction to resolving this?
Yout timestamps are in seconds not microseconds like JavaScript needs it (see here in the documentation). Multiplying by thousand (and shifting the min value because it already cuts off the chart) leads to this updated fiddle version.
Changes to your code:
var d = [[1443903422000,4994], [1443903429000,4993], [1443910918000,4999]];
min: epochT - 2*86400000,
I have large collection of data in the format [1421065200000, 1.72], where the first parameter is time in milliseconds and the second parameter is the value at that specific time. I have data array consisting of such data in large size. Now I want scrollable graph containing plot of such time and value data. Here is my javascript implementation to do so,
var dataArray; //This contains my data array i.e. ([[t1, v1],[t2, v2],...])
var minDate = dataArray[0][0];
var maxDate = dataArray[dataArray.length - 1][0];
var chartOption = {
chart: {
type: graphType,
renderTo: 'graph-container',
zoomType: 'x',
useUTC: false
},
title: {
text: 'Data from last 24 hours'
},
credits : {
enabled: false
},
xAxis: {
title: {
text: null
},
type: 'datetime',
dateTimeLabelFormats: {
second: '%Y-%m-%d<br/>%H:%M:%S',
minute: '%Y-%m-%d<br/>%H:%M',
hour: '%Y-%m-%d<br/>%H:%M',
day: '%Y<br/>%m-%d',
week: '%Y<br/>%m-%d',
month: '%Y-%m',
year: '%Y'
},
allowDecimals: false,
ordinal: false,
min: minDate,
max: maxDate
},
yAxis: {
title: {
text: null
}
},
plotOptions: {
series: {
pointStart: minDate,
pointInterval: 5 * 60 *1000
}
},
series: [{
name: parameterName,
data: dataArray
}],
exporting: {
enabled: false
}
};
parameterChart = new Highcharts.Chart(chartOption);
}
The chart shows incorrect data, the time value on x-axis doesn't match the value at y-axis. What is the most correct and efficient to show such time series. Should I use Highcharts or Highstock. Please guide me through this, with suggestion or maybe with solution.
What I did was, I used HighStock instead of HighCharts (since I needed scrollbar along x-axis for large collection of data). I was passing the date in my local time zone format, whereas the chart was using UTC. So, I disabled the use of UTC (alternative: I could have provided data in UTC and drawn the graph using the same, In my case I needed my local labels). I gave the minimum and maximum range to the x-axis through x-axis min and max configuration. Here is the sample of my code,
//dataArray contains the array of data [[x1, y1], [x2, y2], ...]
//x is Date, y is temperature value (say)
var minDate = dataArray[0][0];
var maxDate = dataArray[dataArray.length - 1][0];
//Disable use of UTC
Highcharts.setOptions({
global: {
useUTC: false
}
});
//Create graph options
var chartOption = {
chart: {
type: graphType, //line, bar, column, etc
renderTo: 'graph-container', //div where my graph will be drawn
zoomType: 'x' //Making x-axis zoomable/scrollable
},
title: {
text: 'Data from last 6 hours'
},
subtitle: {
text: document.ontouchstart === undefined ?
'Click and drag in the plot area to zoom in' :
'Pinch the chart to zoom in'
},
xAxis: {
title: {
text: null
},
type: 'datetime', //For time series, x-axis labels will be time
labels: {
//You can format the label according to your need
format: '{value:%H:%m}'
},
min: minDate,
max: maxDate,
minPadding: 0.05,
maxPadding: 0.05
},
yAxis: {
title: {
text: null
}
},
scrollbar: {
enabled: true
},
series: [{
name: "Temperature", //Name of the series
data: dataArray
}],
exporting: {
enabled: false
},
credits : {
enabled: false
}
};
//Finally create the graph
var myChart = new Highcharts.Chart(chartOption);
I've been working on this for hours and couldnt figure it out, I'd appreciate if anyone could help.
$(function() {
$(document).ready(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
var chart;
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
marginRight: 10,
events: {
load: function() {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function() {
var x = (new Date()).getTime(),
// current time
y = Math.random();
series.addPoint([x, y], true, true);
}, 1000);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime' ,
tickPixelInterval: 150
},
yAxis: {
max: 400,
min: 0,
plotLines: [{
value: 200,
width: 1,
color: '#ccc',
}]
},
tooltip: {
enabled: false
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <=0; i++) {
data.push({
x: time + i * 1000,
y: time + 4 * 50
});
}
return data;
})()}]
});
});
});
Here's what I'm trying to do:
Instead of current time on the xAxis, I like to start from 00:00 and run 5 seconds increments.
I would also like to have the Y value to have random numbers, not sure why it is not working
Last, I would like to get value from another element, and draw a horizontal line on the graph accordingly.
Thanks for looking...
1 - Keep a running counter of the seconds (i) and use setHours() to set the hours,minutes,seconds and milliseconds...the only one you'll really care about is seconds though.
var i = 0;
setInterval(function() {
var x = (new Date((new Date()).setHours(0,0,i,0)).getTime()),
y = Math.random()*400;
series.addPoint([x, y], true, true);
i++;
}, 1000);
2 - Multiply your Math.random() by something (like your max y value).
Math.random():
Returns a floating-point, pseudo-random number in the range [0, 1)
that is, from 0 (inclusive) up to but not including 1 (exclusive),
which you can then scale to your desired range.
3 - Slightly unclear on what you're looking for, would you mind specifying?
EXAMPLE