aboutsummaryrefslogtreecommitdiff
path: root/client/src/View/Statistics/Chart.hs
blob: 63df2a117b7fd34bbd3691140e3865f17fd70273 (plain)
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
    ]