Skip to content

Chart API

Judd2000 edited this page Mar 29, 2024 · 9 revisions

The <Chart> component is a collection component. This component renders the chart visualization based on the properties passed in, including all children.

Canvas vs. SVG

Charts use Vega to draw the chart. Vega charts can be rendered as either svg or canvas elements. We recommend using svg in most situations. However, if you are plotting data on the order of 10K rows or more, you may want to switch to canvas as the renderer. Using canvas as the rendered does not add elements to the document for every shape in the visualization, unlike svg.

<Chart
    data={data}
    renderer="canvas"
    description={chartDescription}
    height={300}
    width={500}
    padding={32}
    theme="light"
>
    <Line />
</Chart>

Handles

Chart exposes four handles, copy(), download(), getBase64Png(), and getSvg(). These are exposed so that you can call them from elsewhere in your application. These are accessed by passing a ref to Chart and calling them from ref.current (see examples below).

Copy

The copy() function will copy the current visualization to the user's clipboard. Copy returns a promise so that you can handle the success/failure as needed.

If attempts to copy to clipboard result in the promise rejecting and receiving this result: "Error occurred while writing to clipboard", then it is likely that writing to the clipboard is not permitted.

Example

const ref = useRef<ChartHandle>(null);

const copy = () => {
    ref.current?.copy().then(console.log, console.warn)
}

return (
    <>
        <Chart data={data} ref={ref}>
            <Line />
        </Chart>

        <ActionButton onPress={copy}>Copy to clipboard</ActionButton>
    </>
)

Download

The download() function will download a PNG of the current visualization to the user's computer. Download returns a promise so that you can handle the success/failure as needed.

Example

const ref = useRef<ChartHandle>(null);

const download = () => {
    ref.current?.download().then(console.log, console.warn)
}

return (
    <>
        <Chart data={data} ref={ref}>
            <Line />
        </Chart>

        <ActionButton onPress={download}>Download</ActionButton>
    </>
)

Get PNG

The getBase64Png() method will return the PNG Base 64 string for the current visualization as the resolution for a promise.

Example

const ref = useRef<ChartHandle>(null);

const getBase64Png = () => {
    ref.current?.getBase64Png().then(console.log, console.warn)
}

return (
    <>
        <Chart data={data} ref={ref}>
            <Line />
        </Chart>

        <ActionButton onPress={getBase64Png}>Log Base64 PNG</ActionButton>
    </>
)

Get SVG

The getSvg() method will return the SVG string for the current visualization as the resolution for a promise.

Example

const ref = useRef<ChartHandle>(null);

const getSvg = () => {
    ref.current?.getSvg().then(console.log, console.warn)
}

return (
    <>
        <Chart data={data} ref={ref}>
            <Line />
        </Chart>

        <ActionButton onPress={getSvg}>Log SVG</ActionButton>
    </>
)

Scales

There are a handful of scales that can be used to differentiate marks in charts. These are:

  • colors
  • lineTypes
  • lineWidths (coming soon)
  • opacities
  • symbolSizes (coming soon)
  • symbolShapes

These scales can be used on the mark components to divide the data into series for the chart. The most common scale used for dividing the data into series is colors.

Example:

<Chart data={data}>
	<Axis position='bottom' labelFormat='time' granularity='month' baseline />
	<Axis position='left' grid title="Visitors" />
	<Line metric="visitors" color="browser" />
	<Legend position='top' title='Browser' />
</Chart>

line-chart_options_standard@2x_1649350993232

It is possible to divide the data using more than one scale and key. The following example will subdivide the data into series by every unique combination of series and period

Example:

This example sets the lineTypes scale to be ['dotted', 'solid']. This means the first division will use be a dotted line and the second division will be a solid line. The line is divided into series using color and lineType. Each unique browser will be a different color and each unique version will be a different line type.

<Chart data={data} lineTypes={['dotted', 'solid']}>
	<Axis position='bottom' labelFormat='time' granularity='day' baseline />
	<Axis position='left' grid title="Events" />
	<Line metric="events" color="browser" lineType="version" />
	<Legend position='bottom' />
</Chart>

Repeating scales

If there are more divisions than there are entries in a scale, then the entries will repeat the loop. For example, if there are 3 series (['Windows', 'Mac', 'Linux']) and only two colors (['red', 'blue']), then the color scale will start over with the third element ('Windows' = 'red', 'Mac' = 'blue', 'Linux' = 'red').

Colors

2D color scales

It is also possible to define colors as a 2D scale (scale of scales). Two dimensional color scales are used when a given series is additionally subdivided. An example of this is using a dodged bar with a subSeries. Each series will use the scale for that series to set the color of each subdivision. Just like the color of the series repeats when the are more series than colors in the scale, the series scale will repeat when the number of sub series is greater than the number of colors in the series scale.

Supported colors

A color scale can be defined as a color scheme name, an array of spectrum color names or an array of css colors. It is possible to mix spectrum color names and css colors in a single array.

Color scheme

The color schemes are defined by spectrum. Research and careful consideration went into selecting these colors so that they are accessible and aesthetically pleasing. It is highly recommended to use the default spectrum color schemes.

Categorical color schemes should be used for ordinal/categorical data. The diverging color schemes should be used for continuous/numerical data, especially when representing high vs. low.

59c69201-d9ec-4c91-9ee4-8ad5b0777c4e 73578353-8726-4eba-b0b9-925937ffd871

