Skip to content

Commit 6412d19

Browse files
authored
Fix 65/daily average speed in plan diagram (#70)
1 parent 1a9073c commit 6412d19

5 files changed

Lines changed: 115 additions & 49 deletions

File tree

src/rando_planner/diagram.clj

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,10 @@
297297
average-speed (plan/average-speed day-plan plan)
298298
elevation (gpx/elevation (:gpx plan))
299299
pauses (plan/pauses day-plan)
300-
main-offset (* (/ km average-speed) box-size)
300+
main-offset (if (> index 0)
301+
(* (/ km (plan/average-speed
302+
(nth (:daily-plans plan) (- index 1)) plan)) box-size)
303+
0)
301304
total-km-for-day (plan/kilometers-in-a-day day-plan average-speed)]
302305
(into [:svg
303306
[:text {:x 0 :y 15
@@ -366,62 +369,59 @@
366369
:font-size ".5em"}
367370
description]])
368371

369-
(defn plan-main-kilometers-svg [total-distance average-speed]
370-
(into [:svg]
371-
[:g
372-
(loop [i 0
373-
output [:g]]
374-
(if (< i (/ total-distance average-speed))
375-
(recur (inc i)
376-
(conj output
377-
[:rect {:x (+ (* 5 box-size)
378-
(* i box-size))
379-
:y box-size
380-
:width box-size :height box-size
381-
:fill (get-from-palette :background)
382-
:stroke "black"
383-
:stroke-width 0.5}]))
384-
output))
385-
;; Opaque box to create the illusion of ticks
386-
[:rect {:x 0 :y 0 :width 400 :height 17 :fill (get-from-palette :background)}]
387-
(loop [i 0
388-
output [:g]]
389-
(if (< i (/ total-distance average-speed))
390-
(recur (inc i)
391-
(conj output
392-
[:text {:x (+ left-margin 5 (* i box-size))
393-
:y 17
394-
:font-family "Fira Sans"
395-
:font-size ".25em"
396-
:text-anchor "middle"}
397-
(str (* average-speed (+ 1 i)))]))
398-
output))]))
372+
(defn plan-main-kilometers-svg [plan]
373+
(let [hourly-distances (plan/hourly-cumulative-distances-in-a-plan plan)]
374+
(into [:svg]
375+
[:g
376+
(loop [i 0
377+
output [:g]]
378+
(if (< i (count hourly-distances))
379+
(recur (inc i)
380+
(conj output
381+
[:rect {:x (+ (* 5 box-size)
382+
(* i box-size))
383+
:y box-size
384+
:width box-size :height box-size
385+
:fill (get-from-palette :background)
386+
:stroke "black"
387+
:stroke-width 0.5}]))
388+
output))
389+
;; Opaque box to create the illusion of ticks
390+
[:rect {:x 0 :y 0 :width 400 :height 17 :fill (get-from-palette :background)}]
391+
(loop [i 0
392+
output [:g]]
393+
(if (< i (count hourly-distances))
394+
(recur (inc i)
395+
(conj output
396+
[:text {:x (+ left-margin 5 (* i box-size))
397+
:y 17
398+
:font-family "Fira Sans"
399+
:font-size ".25em"
400+
:text-anchor "middle"}
401+
(str (nth hourly-distances i))]))
402+
output))])))
399403

400404
(defn plan-diagram [plan]
401-
(let [total-distance (gpx/total-distance (:gpx plan))
402-
center (gpx/center (gpx/points (:gpx plan)))
403-
average-speed (:average-speed plan)]
405+
(let [center (gpx/center (gpx/points (:gpx plan)))]
404406
[:svg {:width diagram-width
405407
:height diagram-height
406408
:viewBox "0 0 300 230"
407409
:style {:background-color (get-from-palette :background)}}
408410
(plan-title (:description plan))
409411
[:g {:transform "translate(0 25)"}
410-
(plan-main-kilometers-svg total-distance
411-
average-speed)]
412+
(plan-main-kilometers-svg plan)]
412413
(loop [index 0
413414
total-kilometers-covered 0
414415
output [:g]]
415416
(if (< index (count (:daily-plans plan)))
416-
(recur (inc index)
417-
(+ total-kilometers-covered
418-
(plan/kilometers-in-a-day (nth (:daily-plans plan) index)
419-
average-speed))
420-
(conj output [:g {:transform (str "translate(0 "
421-
(+ 50 (* index 50)) ")")}
422-
(day-plan->svg plan index
423-
total-kilometers-covered
424-
center)]))
417+
(let [daily-plan (nth (:daily-plans plan) index)]
418+
(recur (inc index)
419+
(+ total-kilometers-covered
420+
(plan/kilometers-in-a-day daily-plan (plan/average-speed daily-plan plan)))
421+
(conj output [:g {:transform (str "translate(0 " (+ 50 (* index 50)) ")")}
422+
(day-plan->svg plan index
423+
total-kilometers-covered
424+
center)])))
425425
output))]))
426426

427427
(def plan-viewer

src/rando_planner/gpx.clj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,16 @@
9898
(map :elevation-gain))))
9999

100100
;; TODO it is not clear this function returns a list of points
101-
(defn elevation [gpx-resource]
101+
102+
(defn %elevation [gpx-resource]
102103
(-> gpx-resource
103104
points
104105
with-cumulative-distance
105106
group-by-kilometer
106107
with-elevation-gain))
107108

109+
(def elevation (memoize %elevation))
110+
108111
(defn total-distance [gpx-resource]
109112
(->> (points gpx-resource)
110113
(partition 2 1)

src/rando_planner/plan.clj

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,24 @@
2222
(:average-speed plan)
2323
default-average-speed)))
2424

25+
(defn hourly-distances-in-a-day [day-plan average-speed]
26+
(->> (:activities day-plan)
27+
(filter #(= (:type %) :ride))
28+
(map #(take (:length %) (repeat average-speed)))
29+
flatten))
30+
31+
(defn hourly-cumulative-distances-in-a-day [day-plan average-speed]
32+
(reductions + (hourly-distances-in-a-day day-plan average-speed)))
33+
34+
(defn hourly-cumulative-distances-in-a-plan [plan]
35+
(->> plan
36+
:daily-plans
37+
(map #(hourly-distances-in-a-day % (average-speed % plan)))
38+
flatten
39+
(reductions +)))
40+
2541
(defn kilometers-in-a-day [day-plan average-speed]
26-
(reduce + (map #(* (:length %) average-speed)
27-
(filter #(= (:type %) :ride)
28-
(:activities day-plan)))))
42+
(reduce + (hourly-distances-in-a-day day-plan average-speed)))
2943

3044
(defn pauses
3145
"Given a day plan it returns a vector of pauses objects,
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
(ns rando-planner.diagram-test
2+
(:require [rando-planner.diagram :as diagram]
3+
[clojure.test :refer [deftest is testing]]))
4+
5+
(def example-plan
6+
{:gpx "gpx/be-rostock.gpx"
7+
:average-speed 20
8+
:daily-plans [{:date "2024-04-01"
9+
:label "First day"
10+
:color "red"
11+
:activities [{:start "10:00" :type :ride :length 3}
12+
{:start "17:00" :type :ride :length 2}
13+
{:start "20:00" :type :ride :length 3}]}
14+
{:date "2024-04-02"
15+
:label "Second day"
16+
:color "orange"
17+
:activities [{:start "10:00" :type :ride :length 4}
18+
{:start "16:00" :type :ride :length 2.5}]}]})
19+
20+
(def example-plan-with-daily-avg-speed
21+
{:gpx "gpx/be-rostock.gpx"
22+
:daily-plans [{:date "2024-04-01"
23+
:label "First day"
24+
:color "red"
25+
:average-speed 20
26+
:activities [{:start "10:00" :type :ride :length 3}
27+
{:start "17:00" :type :ride :length 2}
28+
{:start "20:00" :type :ride :length 3}]}
29+
{:date "2024-04-02"
30+
:label "Second day"
31+
:color "orange"
32+
:average-speed 20
33+
:activities [{:start "10:00" :type :ride :length 4}
34+
{:start "16:00" :type :ride :length 2.5}]}]})
35+
36+
(deftest plan-diagram
37+
(testing "Plan diagram"
38+
(is (some? (diagram/plan-diagram example-plan)))
39+
(is (some? (diagram/plan-diagram example-plan-with-daily-avg-speed)))))

test/rando_planner/plan_test.clj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,19 @@
1515
:activities [{:start "10:00" :type :ride :length 4}
1616
{:start "16:00" :type :ride :length 2.5}]}]})
1717

18+
(def a-daily-plan
19+
(nth (:daily-plans example-plan) 0))
20+
1821
(deftest plan-tests
1922
(testing "Pauses"
2023
(is (= '([{:start "13:00", :after 3, :length 4 :cumulative-pause 0}
2124
{:start "19:00", :after 9, :length 1 :cumulative-pause 4}]
2225
[{:start "14:00", :after 4, :length 2 :cumulative-pause 0}])
2326
(map plan/pauses (:daily-plans example-plan))))))
27+
28+
(deftest daily-measures
29+
(testing "kilometers-in-a-day"
30+
(is (= 160
31+
(plan/kilometers-in-a-day a-daily-plan 20)))
32+
(is (= '(20 40 60 80 100 120 140 160)
33+
(plan/hourly-cumulative-distances-in-a-day a-daily-plan 20)))))

0 commit comments

Comments
 (0)