Skip to content

Instantly share code, notes, and snippets.

Created August 6, 2021 06:10
What would you like to do?
(ns adamdavislee.c964.core
(:require [rum.core :as rum]
[garden.core :refer [css]]
[clojure.string :as str]
[clojure.edn :refer [read-string]]))
(defonce ratom (atom {}))
(def swatch ["#cad2c5" "#84a98c" "#52796f" "#354f52" "#2f3e46"])
(def main-stylesheet
[:body {:background-color (swatch 3)
:animation "cool 2s infinite"
:height "100%"
:margin "0px"
:font-family "Source Sans Pro"
:box-sizing "border-box"}]
[:#app {:height "100vh"}]
[:#root {:height "100vh"}]
[:#titlebar-holder {:display "flex"
:position "fixed"
:width "96vw"
:top "4vh"
:right "0"
:justify-content "center"}]
[:#titlebar {:height "3em"
:width "40em"
:display "flex"
:align-items "center"
:justify-content "center"
:background-color (swatch 1)
:border-radius "20px"}]
[:#title {:font-size "2em"
:font-weight "1000"
:color (swatch 2)}]
[:#navbar {:width "100vh"
:height "4vw"
:display "flex"
:position "fixed"
:bottom "0"
:transform-origin "0 100%"
:transform "rotate(-0.25turn) translateY(4vw)"
:align-items "center"
:justify-content "space-around"
:background-color (swatch 2)}]
[:.navbar-child {:font-size "1.2em"
:background-color (swatch 1)
:color (swatch 2)
:max-height "3ex"
:display "inline-block"
:border "none"
:padding "5px 2em"
:border-radius "20px"
:transition "all 1000ms ease"}]
[:.navbar-child:hover {:transform "scale(1.125)"}]
[:.navbar-child:active {:transform "scale(0.875)"}]
[:#charts {:width "96vw"
:height "90vh"
:position "fixed"
:right "0"
:bottom "0"
:display "flex"
:align-items "center"
:justify-content "center"}]
[:.chart-title {:color (swatch 2)
:padding "0 0 1em 0"
:font-size "1.5em"
:font-weight "800"}]
[:img {:border-radius "20px"}]
[:.chart-box {:display "flex"
:flex-direction "column"
:align-items "center"
:background-color (swatch 1)
:padding "1em"
:border-radius "25px"
:margin "0 1em"}]
[ {:transform "translateY(3em)"}]
[:#prediction-box {:height "fit-content"}]
[:.juxt-charts {:display "flex"}]
[:.grand-prediction {:color (swatch 0)
:font-weight "1000"
:font-size "2.5em"}]
[:.juxt-box {:display "flex"
:flex-flow "column"
:align-items "center"
:transform "scale(0.75)"}]
[:#interactive-line {:font-weight "800"
:font-size "2em"
:color (swatch 2)
:background-color (swatch 1)
:padding "0.2em 1em"
:border-radius "20px"
:margin-bottom "1em"}]
[:.dropdown {:text-transform "uppercase"
:font-size "100%"
:background "transparent"
:border-style "none"
:padding-left "1em"}]
["::placeholder" {:color (swatch 0)
:opacity "0.5"}]
[:.dropdown:hover {:color (swatch 0)}]
[:.pulse {:animation "pulse 2s infinite alternate"
:transition "all 1000ms ease"}]
[:.pulse:hover {:border [[:5px :solid (swatch 0)]]}]
[:.pulse:active {:border [[:10px :solid (swatch 0)]]}]
[:.clickable {:text-decoration "underline"
:color (swatch 0)}]))
(defn verify-input []
(let [prediction-box (.. js/document (getElementById "prediction-box"))
prediction-title (.. js/document (getElementById "prediction-title"))]
(every? identity
(for [id ["state" "month" "year"]]
(let [value (.. js/document (getElementById id) -value)
states #{"WA" "CA"}
months #{"JAN" "FEB"}]
(case id
"state" (states (str/upper-case value))
"month" (months (str/upper-case value))
"year" (< 2015 (read-string value) 2022)))))
(do (.. prediction-box -classList (add "pulse"))
#_(.. prediction-title -classList (add "clickable")))
(do (.. prediction-box -classList (remove "pulse"))
#_(.. prediction-title -classList (remove "clickable"))))))
(defn restrict-chars-and-verify [regex]
(fn [e]
(set! (.. e -target -value)
(apply str (filter #(re-matches regex %)
(.. e -target -value))))
(def prevalence-by-year-view [:#charts [:.chart-box [:.chart-title "The number of fires reported in each year"]
[:img {:src "histogram.png"}]]])
(def prevalence-by-state-view [:#charts [:.chart-box [:.chart-title "The number of fires reported in each state"]
[:img {:src "pie-chart.png"}]]])
(def prediction-view [:#charts [:.juxt-box [:#interactive-line
[:span "Estimate the number of "]
[:input#state.dropdown.clickable {:placeholder "WA"
:type "text"
:size "2"
:max-length "2"
:on-change (restrict-chars-and-verify #"[a-zA-Z]")}]
[:span " fires in "]
[:input#month.dropdown.clickable {:placeholder "JAN"
:type "text"
:size "3"
:max-length "3"
:on-change (restrict-chars-and-verify #"[a-zA-Z]")}]
[:span " of "]
[:input#year.dropdown.clickable {:placeholder "2021"
:type "text"
:size "4"
:max-length "4"
:on-change (restrict-chars-and-verify #"\d")}]]
[:.chart-box [:.chart-title "The requested data w/o regression"] [:img {:src "main-without-line.png"}]]
[:.chart-box [:.chart-title "The requested data w/ regression"] [:img {:src "main.png"}]]
[:#prediction-box.chart-box [:#prediction-title.chart-title "Prediction"] [:.grand-prediction "450.37"]]]]])
(defonce charts-view (atom [:#charts]))
(defn change-view [button-id view]
(fn [_]
(reset! charts-view view)
(.. js/document (getElementById button-id) (classList/add "active-nav-section"))
(dorun (map (fn [a] (.. js/document (getElementById a) (classList/remove "active-nav-section")))
(filter #(not= % button-id) ["button-1" "button-2" "button-3"])))))
(rum/defc root < rum/reactive []
[:style "@import url('');"]
[:style main-stylesheet]
[:style "@keyframes pulse { from { transform: scale(1) } to { transform: scale(1.125) }}"]
[:#titlebar-holder [:#titlebar [:#title "US Wildfire Analysis and Prediction"]]]
[:button#button-1.navbar-child {:on-click (change-view "button-1" prediction-view)} "Prediction"]
[:button#button-2.navbar-child {:on-click (change-view "button-2" prevalence-by-state-view)} "Prevalence by State"]
[:button#button-3.navbar-child {:on-click (change-view "button-3" prevalence-by-year-view)} "Prevalence by Year"]]
(rum/react charts-view)])
(rum/mount (root)
(. js/document (getElementById "app")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment