gampleman/elm-visualization/1.0.0

NOTE: this package is not compatible with Elm 0.19.1

Visualization.Shape

Visualizations typically consist of discrete graphical marks, such as symbols, arcs, lines and areas. While the rectangles of a bar chart may be easy enough to generate directly using SVG or Canvas, other shapes are complex, such as rounded annular sectors and centripetal Catmull–Rom splines. This module provides a variety of shape generators for your convenience.

Note: Currently only rudimentary forms are implemented.

Lines

line : (Curve -> List PathSegment) -> List (Maybe Point) -> String

Generates a line for the given array of points which can be passed to the d attribute of the path SVG element. It needs to be suplied with a curve function. Points accepted are Maybes, Nothing represent gaps in the data and corresponding gaps will be rendered in the line.

Note: A single point (surrounded by Nothing) may not be visible.

Usually you will need to convert your data into a format supported by this function. For example, if your data is a List (Date, Float), you might use something like:

lineGenerator : ( Date, Float ) -> Maybe ( Float, Float )
lineGenerator ( x, y ) =
    Just ( Scale.convert xScale x, Scale.convert yScale y )


linePath : List (Date, Float) -> String
linePath data =
    List.map lineGenerator data
        |> Shape.line Shape.linearCurve

where xScale and yScale would be appropriate Scales.

(Curve -> List PathSegment)
-> List (Maybe ( Point, Point ))
-> String

The area generator produces an area, as in an area chart. An area is defined by two bounding lines, either splines or polylines. Typically, the two lines share the same x-values (x0 = x1), differing only in y-value (y0 and y1); most commonly, y0 is defined as a constant representing zero. The first line (the topline) is defined by x1 and y1 and is rendered first; the second line (the baseline) is defined by x0 and y0 and is rendered second, with the points in reverse order. With a linearCurve curve, this produces a clockwise polygon.

The data attribute you pass in should be a [Just ((x0, y0), (x1, y1))]. Passing in Nothing represents gaps in the data and corresponding gaps in the area will be rendered.

Usually you will need to convert your data into a format supported by this function. For example, if your data is a List (Date, Float), you might use something like:

areaGenerator : ( Date, Float ) -> Maybe ( ( Float, Float ), ( Float, Float ) )
areaGenerator ( x, y ) =
    Just ( ( Scale.convert xScale x, fst (Scale.rangeExtent yScale) ),
           ( Scale.convert xScale x, Scale.convert yScale y ) )


areaPath : List (Date, Float) -> String
areaPath data =
    List.map areaGenerator data
        |> Shape.area Shape.linearCurve

where xScale and yScale would be appropriate Scales.

Curves

linearCurve : Curve -> List PathSegment

Produces a polyline through the specified points.

monotoneInXCurve : Curve -> List PathSegment

Produces a cubic spline that preserves monotonicity in y, assuming monotonicity in x, as proposed by Steffen in A simple method for monotonic interpolation in one dimension: “a smooth curve with continuous first-order derivatives that passes through any given set of data points without spurious oscillations. Local extrema can occur only at grid points where they are given by the data, but not in between two adjacent grid points.”

type Curve

A curve is represented as a list of points, which a curve function can turn into drawing commands.