TimeseriesChart
The TimeseriesChart
visually represents data in sequential order of time. It's
used to observe trends, patterns, and fluctuations in the data over a specific
time period.
Import
import { TimeseriesChart } from '@dynatrace/strato-components-preview/charts';
Use cases
In order to visualize data with the TimeseriesChart
the minimum requirement is
to provide one or more series of type Timeseries
in the data
prop.
In addition to an array of data points of the type TimeseriesDatapoint
, a
Timeseries
is also required to include a name, which will be displayed in the
tooltip and the legend. The data points within the series need to provide a
value and a time dimension. The time dimension can either be handled as a
timestamp if only a start timestamp is given, or as a timeframe if both a start
and an end timestamp are provided for the datapoint.
Size
By default, the chart will use all the available container size up to a maximum
height of 300 pixels. This maximum height can be changed by providing a value in
the height
prop of the TimeseriesChart
. If a number is passed to this prop
without any unit specified, it will be treated as px
.
Variants
The TimeseriesChart
supports three different chart variants: Area, bar and
line. If no value is provided in the variant
prop, the line variant is used by
default. It is important to note that not all features and props apply to all
variants equally. Each of these specific cases are outlined in the use cases
below.
Series actions
A series action is a creator-defined interaction with a given data point in the
chart. Basic interactions include copying a series name and inspecting the
underlying data of a data point. In order to enable chart interactions, the
ChartSeriesAction
subcomponent needs to be appended within the
TimeseriesChart
. More subcomponents can be added within this component, for
instance ChartSeriesAction.Item
, where you can provide a custom action that
will appear in the legend menu. That action can execute any custom logic in its
onSelect
callback or get disabled via a disabled
prop.
Messages
This feature allows the user to display messages in the browser console using a
custom handler. In addition to the text output itself, each message also
includes a level of severity, namely warning
or error
. Chart messages can be
used to notify the user about inconsistencies in the data for instance. The
messages of type ChartMessage
can be passed to the TimeseriesChart
using the
onMessage
prop.
Gap policy
Gaps in data refer to missing or unrepresented values between existing data points. In a dataset exclusively with timestamps, no continuity can be determined and therefore there are always “gaps” between data points regardless of the resolution of the dataset. In a timeframe dataset however, gaps are considered when the end timestamp of the previous data point is earlier than the start timestamp of the next data point, meaning there is a timespan between the end of a previous data point and the next one with no given value.
The TimeseriesChart provides the gapPolicy
prop to configure how gaps are
visualized in a chart. There are three gapPolicy
options available: gap,
connect, and threshold.
- The
gap
option displays gaps on the chart as is (e.g. breaks along a line). This option helps to see the absence of data during a period of time. - The
connect
option connects consecutive data points irrespective of the gap using linear interpolation. - The
threshold
option provides a mechanism to configure thresholds of a certain time (e.g. 30 seconds, 5 minutes, 1 day, 3 months, etc.). When the gap between sequential data points in the dataset is less than or equal to the threshold, then the data points will be connected.
Note: The gapPolicy
prop is only supported in area and line chart variants and
with the band subcomponent. The bar chart variant doesn't support a gapPolicy
and does not react to the property configuration.
Value representation
By default, values within a chart are displayed as is - with their absolute
value (e.g. 3.14 kB). This can, however, be changed so that instead of absolute
values, relative values are represented. Relative values indicate the proportion
that a given series or datapoint contributes to the sum (100%) of a given
timestamp or timeframe. The valueRepresentation
prop can be used to change
this behavior. Only timeframes/timestamps with the same unit will be stacked. If
there is only one series of a given unit, the relative value is based on the
maximum value within the given series.
In the line variant, relative values are always calculated based on the highest value in the dataset, regardless of whether the series are stacked or not. This ensures consistency in representation, as the highest value in the series becomes the baseline for calculating the relative percentages.
Change the chart color/s
The TimeseriesChart
provides a set of predefined color palettes and it also
accepts custom color palettes. See coloring for more
details.
Apart from all these options for providing a color palette, the
TimeseriesChart
also offers the ability to override colors for specific
series. When a color override is specified, it takes precedence over the color
that would otherwise be assigned from the color palette. However, it does not
affect the colors assigned to other series. This allows for fine-grained control
over the appearance of individual series within the chart. In a
TimesereisChart
, a color override is done by a shape (e.g. line, area, etc.)
subcomponent. The desired color should be specified in the color
prop of a
shape subcomponent.
Legend
The purpose of the legend is to provide additional identifying information for the chart, without needing to interact with the legend directly.
Truncation Mode
The purpose of truncation is to gracefully handle extra long labels within data
visualization components. By changing the value of this property, you have
control over where truncation is applied within charts. By default, the
truncation is applied to the middle
of labels with the use of an ellipsis.
Truncation can, however be changed to instead be applied at the start
or end
of data visualization component labels.
Series curve
You can select the curve shape of the line, band and area series via the curve
prop. The available options are 'linear' where line joins will be straight
(default option) or 'smooth' for a more fluid curve.
Visibility
The legend of the TimeseriesChart
is shown by default. In order to hide or
show the legend, you need to set the value of legend.hidden
on the
subcomponent.
Position
By default, the position of the legend of the TimeseriesChart
is set
automatically. This option prioritizes the legend placement to the right of the
chart area. When the chart width is reduced, the legend is repositioned to the
area beneath the chart. It is also possible to explicitly set the chart's legend
position to right or bottom with the position
prop.
Legend ratio
By default, the legend occupies 25%
of the container width, in the case where
the legend is positioned on the right and 25%
of the container height if the
legend position is on the bottom.
It is possible to override the default legend ratio by setting a custom
percentage value for the ratio prop. The expected value is in the range of
5-80
. Values out of expected ranges will roll back to the default legend
ratio.
Chart interactions
Chart interactions enable additional possibilities for end users to interact
with the data plotted within the chart area. The interactive options currently
supported within the TimeseriesChart
are zoom-x, zoom in, zoom out, and pan.
To incorporate these interactions, the ChartInteractions
subcomponent must be
added to the TimeseriesChart
. The chart interaction can then either be
triggered using keyboard shortcuts or by the optional chart toolbar. To enable
the toolbar with the chart interactions, the ChartToolbar
subcomponent must be
added to the TimeseriesChart
. To set initial position of the toolbar, the
placement
prop can be used.
Explore
The explore functionality is the default mode and it allows you to inspect the
data within the chart. It includes an optional feature to select an area to zoom
along the x-axis. In order to enable this option it is necessary to add the
ChartInteractions.ZoomX
subcomponent to the ChartInteractions
component. You
can also pan with the mouse middle button by enabling the
ChartInteractions.Pan
subcomponent.
You can optionally trigger this mode from the keyboard by pressing E
while the
chart has focus.
Zoom-In and Zoom-Out
The zoom functionality within the TimeseriesChart
allows users to zoom in to
the chart's plotted data by a fixed point along the x-axis. The chart supports
zoom in (incremental) and zoom out (decremental) actions.
In order to enable either of these zoom options on a chart it is necessary to
add the ChartInteractions.Zoom
subcomponent to the ChartInteractions
component.
You can optionally zoom in/out different ways by first focusing the chart:
- Pressing
Cmd
(Mac) orCtrl
(Windows) + the mouse wheel, will generate a zoom in/out trigger. - Pressing
Cmd
(Mac) orCtrl
(Windows) + ↑ (Up Arrow) will zoom-in. - Pressing
Cmd
(Mac) orCtrl
(Windows) + ↓ (Down Arrow) will zoom-out.
Pan
Once a user has zoomed into the plotted data on a chart, panning can optionally
be enabled. Panning allows users to navigate left and right along the x-axis
whilst in a zoomed-in state. In order to enable this functionality, the
ChartInteractions.Pan
subcomponent needs to be added to the
ChartInteractions
component.
You can optionally trigger this mode from the keyboard by pressing P
while the
chart has focus.
Once you have triggered this mode:
- Pressing ← (Left Arrow) will pan to the left. You can also press
Shift
to increase the speed of pan movement. - Pressing → (Right Arrow) will pan to the right. You can also press
Shift
to increase the speed of pan movement.
Reset
Reset will restore the chart to its initial state.
You can optionally trigger this action from the keyboard by pressing R
while
the chart has focus.
- Double clicking on any part of the chart will trigger a reset.
It's also possible to programmatically trigger all the previously described
interactions by calling their methods on the TimeseriesChart
instance
reference. The available options are: exploreMode
, panMode
, zoomIn
,
zoomOut
and reset
.
Download data as CSV
The TimeseriesChart
component supports download data in CSV format using a
toolbar button. To enable this feature, a ChartToolbar
subcomponent with
ChartToolbar.DownloadData
inside of it must be provided to the
TimeseriesChart
component. On click of the download button, raw data will be
downloaded as a CSV file.
The CSV file contains the following columns:
dimension-(n)
- the name of the dimension, wheren
is the index of the dimensionseries
- the full name of the series (all dimensions concatenated using•
symbol)unit
- the unit of the seriesstart
- the start timestamp of the data pointend
- the end timestamp of the data pointvalue
- the value of the data point
It's also possible to programmatically trigger the download of the CSV file by
calling the downloadData
method on the TimeseriesChart
instance reference.
Multiple chart configuration
Given certain situations it can be helpful to share a common chart configuration
across several TimeseriesChart
instances. To avoid repeating the same
configuration in all instances, the TimeseriesChartConfig
provider can be
used. It accepts an object where the keys are either props of the
TimeseriesChart
component, or the corresponding object representation of each
one of the TimeseriesChart
subcomponents props. (TimeseriesChart.Legend
,
TimeseriesChart.YAxis
, Timeseries.XAxis
, Timeseries.Tooltip
ChartsInteractions
).
A specific configuration of a TimeseriesChart
instance will take precedence
over the one specified in the TimeseriesChartConfig
.
Axes
To configure the axes of the TimeseriesChart
, the TimeseriesChart.XAxis
and
TimeseriesChart.YAxis
subcomponents can be added. The label
property sets
the axis label. Axis scale boundaries can be set with the min
and max
props.
The Y-axis scale
property can be used to set the value scale to either
linear
or log
(logarithmic).
The TimeseriesChart.XAxis
supports timestamps of type number
, whereas the
TimeseriesChart.YAxis
subcomponent also supports data-max
in the max
property and data-min
in the min
property. These special values allow for
granular control over the Y-axis scale boundaries. By default, the auto
value
is used for both min
and max
properties. The auto
mode automatically
determines both the minimum and maximum values of the Y-axis scale based on the
data in the chart (similar to data-min
and data-max
) and sets the Y-axis
baseline to zero.
Multiple Y-axes
The TimeseriesChart
supports multiple Y-axes. TimeseriesChart.YAxis
provides
a position
property which can be set to either left
or right
.
When you specify multiple Y-axes, the chart automatically assigns data series to Y-axes based on the unique units of the data. The first unique unit is assigned to the left Y-axis, and the second unique unit to the right Y-axis. Note that any additional data series with different units from those already used will not be displayed.
Filtering the data on the legend could result in moving the data from the right axis to the left if there are no left series displayed in the legend.
Currently, it's not possible to assign data series to specific Y-axes, nor is it possible to use the same unit for both Y-axes.
Having a timeseries with two units with different Y-Axes defined:
- If only one left Y-Axis is defined, only the first unit will be displayed on the left.
- If only one right Y-Axis is defined, only the first unit will be displayed on the right.
- If both Y-Axes are defined, the first unit will be placed on the left, and the second unit on the right.
- If both Y-Axes are defined and the
valueRepresentation
is set to relative, only the left axis will be displayed and show the percentage.
Tooltip
Tooltips are used to display additional detailed information about a selected
data point and can be enabled by adding the TimeseriesChart.Tooltip
subcomponent. The tooltip variant
defines whether the tooltip should contain
data points from all series (shared) for the selected timestamp, or just the
closest one (single). The seriesDisplayMode
prop can be used to define whether
the tooltip should be comprised of a single line of information or multiple
lines.
The Tooltip items sequence, will appear in the same order of the series plotted in the chart.
Single
Shared
Formatter
The unit for the TimeseriesChart
, by default, will be appended to the
specified value. There are two other options in the formatter that allow for
greater customization. The first option enables you to prepend the unit to the
value, while the second option enables you to ignore the original unit and
append a custom string instead. Additionally, there is a custom formatter option
available to allow you to change the input unit to one of your choice, e.g.: if
the input unit is bits
, you are able to switch and display the unit as
bytes
, correctly formatted. The formatted value is applied in the axis ticks,
as well as in the tooltip and the axis magnifier. The use cases below outline
each of these scenarios.
The precision of the formatter will adapt automatically based on the data decimals if there is no precision configuration from the custom formatter option.
Annotations
Annotations are used to visualize specific events or contextual notes on the
TimeseriesChart
in the form of markers placed in time-based tracks.
The marker represents an annotation at a certain point or period in time. They can be either timestamp-based (a circular shaped marker) or timeframe-based (a pill shaped marker) depending on the type of the annotation data point. Annotations with the same timestamp/timeframe are grouped together under a single marker that displays the number of grouped annotations. Markers can be displayed on a single or multiple tracks. When there are more than three tracks, an overflow scroll is applied.
Add annotations to the chart
In order to visualize annotation data inside the TimeseriesChart
a
TimeseriesChart.Annotations
component should be initialized. This component
should have at least one track, that contains a marker component per annotation
data point.
An annotation data point should contain a time dimension just as the
TimeseriesChart
(start
and optional end
), an optional symbol
, title
,
and description
, which will be displayed in the tooltip.
Marker content
When the symbol
is provided, it will become the marker content by default.
When not, the title
will be shown as marker content.
In case the content of the marker is bigger than the size of the marker (timestamp/timeframe size in TimeseriesChart), it will expand to fit all the content inside, decoupling from the original scale. In these particular cases, it is encouraged to use the indicators, which will represent the real size of the bin.
Visual customization
Tracks and markers support visual customization in order to differentiate various types of annotations.
It's possible to set custom colors on both the track (to be applied to all
markers) and the marker level by using the color
property on the respective
component. A marker's custom color has precedence over track's. This color can
be set to any Design System color token
, as well as any rgb
, hex
or
CSS color
.
The symbol
property allows you to apply an icon, emoji, single letter, glyph,
or Design System icon to either an individual marker or to an entire track. When
applied to a track, this symbol
will be used as the default. As with the color
property, a marker's custom symbol has higher priority than track's.
When markers partially overlap one another, the order of the annotations defines
which marker is displayed on top. Timestamp-based annotations are always
displayed above timeframe-based ones. It's also possible to customize the marker
display order, by using the priority
property. The higher the value of the
priority property, the higher precedence the marker has. The priority property
also affects the color of markers i.e. within a group, the color of the marker
with the highest priority will be applied to the group.
It's possible to assign a label to a track using the label
property. Be aware
that labels are hidden by default. To show a track's label, the showLabels
property has to be applied to the TimeseriesChart.Annotations
component.
Visibility
An entire track can be hidden by adding the hidden
property to the
TimeseriesAnnotations.Track
component. The same configuration can be applied
to a marker, by setting the hidden
property on the
TimeseriesAnnotations.Marker
component.
When hovering a marker (with the cursor), an annotation indicator appears over
the chart area. The indicator's visibility can be customized on either a track
or marker level by using the indicatorsDisplay
property:
- With the
auto
option, the default behaviour is applied - indicators appear on hover. - The
always
option sets indicators to always be visible within the chart area, regardless of the hovering behavior. - The
never
option sets indicators to never be visible.
Custom actions
Annotations support both out-of-the-box and custom interactions. When hovering
over markers and marker groups, additional detailed information is displayed in
the annotation tooltip (out-of-the-box interaction). Similarly to the
TimeseriesChart
series actions, the TimeseriesChart.Annotations
component
supports custom actions which can be defined by the Creator.
Band chart
A time series based band chart, also known as a prediction band chart or a
confidence band chart, is a type of chart geometry that is commonly used in time
series analysis and forecasting. The chart is designed to visualize and
understand the uncertainty surrounding a predicted value based on historical
data, or fluctuations of a value in a given time period (i.e. min
& max
).
A median line chart (displaying the average
) together with a band chart
(displaying min
& max
values) is useful for better understanding the context
around a given metric value. The band chart helps to visualize the range and/or
level of uncertainty because it helps to visualize the trend of the data and the
level of uncertainty around a given metric or trend. In forecasting usecases
comparing the current value of the data to the prediction band, it is possible
to identify whether or not the data is following the expected trend or deviating
from it.
In terms of data structure, time series charts typically display a single value
for each point in time, whereas band charts, also known as confidence interval
charts, display a range of values by plotting two lines: one for the minimum
value ('lower band', y0
) and one for the maximum value (upper band, y1
).
Basic usage
The band is defined as a subcomponent within the time series chart by using the
TimeseriesChart.Band
sub-component. See below, for the most simple example of
a band chart.
Stroke and fill properties
By default, the band chart is rendered with the area between its bounds
"filled". For use cases in which this is too distracting or where one needs to
compare two bands to one another, the chart geometry also has a strokeOnly
property. When set to true
, only the lines (strokes) delimitating the bounds
of the band will be visible.
Equal values
When the y0
and y1
values in the dataset are equal a line is rendered
instead of a band.
Gaps in the data
As the band chart is an extension of the time series chart, the same gap policies apply to it (see above).
Multiple bands
Multiple bands can be rendered in the same chart and combined with other
geometries. A common use case is rendering a band chart (showing min
& max
)
together with a Timeseries.Line
(showing the average
).
Combination charts (multiple geometries)
Using configuration per series allows for a single series to have a different
configuration, which is more specific than the global one. In order to do so, we
can use a subcomponent for each shape (<TimeseriesChart.Line />
,
<TimeseriesChart.Bar />
, <TimeseriesChart.Area />
and
<TimeseriesChart.Band />
). Each subcomponent will enable different properties
depending on the type of shape. If there is not any variant or subcomponent set
and only the data is set, the default variant will be Line.
There are some
common configurations between shapes, which are:
color
: The color of the series. It will override the color palette configuration for this specific series.valueRepresentation
: It is possible to use a different value representation than the global one only if there is no secondary unit attached to the right axis. If the right axis is already assigned to a unit, the value representation will roll back toabsolute
, and the override will be ignored. This property doesn't apply to the band shape.
ℹ️️ Be aware that the series configuration managed through the subcomponents won't be part of the shareable configuration.
Ordering
In a few words, the shape types (line, bars, area, band) will appear in the same order set on the subcomponents. When a global variant is defined in the chart configuration, it will always have lower priority (it will always be rendered below the other shapes) than the other geometries.
Line
In order to display data as a line (i.e. using the line geometry) within the
chart, pass your data to a <TimeseriesChart.Line />
subcomponent. The
available properties for a series rendered as a line are as follows:
gapPolicy
: It can be eithergap
,connect
, orthreshold
. More details in the gap policy section.pointsDisplay
: Whether to show data points always, never, or depending on a width-based threshold amount.
Bar
In order to display data as a bar (i.e. using the bar geometry) within the
chart, pass your data to a <TimeseriesChart.Bar />
subcomponent. If several
series with the same shape type and unit are added on the same
timeframe/timestamp, the data will be stacked.
Area
In order to display data as an area (i.e. using the area geometry) within the
chart, pass your data to a <TimeseriesChart.Area />
subcomponent. The
available properties for a series rendered as an area are as follows:
gapPolicy
: It can be eithergap
,connect
, orthreshold
. More details in the gap policy section.pointsDisplay
: Whether to show data points always, never, or depending on a width-based threshold amount.
If several series with the same shape type and unit are added on the same timeframe/timestamp, the data will be stacked.
Thresholds
Thresholds are used to mark meaningful ranges or values on a TimeseriesChart
and they add contextual information to a numerical axis. There are two variants
of thresholds:
- a specific point represented on the Y-axis and a line across.
- a range - or filled area - represented by a pill on the Y-axis and a band across.
Point and Range
Both point and range can be represented by static or dynamic data sources. A static data source has a single value representing a point or a single key-value pair representing a fixed range. A dynamic data source has a data array containing more than one value or various key-value pairs.
There are three different types of threshold markers:
-
Range filled, where the value range is defined in order to display the threshold band. The upper and lower lines are not drawn unless the pill is hovered.
-
Range stroke-only variant, where a value range is defined in order to display the threshold band represented by upper and lower dashed lines. The upper and lower lines become continuous lines when the pill is hovered.
-
Point, where only one value is required to display the threshold. It's represented by a dashed line and when the point is hovered the line becomes a continuous line.
Dynamic Point
Dynamic Range
Dynamic Range Stroke Only
There is no limit defined for the number of threshold ranges or points that can
be used in a single TimeseriesChart
.
By default, thresholds are positioned on the left axis and with the use of the
position
prop, we can place thresholds on the right axis or on both, as
depicted below.
Left Axis
Right Axis
Dual Axis
Error state
The ErrorState
subcomponent is responsible for handling errors in a graceful
manner, ultimately improving the overall user experience. Its primary function
is to catch any errors that may occur with the data and display a fallback UI
instead of crashing the entire application. The fallback UI occupies the full
width and height of the chart, ensuring that users are still provided with a
meaningful interface even in the presence of errors.
The ErrorState
subcomponent offers a versatile feature that enables it to
handle both default and custom error messages. You can provide a custom message
through the ErrorState
subcomponent, which will then override the default
error message. This flexibility allows developers to tailor error messages to
their specific needs and requirements, ensuring a more personalized and
informative user experience.
The ErrorState
subcomponent provides the flexibility to format custom error
messages using HTML, which allows for enhanced customization and adaptability in
presenting error information. Furthermore, it is possible to incorporate the
original thrown error within your custom error message, ensuring that users
receive comprehensive and relevant information when an error occurs.
EmptyState
The EmptyState
subcomponent serves as a fallback when there is no data
available to display in a chart. Its purpose is to provide a user-friendly way
of informing the user about the current situation. When there is no data, a
fallback UI is displayed occupying the full width and height of the chart, along
with a default message.
A feature of EmptyState
is its ability to handle custom messages. It provides
the flexibility to format custom messages using HTML, which allows for enhanced
customization and adaptability in presenting error information.
Loading
The loading
prop is a boolean value that can be passed to the
TimeseriesChart
component to control its loading state. When the loading prop
is set to true, the loading indicator appears in the middle of the chart plot to
inform the user that the component is currently fetching or processing data.
When the loading prop is set to false, the component should display its regular
content.
Styling
The TimeseriesChart
also accepts custom styling, which can be set using the
props className
and/or style
as in a regular html element.