hanalyze-0.1.0.0: src/Hanalyze/Viz/PlotData/DataFrame.hs
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wno-orphans #-}
-- | 'ToPlotData' instance for Hackage @dataframe@.
--
-- Kept in its own module so 'Hanalyze.Viz.PlotData' itself does not
-- depend on @dataframe@; future backends (Parquet streaming, SQL, ...)
-- can ship analogous adapter modules without touching the core.
--
-- The instance copies all numeric columns into @pdNumeric@ and all
-- (parseable) text columns into @pdText@. Columns that do not match
-- either projection are dropped silently — Vega specs only ever
-- reference columns by name, so missing columns surface as runtime
-- errors at the spec level rather than at conversion time.
module Hanalyze.Viz.PlotData.DataFrame
( -- Re-exports
PlotData
, ToPlotData (..)
) where
import qualified Data.Map.Strict as Map
import Data.Text (Text)
import qualified Data.Vector as V
import qualified DataFrame as DX
import Hanalyze.DataIO.Convert (getDoubleVec, getTextVec)
import Hanalyze.Viz.PlotData (PlotData (..), ToPlotData (..),
emptyPlotData)
instance ToPlotData DX.DataFrame where
toPlotData df = case DX.columnNames df of
[] -> emptyPlotData
cs ->
let pickNumeric n = (\v -> (n, v)) <$> getDoubleVec n df
pickText n = (\v -> (n, v)) <$> getTextVec n df
numCols = [ c | Just c <- map pickNumeric cs ]
txtCols = [ c | Just c <- map pickText cs ]
rowLen = maximum
(0 : map (V.length . snd) numCols
++ map (V.length . snd) txtCols)
in PlotData
{ pdNumeric = Map.fromList numCols
, pdText = Map.fromList txtCols
, pdLength = rowLen
}