From b396015e3483c2eca9428c1ba7722b222aaff4e6 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Sun, 27 Sep 2026 16:36:37 +0100 Subject: [PATCH] Now also generating graph of number of donors. --- README.md | 2 +- src/gaza_stats/core.clj | 51 +++++++++++++++++++++++++++++------------ 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 87a6df0..2525db2 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ 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. -### `chart-total-donations-by-weeks` +### `(chart-total-donations-by-weeks start-date end-date)` Create and return an XY chart of data on total donations made between `start-date` and `end-date`. Arguments may be supplied as diff --git a/src/gaza_stats/core.clj b/src/gaza_stats/core.clj index cd05e75..9ac610b 100644 --- a/src/gaza_stats/core.clj +++ b/src/gaza_stats/core.clj @@ -1,5 +1,6 @@ (ns gaza-stats.core - (:require [cljc.java-time.local-date :as ld] + (:require [clojure.string :refer [capitalize]] + [cljc.java-time.local-date :as ld] [com.hypirion.clj-xchart :refer [xy-chart]] [korma.core :refer [fields join select where]] [korma.db :refer [defdb sqlite3]])) @@ -32,26 +33,46 @@ (loop [s sd i (ld/plus-days sd 7) r nil] - (let [r' (cons - [s (reduce + - (map :amount - (select 'campaign_donations - (fields :amount) - (where (and {:created_at [> s]} - {:created_at [<= i]})))))] + (let [data (select 'campaign_donations + (fields :amount) + (where (and {:created_at [> s]} + {:created_at [<= i]}))) + amounts (map :amount data) + r' (cons + [s {:total (reduce + amounts) + :n (count data) + :max (apply max amounts) + :min (apply min amounts)}] r)] (if (ld/is-before ed i) (reverse r') (recur i (ld/plus-days i 7) r'))))))) +(defmacro datetime->date [x] + `(java.util.Date/from + (.toInstant (.atStartOfDay ~x) + (java.time.ZoneOffset/ofHours 0)))) + +(defn chart-donations-by-weeks + "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`." + [start-date end-date key] + (let [data (total-donations-by-weeks start-date end-date)] + (xy-chart {(format "%s Donations" (capitalize (name key))) + [(map #(datetime->date (first %)) data) + (map #(:n (nth % 1)) data)]}))) + + (defn chart-total-donations-by-weeks "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`." [start-date end-date] - (let [data (total-donations-by-weeks start-date end-date)] - (xy-chart {"Donations" - [(map #(java.util.Date/from - (.toInstant (.atStartOfDay (first %)) - (java.time.ZoneOffset/ofHours 0))) - data) - (map #(nth % 1) data)]}))) + (chart-donations-by-weeks start-date end-date :total)) + +(defn chart-number-donations-by-weeks + "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`." + [start-date end-date] + (chart-donations-by-weeks start-date end-date :n))