gampleman / elm-visualization

A data visualization library for Elm
http://package.elm-lang.org/packages/gampleman/elm-visualization/latest/
MIT License
514 stars 48 forks source link

Examples improvements? #39

Open gampleman opened 5 years ago

gampleman commented 5 years ago

My intuition is that elm-visualization may be a library that is slightly tricky to use for a beginner for the following reasons:

  1. It requires you to do your own rendering and hence assumes knowledge/skill in SVG programming.
  2. There are no high level functions* (i.e. there is no renderBarChart : List (Float, Float) -> Svg msg) and so you are left to figure out how to glue the functions together on your own.

I attempted to solve (2) by providing a gallery of various examples, so that learners can see some sample code on how to achieve various things.

However, I would like to know:

So, if you are a user of elm-visualization, please add your experiences. I'll try to come up with a plan of attack later based on feedback.


tekul commented 5 years ago

The thing that often confuses me with visualization examples is where the data is and what it represents. I'm lazy and I usually want to plug my own data in as quickly as possible without having to change much code. Some of the example code isn't generic enough to be able to do this, which I think makes it harder to reuse immediately.

So, for example, I looked at https://code.gampleman.eu/elm-visualization/NorwegianCarSales/ a while back and saw there was a SampleData module and found that, but the code is quite involved and it's not obvious what it's doing without reading it. It returns a List (List Float) so the temporal information is lost in the data and it's not obvious that it is looking at data from Jan 1st 2007 until the end of 2016. The view function just knows about this and uses the date values internally. As a beginner you can spot this but if other things break it's hard to know where other information might be hard-coded/data-dependent without understanding what every bit does. If the view function was reusable as it stands (I think I added an interval parameter) it might be better.

So I guess the tldr for my ramble would be

sturgman commented 5 years ago

Late to this but here are some thoughts/ideas (brainstorm, so some might be a little crazy):

crharmon commented 5 years ago

Hello. I am a completely new user to elm. I am considering whether it could be used to develop some engineering data displays (line graphs). I believe the examples are missing:

I really like the direction of this project and I hope that I am able learn and use it.

viktor-ferenczi commented 5 years ago

I've just spent a few hours on trying to get a simple line chart working, so-so...

Difficulties faced:

Public API (exposed) function signatures are complex in some cases:

line : (List ( Float, Float ) -> SubPath) -> List (Maybe ( Float, Float )) -> Path

Something like the following would be more readable, at least for beginners:

type alias Curve = List ( Float, Float ) -> SubPath

type alias Points = List (Maybe ( Float, Float ))

line: Curve -> Points -> Path
viktor-ferenczi commented 5 years ago

Python's matplotlib has simple examples in its Gallery

They work as standalone scripts if you copy-paste them.

viktor-ferenczi commented 5 years ago

Example to plot sin x between 0 .. 2*pi:

Dependencies

elm install gampleman/elm-visualization
elm install elm-community/typed-svg

Main.elm

module Main exposing (main)

import Axis
import Browser
import Color exposing (Color)
import Curve
import Path exposing (Path, element)
import Scale
import Shape
import Svg exposing (Svg)
import TypedSvg exposing (g, svg)
import TypedSvg.Attributes as TSA
import TypedSvg.Types exposing (Fill(..), Length(..), Transform(..))

main =
    Browser.sandbox { init = Nothing, update = update, view = view }

update msg model =
    model

view model =
    plot

plot : Svg msg
plot =
    let
        -- Logical chart dimensions
        width =
            320

        height =
            240

        padding =
            32

        -- Scaling
        xScale =
            Scale.linear ( 0, width - 2 * padding ) ( 0, 2 * pi )

        yScale =
            Scale.linear ( height - 2 * padding, 0 ) ( -1, 1 )

        -- Axes
        xAxis =
            Axis.bottom [ Axis.tickCount 10 ] xScale

        yAxis =
            Axis.left [ Axis.tickCount 10 ] yScale

        -- Produce data points
        resolution =
            100

        xs =
            List.map (\i -> 2 * pi * toFloat i / toFloat resolution) <| List.range 0 resolution

        ys =
            List.map (\x -> sin x) xs

        -- Scale data points to logical chart dimensions
        scaledXs =
            List.map (Scale.convert xScale) xs

        scaledYs =
            List.map (Scale.convert yScale) ys

        -- Combine to (x, y) tuples
        chartPoints =
            List.map Just <| List.map2 Tuple.pair scaledXs scaledYs
    in
    -- Create SVG chart
    svg [ TSA.viewBox 0 0 width height ]
        -- Translate axes
        [ g [ TSA.transform [ Translate (padding - 1) (height - padding) ] ]
            [ xAxis ]
        , g [ TSA.transform [ Translate (padding - 1) padding ] ]
            [ yAxis ]

        -- Translate data plot to match axes
        , g [ TSA.transform [ Translate padding padding ] ]
            -- Convert SVG path to element
            [ element
                -- Actual data series as SVG path
                (Shape.line Curve.linear chartPoints)
                [ TSA.stroke Color.blue
                , TSA.strokeWidth (Px 2)
                , TSA.fill <| FillNone
                ]
            ]
        ]

It does not work, because import Path confuses Elm:

-- UNKNOWN IMPORT ------------------------------------------------- src\Main.elm

The Main module has a bad import:

    import Path

I cannot find that module! Is there a typo in the module name?

The "source-directories" field of your elm.json tells me to only look in the src
directory, but it is not there. Maybe it is in a package that is not installed
yet?

In one project it works, but in this new example project it does not. Does it depend on the order of dependencies in elm.json or something similar? How to fix the module name collision problem in a reliable way? Any ideas?

It produces a nice plot wherever it works: image

gampleman commented 4 years ago

@viktor-ferenczi I've attempted to address some of these issues in this commit https://github.com/gampleman/elm-visualization/commit/c69ce3e8886d48849e499c7e666a7a00161dce7a. Basically the short answer is that you will always need some additional dependencies to be productive, but I now link to an environment which is pre-set with these (so copy pasting the examples should just work (except I also need to inline the data)). I also added some text about the most common packages you will need (including folkertdev/one-true-path-experiment, which is what was causing your error here).

sailfish009 commented 4 years ago

it would be useful, if i could use visualization in Element msg. (not Html msg)

-- Oops! never mind. found elm-ui Element html

before: Element.column [...] [ BackgroundGraph.main ]
after: Element.column [...] [ html BackgroundGraph.main ]