Documentation.
This commit is contained in:
parent
27ec4e620a
commit
78f00dd97e
2 changed files with 148 additions and 36 deletions
96
README.md
96
README.md
|
|
@ -26,7 +26,27 @@ At present several useful functions are implemented:
|
||||||
|
|
||||||
Return a list of maps, each representing one account from the `gaza.onl` database, with a key `:donations`, whose value is a float representing the total donations received by that account between the dates `start-date` (exclusive) and `end-date` (inclusive). Date arguments should be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`.
|
Return a list of maps, each representing one account from the `gaza.onl` database, with a key `:donations`, whose value is a float representing the total donations received by that account between the dates `start-date` (exclusive) and `end-date` (inclusive). Date arguments should be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`.
|
||||||
|
|
||||||
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L98)
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L108)
|
||||||
|
|
||||||
|
### active-accounts
|
||||||
|
|
||||||
|
```
|
||||||
|
(active-accounts date)
|
||||||
|
```
|
||||||
|
|
||||||
|
Return, as an integer, the number of accounts believed to have been active on this `date`, which should be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`
|
||||||
|
|
||||||
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L97)
|
||||||
|
|
||||||
|
### average-donations-received-by-month
|
||||||
|
|
||||||
|
```
|
||||||
|
(average-donations-received-by-month start-date end-date)
|
||||||
|
```
|
||||||
|
|
||||||
|
Return data as a map keyed by the date of the first of each month between `start-date` and `end-date`; the values are maps with keys `:average`, `:count` and `:total`. Arguments should be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`.
|
||||||
|
|
||||||
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L172)
|
||||||
|
|
||||||
### chart-accounts-with-donations-by-months-in-range
|
### chart-accounts-with-donations-by-months-in-range
|
||||||
|
|
||||||
|
|
@ -38,7 +58,17 @@ Return a chart with one line for each calendar month covering from `start-date`
|
||||||
|
|
||||||
TODO: There are currently two problems with this at present: chart legends are not displayed in sequential order; and there appears to be occasional spurious data (but I don’t know why).
|
TODO: There are currently two problems with this at present: chart legends are not displayed in sequential order; and there appears to be occasional spurious data (but I don’t know why).
|
||||||
|
|
||||||
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L138)
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L142)
|
||||||
|
|
||||||
|
### chart-average-donations-received-by-month
|
||||||
|
|
||||||
|
```
|
||||||
|
(chart-average-donations-received-by-month start-date end-date)
|
||||||
|
```
|
||||||
|
|
||||||
|
Return a chart comparing the average donations received per account with the total number of active accounts per month between `start-date` and `end-date`. Arguments should be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`.
|
||||||
|
|
||||||
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L194)
|
||||||
|
|
||||||
### chart-donations-as-percentage-in-date-range
|
### chart-donations-as-percentage-in-date-range
|
||||||
|
|
||||||
|
|
@ -48,7 +78,7 @@ TODO: There are currently two problems with this at present: chart legends are
|
||||||
|
|
||||||
Return a chart of donations received by individual accounts between `start-date` (exclusive) and `end-date` (inclusive). Arguments should be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`. Accounts are identified in the chart only by rank order.
|
Return a chart of donations received by individual accounts between `start-date` (exclusive) and `end-date` (inclusive). Arguments should be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`. Accounts are identified in the chart only by rank order.
|
||||||
|
|
||||||
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L125)
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L129)
|
||||||
|
|
||||||
### chart-donations-by-accounts-in-date-range
|
### chart-donations-by-accounts-in-date-range
|
||||||
|
|
||||||
|
|
@ -58,7 +88,7 @@ Return a chart of donations received by individual accounts between `start-date`
|
||||||
|
|
||||||
Return a chart of donations received by individual accounts between `start-date` (exclusive) and `end-date` (inclusive). Arguments should be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`. Accounts are identified in the chart only by rank order.
|
Return a chart of donations received by individual accounts between `start-date` (exclusive) and `end-date` (inclusive). Arguments should be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`. Accounts are identified in the chart only by rank order.
|
||||||
|
|
||||||
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L115)
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L119)
|
||||||
|
|
||||||
### chart-donations-by-weeks
|
### chart-donations-by-weeks
|
||||||
|
|
||||||
|
|
@ -68,7 +98,7 @@ Return a chart of donations received by individual accounts between `start-date`
|
||||||
|
|
||||||
Create and return an XY chart of data on field represented by `key` of donations made between `start-date` and `end-date`. Arguments may be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`.
|
Create and return an XY chart of data on field represented by `key` of donations made between `start-date` and `end-date`. Arguments may be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`.
|
||||||
|
|
||||||
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L58)
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L57)
|
||||||
|
|
||||||
### chart-number-donations-by-weeks
|
### chart-number-donations-by-weeks
|
||||||
|
|
||||||
|
|
@ -78,7 +108,7 @@ Create and return an XY chart of data on field represented by `key` of donations
|
||||||
|
|
||||||
Create and return an XY chart of data on number of donations made between `start-date` and `end-date`. Arguments may be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`.
|
Create and return an XY chart of data on number of donations made between `start-date` and `end-date`. Arguments may be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`.
|
||||||
|
|
||||||
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L75)
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L74)
|
||||||
|
|
||||||
### chart-total-donations-by-weeks
|
### chart-total-donations-by-weeks
|
||||||
|
|
||||||
|
|
@ -88,7 +118,43 @@ Create and return an XY chart of data on number of donations made between `start
|
||||||
|
|
||||||
Create and return an XY chart of data on total donations made between `start-date` and `end-date`. Arguments may be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`.
|
Create and return an XY chart of data on total donations made between `start-date` and `end-date`. Arguments may be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`.
|
||||||
|
|
||||||
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L68)
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L67)
|
||||||
|
|
||||||
|
### date?
|
||||||
|
|
||||||
|
#### macro
|
||||||
|
|
||||||
|
```
|
||||||
|
(date? x)
|
||||||
|
```
|
||||||
|
|
||||||
|
**TODO**: write docs
|
||||||
|
|
||||||
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L15)
|
||||||
|
|
||||||
|
### datetime->date
|
||||||
|
|
||||||
|
#### macro
|
||||||
|
|
||||||
|
```
|
||||||
|
(datetime->date x)
|
||||||
|
```
|
||||||
|
|
||||||
|
**TODO**: write docs
|
||||||
|
|
||||||
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L52)
|
||||||
|
|
||||||
|
### db
|
||||||
|
|
||||||
|
**TODO**: write docs
|
||||||
|
|
||||||
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L13)
|
||||||
|
|
||||||
|
### db-spec
|
||||||
|
|
||||||
|
**TODO**: write docs
|
||||||
|
|
||||||
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L9)
|
||||||
|
|
||||||
### enhance-account-with-donations
|
### enhance-account-with-donations
|
||||||
|
|
||||||
|
|
@ -98,7 +164,19 @@ Create and return an XY chart of data on total donations made between `start-dat
|
||||||
|
|
||||||
Take this `account_map`, which must at least have a valid value for the key `:campaign_url` and return a similar map including the key `:donations`, whose value is a float representing the total donations received by that campaign URL between the dates `sd` (exclusive) and `ed` (inclusive). Date arguments should be supplied as `java.time.LocalDate` objects.
|
Take this `account_map`, which must at least have a valid value for the key `:campaign_url` and return a similar map including the key `:donations`, whose value is a float representing the total donations received by that campaign URL between the dates `sd` (exclusive) and `ed` (inclusive). Date arguments should be supplied as `java.time.LocalDate` objects.
|
||||||
|
|
||||||
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L82)
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L81)
|
||||||
|
|
||||||
|
### normalise-date
|
||||||
|
|
||||||
|
#### macro
|
||||||
|
|
||||||
|
```
|
||||||
|
(normalise-date date default)
|
||||||
|
```
|
||||||
|
|
||||||
|
**TODO**: write docs
|
||||||
|
|
||||||
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L18)
|
||||||
|
|
||||||
### total-donations-by-weeks
|
### total-donations-by-weeks
|
||||||
|
|
||||||
|
|
@ -106,7 +184,7 @@ Take this `account_map`, which must at least have a valid value for the key `:ca
|
||||||
|
|
||||||
Return a list of pairs [java.time.LocalDate date, float amount](file:///home/simon/workspace/gaza-stats/docs/codox/java.time.LocalDate date, float amount) representing the total of donations made between `start-date` and `end-date`. Arguments may be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`. If `end-date` is not supplied, data for a single week will be returned.
|
Return a list of pairs [java.time.LocalDate date, float amount](file:///home/simon/workspace/gaza-stats/docs/codox/java.time.LocalDate date, float amount) representing the total of donations made between `start-date` and `end-date`. Arguments may be supplied as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`. If `end-date` is not supplied, data for a single week will be returned.
|
||||||
|
|
||||||
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L18)
|
[view source](https://git.journeyman.cc/simon/gaza-stats/src/branch/main/src/gaza_stats/core.clj#L23)
|
||||||
|
|
||||||
### Viewing charts
|
### Viewing charts
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,11 @@
|
||||||
(defmacro date? [x]
|
(defmacro date? [x]
|
||||||
`(instance? java.time.LocalDate ~x))
|
`(instance? java.time.LocalDate ~x))
|
||||||
|
|
||||||
|
(defmacro normalise-date [date default]
|
||||||
|
`(cond (date? ~date) ~date
|
||||||
|
(string? ~date) (ld/parse ~date)
|
||||||
|
:else (ld/parse ~default)))
|
||||||
|
|
||||||
(defn total-donations-by-weeks
|
(defn total-donations-by-weeks
|
||||||
"Return a list of pairs [java.time.LocalDate date, float amount] representing
|
"Return a list of pairs [java.time.LocalDate date, float amount] representing
|
||||||
the total of donations made between `start-date` and `end-date`. Arguments may
|
the total of donations made between `start-date` and `end-date`. Arguments may
|
||||||
|
|
@ -22,17 +27,11 @@
|
||||||
`yyyy-mm-dd`. If `end-date` is not supplied, data for a single week will be
|
`yyyy-mm-dd`. If `end-date` is not supplied, data for a single week will be
|
||||||
returned."
|
returned."
|
||||||
([start-date]
|
([start-date]
|
||||||
(let [sd (cond (date? start-date) start-date
|
(let [sd (normalise-date start-date "2024-01-01")]
|
||||||
(string? start-date) (ld/parse start-date)
|
|
||||||
:else (ld/parse "2024-01-01"))]
|
|
||||||
(total-donations-by-weeks sd (ld/plus-days sd 7))))
|
(total-donations-by-weeks sd (ld/plus-days sd 7))))
|
||||||
([start-date end-date]
|
([start-date end-date]
|
||||||
(let [sd (cond (date? start-date) start-date
|
(let [sd (normalise-date start-date "2024-01-01")
|
||||||
(string? start-date) (ld/parse start-date)
|
ed (normalise-date end-date (ld/now))]
|
||||||
:else (ld/parse "2024-01-01"))
|
|
||||||
ed (cond (date? end-date) end-date
|
|
||||||
(string? end-date) (ld/parse end-date)
|
|
||||||
:else (ld/now))]
|
|
||||||
(loop [s sd
|
(loop [s sd
|
||||||
i (ld/plus-days sd 7)
|
i (ld/plus-days sd 7)
|
||||||
r nil]
|
r nil]
|
||||||
|
|
@ -95,6 +94,17 @@
|
||||||
{:created_at [> sd]}
|
{:created_at [> sd]}
|
||||||
{:created_at [<= ed]})))))))
|
{:created_at [<= ed]})))))))
|
||||||
|
|
||||||
|
(defn active-accounts
|
||||||
|
"Return, as an integer, the number of accounts believed to have been active
|
||||||
|
on this `date`, which should be
|
||||||
|
supplied as `java.time.LocalDate` objects, or as strings in the format
|
||||||
|
`yyyy-mm-dd`"
|
||||||
|
[date]
|
||||||
|
(let [d (normalise-date date (ld/now))]
|
||||||
|
(select 'accounts
|
||||||
|
(fields :id :display_name :created_at :campaign_url)
|
||||||
|
(where {:created_at [< d]}))))
|
||||||
|
|
||||||
(defn accounts-with-donations-by-date-range
|
(defn accounts-with-donations-by-date-range
|
||||||
"Return a list of maps, each representing one account from the `gaza.onl`
|
"Return a list of maps, each representing one account from the `gaza.onl`
|
||||||
database, with a key `:donations`, whose value is a float representing the
|
database, with a key `:donations`, whose value is a float representing the
|
||||||
|
|
@ -102,15 +112,9 @@
|
||||||
(exclusive) and `end-date` (inclusive). Date arguments should be supplied
|
(exclusive) and `end-date` (inclusive). Date arguments should be supplied
|
||||||
as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`."
|
as `java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`."
|
||||||
[start-date end-date]
|
[start-date end-date]
|
||||||
(let [sd (cond (date? start-date) start-date
|
(let [sd (normalise-date start-date "2024-01-01")
|
||||||
(string? start-date) (ld/parse start-date))
|
ed (normalise-date end-date (ld/now))]
|
||||||
ed (cond (date? end-date) end-date
|
(map #(enhance-account-with-donations % sd ed) (active-accounts sd))))
|
||||||
(string? end-date) (ld/parse end-date)
|
|
||||||
:else (ld/now))
|
|
||||||
accounts (select 'accounts
|
|
||||||
(fields :id :display_name :created_at :campaign_url)
|
|
||||||
(where {:created_at [< sd]}))]
|
|
||||||
(map #(enhance-account-with-donations % sd ed) accounts)))
|
|
||||||
|
|
||||||
(defn chart-donations-by-accounts-in-date-range
|
(defn chart-donations-by-accounts-in-date-range
|
||||||
"Return a chart of donations received by individual accounts between
|
"Return a chart of donations received by individual accounts between
|
||||||
|
|
@ -146,15 +150,11 @@
|
||||||
are not displayed in sequential order; and there appears to be occasional
|
are not displayed in sequential order; and there appears to be occasional
|
||||||
spurious data (but I don't know why)."
|
spurious data (but I don't know why)."
|
||||||
[start-date end-date]
|
[start-date end-date]
|
||||||
(let [sd (cond (date? start-date) start-date
|
(let [sd (normalise-date start-date "2024-01-01")
|
||||||
(string? start-date) (ld/parse start-date)
|
ed (normalise-date end-date (ld/now))]
|
||||||
:else (ld/now))
|
|
||||||
ed (cond (date? end-date) end-date
|
|
||||||
(string? end-date) (ld/parse end-date)
|
|
||||||
:else (ld/now))]
|
|
||||||
(loop [s (.withDayOfMonth sd 1)
|
(loop [s (.withDayOfMonth sd 1)
|
||||||
i (.withDayOfMonth (.plusMonths sd 1) 1)
|
i (.withDayOfMonth (.plusMonths sd 1) 1)
|
||||||
m {}]
|
m (sorted-map)]
|
||||||
(let [data (accounts-with-donations-by-date-range s i)
|
(let [data (accounts-with-donations-by-date-range s i)
|
||||||
m' (assoc m (format "Donations between\n%s and\n%s" s i)
|
m' (assoc m (format "Donations between\n%s and\n%s" s i)
|
||||||
[(range (count data)) (sort (map :donations data))])]
|
[(range (count data)) (sort (map :donations data))])]
|
||||||
|
|
@ -168,3 +168,37 @@
|
||||||
;; {:campaign_url [= "https://www.chuffed.org/project/128261-photographer-from-gaza-rebuilding-life-dreams"]}
|
;; {:campaign_url [= "https://www.chuffed.org/project/128261-photographer-from-gaza-rebuilding-life-dreams"]}
|
||||||
;; {:created_at [> "2024-04-01"]}
|
;; {:created_at [> "2024-04-01"]}
|
||||||
;; {:created_at [<= "2o24-04-30"]}))))
|
;; {:created_at [<= "2o24-04-30"]}))))
|
||||||
|
|
||||||
|
(defn average-donations-received-by-month
|
||||||
|
"Return data as a map keyed by the date of the first of each month between
|
||||||
|
`start-date` and `end-date`; the values are maps with keys `:average`,
|
||||||
|
`:count` and `:total`. Arguments should be supplied as `java.time.LocalDate`
|
||||||
|
objects, or as strings in the format `yyyy-mm-dd`."
|
||||||
|
[start-date end-date]
|
||||||
|
(let [sd (normalise-date start-date "2024-01-01")
|
||||||
|
ed (normalise-date end-date (ld/now))]
|
||||||
|
(loop [s (.withDayOfMonth sd 1)
|
||||||
|
i (.withDayOfMonth (.plusMonths sd 1) 1)
|
||||||
|
m (sorted-map)]
|
||||||
|
(let [accs (accounts-with-donations-by-date-range s i)
|
||||||
|
n (count accs)
|
||||||
|
total (reduce + (map :donations accs))
|
||||||
|
av (if (zero? n)
|
||||||
|
n
|
||||||
|
(float (/ total n)))
|
||||||
|
m' (assoc m s {:average av :count n :total total})]
|
||||||
|
(if (ld/is-before ed i)
|
||||||
|
m'
|
||||||
|
(recur i (.withDayOfMonth (.plusMonths i 1) 1) m'))))))
|
||||||
|
|
||||||
|
(defn chart-average-donations-received-by-month
|
||||||
|
"Return a chart comparing the average donations received per account with
|
||||||
|
the total number of active accounts per month between `start-date` and
|
||||||
|
`end-date`. Arguments should be supplied as `java.time.LocalDate` objects,
|
||||||
|
or as strings in the format `yyyy-mm-dd`."
|
||||||
|
[start-date end-date]
|
||||||
|
(let [data (average-donations-received-by-month start-date end-date)]
|
||||||
|
(xy-chart {(format "Average donations\nper active account\nbetween\n%s and\n%s" start-date end-date)
|
||||||
|
[(map #(datetime->date %)(keys data)) (map :average (vals data))]
|
||||||
|
(format "Active accounts\nbetween\n%s and\n%s" start-date end-date)
|
||||||
|
[(map #(datetime->date %)(keys data)) (map :count (vals data))]})))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue