How to create a pie chart that allows time range selection? - grafana

I have a JSON file that contains data like below:
[
{
"Time": "Jan 1 2023",
"Equipment": "TV",
"Usage": 10
},
{
"Time": "Jan 1 2023",
"Equipment": "Laptop",
"Usage": 20
},
{
"Time": "Jan 2 2023",
"Name": "TV",
"Usage": 30
}
]
It means: on Jan 1 2023, I used TV for 10$ and Laptop for 10$; on Jan 2 2023, I used TV for 30$.
I already created a pie chart for total usage of 2 days like below
Now I want the option for viewers to view data only during a specific time range, e.g. when they select time range Jan 2 2023 - Jan 3 2023, the chart should look like this
I want to stick with the JSON file as data source if at all possible (the file is fully customizable). If not, please suggest anything that works.
I'm actually not sure if it's possible to use Grafana to create a time-series pie chart.

Found the solution. In the Filter box under "Computed columns Filter, Group by", I put
"Time >= ${__from:date:seconds} && Time <= ${__to:date:seconds}"
In the JSON file, I use epoch format for value of "Time".
Reference: https://grafana.com/docs/grafana/latest/dashboards/variables/add-template-variables/#__from-and-__to

Related

How Do I Structure MongoDB To Query By Date Time Per Minute?

I am trying to store the price of stocks price per minute, so I can easily return results based on the minute date time per minute interval and store historical data, so i can query like last 24 hours, last 30 days etc (please also let me know if this is wrong approach)
for example if i check current time with fmt.Println("time now: ", time.Now()) i get the following date time 2022-01-29 11:47:02.398118591 +0000 UTC m=+499755.770119738
so what i want is to only get up to minute level, so i can store per minute
so i will liek to use this date time 2022-01-29 11:47:00 +0000 UTC
I will like to UTC, so i can stick to that universal time zone to store and retrive data
Each row will be a list of multiple stock price data
Do i need to have the _id field? Am not sure, so just looking for best practice as help.
database name: "stock-price-db"
collection name: "stock-price"
Thinking of something like this, just for example
[
{
"_id" : ObjectId("5458b6ee09d76eb7326df3a4"),
"2022-01-29 11:48:00 +0000 UTC":
[
{
"stock": "TSLA",
"price": "859.83",
"marketcap": "8938289305",
},
{
"stock": "AAPL",
"price": "175.50",
"marketcap": "3648289305",
},
]
},
{
"_id" : ObjectId("5458b6ee09d76eb7326df3a4"),
"2022-01-29 11:47:00 +0000 UTC":
[
{
"stock": "TSLA",
"price": "855.50",
"marketcap": "8848289305",
},
{
"stock": "AAPL",
"price": "172.96",
"marketcap": "3638289305",
},
]
},
]
First, is this the right way to do store this type of data in mongodb and how do I structure the model to store the data this way so I can store the data per minute interval, so I can query per minute interval?
There are few drawbacks in your design.
Do not use dynamic keys - you will end up using few extra aggregation pipelines.
Store the date in a static-key field i.e time:ISODate()
Better store all the available time units, till milliseconds, it will be helpful to handle the future requirement changes
If there are too many stocks changes, it is not a scalable design.
If you want to find out historical data for a stock, provided design may have performance issues.
You will end up with issues in sharding.
What other alternatives:
Not all the use-cases can be solved by one design.
If this use case is purely for time series use case, I would recommend you to use a time series design/ time series database i.e influx, tsdb.
If you need to cover all the use-cases, normalise and use GQL.

How to filter records by timestap

I have a list of events with start time and i need to display only future events. Basically something like startTime > now.
Any suggestions?
thanks!
If you put a record with a date as an integer, you can use a filter on numerical values.
For example, if you have a record like that:
{
"objectID": 1,
"eventName": "Algolia Search party",
"startTime": 1507705690 //Wednesday, October 11, 2017 7:08:10 AM in timestamp
}
You can search on top with something like:
index.search({
filters: 'startTime > ' + new Date().getTime()
});
You can find more here: https://www.algolia.com/doc/guides/searching/filtering/?language=php#filter-by-numerical-value

Date range queries mongodb

