Charts.hs 13 KB
Newer Older
Sudhir Kumar's avatar
Sudhir Kumar committed
1
module Gargantext.Components.Charts.Charts where
2

Sudhir Kumar's avatar
Sudhir Kumar committed
3
import Prelude hiding (min)
4

5
import Gargantext.Components.Charts.Options.Series (Series(..), D1, seriesType, SeriesShape(..))
6
import CSS (Color, white)
Mael NICOLAS's avatar
Mael NICOLAS committed
7
import Data.Maybe (Maybe(..))
8 9
import React as R
import React.DOM (p)
Mael NICOLAS's avatar
Mael NICOLAS committed
10
import React.DOM.Props (Props, unsafeFromPropsArray, unsafeMkProps)
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

-- eCharts Props

-- className :: String -> from React DOM Props
--    style     :: String,  -- object,

theme :: String -> Props
theme = unsafeMkProps "theme"

group :: String -> Props
group = unsafeMkProps "group"

    -- group     :: String,
    -- option    :: Option, --  PropTypes.object.isRequired,
    -- initOpts  :: String, -- PropTypes.object,
    -- notMerge  :: Boolean,
    -- lazyUpdate:: Boolean,
    -- loading   :: Boolean,
    -- optsLoading::  OptsLoading, --  PropTypes.object,
    -- onReady    :: String, --  PropTypes.func,
    -- resizable  :: Boolean, -- PropTypes.bool,
    -- onEvents   :: String --  PropTypes.object

34
type EchartsProps=
35
  { className   :: String,
Mael NICOLAS's avatar
Mael NICOLAS committed
36
    style       :: String,  -- objealect-black-altdarkmincnaquadahherry-blossomect,
37 38 39 40 41 42 43 44 45 46 47
    theme       :: String,
    group       :: String,
    option      :: Option, --  PropTypes.object.isRequired,
    initOpts    :: String, -- PropTypes.object,
    notMerge    :: Boolean,
    lazyUpdate  :: Boolean,
    loading     :: Boolean,
    optsLoading :: OptsLoading, --  PropTypes.object,
    onReady     :: String, --  PropTypes.func,
    resizable   :: Boolean, -- PropTypes.bool,
    onEvents    :: String --  PropTypes.object
48 49 50
  }

type OptsLoading =
51 52
  { text      :: String,
    color     :: Color,  --- color
53
    textColor :: Color, --color
54 55
    maskColor :: Color, --color
    zlevel    :: Int
56 57
  }

Mael NICOLAS's avatar
Mael NICOLAS committed
58
type OpTest =
59
  {children :: R.Children, option :: Option}
Mael NICOLAS's avatar
Mael NICOLAS committed
60

61
type Option =
Mael NICOLAS's avatar
Mael NICOLAS committed
62
  { title    :: Maybe Title
Mael NICOLAS's avatar
Mael NICOLAS committed
63
  , legend   :: Maybe Legend
64 65 66 67 68 69
  , tooltip  :: Tooltip
  , grid     :: Grid
  , xAxis    :: XAxis
  , yAxis    :: YAxis
  , series   :: Array Series
  , dataZoom :: Array DataZoom
70 71 72 73
  }


type DataZoom =
74 75 76 77 78
  {"type"      :: String
  , xAxisIndex :: Int
  , filterMode :: String
  , start      :: Int
  , end        :: Int
79 80 81 82 83 84 85
  }

type Grid =
  {containLabel :: Boolean
  }

type Legend =
Mael NICOLAS's avatar
Mael NICOLAS committed
86 87
  {"type"  :: String
  , show   :: Boolean
Mael NICOLAS's avatar
Mael NICOLAS committed
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
  , zlevel :: Maybe Number
  , z      :: Maybe Number
  , left   :: Maybe Number
  , top    :: Maybe Number
  , right  :: Maybe Number
  , bottom :: Maybe Number
  , width  :: Maybe Number
  , height :: Maybe Number
  , orient :: Maybe String
  , align  :: Maybe String
  , padding       :: Maybe Number
  , itemGap       :: Maybe Number
  , itemWidth     :: Maybe Number
  , itemHeight    :: Maybe Number
  , formatter     :: Maybe String
  , selectedMode  :: Maybe Boolean
  , inactiveColor :: Maybe Color
  , selected      :: Maybe String -- object
Mael NICOLAS's avatar
Mael NICOLAS committed
106
  , "data"        :: Maybe (Array Data)
107 108 109
  }

type Data =
110
  { name      :: String
Mael NICOLAS's avatar
Mael NICOLAS committed
111 112
  , icon      :: Maybe String
  , textStyle :: Maybe {}
113 114 115
  }

type SubtextStyle =
116 117
  { color      :: Color
  , fontStyle  :: String
118 119
  , fontWeight :: String
  , fontFamily :: String
120 121
  , fontSize   :: Int
  , align      :: String
122
  , verticalAlign :: String
123 124 125
  , lineHeight    :: Number
  , width         :: Number
  , height        :: Number
126 127 128
  , textBorderColor :: String
  , textBorderWidth :: Number
  , textShadowColor :: String
129
  , textShadowBlur  :: Number
130 131
  , textShadowOffsetX :: Number
  , textShadowOffsetY :: Number
132
  , rich              :: Rich
133 134 135 136
  }


type Tooltip =
137
  { trigger   :: String
138
  , formatter :: Maybe String -- TODO function
139 140 141
  }

type XAxis =
Mael NICOLAS's avatar
Mael NICOLAS committed
142
  { "data"   :: Array Data
143
  , "type"   :: String
144 145
  , axisTick :: AxisTick
  }
146

147 148 149 150 151 152
type AxisTick =
  {
    alignWithLabel :: Boolean
  }

type YAxis =
153 154 155 156
  { "type"    :: String
  , name      :: String
  , min       :: Int
  , position  :: String
157 158 159 160 161 162 163 164
  , axisLabel :: AxisLabel
  }

type AxisLabel =
  { formatter :: String -- string or function
  }


165 166 167 168 169 170
--type Series =
--  { name   :: String
--  , "type" :: String
--  , "data" :: Array Int
--  }

171 172

type Title =
173 174 175 176 177 178 179 180
  { text         :: String
  , show         :: Boolean
  , link         :: String
  , target       :: String
  , textStyle    :: TextStyle
  , subtext      :: String
  , sublink      :: String
  , subtarget    :: String
181
  , subtextStyle :: SubtextStyle
182 183 184 185 186 187 188 189
  , padding      :: Number
  , itemGap      :: Number
  , zlevel       :: Number
  , z            :: Number
  , left         :: Number
  , top          :: Number
  , right        :: Number
  , bottom       :: Number
190
  , backgroundColor :: Color
191 192 193 194 195 196 197
  , borderColor     :: Color
  , borderWidth     :: Number
  , borderRadius    :: Number -- NumberOrArray
  , shadowBlur      :: Number
  , shadowColor     :: Color
  , shadowOffsetX   :: Number
  , shadowOffsetY   :: Number
198 199 200 201 202 203 204 205 206
  }

-- data NumberOrArray = Number | Array Number



type Rich = {}


207
foreign import eChartsClass :: forall props. R.ReactClass { children :: R.Children | props}
Mael NICOLAS's avatar
Mael NICOLAS committed
208
foreign import eChartsClass2 :: R.ReactClass OpTest
209

210 211
echarts :: Array Props -> R.ReactElement
echarts p = R.unsafeCreateElementDynamic eChartsClass (unsafeFromPropsArray p) []
212

213 214
echarts' :: Option -> R.ReactElement
echarts' chart = R.unsafeCreateElementDynamic eChartsClass2 {option: chart} []
Mael NICOLAS's avatar
Mael NICOLAS committed
215

216 217 218 219 220 221
-- Props

loading :: Boolean -> Props
loading = unsafeMkProps "loading"

type TextStyle =
222 223
  { color      :: Color
  , fontStyle  :: String
224 225
  , fontWeight :: String
  , fontFamily :: String
226 227 228 229 230 231
  , fontSize   :: Int
  , align      :: String
  , verticalAlign   :: String
  , lineHeight      :: Int
  , width           :: Int
  , height          :: Int
232 233 234
  , textBorderColor :: String
  , textBorderWidth :: Int
  , textShadowColor :: String
235
  , textShadowBlur  :: Int
236 237
  , textShadowOffsetX :: Int
  , textShadowOffsetY :: Int
238
  , rich              :: Rich
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
  }

foreign import data TextStyleProps :: Type

textStyle :: Array Props -> Props
textStyle = unsafeMkProps "textStyle"

subTextStyle :: Array Props -> Props
subTextStyle = unsafeMkProps "subTextStyle"

color :: Color -> Props
color = unsafeMkProps "color"

align :: String -> Props
align = unsafeMkProps "align"

option :: Array Props -> Props
option = unsafeMkProps "option" <<< unsafeFromPropsArray

ts :: Props
ts = textStyle [color white, align "left"]

title :: Array Props -> Props
title = unsafeMkProps "title" <<< unsafeFromPropsArray

text :: String -> Props
text = unsafeMkProps "text"


tooltip :: Array Props -> Props
tooltip = unsafeMkProps "tooltip" <<< unsafeFromPropsArray

trigger :: String -> Props
trigger = unsafeMkProps "trigger"

grid :: Array Props -> Props
grid = unsafeMkProps "grid" <<< unsafeFromPropsArray

containLabel :: Boolean -> Props
containLabel = unsafeMkProps "containLabel"

legend :: Array Props -> Props
legend = unsafeMkProps "legend" <<< unsafeFromPropsArray

data' :: forall a. a -> Props
data' = unsafeMkProps "data"

xAxis :: Array Props -> Props
xAxis ap = unsafeMkProps "xAxis" [unsafeFromPropsArray ap]

type' :: String -> Props
type' = unsafeMkProps "type"

axisTick :: Array Props -> Props
axisTick = unsafeMkProps "axisTick" <<< unsafeFromPropsArray

alignWithLabel :: Boolean -> Props
alignWithLabel = unsafeMkProps "alignWithLabel"

xAxisIndex :: Int -> Props
xAxisIndex = unsafeMkProps "xAxisIndex"

filterMode :: String -> Props
filterMode = unsafeMkProps "filterMode"

start :: Int -> Props
start = unsafeMkProps "start"

end :: Int -> Props
end = unsafeMkProps "end"

dataZoom :: Array Props -> Props
dataZoom = unsafeMkProps "dataZoom"

name :: String -> Props
name = unsafeMkProps "name"

position :: String -> Props
position = unsafeMkProps "position"

axisLabel :: Array Props -> Props
axisLabel = unsafeMkProps "axisLabel" <<< unsafeFromPropsArray

formatter :: String -> Props
formatter = unsafeMkProps "formatter"

min :: Int -> Props
min = unsafeMkProps "min"

yAxis :: Array Props -> Props
yAxis = unsafeMkProps "yAxis"

series :: Array Props -> Props
series = unsafeMkProps "series"

label :: Array Props -> Props
label = unsafeMkProps "label"

normal :: Array Props -> Props
normal = unsafeMkProps "normal"

showp :: Boolean -> Props
showp = unsafeMkProps "show"

lineStyle :: Array Props -> Props
lineStyle = unsafeMkProps "lineStyle" <<< unsafeFromPropsArray

width :: Int -> Props
width = unsafeMkProps "width"

shadowColor :: String -> Props
shadowColor = unsafeMkProps "shadowColor"

shadowBlur :: Int -> Props
shadowBlur = unsafeMkProps "shadowBlur"

shadowOffsetY :: Int -> Props
shadowOffsetY = unsafeMkProps "shadowOffsetY"

yAxisIndex :: Int -> Props
yAxisIndex = unsafeMkProps "yAxisIndex"



-------------------


      -- [ p''
      -- , ex1
      -- , p''
      -- ]

371 372
legend' :: Legend
legend' =
Mael NICOLAS's avatar
Mael NICOLAS committed
373
  {
Mael NICOLAS's avatar
Mael NICOLAS committed
374 375 376 377 378 379 380
    "type": "plain"
   , show: true
   , zlevel: Nothing
   , z: Nothing
   , left: Nothing
   , top: Nothing
   , right: Nothing
Mael NICOLAS's avatar
Mael NICOLAS committed
381
   , bottom: Nothing
Mael NICOLAS's avatar
Mael NICOLAS committed
382
   , width: Nothing
Mael NICOLAS's avatar
Mael NICOLAS committed
383 384
   , height: Nothing
   , orient: Nothing
Mael NICOLAS's avatar
Mael NICOLAS committed
385 386 387 388 389 390 391
   , align: Nothing
   , padding: Nothing
   , itemGap: Nothing
   , itemWidth: Nothing
   , itemHeight: Nothing
   , formatter: Nothing
   , selectedMode: Nothing
Mael NICOLAS's avatar
Mael NICOLAS committed
392
   , inactiveColor: Nothing
Mael NICOLAS's avatar
Mael NICOLAS committed
393 394
   , selected: Nothing
   , "data": Nothing
Mael NICOLAS's avatar
Mael NICOLAS committed
395 396 397 398 399 400 401 402 403 404 405
  }

data1 :: Data
data1 = {name: "Map terms coverage", icon: Nothing, textStyle: Nothing}

data2 :: Data
data2 = {name: "Favorites", icon: Nothing, textStyle: Nothing}

data3 :: Data
data3 = {name: "All", icon: Nothing, textStyle: Nothing}

406 407
xAxis' :: XAxis
xAxis' =
Mael NICOLAS's avatar
Mael NICOLAS committed
408
 {
409 410 411 412 413 414 415
   "data": [xData1, xData2, xData3]
 , "type": "category"
 , axisTick: {alignWithLabel: true}
 }

xData1 :: Data
xData1 = {name: "Jan", icon: Nothing, textStyle: Nothing}
Mael NICOLAS's avatar
Mael NICOLAS committed
416

417 418 419 420 421 422 423 424 425 426 427 428 429 430
xData2 :: Data
xData2 = {name: "Feb", icon: Nothing, textStyle: Nothing}

xData3 :: Data
xData3 = {name: "Mar", icon: Nothing, textStyle: Nothing}

yData1 :: YAxis
yData1 =
  {
    "type": "value"
  , name: "Score metric"
  , min: 0
  , position: "right"
  , axisLabel: {formatter: "{value}"}
Mael NICOLAS's avatar
Mael NICOLAS committed
431 432
  }

433 434 435 436 437 438 439 440
tooltip' :: Tooltip
tooltip' =
  {
    trigger: "axis"
  , formatter: Nothing
  }


441
series' :: D1
442 443 444
series' =
  {
    name: "All"
445 446
  , "type": seriesType Bar
  , "data": [201.0, 777, 879]
447 448
  }

