# Visualization Canvas

## Description

This package publishes canvas based react visualization components currently for timeseries based data charts (that include line, bar, and area charts) and in future expanded to more performant canvas based charts.

The core of the chart visualization is built on top of [uPlot](https://github.com/leeoniya/uPlot) to support fast rendering and rerendering of charts.

Note:- This package has been ported over initially from `olly-timeseries-viz` to Splunk vision repo, in effort of consolidating viz components centrally and to further expand the capabililities.

This package contains small components for direct consumption use case (outside of udf-dashboard) that gets used for customizable visual features for canvas based graphs. The features contain different options of visual displays such as Legends, Marks, Pins that gets used to visualize interactable dashboards components.

## Running viz-canvas storybook

Make sure your node version is >= 20.

```
yarn install
yarn storybook
```

Once the setup is complete storybook will start at: http://localhost:6006

## Glossary

| Term                                       | Meaning                                                                                                                                                                                                          |
| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| DataSet                                    | The data format used for the TimeSeriesChart component. The format follows the (udf data set)[https://splunkui.splunkdev.page/Packages/dashboard-docs/?path=%2FDataset] format with `_time` as the first column. |
| [uPlot](https://github.com/leeoniya/uPlot) | A small, fast chart package for time series, lines, areas, bars, and more                                                                                                                                        |
| UDF                                        | [Unified Dashboard Framework](https://splunkui.splunkdev.page/Packages/dashboard-docs/?path=%2FIntroduction) (internal name of the Dashboarding Framework)                                                       |
| Mark                                       | A horizontal or vertical line drawn on the chart, sometimes called a marker as well. Used to show a trend, calculation, boundary, or other important value.                                                      |
| Pin                                        | A dismissable, vertical indicator showing a specific point that was clicked on a chart.                                                                                                                          |
| Tooltip                                    | An overlay that shows additional details for the area occupied by the cursor on the chart.                                                                                                                       |
| Event Annotation                           | An icon that appears below the x-axis of the chart indicating that an event happened at that point in time                                                                                                       |
| Range Selection                            | The ability to select a subsection of the chart for focus, zooming, or other follow up interactions                                                                                                              |

## Getting started with `TimeSeriesChart`

To get started with the `TimeSeriesChart` examples of some use cases are provided below. To see these examples running look at the **Overview** section of Storybook.

## DataSet

The DataSet object has a `fields` array that contains the names for each series and a `columns` property that is an array of arrays where each array maps to the corresponding index in the `fields` array.

A simple example with a few datapoints for 1 time series is:

```
const sampleDataSet = {
  fields: ['_time', 'cpu_utilization'],
  columns: [[
    1729274400000,
    1729274401000,
    1729274402000,
    1729274403000
  ],[
    70,
    75,
    93,
    82
  ]]
}
```

For categorical x-axis data (non timeseries chart), `GenericDataSet` object can be used, that doesnot have the restriction for field[0] to be `_time` and and column[0] can be number or string array type

```
const CategoricalData: GenericDataSet = {
    fields: ['foo', 'bar', 'baz'],
    columns: [
        ['one', 'two', 'three', 'four', 'five', 'six'],
        [5.87, 6.55, 7.6, 8.79, 9.1, 5.86],
        [25.97, 24.52, 23.23, 22.63, 21.15, 10.29],
    ],
};
```

## Basic Line Chart

There are only 3 required parameters for the TimeSeriesChart, `width`, `height`, and `data`. `width` and `height` can be a number representing a pixel value or a string such as `100%`.

The `data` is formatted as a **DataSet**.

So a simple chart using the `sampleDataSet` from above would look like

```
<TimeSeriesChart
    height={300}
    width={800}
    data={sampleDataSet}
/>
```

## Basic Line Chart with series and scales

To associate formatting to the scale and the chart, for example to show that it is a percent scale, you use the `scaleConfig` and `seriesConfig` props. The keys for the `seriesConfig` match the series names in the `DataSet` `fields`. The `scaleConfig` keys can then be used to match up a `seriesConfig` to a scale.

```
<TimeSeriesChart
    height={300}
    width={800}
    data={sampleDataSet as DataSet}
    scaleConfig={{
        '%': { label: 'Percent', side: 'left' },
    }}
    seriesConfig={{
        cpu_utilization: {
            scale: '%',
            label: 'CPU %',
        },
    }}
/>
```

## Basic Bar Chart

To change to other chart types supported by the `TimeSeriesChart` component you can specify a `type` in the `seriesConfig`. Here is an example for a message queue showing how many have been processed each minute.

```
const sampleMessageQueueDataSet = {
    fields: ['_time', 'messages_handled'],
    columns: [
        [1729274400000, 1729274460000, 1729274520000, 1729274580000],
        [3000, 400, 1000, 2100],
    ],
};

const BasicBarChart = (
      <TimeSeriesChart
        height={300}
        width={800}
        data={sampleMessageQueueDataSet as DataSet}
        seriesConfig={{
            messages_handled: {
                type: 'bar',
            },
        }}
    />
)
```
