0 | module CyBy.Draw.PeriodicTableCanvas
3 | import CyBy.Draw.Internal.CoreDims
4 | import CyBy.Draw.Draw
5 | import CyBy.Draw.Event
6 | import CyBy.Draw.Internal.Settings
11 | import Derive.Prelude
14 | import Text.SVG.Attribute as A
17 | %language ElabReflection
21 | record SceneDims where
28 | sceneCenter : SceneDims -> Point Id
29 | sceneCenter sd = P (sd.swidth / 2.0) (sd.sheight / 2.0)
33 | sceneBounds : SceneDims -> Bounds2D Id
34 | sceneBounds sd = BS (range 0.0 sd.swidth) (range 0.0 sd.sheight)
50 | %runElab derive "Cell" [Show,Eq]
52 | xRelativeTo : Elem -> Elem -> Nat
53 | xRelativeTo x rel = cast $
conIndexElem x - conIndexElem rel
56 | PSERows, PSEColumns : Nat
60 | elemPosition : Elem -> (Nat,Nat)
61 | elemPosition H = (0,0)
62 | elemPosition He = (17,0)
63 | elemPosition Li = (0,1)
64 | elemPosition Be = (1,1)
65 | elemPosition Na = (0,2)
66 | elemPosition Mg = (1,2)
68 | if e >= B && e <= Ne then ((e `xRelativeTo` B) + 12,1)
69 | else if e >= Al && e <= Ar then ((e `xRelativeTo` Al) + 12,2)
70 | else if e >= K && e <= Kr then (e `xRelativeTo` K ,3)
71 | else if e >= Rb && e <= Xe then (e `xRelativeTo` Rb ,4)
72 | else if e >= Cs && e <= La then (e `xRelativeTo` Cs ,5)
73 | else if e >= Ce && e <= Lu then (e `xRelativeTo` Ba ,8)
74 | else if e >= Hf && e <= Rn then ((e `xRelativeTo` Hf) + 3,5)
75 | else if e >= Fr && e <= Ac then (e `xRelativeTo` Fr ,6)
76 | else if e >= Th && e <= Lr then (e `xRelativeTo` Ra ,9)
77 | else if e >= Rf && e <= Ts then ((e `xRelativeTo` Rf) + 3,6)
89 | map (\e => let (x,y) := elemPosition e in PC e x y) values
104 | parameters {auto s : DrawSettings}
108 | hcellRel = sd.sheight / cast PSERows
111 | wcellRel = sd.swidth / cast PSEColumns
116 | mousePos : (x,y : Double) -> (Nat,Nat)
117 | mousePos x y = (cast $
x / wcellRel, cast $
y / hcellRel)
120 | hoveredElem : {0 t : _} -> Point t -> Maybe Elem
121 | hoveredElem (P dx dy) =
122 | let (x,y) := mousePos dx dy
123 | in element <$> find (\c => c.posX == x && c.posY == y) cells
125 | drawCell : Maybe Elem -> Cell -> SVGNode
126 | drawCell me (PC elem px py) =
127 | let x := cast px * wcell
128 | y := cast py * hcell
129 | txtX := x + half * wcell
130 | txtY := y + half * hcell
131 | hovCol := if me == Just elem then s.hoverBG else s.defaultBG
132 | in g [transform (Scale (wcellRel / wcell) (hcellRel / hcell))]
133 | [ rect [A.x x.u, A.y y.u, width wcell.u, height hcell.u, fill hovCol, stroke black]
134 | , text1 [A.x txtX.u, A.y txtY.u, fill (s.elemColor elem)] (show elem)
138 | displayPSE : Maybe Elem -> SVGNode
141 | [ fontFamily s.core.font
142 | , fontSize (cast s.pseFontSize).px
143 | , textAnchor Middle
144 | , dominantBaseline Central
146 | (map (drawCell me) cells)