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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
module Chart.Model exposing
( Chart
, Serie
, maxScale
, Vec2
, View
, mkView
, bounds
)
import List.Extra as List
type alias Chart =
{ keys : List String
, series : List Serie
, size : Vec2
, title : String
, scaleColor : String
, formatOrdinate : Float -> String
, ordinateLines : Int
}
type alias Serie =
{ values : List Float
, color : String
, label : String
}
maxScale : Chart -> Float
maxScale { keys, series } =
List.range 0 (List.length keys - 1)
|> List.map (\i ->
series
|> List.map (truncate << Maybe.withDefault 0 << List.getAt i << .values)
|> List.maximum
|> Maybe.withDefault 0
)
|> List.maximum
|> Maybe.withDefault 0
|> upperBound
upperBound : Int -> Float
upperBound n = toFloat (upperBoundInt 0 n)
upperBoundInt : Int -> Int -> Int
upperBoundInt count n =
if n < 10
then
(n + 1) * (10 ^ count)
else
upperBoundInt (count + 1) (n // 10)
type alias Vec2 =
{ x : Float
, y : Float
}
type alias View =
{ fx : Float -> Float
, fy : Float -> Float
}
mkView : Vec2 -> Vec2 -> View
mkView p1 p2 =
{ fx = \x -> p1.x + x * (p2.x - p1.x)
, fy = \y -> p1.y + y * (p2.y - p1.y)
}
bounds : View -> (Vec2, Vec2)
bounds { fx, fy } =
( { x = fx 0, y = fy 0 }
, { x = fx 1, y = fy 1 }
)
|