pijul nest
guest [sign in]

Fork channel

Create a new channel as a copy of main.

Rename channel

Rename main to:

Delete channel

Delete main? This cannot be undone.

Plot.hs
module Frontend.Component.Plot where

import Prelude

import Data.Foldable (sequence_, traverse_)
import Data.Maybe (Maybe(..))
import Data.Traversable (for_)
import Effect.Aff.Class (class MonadAff)
import Effect.Class (class MonadEffect)
import Effect.Class.Console (log)
import Frontend.UPlot as UPlot
import Halogen (liftEffect)
import Halogen as H
import Halogen.HTML as HH
import Halogen.HTML.Properties as HP
import Halogen.Query.EventSource (eventListenerEventSource)
import Web.Event.Event (EventType(..))
import Web.HTML (window)
import Web.HTML.HTMLElement (getBoundingClientRect)
import Web.HTML.Window (document, toEventTarget)

type State =
  { plot :: Maybe UPlot.Plot
  , opts :: UPlot.Opts
  }

type Data = Array (Array (Maybe Number))

data Query a =
  SetData Data a

data Action
  = Initialize
  | Finalize
  | Resize
  -- | SetOpts UPlot.Opts

component :: forall o m. MonadAff m => H.Component HH.HTML Query UPlot.Opts o m
component =
  H.mkComponent
    { initialState: \opts -> { plot: Nothing, opts }
    , render
    , eval: H.mkEval $ H.defaultEval
      { handleAction = handleAction
      , handleQuery = handleQuery
      , initialize = Just Initialize
      , finalize = Just Finalize
      , receive = const Nothing -- Just <<< SetOpts
      }
    }

render :: forall m. State -> H.ComponentHTML Action () m
render state = HH.div [ HP.ref (H.RefLabel "plot") ] []

handleQuery :: forall a o m. MonadEffect m => Query a -> H.HalogenM State Action () o m (Maybe a)
handleQuery = case _ of
  SetData d a -> do
    plot' <- H.get <#> _.plot
    for_ plot' \plot -> do
      liftEffect $ UPlot.setData plot d
    pure (Just a)

handleAction forall o m. MonadAff m => Action H.HalogenM State Action () o m Unit
handleAction = case _ of
  Initialize -> do
    log "Initializing"
    div <- H.getHTMLElementRef (H.RefLabel "plot")
    opts <- H.get <#> _.opts
    for_ div \element -> do
      plot <- liftEffect $ UPlot.initialize element opts
      -- liftEffect $ setData plot [[1.0, 2.0, 3.0], [10.0, 12.0, 11.0], [20.0, 12.0, 11.0], [30.0, 12.0, 11.0]]
      H.modify_ _ { plot = Just plot }

    -- Register resize handler
    document <- H.liftEffect $ document =<< window
    window <- liftEffect window
    H.subscribe' \sid ->
      eventListenerEventSource
        (EventType "resize")
        (toEventTarget window)
        \ev -> Just Resize
    handleAction Resize

      -- log $ show element
  Finalize -> do
    plot <- H.get <#> _.plot
    liftEffect $ traverse_ UPlot.destroy plot

  Resize -> do
    div <- H.getHTMLElementRef (H.RefLabel "plot")
    state <- H.get

    sequence_ do
      div' <- div
      plot <- state.plot :: Maybe UPlot.Plot
      pure $ do
        rect <- liftEffect $ getBoundingClientRect div'
        liftEffect $ UPlot.setSize plot rect.width state.opts.height

  -- SetOpts opts -> do
  --   H.modify_ _ { opts = opts }
  --   log "Setting opts"
  --   handleAction Initialize