nagix / chartjs-plugin-streaming Goto Github PK
View Code? Open in Web Editor NEWChart.js plugin for live streaming data
License: MIT License
Chart.js plugin for live streaming data
License: MIT License
When a pie chart is present on a page including chartjs-plugin-streaming, I got the following errors:
Uncaught TypeError: Cannot read property 'xAxes' of undefined
chartjs-plugin-streaming.min.self-Uncaught TypeError: Cannot read property 'getScaleForId' of null
We have a datastream that at the current time feeds in data from 5 minutes ago. The x axis labels refuse to change. In the examples, they use Date.now(). Using any form of Date object manipulation or moment functions, it is not allowing the offset to occur. See here for methods we have tried: https://stackoverflow.com/questions/674721/how-do-i-subtract-minutes-from-a-date-in-javascript
It moves the data off screen and we would have to have an absurd duration to see it. Instead, we want to adjust the value of the recent time feeding in as shown in the xaxis labels.
In the docs here you can see the following:
Note that the following options are ignored for the 'realtime' scale.
bounds
distribution (always 'linear')
**offset (always false)**
There is no reason why offset should always be false. Let it be default to false, but do not ignore this field. If I specifically set an offset, please use that value.
When using websocket or other forms of data streaming, chart should be refreshed with sampled data periodically. In this case we need two dimensional array (e.g. 2DArray=[{time, A1,A2,A3,...}) and push it to the chart.
It seems chartjs-plugin does not accept array (chart.data.datasets[j].data.push(data[i][j]);)
Your help greatly appreciated for a working example.
Thanks
Here's my use case: I have two charts, one on top of the other, as seen here. Ideally, they'd be two datasets in a single chart, but I couldn't come up with a way to start one chart halfway through the other (especially with the streaming delay). Regardless, both datasets should have the same scale max and min.
I could manually give them the same ticks: { min, max}
on creation, but the range of values in my dataset is too large to set them once at the beginning and leave them. So, I have to let chart.js figure out the scales for me based on the data currently in the chart. But since both lines have slightly different data, the generated scales vary slightly, and you can see them rescale at different times in the gif above.
I've tried setting the parent component's state with the larger chart's chart.scales["y-axis-0"].max
and min
from within the options: plugins: streaming: onRefresh:
function, and then trying to set the other chart's values from that state within its onRefresh
. But the second chart seems to be ignoring the updated values (or the values I'm setting don't actually control the scale).
So, what is the best way to keep scales in sync across multiple charts?
Is there a way to refresh chart periodically when data is coming fast from a client in a lets say Inputmessage() and can save data on a two dimensional array (Data[row][column])?
You provided a great facility for data streaming but the examples are having the same format. Could you please add an multi datasets (time,A1,A2,A3,A4) chart with pause key in the chartjs-plugin-streaming repository. Thank you
The documentation for ttl
says:
If not set, old data will be automatically deleted as it disappears off the chart.
If the chart is paused the old data is not removed. This correct according to the documentation because technically, the data does not disappear off the chart when paused as the chart isn't moving.
However if paused for a long time and there is a lot of new data, and then resuming, the browser can freeze until the old data is removed. This is also bad memory wise.
I expected it to follow the duration
option (+ x
to be sure it is off the chart and doesn't affect interpolation), but appears to be using the scale. The scale is not changing when paused.
I'm not sure what the best solution would be. Either way, checking for old data when paused (without having set ttl
) doesn't do anything useful since scale.left
doesn't change when paused. So currently that's just wasted cpu.
As a workaround I'm currently setting ttl
to duration + 5000
.
ps: awesome plugin btw. great work
Is there a way to preload data to the left of the chart? For example historical data that does not need to be streamed in.
Couldnt find any options to stream the charts from left to right instead of right to left. Is there any way to realize that without doing code changes to the plugin?
I've setup a horizontal bar chart to draw a bar based on data pushed to the graph. When I add the data labels plugin into my chart the line is animated and then disappears with the length of the dataset always being erased. If I remove the data labels plugin from the graph the values will chart correctly, but only until the second data_value is pushed onto the dataset, it skips the first one for some reason (maybe a separate bug).
Library versions:
"chart.js": "^2.7.2",
"chartjs-plugin-datalabels": "^0.4.0",
"chartjs-plugin-streaming": "^1.7.0",
Below is my react component:
<HorizontalBar
ref='chart'
data={{
datasets: [{
label: 'Depth',
backgroundColor: '#305c8a',
borderColor: '#305c8a',
data: []
}]
}}
height={700}
options={{
title: {
display: false
},
maintainAspectRation: false,
tooltips: {
enabled: false
},
legend: {
display: false
},
plugins: {
datalabels: {
display: (ctx) =>{
var val = ctx.dataset.data[ctx.dataIndex];
return val.depth % 5 == 0;
},
anchor: 'end',
align: 'right',
clip: true,
formatter: (value, ctx) => {
return `${Formatter.formatNumber(value.depth)}'`;
}
}
},
scales: {
xAxes: [{
ticks: {
display: false,
min: 0,
max: 2
},
gridLines: {
display: false
}
}],
yAxes: [{
type: 'realtime',
maxBarThickness: 3,
gridLines: {
display: true
},
realtime: {
duration: 300000/*14400000*/,
delay: 1000,
onRefresh: (chart) => {
chart.data.datasets[0].data.push({x: 1, y: Date.now(), depth: 1200});
}
}
}]
}
}}
/>
Hi,
I'm working on streaming chartjs and trying to display the tooltip of the newest updating point. How can i do it without using 'mousehover'
I'm unable to get x axis ticks or labels to render like they do in the tutorial. I copied and pasted from the source of your tutorial and created a jsfiddle to demonstrate the issue.
Hello,
I've been using your plugin for a week and it's awesome. I am currently investigating ways on "pausing" the chart scrolling, stopping all updates to the chart data at the same time. Stopping the Ingress of data is easy, but I can't find a straightforward way to stop the automatic scrolling of the chart so I can peruse a subset of the data without it vanishing on me.
Please advise.
Thanks in advance,
Jordan
Is there a way to show a scroll bar along X-axis (time) so we can still see the old data that have already disappeared off the chart?
I understand current limitation of x axis (only accept time format) but I guess with refreshing delay and colors can make it faster to display 1000 hz sampling rate streaming data.
Please advice.
Thanks
When the number of charts is over around 15, the frame rate goes down 10(7-8) and the screen seems ugly. I've tested out with your samples by adding the same chart over 20 and it also gets too slow. Is there any performance handling workaround other than you specified on README
?
If I modify the streaming example to host 2 charts, the UI jitters horribly.
index.txt
@Input() a
...
this.chartObj = new Chart(this.el.nativeElement.getContext('2d'), {
...
options: {
plugins: {
streaming: {
refresh: 1000, // onRefresh callback will be called every 1s
onRefresh: (chart: Chart) => {
// something
}
}
}
}
});
With the above snippet, I'd like to control the refresh the chart when I get the new input data a
but apparently, the datasets only get updated every 1s.
I've tried using ngOnChanges
cycle, pushing the new data to the datasets and update the chart instance but it didn't seem to work.
this.chartObj.config.data.datasets.push({
// label: 'Dataset ' + config.data.datasets.length,
// backgroundColor: color(newColor).alpha(0.5).rgbString(),
// borderColor: newColor,
fill: false,
lineTension: 0,
data
});
this.chartObj.update();
What am I missing?
how i create blink bar like this
issue.zip
hi , im trying update to new version 1.3 after replace code i have this error
Uncaught TypeError: Cannot read property 'duration' of undefined chartjs-plugin-streaming
chartjs-plugin-streaming : 1.3
Chartjs : 2.7.2
I get the following gulp build error for the streaming plugin:
gulp build
[22:47:25] Using gulpfile ~/node_modules/chartjs-plugin-streaming/gulpfile.js
[22:47:25] Starting 'build'...
options.entry is deprecated, use options.input
events.js:160
throw er; // Unhandled 'error' event
^
Error: Unexpected key 'moduleName' found, expected one of: acorn, amd, banner, cache, context, entry, exports, extend, external, file, footer, format, globals, indent, input, interop, intro, legacy, moduleContext, name, noConflict, onwarn, output, outro, paths, plugins, preferConst, pureExternalModules, sourcemap, sourcemapFile, strict, targets, treeshake, watch
at validateKeys (/home/sboyls/node_modules/chartjs-plugin-streaming/node_modules/rollup/dist/rollup.js:171:11)
at checkInputOptions (/home/sboyls/node_modules/chartjs-plugin-streaming/node_modules/rollup/dist/rollup.js:10154:14)
at Object.rollup (/home/sboyls/node_modules/chartjs-plugin-streaming/node_modules/rollup/dist/rollup.js:10225:3)
at /home/sboyls/node_modules/chartjs-plugin-streaming/node_modules/rollup-stream/index.js:65:19
at process._tickCallback (internal/process/next_tick.js:109:7)
at Module.runMain (module.js:606:11)
at run (bootstrap_node.js:389:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:502:3
Help!
Let's say the I refresh values after every 5 minutes. But sometimes there will be no value. The last point is just pass and not showing on the graph. Say after 20 minutes I have a new value to be added. The issue is not that the new values are linked to the last shown values that were 20 minutes ago. Though it doesn't have to link to that point whose time is passed.
Here is my code:
import { Component, OnInit } from '@angular/core';
import 'chartjs-plugin-streaming';
import { ActivatedRoute } from '../../../node_modules/@angular/router';
@Component({
selector: 'app-resource-monitor',
templateUrl: './resource-monitor.component.html',
styleUrls: ['./resource-monitor.component.css']
})
export class ResourceMonitorComponent implements OnInit {
datasets: any[] = [{
data: [],
label: 'line1'
}, {
data: [],
label: 'line2'
}];
options: any = {
scales: {
xAxes: [{
type: 'realtime'
}]
},
plugins: {
streaming: {
onRefresh: function (chart: any) {
chart.data.datasets.forEach(function (dataset: any) {
dataset.data.push({
x: Date.now(),
y: Math.random()
});
});
},
duration: 20000, // data in the past 20000 ms will be displayed
refresh: 1000, // onRefresh callback will be called every 1000 ms
delay: 1000, // delay of 1000 ms, so upcoming values are known before plotting a line
frameRate: 30, // chart is drawn 30 times every second
pause: false, // chart is not paused
}
},
animation: {
duration: 0 // general animation time
},
hover: {
animationDuration: 0 // duration of animations when hovering an item
},
};
constructor(private route: ActivatedRoute) { }
ngOnInit(): void {
this.route.params.subscribe(params => {
const id = params['id'];
});
}
pause() {
this.options.plugins.streaming.pause = !this.options.plugins.streaming.pause;
}
}
I want to start/pause the chart.
It seems like I need to update the chart after setting this.options.plugins.streaming.pause as true.
So I wonder if there is any way to obtain the chart object and call chart.update().
Thanks a lot!!!
My chart data refreshes every 3 seconds. I've set the X-axis stepSize to 20 so I have a 20-second interval between ticks. But the resulting chart shows big gaps between these ticks. Is there a way to "squeeze" them so the intervals are close to each other?
JSFiddle: https://jsfiddle.net/xbqthaoL/5/
It could be nice if you were able to set a different time zone then one the client is currently in.
Any hints on how to make this possible?
Hi, (sorry for my english)
i use chartjs-plugin-streaming for the real time chartjs and i want to use the chartjs-plugin-zoom.
But when i try to zoom, nothing happens.
I see that the 'doZoom' method of 'chartjs-plugin-zoom' is called, but when it called 'update method nothing happens.
I tested to call pause of the streaming before to do the zoom but there is the same problem...
What can I do to make the zoom work?
Thank for now...
Hello, I'd like to report a bug, But maybe it's a feature and designed behaviour,
After dynamic changing duration from bigger to smaller and to bigger again some points in the beggining of chart dissapears,
It can be repriduced on samle with interactions - https://nagix.github.io/chartjs-plugin-streaming/samples/interactions.html
Steps:
Actual:
Points that appeared between max and min duration change are lost.
Expected:
All points are preserved.
If you need any help from my side to fix this, please let me know.
The graphs produced by this plugin are very beautiful, but they use a lot of cpu, are there any, or could there be any configurable perf options; perhaps make the animation less fluid at the cost of cpu cycles?
In my case I have a slow stream that updates every 5 seconds which i've specified with the delay
property. The problem with this is that the data will be fetched after 5 seconds so my users have to wait 5 seconds before they can read the chart. The data is available right away, so is there an option that I can start immediately instead of waiting 5 seconds or preloading that data somehow?
I could draw streaming ChartJs with integer but I need like ChartJs draw float numbers for X and Y axes.
I'm currently using this plugin to display data I'm polling from a server through ajax.
The asynch ajax method pushes data to an array, and the onRefresh method of the plugin pops it from the array and renders the point.
My problem is that when I minimize the tab, the onRefresh method stops firing (also observable on your demo web-page).
My question (or perhaps feature request) is for the onRefresh method to be called even when the page is minimised.
Can you also recommend a better pattern for using your chart to load datapoints polled from a server through ajax?
core.js:1598 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'removeEventListener' of null
TypeError: Cannot read property 'removeEventListener' of null
at Object.destroy (chartjs-plugin-streaming.js:874)
at Object.notify (core.plugins.js:109)
at Chart.destroy (core.controller.js:767)
at BaseChartDirective.push../node_modules/ng2-charts/charts/charts.js.BaseChartDirective.ngOnDestroy (charts.js:51)
at callProviderLifecycles (core.js:10420)
at callElementProvidersLifecycles (core.js:10388)
at callLifecycleHooksChildrenFirst (core.js:10378)
at destroyView (core.js:11442)
at callViewAction (core.js:11568)
at execComponentViewsAction (core.js:11490)
at Object.destroy (chartjs-plugin-streaming.js:874)
at Object.notify (core.plugins.js:109)
at Chart.destroy (core.controller.js:767)
at BaseChartDirective.push../node_modules/ng2-charts/charts/charts.js.BaseChartDirective.ngOnDestroy (charts.js:51)
at callProviderLifecycles (core.js:10420)
at callElementProvidersLifecycles (core.js:10388)
at callLifecycleHooksChildrenFirst (core.js:10378)
at destroyView (core.js:11442)
at callViewAction (core.js:11568)
at execComponentViewsAction (core.js:11490)
at resolvePromise (zone.js:814)
at resolvePromise (zone.js:771)
at zone.js:873
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
at Object.onInvokeTask (core.js:4053)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
at drainMicroTaskQueue (zone.js:595)
at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:500)
at invokeTask (zone.js:1540)
It works fine in the chart view. The error occurs when I leave the chart view.
Hi,
I'm having some issues placing both a chart of x-axis type 'time' along with a realtime chart.
It seems like the 'time' chart is being overruled by the realtime x-axis even if the x-axis is set to 'time', making both charts realtime charts.
Is there something that I may be missing?
Thanks again for a great chartjs plugin!
Hi, your plugin is very neat and useful. Thanks for the effort!
As I'm trying to create a real time data control chart. I'm using your plugin for streaming data and annotation plugin to draw UCL & LCL (Upper Control Limit & Lower Control Limit) lines. The problem is that when the chart is moved to the left, the annotation lines, which must be static, are moved as well. Screenshot attached below.
Is it possible to make the annotation lines static just like the axises? Thanks in advance!
I'd like to pause the chart on certain input bindings. How do I trigger the pause?
I'd like to reset the max ticks of yAxes dynamically when based on the realtime data. I tried implementing it as following:
// Angular 5+
// When the new data arrives,
// data: number[]
this.chartObj.config.options.scales.yAxes[0].ticks.max = Math.max(...data) >= 5 ? undefined : 5; // 5: default Y max value
But if the new data's max value is 3, for example, the max Y sets as 5 and if the previous max value is 8 and the data is still drawn on the chart, the result is not right. So my question is, how can I figure out the max data on the chart area so that I could set the max Y accordingly?
Many thanks!
Hi, I want to know if there is a way to stream past data. Here are the details:
I receive a past data array which is gathered in the backend from date1 to date1. (Both date1 and date2 are past dates)
I want to stream the data array from the beginning to the end.
Thanks a lot!
How i do to blink( for highlight ) some bar in the bar chart.
It looks like the ttl option is not available in npm yet. Will you be able to release it pretty soon?
Thank you!
I'm running into issues with the React lifecycle, where the chart instance is being destroyed and recreated, leaving the exisitng afterInit() plugin timer hanging around. Multiple timers get spun up because of this.
I recommend to cancel that timer in the destroy() plugin hook as a best practice.
afterInit: function(chart, options) {
refreshTimerId = setInterval(function() {
onRefresh(chart);
}, options.refresh);
},
destroy: function(chart, options) {
clearInterval(refreshTimerId);
},
When Chart.js rescales to fit the data in the chart within the y-axes, it does so rather abruptly (as seen here). Ideally, the transition should be smooth, similar to Smoothie Charts.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.