-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGraph.elm
51 lines (36 loc) · 2.19 KB
/
Graph.elm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
module Graph where
import Graphics.Collage
import Util (range,floatPrecision)
data Axis = Linear | Log
textWidth : Float
textWidth = toFloat . widthOf . plainText . show <| "-9.99e-9"
textHeight : Float
textHeight = toFloat . heightOf . plainText . show <| "-9.99e-9"
log = logBase 10
axisMaker kind size low high value =
case kind of
Linear -> (value-low)/(high-low)*size-size/2
Log -> let v = log value
l = log low
h = log high
in (v-l)/(h-l)*size-size/2
ticMaker : Axis -> [Float] -> [Float]
ticMaker kind =
case kind of
Linear -> smartTics 3
Log -> map (\x -> e^x) . smartTics 4 . map log
projectPoints : (Float->Float) -> (Float->Float) -> [(Float,Float)] -> [(Float,Float)]
projectPoints fx fy ps = zip (map (fx . fst) ps) (map (fy . snd) ps)
canvas : Int -> Int -> (Float->Float) -> Axis -> (Float->Float) -> Axis -> [(Float,Float)] -> Element
canvas w h xax xKind yax yKind points = Graphics.Collage.collage w h [traced (solid lightBlue) <| Graphics.Collage.path (projectPoints xax yax points), xGrid h xax . ticMaker xKind <| map fst points, yGrid w yax . ticMaker yKind <| map snd points]
smartTics count pts = let low = minimum pts
high = maximum pts
in range low high count
xGrid h xax pts = let lines = map (traced (solid darkGrey) . Graphics.Collage.path . projectPoints xax id . \x -> [(x,(toFloat h)/(-2)+textHeight),(x,(toFloat h)/2)]) <| pts
labels = map (\x -> moveY ((toFloat h)/(-2) + textHeight/2) . moveX (xax x) <| toForm . plainText . floatPrecision 3 <| x) <| pts
in group [group lines, group labels]
yGrid h xax pts = let lines = map (traced (solid darkGrey) . Graphics.Collage.path . projectPoints id xax . \x -> [((toFloat h)/(-2)+textWidth,x),((toFloat h)/2,x)]) <| pts
labels = map (\x -> moveX ((toFloat h)/(-2) + textWidth/2) . moveY (xax x) <| toForm . plainText . floatPrecision 3 <| x) <| pts
in group [group lines, group labels]
makePoints : [Float] -> (Float -> Float) -> [(Float,Float)]
makePoints base f = zip base <| map f base