[{"name":"ZoomPlot","comment":"\n\n\n# Minimal configuration\n\n@docs easyConfig\n\n\n# Storing the plot state in your model\n\n@docs State\n@docs init\n\n\n# Including `Plot.Msg` in your `Msg`\n\n@docs Msg\n\n\n# Drawing your linechart\n\n@docs draw\n@docs drawHtml\n\n\n# Updating your plot state\n\n@docs update\n\n\n# Customizing your plot\n\nLet's say you want customize your configuration to show legends for your different lines and also extend the right margin so the legends doesn't get cut off. You can do it like this:\n\n    myConfig =\n        let\n            default =\n                Plot.easyConfig points\n        in\n        { default\n            | showLegends = True\n            , marginRight = 70\n        }\n\nWhat if your data isn't in the form of `{ x : Float, y : Float}`?\n\nThen you will need:\n\n@docs defaultConfigWith\n\nIf you want to start customizing every aspect of your plot you need to know about all the fields of the `Plot.Config` type:\n\n@docs Config\n\nSo, what does all this mean?\n\n  - **lines** :\n    A list where you set how your different \"lines\" on your chart should look: color, point shape and legend name. Most importantly it is also here you supply your data to the configuration.\n\n        import LineChart\n        import LineChart.Colors as Colors\n        import LineChart.Dots as Dots\n\n        [ LineChart.line\n            Colors.tealLight\n            Dots.circle\n            \"cos\"\n            myCosData\n        , LineChart.line\n            Colors.goldLight\n            Dots.diamond\n            \"polysin\"\n            myPolySinData\n        ]\n\n    _Note:_ This package use the fork [peterszerzo/line-charts](https://package.elm-lang.org/packages/peterszerzo/line-charts/latest) since it contains necessary updates to Tereza Sokols (terezka) great original package. I advise you to do the same, otherwise namespace collisions seem inevitable.\n\n  - **xAcc** :\n    Accessor function (getter) from your data type to the float value used for x coordinates. If you want a time axis (don't forget to set `xIsTime` to `True`) for your `Time.Posix` values you can do something like this:\n\n        .time >> Time.posixToMillis >> toFloat\n\n  - **yAcc** :\n    Accessor function (getter) from your data type to the float value used for y coordinates.\n\n        .rocketThrust\n\n  - **pointDecoder** :\n    The internals of the package needs a way to convert Point back to your type. You basically have to write a function that puts the coordinates of a `Point` into an \"empty\" instance of your type.\n\n        \\{ x, y } -> RocketData 0 0 \"\" x 0 \"\" 0 y Nothing\n\n  - **xIsTime** :\n    Whether the x-axis should display its values as time or not.\n\n        True\n\n  - **language** :\n    What language dates on time axes will be in.\n\n        import DateFormat.Language\n\n        DateFormat.Language.swedish\n\n  - **numberFormat** :\n    The function which turns floats to strings for the axis labels (on non-time axes).\n\n        import FormatNumber\n        import FormatNumber.Locales\n\n        \\float ->\n            FormatNumber.format\n                FormatNumber.Locales.frenchLocale\n                float\n\n  - **timeZone** :\n    Which timezone should your `Time.Posix` values be converted into for your time axis.\n\n        import Time\n\n        Time.utc -- This is the default.\n\n  - **showLegends** :\n    Whether legends for your plot lines should be drawn. If you turn this on you most likely need to adjust `marginRight` for them to not get cut off.\n\n        True\n\n  - **labelFunc** :\n    Hoverlabels for the x and y coordinates are always on, but if you want to add something extra on a row above them you use this field. One of the more straightforward ways to use this is to just use a string field from your data type:\n\n        .rocketInventorName\n\n    or something more involved:\n\n        \\d -> d.firstName ++ \" \" ++ d.lastName\n\n  - **xAxisLabel** / **yAxisLabel** :\n    Strings for labling the axes. Adjustment of margins and labeloffsets could be required to get the desired result.\n\n        \"Rocket velocity [km/s]\"\n\n  - **marginTop** / **marginRight** / **marginBottom** / **marginLeft** :\n    Size in pixels of the different margins around the actual plot. This is real estate that may or may not be needed by tick labels, legends and axis labels.\n\n        60\n\n  - **xAxisLabelOffsetX** / **xAxisLabelOffsetY** / **yAxisLabelOffsetX** / **yAxisLabelOffsetY** :\n    Distance in pixels of how much you want to adjust the positioning of the axis title labels.\n\n        20\n\n","unions":[{"name":"Msg","comment":" Include it within a constructor for easy pattern matching in your update function:\n\n    type Msg\n        = MyPlotMsg (Plot.Msg Point)\n        | MsgNotConcerningPlots\n\nor if you need routing for several plots:\n\n    type PlotNr\n        = Plot1\n        | Plot2\n        | Plot3\n\n    type Msg\n        = ToPlot PlotNr (Plot.Msg ExampleType)\n\n","args":["data"],"cases":[]}],"aliases":[{"name":"Config","comment":" ","args":["data"],"type":"{ lines : List.List (LineChart.Series data), xAcc : data -> Basics.Float, yAcc : data -> Basics.Float, pointDecoder : LineChart.Coordinate.Point -> data, xIsTime : Basics.Bool, language : DateFormat.Language.Language, numberFormat : Basics.Float -> String.String, timezone : Time.Zone, showLegends : Basics.Bool, labelFunc : data -> String.String, xAxisLabel : String.String, yAxisLabel : String.String, marginTop : Basics.Float, marginRight : Basics.Float, marginBottom : Basics.Float, marginLeft : Basics.Float, xAxisLabelOffsetX : Basics.Float, xAxisLabelOffsetY : Basics.Float, yAxisLabelOffsetX : Basics.Float, yAxisLabelOffsetY : Basics.Float }"},{"name":"State","comment":" You need to store the internal state of the plot in your model.\n\nIt can be as simple as:\n\n    type alias Model =\n        { plotState : Plot.State Point }\n\nor if you have multiple plots on your page:\n\n    type alias Model =\n        { plot1 : Plot.State Point\n        , plot2 : Plot.State Point\n        , plot3 : Plot.State Point\n        }\n\n","args":["data"],"type":"{ mouseDown : Maybe.Maybe data, rangeX : Maybe.Maybe LineChart.Coordinate.Range, rangeY : Maybe.Maybe LineChart.Coordinate.Range, xZoom : ZoomPlot.Zoom, yZoom : ZoomPlot.Zoom, hovered : Maybe.Maybe data, moved : Maybe.Maybe data, movedSinceMouseDown : Basics.Int }"}],"values":[{"name":"defaultConfigWith","comment":" Say that your data is a list of this type:\n\n    type alias ExampleType =\n        { time : Posix\n        , value : Float\n        , text : String\n        , otherValue : Float\n        }\n\nIf you want to plot data like this you can't use `easyConfig`, because it only works with data of type `Point`.\nInstead you will have to use `defaultConfigWith` to create your starting point configuration.\n\nYou need to supply it with two accessor functions (getters), one for each chart coordinate (x and y).\n\n    myDefaultConfig : Plot.Config ExampleType\n    myDefaultConfig =\n        Plot.defaultConfigWith\n            listOfExampleTypes\n            (.time >> Time.posixToMillis >> toFloat)\n            .value\n            myPointDecoder\n\nIt also needs a _point decoder_. The internals of the package needs a way to convert Point back to your type. You basically have to write a function that puts the coordinates of a `Point` into an \"empty\" instance of your type:\n\n    myPointDecoder { x, y } =\n        let\n            decodedX =\n                x |> floor |> Time.millisToPosix\n        in\n        ExampleType decodedX y \"\" 0\n\n","type":"List.List data -> (data -> Basics.Float) -> (data -> Basics.Float) -> (LineChart.Coordinate.Point -> data) -> ZoomPlot.Config data"},{"name":"draw","comment":" Use this function to place your linechart within your view.\n\n    import Element as E\n\n    view model =\n        E.layout [ E.padding 20 ] <|\n            E.el\n                [ E.width <| px 800\n                , E.height <| px 600\n                ]\n            <|\n                Plot.draw\n                    800\n                    600\n                    myConfig\n                    model.plotState\n                    MyPlotMsg\n\nThe first two arguments are width and height, which mostly determines the aspect ratio of your plot since it fills the container you place it in.\n\nSmall dimension values in large containers can make the text in the plot unreasonably large.\n\n","type":"Basics.Float -> Basics.Float -> ZoomPlot.Config data -> ZoomPlot.State data -> (ZoomPlot.Msg data -> msg) -> Element.Element msg"},{"name":"drawHtml","comment":" If you for some reason are not using [mdgriffith/elm-ui](https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest) you can use this draw function instead which outputs regular `Html msg`.\n","type":"Basics.Float -> Basics.Float -> ZoomPlot.Config data -> ZoomPlot.State data -> (ZoomPlot.Msg data -> msg) -> Html.Html msg"},{"name":"easyConfig","comment":" Use this configuration as a starting point when your data is just a `List Point`:\n\n    type alias Point =\n        { x : Float, y : Float }\n\n    points =\n        [ Point 11 120\n        , Point 12 121\n        , Point 13 120.5\n        ]\n\n    myConfig =\n        Plot.easyConfig points\n\n","type":"List.List LineChart.Coordinate.Point -> ZoomPlot.Config LineChart.Coordinate.Point"},{"name":"init","comment":" All plots have the same initial state regardless of individual configuration.\n\n    init : Model\n    init =\n        { plot1 = Plot.init\n        , plot2 = Plot.init\n        , plot3 = Plot.init\n        }\n\n","type":"ZoomPlot.State data"},{"name":"update","comment":" Naturally you need to handle the plot messages in your update function. This is what `Plot.update` is for.\n\n    update : Msg -> Model -> Model\n    update msg model =\n        case msg of\n            MyPlotMsg plotMsg ->\n                { model\n                    | plotState =\n                        Plot.update\n                            myConfig\n                            plotMsg\n                            model.plotState\n                }\n\nIf you need routing to update multiple plots:\n\n    update : Msg -> Model -> ( Model, Cmd Msg )\n    update msg model =\n        case msg of\n            ToPlot Plot1 plotMsg ->\n                ( { model\n                    | plot1 =\n                        Plot.update\n                            plotConfig1\n                            plotMsg\n                            model.plot1\n                  }\n                , Cmd.none\n                )\n\n            ToPlot Plot2 plotMsg ->\n                ( { model\n                    | plot2 =\n                        Plot.update\n                            plotConfig2\n                            plotMsg\n                            model.plot2\n                  }\n                , Cmd.none\n                )\n\n","type":"ZoomPlot.Config data -> ZoomPlot.Msg data -> ZoomPlot.State data -> ZoomPlot.State data"}],"binops":[]}]