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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
{-# LANGUAGE CPP #-}
{-# LANGUAGE JavaScriptFFI #-}
module View.Statistics.Chart
( view
, In(..)
, Dataset(..)
) where
import qualified Control.Concurrent as Concurrent
import Control.Monad (void)
import Control.Monad.IO.Class (liftIO)
import Data.Aeson ((.=))
import qualified Data.Aeson as AE
import qualified Data.Map as M
import Data.Text (Text)
import Language.Javascript.JSaddle (JSString, JSVal)
import qualified Language.Javascript.JSaddle.Value as JSValue
import Reflex.Dom (MonadWidget)
import qualified Reflex.Dom as R
-- import GHCJS.Foreign.Callback
#ifdef __GHCJS__
foreign import javascript unsafe "new Chart(document.getElementById($1), $2);" drawChart :: JSString -> JSVal -> IO ()
#else
drawChart = error "drawChart: only available from JavaScript"
#endif
data In = In
{ _in_title :: Text
, _in_labels :: [Text]
, _in_datasets :: [Dataset]
}
data Dataset = Dataset
{ _dataset_label :: Text
, _dataset_data :: [Int]
, _dataset_color :: Text
}
view :: forall t m. MonadWidget t m => In -> m ()
view input = do
R.divClass "g-Chart" $
R.elAttr "canvas" (M.singleton "id" "chart") $
R.blank
liftIO $ Concurrent.forkIO $ do
Concurrent.threadDelay 500000
config <- JSValue.valMakeJSON (configToJson input)
drawChart "chart" config
return ()
configToJson (In title labels datasets) =
AE.object
[ "type" .= AE.String "line"
, "data" .=
AE.object
[ "labels" .= labels
, "datasets" .= map datasetToJson datasets
]
, "options" .=
AE.object
[ "responsive" .= True
, "title" .=
AE.object
[ "display" .= True
, "text" .= title
]
, "tooltips" .=
AE.object
[ "mode" .= AE.String "nearest"
, "intersect" .= False
]
, "hover" .=
AE.object
[ "mode" .= AE.String "nearest"
, "intersect" .= True
]
, "scales" .=
AE.object
[ "yAxes" .=
[ [ AE.object
[ "ticks" .=
AE.object
[ "beginAtZero" .= True ]
]
]
]
]
]
]
datasetToJson (Dataset label data_ color) =
AE.object
[ "label" .= label
, "data" .= data_
, "fill" .= False
, "backgroundColor" .= color
, "borderColor" .= color
]
|