Skip to content

Commit

Permalink
feat(react-components): add arrow datasource
Browse files Browse the repository at this point in the history
  • Loading branch information
jmbuss authored and corteggiano committed Jun 24, 2024
1 parent 4c2402c commit efb0d6d
Show file tree
Hide file tree
Showing 24 changed files with 3,500 additions and 19 deletions.
79 changes: 79 additions & 0 deletions packages/doc-site/stories/components/anomalyChart/Data.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,82 @@ Here's an example of the Anomaly chart data structure:
```

In this example, the state is 'success', indicating that the data was loaded successfully. The value object contains two diagnostic events, each with a timestamp and an array of diagnostic objects. Each diagnostic object has a name and a value between 0 and 1. The styles object overrides the global color palette for rendering the diagnostics, specifying an array of colors (['pink', 'blue', 'green', 'red']).

---

**value (object, required)** : An object containing the raw data and optional style overrides. It has the following properties:

- **data** (object, required): An object that represents the data in a columnar table by using fields, where each field represents a column in a table, the values in a field represent a the rows in the table, and a single value represents a cell in the table row for that field. The fields together represent a single Diagnostic event with a timestamp and Diagnostic values.

- **name** (string, optional): The name of the data frame.

- **fields** (array, required): An array of objects where each object describes one column in the table with the following properties:

- **name** (string, required): The name of the column, which should be either `time, prediction_reason, prediction, quality, anomaly_score, or <diagnostic name>`.

- **type** (string, required): The data type of the column, which should be either `time, number, or string`.

- **values** (array, required): An array of table values whose types are the same as the type property.

- **length** (number, required): The number of rows in the columnar table.

- **styles** (object, optional): An object that overrides global style settings. It can have the following properties:

- **decimalPlaces** (number, optional): Defines the number of decimal places to display for the diagnostic values.

- **color** (array, optional): An array representing the color palette used to render the diagnostics.


### Example

Here's an example of the Anomaly chart data structure:

```
{
state: 'success',
value: {
styles: {
// defines the color pallette for the diagnostics
color: ['pink', 'blue', 'green', 'red'],
},
data: {
fields: [
{
name: 'time',
type: FieldType.time,
values: [1714676404000, 1714676405000, 1714676407000, 1714676408000],
},
{
name: 'prediction_reason',
type: FieldType.string,
values: [
'ANOMALY_DETECTED',
'ANOMALY_DETECTED',
'ANOMALY_DETECTED',
'ANOMALY_DETECTED',
],
},
{
name: 'Diagnostic 1',
type: FieldType.number,
values: [0.27978, 0.2796, 0.27943, 0.27925],
},
{
name: 'Diagnostic 2',
type: FieldType.number,
values: [0.10742, 0.10739, 0.10735, 0.10731],
},
{
name: 'Diagnostic 3',
type: FieldType.number,
values: [0.21679, 0.21717, 0.21754, 0.21792],
},
],
length: 4,
name: 'Diagnostic Data Frame',
}
},
};
```

In this example, the state is 'success', indicating that the data was loaded successfully. The value object contains four diagnostic events, represented by index across the values of each field. Each diagnostic field object has a name and values between 0 and 1. The styles object overrides the global color palette for rendering the diagnostics, specifying an array of colors (['pink', 'blue', 'green', 'red']).
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { AnomalyChartOptions } from './types';
import {
AnomalyObjectDataSourceTransformer,
AnomalyArrowDataSourceTransformer,
DataSourceLoader,
} from '../../data';

Expand All @@ -21,6 +22,7 @@ import { DEFAULT_ANOMALY_DATA_SOURCE_VIEWPORT } from '../../queries/useSiteWiseA
*/
const AnomalyDataSourceLoader = new DataSourceLoader([
new AnomalyObjectDataSourceTransformer(),
new AnomalyArrowDataSourceTransformer(),
]);

export const AnomalyChart = (options: AnomalyChartOptions) => {
Expand Down
2,599 changes: 2,599 additions & 0 deletions packages/react-components/src/components/anomaly-chart/tests/mockDataSources.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Viewport } from '@iot-app-kit/core';
import type { FixedLengthArray } from 'type-fest';
import { AnomalyObjectDataSource } from '../../data/transformers/anomaly/object/datasource';
import { AnomalyDataQuery } from '@iot-app-kit/source-iotsitewise';
import { AnomalyArrowDataSource, AnomalyObjectDataSource } from '../../data';

export type TooltipSort = 'value' | 'alphabetical';
export type ThemeMode = 'light' | 'dark';

export type AnomalyChartDataSources = AnomalyObjectDataSource;
export type AnomalyChartDataSources =
| AnomalyObjectDataSource
| AnomalyArrowDataSource;

export type AnomalyChartDataSourceOption = {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import {
AnomalyObjectDataSource,
AnomalyObjectDataSourceTransformer,
} from '../transformers/anomaly';
import {
AnomalyArrowDataSource,
AnomalyArrowDataSourceTransformer,
} from '../transformers/anomaly/arrow';
import { FieldType } from '../transformers/arrow';
import { DataSource } from '../types';
import { DataSourceLoader } from './dataSourceLoader';

Expand Down Expand Up @@ -52,6 +57,78 @@ const validAnomalyObjectDataSource: AnomalyObjectDataSource = {
},
};

const validAnomalyArrowDataSource: AnomalyArrowDataSource = {
state: 'success',
value: {
data: {
fields: [
{
name: 'time',
type: FieldType.time,
values: [1714676404000, 1714676405000, 1714676407000, 1714676408000],
},
{
name: 'quality',
type: FieldType.string,
values: ['GOOD', 'GOOD', 'GOOD', 'GOOD'],
},
{
name: 'anomaly_score',
type: FieldType.number,
values: [0.85666, 0.85684, 0.85702, 0.85721],
},
{
name: 'prediction_reason',
type: FieldType.string,
values: [
'ANOMALY_DETECTED',
'ANOMALY_DETECTED',
'ANOMALY_DETECTED',
'ANOMALY_DETECTED',
],
},
{
name: 'water_temperature',
type: FieldType.number,
values: [0.27978, 0.2796, 0.27943, 0.27925],
},
{
name: 'ph',
type: FieldType.number,
values: [0.10578, 0.10573, 0.10569, 0.10564],
},
{
name: 'room_humidity',
type: FieldType.number,
values: [0.10475, 0.1047, 0.10466, 0.10462],
},
{
name: 'water_level',
type: FieldType.number,
values: [0.0801, 0.08007, 0.08003, 0.08],
},
{
name: 'soil_moisture',
type: FieldType.number,
values: [0.10538, 0.10534, 0.1053, 0.10526],
},
{
name: 'room_temperature',
type: FieldType.number,
values: [0.10742, 0.10739, 0.10735, 0.10731],
},
{
name: 'light_intensity',
type: FieldType.number,
values: [0.21679, 0.21717, 0.21754, 0.21792],
},
],
length: 4,
name: 'Hydroponic_Garden_1',
},
},
};

const unsupportedDataSource: DataSource = {
state: 'success',
value: {
Expand All @@ -60,10 +137,32 @@ const unsupportedDataSource: DataSource = {
};

describe('Data Source Loader', () => {
it('can transform different types of datasources', () => {
const anomalyObjectTransformer = new AnomalyObjectDataSourceTransformer();
const anomalyArrowTransformer = new AnomalyArrowDataSourceTransformer();

const dataLoader = new DataSourceLoader([
anomalyObjectTransformer,
anomalyArrowTransformer,
]);

// specific transform types handled by the transformer tests
expect(
dataLoader.transform([validAnomalyObjectDataSource])
).toBeArrayOfSize(1);
expect(dataLoader.transform([validAnomalyArrowDataSource])).toBeArrayOfSize(
1
);
});

it('can transform datasources', () => {
const anomalyTransformer = new AnomalyObjectDataSourceTransformer();
const anomalyObjectTransformer = new AnomalyObjectDataSourceTransformer();
const anomalyArrowTransformer = new AnomalyArrowDataSourceTransformer();

const dataLoader = new DataSourceLoader([anomalyTransformer]);
const dataLoader = new DataSourceLoader([
anomalyObjectTransformer,
anomalyArrowTransformer,
]);

// specific transform types handled by the transformer tests
expect(dataLoader.transform([validAnomalyObjectDataSource])).toBeArray();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ArrowDataSource } from '../../arrow';
import { AnomalyArrowDataSourceValue } from './input';

export type AnomalyArrowDataSource =
ArrowDataSource<AnomalyArrowDataSourceValue>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './input';
export * from './transformer';
export * from './datasource';
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { ArrowDataSourceValue } from '../../arrow';
import { AnomalyStyles } from '../input';

export type AnomalyArrowDataSourceValue = ArrowDataSourceValue<AnomalyStyles>;
Loading

0 comments on commit efb0d6d

Please sign in to comment.