If a sequential scheme is needed, request to have the spectrum sequential color schemes added or submit a PR (haven't been prioritized yet).

Available color schemes:

  • categorical6
  • categorical12
  • categorical16
  • divergentOrangeYellowSeafoam5
  • divergentOrangeYellowSeafoam9
  • divergentOrangeYellowSeafoam15
  • divergentRedYellowBlue5
  • divergentRedYellowBlue9
  • divergentRedYellowBlue15
  • divergentRedBlue5
  • divergentRedBlue9
  • divergentRedBlue15

Spectrum color names

A color scale can be defined as an array of spectrum color names. Spectrum color names are responsive (excluding static* variants). This is great for when light and dark mode support is needed. The colors adjust so that they look ideal in both light and dark mode.

Example: ['red-500', 'blue-600', 'celery-400']

CSS colors

A color scale can also be defined as an array of css colors. This method is the least desirable.

Example: ['#FFF', 'DarkGoldenRod', '#00008B', 'rgb(150, 150, 150)']

Locale

react-spectrum-charts supports locale for both number and date/time values. There are multiple methods available for setting the locale definitions.

  1. Use a locale code. This will use the provided locale for both number and date/time values.
    • Example: locale='fr-FR'
  2. Use different locale codes for number and date/time. For example you can specify ar-AE to be used for numbers, and ar-SY to be used for dates/times. This method may be appropriate for use cases that require more customizability than using a single locale.
    • Example: locale={{number: 'ar-AE', time: 'ar-SY'}}
  3. Provide your own locale definitions. You can create any custom definition for number or date/ time locales, using the properties available for the formatLocale and timeFormatLocale methods, respectively. For examples for various locales, check out number locale definitions and time locale definitions.

Custom locale definition example

import {NumberLocale, TimeLocale} from 'vega'

...
const numberLocale: NumberLocale = {
    "decimal": ",",
    "thousands": "\u00a0",
    "grouping": [3],
    "currency": ["", "\u00a0CHF"],
    "percent": "\u202f%"
};
const timeLocale: TimeLocale = {
    "dateTime": "%A %e %B %Y à %X",
    "date": "%d.%m.%Y",
    "time": "%H:%M:%S",
    "periods": ["AM", "PM"],
    "days": ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
    "shortDays": ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."],
    "months": ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"],
    "shortMonths": ["janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc."]
}

...
<Chart {...chartProps} locale={{number: numberLocale, time: timeLocale}}>
...

Props

name type default description
animations boolean Whether or not to include initial, dataset transition, and opacity animations in bar, area, and line charts. Animations are on by default. Explicitly define this prop as false to disable them.
children* Axis | Group | Line | Bar | Legend The elements that make up the chart.
data* object[] Data that needs to be plotted in the chart.
colors Color | Color[] 'categorical12' Defines the color scale used for coloring divisions (series). A single dimension color scale can be defined by supplying a ColorScheme or and array of CssColor | SpectrumColor[]
config Config Vega config object that sets the custom style of the chart. This config will be merged with the default spectrum config.
dataTestId string Adds a data-testid to the Chart component.
debug boolean false Flag that will console.log useful information about the chart (ex the vega spec for the chart). Helpful for debugging your visualization.DO NOT SHIP WITH DEBUG ENABLED
description string Chart description.
height number 500 Chart height in pixels.
hiddenSeries string[] List of series names that should be hidden from the chart (controlled). This does not hide these series in the legend as well, only the chart. To hide series in the legend, use `hiddenEntries` in the `Legend` component.
highlightedSeries string The series that should be highlighted on the chart (controlled). This will not have an effect if `highlight` (uncontrolled) is enabled on a `Legend` somewhere in the chart.
lineTypes ('solid' | 'dashed' | 'dotted' | 'dotDash' | 'longDash' | 'twoDash' | number[])[] ['solid', 'dashed', 'dotted', 'dotDash', 'longDash', 'twoDash'] Defines the line type scale used for divisions (series).
The default line types available are `solid`, `dashed` ([7, 4]), `dotted` ([2, 3]), `dotDash`([2, 3, 7, 4]), `longDash`([11, 4]), and `twoDash` ([5, 2, 11, 2]).
Custom line types can be set by using the dash array format.
loading boolean false Defines if the loading screen should be displayed instead of the visualization.
locale Locale | LocaleCode | { number?: NumberLocaleCode | NumberLocale; time?: TimeLocaleCode | TimeLocale } 'en-US' Sets the locale for numeric and time values. Can be set using many different predefined locale codes or you can provide your own locale definitions. See Locale for more details.
maxWidth number Infinity Max width of the chart in pixels.
minWidth number 100 Min width of the chart in pixels.
opacities number[] [1] Defines the opacity scale used for divisions (series).
The default opacities are dynamically calculated based on the number of unique values in the domain. For example, if the `opacity` on a bar is set on `version` and there are 3 unique versions in the data supplied, the default opacities scale will be [1, 0.67, 0.33]. If there were 4 unique versions, the the default opacities scale will be [1, 0.75, 0.5, 0.25]
Default opacities scale equation: new Array(nDivisions).fill(0).map((d, i) => (nDivisions - i) / nDivisions)
padding number | {left: number, top: number, right: number, bottom: number} 0 Chart padding. If a single number is provided, the padding around the chart will be that number on all sides. Supply and object to customize the padding by side.
renderer 'canvas' | 'svg' 'svg' Sets if the chart should be rendered as an SVG or as a canvas element
theme 'light' | 'dark' 'light' Sets the theme of the chart. This primarily sets colors to make sure everything is accessible.
title string Sets the chart title. If the Title component is used to define the chart title, that will overwrite this prop.
width number | 'auto' | string // percentage format (/^\d+%$/) 'auto' Chart width. Number will set the width in pixels. 'auto' will expand to fill the parent element. A percentage will take up a percentage of the parent element. Must be integer percentages.
Note: 'auto' and '100%' are the same.