{-# language OverloadedStrings, ExtendedDefaultRules #-}
module Lucid.VegaLite (
mkVegaHtml
, vegaEmbedHead, vegaEmbedBodyScript) where
import Lucid
import Lucid.PreEscaped (scriptSrc)
import qualified Data.Aeson as A
import qualified Data.Text.Encoding as T (decodeUtf8)
import qualified Data.ByteString.Lazy as LBS
import Data.Monoid
vegaCDN, vegaLiteCDN, vegaEmbedCDN :: Monad m => HtmlT m ()
vegaCDN = scriptSrc "https://cdn.jsdelivr.net/npm/vega@3"
vegaLiteCDN = scriptSrc "https://cdn.jsdelivr.net/npm/vega-lite@2.5.0"
vegaEmbedCDN = scriptSrc "https://cdn.jsdelivr.net/npm/vega-embed@3"
mkVegaHtml :: A.Value -> Html ()
mkVegaHtml vl = doctypehtml_ $ html_ $ do
meta_ [charset_ "UTF-8"]
head_ vegaEmbedHead
with div_ [id_ "vis"] ""
body_ $ vegaEmbedBodyScript vl
vegaEmbedHead :: Html ()
vegaEmbedHead = do
vegaCDN
vegaLiteCDN
vegaEmbedCDN
vegaEmbedBodyScript :: A.Value -> Html ()
vegaEmbedBodyScript vl =
script_ $ T.decodeUtf8 $ LBS.toStrict ("const spec =" <> A.encode vl <> "; vegaEmbed('#vis', spec).then(result => console.log(result)).catch(console.warn);" :: LBS.ByteString)