Mael NICOLAS's avatar
Mael NICOLAS committed
449 450 451
opt :: Option
opt =
  {
Mael NICOLAS's avatar
Mael NICOLAS committed
452 453
    title: Nothing
    ,legend: Nothing
Mael NICOLAS's avatar
Mael NICOLAS committed
454
    ,tooltip: tooltip'
Mael NICOLAS's avatar
Mael NICOLAS committed
455
    ,grid: {containLabel: true}
456 457
    ,xAxis: xAxis'
    ,yAxis: yData1
458
    ,series: [SeriesD1 series']
459
    ,dataZoom: [dz1', dz1', dz2', dz2']
Mael NICOLAS's avatar
Mael NICOLAS committed
460 461
  }

462 463
histogram2 :: R.ReactElement
histogram2 = echarts' opt
Mael NICOLAS's avatar
Mael NICOLAS committed
464

465
histogram :: R.ReactElement
466
histogram = echarts
467 468 469
     [ option
       [ tooltip [trigger "axis"]
       , grid [containLabel true]
470
       , legend [data' ["TEST MUDADA", "Favorites", "All"]]
471
       -- , legend [data' ["Map Terms coverage", "Favorites", "All"]]
472 473 474
       , xAxis
         [ type' "category"
         , axisTick [alignWithLabel true]
475 476 477 478
         , data' ["Jan" , "Feb", "Mar" , "Apr"
                 , "May", "Jun", "July", "Aug"
                 , "Sep", "Oct", "Nov" , "Dec"
                 ]
479
         ]
480
       , dataZoom' [dz1', dz1', dz2', dz2']
481
       , yAxis [ya1, ya2]
Mael NICOLAS's avatar
Mael NICOLAS committed
482
       , series [sd1, sd2, sd3]
483 484 485
       ]
     ]

486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
{-
type DataZoom =
  {"type"      :: String
  , xAxisIndex :: Int
  , filterMode :: String
  , start      :: Int
  , end        :: Int
  }
-}

dz1' :: DataZoom
dz1' = {
  "type": "slider"
  ,xAxisIndex: 0
  ,filterMode: "empty"
  ,start: 0
  ,end: 100
  }

dz2' :: DataZoom
dz2' = {
  "type": "inside"
  ,xAxisIndex: 0
  ,filterMode: "empty"
  ,start: 0
  ,end: 100
  }

dz1 :: forall props. props
515 516 517 518 519 520 521 522
dz1 = unsafeFromPropsArray
      [ type' "slider"
      , xAxisIndex 0
      , filterMode "empty"
      , start 0
      , end 100
      ]

523
dz2 :: forall props. props
524 525 526 527 528 529 530 531
dz2 = unsafeFromPropsArray
      [ type' "inside"
      , xAxisIndex 0
      , filterMode "empty"
      , start 0
      , end 100
      ]

532
ya1 :: forall props. props
533 534
ya1 = unsafeFromPropsArray
      [ type' "value"
535
      , name "Score metric"
536
      , min 0
537
      , position "right"
538
      , axisLabel [formatter "{value}"]
539
      ]
540
ya2 :: forall props. props
541 542
ya2 = unsafeFromPropsArray
      [ type' "value"
543
      , name "Publications (by year)"
544
      , min 0
545
      , position "left"
546
      , axisLabel [formatter "{value}"]
547 548
      ]

549
sd1 :: forall props. props
550
sd1 = unsafeFromPropsArray
551
      [ name "Map terms coverage"
552 553 554 555 556 557 558 559
      , type' "line"
      , label [normal[showp true, position "top"]]
      , lineStyle [ normal
                    [ width 3
                    , shadowColor "rgba(0,0,0,0.4)"
                    , shadowBlur 10
                    , shadowOffsetY 10
                    ]]
560
      , data' [95, 80, 75, 35, 30, 50, 70, 80, 95, 95, 95, 99]
561 562
      ]

563
sd3 :: forall props. props
564
sd3 = unsafeFromPropsArray
565
      [ name "All"
566 567 568 569 570 571
      , type' "bar"
      , label [normal[showp true, position "top"]]
      , yAxisIndex 1
      , data' [201, 222, 223, 777, 244, 255, 555, 879, 938, 1364, 1806, 2324]
      ]

Mael NICOLAS's avatar
Mael NICOLAS committed
572 573 574 575 576 577 578 579 580 581 582 583 584
dataZoom' :: Array DataZoom -> Props
dataZoom' dzs = unsafeMkProps "dataZoom" $ dzToProps <$> dzs

dzToProps :: forall props. DataZoom -> props
dzToProps dz = unsafeFromPropsArray
               [ type' dz."type"
               , xAxisIndex dz.xAxisIndex
               , filterMode dz.filterMode
               , start dz.start
               , end dz.end
               ]


585

586
sd2 :: forall props. props
587 588 589 590 591 592 593 594
sd2 = unsafeFromPropsArray
      [ name "Favorites"
      , type' "bar"
      , label [normal[showp true, position "top"]]
      , yAxisIndex 1
      , data' [22, 22, 23, 77, 24, 55, 139, 350, 150, 164, 106, 224]
      ]

595

596