Not so much of a branch, more a whole new project
This commit is contained in:
		
							parent
							
								
									985c91a72e
								
							
						
					
					
						commit
						3a1ae81f08
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -11,3 +11,5 @@ out | |||
| *.tgz | ||||
| 
 | ||||
| *.zip | ||||
| .lsp/ | ||||
| .clj-kondo/ | ||||
|  |  | |||
							
								
								
									
										1
									
								
								.lein-failures
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.lein-failures
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| {} | ||||
|  | @ -1,6 +1,6 @@ | |||
| # swingometer | ||||
| # radial-svg-graph | ||||
| 
 | ||||
| A [re-frame](https://github.com/Day8/re-frame) application designed to show votes in an election. | ||||
| A [re-frame](https://github.com/Day8/re-frame) application designed to show a radial SVG graph, possibly with several rings. | ||||
| 
 | ||||
| ## Development Mode | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										76
									
								
								project.clj
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								project.clj
									
									
									
									
									
								
							|  | @ -1,11 +1,17 @@ | |||
| (defproject swingometer "0.1.0-SNAPSHOT" | ||||
|   :dependencies [[org.clojure/clojure "1.8.0"] | ||||
|                  [org.clojure/clojurescript "1.9.229"] | ||||
|                  [reagent "0.6.0"] | ||||
|                  [re-frame "0.9.4"] | ||||
|                  [re-com "2.0.0"]] | ||||
| (defproject rsvggraph "0.1.0-SNAPSHOT" | ||||
|   :dependencies [[clojure2d "1.4.5"] ;; (mainly) for colours | ||||
|                  [generateme/fastmath "2.4.0"] | ||||
|                  [hiccup "2.0.0-RC3"] | ||||
|                  [javax.xml.bind/jaxb-api "2.4.0-b180830.0359"] | ||||
|                  [org.clojure/clojure "1.8.0"] | ||||
|                 ;;  [org.clojure/clojurescript "1.9.229"] | ||||
|                 ;;  [org.omcljs/om "1.0.0-beta1"] | ||||
|                 ;;  [reagent "0.6.0"] | ||||
|                 ;;  [re-frame "0.9.4"] | ||||
|                 ;;  [re-com "2.0.0"] | ||||
|                  ] | ||||
| 
 | ||||
|   :plugins [[lein-cljsbuild "1.1.4"]] | ||||
|   ;; :plugins [[lein-cljsbuild "1.1.4"]] | ||||
| 
 | ||||
|   :min-lein-version "2.5.3" | ||||
| 
 | ||||
|  | @ -15,36 +21,32 @@ | |||
| 
 | ||||
|   :figwheel {:css-dirs ["resources/public/css"]} | ||||
| 
 | ||||
|   :profiles | ||||
|   {:dev | ||||
|    {:dependencies [[binaryage/devtools "0.8.2"]] | ||||
|   ;; :profiles | ||||
|   ;; {:dev | ||||
|   ;;  {:dependencies [[binaryage/devtools "0.8.2"]] | ||||
| 
 | ||||
|     :plugins      [[lein-figwheel "0.5.9"]] | ||||
|     }} | ||||
|   ;;   :plugins      [[lein-figwheel "0.5.9"]] | ||||
|   ;;   }} | ||||
| 
 | ||||
|   :cljsbuild | ||||
|   {:builds | ||||
|    [{:id           "dev" | ||||
|      :source-paths ["src/cljs"] | ||||
|      :figwheel     {:on-jsload "swingometer.core/mount-root"} | ||||
|      :compiler     {:main                 swingometer.core | ||||
|                     :output-to            "resources/public/js/compiled/app.js" | ||||
|                     :output-dir           "resources/public/js/compiled/out" | ||||
|                     :asset-path           "js/compiled/out" | ||||
|                     :source-map-timestamp true | ||||
|                     :preloads             [devtools.preload] | ||||
|                     :external-config      {:devtools/config {:features-to-install :all}} | ||||
|                     }} | ||||
|   ;; :cljsbuild | ||||
|   ;; {:builds | ||||
|   ;;  [{:id           "dev" | ||||
|   ;;    :source-paths ["src/cljs"] | ||||
|   ;;    :figwheel     {:on-jsload "rsvggraph.core/mount-root"} | ||||
|   ;;    :compiler     {:main                 rsvggraph.core | ||||
|   ;;                   :output-to            "resources/public/js/compiled/app.js" | ||||
|   ;;                   :output-dir           "resources/public/js/compiled/out" | ||||
|   ;;                   :asset-path           "js/compiled/out" | ||||
|   ;;                   :source-map-timestamp true | ||||
|   ;;                   :preloads             [devtools.preload] | ||||
|   ;;                   :external-config      {:devtools/config {:features-to-install :all}} | ||||
|   ;;                   }} | ||||
| 
 | ||||
|     {:id           "min" | ||||
|      :source-paths ["src/cljs"] | ||||
|      :compiler     {:main            swingometer.core | ||||
|                     :output-to       "resources/public/js/compiled/app.js" | ||||
|                     :optimizations   :advanced | ||||
|                     :closure-defines {goog.DEBUG false} | ||||
|                     :pretty-print    false}} | ||||
| 
 | ||||
| 
 | ||||
|     ]} | ||||
| 
 | ||||
|   ) | ||||
|   ;;   {:id           "min" | ||||
|   ;;    :source-paths ["src/cljs"] | ||||
|   ;;    :compiler     {:main            rsvggraph.core | ||||
|   ;;                   :output-to       "resources/public/js/compiled/app.js" | ||||
|   ;;                   :optimizations   :advanced | ||||
|   ;;                   :closure-defines {goog.DEBUG false} | ||||
|   ;;                   :pretty-print    false}}]}) | ||||
| ) | ||||
|  |  | |||
|  | @ -1,70 +1,73 @@ | |||
| /***************************************************************************\ | ||||
|  *                                                                         * | ||||
|  *      swinging-needle-meter.css                                          * | ||||
|  *      rsvggraph.css                                                      * | ||||
|  *                                                                         * | ||||
|  *      CSS styling for the swinging needle meter itself.                  * | ||||
|  *      CSS styling for the radial svg graph itself.                       * | ||||
|  *                                                                         * | ||||
| \***************************************************************************/ | ||||
| 
 | ||||
| .snm-cursor { | ||||
| svg { | ||||
| 	border: thin solid gray; | ||||
| 	object-fit: contain; | ||||
| } | ||||
| 
 | ||||
| .rsvggraph-cursor { | ||||
| 	stroke:#ff8500; | ||||
| 	stroke-width: 3%; | ||||
| 	stroke-opacity: 0.5; | ||||
| } | ||||
| 
 | ||||
| .snm-frame { | ||||
| .rsvggraph-frame { | ||||
| 	fill: none; | ||||
| 	stroke-width: 5%; | ||||
| 	stroke-linejoin: round; | ||||
| 	stroke: #444444; | ||||
| 	stroke: none; | ||||
| } | ||||
| 
 | ||||
| .snm-gradation path { | ||||
| .rsvggraph-gradation path { | ||||
|   stroke: black; | ||||
|   stroke-width: 1; | ||||
| } | ||||
| 
 | ||||
| .snm-gradation text { | ||||
| .rsvggraph-gradation text { | ||||
|   font-size: 200%; | ||||
|   font-weight: lighter; | ||||
| } | ||||
| 
 | ||||
| .snm-hub { | ||||
| .rsvggraph-hub { | ||||
| 	fill: #444444; | ||||
| } | ||||
| 
 | ||||
| .snm-meter { | ||||
| .rsvggraph-graph { | ||||
| 	height: 50%; | ||||
| 	width: auto; | ||||
| } | ||||
| 
 | ||||
| .snm-needle { | ||||
| .rsvggraph-needle { | ||||
| 	stroke: black; | ||||
| 	stroke-width: 1; | ||||
| } | ||||
| 
 | ||||
| .snm-redzone { | ||||
| .rsvggraph-redzone { | ||||
| 	fill:none; | ||||
| 	stroke: maroon; | ||||
| 	stroke-width: 10%; | ||||
| } | ||||
| 
 | ||||
| .snm-scale { | ||||
| .rsvggraph-scale { | ||||
| 	fill: none; | ||||
| 	stroke: silver; | ||||
| 	stroke-width: 10%; | ||||
| } | ||||
| 
 | ||||
| .snm-target .snm-frame { | ||||
| .rsvggraph-target .rsvggraph-frame { | ||||
|   stroke: green; | ||||
| } | ||||
| 
 | ||||
| .snm-value { | ||||
| .rsvggraph-value { | ||||
|   font-size: 400%; | ||||
|   font-weight: bold; | ||||
|   text-align: center; | ||||
| } | ||||
| 
 | ||||
| .snm-warning .snm-frame { | ||||
| .rsvggraph-warning .rsvggraph-frame { | ||||
|   stroke: maroon; | ||||
| } | ||||
|  | @ -5,16 +5,16 @@ | |||
|     <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css"> | ||||
|     <link rel="stylesheet" href="vendor/css/material-design-iconic-font.min.css"> | ||||
|     <link rel="stylesheet" href="css/re-com.css"> | ||||
|     <link rel="stylesheet" href="css/swingometer.css"> | ||||
|     <link rel="stylesheet" href="css/rsvggraph.css"> | ||||
|     <link href="http://fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic" rel="stylesheet" type="text/css"> | ||||
|     <link href="http://fonts.googleapis.com/css?family=Roboto+Condensed:400,300" rel="stylesheet" type="text/css"> | ||||
| 
 | ||||
| 
 | ||||
|     <title>Example swingometer following re-com conventions.</title> | ||||
|     <title>Example rsvggraph following re-com conventions.</title> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div id="app"></div> | ||||
|     <script src="js/compiled/app.js"></script> | ||||
|     <script>swingometer.core.init();</script> | ||||
|     <script>rsvggraph.core.init();</script> | ||||
|   </body> | ||||
| </html> | ||||
|  |  | |||
							
								
								
									
										40
									
								
								resources/public/sample-data.edn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								resources/public/sample-data.edn
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | |||
| {:id "ge2024" | ||||
|  :label "UK General Election 2024" | ||||
|  :children [{:id "no-show" | ||||
|              :label "Did not vote" | ||||
|              :magnitude 18365357} | ||||
|             {:id "voted" | ||||
|              :label "Voted" | ||||
|              :children [{:id "reform" | ||||
|                          :label "Reform UK Ltd." | ||||
|                          :magnitude 4091549} | ||||
|                         {:id "greenew" | ||||
|                          :label "Green Party of England and Wales" | ||||
|                          :magnitude 1939502} | ||||
|                         {:id "pc" | ||||
|                          :label "Plaid Cymru" | ||||
|                          :magnitude 194811} | ||||
|                         {:id "sf" | ||||
|                          :label "Sinn Féin" | ||||
|                          :magnitude 210891} | ||||
|                         {:id "ld" | ||||
|                          :label "Liberal Democrats" | ||||
|                          :magnitude 3499933} | ||||
|                         {:id "labour" | ||||
|                          :label "Labour" | ||||
|                          :magnitude 9712011} | ||||
|                         {:id "apni" | ||||
|                          :label "Alliance Party" | ||||
|                          :magnitude 117191} | ||||
|                         {:id "sdlp" | ||||
|                          :label "Social Democratic and Labour Party" | ||||
|                          :magnitude 86861} | ||||
|                         {:id "dup" | ||||
|                          :label "Democratic Unionist Party" | ||||
|                          :magnitude 172058} | ||||
|                         {:id "snp" | ||||
|                          :label "Scottish National Party" | ||||
|                          :magnitude 708759} | ||||
|                         {:id "con" | ||||
|                          :label "Conservative" | ||||
|                          :magnitude 6814469}]}]} | ||||
							
								
								
									
										1
									
								
								src/clj/rsvggraph/core.clj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/clj/rsvggraph/core.clj
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| (ns rsvggraph.core) | ||||
							
								
								
									
										29
									
								
								src/clj/rsvggraph/data.clj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/clj/rsvggraph/data.clj
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| (ns rsvggraph.data | ||||
|   "Normalise data for use in generating radial graphs." | ||||
|   (:require [clojure2d.color :refer [gradient]])) | ||||
| 
 | ||||
| 
 | ||||
| (def ;; ^:dynamic  | ||||
|   *gradient* | ||||
|   "The gradient to use to automatically assign pleasing colours to sectors, if | ||||
|    no colours are defined in the data. Suitable gradients are defined  | ||||
|    [here](https://clojure2d.github.io/clojure2d/docs/static/gradients/)." | ||||
|   :rainbow2) | ||||
| 
 | ||||
| (def children-fn | ||||
|   "Basic (overridable) children function; assumes `data` is a map, and returns  | ||||
|    the value of the `:children` key within that map." | ||||
|   (memoize (fn [data] | ||||
|              (:children data)))) | ||||
| 
 | ||||
| (def quantity-fn | ||||
|   "Basic (overridable) children function; assumes `data` is a map. If the value | ||||
|    of the `:children` key within that map is a sequence, sums the result of  | ||||
|    mapping itself over that sequence. Otherwise, returns the value of the  | ||||
|    `:quantity` key, if present and a number, or `1` as a final default." | ||||
|   (memoize (fn [data] | ||||
|              (let [c (children-fn data) | ||||
|                    q (:quantity data)] | ||||
|                (cond (coll? c) (reduce + 0 (map quantity-fn c)) | ||||
|                      (number? q) q | ||||
|                      :else 1))))) | ||||
|  | @ -1 +0,0 @@ | |||
| (ns swingometer.core) | ||||
|  | @ -1,4 +1,4 @@ | |||
| (ns swingometer.config) | ||||
| (ns rsvggraph.config) | ||||
| 
 | ||||
| (def debug? | ||||
|   ^boolean goog.DEBUG) | ||||
|  | @ -1,10 +1,10 @@ | |||
| (ns swingometer.core | ||||
| (ns rsvggraph.core | ||||
|   (:require [reagent.core :as reagent] | ||||
|             [re-frame.core :as re-frame] | ||||
|             [swingometer.events] | ||||
|             [swingometer.subs] | ||||
|             [swingometer.views :as views] | ||||
|             [swingometer.config :as config])) | ||||
|             [rsvggraph.events] | ||||
|             [rsvggraph.subs] | ||||
|             [rsvggraph.views :as views] | ||||
|             [rsvggraph.config :as config])) | ||||
| 
 | ||||
| 
 | ||||
| (defn dev-setup [] | ||||
|  | @ -1,4 +1,4 @@ | |||
| (ns swingometer.db) | ||||
| (ns rsvggraph.db) | ||||
| 
 | ||||
| (def default-db | ||||
|   {:name "re-frame"}) | ||||
|  | @ -1,6 +1,6 @@ | |||
| (ns swingometer.events | ||||
| (ns rsvggraph.events | ||||
|   (:require [re-frame.core :as re-frame] | ||||
|             [swingometer.db :as db])) | ||||
|             [rsvggraph.db :as db])) | ||||
| 
 | ||||
| (re-frame/reg-event-db | ||||
|  :initialize-db | ||||
|  | @ -1,14 +1,13 @@ | |||
| (ns swingometer.swingometer | ||||
| (ns rsvggraph.rsvggraph | ||||
|   (:require [clojure.string :as string] | ||||
|             [re-com.core     :refer [h-box v-box box gap line label title slider checkbox p]] | ||||
|             [re-com.box      :refer [flex-child-style]] | ||||
|             [re-com.util     :refer [deref-or-value]] | ||||
|             [re-com.validate :refer [number-or-string? css-style? html-attr? validate-args-macro]] | ||||
|             [reagent.core    :as    reagent])) | ||||
|             [re-com.validate :refer [number-or-string? css-style? html-attr? validate-args-macro]])) | ||||
| 
 | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;;;; | ||||
| ;;;; swingometer: an experiment in animating SVG from re-frame. | ||||
| ;;;; rsvggraph: an experiment in animating SVG from re-frame. | ||||
| ;;;; Draws heavily on re-com.. | ||||
| ;;;; | ||||
| ;;;; This program is free software; you can redistribute it and/or | ||||
|  | @ -31,12 +30,12 @@ | |||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| 
 | ||||
| ;; ------------------------------------------------------------------------------------ | ||||
| ;;  Component: swingometer | ||||
| ;;  Component: rsvggraph | ||||
| ;; ------------------------------------------------------------------------------------ | ||||
| 
 | ||||
| ;;; It seems the defaults given here are just documentation; the defaults | ||||
| ;;; that are actually used are those given in the :or clause of the argument map. | ||||
| (def swingometer-args-desc | ||||
| (def rsvggraph-args-desc | ||||
|   [{:name :model         :required true  :type "map | atom" | ||||
|     :validate-fn map? :description "A map mapping keys to maps of the following structure: {:id :snp :name \"Scottish National Party\" :colour \"yellow\" :votes 1234}"} | ||||
|    {:name :width         :required false :type "integer"                 :default "300" | ||||
|  | @ -45,12 +44,12 @@ | |||
|     :validate-fn integer?          :description "a CSS height"} | ||||
|    {:name :class         :required false :type "string" | ||||
|     :validate-fn string?           :description "CSS class names, space separated, for the top-level SVG element"} | ||||
|    {:name :frame-class   :required false :type "string"                 :default "snm-frame" | ||||
|    {:name :frame-class   :required false :type "string"                 :default "rsvggraph-frame" | ||||
|     :validate-fn string?           :description "CSS class names, space separated, for the frame"} | ||||
|    {:name :scale-class   :required false :type "string"                 :default "snm-scale" | ||||
|    {:name :scale-class   :required false :type "string"                 :default "rsvggraph-scale" | ||||
|     :validate-fn string?           :description "CSS class names, space separated, for the scale"} | ||||
|    {:name :id            :required false :type "string"                 :default "meter" | ||||
|     :validate-fn string?           :description "Element id for this instance of the meter"} | ||||
|    {:name :id            :required false :type "string"                 :default "graph" | ||||
|     :validate-fn string?           :description "Element id for this instance of the graph"} | ||||
|    {:name :gradations    :reduired false :type "integer"                :default 5 | ||||
|     :validate-fn integer?          :description "Number of gradations to show on the scale, not counting the point."} | ||||
|    {:name :style         :required false :type "CSS style map" | ||||
|  | @ -59,9 +58,9 @@ | |||
|     :validate-fn html-attr?        :description [:span "HTML attributes, like " [:code ":on-mouse-move"] [:br] "No " [:code ":class"] " or " [:code ":style"] "allowed"]}]) | ||||
| 
 | ||||
| 
 | ||||
| ;; the constant 140 represents the full sweep of the needle | ||||
| ;; from the left end of the scale to right end, in degrees. | ||||
| (def full-scale-deflection 140) | ||||
| (def full-scale-deflection | ||||
|   "the full sweep of the needle from the left end of the scale to right end, in degrees." | ||||
|   360) | ||||
| 
 | ||||
| 
 | ||||
| (defn deflection | ||||
|  | @ -112,7 +111,7 @@ | |||
|   at `cx`, cy` starting at `min-radius` and extending to `max-radius`, with the specified | ||||
|   `label`." | ||||
|   [cx cy min-radius max-radius angle label] | ||||
|   [:g {:class "snm-gradation" | ||||
|   [:g {:class "rsvggraph-gradation" | ||||
|        :transform (string/join " " ["rotate(" angle cx cy ")"])} | ||||
|    [:path {:d (string/join | ||||
|                 " " | ||||
|  | @ -157,63 +156,68 @@ | |||
|           others (recursively-draw-segments (rest still-to-do) (cons party done) total-votes cx cy radius) | ||||
|           vote-share (* (/ (:votes party) total-votes) 100)] | ||||
|       (if (> vote-share 1) | ||||
|         (cons [:g [:path {:class "snm-scale" | ||||
|         (cons [:g [:path {:class "rsvggraph-scale" | ||||
|                           :id (str (:id party) "-segment") | ||||
|                           :style {:stroke (:colour party)} | ||||
|                           :d (describe-arc cx cy radius start-angle end-angle)}] | ||||
|                (gradation cx cy (* radius 0.8) (* radius 1.1) start-angle | ||||
|                           (str | ||||
|                             (if (> vote-share 5) (name (:id party)) "") | ||||
|                             (if (> vote-share 10) (str " " (as-label vote-share) "%"))))] | ||||
|                             (when (> vote-share 5) (name (:id party)) "") | ||||
|                             (when (> vote-share 10) (str " " (as-label vote-share) "%"))))] | ||||
|               others) | ||||
|         others)))) | ||||
| 
 | ||||
| 
 | ||||
| (defn swingometer | ||||
|   "Render an SVG swinging needle meter" | ||||
| (defn rsvggraph | ||||
|   "Render an SVG radial graph. The idea here is there is a stack of rings, | ||||
|    each with zero or more segments. Each ring has an inner diameter and an  | ||||
|    outer diameter, each of which is expressed as a number in the range 0...1, | ||||
|    representing a fraction of the overall dimension of the graph.  | ||||
|     | ||||
|    The rings are drawn in ascending order of inner diameter. | ||||
|     | ||||
|    Each segment has a label and a magnitude" | ||||
|   [& {:keys [model width height class scale-class frame-class id style attr] | ||||
|       :or   {width          300 | ||||
|              height         200 | ||||
|              scale-class    "snm-scale" | ||||
|              frame-class    "snm-frame" | ||||
|              id "meter"} | ||||
|              height         300 | ||||
|              scale-class    "rsvggraph-scale" | ||||
|              frame-class    "rsvggraph-frame" | ||||
|              id "graph"} | ||||
|       :as   args}] | ||||
|   {:pre [(validate-args-macro swingometer-args-desc args "swingometer")]} | ||||
|   {:pre [(validate-args-macro rsvggraph-args-desc args "rsvggraph")]} | ||||
|   (let [model (deref-or-value model) | ||||
|         mid-point-deflection (/ full-scale-deflection 2) | ||||
|         cx (/ width 2) | ||||
|         cy (* height 0.90) | ||||
|         needle-length (* height 0.75) | ||||
|         scale-radius (* height 0.7) | ||||
|         gradation-inner (* height 0.55) | ||||
|         gradations 5 | ||||
|         dimension (min width height) | ||||
|         cx (/ dimension 2) | ||||
|         cy (* dimension 0.50) | ||||
|         scale-radius (* dimension 0.45) | ||||
|         total-votes (reduce + (map #(:votes %) (vals model)))] | ||||
|     [box | ||||
|      :align :start | ||||
|      :child [:div | ||||
|              (merge | ||||
|                {:class (str "swingometer  " class) | ||||
|                {:class (str "rsvggraph  " class) | ||||
|                 :style (merge (flex-child-style "none") | ||||
|                               {:width width :height height} | ||||
|                               {:width dimension :height dimension} | ||||
|                               style)} | ||||
|                attr) | ||||
|              [:svg {:xmlSpace "preserve" | ||||
|                     :overflow "visible" | ||||
|                     :viewBox (string/join " " [0 0 width height]) | ||||
|                     :width (str width "px") | ||||
|                     :height (str height "px") | ||||
|                     :viewBox (string/join " " [0 0 dimension dimension]) | ||||
|                     :width (str dimension "px") | ||||
|                     :height (str dimension "px") | ||||
|                     :y "0px" | ||||
|                     :x "0px" | ||||
|                     :version "1.1" | ||||
|                     :id id | ||||
|                     :class (str "snm-meter " class)} | ||||
|                     :class (str "rsvggraph-graph " class)} | ||||
|                             [:text | ||||
|                {:text-anchor "middle" | ||||
|                 :x (/ width 2) | ||||
|                 :y (/ height 2) | ||||
|                 :width "100" | ||||
|                 :x (/ dimension 2) | ||||
|                 :y (/ dimension 2) | ||||
|                 :width (/ dimension 4) | ||||
|                 :id (str id "-total-votes") | ||||
|                 :class "snm-value"}[:tspan (reduce + (map :votes (vals model)))]] | ||||
|                 :class "rsvggraph-value"}[:tspan (reduce + (map :votes (vals model)))]] | ||||
|               [:path {:class scale-class | ||||
|                       :id (str id "-scale") | ||||
|                       :d (describe-arc cx cy scale-radius | ||||
|  | @ -1,4 +1,4 @@ | |||
| (ns swingometer.subs | ||||
| (ns rsvggraph.subs | ||||
|   (:require-macros [reagent.ratom :refer [reaction]]) | ||||
|   (:require [re-frame.core :as re-frame])) | ||||
| 
 | ||||
|  | @ -1,4 +1,4 @@ | |||
| (ns swingometer.utils | ||||
| (ns rsvggraph.utils | ||||
|   (:require [re-com.core :refer [h-box v-box box gap title line label hyperlink-href align-style]])) | ||||
| 
 | ||||
| ;;;; This file is just stolen wholesale from re-demo in the re-com package; | ||||
|  | @ -1,12 +1,12 @@ | |||
| (ns swingometer.views | ||||
| (ns rsvggraph.views | ||||
|   (:require [re-frame.core :as    re-frame] | ||||
|             [re-com.core   :refer [h-box v-box box gap line label title progress-bar slider checkbox p single-dropdown]] | ||||
|             [re-com.util   :refer [deref-or-value]] | ||||
|             [swingometer.swingometer :refer [swingometer  swingometer-args-desc]] | ||||
|             [swingometer.utils   :refer [panel-title title2 args-table github-hyperlink status-text]] | ||||
|             [rsvggraph.rsvggraph :refer [rsvggraph  rsvggraph-args-desc]] | ||||
|             [rsvggraph.utils   :refer [panel-title title2 args-table github-hyperlink status-text]] | ||||
|             [reagent.core  :as    reagent])) | ||||
| 
 | ||||
| (defn swingometer-demo | ||||
| (defn rsvggraph-demo | ||||
|   [] | ||||
|   (let [model (reagent/atom {:snp {:id :snp :name "Scottish National Party" :colour "yellow" :votes 10} | ||||
|                              :lab {:id :lab :name "Labour Party" :colour "red" :votes 10} | ||||
|  | @ -19,7 +19,7 @@ | |||
|       [v-box | ||||
|        :size     "auto" | ||||
|        :gap      "10px" | ||||
|        :children [[panel-title "Swingometer"] | ||||
|        :children [[panel-title "rsvggraph"] | ||||
|                   [h-box | ||||
|                    :gap      "100px" | ||||
|                    :children [[v-box | ||||
|  | @ -27,21 +27,21 @@ | |||
|                                :width    "450px" | ||||
|                                :children [[title2 "Notes"] | ||||
|                                           [status-text "Wildly experimental"] | ||||
|                                           [p "An SVG swingometer intended to be useful in elections."] | ||||
|                                           [p "An SVG rsvggraph intended to be useful in elections."] | ||||
| 
 | ||||
|                                           [title2 "Behaviour"] | ||||
| 
 | ||||
| 
 | ||||
|                                           [args-table swingometer-args-desc]]] | ||||
|                                           [args-table rsvggraph-args-desc]]] | ||||
|                               [v-box | ||||
|                                :gap      "10px" | ||||
|                                :children [[title2 "Demo"] | ||||
|                                           [v-box | ||||
|                                            :gap      "20px" | ||||
|                                            :children [[swingometer | ||||
|                                            :children [[rsvggraph | ||||
|                                                        :model     model | ||||
|                                                        :height    600 | ||||
|                                                        :width     1000] | ||||
|                                                        :height    500 | ||||
|                                                        :width     500] | ||||
|                                                       [title :level :level3 :label "Parameters"] | ||||
|                                                       [h-box | ||||
|                                                        :gap "10px" | ||||
|  | @ -127,11 +127,11 @@ | |||
| ;; core holds a reference to panel, so need one level of indirection to get figwheel updates | ||||
| (defn panel | ||||
|   [] | ||||
|   [swingometer-demo]) | ||||
|   [rsvggraph-demo]) | ||||
| 
 | ||||
| 
 | ||||
| (defn main-panel [] | ||||
|   (fn [] | ||||
|     [v-box | ||||
|      :height "100%" | ||||
|      :children [[swingometer-demo]]])) | ||||
|      :children [[rsvggraph-demo]]])) | ||||
		Loading…
	
		Reference in a new issue