import ProofWidgets.Data.Html import ProofWidgets.Component.Basic import OctiveLean.PlotData /-! Renders plot figures as an interactive widget in the infoview. Figure data is encoded as JSON and passed to the React component in `widget/js/interactivePlot.js`, which handles zoom, pan, and hover. -/ namespace OctiveLean.PlotWidget open ProofWidgets Lean -- ── Props ───────────────────────────────────────────────────────── structure OctivePlotProps where figures : Array Json deriving Server.RpcEncodable -- ── Widget module ───────────────────────────────────────────────── @[widget_module] def OctivePlotWidget : Component OctivePlotProps where javascript := include_str ".." / "widget" / "js" / "interactivePlot.js" -- ── JSON encoding of plot data ──────────────────────────────────── private def encodeMarkType : MarkType → String | .line => "line" | .scatter => "scatter" | .bar => "bar" | .stem => "stem" | .histogram => "histogram" | .scatter3 => "scatter3" | .line3 => "line3" | .surface => "surface" | .waterfall => "waterfall" | .contour => "contour" private def encodeFloatArr (a : Array Float) : Json := Json.arr (a.map toJson) private def encodeSeries (s : PlotSeries) : Json := Json.mkObj [ ("xData", encodeFloatArr s.xData), ("yData", encodeFloatArr s.yData), ("zData", encodeFloatArr s.zData), ("markType", Json.str (encodeMarkType s.markType)), ("label", Json.str s.label), ("color", Json.str s.color), ("gridRows", toJson s.gridRows), ("gridCols", toJson s.gridCols) ] private def encodeFigure (fig : Figure) : Json := Json.mkObj [ ("title", Json.str fig.title), ("xlabel", Json.str fig.xlabel), ("ylabel", Json.str fig.ylabel), ("zlabel", Json.str fig.zlabel), ("is3D", Json.bool fig.is3D), ("series", Json.arr (fig.series.map encodeSeries)) ] -- ── Entry point ─────────────────────────────────────────────────── def render (figs : Array Figure) : Html := if figs.isEmpty then Html.text "" else Html.ofComponent OctivePlotWidget { figures := figs.map encodeFigure } #[] end OctiveLean.PlotWidget