From ccfdf094c5877dda2fe29456ddb5ba9e4452cff2 Mon Sep 17 00:00:00 2001 From: Kenneth Cheung Date: Tue, 17 Mar 2026 14:50:48 -0400 Subject: [PATCH 1/5] update settings page to consolidate directional variables into one parent setting --- projects/behave/src/cljs/behave/vms/subs.cljs | 66 ++-- .../behave/src/cljs/behave/wizard/views.cljs | 10 +- .../src/cljs/behave/worksheet/events.cljs | 276 ++++++++++------- .../src/cljs/behave/worksheet/subs.cljs | 292 +++++++++++------- 4 files changed, 384 insertions(+), 260 deletions(-) diff --git a/projects/behave/src/cljs/behave/vms/subs.cljs b/projects/behave/src/cljs/behave/vms/subs.cljs index 0754d08c..c6b28abe 100644 --- a/projects/behave/src/cljs/behave/vms/subs.cljs +++ b/projects/behave/src/cljs/behave/vms/subs.cljs @@ -1,5 +1,6 @@ (ns behave.vms.subs (:require [behave.schema.core :refer [rules]] + [behave.translate :refer [ parent for quick lookup - parent-map (into {} (map (fn [g] - [(:db/id g) - (when-let [parent (:group/_children g)] - (:db/id parent))]) - groups-with-parents)) + parent-map (into {} (map (fn [g] + [(:db/id g) + (when-let [parent (:group/_children g)] + (:db/id parent))]) + groups-with-parents)) ;; Sort groups from root to leaf by following parent chain - sort-groups (fn [group-eid] - (loop [current group-eid - path []] - (if-let [parent (get parent-map current)] - (recur parent (conj path current)) - (reverse (conj path current))))) + sort-groups (fn [group-eid] + (loop [current group-eid + path []] + (if-let [parent (get parent-map current)] + (recur parent (conj path current)) + (reverse (conj path current))))) - sorted-group-eids (sort-groups immediate-group-eid) - submodule {:db/id submodule-eid}] + sorted-group-eids (sort-groups immediate-group-eid) + submodule {:db/id submodule-eid}] ;; Return: [submodule parent-groups... immediate-group] (cons submodule (map #(hash-map :db/id %) sorted-group-eids))))) @@ -332,3 +332,21 @@ (fn [_ [_ gv-uuid]] (get-group-hierarchy @@vms-conn gv-uuid))) +(defn direction-variables [gv-uuid] + (let [entity (d/entity @@vms-conn [:bp/uuid gv-uuid])] + (seq (:group-variable/direction-variables entity)))) + +(reg-sub + :vms/directional-children + (fn [_ [_ gv-uuid]] + (direction-variables gv-uuid))) + +(defn directional-parent-entity [gv-uuid] + (let [entity (d/entity @@vms-conn [:bp/uuid gv-uuid])] + (first (:group-variable/_direction-variables entity)))) + +(reg-sub + :vms/directional-parent + (fn [_ [_ gv-uuid]] + (directional-parent-entity gv-uuid))) + diff --git a/projects/behave/src/cljs/behave/wizard/views.cljs b/projects/behave/src/cljs/behave/wizard/views.cljs index 3606bf1e..ef03ee4e 100644 --- a/projects/behave/src/cljs/behave/wizard/views.cljs +++ b/projects/behave/src/cljs/behave/wizard/views.cljs @@ -26,6 +26,7 @@ input-value]] [goog.string :as gstring] [goog.string.format] + [re-frame.core :as rf] [re-frame.core :refer [dispatch dispatch-sync subscribe]] [reagent.core :as r] [string-utils.core :as s] @@ -392,8 +393,8 @@ *gv-order (subscribe [:vms/group-variable-order ws-uuid]) gv-uuid+min+max-entries-sorted (->> @*gv-uuid+min+max-entries (sort-by #(.indexOf @*gv-order (first %)))) - *default-max-values (subscribe [:worksheet/output-uuid->result-max-values ws-uuid]) - *default-min-values (subscribe [:worksheet/output-uuid->result-min-values ws-uuid]) + *default-max-values (subscribe [:worksheet/output-uuid->result-min-or-max-values ws-uuid :max]) + *default-min-values (subscribe [:worksheet/output-uuid->result-min-or-max-values ws-uuid :min]) units-lookup @(subscribe [:worksheet/result-table-units ws-uuid]) maximums (number-inputs {:saved-entries (map (fn remove-min-val [[gv-uuid _min-val max-val enabled?]] [gv-uuid max-val enabled?]) @@ -417,7 +418,10 @@ names (map (fn get-variable-name [[gv-uuid _min _max]] (gstring/format "%s (%s)" @(subscribe [:wizard/gv-uuid->resolve-result-variable-name gv-uuid]) - (get units-lookup gv-uuid))) + (get units-lookup + (if-let [direcitonal-children (seq @(subscribe [:vms/directional-children gv-uuid]))] + (:bp/uuid (first direcitonal-children)) + gv-uuid)))) gv-uuid+min+max-entries-sorted) enabled-check-boxes (when (= rf-event-id :worksheet/update-table-filter-attr) (map (fn [[gv-uuid _min _max enabled?]] diff --git a/projects/behave/src/cljs/behave/worksheet/events.cljs b/projects/behave/src/cljs/behave/worksheet/events.cljs index 648b4054..1f1051a2 100644 --- a/projects/behave/src/cljs/behave/worksheet/events.cljs +++ b/projects/behave/src/cljs/behave/worksheet/events.cljs @@ -1,15 +1,16 @@ (ns behave.worksheet.events - (:require [re-frame.core :as rf] - [re-posh.core :as rp] - [datascript.core :as d] - [behave.components.toolbar :refer [step-priority]] + (:require [behave.components.toolbar :refer [step-priority]] [behave.importer :refer [import-worksheet]] [behave.logger :refer [log]] [behave.solver.core :refer [solve-worksheet]] - [vimsical.re-frame.cofx.inject :as inject] - [number-utils.core :refer [to-precision]] + [behave.vms.subs :refer [directional-parent-entity]] [behave.wizard.subs :refer [all-conditionals-pass?]] - [clojure.string :as str])) + [clojure.string :as str] + [datascript.core :as d] + [number-utils.core :refer [to-precision]] + [re-frame.core :as rf] + [re-posh.core :as rp] + [vimsical.re-frame.cofx.inject :as inject])) ;;; Helpers @@ -92,7 +93,7 @@ (rp/reg-event-fx :worksheet/new (fn [_ [_ {:keys [uuid name modules version]}]] - (let [tx (cond-> {:worksheet/uuid (or uuid (str (d/squuid))) + (let [tx (cond-> {:worksheet/uuid (or uuid (str (d/squuid))) :worksheet/modules modules :worksheet/created (.now js/Date)} version @@ -447,47 +448,55 @@ (not enabled?))}] :fx [[:dispatch [:worksheet/set-default-graph-settings ws-uuid]]]}))) +(defn get-graph-axis-limit-eid [db ws-uuid gv-uuid] + (d/q '[:find ?y . + :in $ ?ws-uuid ?group-var-uuid + :where + [?w :worksheet/uuid ?ws-uuid] + [?w :worksheet/graph-settings ?g] + [?g :graph-settings/y-axis-limits ?y] + [?y :y-axis-limit/group-variable-uuid ?group-var-uuid]] + db + ws-uuid + gv-uuid)) + (rp/reg-event-fx :worksheet/update-y-axis-limit-attr - [(rp/inject-cofx :ds)] - (fn [{:keys [ds]} [_ ws-uuid group-var-uuid attr value]] - (when-let [y (first (d/q '[:find [?y] - :in $ ?ws-uuid ?group-var-uuid - :where - [?w :worksheet/uuid ?ws-uuid] - [?w :worksheet/graph-settings ?g] - [?g :graph-settings/y-axis-limits ?y] - [?y :y-axis-limit/group-variable-uuid ?group-var-uuid]] - ds - ws-uuid - group-var-uuid))] - {:transact [(assoc {:db/id y} attr value)]}))) - + [(rp/inject-cofx :ds) + (rf/inject-cofx ::inject/sub (fn [[_ _ group-var-uuid]] [:vms/directional-children group-var-uuid]))] + (fn [{ds :ds + directional-children :vms/directional-children} [_ ws-uuid group-var-uuid attr value]] + (when-let [graph-axis-limit-id (get-graph-axis-limit-eid ds ws-uuid group-var-uuid)] + (let [children-payload (map (fn [child] + (let [child-graph-axis-limit-id + (get-graph-axis-limit-eid ds ws-uuid (:bp/uuid child))] + (assoc {:db/id child-graph-axis-limit-id} attr value))) + directional-children)] + {:transact (cond-> [(assoc {:db/id graph-axis-limit-id} attr value)] + (seq children-payload) (concat children-payload))})))) (rp/reg-event-fx :worksheet/update-all-y-axis-limits-from-results - [(rf/inject-cofx ::inject/sub (fn [[_ ws-uuid]] [:worksheet/output-uuid->result-min-values ws-uuid])) - (rf/inject-cofx ::inject/sub (fn [[_ ws-uuid]] [:worksheet/output-uuid->result-max-values ws-uuid]))] - (fn [{output-uuid->result-min-values :worksheet/output-uuid->result-min-values - output-uuid->result-max-values :worksheet/output-uuid->result-max-values} - [_ ws-uuid]] - (let [gv-uuids (keys output-uuid->result-min-values)] - {:fx (reduce (fn [acc gv-uuid] - (let [max-val (get output-uuid->result-max-values gv-uuid)] - (-> acc - (conj [:dispatch [:worksheet/update-y-axis-limit-attr - ws-uuid - gv-uuid - :y-axis-limit/min - 0]]) - (conj [:dispatch [:worksheet/update-y-axis-limit-attr - ws-uuid - gv-uuid - :y-axis-limit/max - (if (< max-val 1) - (to-precision max-val 1) - (.ceil js/Math max-val))]])))) - [] - gv-uuids)}))) + [(rf/inject-cofx ::inject/sub (fn [[_ ws-uuid]] [:worksheet/output-min+max-values ws-uuid]))] + (fn [{output-min-max-values :worksheet/output-min+max-values} [_ ws-uuid]] + {:fx (reduce (fn [acc [gv-uuid [min-val max-val]]] + (let [[_min-to-use max-to-use] (if-let [direcitonal-parent-uuid (:bp/uuid (directional-parent-entity gv-uuid))] + (get output-min-max-values direcitonal-parent-uuid) + [min-val max-val])] + (-> acc + (conj [:dispatch [:worksheet/update-y-axis-limit-attr + ws-uuid + gv-uuid + :y-axis-limit/min + 0]]) + (conj [:dispatch [:worksheet/update-y-axis-limit-attr + ws-uuid + gv-uuid + :y-axis-limit/max + (if (< max-to-use 1) + (to-precision max-to-use 1) + (.ceil js/Math max-to-use))]])))) + [] + output-min-max-values)})) (rp/reg-event-fx :worksheet/update-x-axis-limit-attr @@ -503,21 +512,32 @@ ws-uuid)] {:transact [(assoc {:db/id eid} attr value)]}))) +(defn get-table-filter-eid [db ws-uuid gv-uuid] + (d/q '[:find ?f . + :in $ ?ws-uuid ?group-var-uuid + :where + [?w :worksheet/uuid ?ws-uuid] + [?w :worksheet/table-settings ?t] + [?t :table-settings/filters ?f] + [?f :table-filter/group-variable-uuid ?group-var-uuid]] + db + ws-uuid + gv-uuid)) + (rp/reg-event-fx :worksheet/update-table-filter-attr - [(rp/inject-cofx :ds)] - (fn [{ds :ds} [_ ws-uuid group-var-uuid attr value]] - (when-let [table-filter-id (d/q '[:find ?f . - :in $ ?ws-uuid ?group-var-uuid - :where - [?w :worksheet/uuid ?ws-uuid] - [?w :worksheet/table-settings ?t] - [?t :table-settings/filters ?f] - [?f :table-filter/group-variable-uuid ?group-var-uuid]] - ds - ws-uuid - group-var-uuid)] - {:transact [(assoc {:db/id table-filter-id} attr value)]}))) + [(rp/inject-cofx :ds) + (rf/inject-cofx ::inject/sub (fn [[_ _ group-var-uuid]] [:vms/directional-children group-var-uuid]))] + (fn [{ds :ds + directional-children :vms/directional-children} [_ ws-uuid group-var-uuid attr value]] + (when-let [table-filter-id (get-table-filter-eid ds ws-uuid group-var-uuid)] + (let [children-payload (map (fn [child] + (let [child-table-filter-id + (get-table-filter-eid ds ws-uuid (:bp/uuid child))] + (assoc {:db/id child-table-filter-id} attr value))) + directional-children)] + {:transact (cond-> [(assoc {:db/id table-filter-id} attr value)] + (seq children-payload) (concat children-payload))})))) (rp/reg-event-fx :worksheet/add-table-filter @@ -541,21 +561,24 @@ [(rf/inject-cofx ::inject/sub (fn [[_ ws-uuid]] [:worksheet/output-min+max-values ws-uuid]))] (fn [{output-min-max-values :worksheet/output-min+max-values} [_ ws-uuid]] {:fx (reduce (fn [acc [gv-uuid [min-val max-val]]] - (-> acc - (conj [:dispatch [:worksheet/update-table-filter-attr - ws-uuid - gv-uuid - :table-filter/min - (if (< min-val 1) - (to-precision min-val 1) - (.floor js/Math min-val))]]) - (conj [:dispatch [:worksheet/update-table-filter-attr - ws-uuid - gv-uuid - :table-filter/max - (if (< max-val 1) - (to-precision max-val 1) - (.ceil js/Math max-val))]]))) + (let [[min-to-use max-to-use] (if-let [direcitonal-parent-uuid (:bp/uuid (directional-parent-entity gv-uuid))] + (get output-min-max-values direcitonal-parent-uuid) + [min-val max-val])] + (-> acc + (conj [:dispatch [:worksheet/update-table-filter-attr + ws-uuid + gv-uuid + :table-filter/min + (if (< min-to-use 1) + (to-precision min-to-use 1) + (.floor js/Math min-to-use))]]) + (conj [:dispatch [:worksheet/update-table-filter-attr + ws-uuid + gv-uuid + :table-filter/max + (if (< max-to-use 1) + (to-precision max-to-use 1) + (.ceil js/Math max-to-use))]])))) [] output-min-max-values)})) @@ -575,8 +598,10 @@ (rp/reg-event-fx :worksheet/toggle-enable-filter - [(rp/inject-cofx :ds)] - (fn [{:keys [ds]} [_ ws-uuid gv-uuid]] + [(rp/inject-cofx :ds) + (rf/inject-cofx ::inject/sub (fn [[_ _ group-var-uuid]] [:vms/directional-children group-var-uuid]))] + (fn [{ds :ds + directional-children :vms/directional-children} [_ ws-uuid gv-uuid]] (when-let [eid (d/q '[:find ?f . :in $ ?uuid ?gv-uuid :where @@ -585,9 +610,22 @@ [?t :table-settings/filters ?f] [?f :table-filter/group-variable-uuid ?gv-uuid]] ds ws-uuid gv-uuid)] - (let [enabled? (:table-filter/enabled? (d/entity ds eid))] - {:transact [{:db/id eid - :table-filter/enabled? (not enabled?)}]})))) + (let [enabled? (:table-filter/enabled? (d/entity ds eid)) + children-payload (map (fn [child] + (let [table-filter-id (d/q '[:find ?f . + :in $ ?uuid ?gv-uuid + :where + [?w :worksheet/uuid ?uuid] + [?w :worksheet/table-settings ?t] + [?t :table-settings/filters ?f] + [?f :table-filter/group-variable-uuid ?gv-uuid]] + ds ws-uuid (:bp/uuid child))] + {:db/id table-filter-id + :table-filter/enabled? (not enabled?)})) + directional-children)] + {:transact (cond-> [{:db/id eid + :table-filter/enabled? (not enabled?)}] + (seq children-payload) (concat children-payload))})))) (rp/reg-event-fx :worksheet/update-graph-settings-attr @@ -614,12 +652,12 @@ submodule-io {:keys [title body] :as _payload}]] (when-let [ws-id (d/entid ds [:worksheet/uuid ws-uuid])] - {:transact [(cond-> {:db/id -1 + {:transact [(cond-> {:db/id -1 :worksheet/_notes ws-id - :note/name (if (empty? title) - (str submodule-name " " submodule-io) - title) - :note/content body} + :note/name (if (empty? title) + (str submodule-name " " submodule-io) + title) + :note/content body} submodule-uuid (assoc :note/submodule submodule-uuid))]}))) (rp/reg-event-fx @@ -698,25 +736,25 @@ fire-head-at-attack contain-status units-uuid]] - {:transact [(cond-> {:worksheet/_diagrams [:worksheet/uuid ws-uuid] - :worksheet.diagram/title title + {:transact [(cond-> {:worksheet/_diagrams [:worksheet/uuid ws-uuid] + :worksheet.diagram/title title :worksheet.diagram/group-variable-uuid group-variable-uuid - :worksheet.diagram/row-id row-id - :worksheet.diagram/units-uuid units-uuid - :worksheet.diagram/ellipses [(let [l (- fire-head-at-report fire-back-at-report) - w (/ l length-to-width-ratio)] - {:ellipse/legend-id "Fire Perimeter at Report" - :ellipse/semi-major-axis (/ l 2) - :ellipse/semi-minor-axis (/ w 2) - :ellipse/rotation 90 - :ellipse/color "blue"}) - (let [l (- fire-head-at-attack fire-back-at-attack) - w (/ l length-to-width-ratio)] - {:ellipse/legend-id "Fire Perimeter at Attack" - :ellipse/semi-major-axis (/ l 2) - :ellipse/semi-minor-axis (/ w 2) - :ellipse/rotation 90 - :ellipse/color "red"})]} + :worksheet.diagram/row-id row-id + :worksheet.diagram/units-uuid units-uuid + :worksheet.diagram/ellipses [(let [l (- fire-head-at-report fire-back-at-report) + w (/ l length-to-width-ratio)] + {:ellipse/legend-id "Fire Perimeter at Report" + :ellipse/semi-major-axis (/ l 2) + :ellipse/semi-minor-axis (/ w 2) + :ellipse/rotation 90 + :ellipse/color "blue"}) + (let [l (- fire-head-at-attack fire-back-at-attack) + w (/ l length-to-width-ratio)] + {:ellipse/legend-id "Fire Perimeter at Attack" + :ellipse/semi-major-axis (/ l 2) + :ellipse/semi-minor-axis (/ w 2) + :ellipse/rotation 90 + :ellipse/color "red"})]} (= contain-status 3) (assoc :worksheet.diagram/scatter-plots [{:scatter-plot/legend-id "Fireline Constructed" :scatter-plot/color "black" @@ -816,24 +854,24 @@ :worksheet.diagram/row-id row-id :worksheet.diagram/units-uuid units-uuid :worksheet.diagram/arrows (cond-> [{:arrow/legend-id "MaxSpread" - :arrow/length max-spread-rate - :arrow/rotation max-spread-dir - :arrow/color "red"} + :arrow/length max-spread-rate + :arrow/rotation max-spread-dir + :arrow/color "red"} {:arrow/legend-id "Flanking1" - :arrow/length flanking-spread-rate - :arrow/rotation flanking-dir - :arrow/color "#81c3cb"} + :arrow/length flanking-spread-rate + :arrow/rotation flanking-dir + :arrow/color "#81c3cb"} {:arrow/legend-id "Flanking2" - :arrow/length flanking-spread-rate - :arrow/rotation (mod (+ flanking-dir 180) 360) - :arrow/color "#347da0"} + :arrow/length flanking-spread-rate + :arrow/rotation (mod (+ flanking-dir 180) 360) + :arrow/color "#347da0"} {:arrow/legend-id "Backing" - :arrow/length backing-spread-rate - :arrow/rotation backing-dir - :arrow/color "orange"} + :arrow/length backing-spread-rate + :arrow/rotation backing-dir + :arrow/color "orange"} (let [l (min max-spread-rate wind-speed)] {:arrow/legend-id "Wind" @@ -841,12 +879,12 @@ ;; make wind 10% larger than ;; max spread rate. ;; :arrow/length wind-speed - :arrow/length (if (> wind-speed max-spread-rate) - (* l 1.1) - l) - :arrow/rotation wind-dir - :arrow/color "blue" - :arrow/dashed? true})] + :arrow/length (if (> wind-speed max-spread-rate) + (* l 1.1) + l) + :arrow/rotation wind-dir + :arrow/color "blue" + :arrow/dashed? true})] has-direction-of-interest? (conj {:arrow/legend-id "Interest" diff --git a/projects/behave/src/cljs/behave/worksheet/subs.cljs b/projects/behave/src/cljs/behave/worksheet/subs.cljs index 811d4c5b..1f63cdfc 100644 --- a/projects/behave/src/cljs/behave/worksheet/subs.cljs +++ b/projects/behave/src/cljs/behave/worksheet/subs.cljs @@ -4,6 +4,8 @@ [behave.store :as s] [behave.translate :refer [directional-gvs + (group-by first + (d/q '[:find ?parent-var-uuid ?uuid ?min ?max ?enabled + :in $ $ws % ?ws-uuid + :where + [$ws ?w :worksheet/uuid ?ws-uuid] + [$ws ?w :worksheet/outputs ?o] + [$ws ?o :output/group-variable-uuid ?uuid] + [$ws ?o :output/enabled? true] + (lookup ?uuid ?gv) + + [$ ?v :group-variable/direction-variables ?gv] + [$ ?v :bp/uuid ?parent-var-uuid] + + [$ws ?w :worksheet/table-settings ?ts] + [$ws ?ts :table-settings/filters ?tf] + [$ws ?tf :table-filter/group-variable-uuid ?uuid] + [$ws ?tf :table-filter/min ?min] + [$ws ?tf :table-filter/max ?max] + [$ws ?tf :table-filter/enabled? ?enabled]] + @@vms-conn @@s/conn rules ws-uuid))] + (doall (map (fn [[parent-gv directional-gvs]] + (let [mins (map #(nth % 2) directional-gvs) + maxs (map #(nth % 3) directional-gvs) + enabled? (map #(nth % 4) directional-gvs)] + [parent-gv (apply min mins) (apply max maxs) (every? true? enabled?)])) + parent-gv->directional-gvs))))) + (rp/reg-sub :worksheet/table-settings-filters (fn [_ [_ ws-uuid]] @@ -676,8 +729,9 @@ (rf/reg-sub :worksheet/table-settings-filters-filtered - (fn [[_ ws-uuid]] (rf/subscribe [:worksheet/table-settings-filters ws-uuid])) - (fn [table-settings-filters _] + (fn [[_ ws-uuid]] + [(rf/subscribe [:worksheet/table-settings-filters ws-uuid])]) + (fn [[table-settings-filters] _] (remove (fn [[group-var-uuid]] (let [kind (d/q '[:find ?kind . @@ -689,7 +743,8 @@ @@vms-conn group-var-uuid)] (or (= kind :discrete) - (= kind :text)))) + (= kind :text) + (directional-parent-entity group-var-uuid)))) table-settings-filters))) ;; Results Table formatters @@ -775,25 +830,25 @@ (rp/reg-sub :worksheet/result-table-cell-data (fn [_ [_ ws-uuid]] - {:type :query - :query '[:find ?row ?col-uuid ?repeat-id ?value - :in $ ?ws-uuid - :where - [?w :worksheet/uuid ?ws-uuid] - [?w :worksheet/result-table ?rt] - [?rt :result-table/rows ?r] - - ;;get row - [?r :result-row/id ?row] - - ;;get-header - [?r :result-row/cells ?c] - [?c :result-cell/header ?h] - [?h :result-header/group-variable-uuid ?col-uuid] - [?h :result-header/repeat-id ?repeat-id] - - ;;get value - [?c :result-cell/value ?value]] + {:type :query + :query '[:find ?row ?col-uuid ?repeat-id ?value + :in $ ?ws-uuid + :where + [?w :worksheet/uuid ?ws-uuid] + [?w :worksheet/result-table ?rt] + [?rt :result-table/rows ?r] + + ;;get row + [?r :result-row/id ?row] + + ;;get-header + [?r :result-row/cells ?c] + [?c :result-cell/header ?h] + [?h :result-header/group-variable-uuid ?col-uuid] + [?h :result-header/repeat-id ?repeat-id] + + ;;get value + [?c :result-cell/value ?value]] :variables [ws-uuid]})) @@ -820,21 +875,37 @@ data))) (rf/reg-sub - :worksheet/output-uuid->result-min-values + :worksheet/output-uuid->result-min-or-max-values (fn [[_ ws-uuid]] [(rf/subscribe [:worksheet/result-table-cell-data ws-uuid]) (rf/subscribe [:worksheet/output-uuids-filtered ws-uuid])]) - (fn [[result-table-cell-data all-output-uuids] _] - (reduce - (fn [acc [_row-id gv-uuid _repeat-id value]] - (if (contains? (set all-output-uuids) gv-uuid) - (update acc gv-uuid (fn [min-v] - (let [min-float (js/parseFloat min-v) - value-float (js/parseFloat value)] - (min (or min-float ##Inf) value-float)))) - acc)) - {} - result-table-cell-data))) + (fn [[result-table-cell-data all-output-uuids] [_ _ws-uuid min-or-max]] + (let [results (reduce + (fn [acc [_row-id gv-uuid _repeat-id value]] + (let [update-fn (case min-or-max + :min (fn [min-v] + (let [min-float (js/parseFloat min-v) + value-float (js/parseFloat value)] + (min (or min-float ##Inf) value-float))) + :max (fn [max-v] + (let [max-float (js/parseFloat max-v) + value-float (js/parseFloat value)] + (max (or max-float ##-Inf) value-float))))] + (if (contains? (set all-output-uuids) gv-uuid) + (update acc gv-uuid update-fn) + acc))) + {} + result-table-cell-data) + op (case min-or-max + :min min + :max max)] + (into {} (reduce (fn [acc [gv-uuid _max-val]] + (if-let [directional-parent-uuid (:bp/uuid (directional-parent-entity gv-uuid))] + (let [directional-children-uuids (map :bp/uuid (direction-variables directional-parent-uuid))] + (assoc acc directional-parent-uuid (apply op (remove nil? (map #(get results %) directional-children-uuids))))) + acc)) + results + results))))) (rf/reg-sub :worksheet/output-min+max-values @@ -845,29 +916,22 @@ (reduce (fn [acc [_row-id gv-uuid _repeat-id value]] (if (contains? (set all-output-uuids) gv-uuid) - (update acc gv-uuid (fn [[min-v max-v]] - (let [min-float (js/parseFloat min-v) - max-float (js/parseFloat max-v) - value-float (js/parseFloat value)] - [(min (or min-float ##Inf) value-float) - (max (or max-float ##-Inf) value-float)]))) - acc)) - {} - result-table-cell-data))) - -(rf/reg-sub - :worksheet/output-uuid->result-max-values - (fn [[_ ws-uuid]] - [(rf/subscribe [:worksheet/result-table-cell-data ws-uuid]) - (rf/subscribe [:worksheet/output-uuids-filtered ws-uuid])]) - (fn [[result-table-cell-data all-output-uuids] _] - (reduce - (fn [acc [_row-id gv-uuid _repeat-id value]] - (if (contains? (set all-output-uuids) gv-uuid) - (update acc gv-uuid (fn [max-v] - (let [max-float (js/parseFloat max-v) - value-float (js/parseFloat value)] - (max (or max-float ##-Inf) value-float)))) + (let [parent-directional-gv (:bp/uuid (first (:group-variable/_direction-variables (d/pull @@vms-conn '[{:group-variable/_direction-variables + [:bp/uuid]}] + [:bp/uuid gv-uuid]))))] + (cond-> (update acc gv-uuid (fn [[min-v max-v]] + (let [min-float (js/parseFloat min-v) + max-float (js/parseFloat max-v) + value-float (js/parseFloat value)] + [(min (or min-float ##Inf) value-float) + (max (or max-float ##-Inf) value-float)]))) + parent-directional-gv + (update parent-directional-gv (fn [[min-v max-v]] + (let [min-float (js/parseFloat min-v) + max-float (js/parseFloat max-v) + value-float (js/parseFloat value)] + [(min (or min-float ##Inf) value-float) + (max (or max-float ##-Inf) value-float)]))))) acc)) {} result-table-cell-data))) @@ -1060,50 +1124,50 @@ (rp/reg-sub :worksheet/input-gv-uuid+value+units (fn [_ [_ ws-uuid row-id]] - {:type :query - :query '[:find ?gv-uuid ?value ?units - :in $ ?ws-uuid ?row-id - :where - [?ws :worksheet/uuid ?ws-uuid] - [?ws :worksheet/input-groups ?ig] - [?ws :worksheet/result-table ?t] - [?t :result-table/rows ?rr] - [?rr :result-row/id ?row-id] - [?rr :result-row/cells ?c] - - ;; Filter only input variables - [?ig :input-group/inputs ?i] - [?i :input/group-variable-uuid ?gv-uuid] - - ;; Get gv-uuid, value and units - [?rh :result-header/group-variable-uuid ?gv-uuid] - [?rh :result-header/units ?units] - [?c :result-cell/header ?rh] - [?c :result-cell/value ?value]] + {:type :query + :query '[:find ?gv-uuid ?value ?units + :in $ ?ws-uuid ?row-id + :where + [?ws :worksheet/uuid ?ws-uuid] + [?ws :worksheet/input-groups ?ig] + [?ws :worksheet/result-table ?t] + [?t :result-table/rows ?rr] + [?rr :result-row/id ?row-id] + [?rr :result-row/cells ?c] + + ;; Filter only input variables + [?ig :input-group/inputs ?i] + [?i :input/group-variable-uuid ?gv-uuid] + + ;; Get gv-uuid, value and units + [?rh :result-header/group-variable-uuid ?gv-uuid] + [?rh :result-header/units ?units] + [?c :result-cell/header ?rh] + [?c :result-cell/value ?value]] :variables [ws-uuid row-id]})) (rp/reg-sub :worksheet/output-gv-uuid+value+units (fn [_ [_ ws-uuid row-id]] - {:type :query - :query '[:find ?gv-uuid ?value ?units - :in $ ?ws-uuid ?row-id - :where - [?ws :worksheet/uuid ?ws-uuid] - [?ws :worksheet/outputs ?o] - [?ws :worksheet/result-table ?t] - [?t :result-table/rows ?rr] - [?rr :result-row/id ?row-id] - [?rr :result-row/cells ?c] - - ;; Filter only output variables - [?o :output/group-variable-uuid ?gv-uuid] - - ;; Get gv-uuid, value and units - [?rh :result-header/group-variable-uuid ?gv-uuid] - [?rh :result-header/units ?units] - [?c :result-cell/header ?rh] - [?c :result-cell/value ?value]] + {:type :query + :query '[:find ?gv-uuid ?value ?units + :in $ ?ws-uuid ?row-id + :where + [?ws :worksheet/uuid ?ws-uuid] + [?ws :worksheet/outputs ?o] + [?ws :worksheet/result-table ?t] + [?t :result-table/rows ?rr] + [?rr :result-row/id ?row-id] + [?rr :result-row/cells ?c] + + ;; Filter only output variables + [?o :output/group-variable-uuid ?gv-uuid] + + ;; Get gv-uuid, value and units + [?rh :result-header/group-variable-uuid ?gv-uuid] + [?rh :result-header/units ?units] + [?c :result-cell/header ?rh] + [?c :result-cell/value ?value]] :variables [ws-uuid row-id]})) (rf/reg-sub From c810255f90e12589db4f0a9ce052eb79055b0009 Mon Sep 17 00:00:00 2001 From: Kenneth Cheung Date: Tue, 17 Mar 2026 17:41:12 -0400 Subject: [PATCH 2/5] add some docs --- ...tion_variables_attr_to_group_variables.clj | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/development/migrations/2026_03_03_add_direction_variables_attr_to_group_variables.clj b/development/migrations/2026_03_03_add_direction_variables_attr_to_group_variables.clj index b20979a8..7498be52 100644 --- a/development/migrations/2026_03_03_add_direction_variables_attr_to_group_variables.clj +++ b/development/migrations/2026_03_03_add_direction_variables_attr_to_group_variables.clj @@ -10,11 +10,12 @@ ;; Overview ;; =========================================================================================================== -;; 1. create new group variables for the heading direciton of scorch height, tree crown length -;; scorched, and crown volume scorched -;; 2. Repurpose exisitng scorch height, tree crown length scorched, and crown volume scorched to be -;; like the ones for surface > rate of spread (i.e. this group variable does not compute anything -;; but is used as parent group variable that links to the 3 directional versions) +;; 1. Link Directional Versions of Group Variable to it's Parent +;; 2. Rename Translation keys +;; 3. Add new Group Variables +;; 4. Clean up Variables +;; 5. Add translations for the group variables with translation keys renamed from step 1. +;; 6. Fix Variables, missing bp/uuid and bp/nid ;; =========================================================================================================== ;; Initialize @@ -55,7 +56,7 @@ :group-variable/direction-variables (mapv #(gv-eid->translation-key (second %)) pairs)}))) ;; =========================================================================================================== -;; 3. Link Directional Versions of Group Variable to it's Parent +;; 1. Link Directional Versions of Group Variable to it's Parent ;; =========================================================================================================== #_{:clj-kondo/ignore [(:missing-docstring)]} @@ -81,9 +82,11 @@ (sm/t-key->eid conn "behaveplus:surface:output:size:surface___fire_size:flanking-spread-distance")]}]) ;; =========================================================================================================== -;; 1. Rename Translation keys +;; 2. Rename Translation keys ;; =========================================================================================================== +;; These group variables should have their keys updated for the heading direction. + #_{:clj-kondo/ignore [(:missing-docstring)]} (def t-keys-to-process ["behaveplus:mortality:output:tree_mortality:tree_mortality:probability_of_mortality" "behaveplus:mortality:output:tree_mortality:tree_mortality:bole_char_height" @@ -115,7 +118,7 @@ (map t-key->new-t-key-payload t-keys-to-process)) ;; =========================================================================================================== -;; 2. Add new Group Variables +;; 3. Add new Group Variables ;; =========================================================================================================== ;; Add new group variables that mimic the Surface > Fire Behavior (output) > Surface Fire > Rate of Spread @@ -206,9 +209,11 @@ :hide-result? true})]) ;; =========================================================================================================== -;; Clean up Variables +;; 4. Clean up Variables ;; =========================================================================================================== +;; These variables should no longer be in the system. + (def variables-to-clean [["Heading Rate of Spread" "Rate of Spread" "behaveplus:surface:output:fire_behavior:surface_fire:heading_rate_of_spread"] ["Backing Rate of Spread" "Rate of Spread" "behaveplus:surface:output:fire_behavior:surface_fire:backing_rate_of_spread"] @@ -239,12 +244,6 @@ [:db/add (sm/name->eid conn :variable/name new-var-name) :variable/group-variables (sm/t-key->eid conn t-key)]]) variables-to-clean)) -#_(d/q '[:find ?e - :in $ - :where [?v :variable/name "Bole Char Height Flanking" - ?v :variable/group-variables ?e]] - (d/db conn)) - (def add-missing-result-translation [{:db/id (sm/t-key->eid conn "behaveplus:surface:output:fire_behavior:surface_fire:flame_length") :group-variable/result-translation-key "behaveplus:surface:result:fire_behavior:surface_fire:flame_length"} @@ -254,7 +253,7 @@ :group-variable/result-translation-key "behaveplus:surface:result:fire_behavior:surface_fire:heading_fireline_intensity"}]) ;; =========================================================================================================== -;; Add translations for the group variables with translation keys renamed from step 1. +;; 5. Add translations for the group variables with translation keys renamed from step 1. ;; =========================================================================================================== #_{:clj-kondo/ignore [(:missing-docstring)]} @@ -278,9 +277,12 @@ update-translation-key-payload)))) ;; =========================================================================================================== -;; Fix Variables, missing bp/uuid and bp/nid +;; 6. Fix Variables, missing bp/uuid and bp/nid ;; =========================================================================================================== +;; These prevously created variables are missing some of the necessary attributes we need. It was not necessary before because the actual variables that were used +;; were (i.e. Heading Rate of Spread, Backing Rate of Spread, etc) which had this info. Now that we are deleting those variables, we need to add these backin. All directional group variables will point to the same variable now + (def fix-variable-missing-bp-uuid-payload [{:db/id (sm/name->eid conn :variable/name "Rate of Spread") :bp/uuid (str (squuid)) From 562bd98f756691e9a7a3e684673038098dc44159 Mon Sep 17 00:00:00 2001 From: Kenneth Cheung Date: Wed, 18 Mar 2026 12:59:54 -0400 Subject: [PATCH 3/5] fix table shading filter to round value before comparison --- .../behave/src/cljs/behave/components/results/matrices.cljs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/projects/behave/src/cljs/behave/components/results/matrices.cljs b/projects/behave/src/cljs/behave/components/results/matrices.cljs index 2c679311..7b0bc73c 100644 --- a/projects/behave/src/cljs/behave/components/results/matrices.cljs +++ b/projects/behave/src/cljs/behave/components/results/matrices.cljs @@ -2,6 +2,7 @@ (:require [behave.components.core :as c] [behave.translate :refer [ Date: Wed, 18 Mar 2026 13:29:14 -0400 Subject: [PATCH 4/5] sort graphs --- .../src/cljs/behave/worksheet/subs.cljs | 37 ++----------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/projects/behave/src/cljs/behave/worksheet/subs.cljs b/projects/behave/src/cljs/behave/worksheet/subs.cljs index 1f63cdfc..4cea58d9 100644 --- a/projects/behave/src/cljs/behave/worksheet/subs.cljs +++ b/projects/behave/src/cljs/behave/worksheet/subs.cljs @@ -561,7 +561,7 @@ (fn [[_ ws-uuid]] (rf/subscribe [:worksheet ws-uuid])) (fn [worksheet [_ ws-uuid]] - (->> (d/q '[:find ?uuid ?hide-result ?graph-result + (->> (d/q '[:find ?uuid ?hide-result ?graph-result ?order :in $ $ws % ?ws-uuid :where [$ws ?w :worksheet/uuid ?ws-uuid] @@ -570,11 +570,13 @@ [$ws ?o :output/enabled? true] (lookup ?uuid ?gv) [(get-else $ ?gv :group-variable/hide-result? false) ?hide-result] - [(get-else $ ?gv :group-variable/hide-graph? false) ?graph-result]] + [(get-else $ ?gv :group-variable/hide-graph? false) ?graph-result] + [$ ?gv :group-variable/order ?order]] @@vms-conn @@s/conn rules ws-uuid) + (sort-by last) (remove (fn [[_ hide-result? hide-graph?]] (or hide-result? hide-graph?))) (map first) (map (fn [gv-uuid] @(rf/subscribe [:vms/entity-from-uuid gv-uuid]))) @@ -677,37 +679,6 @@ [?y :x-axis-limit/max ?max]] :variables [ws-uuid]})) -(rf/reg-sub - :worksheet/directional-output-gv-uuids - (fn [_ [_ ws-uuid]] - (let [parent-gv->directional-gvs - (group-by first - (d/q '[:find ?parent-var-uuid ?uuid ?min ?max ?enabled - :in $ $ws % ?ws-uuid - :where - [$ws ?w :worksheet/uuid ?ws-uuid] - [$ws ?w :worksheet/outputs ?o] - [$ws ?o :output/group-variable-uuid ?uuid] - [$ws ?o :output/enabled? true] - (lookup ?uuid ?gv) - - [$ ?v :group-variable/direction-variables ?gv] - [$ ?v :bp/uuid ?parent-var-uuid] - - [$ws ?w :worksheet/table-settings ?ts] - [$ws ?ts :table-settings/filters ?tf] - [$ws ?tf :table-filter/group-variable-uuid ?uuid] - [$ws ?tf :table-filter/min ?min] - [$ws ?tf :table-filter/max ?max] - [$ws ?tf :table-filter/enabled? ?enabled]] - @@vms-conn @@s/conn rules ws-uuid))] - (doall (map (fn [[parent-gv directional-gvs]] - (let [mins (map #(nth % 2) directional-gvs) - maxs (map #(nth % 3) directional-gvs) - enabled? (map #(nth % 4) directional-gvs)] - [parent-gv (apply min mins) (apply max maxs) (every? true? enabled?)])) - parent-gv->directional-gvs))))) - (rp/reg-sub :worksheet/table-settings-filters (fn [_ [_ ws-uuid]] From 6f3385f29618a0567a61a83db4a9bc1d923e8724 Mon Sep 17 00:00:00 2001 From: Kenneth Cheung Date: Wed, 18 Mar 2026 14:55:28 -0400 Subject: [PATCH 5/5] refactor --- projects/behave/src/cljs/behave/worksheet/subs.cljs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/projects/behave/src/cljs/behave/worksheet/subs.cljs b/projects/behave/src/cljs/behave/worksheet/subs.cljs index 4cea58d9..059ebbfd 100644 --- a/projects/behave/src/cljs/behave/worksheet/subs.cljs +++ b/projects/behave/src/cljs/behave/worksheet/subs.cljs @@ -887,9 +887,7 @@ (reduce (fn [acc [_row-id gv-uuid _repeat-id value]] (if (contains? (set all-output-uuids) gv-uuid) - (let [parent-directional-gv (:bp/uuid (first (:group-variable/_direction-variables (d/pull @@vms-conn '[{:group-variable/_direction-variables - [:bp/uuid]}] - [:bp/uuid gv-uuid]))))] + (let [parent-directional-gv (:bp/uuid directional-parent-entity gv-uuid)] (cond-> (update acc gv-uuid (fn [[min-v max-v]] (let [min-float (js/parseFloat min-v) max-float (js/parseFloat max-v)