Manipulating MongoDB values for a stock chart - javascript

I currently have a simple line chart that is using a 'value' and 'date' to be generated. This is being pulled straight from my database (mongodb)
{
product: 'title',
value: 123,
date: ISODate("2022-08-25T06:30:12.713Z")
}
I would like to now change this chart to a stock chart but instead of a 'value' and 'date' i'll need an 'open', 'close', 'high' and 'low'.
{
product: 'title',
open: 123,
close: 125,
high: 130,
low: 120
}
What is the best and most performant way for me to approach this?
a) Mass data manipulator/processing on the front end after recieving the data from the api?
b) A huge aggregation query to calculate and group every price, for every hour that has passed since October?
c) Mass database update retrofitting and calculating all of the values and storing them as the fields I need?
d) Something else I've not considered?
Any advice greatly appreciated.

Related

How to create a threshold in Observable Plot in JavaScript / TypeScript

I am trying to create a grouped bar chart using Observable's Plot.plot in JavaScript (code is in TypeScript).
The problem is that the x-axis is showing each specific date, however I want the dates to show dynamic months or weeks, not specific dates.
This is the code:
const chart = Plot.plot({
x: { axis: null, domain: ["Add", "Remove"], },
y: { tickFormat: "s", label: "↑ Access Requests", grid: true },
color: {
legend: true,
type: "categorical",
domain: ["Add", "Remove"],
range: redGreenColorRange,
},
style: {
background: "transparent",
},
width: 1350,
caption: "in 2 week increments",
facet: {
data: groupedAddRemove,
label: "Created Date",
x: "createdDate",
// thresholds: d3.utcWeeks,
// ^ this doesn't work, but a similar structure has worked in other projects I've seen
},
marks: [
Plot.barY(groupedAddRemove, {
x: "type",
y: "count",
fill: "type",
}),
Plot.ruleY([0]),
],
});
and this is what it looks like:
I want the x-axis marks to show a dynamic version of Months, like:
My data structure either could show the "Date" as a string, or a TypeScript typeof Date object
data structure with date with a type of string
data structure with date with a type of Date
This is the data structure type:
The 'groupedAddRemove' is an array of this type
( AddRemoveBarChartType[] )
type AddRemoveBarChartType = {
createdDate: Date;
count: number;
type: "Add" | "Remove";
};
the "Type" can either be "Add" or "Remove". I had a boolean for this value previously, but the "Add" and "Remove" fit better to automatically have the legend say "Add" and "Remove". It could be changed back to a boolean if there is a better way to display it that way.
The data could be changed in other ways too, if that will simplify things. I am also open to using a D3.js implementation instead of Plot.plot.
I'm very new to Observable Plot.plot so any help is appreciated, thank you!

NodeJS calculating difference between timestamps based on specific conditions

Have an interesting problem.
I have a SQL database, 50000+ entries containing data that looks as follows when queried with KnexJS:
[{
id: 65532,
status: 0.00,
timestamp: 1656124205000,
},
{
id: 65533,
status: 49.81,
timestamp: 1656124503000,
},
{
id: 65534,
status: 0.00,
timestamp: 1656124909000,
}
.... 60000+ more entries
]
I'm using Knex as the query builder.
I want be able to find every object where status is 0 and then get the following object where status is not 0 and then calculate the time difference for each occurrence where that happened.
Usually 0.00 won't be consecutive, but there's no guarantee for that, else I would've just grabbed the id/index where status is 0.00 and + 1.
Any suggestions where to get started with this kinda logic?

HighStock: chart gets broken when navigator touches right border

I'm developing an web application that handles and shows large amounts of live data from some devices. To visualise the data I decided to use HighStock. It seems to work well on most of the data:
However, when the bottom navigator touches right border, the picture becomes quite different:
The timeline is almost the same, but the number of points is different, also vertical scale is different... What is this happening? How to fix it?
My code looks this way:
const ch1 = Highcharts.stockChart('chart1', {
rangeSelector: {
selected: 1,
inputEnabled: false,
buttonTheme: {visibility: 'hidden'},
labelStyle: {visibility: 'hidden'},
},
title: {
text: 'Metrics',
},
series: [{
name: 'Sensor 1', data: [],
}, {
name: 'Sensor 2', data: [],
}, {
name: 'Sensor 3', data: [],
}]
});
// a,b,c gets values from the server
// They are arrays of pairs of timestamp & value
ch1.series[0].setData(a);
ch1.series[1].setData(b);
ch1.series[2].setData(c);
// tm_min & tm_max are dynamically calculated using the data
ch1.xAxis[0].setExtremes(tm_min, tm_max);
Update: Here is an example with 2% of my data – try to do the same as shown above.
I found the solution. The issue is caused by your data and xAxis.ordinal that is enabled by default in Highstock. Your data has many empty points on the right side of the chart and because of ordinal, the empty space was not rendered, yet dataGrouping grouped data differently.
Check this here https://jsfiddle.net/BlackLabel/x1tgqbw6/ (disabled ordinal):
xAxis: {
ordinal: true
}
So, the solution is to disable xAxis.ordinal or generate your data without null points:
https://jsfiddle.net/BlackLabel/ex054oy8/
API reference:
https://api.highcharts.com/highstock/xAxis.ordinal

Setting additional point attributes in HighStock time series with large data sets

I know you can pass arbitrary data into your time series points, such as:
new Highcharts.Chart( {
...,
series: [{
name: 'Foo',
data: [ { y : 10.0, customData : 'value 1' },
{ y : 20.0, customData : 'value 2' },
{ y : 30.0, customData : 'value 3' } ]
}]
} );
However, I noticed that this doesn't quite work in HighStock when your time series is comprised of a large data set (1000+ points).
For example, here is a working fiddle http://jsfiddle.net/gparajon/c5fej775/ (less than 1000 points, which also happens to be the default turboThreshold). And here's the same fiddle, with more data, which breaks the tooltip formatter: http://jsfiddle.net/gparajon/5om258az/
Any workaround?
Thanks!
The error in the console is a bug and it is not really connect why you cannot access extra info in the formatter.
The difference between a chart and a stockchart is that a stockchart does data grouping, what means that in the formatter callback you receive grouped points which does not include extra data (how should they be grouped?).
example: https://jsfiddle.net/g04La2qh/1/
If you disable data grouping, you will receive non-grouped points with extra data.
dataGrouping: {
enabled: false
},
example: https://jsfiddle.net/g04La2qh/2/

HighStock Grouping Daily and Monthly with columns

I have a HighStock chart (type column) that contains a value for each day. What I would like to do looks very simple, however I cannot manage to achieve it. I would like my data to appear day by day when we display one month and month by month when we display more than one month. I have 3 buttons for range selector :
buttons: [{
type: 'month',
count: 1,
text: 'Vue par mois'
}, {
type: 'year',
count: 1,
text: 'Annee'
}, {
type: 'all',
text: 'Tout'
}]
I tried to play with de datagrouping options but the problem is that the default value group my data by week instead of month. I tried many solutions but nothing works :
units:
[[
'month',
[1]
],
[
'day',
[1]
]
]
The solution above for example group the data by month, even if we display for one month, resulting in a big column block on the graph.
I feel like I'm missing something but what ? I hope my explanations are understandable. Any help would really be appreciated.
Thanks in advance !
Milene

Categories