I've two collections one is random and other one is 'msg'
In message I've a document like
{ "message": "sssss", postedAt: Fri Jul 17 2015 09:03:43 GMT+0530 (IST) }
For random collection, there is a script which generates random number every minute
like
{ "randomStr": "sss", postedAt: Fri Jul 17 2015 09:03:43 GMT+0530 (IST) }
{ "randomStr": "xxx", postedAt: Fri Jul 17 2015 09:04:43 GMT+0530 (IST) }
{ "randomStr": "yyy", postedAt: Fri Jul 17 2015 09:05:43 GMT+0530 (IST) }
Notice the change in timings, for every mintute there is a new record.
Now, my issue is
when I query for message collection, I'll get one record.
Lets's say this
{ "message": "sssss", postedAt: Fri Jul 17 2015 09:03:13 GMT+0530 (IST) }
now I want to get the record from random collection which posts at exact minute
this message is posted at 09:03, I want to get the record from random collection which postedat exactly same time 09:03.
How to do that? Any help appreciated. Thx.
Note: I'm doing this in meteor
Edit
Added image for first comment
So the point here is 'actually use a range' and also be aware of the Date value you get in return. So as a basic example in principle.
The time right now as I execute this is:
var date = new Date()
ISODate("2015-07-17T04:02:04.471Z")
So if you presume then that your actual timestamp in the document is "not exactly to the minute" (like above) nor is it likely the "random record" is so then the first thing to do is "round" it to the minute:
date = new Date(date.valueOf() - date.valueOf() % ( 1000 * 60 ))
ISODate("2015-07-17T04:02:00Z")
And of course the "end date" is just one minute after that:
var endDate = new Date(date.valueOf() + ( 1000 * 60 ))
ISODate("2015-07-17T04:03:00Z")
Then when you query "rqndom" you just get the "range", with $gte and $lt operators:
db.random.find({ "postedAt": { "$gte": date, "$lt": endDate } })
Which just retrieves your single "write once a minute" item from "random" at any possible value within that minute.
So basically:
Round your input retrieved date to the minute
Search on the "range" betweeen that value and the next minute

Unique hash/index for time interval

I am working on a simple resource booking app. The use of the resource is exclusive so it can't be booked more than once at the same time. I am wondering if this constraint can be enforced by a unique index instead of having to build validation in code.
The resource can only be booked by block of 30 minutes and the start and end time must be on the hour OR the half hour. So the booking can modeled as an array of blocks that are unique (dividing the timestamp in chunks of 30 minutes).
Can anyone think of a way to hash that so any booking with one or more 30-min. block in common would violate the unique index condition?
NB: I am using MongoDB (I don't think it really matters)
I am wondering if this constraint can be enforced by a unique index instead of having to build validation in code.
Use an unique compound index on the resource id, day and chunk of 30 minutes. Then insert one document for each 30 minutes of period of reservation.
For example, to reserve the resource id 123 on 9 of June 2015 from 8:00 to 9:30 (16th, 17th and 18th 30 minutes period of the day), you insert 3 documents:
> db.booking.createIndex({resource: 1,
day: 1, period:1},{unique:true})
{
resource: 123,
day: ISODate("2015-09-06"),
period: 16
},
{
resource: 123,
day: ISODate("2015-09-06"),
period: 17
},
{
resource: 123,
day: ISODate("2015-09-06"),
period: 18
},
Depending the number en entries, you might consider using embedded documents instead:
> db.resource.createIndex({_id: 1,
"booking.day": 1,
"booking:period":1},{unique:true})
And describe your resources like this:
{
_id: 123,
someOtherResourceAttributes: "...",
booking: [
{
day: ISODate("2015-09-06"),
period: 16
},
{
day: ISODate("2015-09-06"),
period: 17
},
{
day: ISODate("2015-09-06"),
period: 18
},
]
},
This has the great advantage that insert/update would be atomic for the whole reservation. But beware that document size is limited to 16M.

MongoDB squema design for objects with several dates

I'm building an event website. There are 2 types of events:
Events with specific dates and times. For example, a theatre show can have a show Jan 10 at 8pm, Jan 11 at 8pm and Jan 13 at 7pm.
Events which open a range of hours during several days. For example, an exhibition on a museum can open from Jan 10 to Jan 30 from 10am to 6pm.
I need to save the dates and times so that I can answer the following questions/queries:
Which events are going to happen tomorrow from 7pm to 12am?
Which events are going to happen this weekend?
Which events are about to finish? (the last day is less than one week away)
If we didn't have events type 2, we could have the following squema:
name
category
dates: an array of dates (each day would be on the array)
But because we have events type 2, it has to be different. I thought on having:
name
category
dates: an array of objects like {"2015-01-10 09:00": "2015-01-10 18:00"} with the range of hours of each day.
But I think it's not possible to do a query to solve Question 1 with this squema. Am I wrong?
How would you structure the data so I could answer those three questions?
thanks!
It was easier than I tought.
First, on MongoDB you can't have dates as keys.
The model is:
{
"name" : "Bob Dylan",
"category" : "Exhibition",
"dates" : [
{
"init" : ISODate("2015-01-08T08:00:00Z"),
"end" : ISODate("2015-01-08T19:00:00Z")
},
{
"init" : ISODate("2015-01-09T08:00:00Z"),
"end" : ISODate("2015-01-09T21:00:00Z")
},
{
"init" : ISODate("2015-01-10T08:00:00Z"),
"end" : ISODate("2015-01-10T21:00:00Z")
}
],
"createdAt" : ISODate("2015-01-09T16:33:51.338Z")
}
And the query is:
return Events.find({
'dates.init' : { $gte: dateInit },
'dates.end' : { $lte: dateEndPlusOneDay }
});