stream-charts
v1.0.1
Published
Charts for steaming data
Downloads
12
Readme
stream-charts
Homepage • Code Docs • Change History • Example Project
stream-charts
are react-based time-series charts for viewing high frequency data, streamed in real-time using rxjs. Generally, update periods of 25 ms aren't a problem for about a hundred or so time-series. To achieve this type of performance, the charts are implemented using d3 SVG elements, wrapped in react functional components, and keep chart updates outside the react render cycle.
quick overview
With stream-charts
you can display initial (or static) data as well as live data from an Observable
.
Charts
are composable using react components. So you can add different axis types, multiple axes, trackers, tooltips, and plots.
All aspects of the Charts
style are exposed allowing you to use your favorite frameworks theme provider, or none at all.
Charts
provide zooming and panning can be enabled or disabled. And zooming is set to use a modifier key by default so that it doesn't interfere with normal scrolling.
When using lower update frequencies, such as < 250 ms, and data updates are sparse, you can set an update cadence so that the plot's time smoothly scrolls, rather than updating only when new data arrives.
Charts
can have a data TTL (time-to-live) to drop older data to allow long-running streams of data. With the data-update callback you can capture that data and store it in local storage, memory, or a location of your choice.
project status
Although still under development, there are two charts available:
- a neuron raster chart, and a
- scatter chart.
Over time, I'll add additional chart types. In the meantime, I welcome any contributions to create new chart types (bar, gauges, etc).
⤒ content
quick start example raster chart code example scatter chart code
intro terminology data ttl, time-windows, performance
chart <Chart/> dimensions styling initial data streaming data
axes <ContinousAxis/> base properties styling
<CategoryAxis/> base properties styling
plots <ScatterPlot/> base properties view-modifying interactions
<RasterPlot/> base properties view-modifying interactions
utilities <Tracker/> base properties styling
⤒ quick start
npm install stream-charts
⤒ example raster chart
For the neuron raster chart (see example)
import {RasterChart} from "stream-charts";
// .
// .
// .
<Chart
width={useGridCellWidth()}
height={useGridCellHeight()}
margin={{...defaultMargin, top: 60, right: 60}}
color={theme.color}
backgroundColor={theme.backgroundColor}
seriesStyles={new Map([
['test1', {...defaultLineStyle, color: 'orange', lineWidth: 1, highlightColor: 'orange'}],
['test2', {...defaultLineStyle,
color: theme.name === 'light' ? 'blue' : 'gray',
lineWidth: 3,
highlightColor: theme.name === 'light' ? 'blue' : 'gray',
highlightWidth: 5}
],
])}
initialData={initialDataRef.current}
seriesFilter={filter}
seriesObservable={observableRef.current}
shouldSubscribe={running}
windowingTime={35}
>
<ContinuousAxis
axisId="x-axis-1"
location={AxisLocation.Bottom}
domain={[0, 5000]}
label="x-axis"
// font={{color: theme.color}}
/>
<ContinuousAxis
axisId="x-axis-2"
location={AxisLocation.Top}
domain={[0, 10000]}
label="x-axis"
// font={{color: theme.color}}
/>
<CategoryAxis
axisId="y-axis-1"
location={AxisLocation.Left}
categories={initialDataRef.current.map(series => series.name)}
label="y-axis"
/>
<CategoryAxis
axisId="y-axis-2"
location={AxisLocation.Right}
categories={initialDataRef.current.map(series => series.name)}
label="y-axis"
/>
<Tracker
visible={visibility.tracker}
labelLocation={TrackerLabelLocation.WithMouse}
style={{color: theme.color}}
font={{color: theme.color}}
// onTrackerUpdate={update => console.dir(update)}
/>
<Tooltip
visible={visibility.tooltip}
style={{
fontColor: theme.color,
backgroundColor: theme.backgroundColor,
borderColor: theme.color,
backgroundOpacity: 0.9,
}}
>
<RasterPlotTooltipContent
xFormatter={value => formatNumber(value, " ,.0f") + ' ms'}
yFormatter={value => formatNumber(value, " ,.1f") + ' mV'}
/>
</Tooltip>
<RasterPlot
axisAssignments={new Map([
// ['test', assignAxes("x-axis-1", "y-axis-1")],
['test1', assignAxes("x-axis-2", "y-axis-2")],
// ['test3', assignAxes("x-axis-1", "y-axis-1")],
])}
dropDataAfter={10000}
panEnabled={true}
zoomEnabled={true}
zoomKeyModifiersRequired={true}
withCadenceOf={30}
/>
</Chart>
⤒ example scatter chart
An example scatter chart (see example)
import {ScatterChart} from "stream-charts";
// .
// .
// .
<Chart
width={useGridCellWidth()}
height={useGridCellHeight()}
margin={{...defaultMargin, top: 60, right: 60}}
color={theme.color}
backgroundColor={theme.backgroundColor}
seriesStyles={new Map([
['test1', {...defaultLineStyle, color: 'orange', lineWidth: 1, highlightColor: 'orange'}],
['test2', {...defaultLineStyle,
color: theme.name === 'light' ? 'blue' : 'gray',
lineWidth: 3,
highlightColor: theme.name === 'light' ? 'blue' : 'gray',
highlightWidth: 5}
],
])}
initialData={initialDataRef.current}
seriesFilter={filter}
seriesObservable={observableRef.current}
shouldSubscribe={running}
windowingTime={25}
>
<ContinuousAxis
axisId="x-axis-1"
location={AxisLocation.Bottom}
domain={[10, 5000]}
label="x-axis"
/>
<ContinuousAxis
axisId="y-axis-1"
location={AxisLocation.Left}
domain={[0, 1000]}
label="y-axis"
/>
<ContinuousAxis
axisId="x-axis-2"
location={AxisLocation.Top}
domain={[100, 2500]}
label="x-axis (2)"
/>
<ContinuousAxis
axisId="y-axis-2"
location={AxisLocation.Right}
scale={d3.scaleLog()}
domain={[100, 1200]}
label="y-axis (2)"
/>
<Tracker
visible={visibility.tracker}
labelLocation={TrackerLabelLocation.WithMouse}
style={{color: theme.color}}
font={{color: theme.color}}
// onTrackerUpdate={update => console.dir(update)}
/>
<Tooltip
visible={visibility.tooltip}
style={{
fontColor: theme.color,
backgroundColor: theme.backgroundColor,
borderColor: theme.color,
backgroundOpacity: 0.9,
}}
>
<ScatterPlotTooltipContent
xLabel="t (ms)"
yLabel="count"
yValueFormatter={value => formatNumber(value, " ,.0f")}
yChangeFormatter={value => formatNumber(value, " ,.0f")}
/>
</Tooltip>
<ScatterPlot
interpolation={interpolation}
axisAssignments={new Map([
['test2', assignAxes("x-axis-2", "y-axis-2")],
])}
dropDataAfter={10000}
panEnabled={true}
zoomEnabled={true}
zoomKeyModifiersRequired={true}
withCadenceOf={30}
/>
</Chart>
⤒ intro
stream-charts
aim to provide high-performance charts for displaying large amounts of data in real-time. The examples (above) show a scatter plot and raster plot whose data was updated about every 25 ms. These plots show 30 time-series of data each.
There are obviously limits to the amount of data, and the performance of the plots. For example, the raster chart plots thousands of lines in the chart. When displaying more data in the raster plot, update performance will suffer. Therefore, you must tune your plots somewhat when you are working in the limits of their performance.
The scatter chart can handle a larger number of series at 25 ms update frequency.
⤒ terminology
A <Chart/> holds a plot
, the axes
, and optionally, a <Tracker/>, and a <Tooltip/>. A <Chart/> is generic, and holds a specific type of plot
, for example, a <RasterPlot/> or a <ScatterPlot/>. The plot
holds the data, and optionally provides pan and zoom. The axes
provide the scale of the data. For example, the scale could be a continuous numeric logarithmic scale, or a category scale. The axes
are also generic. Though, a plot
can restrict the type of axes
allowed. For example, a <RasterPlot/> requires that the y-axes are category axes. <Trackers/> are generic. <Tooltipes/> are also generic, though the tooltip content is a child, specific to a plot type, that it knows how to interpret and present the data.
<Chart/> ↴ Generic container which holds the
Axes
,Plot
,Tracker
,Tooltip
.
Axes ↴ Defines the scale of the data.
stream-charts
current has two axis types: <ContinousAxis/> and <CategoryAxis/>. The <ContinousAxis can be used as an x-axis or y-axis. However, the <CategoryAxis/> can only be used as a y-axes because these are all time-series charts and the x-axis currently only represents time (this will change in the future with additional plot types).
Plot ↴ The plot is a container for the data that uses the
axes
for scale, domain, and range information. Plots provide panning and zooming of the x-axis (time), interacting with theaxes
to update the time-range. The plot is the visual representation of the data. Currently, two type of plots are available: <RasterPlot/>, and <ScatterPlot/>.
<Tracker/> ↴ The tracker displays the current plot time of the mouse. When multiple x-axes are used in the chart, then the tracker displays both times (i.e. from the upper and lower x-axis).
<Tooltip/> ↴ The tooltip is a generic component for rendering information about the data when the user mouses over a series or datum. The
<Tooltip/>
expects a child component that understands the data and renders the information show in the tooltip. For example, when using a <RasterPlot/>, the <RasterPlotTooltipContent/> renders the data for the raster plot tooltip. And when using a <ScatterPlot/>, the <ScatterPlotTooltipContent/> renders the data for the scatter plot tooltip. The tooltip content can be extended.
⤒ data ttl, time-windows, performance
The stream-charts
have been designed to work with fairly large amounts of high frequency data. When the data time exceeds the larges time on the x-axes, the chart begins to scroll, shifting the time-window to keep up with the present data time. The data that falls off the chart is held in memory and can be viewed by changing the time-window with "zoom" or panning to earlier times.
For long-running charts, the amount of data may get large. Because of this, each stream-charts
plot provides a data time-to-live (TTL) setting called dropDataAfter
which is the number of milliseconds, in chart time, after which the data is dropped. The TTL applies to data that falls off the chart. The TTL does not refer to real time. The data will not dissappear fro the plot of the dropDataAfter
milliseconds (see dropDataAfter for raster plots, and dropDataAfter for scatter plots).
As the amount of data and the update frequency increase, you have three levers to make your plots run more smoothly when the start to stutter. Each set of streaming data is unique and may require tuning when the default settings aren't giving the desired results.
- Drop data with the data TTL. By dropping data,
d3
has less data to manage and will run faster. Without TTD, the data the falls off the time-window as the plot scroll is still kept in memory, and is still processed byd3
, but it is clipped, and so not shown. Dropping data will reduce the processing load as data is streamed in. To later view that dropped data, you can store the data from your observable with a separate observer, and when the streaming is complete, load that data once into the plot. - Decrease the windowing-time. The windowing-time, not to be confused with the time-window described below, determines how long (in milliseconds) the incoming data is buffered before the plot is updated. Longer windowing times give better performance, though, at the cost of more choppy scrolling.
- Decrease the time-window. The time-window is defined by the (min, max) time values of your axes. Smaller time-windows mean less data, but also it will stream by faster.
As a final note, generally, the <ScatterPlot/> performs better than the <RasterPlot/>.
⤒ chart
The stream-charts
module wraps d3 elements with functional react in a way that keeps the chart (d3) updates out of the react render cycle. All stream-charts
start with the <Chart/> root element.
⤒ <Chart/>
The Chart
component creates the main SVG element (container) holding the chart, manages a reference to that container, and is the wraps the children in the chart context provider so that they have access to the useChart hook which holds properties, styles, callbacks, subscription needed to construct the charts and make them interactive.
The Chart
s properties fall into four categories:
- container dimensions
- chart style
- initial (static data)
- streamed data and how to manage the stream of data
⤒ <Chart/> dimensions
width (pixels) The width (in pixels) of the container that holds the chart. The actual plot will be smaller based on the margins.
height (pixels) The height (in pixels) of the container that holds the chart. The actual plot will be smaller based on the margins.
⤒ <Chart/> styling
margin (Margin, optional) The margin (in pixels) around plot. For example, if the container has a (h, w) = (300, 600) and a margin of 10 pixels for the top, left, right, bottom, then the actual plot will have a (h, w) = (290, 590), leaving only 10 pixels around the plot for axis titles, ticks, and axis labels.
The Margin has the following shape
interface Margin { top: number bottom: number left: number right: number }
color (string, optional) The color of the axis lines and text, which can be overridden specifically by the axes styles.
backgroundColor (string, optional) The color of the chart background (the whole chart, not just the plot).
svgStyle (SvgStyle, optional) The style attributes for the main SVG element, in case you want to change those. Generally, this is not needed.
The SvgStyle has the following shape
interface SvgStyle { height?: string | number width?: string | number outline?: string // any valid SVG CSS attribute [propName: string]: any }
seriesStyles (Map<string, SeriesLineStyle >, optional) A map holding the data series name with an associated SeriesLineStyle. Any series listed in this map will use the associated styles for that series. Any series not in the map will use the default series styles.
The SeriesLineStyle has the following shape
interface SeriesLineStyle { color: string lineWidth: number // the color of the series when the user mouses over the series highlightColor: string // the line width of the series when the user mouses over the series highlightWidth: number // the line margin used for raster charts margin?: number }
⤒ <Chart/> initial data
Holds the initial (static data). This data is displayed in the chart even before subscribing to the chart-data observable. The initial data can be used to generate static charts.
initialData (Array<Series >) An array holding the initial data series to be plotted before subscribing to the chart-data observable.
The Series has the following shape
interface Series { // the series name readonly name: string; // the array of time-value pairs data: Array<Datum>; // ... accessor functions . . . }
And the Datum is an immutable object that has the following shape
interface Datum { readonly time: number; readonly value: number; }
There are a number of helper functions for creating
Series
andDatum
.
seriesFrom(name: string, data: Array<Datum> = []): Series
seriesFromTuples(name: string, data: Array<[number, number]> = []): Series
emptySeries(name: string): Series
emptySeriesFor(names: Array<string>): Array<Series>
⤒ <Chart/> streaming data
A set of properties, functions, and callbacks to control and observe the streaming of live data into the chart.
seriesObservable (Observable<ChartData >) An observable of (source for) chart-data. The
shouldSubscribe
property controls whether the chart subscribes to the observable, or unsubscribes. This is the source of live data to the chart. An example of an observable is shown below.function randomSpikeDataObservable( series: Array<Series>, updatePeriod: number = UPDATE_PERIOD_MS, spikeProbability: number = 0.1 ): Observable<ChartData> { const seriesNames = series.map(series => series.name) const initialData = initialChartData(series) return interval(updatePeriod).pipe( // convert the number sequence to a time map(sequence => (sequence + 1) * updatePeriod), // create a random spike for each series map((time) => randomSpikeData(time, seriesNames, initialData.maxTimes, updatePeriod, spikeProbability)) ) }
shouldSubscribe (boolean, optional, default = false) Optional property, that when set from
false
totrue
, causes the <Chart/> to subscribe to the chart-data observable. When set tofalse
after a subscription, causes the <Chart/> to unsubscribe from the chart-data observable.
windowingTime (number, milliseconds, optional, default = 100 ms) Optional property that defines a time-window during which incoming events are buffered, and then handed to plot, causing the plot to update. The
windowingTime
defines the maximum plot update rate, though not the maximum data update rate. The larger the windowing time, the fewer updates per unit time, and the more choppy the updates. Large amounts of data with high update rates can cause rendering delays. The windowing time provides a lever to manage the plot update rates to get the smoothest plot updates that keep up with real-time.
shouldSubscribe (number, optional, default = false) Optional property that default to
false
. When changed totrue
, fromfalse
, signals the <Chart/> to subscribe to theseriesObservable
, streaming in theChartData
and updating the <Chart/> in real-time.
onSubscribe (callback function, (subscription: Subscription) => void, optional, default = noop Optional callback function that is called when the <Chart/> subscribes to the
ChartData
observable.
onUpdateData (callback function, (seriesName: string, data: Array)) => void, optional, default = noop) Optional callback function that is called when the data updates. This callback can be used if you would like to respond to data updates. For example, use this callback if you would like to have the plot drop data after 10 seconds, but would like to store that data in an in-browser database. Though, a more efficient way to store the data would be to subscribe to the series-observable separately, and then use that observer to stream the data to the storage.
onUpdateTime (callback function, (times: Map<string, [start: number, end: number]>) => void, optional, default = noop) Optional callback this is called whenever the time-ranges change. Use this to track the current time of the plot.
⤒ axes
⤒ <ContinuousAxis/>
The <ContinuousAxis/> must be a child of the <Chart/>. Each <Chart/> can one or two continuous axes for the x-axes and for the y-axes. When a <Chart/> has multiple x-axes or y-axes then you must assign series to the axes in one of the Plot
components. Any series that are not explicitly assigned an axis will be assigned to the default x-axis or y-axis. The default x-axis is the bottom axis in the <Chart/>, and the default y-axis is the left-hand side axis in the <Chart/>.
When creating a <ContinuousAxis/>, you must specify its location using the AxisLocation
enum defined in the axes.ts file. Each axis must have a unique axis ID. By default a <ContinuousAxis/> will have a linear scale (d3.scaleLinear). The scale
property can by used to set the scale to a log
(d3.scaleLog) or power
(d3.scalePow) scale or any other continuous numeric scale available in d3
. The domain
property defines the initial min and max values for the axis, and when data streams into the plot, that defines the time-window displayed for the axis (unless changed by a zoom event).
⤒ <ContinuousAxis/> base properties
The base properties defining the axis.
axisId (string) The unique ID of the axis. The axis can then be referred to by this ID. For example, when assigning axes to series, the assignment is made by associating the axis ID to the series name.
location (AxisLocation ) The location of the axis. As defined by the
AxisLocation
in the the axes.ts file, x-axes can be placed on thebottom
or thetop
, and y-axes can be placed on theleft
or theright
.
scale (ScaleContinuousNumeric<number, number>, optional, default = d3.scaleLinear) The optional scale (factory) of the continuous axis. The scale of the axis is like the axis ruler and determines how the points are placed on the screen. For example, a linear scale is like an evenly spaced ruler, and the mapping between screen location and data value are linear. As another example, the log scale has a logarithmic mapping between the screen location and the data. The scale can be a linear scale (default scale, d3.scaleLinear), a logarithmic scale (d3.scaleLog), a power scale (d3.scalePower), or any other d3 continouos numeric scale that works. Not that if a chart, for example, has two x-axes, that the x-axes are not required to have the same scale.
domain ([min: number, max: number]) The domain of the axis (in d3 terminology) is effectively the minimum value of the axis and the maximum value of the axis when the initial data is displayed. The domain defines the time-window of the displayed data. For example, if the
domain
for an x-axis is specified as[1000, 6000]
, then the axis starts at1000
and ends at6000
, and the time-window is5000
. Once data starts to stream past the axis end, the plot starts to scroll, maintaining the calculated time-window (in out example, 5000). Of course, a zooming event will change the domain, and also the time-window.
label (string) The axis label.
⤒ <ContinuousAxis/> styling
A set of properties to update the style of the axes.
font (Partial<AxesLabelFont >) An optional CSS properties specifying the font for the axis and tick labels.
⤒ <CategoryAxis/>
The <CategoryAxis/> must be a child of the <Chart/>. Each <Chart/> can one or two category axes for the y-axes. Unlike the <ContinousAxis/>, the <CategoryAxis/> can only be used as a y-axis because for stream charts (at this point) the x-axes represent time. In the same way as with the <ContinousAxis/>, when using multiple multiple y-axes you must assign the series to the axes in one of the Plot
components. Any series that are not explicitly assigned an axis will be assigned to the default y-axis, which is the left-hand side axis in the <Chart/>.
When creating a <CategoryAxis/>, you must specify its location using the AxisLocation
enum defined in the axes.ts file. Each axis must have a unique axis ID. The <CategoryAxis/> uses a band scale (d3.scaleLinear).
⤒ <CategoryAxis/> base properties
The base properties defining the axis.
axisId (string) The unique ID of the axis. The axis can then be referred to by this ID. For example, when assigning axes to series, the assignment is made by associating the axis ID to the series name.
location (AxisLocation ) The location of the axis. As defined by the
AxisLocation
in the the axes.ts file, x-axes can be placed on thebottom
or thetop
, and y-axes can be placed on theleft
or theright
.
categories (Array) The required
categories
property holds the names of the categories, in the order that they will be displayed on the axis. The first element in the array will be on shown at the top of the axis. The second element will be on lower, and the last element will be at the bottom of the axis.
domain ([min: number, max: number]) The domain of the axis (in d3 terminology) is effectively the minimum value of the displayed axis and the maximum value of the displayed axis when the initial data is displayed. The domain defines the time-window of the displayed data. For example, if the
domain
for an x-axis is specified as[1000, 6000]
, then the axis starts at1000
and ends at6000
, and the time-window is5000
. Once data starts to stream past the axis end, the plot starts to scroll, maintaining the calculated time-window (in out example, 5000). Of course, a zooming event will change the domain, and also the time-window.
label (string) The axis label.
⤒ <CategoryAxis/> styling
A set of properties to update the style of the axes.
font (Partial<AxesLabelFont >, optional) An optional CSS properties specifying the font for the axis and tick labels.
⤒ plots
⤒ <ScatterPlot/>
In stream-charts
, the plot
is the data visualization component. To work, a plot must be a child of the <Chart/> component so that it is plugged into the stream-charts
ecosystem. The plot determines how to render the data. But it relies on the axes to determine scaling information so that it can map data to screen locations. And therefore, a plot must have sibling axes (<ContinousAxis/>, <CategoryAxis/>) components for the x-axis and the y-axis. Because the plot is responsible for data visualization, it is also where the data series are assigned to axes. The assignment of axes to series is optional, and any series not explicitly assigned to an axis will be assigned to the default axes. The default x-axis is the bottom axis, and the default y-axis is the axis on the left-hand side of the plot.
The plot determines what view-modifying user interactions are available. Specifically, panning the data to the left and right in time, and zooming in time.
The <ScatterPlot/> specifically is used to plot time-series data, where the x-values are time. The x-axis and y-axis are required to be a <ContinousAxis/>.
⤒ <ScatterPlot/> base properties
axisAssignments (Map<string, AxesAssignment >, optional, default = Map()) An optional property that assigns data series to (x, y)-axes. Any series not assigned to an axis will use the default axis. The default x-axis is the bottom axis, and the default y-axis is the axis on the left-hand side of the plot. The
Map
associates the series name with an AxesAssignment, which is a simple object ({xAxis: string, yAxis: string}
) that holds the axis ID for the x-axis and for the y-axis assigned to the series.
interpolation (d3.CurveFactory, optional, default = d3.curveLinear) An optional property that defines how the data series line will be interpolated between individual data points. You can use any valid d3.CurveFactory for the interpolation. Changing the interpolation once the data is already display, will cause a re-render of the data with the new interpolation.
dropDataAfter (number, milliseconds, opitional, default = Infinity) Optional property that sets when to drop data (effectively a TTL). This only drops data while streaming. Don't worry, your data won't disappear after the streaming has stopped. By default, none of the data is dropped. However, when large amounts of data are being streamed and plotted over long periods of time, memory and performance may become an issue. Setting this value allows a scrolling chart to run forever without running into resource issues.
⤒ <ScatterPlot/> view-modifying interactions
View-modifying interactions are those that change the way the data is displayed. For example, zooming in time, panning in time.
panEnabled (boolean, optional, default = false) Optional property that defaults to
false
. When set totrue
then enables "panning" which allows the user to drag the plot to the left and right.
zoomEnabled (boolean, optional, default = false) Optional property that defaults for
false
. When set totrue
then enables "zooming" which allows the user to increase or decrease the displayed time range. By default, scrolling will cause the zoom effect. See thezoomKeyModifiersRequired
property which requires theshift
key to be pressed in order for the zoom action to apply.
zoomKeyModifiersRequired (boolean, optional, default = false) An optional property that defaults to
false
. When set totrue
, and thezoomEnabled
property is also set totrue
, then requires that theshift
key be pressed when scrolling in order to activate the zoom. This is nice when a user can scroll through your page containing the plot, so that zooming doesn't interfere with scrolling.
withCadenceOf (number, optional, default = undefinded) An optional property that defaults to
undefined
. When set, uses a cadence with the specified refresh period (in milliseconds). For plots with slow data updates (> 100 ms) using a cadence of 10 to 25 ms smooths out the updates so the time scrolling doesn't appear choppy. When updates are around 25 ms or less, then setting the cadence period too small will result in poor update performance. Generally at high update speeds, the cadence is unnecessary. Finally, using cadence, sets the max time to the current time. See also the related <Chart/>'swindowingTime
property.
⤒ <RasterPlot/>
In stream-charts
, the plot
is the data visualization component. To work, a plot must be a child of the <Chart/> component so that it is plugged into the stream-charts
ecosystem. The plot determines how to render the data. But it relies on the axes to determine scaling information so that it can map data to screen locations. And therefore, a plot must have sibling axes (<ContinousAxis/>, <CategoryAxis/>) components for the x-axis and the y-axis. Because the plot is responsible for data visualization, it is also where the data series are assigned to axes. The assignment of axes to series is optional, and any series not explicitly assigned to an axis will be assigned to the default axes. The default x-axis is the bottom axis, and the default y-axis is the axis on the left-hand side of the plot.
The plot determines what view-modifying user interactions are available. Specifically, panning the data to the left and right in time, and zooming in time.
The <RasterPlot/> specifically is used to plot event-timing data, where the x-values are time, and the y-values are a category to which the event belongs. The x-axis is required to be a <ContinousAxis/>, and the y-axis is required to the a <CategoryAxis/>.
⤒ <RasterPlot/> base properties
axisAssignments (Map<string, AxesAssignment >, optional, default = Map()) An optional property that assigns data series to (x, y)-axes. Any series not assigned to an axis will use the default axis. The default x-axis is the bottom axis, and the default y-axis is the axis on the left-hand side of the plot. The
Map
associates the series name with an AxesAssignment, which is a simple object ({xAxis: string, yAxis: string}
) that holds the axis ID for the x-axis and for the y-axis assigned to the series.
dropDataAfter (number, milliseconds, opitional, default = Infinity) Optional property that sets when to drop data (effectively a TTL). This only drops data while streaming. Don't worry, your data won't disappear after the streaming has stopped. By default, none of the data is dropped. However, when large amounts of data are being streamed and plotted over long periods of time, memory and performance may become an issue. Setting this value allows a scrolling chart to run forever without running into resource issues.
spikeMargin (number, pixels, default = 2) Optional property that adds a margin to the top and bottom of the raster (event) lines to give vertical spacing to the events in the plot. Margins on individual series can also be set through the Chart.seriesStyles property.
⤒ <RasterPlot/> view-modifying interactions
View-modifying interactions are those that change the way the data is displayed. For example, zooming in time, panning in time.
panEnabled (boolean, optional, default = false) Optional property that defaults to
false
. When set totrue
then enables "panning" which allows the user to drag the plot to the left and right.
zoomEnabled (boolean, optional, default = false) Optional property that defaults for
false
. When set totrue
then enables "zooming" which allows the user to increase or decrease the displayed time range. By default, scrolling will cause the zoom effect. See thezoomKeyModifiersRequired
property which requires theshift
key to be pressed in order for the zoom action to apply.
zoomKeyModifiersRequired (boolean, optional, default = false) An optional property that defaults to
false
. When set totrue
, and thezoomEnabled
property is also set totrue
, then requires that theshift
key be pressed when scrolling in order to activate the zoom. This is nice when a user can scroll through your page containing the plot, so that zooming doesn't interfere with scrolling.
withCadenceOf (number, optional, default = undefinded) An optional property that defaults to
undefined
. When set, uses a cadence with the specified refresh period (in milliseconds). For plots with slow data updates (> 100 ms) using a cadence of 10 to 25 ms smooths out the updates so the time scrolling doesn't appear choppy. When updates are around 25 ms or less, then setting the cadence period too small will result in poor update performance. Generally at high update speeds, the cadence is unnecessary. Finally, using cadence, sets the max time to the current time. See also the related <Chart/>'swindowingTime
property.
⤒ utilities
⤒ <Tracker/>
The tracker, when enabled, follows the mouse when it is in the plot area, renders a vertical line from the bottom x-axis to the top of the plot, and displays the time value for either one or both the x-axes.
⤒ <Tracker/> base properties
visible (boolean) When set to
true
the tracker is visible when the mouse is in the plot area. When set tofalse
the tracker is not shown.
labelLocation (TrackerLabelLocation, optional, default = TrackerLabelLocation.WithMouse) Optional property specifies the location of the label. The
TrackerLabelLocation
is an enumeration with three valuesNowhere
,WithMouse
, andByAxes
. By default, the label location is with the mouse (i.e.WithMouse
). TheNowhere
location can be used to hide the label, in cases where you would like to use your own. TheWithMouse
value has the label follow the mouse in the vertical direction along the tracker line. And theByAxes
displays the labels next to their respective axes, with the tracker line.
onTrackerUpdate ((update: TrackerAxisUpdate) => void, optional, default = noop) Optional callback function that accepts the update from the tracker. Use this to display the tracker and data information outside of the <Chart/>. The
TrackerAxisUpdate
is aMap<string, TrackerAxisInfo>
, theTrackerAxisInfo
has the shape{x: number, axisLocation: AxisLocation}
, and theAxisLocation
is an same enumeration used for placing the axes on the chart (i.e.AxisLocation.Bottom
,AxisLocation.Top
).
⤒ <Tracker/> styling
style (TrackerStyle, optional, default = {visible: false, color: '#d2933f', lineWidth: 1}) Optional property defining the style for the tracker line. Has a shape of
{visible: boolean, color: string, lineWidth: number}
.
font (TrackerLabelFont, optional, default = {size: 12, color: '#d2933f', weight: 300, family: 'sans-serif'}) Optional property defining the font for the tracker label. Has a shape of
{size: number, color: string, family: string, weight: number}
.
⤒ <Tooltip/>
A tooltip renders information about the data over which the mouse is hovering. The <Tooltip/> component in stream-charts
is the container for the tooltip content. It is responsible for rendering the area in which the tooltip contents are displayed. The tooltip content is a child of the <Tooltip/> component so that it can be (relatively) easily extended. Currently stream-charts
has two tooltip contents, one for each plot type (<ScatterPlotTooltipContent/> and <RasterPlotTooltipContent/>). Each of these will be covered after we discuss the <Tooltip/>.
The properties for the lt;Tooltip/> are simple and limited. The tooltip content components have more options.
visible (boolean) When set to
true
the the tooltip is shown when the mouse hovers over a data series or point.
style (TooltipStyle, optional, default = defaultTooltipStyle ) Optional property defining the style of the tooltip. The following style elements are available
- visibleVisibility of the tooltip when the mouse hovers over a data series or point
- fontSizeThe size of the font displayed in the tooltip
- fontColorThe color of the text displayed in the tooltip
- fontFamilyThe font weight for the text displayed in the tooltip
- fontWeightThe font weight for the text displayed in the tooltip
- backgroundColorThe background color of the tooltip
- backgroundOpacityThe opacity of the background (i.e. how transparent it is)
- borderColorThe color of the border surrounding the tooltip content
- borderWidthThe width of the border surrounding the tooltip content
- borderRadiusThe radius of the border surrounding the tooltip content
- paddingLeftThe padding to the left of the tooltip content
- paddingRightThe padding to the right of the tooltip content
- paddingTopThe padding to the top of the tooltip content
- paddingBottomThe padding to the bottom of the tooltip content
children (<ScatterPlotTooltipContent/> and <RasterPlotTooltipContent/>) The tooltip content.
⤒ <ScatterPlotTooltipContent/>
The <ScatterPlotTooltipContent/> renders a table displaying the series datum that immediately precedes the mouse location, and immediately follows the mouse location. The first row shows the x-values, and the second row shows the y-values. The table below maps the properties to the table elements they effect.
series name
| | beforeHeader | afterHeader | deltaHeader | |---|-------------|-------------|-------------| | xLabel | xValueFormatter | xValueFormatter | xChangeFormatter | | yLabel | yValueFormatter | yValueFormatter | yChangeFormatter |
xLabel (string) Required property that gives a name to the x-values. This is the label for the x-values in the tooltip.
yLabel (string) Required property that gives a name to the y-values. This is the label for the y-values in the tooltip.
beforeHeader (string, optional, default = 'before') Optional property that gives a name to the data point that is immediately before the mouse location.
afterHeader (string, optional, default = 'after') Optional property that gives a name to the data point that is immediately after the mouse location.
deltaHeader (string, optional, default = '∆') Optional property that gives a name to the difference between the datum immediately before and after the mouse location.
xValueFormatter ((value: number) => string, optional, default = formatTime Optional function that formats the x-value immediately before and after the mouse location. The default function formats that x-values as natural numbers representing milliseconds.
yValueFormatter ((value: number) => string, optional, default = formatValue Optional function that formats the x-value immediately before and after the mouse location. The default function formats the y-values as floating point with 3 values to the right of the decimal point.
xChangeFormatter ((value1: number, value2: number) => string, optional, default = formatTimeChange Optional function that formats the change in the x-value of the points immediately before and after the mouse location. The default function formats the value as a natural number.
yChangeFormatter ((value1: number, value2: number) => string, optional, default = formatValueChange Optional function that formats the change in the y-value of the points immediately before and after the mouse location. The default function formats the value as floating point with 3 values to the right of the decimal point.
style (TooltipStyle, optional, default = defaultTooltipStyle ) Optional styles for the tooltip content. The styles are the same as those for the <Tooltip/>.
⤒ <RasterTooltipContent/>
The <RasterPlotTooltipContent/> shows the series name, the time and value of the point over which the mouse is hovering. There are only three properties.
xFormatter ((value: number) => string, optional, default = formatTime Optional function that formats the x-value immediately before and after the mouse location. The default function formats that x-values as natural numbers representing milliseconds.
yFormatter ((value: number) => string, optional, default = formatValue Optional function that formats the x-value immediately before and after the mouse location. The default function formats the y-values as floating point with 3 values to the right of the decimal point.
style (TooltipStyle, optional, default = defaultTooltipStyle ) Optional styles for the tooltip content. The styles are the same as those for the <Tooltip/>.
building
Building
npm install
npm run build
Packaging
npm pack
Testing
npm run test
Creating docs
npm install typedoc
npx typedoc src/app/charts/*