Alpha version!
Make sure to check out the many examples at elm-charts.org.
The configuration of this charting library mirrors the pattern of HTML elements and attributes. It looks something like this:
import Html exposing (Html)
import Chart as C
import Chart.Attributes as CA
view : Html msg
view =
C.chart
[ CA.width 300
, CA.height 300
]
[ C.xTicks []
, C.yTicks []
, C.xLabels []
, C.yLabels []
, C.bars []
[ C.bar .income [ CA.color "red" ]
, C.bar .spending [ CA.opacity 0.8 ]
]
data
]All the elements, like chart, xTicks, yTicks, xLabels, yLabels, bars and bar in the example
above, and many others, are defined in this module. All the attributes, like width, height, color, and opacity,
are defined in Chart.Attributes. Attributes related to events are located in
the Chart.Events module. Functions for working with rendered chart items are located in Chart.Item.
Lastly, Chart.Svg holds charting primitives in case you have very special needs.
In the examples throughout the documentation, I will assume the imports:
import Html as H exposing (Html)
import Html.Attributes as HA
import Html.Events as HE
import Svg as S
import Svg.Attributes as SA
import Svg.Events as SE
import Chart as C
import Chart.Attributes as CA
import Chart.Events as CE
import Chart.Item as CIThe representation of a chart element.
Add a bar series to your chart. Here's some handy terminology:

Each data in your List data is a "bin". For
each "bin", whatever number of bars your have specified in the second argument will
show up, side-by-side.
C.bars []
[ C.bar .income []
, C.bar .spending []
]
[ { income = 10, spending = 2 }
, { income = 12, spending = 6 }
, { income = 18, spending = 16 }
]The example above will thus produce three bins, each containing two bars. You can make
your bars show up overlapping instead of side-by-side by using the CA.ungroup
attribute:
C.bars
[ CA.ungroup ]
[ C.bar .total []
, C.bar .gross []
, C.bar .net []
]
[ { net = 10, gross = 20, total = 50 }
, { net = 13, gross = 28, total = 63 }
, { net = 16, gross = 21, total = 82 }
]By default, the x value of each bin is set by a simple count. The first bin is set at
x = 1, the second at x = 2, and so on. If you'd like to control what the x values of
your bins are, e.g. you are making a histogram, you may use the CA.x1 and CA.x2
attributes, as illustrated below.
C.bars
[ CA.x1 .score
, CA.x2 (\datum -> datum.score + 20)
]
[ C.bar .students [] ]
[ { score = 0, students = 1 }
, { score = 20, students = 10 }
, { score = 40, students = 30 }
, { score = 60, students = 20 }
, { score = 80, students = 1 }
]In this case, you actually only need to specify either x1 or x2 because the library
estimates the unknown x value based on the size of the previous or next bin. However, it comes in
handy to specify both when you have bins of irregular sizes.
The rest of the configuration options concern styling:
C.bars
[ CA.spacing 0.1 -- The spacing _between_ the bars in each bin relative to the full length (1).
, CA.margin 0.2 -- The spacing _around_ the bars in each bin relative to the full length (1).
, CA.roundTop 0.2 -- The rounding of your bars' top corners. It gets weird after around 0.5.
, CA.roundBottom 0.2 -- The rounding of your bars' bottom corners. It gets weird after around 0.5.
, CA.withGrid -- Add grid lines at the bin limits.
]
[ C.bar .income []
, C.bar .spending []
]
[ { income = 10, spending = 2 }
, { income = 12, spending = 6 }
, { income = 18, spending = 16 }
]Explore live examples for the following attributes:
This is just like bars, but it maps your data. This is useful if you have
several kinds of data types present in your chart.
type Datum
= Money { year : Float, income : Float }
| People { year : Float, people : Float }
view : Html msg
view =
C.chart []
[ C.barsMap Money
[ CA.x1 .year ]
[ C.bar .income [] ]
[ { year = 2000, income = 200 }
, { year = 2010, income = 300 }
, { year = 2020, income = 500 }
]
, C.barsMap People
[ CA.x1 .year ]
[ C.bar .people [] ]
[ { year = 2000, people = 21 }
, { year = 2010, people = 65 }
, { year = 2020, people = 93 }
]
]Specify the configuration of a bar. The first argument will determine the height of your bar. The second is a list of styling attributes. The example below illustrates what styling options are available.
C.chart []
[ C.bars []
[ C.bar .income
[ CA.color "blue" -- Change the color
, CA.border "darkblue" -- Change the border color
, CA.borderWidth 2 -- Change the border width
, CA.opacity 0.7 -- Change the border opacity
-- A bar can either be solid (default), striped, dotted, or gradient.
, CA.striped
[ CA.width 2 -- Width of each stripe
, CA.spacing 3 -- Spacing bewteen each stripe
, CA.color "blue" -- Color of stripe
, CA.rotate 90 -- Angle of stripe
]
, CA.dotted []
-- Same configurations as `striped`
, CA.gradient
[ "blue", "darkblue" ] -- List of colors in gradient
, CA.roundTop 0.2 -- Round the top corners
, CA.roundBottom 0.2 -- Round the bottom corners
-- You can highlight a bar or a set of bars by adding a kind of "aura" to it.
, CA.highlight 0.5 -- Determine the opacity of the aura
, CA.highlightWidth 5 -- Determine the width of the aura
, CA.highlightColor "blue" -- Determine the color of the aura
-- Add arbitrary SVG attributes to your bar
, CA.attrs [ SA.strokeOpacity "0.5" ]
]
]
[ { income = 10 }
, { income = 12 }
, { income = 18 }
]
]Explore live examples for the following attributes:
Same as bar, but allows for missing data.
C.chart []
[ C.bars []
[ C.barMaybe .income [] ]
[ { income = Just 10 }
, { income = Nothing }
, { income = Just 18 }
]
]Add a scatter or line series to your chart. Each data in your List data will result in one "dot".
The first argument of series determines the x value of each dot. The y value and all styling configuration
is determined by the list of interpolated or scatter properties defined in the second argument.
C.series .age
[ C.interpolated .height [] []
, C.interpolated .weight [] []
]
[ { age = 0, height = 40, weight = 4 }
, { age = 5, height = 80, weight = 24 }
, { age = 10, height = 120, weight = 36 }
, { age = 15, height = 180, weight = 54 }
, { age = 20, height = 184, weight = 60 }
]See interpolated and scatter for styling options.
This is just like series, but it maps your data. This is useful if you have
several kinds of data types present in your chart.
type Datum
= Height { age : Float, height : Float }
| Weight { age : Float, weight : Float }
view : Html msg
view =
C.chart []
[ C.seriesMap Height .age
[ C.interpolated .height [] ]
[ { age = 0, height = 40 }
, { age = 5, height = 80 }
, { age = 10, height = 120 }
, { age = 15, height = 180 }
]
, C.seriesMap Weight .age
[ C.interpolated .weight [] ]
[ { age = 0, weight = 4 }
, { age = 5, weight = 24 }
, { age = 10, weight = 36 }
, { age = 15, weight = 54 }
]
]Specify the configuration of a set of dots. The first argument will determine the y value of your dots. The second is a list of styling attributes. The example below illustrates what styling options are available.
C.series .year
[ C.scatter .income
[ CA.size 10 -- Change size of dot
, CA.color "blue" -- Change color
, CA.opacity 0.8 -- Change opacity
, CA.border "lightblue" -- Change border color
, CA.borderWidth 2 -- Change border width
-- You can highlight a dot or a set of dots by adding a kind of "aura" to it.
, CA.highlight 0.3 -- Determine the opacity of the aura
, CA.highlightWidth 6 -- Determine the width of the aura
, CA.highlightColor "blue" -- Determine the color of the aura
-- A dot is by default a circle, but you can change it to any
-- of the shapes below.
, CA.triangle
, CA.square
, CA.diamond
, CA.plus
, CA.cross
]
]
[ { year = 2000, income = 40000 }
, { year = 2010, income = 57000 }
, { year = 2020, income = 62000 }
]Explore live examples for the following attributes:
Same as scatter, but allows for missing data.
C.chart []
[ C.series .year
[ C.scatterMaybe .income [] ]
[ { year = 2000, income = Just 40000 }
, { year = 2010, income = Nothing }
, { year = 2020, income = Just 62000 }
]
]Specify the configuration of a interpolated series (a line). The first argument will determine the y value of your dots. The second is a list of attributes pertaining to your interpolation. The third argument is a list of attributes pertaining to the dots of your series.
The example below illustrates what styling options are available.
C.series .age
[ C.interpolated .height
[ -- The following attributes allow alternatives to the default
-- linear interpolation.
CA.monotone -- Use a monotone interpolation (looks smooth)
, CA.stepped -- Use a stepped interpolation (looks like stairs)
, CA.color "blue"
, CA.width 2
, CA.dashed [ 4, 4 ]
-- The area beneath the curve is by default transparent, but you
-- can change the opacity of it, or make it striped, dotted, or gradient.
, CA.opacity 0.5
, CA.striped
[ CA.width 2 -- Width of each stripe
, CA.spacing 3 -- Spacing bewteen each stripe
, CA.color "blue" -- Color of stripe
, CA.rotate 90 -- Angle of stripe
]
, CA.dotted [] -- Same configurations as `striped`
, CA.gradient [ "blue", "darkblue" ] -- List of colors in gradient
-- Add arbitrary SVG attributes to your line
, CA.attrs [ SA.id "my-chart" ]
]
[]
]
[ { age = 0, height = 40 }
, { age = 5, height = 80 }
, { age = 10, height = 120 }
, { age = 15, height = 180 }
, { age = 20, height = 184 }
]Explore live examples for the following attributes:
Same as interpolated, but allows for missing data.
C.chart []
[ C.series .age
[ C.interpolatedMaybe .height [] ]
[ { age = 0, height = Just 40 }
, { age = 5, height = Nothing }
, { age = 10, height = Just 120 }
, { age = 15, height = Just 180 }
, { age = 20, height = Just 184 }
]
]See live example of missing data in line chart.
A property of a bar, line, or scatter series.
Stack a set of bar or line series.
C.chart []
[ C.bars []
[ C.stacked
[ C.bar .cats []
, C.bar .dogs []
]
]
[ { cats = 2, dogs = 4 }
, { cats = 3, dogs = 2 }
, { cats = 6, dogs = 1 }
]
]See live example.
Change the style of your bars or dots based on the index of its data point and the data point itself.
C.chart []
[ C.series .year
[ C.scatter .income [ CA.opacity 0.6 ]
|> C.variation (\index datum -> [ CA.size datum.people ])
]
[ { year = 2000, income = 40000, people = 150 }
, { year = 2010, income = 48000, people = 98 }
, { year = 2020, income = 62000, people = 180 }
]
]See live example.
Change the style of your bars or dots based on whether it is a member
of the group of products which you list. A such group of products can be
attrained through events like Chart.Events.onMouseMove or similar.
C.chart
[ CE.onMouseMove OnHover (CE.getNearest CI.dots) ]
[ C.series .year
[ C.scatter .income [ CA.opacity 0.6 ]
|> C.amongst model.hovering (\datum -> [ CA.highlight 0.5 ])
]
[ { year = 2000, income = 40000, people = 150 }
, { year = 2010, income = 48000, people = 98 }
, { year = 2020, income = 62000, people = 180 }
]
]See live example.
Name a bar, scatter, or interpolated series. This name will show up in the default tooltip, and you can use it to identify items from this series.
C.chart []
[ C.series .year
[ C.scatter .income []
|> C.named "Income"
]
[ { year = 2000, income = 40000 }
, { year = 2010, income = 48000 }
, { year = 2020, income = 62000 }
]
]See live example.
Easily format the value which shows up by default in your tooltip if you add one. You
can also access it using Chart.Item.getTooltipValue.
See live example.
Like format, except it allows you customize the formatting of missing values too!
Add an x-axis line to your chart. The example below illustrates the styling options:
C.chart []
[ C.xAxis
[ CA.color "red" -- Change color of line
, CA.width 2 -- Change width of line
, CA.noArrow -- Remove arrow from line
, CA.pinned .max -- Change what y position the axis is set at
-- .max is at the very top
-- .min is at the very bottom
-- CA.zero is the closest you can go to zero
-- (always 3) is at y = 3.
, CA.limits
[ CA.lowest 2 CA.exactly
, CA.highest 8 CA.exactly
]
-- Change from where to where you line goes.
-- The example will make a line where x1 = 2 to x2 = 8
]
]Explore live examples for the following attributes:
Add an y-axis line to your chart. The styling options are the same
as for xAxis.
Produce a set of ticks at "nice" numbers on the x-axis of your chart. The example below illustrates the configuration:
C.chart []
[ C.xTicks
[ CA.color "red" -- Change color
, CA.height 8 -- Change height
, CA.width 2 -- Change width
, CA.amount 15 -- Change amount of ticks
, CA.flip -- Flip to opposite direction
, CA.noGrid -- By default a grid line is added
-- for each tick. This removes them.
, CA.ints -- Add ticks at "nice" ints
, CA.times Time.utc -- Add ticks at "nice" times
, CA.pinned .max -- Change what y position the ticks are set at
-- .max is at the very top
-- .min is at the very bottom
-- CA.zero is the closest you can go to zero
-- (always 3) is at y = 3.
, CA.limits
[ CA.lowest 2 CA.exactly
, CA.highest 8 CA.exactly
]
-- Change the upper and lower limit of your tick range.
-- The example will add ticks between x = 2 and 8.
]
]Explore live examples for the following attributes:
Produce a set of ticks at "nice" numbers on the y-axis of your chart.
The styling options are the same as for xTicks.
Produce a set of labels at "nice" numbers on the x-axis of your chart. The example below illustrates the configuration:
C.chart []
[ C.xLabels
[ CA.color "red" -- Change color
, CA.fontSize 12 -- Change font size
, CA.uppercase -- Make labels uppercase
, CA.rotate 90 -- Rotate labels
, CA.alignRight -- Anchor labels to the right
, CA.alignLeft -- Anchor labels to the left
, CA.moveUp 5 -- Move 5 SVG units up
, CA.moveDown 5 -- Move 5 SVG units down
, CA.moveLeft 5 -- Move 5 SVG units left
, CA.moveRight 5 -- Move 5 SVG units right
, CA.amount 15 -- Change amount of ticks
, CA.flip -- Flip to opposite direction
, CA.withGrid -- Add grid line by each label.
, CA.ints -- Add ticks at "nice" ints
, CA.times Time.utc -- Add ticks at "nice" times
, CA.format (\num -> String.fromFloat num ++ "°")
-- Format the "nice" number
, CA.ellipsis 40 10
-- Add ellipsis. Arguments are width and height of label.
-- Note: There is no SVG feature for ellipsis, so this
-- turns labels into HTML.
, CA.pinned .max -- Change what y position the labels are set at
-- .max is at the very top
-- .min is at the very bottom
-- CA.zero is the closest you can go to zero
-- (always 3) is at y = 3.
, CA.limits
[ CA.lowest 2 CA.exactly
, CA.highest 8 CA.exactly
]
-- Change the upper and lower limit of your labels range.
-- The example will add labels between x = 2 and 8.
]
]Explore live examples for the following attributes:
For more in depth and irregular customization, see xLabel or check out
the custom labels example.
Produce a set of labels at "nice" numbers on the y-axis of your chart.
The styling options are the same as for xLabels.
Add a custom grid to your chart.
C.chart []
[ C.grid [ CA.width 2 ]
, C.xTicks []
, C.yTicks []
]Grid lines are added by default where ticks are added. You can add
grid lines to where your labels are using the CA.withGrid attribute:
C.yLabels [ CA.withGrid ]Customizations:
C.grid
[ CA.color "blue" -- Change color
, CA.width 3 -- Change width
, CA.dashed [ 5, 5 ] -- Add dashing (only for line grids)
, CA.dotGrid -- Use dot grid instead of line grid
]Produce a single x label. This is typically for cases where you need
very custom labels and xLabels does not cut it. It is especially useful
in combination with the generate helper. An example use case:
C.chart []
[ -- Create labels for 10 "nice" integers on the x-axis
-- and highlight the label at x = 0.
C.generate 10 C.ints .x [] <| \plane int ->
let color = if int == 0 then "red" else "gray" in
[ C.xLabel
[ CA.x (toFloat int), CA.color color ]
[ S.text (String.fromInt int) ]
]
]A full list of possible attributes:
C.chart []
[ C.xLabel
[ CA.x 5 -- Set x coordinate
, CA.y 8 -- Set y coordinate
, CA.moveUp 5 -- Move 5 SVG units up
, CA.moveDown 5 -- Move 5 SVG units down
, CA.moveLeft 5 -- Move 5 SVG units left
, CA.moveRight 5 -- Move 5 SVG units right
, CA.border "white" -- Set stroke color
, CA.borderWidth 0.5 -- Set stroke width
, CA.fontSize 12 -- Set font size
, CA.color "red" -- Set color
, CA.alignRight -- Anchor labels to the right
, CA.alignLeft -- Anchor labels to the left
, CA.rotate 90 -- Rotate label 90 degrees
, CA.uppercase -- Make uppercase
, CA.flip -- Flip to opposite direction
, CA.ellipsis 40 10
-- Add ellipsis. Arguments are width and height of label.
-- Note: There is no SVG feature for ellipsis, so this
-- turns labels into HTML.
, CA.withGrid -- Add grid line by each label.
]
[ S.text "hello!" ]
]See also the custom labels example.
Produce a single y label. This is typically for cases where you need
very custom labels and yLabels does not cut it. See xLabel for
usage and customization.
Produce a single x tick. This is typically for cases where you need
very custom ticks and xTicks does not cut it. It is especially useful
in combination with the generate helper. An example use case:
C.chart []
[ -- Create ticks for 10 "nice" integers on the x-axis
-- and highlight the tick at x = 0.
C.generate 10 C.ints .x [] <| \plane int ->
let color = if int == 0 then "red" else "gray" in
[ C.xTick [ CA.x (toFloat int), CA.color color ] ]
]A full list of possible attributes:
C.xTick
[ CA.x 5 -- Set x coordinate
, CA.y 8 -- Set y coordinate
, CA.color "red" -- Change color
, CA.height 8 -- Change height
, CA.width 2 -- Change width
, CA.amount 15 -- Change amount of ticks
, CA.flip -- Flip to opposite direction
, CA.noGrid -- By default a grid line is added
-- for each tick. This removes them.
]Produce a single y tick. This is typically for cases where you need
very custom ticks and yTicks does not cut it. See xTick for
usage and customization.
Generate "nice" numbers. Useful in combination with xLabel, yLabel, xTick, and yTick.
C.chart []
[ C.generate 10 C.ints .x [ CA.lowest -5 CA.exactly, CA.highest 15 CA.exactly ] <| \plane int ->
[ C.xTick [ CA.x (toFloat int) ]
, C.xLabel [ CA.x (toFloat int) ] [ S.text (String.fromInt int) ]
]
]The example above generates 10 ints on the x axis between x = -5 and x = 15. For each of those ints, it adds a tick and a label.
See live example.
Generate "nice" floats.
Generate "nice" ints.
Generate "nice" times.
See the docs in terezka/intervals
for more info about the properties of Time!
Add labels by every bin.
C.chart []
[ C.bars [] [ C.bar .income [] ]
[ { name = "Anna", income = 60 }
, { name = "Karenina", income = 70 }
, { name = "Jane", income = 80 }
]
, C.binLabels .name [ CA.moveDown 15 ]
]Attributes you can use:
C.binLabels .name
[ CA.moveUp 5 -- Move 5 SVG units up
, CA.moveDown 5 -- Move 5 SVG units down
, CA.moveLeft 5 -- Move 5 SVG units left
, CA.moveRight 5 -- Move 5 SVG units right
, CA.color "#333"
, CA.border "white"
, CA.borderWidth 1
, CA.fontSize 12
, CA.alignRight -- Anchor labels to the right
, CA.alignLeft -- Anchor labels to the left
, CA.rotate 90 -- Rotate label 90 degrees
, CA.uppercase -- Make uppercase
-- Add arbitrary SVG attributes to your labels.
, CA.attrs [ SA.class "my-bin-labels" ]
-- Edit the position of the label
, CA.position CI.getTop
-- Given the entire bin item (not just the data)
-- produce a string.
, CA.format (\bin -> String.fromFloat (CI.getShared bin).start)
]See live example.
Add labels by every bar.
C.chart []
[ C.bars []
[ C.bar .income [] ]
[ { name = "Anna", income = 60 }
, { name = "Karenina", income = 70 }
, { name = "Jane", income = 80 }
]
, C.barLabels [ CA.moveUp 6 ]
]Attributes you can use:
C.barLabels
[ CA.moveUp 5 -- Move 5 SVG units up
, CA.moveDown 5 -- Move 5 SVG units down
, CA.moveLeft 5 -- Move 5 SVG units left
, CA.moveRight 5 -- Move 5 SVG units right
, CA.color "#333"
, CA.border "white"
, CA.borderWidth 1
, CA.fontSize 12
, CA.alignRight -- Anchor labels to the right
, CA.alignLeft -- Anchor labels to the left
, CA.rotate 90 -- Rotate label 90 degrees
, CA.uppercase -- Make uppercase
-- Add arbitrary SVG attributes to your labels.
, CA.attrs [ SA.class "my-bar-labels" ]
-- Edit the position of the label
, CA.position CI.getTop
-- Change the text of the label
, CA.format (\bar -> String.fromFloat (CI.getY bar))
]See live example.
Add labels by every bar.
C.chart []
[ C.series .age
[ C.scatter .income [] ]
[ { age = 34, income = 60 }
, { age = 42, income = 70 }
, { age = 48, income = 80 }
]
, C.dotLabels CI.getCenter [ CA.moveUp 6 ]
]Attributes you can use:
C.dotLabels
[ CA.moveUp 5 -- Move 5 SVG units up
, CA.moveDown 5 -- Move 5 SVG units down
, CA.moveLeft 5 -- Move 5 SVG units left
, CA.moveRight 5 -- Move 5 SVG units right
, CA.color "#333"
, CA.border "white"
, CA.borderWidth 1
, CA.fontSize 12
, CA.alignRight -- Anchor labels to the right
, CA.alignLeft -- Anchor labels to the left
, CA.rotate 90 -- Rotate label 90 degrees
, CA.uppercase -- Make uppercase
-- Add arbitrary SVG attributes to your labels.
, CA.attrs [ SA.class "my-dot-labels" ]
-- Edit the position of the label
, CA.position CI.getTop
-- Change the text of the label
, CA.format (\dot -> String.fromFloat (CI.getY dot))
]See live example.
Helper to add a label by a particular product.
C.chart
[ CE.onMouseMove OnHover (CE.getNearest CI.bars) ]
[ C.bars []
[ C.bar .income [] ]
[ { name = "Anna", income = 60 }
, { name = "Karenina", income = 70 }
, { name = "Jane", income = 80 }
]
, C.each model.hovering <| \_ bar ->
[ C.productLabel [ CA.moveUp 6 ] bar ]
]Attributes you can use:
C.productLabel
[ CA.moveUp 5 -- Move 5 SVG units up
, CA.moveDown 5 -- Move 5 SVG units down
, CA.moveLeft 5 -- Move 5 SVG units left
, CA.moveRight 5 -- Move 5 SVG units right
, CA.color "#333"
, CA.border "white"
, CA.borderWidth 1
, CA.fontSize 12
, CA.alignRight -- Anchor labels to the right
, CA.alignLeft -- Anchor labels to the left
, CA.rotate 90 -- Rotate label 90 degrees
, CA.uppercase -- Make uppercase
-- Add arbitrary SVG attributes to your labels.
, CA.attrs [ SA.class "my-bar-labels" ]
-- Edit the position of the label
, CA.position CI.getTop
-- Change the text of the label
, CA.format (\bar -> String.fromFloat (CI.getY bar))
]
productAdd a label, such as a chart title or other note, at a specific coordinate.
C.chart []
[ C.label [] [ S.text "Data from Fruits.com" ] { x = 5, y = 10 } ]The example above adds your label at coordinates x = y and y = 10.
Other attributes you can use:
C.labelAt
[ CA.moveUp 5 -- Move 5 SVG units up
, CA.moveDown 5 -- Move 5 SVG units down
, CA.moveLeft 5 -- Move 5 SVG units left
, CA.moveRight 5 -- Move 5 SVG units right
, CA.color "#333"
, CA.border "white"
, CA.borderWidth 1
, CA.fontSize 12
, CA.alignRight -- Anchor labels to the right
, CA.alignLeft -- Anchor labels to the left
, CA.rotate 90 -- Rotate label 90 degrees
, CA.uppercase -- Make uppercase
, CA.ellipsis 40 10
-- Add ellipsis. Arguments are width and height of label.
-- Note: There is no SVG feature for ellipsis, so this
-- turns labels into HTML.
-- Add arbitrary SVG attributes to your labels.
, CA.attrs [ SA.class "my-label" ]
]
[ S.text "Data from Fruits.com" ]
{ x = 5, y = 10 }Add a label, such as a chart title or other note, at a position relative to your axes.
C.chart []
[ C.labelAt (CA.percent 20) (CA.percent 90) [] [ S.text "Data from Fruits.com" ] ]The example above adds your label at 20% the length of your range and 90% of your domain.
Other attributes you can use:
C.labelAt (CA.percent 20) (CA.percent 90)
[ CA.moveUp 5 -- Move 5 SVG units up
, CA.moveDown 5 -- Move 5 SVG units down
, CA.moveLeft 5 -- Move 5 SVG units left
, CA.moveRight 5 -- Move 5 SVG units right
, CA.color "#333"
, CA.border "white"
, CA.borderWidth 1
, CA.fontSize 12
, CA.alignRight -- Anchor labels to the right
, CA.alignLeft -- Anchor labels to the left
, CA.rotate 90 -- Rotate label 90 degrees
, CA.uppercase -- Make uppercase
-- Add arbitrary SVG attributes to your labels.
, CA.attrs [ SA.class "my-label" ]
]
[ S.text "Data from Fruits.com" ]See live example.
Add legends to your chart.
C.chart []
[ C.series .x
[ C.line .y [] []
|> C.named "cats"
, C.line .y [] []
|> C.named "dogs"
]
, C.legendsAt .min .max
[ CA.column -- Appear as column instead of row
, CA.alignRight -- Anchor legends to the right
, CA.alignLeft -- Anchor legends to the left
, CA.moveUp 5 -- Move 5px up
, CA.moveDown 5 -- Move 5px down
, CA.moveLeft 5 -- Move 5px left
, CA.moveRight 5 -- Move 5px right
, CA.spacing 20 -- Spacing between legends
, CA.background "beige" -- Color background
, CA.border "gray" -- Add border
, CA.borderWidth 1 -- Set border width
-- Add arbitrary HTML attributes. Convinient for extra styling.
, CA.htmlAttrs [ HA.class "my-legend" ]
]
[ CA.width 30 -- Change width of legend window
, CA.height 30 -- Change height of legend window
, CA.fontSize 12 -- Change font size
, CA.color "red" -- Change font color
, CA.spacing 12 -- Change spacing between window and title
, CA.htmlAttrs [ HA.class "my-legends" ] -- Add arbitrary HTML attributes.
]
]See live example:
Add a tooltip for a specific item.
C.chart
[ CE.onMouseMove OnHover (CE.getNearest CI.any) ]
[ C.series .year
[ C.scatter .income [] ]
[ { year = 2000, income = 40000 }
, { year = 2010, income = 56000 }
, { year = 2020, income = 62000 }
]
, C.each model.hovering <| \plane product ->
[ C.tooltip product [] [] [] ]
]Customizations:
C.tooltip item
[ -- Change direction
CA.onTop -- Always place tooltip on top of the item
, CA.onBottom -- Always place tooltip below of the item
, CA.onRight -- Always place tooltip on the right of the item
, CA.onLeft -- Always place tooltip on the left of the item
, CA.onLeftOrRight -- Place tooltip on the left or right of the item,
-- depending on which side has more space available
, CA.onTopOrBottom -- Place tooltip on the top or bottom of the item,
-- depending on which side has more space available
-- Change focal point (where on the item the tooltip is achored)
, CA.top
, CA.bottom
, CA.left
, CA.right
, CA.center
, CA.topLeft
, CA.topRight
, CA.topCenter
, CA.bottomLeft
, CA.bottomRight
, CA.bottomCenter
, CA.leftCenter
, CA.rightCenter
, CA.offset 20 -- Change offset between focal point and tooltip
, CA.noArrow -- Remove little box arrow
, CA.border "blue" -- Change border color
, CA.background -- Change background color
]
[] -- Add any HTML attributes
[] -- Add any HTML children (Will be filled with default tooltip if left empty)Explore live examples for the following attributes:
See also example of custom formatting and example of custom content and the other examples pertaining to interactivity.
Add a line.
C.chart []
[ C.line
[ CA.x1 2 -- Set x1
, CA.x2 8 -- Set x2
, CA.y1 3 -- Set y1
, CA.y2 7 -- Set y2
-- Instead of specifying x2 and y2
-- you can use `x2Svg` and `y2Svg`
-- to specify the end coordinate in
-- terms of SVG units.
--
-- Useful if making little label pointers.
-- This makes a from ( x1, y1 ) to the point
-- ( x1 + 15 SVG units, y1 + 30 SVG units )
, CA.x2Svg 15
, CA.y2Svg 30
, CA.break -- "break" line, so it it has a 90° angle
, CA.flip -- flip break to opposite direction
, CA.tickLength -- Add "ticks" at the ends of the line
, CA.tickDirection -- The angle of the ticks
, CA.color "red" -- Change color
, CA.width 2 -- Change width
, CA.opacity 0.8 -- Change opacity
, CA.dashed [ 5, 5 ] -- Add dashing
-- Add arbitrary SVG attributes.
, CA.attrs [ SA.id "my-line" ]
]
]See live example.
Add a rectangle.
C.chart []
[ C.rect
[ CA.x1 2 -- Set x1
, CA.x2 8 -- Set x2
, CA.y1 3 -- Set y1
, CA.y2 7 -- Set y2
, CA.color "#aaa" -- Change fill color
, CA.opacity 0.8 -- Change fill opacity
, CA.border "#333" -- Change border color
, CA.borderWidth 2 -- Change border width
-- Add arbitrary SVG attributes.
, CA.attrs [ SA.id "my-rect" ]
]
]See live example.
Add arbitrary SVG at a specific location. See Chart.Svg for handy SVG helpers.
C.chart []
[ C.svgAt .min .max 10 20 [ .. ]
-- Add .. at x = the minumum value of your range (x-axis) + 12 SVG units
-- and y = the maximum value of your domain (y-axis) + 20 SVG units
]Add arbitrary HTML at a specific location.
See live example.
Add arbitrary SVG. See Chart.Svg for handy SVG helpers.
See live example.
Add elements for each bin.
C.chart []
[ C.bars []
[ C.bar .income []
, C.bar .spending []
]
[ { country = "Denmark", income = 40000, spending = 10000 }
, { country = "Sweden", income = 56000, spending = 12000 }
, { country = "Norway", income = 62000, spending = 18000 }
]
, C.eachBin <| \plane bin ->
let common = CI.getShared bin in
[ C.label [] [ S.text common.datum.country ] (CI.getBottom plane bin) ]
]Use the functions in Chart.Item to access information about your bins.
Add elements for each stack.
C.chart []
[ C.bars []
[ C.stacked
[ C.bar .income []
, C.bar .savings []
]
]
[ { income = 40000, savings = 10000 }
, { income = 56000, savings = 12000 }
, { income = 62000, savings = 18000 }
]
, C.eachStack <| \plane stack ->
let total = List.sum (List.map CI.getY (CI.getMembers stack)) in
[ C.label [] [ S.text (String.fromFloat total) ] (CI.getTop plane stack) ]
]Use the functions in Chart.Item to access information about your stacks.
Add elements for each bar.
C.chart []
[ C.bars []
[ C.bar .income []
, C.bar .spending []
]
[ { income = 40000, spending = 10000 }
, { income = 56000, spending = 12000 }
, { income = 62000, spending = 18000 }
]
, C.eachBar <| \plane bar ->
let yValue = CI.getY bar in
[ C.label [] [ S.text (String.fromFloat yValue) ] (CI.getTop plane bar) ]
]Use the functions in Chart.Item to access information about your bars.
Add elements for each dot.
C.chart []
[ C.series []
[ C.scatter .income []
, C.scatter .spending []
]
[ { income = 40000, spending = 10000 }
, { income = 56000, spending = 12000 }
, { income = 62000, spending = 18000 }
]
, C.eachBar <| \plane bar ->
let yValue = CI.getY bar in
[ C.label [] [ S.text (String.fromFloat yValue) ] (CI.getTop plane bar) ]
]Use the functions in Chart.Item to access information about your dots.
Add elements for each dot or bar. Works like eachBar and eachDot, but includes both
bars and dots.
Use the functions in Chart.Item to access information about your items.
Add elements for each item of whatever list in the first argument.
C.chart
[ CE.onMouseMove OnHover (CE.getNearest CI.any) ]
[ C.series .year
[ C.scatter .income [] ]
[ { year = 2000, income = 40000 }
, { year = 2010, income = 56000 }
, { year = 2020, income = 62000 }
]
, C.each model.hovering <| \plane product ->
[ C.tooltip product [] [] [] ]
]See live example.
Filter and group products in any way you'd like and add elements for each of them.
C.chart []
[ C.eachCustom (CI.named "cats") <| \plane product ->
[ C.label [] [ S.text "hello" ] (CI.getTop plane product) ]
]The above example adds a label for each product of the series named "cats".
Use the functions in Chart.Item to access information about your items.
Given all your bins, add a list of elements.
Use helpers in Chart.Item to interact with bins.
Given all your stacks, add a list of elements.
Use helpers in Chart.Item to interact with stacks.
Given all your bars, add a list of elements.
Use helpers in Chart.Item to interact with bars.
Given all your dots, add a list of elements.
Use helpers in Chart.Item to interact with dots.
Given all your products, add a list of elements.
Use helpers in Chart.Item to interact with products.
Using the information about your coordinate system, add a list of elements.
Add a custom element.
See live example.
Gather data points into bins. Arguments:
The desired bin width.
The function to access the binned quality on the data
The list of data.
C.binned 10 .score [ Result "Anna" 43 , Result "Maya" 65 , Result "Joan" 69 , Result "Tina" 98 ] == [ { bin = 40, data = [ Result "Anna" 43 ] } , { bin = 60, data = [ Result "Maya" 65, Result "Joan" 69 ] } , { bin = 90, data = [ Result "Tina" 98 ] } ]
type alias Result = { name : String, score : Float }
This is the root container of your chart. All your chart elements must be placed in here. The below example illustrates what configurations are available for the
chartelement.Explore live examples for the following attributes: