This is extremely correct, that the Beeminder API shouldn’t make clients reimplement aggday!
In the case of Mathematica, that’s what all this was originally implemented in so… I can just show you the original code for that (note that it’s out of date and doesn’t have the current slate of aggday functions):
(* Returns a pure function that aggregates a list of values in the way indicated
by the string s, which is what was passed in as the aggday param. *)
aggregator["all"] = Identity; (* all & last are equivalent except that *)
aggregator["last"] = {Last@#}&; (* aggday all means all datapoints are *)
aggregator["first"] = {First@#}&; (* plotted; the last datapoint is still *)
aggregator["min"] = {Min@#}&; (* the official one when aggday==all. *)
aggregator["max"] = {Max@#}&; (* WAIT: aggday=last *)
aggregator["truemean"] = {Mean@#}&; (* doesn't work for *)
aggregator["uniqmean"] = {Mean@DeleteDuplicates@#}&; (* kyoom graphs! *)
aggregator["mean"] = {Mean@DeleteDuplicates@#}&;
aggregator["median"] = {Median@#}&;
aggregator["mode"] = {Median@Commonest@#}&;
aggregator["trimmean"] = {TrimmedMean[#, .1]}&;
aggregator["sum"] = {Total@#}&;
(* Aggregate datapoints on the same day per the aggday parameter. *)
agg0[a_][d_]:= With[{x = d[[1,1]], y = aggregator[a][d[[All,2]]]}, {x,#}& /@ y]
aggregate[data_, a_:Null] :=
Flatten[agg0[If[a===Null, aggday, a]] /@ SplitBy[data, First], 1]
Oh, right, and there’s kyoomify (applying auto-summing) and the odometer reset feature:
(* For every day with no datapoint, add one with the same value as the previous
datapoint. Do this after kyoomify, etc.
Implementation note:
This has a side effect of throwing away all but the last datapoint on each
day, which currently doesn't matter since we've ensured that there is only
one datapoint per day when we call this. *)
fillZeros[{}] = {};
fillZeros[data_] := Module[{val, a,b, x},
each[{t_,v_}, data, val[t] = v];
{a,b} = Extract[data, {{1,1}, {-1,1}}];
(If[NumericQ[val[#]], x = val[#]]; {#,x})& /@ Range[a,b, SID]]
(* Transform data so, eg, values {1,2,1,1} become {1,3,4,5} *)
kyoomify[{}] = {};
kyoomify[data_] := Transpose @ {#1, Accumulate@#2}& @@ Transpose@data
(* The inverse of kyoomify -- gives differences from previous datapoint. *)
unkyoomify[{}] = {};
unkyoomify[data_] := Transpose @ {#1, #2-Prepend[Most@#2,0]}& @@ Transpose@data
(* Or: Transpose@{#1, Differences[Prepend[#2,0]]}& @@ Transpose@data *)
(* Transform data as follows: every time there's a decrease in value from one
datapoint to the next where the second value is zero, say {t1,V} followed by
{t2,0}, add V to the value of every datapoint on or after t2. This is what
you want if you're reporting odometer readings (eg, your page number in a
book can be thought of that way) and the odometer gets accidentally reset (or
you start a new book but want to track total pages read over a set of books).
This should be done before kyoomify and will have no effect on data that has
actually been kyoomified since kyoomification leaves no nonmonotonicities. *)
odo00[{prev_,offset_}, next_] := {next, offset + If[prev>next==0, prev, 0]}
odomify0[list_] := list + Rest[FoldList[odo00, {-Infinity,0}, list]][[All,2]]
odomify[{}] = {}
odomify[data_] := Transpose@{#1, odomify0[#2]}& @@ Transpose@data
Should I get all this somewhere publicly viewable in GitHub?
PS: We also have Python and Javascript versions of all this.