Created
December 14, 2025 08:30
-
-
Save mchav/ba7d1271144443102150ce1a924198b9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- Sort of like Java's step builder pattern. | |
| -- https://medium.com/@castigliego/step-builder-pattern-3bcac4eaf9e8 | |
| -- A type that encodes that Y doesn't exist. | |
| data NeedY | |
| -- A type that encodes that a chart is ready. | |
| data Ready | |
| data Plot (s :: *) where | |
| Scatter :: | |
| { pX :: SomeNumExpr | |
| , pY :: Maybe SomeNumExpr | |
| , pColour :: Maybe SomeCatExpr | |
| , pHudEdits :: Endo HudOptions | |
| , pMarkupEdits :: Endo MarkupOptions | |
| , pForceRange :: Maybe ((Double, Double), (Double, Double)) | |
| } -> Plot s | |
| data SomeNumExpr = forall a. (Real a) => SomeNumExpr (Expr a) | |
| data SomeCatExpr = forall a. (Enum a) => SomeCatExpr (Expr a) | |
| scatter :: Real a => Expr a -> Plot NeedY | |
| scatter x = Scatter (SomeNumExpr x) Nothing Nothing mempty mempty Nothing | |
| against :: Real b => Expr b -> Plot NeedY -> Plot Ready | |
| against y p = p { pY = Just (SomeNumExpr y) } | |
| colourWith :: Enum c => Expr c -> Plot Ready -> Plot Ready | |
| colourWith c p = p { pColour = Just (SomeCatExpr c) } | |
| setTitle :: T.Text -> Plot s -> Plot s | |
| setTitle t p = | |
| p { pHudEdits = pHudEdits p <> Endo (\hud -> | |
| hud { titles = [Priority 0 (defaultTitleOptions t)] } ) } | |
| axisTitles :: T.Text -> T.Text -> Plot s -> Plot s | |
| axisTitles xlab ylab p = | |
| p { pHudEdits = pHudEdits p <> Endo (\hud -> | |
| hud { titles = ... | |
| }) } | |
| axisTicks :: [Double] -> [Double] -> Plot s -> Plot s | |
| axisTicks xt yt p = | |
| p { pHudEdits = pHudEdits p <> Endo (\hud -> | |
| hud { axes = ... | |
| }) } | |
| dimensions :: (Double, Double) -> (Double, Double) -> Plot s -> Plot s | |
| dimensions xr yr p = p { pForceRange = Just (xr, yr) } | |
| data PlotError | |
| = MissingY | |
| | ColumnEvalError T.Text | |
| deriving (Show) | |
| render :: Plot Ready -> DataFrame -> Either PlotError ByteString | |
| render p df = do | |
| -- we can finally run the expressions through the dataframe to get the x and y points. | |
| ptsByColour <- buildPoints p df | |
| let charts = ... -- build chart from points | |
| chartOpts = | |
| mempty | |
| { chartTree = named "scatter" charts' | |
| -- endomorphism means we can combine all the different HUD options | |
| -- seems like the right abstraction for composing these. | |
| , hudOptions = appEndo (pHudEdits p) defaultHudOptions | |
| , markupOptions = appEndo (pMarkupEdits p) defaultMarkupOptions | |
| } | |
| pure (encodeChartOptions chartOpts) | |
| -- somwhere in the call point | |
| let svgBytes = | |
| ( Plt.scatter penguinHeight | |
| |> Plt.against penguinWeight | |
| |> Plt.colourWith penguinSpecies | |
| |> Plt.setTitle "my penguine chart" | |
| |> Plt.axisTitles "Penguin Height" "Penguin Weight" | |
| |> Plt.axisTicks [1, 5, 12] [123, 349, 400] | |
| |> Plt.dimensions (0, 15) (100, 500) | |
| |> Plt.render | |
| ) df |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment