My scenario:
A machine creates events ON, RELOAD, OFF on certain time instances.
It also sends sensor Heat data every hour, that may or may not be at time instances of events.
See sample data below.
events [10.30AM, 4.45PM, 6.15PM, 8PM]
Heat Data [11Am, 12PM,........., 7PM]
As you can see data points falls in different time ranges. Therefore, If I use example below, heat data will be totally miss aligned.
https://www.chartjs.org/samples/latest/scales/time/line-point-data.html
Is there a way to plot these two datasets accurately?
Simply define your data as points through an array of objects that have an x and an y property each.
data: [{
x: new Date(),
y: 1
}, {
t: new Date(),
y: 10
}]
Make sure to not define data.labels in this case.
Related
In my application, I can view multiple charts at the same time. Those charts can be either displayed seperated or overlayed. Overlayed means, that those charts all are in the same chart-div, like this:
The problem is: if i want to add the data, i need to build an array out of all those datapoints, looking like this:
let data=[
{
date:...,
data1:...,
data2:...,
.....
},
{
....
}
]
But when i load it from the server, I have seperate data arrays which i have to merge. That means, I have to look at every single datapoint and create a new one in the "merged-array" if there is no datapoint at the given date.
Doing this with thousands of datapoints uses way too much resources. My question is: is it possible to supply multiple data arrays instead of only 1?
Using series.data instead of chart.data solved the problem for me!
I have too many points on x-axis in my chart. I would like to limit maximum of displayed points to 100. But at the same time still displaying same chart. Exactly same chart - but with fewer points.
screenshot of my chart with too many points
I have no idea how to do it in PHP at server side so I was thinking if there is any solution on client side in chart.js?
It's your responsibility to give chart.js the points it should display. You have to limit the arrays with the labels and the data to 100 datapoints. Use every second data or so. Just do it in plain JavaScript. There's no function in chart.js for that.
For large datasets, chart.js does offer a data decimation plugin that automatically decimates data at the start of the chart lifecycle, reducing the number of data points drawn.
According to chart.js docs, to use the decimation plugin, the following requirements must be met:
The dataset must have an indexAxis of 'x' The dataset must be a line
The X axis for the dataset must be either a 'linear' or 'time' type axis
Data must not need parsing, i.e. parsing must be false
The dataset object must be mutable. The plugin stores the original data
as dataset._data and then defines a new data property on the dataset.
Your chart options should look something like this:
options: {
parsing: false,
plugins: {
decimation: {
enabled: false,
algorithm: 'min-max',
},
},
scales: {
x: {
type: 'time',
ticks: {
source: 'auto',
autoSkip: true,
}
}
}
Remember also that if you disable parsing the data you pass should be in the right format for the type of chart you chose, so epoch timestamps in this case. More info here.
Finally, you can find a working example here.
I'd like to draw a line chart with data for a year. Total number of points will be about 264 pieces.
I'd like to organize labels on x-axis not for every point. Say, in a month I have about 22 points, and I'd like to have 3 labels per month.
Could you help me: what is the most elegant way to do that?
Use an array that stores all values you have (if you want to update your chart, display other values or to reduce AJAX calls). Then use another array with the data you want to display. You need an appropriate function to copy and filter your old array.
Here I use every fifth element:
let delta = 5
let displayedData = []
for (let i = 0; i < allData.length; i=i+delta) {
displayedData.push(allData[i]);
}
You can calculate the delta in a different way or use a completely different approach to get your data.
Side note: don't use .filter(), you don't want to lop through all your data. Use a direct access like I did above.
Currently working on a chart that displays upwards ~1000 datapoints at any given moment between 2-3 datasets.
The only thing is that each of the points has a different timestamp (x-value).
Our goal is that upon hovering on one data point, it also brings the closest data point from the other datasets as well. We were able to achieve that with:
options={{
tooltips: {
mode: 'x'
}
}}
I understand that there is a default pointHitRadius and that seems to be the reason why multiple values of the same dataset are appearing in the same tooltip.
I made a simple test case: TEST
I increased the pointBorderRadius and it seems to include 1-5 points at a time.
Is there a way to only include data from each dataset ONCE?
The closest thing I found (before having to extend functionality), is that there is a filter function available.
However, from what I can see, it looks like it only returns one instance from each dataset. Which wouldn't be too helpful.
Anyone run into this issue?
I am new to working with Data.
So I have a lot of data based on time.
Data row for every 15 mins. Should I compute the data and store data for every 1 hour, 1 day, 1 month on the database?
if I do would this schema be good.
{
_id: "joe",
name: "Joe Bookreader",
time min: [
{
time: "1",
steps: "10"
},
{
time: "2",
steps: "4"
}
]
time day: [
{
time: "1",
steps: "30"
},
{
time: "2",
steps: "30"
}
]
}
If you have any advice on how I can improve my data modeling knowledge with document databases, I would be really grateful.
For a minute step away from programmatic approach to the problem and think about the task at hand.
How are you going to use that data after you stored it? When you use the data it is important for you to know exactly number of steps for a particular user or you want to see a big picture based on the time particular sample points in time.
If you care for per user perspective then your scheme above will work. On the other hand if you want to run global reports like how far along users were on average (or total) during certain time,then I would opt in for schema where your document is time (point in time or range in time), while user and steps are your properties.
Another important concept in database is not to statically store data that can be calculated on the fly. As with any rules there are some exceptions to this. Like Cached values that are short lived and will not have major effect on your application if they are incorrect. Another one is reports, you produced a report for the user based on current values and stored it. If user feels like getting fresh data, user will re-run the report. (I am sure there are few other)
But in most cases the risk that comes with serving stale/wrong data resulting in wrong decision based on that data will outweigh performance benefit of avoiding extra calculations.
The reason I am mentioning this, is because you are storing time min and time day. If time day can be calculated based on time min you should not store it in the database, but rather calculate it on the fly. You can write queries that will produce actual result of time day without using any extra computational power on your application node. All computations will be done on the data node, much more efficiently than a compute node and without network penalties.
I realize this post is a bit old, but I hope my answer will help someone.