Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logarithmic scales - Temporary solution while waiting for the good one #130

Open
lucamug opened this issue Sep 11, 2024 · 0 comments
Open

Comments

@lucamug
Copy link

lucamug commented Sep 11, 2024

I create this issue in case someone is looking for something similar.

Logarithmic scales are in the roadmap https://www.elm-charts.org/administration but if you need something quick in the meantime, this could be a temporary solution:

https://ellie-app.com/scSXWKh7kQQa1

module Main exposing (main)

import Browser
import Chart as C
import Chart.Attributes as CA
import Chart.Events as CE
import Chart.Item as CI
import Html as H
import Html.Attributes as HA


main : Program () Model Msg
main =
    Browser.sandbox
        { init = init
        , view = view
        , update = update
        }


view : Model -> H.Html Msg
view model =
    H.div [ HA.style "font-family" "sans-serif" ]
        [ H.div [ HA.style "display" "flex" ]
            [ H.div [ HA.style "width" "100%", HA.style "margin" "20px 7vw 0 7vw" ]
                [ H.h2 [ HA.style "margin" "0 0 50px 0" ] [ H.text "Linear" ]
                , viewChart
                    { transformX = Nothing
                    , transformY = Nothing
                    }
                    OnHover1
                    model.hovering1
                ]
            , H.div [ HA.style "width" "100%", HA.style "margin" "20px 7vw 0 7vw" ]
                [ H.h2 [ HA.style "margin" "0 0 50px 0" ] [ H.text "Log Y" ]
                , viewChart
                    { transformX = Nothing
                    , transformY = Just { t1 = logarithmic, t2 = exponential }
                    }
                    OnHover2
                    model.hovering2
                ]
            , H.div [ HA.style "width" "100%", HA.style "margin" "20px 7vw 0 7vw" ]
                [ H.h2 [ HA.style "margin" "0 0 50px 0" ] [ H.text "Log XY" ]
                , viewChart
                    { transformX = Just { t1 = logarithmic, t2 = exponential }
                    , transformY = Just { t1 = logarithmic, t2 = exponential }
                    }
                    OnHover3
                    model.hovering3
                ]
            ]
        , H.div [ HA.style "margin" "50px 7vw 0 7vw" ] [ H.text <| Debug.toString data ]
        ]


type alias Hovering =
    List (CI.One Datum CI.Dot)


type alias Model =
    { hovering1 : Hovering
    , hovering2 : Hovering
    , hovering3 : Hovering
    }


init : Model
init =
    { hovering1 = []
    , hovering2 = []
    , hovering3 = []
    }


type Msg
    = OnHover1 Hovering
    | OnHover2 Hovering
    | OnHover3 Hovering


update : Msg -> Model -> Model
update msg model =
    case msg of
        OnHover1 hovering ->
            { model | hovering1 = hovering }

        OnHover2 hovering ->
            { model | hovering2 = hovering }

        OnHover3 hovering ->
            { model | hovering3 = hovering }


type alias Datum =
    { x : Float
    , y1 : Float
    , y2 : Float
    }


data : List Datum
data =
    [ { x = 1, y1 = 1, y2 = 100 }
    , { x = 10, y1 = 10, y2 = 1000 }
    , { x = 100, y1 = 100, y2 = 10000 }
    , { x = 1000, y1 = 1000000, y2 = 100000 }
    ]


viewChart :
    { transformX : Maybe { t1 : Float -> Float, t2 : Float -> Float }
    , transformY : Maybe { t1 : Float -> Float, t2 : Float -> Float }
    }
    -> (Hovering -> Msg)
    -> Hovering
    -> H.Html Msg
viewChart { transformX, transformY } msg hovering =
    let
        f : Maybe t -> (t -> (float -> float)) -> (float -> float)
        f maybeArg func =
            case maybeArg of
                Just arg ->
                    func arg

                Nothing ->
                    identity

        tX1 : Float -> Float
        tX1 =
            f transformX .t1

        tX2 : Float -> String
        tX2 =
            String.fromFloat << f transformX .t2

        tY1 : Float -> Float
        tY1 =
            f transformY .t1

        tY2 : Float -> String
        tY2 =
            String.fromFloat << f transformY .t2
    in
    C.chart
        [ CE.onMouseMove msg (CE.getNearest CI.dots)
        , CE.onMouseLeave (msg [])
        ]
        [ C.xLabels
            [ CA.withGrid
            , CA.format tX2
            ]
        , C.yLabels
            [ CA.withGrid
            , CA.format tY2
            ]
        , C.series (tX1 << .x)
            [ C.interpolated (tY1 << .y1) [] [ CA.cross, CA.size 10 ]
            , C.interpolated (tY1 << .y2) [] [ CA.circle, CA.size 10 ]
            ]
            data
        , C.dotLabels
            [ CA.moveUp 10
            , CA.format (\dot -> tY2 <| CI.getY dot)
            ]
        , C.each hovering <|
            \plane dot ->
                [ C.tooltip dot
                    []
                    [ HA.style "color" (CI.getColor dot) ]
                    [ H.text "x: "
                    , H.text (tX2 <| CI.getX dot)
                    , H.text " y: "
                    , H.text (tY2 <| CI.getY dot)
                    ]
                ]
        ]


base : Float
base =
    10


exponential : Float -> Float
exponential n =
    toFloat (round <| (base ^ n))


logarithmic : Float -> Float
logarithmic number =
    logBase base number
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant