blockscout-rs
blockscout-rs copied to clipboard
stats: aggregate result of line chart by days, weeks, months, years
Add new input to stats page (like interval) called "resolution" to return results for a single day, a week, a month, or a year:
most likely it will change api, or at least date
key in response
Refactor the service in preparation for feature:
- [x] Modify the service to allow more generic and complex relationships (e.g. between charts) #891
Implement resolutions:
- [x]
Week
data type - [x] Generic data types that support abstract resolution
- [x] Interface inner resolutioned points <-> DB
- [x] Adapt data source implementors for various resolutions
- [x] Implement one weekly chart with passing test
- [x] Work through using chart info (in DB) for resolutioned charts
- [x] Add resolutions to configs
- [x] Update read service (+protobuf)
- [x] Implement weekly versions for all chart types
- [x] Cover with tests
- [x] Generalize the solution to years & months
- [x] Add new cases to tests
- [ ] Smoke run (test) locally
Caveat: chart "ActiveAccounts". Adding intervals requires us to calculate/store unique users for each interval. It's quite non-trivial. Also not really clear what to do with cumulative/increasing graphs. Show result at the start/middle/end of the interval, or even an average value.
Almost forgot: graphs with averages are non-trivial as well. To properly compute an average of some interval from averages of subintervals we need to retrieve # of entries for each subinterval.
I.e. we have 100 entries on monday (avg=0.5) and 1 entry on friday (avg=1). Avg for the week should be ~0.5 instead of 0.75
for now will implement it for easier cases, let's decide on "ActiveAccounts" later..
Also not really clear what to do with cumulative/increasing graphs. Show result at the start/middle/end of the interval, or even an average value.
and for this it makes sense to let it be configurable (i.e. also decide later)
API design (report-ish)
Request
Add a parameter to query string (enum => string with some set of available values). Variants:
- day
- week
- month
- year
Pros:
- readable
- clear list of possible inputs
- flexible, string type doesn’t restrict possible resolutions
Cons:
- might become ugly if some non-regular intervals are added later (i.e. for 3 months
..&resolution=3months
looks weird) - minor, seems ok
Response
Variant A
Response API remains the same:
{
"chart": [
{
"date": "2024-07-01",
"value": "35607"
},
{
"date": "2024-07-02",
"value": "8832",
"is_approximate": true
}
]
}
and for resolutions the end(or middle or start) of each interval is returned. I.e. for month
it may return the last date of each month.
Maybe we can add this info for each chart separately (e.g. in /lines
endpoint or as in #913)
Pros:
- no change to API Cons:
- might not be clear where the interval starts/ends
Variant B
Add date_to
or date_from
field
{
"chart": [
{
"date": "2024-06-01",
"date_to": "2024-06-30",
"value": "35607"
},
{
"date": "2024-07-01",
"date_to": "2024-07-31",
"value": "8832",
"is_approximate": true
}
]
}
Pros:
- clearly visible (and easy to display in frontend (?)) borders of intervals Cons:
- a little bit weird naming of fields, maybe rename
date
todate_from
? (will be backwards-incompatible - bad ig)
some other rejected variants:
- separate types for each resolutions in response => sounds hard to abstract on frontend side (need to support each type separately) + weeks are non-trivial to name/number propery
- multiple endpoints for each resolution => similar to above