All angles now depend on the deflection function

This is preparatory to making the deflection function pluggable.
This commit is contained in:
simon 2017-07-11 16:46:35 +01:00
parent 3519807649
commit 6dca39ce91
2 changed files with 40 additions and 37 deletions

View file

@ -82,6 +82,7 @@
{:name :attr :required false :type "HTML attr map" {:name :attr :required false :type "HTML attr map"
:validate-fn html-attr? :description [:span "HTML attributes, like " [:code ":on-mouse-move"] [:br] "No " [:code ":class"] " or " [:code ":style"] "allowed"]}]) :validate-fn html-attr? :description [:span "HTML attributes, like " [:code ":on-mouse-move"] [:br] "No " [:code ":class"] " or " [:code ":style"] "allowed"]}])
(defn abs (defn abs
"Return the absolute value of the (numeric) argument." "Return the absolute value of the (numeric) argument."
[n] (max n (- n))) [n] (max n (- n)))
@ -90,21 +91,22 @@
;; from the left end of the scale to right end, in degrees. ;; from the left end of the scale to right end, in degrees.
(def full-scale-deflection 140) (def full-scale-deflection 140)
;; ultimately this should be resizeable, and radius should be a function of ;; ultimately this should be resizeable, and radius should be a function of
;; size... ;; size...
(def scale-radius 75) (def scale-radius 75)
(defn deflection (defn deflection
"Return the deflection of a needle given this `value` on the "Return the linear deflection of a needle given this `value` on the
range `min-value`...`max-value`." range `min-value`...`max-value`."
[value min-value max-value] [value min-value max-value]
(let [range (- max-value min-value) (let [range (- max-value min-value)
deflection (/ value range)
zero-offset (/ (- 0 min-value) range) zero-offset (/ (- 0 min-value) range)
limited (min (max (+ zero-offset deflection) 0) 1)] limited (min (max (+ zero-offset (/ value range)) 0) 1)]
(js/console.log (str "zero-offset: " zero-offset))
(* (- limited 0.5) full-scale-deflection))) (* (- limited 0.5) full-scale-deflection)))
(defn polar-to-cartesian (defn polar-to-cartesian
"Return, as a map with keys :x. :y, the cartesian coordinates at the point "Return, as a map with keys :x. :y, the cartesian coordinates at the point
`radius` distance at `theta` (degrees) angle from a point at `radius` distance at `theta` (degrees) angle from a point at
@ -115,6 +117,7 @@
{:x (+ cx (* radius (.cos js/Math in-radians))) {:x (+ cx (* radius (.cos js/Math in-radians)))
:y (+ cy (* radius (.sin js/Math in-radians)))})) :y (+ cy (* radius (.sin js/Math in-radians)))}))
(defn describe-arc (defn describe-arc
"Return as a string an SVG path definition describing an arc centred "Return as a string an SVG path definition describing an arc centred
at `cx`, cy` starting at `start-angle` and ending at `end-angle` (both at `cx`, cy` starting at `start-angle` and ending at `end-angle` (both
@ -141,18 +144,21 @@
"Return as a string an SVG path definition describing a radial stroke from a center "Return as a string an SVG path definition describing a radial stroke from a center
at `cx`, cy` starting at `min-radius` and extending to `max-radius`." at `cx`, cy` starting at `min-radius` and extending to `max-radius`."
[cx cy min-radius max-radius angle label] [cx cy min-radius max-radius angle label]
(let [:g {:class "snm-gradation"
[start (polar-to-cartesian cx cy min-radius angle) :transform (string/join " " ["rotate(" angle cx cy ")"])}
mid (polar-to-cartesian cx cy (+ min-radius [:path {:d (string/join
(* (- max-radius min-radius) 0.333)) " "
angle) ["M"
end (polar-to-cartesian cx cy max-radius angle)] cx
[:g {:class "snm-gradation"} (- cy
[:path {:d (string/join " " ["M" (:x mid) (:y mid) "L" (:x end) (:y end)])}] (+ min-radius
[:text {:text-anchor "middle" (* (- max-radius min-radius) 0.333)))
:x (:x start) "L"
:y (:y start) cx
:transform (string/join " " ["rotate(" angle (:x start) (:y start) ")"])} (as-label label)]])) (- cy max-radius)])}]
[:text {:text-anchor "middle"
:x cx
:y (- cy min-radius)} (as-label label)]])
(defn swinging-needle-meter (defn swinging-needle-meter
@ -178,12 +184,7 @@
{:pre [(validate-args-macro swinging-needle-args-desc args "swinging-needle")]} {:pre [(validate-args-macro swinging-needle-args-desc args "swinging-needle")]}
(let [model (deref-or-value model) (let [model (deref-or-value model)
setpoint (deref-or-value setpoint) setpoint (deref-or-value setpoint)
mid-point-deflection (/ full-scale-deflection 2) mid-point-deflection (/ full-scale-deflection 2)]
;; if warn-value is greater than max-value, we don't want a red-zone at all.
red-zone-deflection (if
(< warn-value max-value)
(* full-scale-deflection (/ warn-value max-value))
full-scale-deflection)]
[box [box
:align :start :align :start
:child [:div :child [:div
@ -197,9 +198,7 @@
{:width width :height height} {:width width :height height}
style)} style)}
attr) attr)
[:svg {:xmlns:svg "http://www.w3.org/2000/svg" [:svg {:xmlSpace "preserve"
:xmlns "http://www.w3.org/2000/svg"
:xml:space "preserve"
:overflow "visible" :overflow "visible"
:viewBox "0 0 180 120" :viewBox "0 0 180 120"
:y "0px" :y "0px"
@ -216,11 +215,14 @@
:class "snm-value"}[:tspan (str (as-label model) (if unit " ") unit)]] :class "snm-value"}[:tspan (str (as-label model) (if unit " ") unit)]]
[:path {:class scale-class [:path {:class scale-class
:id (str id "-scale") :id (str id "-scale")
:d (describe-arc 80 100 scale-radius (- 0 mid-point-deflection) mid-point-deflection)}] :d (describe-arc 80 100 scale-radius
(deflection min-value min-value max-value)
(deflection max-value min-value max-value))}]
[:path {:class redzone-class [:path {:class redzone-class
:id (str id "-redzone") :id (str id "-redzone")
:d (describe-arc 80 100 scale-radius (- red-zone-deflection mid-point-deflection) mid-point-deflection)}] :d (describe-arc 80 100 scale-radius
(deflection warn-value min-value max-value)
(deflection max-value min-value max-value))}]
[:path {:class cursor-class [:path {:class cursor-class
:id (str id "-cursor") :id (str id "-cursor")
:d "M 80,20 80,100" :d "M 80,20 80,100"
@ -230,15 +232,15 @@
:id (str id "-needle") :id (str id "-needle")
:d "M 80,20 80,100" :d "M 80,20 80,100"
:transform (str "rotate( " (deflection model min-value max-value) ", 80, 100)") }] :transform (str "rotate( " (deflection model min-value max-value) ", 80, 100)") }]
(apply vector (cons :g (map #(gradation 80 100 60 82 (apply vector (cons :g (map #(let
(- (* % [value (+ min-value
(/ full-scale-deflection gradations)) (*
mid-point-deflection) (/
(+ min-value (- max-value min-value)
(* gradations) %))]
(/ (gradation 80 100 60 82
(- max-value min-value) (deflection value min-value max-value)
gradations) %))) value))
(range 0 (+ gradations 1))))) (range 0 (+ gradations 1)))))
[:rect {:class frame-class [:rect {:class frame-class
:id (str id "-frame") :id (str id "-frame")

View file

@ -63,6 +63,7 @@
;; :max-value (aget js/Math "PI") ;; :max-value (aget js/Math "PI")
:tolerance 2 :tolerance 2
:alarm-class "snm-warning" :alarm-class "snm-warning"
:gradations 5
:width "350px"] :width "350px"]
[title :level :level3 :label "Parameters"] [title :level :level3 :label "Parameters"]
[h-box [h-box