Flot: Plot rolling 1 hour chart - javascript

I have this code to plot a chart which is invoked at a 5 second interval. How can I set the X axis to plot for a rolling 1 hour period?
/**
* Plot chart from retrieved quote data.
*/
function plotData() {
for(var i = 0; i < Quotes.length; ++i) {
if(dataSets[i].length == 7) dataSets[i].shift();
var timestamp = new Date().getTime();
dataSets[i].push([timestamp, Quotes[i].unitprice]);
}
var data = [];
for(var i = 0; i < Quotes.length; ++i) {
data.push({label: Quotes[i].stock, data: dataSets[i]});
}
$.plot('#livetrades-chart', data,
{ xaxis: { axisLabel: 'Time', axisLabelUseCanvas: true,
mode: 'time', timeformat: '%d/%m/%Y %H:%M:%S', timezone: TIME_ZONE },
yaxis: { axisLabel: 'Stock Price', axisLabelUseCanvas: true, tickDecimals: 2 }
});
}
Thanks.

The real-time updates example demonstrates rolling data, where each time a new point is added the oldest one is shifted off the array. What you want to do is basically identical, except with a time axis.
Edit: I still don't understand what the question is; your screenshot shows a time axis, and if you have an hour of data in your array (as opposed to the five seconds shown) then it will show an hour on the axis.
I think maybe you're confused about having to configure the x-axis in some way. You don't: if you provide data whose x-values are spaced an hour apart, the axis will fit to match it. The only thing you might need to tweak is the timeformat (see the Time Series section of the docs for more info) option, if you want the ticks to appear with only H:M:S rather than Y/M/D.

So as far as DNS suggests your cuestion is how did you setup the flot to updates also the xaxis.
here is a runing plunkr for that scenario.
http://plnkr.co/edit/TWpWhL?p=preview

Related

Chart.js - consolidating days to month totals along the x (time) axis?

I'm feeding two daily statistics datasets into my chart. As you can see, each element represents the value for a particular day.
"data":[[{"y":"1", "x":"2018-04-01T04:00:00Z"},
{"y":"14", "x":"2018-04-02T04:00:00Z"},
{"y":"5", "x":"2018-04-03T04:00:00Z"},
{"y":"7", "x":"2018-04-04T04:00:00Z"},
...
The x axis is defined as follows:
xAxes: [{
type: 'time',
distribution: 'series',
time: {
unit: 'month'
}
}]
I (naively?) thought that the chart would be rolling up (summing) the day values into the appropriate month buckets but that's not what I got. Instead, I got monthly tick marks along the x-axis but data points are plotted within the chart at daily precision. (See screenshot.)
Before I go ahead and reprocess my dataset to manually roll up days into their respective month buckets, I'd like to hear whether the chart can in fact do this for me but I'm just setting this up wrong, or whether I do in fact need to take care of this summarization myself, before supplying the dataset to the chart for plotting.
Thanks for your advice!
I solved this by doing the rollup myself during the assembly of the underlying dataset which is then supplied to the chart.
var dayDate = new Date($scope.insights.locationMetrics[lm].metricValues[metric].dimensionalValues[dim].timeDimension.timeRange.startTime);
var monthDate = dayDate.getFullYear() + "-" + (dayDate.getMonth() + 1);
var hitCount = {
y: $scope.safeNumber($scope.insights.locationMetrics[lm].metricValues[metric].dimensionalValues[dim].value),
x: monthDate
}
var alreadyRecorded = hits[labelIdx].findIndex(obj => obj.x == hitCount.x)
if (alreadyRecorded > -1) {
hits[labelIdx][alreadyRecorded].y += Number(hitCount.y);
}
else {
hits[labelIdx].push(hitCount);
}
Extract the date from the underlying data source
Extract yyyy-mm from the date
Create the hitCount object
Check if the hitCount object is already in the array
If the object is already in the array then increment the hitCount (y) within the array.
Otherwise, push the object into the array.

Chart.js need to fix x axis number of vales

I am using chart.js JavaScript library for generating charts.
On my Yaxis I have float values and I am updating them after every one second.
On my Xaxis I have time line, actually I am displaying time line as data is updating after every second so no use of Xaxis time.
But my data keeps updating for n number of time and because of that as data increases my chart becomes unreadable and clumsy.
So I want to limit around 100 data points should be displayed at a given point. So every time graph displays <= 100 items at a time, even if I keep adding new data.
How this can be done using chart.js with simple line chart.
The time axis type in ChartJS supports min and max - so you can work out what the oldest value you want displayed it and set its x value as min.
let data = [/* some data */]
data.sort((a, b) => a.x < b.x)
const min = data.length > 100 ? data[99].x : data[data.length - 1].x
var chart = new Chart(ctx, {
type: 'line',
data,
options: {
scales: {
xAxes: [{
time: {
min
}
}]
}
}
})

How to limit chart xAxis date range in HighCharts?

The data series in my HighCharts chart only includes dates from the past few days, but the chart's x-axis and zoom bar show a date range all the way back to 1970.
How can I limit the presented date range so it only goes back as far as the first date present in the series data?
Example
HTML
<div id="chart_container" style="height: 500px></div>
JavaScript
$(function () {
var timestamps = [1481000484000,1481108510000,1481215541000,1481316568000,1481417583000];
var series_raw_data = [100,300,750,400,200];
// prepare data
var points = [[],[]];
for (var i = 0; i < timestamps.length; i++) {
points.push([timestamps[i], series_raw_data[i]]);
}
// create chart
$('#chart_container').highcharts('StockChart', {
series: [{
data: points
}]
});
});
Here's Fiddle1 which shows the behavior.
I also tried setting the xAxis 'min' option to the first timestamp, and setting the axis type to 'datetime', but those didn't help - Fiddle2.
The reason why it happens is your points array.
If fact, after filling, it looks like this:
points = [ [], [], [x, y], [x, y]]
Those two empty arrays create unwanted behaviour.
Fix the initial array and it works
var points = [];
example: https://jsfiddle.net/hbwosk3o/3/

Highstock Series Compare to First Day of Boundary Instead of Previous Day

I am working with the Highstock compare demo:
http://www.highcharts.com/stock/demo/compare
jsFiddle:
http://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/stock/demo/compare/
The associated code of the percent compare is as follows:
plotOptions: {
series: {
compare: 'percent'
}
},
If we set the rangeSelector to 1m (one month), and assuming today is August 15, 2016, then the first entry displayed is Tuesday, July 12. The values are MSFT: 53.21, AAPL: 97.42, and GOOG: 720.64. The Tooltip shows percentage changes of +1.18%, +0.45%, and +0.78%, respectively, over the previous day. But the problem is that the values for the previous day (7/11/2016) are not shown. This is confusing to the user, in my opinion. What I want to do instead is give each of these starting values a percentage change of 0%, so the left-side of the graph always starts at the origin. How do I do this?
UPDATE: I was thinking along the lines of something like this:
events: {
load: function(e) {
set_new_min_y_data_points(e);
}
}
// ...
function set_new_min_y_data_points(e) {
for (var i = 0; i < e.target.series.length; ++i) {
// By setting the first data point to the same
// value as the second data point, we ensure
// that the series starts at the origin.
e.target.series[i].processedYData[0] = e.target.series[i].processedYData[1];
}
}
...but this doesn't work. Even though the values of e.target.series[i].processedYData[0] are changed, the graph looks the same.

Show gap of missing data with Highstock

Using Highstock to chart a sorted time serie: [[timestamp, value], ...]
The datasource is sampled at irregular intervals. As result the distances between two points (in the time axis) varies.
If two adjacent points are separated for more than 5 minutes I want to show a gap in the chart.
Using the gapSize option doesn't work, because it doesn't allows to specify the 'size' of the gap as a function of time.
Showing gaps is already a part of Highstock, I just need a way to specify it as a fixed amount of time (5 minutes). Ideas?
Btw, beside that the plot works great.
Here's a slightly unclean way to "manipulate" gapSize to work so that it's value is the amount of milliseconds required to create a gap.
(function (H) {
// Wrap getSegments to change gapSize functionality to work based on time (milliseconds)
H.wrap(H.Series.prototype, 'getSegments', function (proceed) {
var cPR = this.xAxis.closestPointRange;
this.xAxis.closestPointRange = 1;
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
this.xAxis.closestPointRange = cPR;
});
}(Highcharts));
This utilizes that gapSize is only used within the getSegments function (see source), and it works based on the closestPointRange of the axis. It wraps the getSegments, sets closestPointRange to 1, calls the original method and then resets closestPointRange to its original value.
With the code above you could do gaps for 5 minutes like this:
plotOptions: {
line: {
gapSize: 300000 // 5 minutes in milliseconds
}
}
See this JSFiddle demonstration of how it may work.
Halvor Strand function wrapper did not work for me as long as getSegments is not part of highstock source code anymore to calculate that gap. Anyway, you can find an approximation to solve the problem combining this other topic and the previows answer like this:
(function(H) {
H.wrap(H.Series.prototype, 'gappedPath', function(proceed) {
var gapSize = this.options.gapSize,
xAxis = this.xAxis,
points = this.points.slice(),
i = points.length - 1;
if (gapSize && i > 0) { // #5008
while (i--) {
if (points[i + 1].x - points[i].x > gapSize) { // gapSize redefinition to be the real threshold instead of using this.closestPointRange * gapSize
points.splice( // insert after this one
i + 1,
0, {
isNull: true
}
);
}
}
}
return this.getGraphPath(points);
});
}(Highcharts))
setting gapSize in plotOptions to the desired size (in ms) like Halvor said:
plotOptions: {
line: {
gapSize: 300000 // 5 minutes in milliseconds
}
}
In case anyone comes across this and is spending hours trying to figure out why gapSize is not working like me. Make sure your time series data is sorted, only then will the gaps appear in the graph.
Another issue I ran into was my data series was in this format
[
{x: 1643967900000, y: 72},
{x: 1643967600000, y: 72},
{x: 1643967300000, y: 72}
]
However this does not seem to work with gapSize and needs to be in the format below
[
[1643967900000, 72],
[1643967600000, 91],
[1643967300000, 241]
]

Categories

Resources