UPlot.hs
module Frontend.UPlot where
import Prelude
import Data.Maybe (Maybe)
import Data.Nullable (Nullable, toNullable)
import Effect (Effect)
import Web.HTML (HTMLElement)
foreign import initializeImpl :: HTMLElement -> Opts -> Effect UPlot
foreign import setSizeImpl :: UPlot -> Number -> Number -> Effect Unit
foreign import setDataImpl :: UPlot -> Array (Array (Nullable Number)) -> Effect Unit
foreign import destroyImpl :: UPlot -> Effect Unit
data UPlot -- opaque uPlot handle
data Plot = Plot
{ uplot :: UPlot
}
-- Opts
type Series =
{ stroke :: String
, fill :: String
}
type Grid =
{ show :: Boolean
, stroke :: String
, width :: Int
}
defaultGrid :: Grid
defaultGrid =
{ show: true
, stroke: "rgba(0,0,0,0.07)"
, width: 2
}
noGrid :: Grid
noGrid = defaultGrid { show=false }
type Axis =
{ show :: Boolean
, scale :: String
, space :: Int
, gap :: Int
, size :: Int
, labelSize :: Int
-- , labelFont :: Font
, side :: Int
, grid :: Grid
-- , ticks :: Ticks
-- , font :: Font
-- , rotate: Int
}
defaultXAxis :: Axis
defaultXAxis =
{ show: true
, scale: "x"
, space: 50
, gap: 5
, size: 50
, labelSize: 30
-- , labelFont
, side: 2
--, class: "x-vals"
--, incrs: timeIncrs
--, values: timeVals
--, filter: retArg1
, grid: defaultGrid
-- , ticks
-- , font
-- , rotate: 0
}
defaultYAxis :: Axis
defaultYAxis =
{ show: true
, scale: "y"
, space: 30
, gap: 5
, size: 50
, labelSize: 30
-- , labelFont
, side: 3
--, class: "x-vals"
--, incrs: timeIncrs
--, values: timeVals
--, filter: retArg1
, grid: defaultGrid
-- , ticks
-- , font
-- , rotate: 0
}
noAxis :: Axis
noAxis = defaultXAxis { show=false }
type Opts =
{ width :: Number
, height :: Number
, axes :: Array Axis
, scales ::
{ x ::
{ time :: Boolean
, distr :: Int
}
}
, series :: Array Series
}
defaultSeries :: Series
defaultSeries =
{ stroke: "blue"
, fill: "rgba(0,0,255,0.1)"
}
defaultOpts :: Opts
defaultOpts =
{ width: 500.0
, height: 300.0
, axes: [defaultXAxis, defaultYAxis]
, scales:
{ x:
{ time: true
, distr: 1
}
}
, series: [defaultSeries, defaultSeries]
}
initialize :: HTMLElement -> Opts -> Effect Plot
initialize e opts = initializeImpl e opts <#> \uplot -> Plot { uplot: uplot }
setSize :: Plot -> Number -> Number -> Effect Unit
setSize (Plot p) w h = setSizeImpl p.uplot w h
setData :: Plot -> Array (Array (Maybe Number)) -> Effect Unit
setData (Plot p) = setDataImpl p.uplot <<< map (map toNullable)
destroy :: Plot -> Effect Unit
destroy (Plot p) = destroyImpl p.uplot