LogoLogo
Developer HubGitHubContact Us
  • Welcome!
  • Olive Helps
    • Platform
      • How Olive Helps Works
      • Installation
      • Account Creation
      • Distributing Olive Helps
    • FAQs
      • General Loop FAQs
      • Loop Development FAQs
      • Olive Helps User FAQs
      • Security / IT FAQs
    • Data Security
      • User Data
      • Antivirus and Firewalls
  • Loop Development Kit
    • Your First Loop
      • Become a Loop Author
      • Creating a Loop
      • Build Your Loop
      • Local Loop Installation
      • Restarting Local Loops
    • Troubleshooting
    • Loop Security
      • Permissions
      • Environment Permissions
    • Loop Publication
      • Loop Approval Checklist
    • Loop Analytics Library
    • Examples
  • Documentation
  • Interfaces
  • Type Alias
  • Enumerations
  • Whisper Components
    • Base Attributes
    • Autocomplete
    • Box
    • Breadcrumb
    • Button
    • Chart
    • CollapseBox
    • Grid
    • Checkbox
    • Date Time
    • Divider
    • DropZone
    • Email
    • Icon
    • List Pair
    • Link
    • Pagination
    • Number
    • Markdown
    • Message
    • Password
    • Progress
    • Radio
    • Rating
    • RichTextEditor
    • Section Title
    • Select
    • Text Input
    • Telephone
    • Typography
  • APTITUDES
    • What are Aptitudes?
    • Browser
    • Clipboard
    • Config
    • Cursor
      • Screen Scaling Behavior
    • Document
    • Filesystem
    • Keyboard
    • Network
    • Process
    • Screen
    • Search
      • Index
    • System
    • UI
      • Loop UI Handlers
    • User
      • JWT
    • Vault
    • Whisper
      • Whisper Updates
      • JSX Whispers
    • Window
      • Screen Scaling Behavior
  • Release Notes
    • What's New
      • Olive Helps v0.55.0
      • Olive Helps v0.54.1
      • Olive Helps v0.53.1
      • Olive Helps v0.51.2
      • LDK v4.0.0
      • Olive Helps v0.50.3
      • Olive Helps v0.49.5
      • LDK v 3.18.0
      • Olive Helps v0.47.2
      • Olive Helps v0.46.2
      • LDK v 3.17.0
      • Olive Helps v0.45.4
      • Olive Helps v0.44.2
      • Olive Helps v0.43.1
      • Olive Helps v0.42.1
      • Olive Helps v0.41.4
      • Olive Helps v0.40.2
      • Olive Helps v0.39.4 & LDK v3.16.0
      • Olive Helps v0.38.8 & LDK v3.15.0
      • Olive Helps v0.36.5
      • Olive Helps v0.36.4
    • Archive
      • Olive Helps v0.36.3 & LDK v3.14.0
      • Olive Helps v0.34.4
      • LDK v3.13.0
      • Olive Helps v0.32.2 & LDK v3.12.0
      • Olive Helps v0.31.2 & LDK v3.11.0
      • Olive Helps v0.30.2 & LDK v3.10.0
      • Olive Helps v0.29.4
      • Olive Helps v0.29.3 & LDK v3.9.0
      • Olive Helps v0.28.3 & LDK v3.8.0
      • Olive Helps v0.27.7
      • Olive Helps v0.27.5
      • Olive Helps v.027.4
      • Olive Helps v0.27.2 & LDK v3.7.0
      • Olive Helps v0.25.3 & LDK v3.5.1
      • Olive Helps v0.24.6 & LDK v3.4.0
      • Olive Helps v0.23.2 & LDK v3.3.0
      • Olive Helps v0.22.3 & LDK v3.2.0
Powered by GitBook
On this page
  • Props:
  • Examples:

Was this helpful?

  1. Whisper Components

Chart

A chart is a graphical representation for data visualization. A chart can represent tabular numeric data, functions, as well as many other data points.

Props:

Name
Type
Description
Required
Default

chartTitle

string

Title of the chart. Appears above the chart.

heightToWidthRatio

string

Sets the height-to-width ratio of the chart. The width of the chart is automatically set to 100% of the width of the Whisper card and popup window so the height is defined as a ratio of the width (rather than as an absolute value).

1

horizontalLineTotal

number

Set the total number of horizontal lines showing on the grid.

auto-calculated

horizontalGridLines

boolean

Show horizontal lines on the grid.

true

margin

{ left:number, right:number, top:number, bottom:number }

Set the margins around the chart. This is especially useful for widening the left or bottom margins to accommodate larger tick mark labels. The units are expressed in pixels.

{ left: 40, right: 10, top: 10, bottom: 40 }

series

Series<+SeriesType>[]

An array of the series that will appear in the chart. Up to 10 series may be provided. SeriesType { Area = 'area', Line = 'line', Mark = 'mark', VerticalBar = 'verticalBar', }

showChartInPopupWindowOnly

boolean

If true, the chart will only appear in the popup window and not in the Whisper itself.

false

showCrosshair

boolean

If true, show a tooltip when hovering over the chart, which displays the nearest x value and the corresponding y values for all series.

true

verticalGridLines

boolean

Show vertical lines on the grid.

true

verticalLineTotal

number

Set the total number of vertical lines showing on the grid.

auto-calculated

xAxis

boolean

Show the x-axis.

true

xAxisLabel

string

Set the x-axis label.

xAxisPadding

number

Sets the right and left (inside the x-axis) padding as a percentage of the chart width. Half of the provided value is applied to each side.

no padding

xAxisScale

+AxisScale

Scales determine how the data should be interpreted. The three scales available are linear, ordinal, and time.

Linear: a continuous scale that works with numbers.

Ordinal: a discrete, ordered set that works with numbers or strings. For example, the x values could contain the months of the year in string form.

Time: used for time series. x values will be interpreted as unix time.

liner

xAxisTickTotal

number

Total number of tick marks on the x-axis.

auto-calculated

xAxisTickLabelAngle

number

Set the angle of the tick mark labels on the x-axis in terms of degrees (positive or negative).

0

yAxis

boolean

Show the y-axis

true

yAxisLabel

string

Set the y-axis label

yAxisPadding

number

Sets the right and left (inside the y-axis) padding as a percentage of the chart width. Half of the provided value is applied to each side.

no padding

yAxisScale

+AxisScale

Scales determine how the data should be interpreted. The three scales available are linear, ordinal, and time.

Linear: a continuous scale that works with numbers.

Ordinal: a discrete, ordered set that works with numbers or strings. For example, the y values could contain the months of the year in string form.

Time: used for time series. Y values will be interpreted as unix time.

liner

yAxisTickLabelAngle

number

Set the angle of the tick mark labels on the y-axis in terms of degrees (positive or negative).

0

yAxisTickTotal

number

Total number of tick marks on the y-axis.

auto-calculated

Please note: Types marked with + are Olive LDK enums

Examples:

Area Graph:

Bar Graph:

Line Graph:

Mark Graph:

Four Series Graph:

Please note: The Chart Component is a beta feature.

import { whisper } from '@oliveai/ldk';
import {
  SeriesType,
  WhisperComponentType,
} from '@oliveai/ldk/dist/whisper/types';

const areaSeries = [
  {
    data: [
      { x: 1, y: 0 },
      { x: 1, y: 10 },
      { x: 2, y: 5 },
      { x: 3, y: 15 },
    ],
    title: 'Test Area 1',
    type: SeriesType.Area,
  },
  {
    data: [
      { x: 1, y: 0 },
      { x: 1, y: 3 },
      { x: 2, y: 1 },
      { x: 3, y: 6 },
    ],
    title: 'Test Area 2',
    type: SeriesType.Area,
  },
];

const barSeriesData = [
  {
    barWidth: 2,
    data: [
      { x: 50, y: 200 },
      { x: 150, y: 100 },
      { x: 400, y: 50 },
      { x: 600, y: 150 },
    ],
    title: 'Test Bars 1',
    type: SeriesType.VerticalBar,
  },
  {
    barWidth: 1,
    data: [
      { x: 100, y: 200 },
      { x: 200, y: 100 },
      { x: 300, y: 50 },
      { x: 500, y: 150 },
    ],
    title: 'Test Bars 2',
    type: SeriesType.VerticalBar,
  },
];

const lineSeriesData = [
  {
    data: [
      { x: 20, y: 200 },
      { x: 150, y: 100 },
      { x: 400, y: 50 },
      { x: 600, y: 150 },
    ],
    title: 'Test Bars 1',
    type: SeriesType.Line,
  },
  {
    data: [
      { x: 10, y: 200 },
      { x: 100, y: 100 },
      { x: 200, y: 50 },
      { x: 300, y: 150 },
    ],
    title: 'Test Bars 2',
    type: SeriesType.Line,
  },
];

const markSeriesData = [
  {
    data: [
      { x: 20, y: 200 },
      { x: 150, y: 100 },
      { x: 400, y: 50 },
      { x: 600, y: 150 },
    ],
    title: 'Test Bars 1',
    type: SeriesType.Mark,
  },
  {
    data: [
      { x: 10, y: 200 },
      { x: 100, y: 100 },
      { x: 200, y: 50 },
      { x: 300, y: 150 },
    ],
    title: 'Test Bars 2',
    type: SeriesType.Mark,
  },
];

const fourSeriesData = [
  {
    data: [
      { x: 100, y: 0 },
      { x: 100, y: 100 },
      { x: 200, y: 500 },
      { x: 300, y: 150 },
    ],
    title: 'Test Area 1',
    type: SeriesType.Area,
  },
  {
    data: [
      { x: 100, y: 0 },
      { x: 100, y: 300 },
      { x: 200, y: 100 },
      { x: 300, y: 600 },
    ],
    title: 'Test Area 2',
    type: SeriesType.Area,
  },
  {
    barWidth: 2,
    data: [
      { x: 50, y: 200 },
      { x: 150, y: 100 },
      { x: 400, y: 50 },
      { x: 600, y: 150 },
    ],
    title: 'Test Bars 1',
    type: SeriesType.VerticalBar,
  },
  {
    barWidth: 1,
    data: [
      { x: 100, y: 200 },
      { x: 200, y: 100 },
      { x: 300, y: 50 },
      { x: 500, y: 150 },
    ],
    title: 'Test Bars 2',
    type: SeriesType.VerticalBar,
  },
  {
    data: [
      { x: 20, y: 200 },
      { x: 150, y: 100 },
      { x: 400, y: 50 },
      { x: 600, y: 150 },
    ],
    title: 'Test Bars 1',
    type: SeriesType.Line,
  },
  {
    data: [
      { x: 10, y: 200 },
      { x: 100, y: 100 },
      { x: 200, y: 50 },
      { x: 300, y: 150 },
    ],
    title: 'Test Bars 2',
    type: SeriesType.Line,
  },
  {
    data: [
      { x: 20, y: 200 },
      { x: 150, y: 100 },
      { x: 400, y: 50 },
      { x: 600, y: 150 },
    ],
    title: 'Test Bars 1',
    type: SeriesType.Mark,
  },
  {
    data: [
      { x: 10, y: 200 },
      { x: 100, y: 100 },
      { x: 200, y: 50 },
      { x: 300, y: 150 },
    ],
    title: 'Test Bars 2',
    type: SeriesType.Mark,
  },
];

const chartWhisper = async () => {
  await whisper.create({
    label: 'Chart',
    onClose: () => {
      console.log('Closed chart Whisper');
    },
    components: [
      {
        type: WhisperComponentType.Chart,
        chartTitle: 'Area Graph',
        series: areaSeries,
        xAxisLabel: "Custom X Axis Label",
        yAxisLabel: "Custom Y Axis Label",
      },
      {
        type: WhisperComponentType.Chart,
        chartTitle: "Bar Graph",
        series: barSeriesData,
        xAxisLabel: "Custom X Axis Label",
        yAxisLabel: "Custom Y Axis Label",
      },
      {
        type: WhisperComponentType.Chart,
        chartTitle: "Line Graph",
        series: lineSeriesData,
        xAxisLabel: "Custom X Axis Label",
        yAxisLabel: "Custom Y Axis Label",
      },
      {
        type: WhisperComponentType.Chart,
        chartTitle: "Mark Graph",
        series: markSeriesData,
        xAxisLabel: "Custom X Axis Label",
        yAxisLabel: "Custom Y Axis Label",
      },
      {
        type: WhisperComponentType.Chart,
        chartTitle: "Four Series Graph",
        series: fourSeriesData,
        xAxisLabel: "Custom X Axis Label",
        yAxisLabel: "Custom Y Axis Label",
      },
    ],
  });
}
import { whisper, React, ReactWhisper } from '@oliveai/ldk';
import { AxisScale, SeriesColor, SeriesType } from '@oliveai/ldk/dist/whisper/types';
import { onActionWrapper } from '../utils';

type SeriesInput = {
  barWidth?: number;
  color?: SeriesColor;
  numberOfPoints?: number;
  title: string;
  type: SeriesType;
};

const generateSeries = (inputs: SeriesInput[]) =>
  inputs.map((input) => {
    const data = [];

    for (let i = 0; i < (input.numberOfPoints || 20); i += 1) {
      const x = Math.floor(Math.random() * 100);
      const y = Math.floor(Math.random() * 100);
      data.push({ x, y });
    }

    return { ...input, data };
  });

type RegenerateButtonParams = {
  setter: React.Dispatch<React.SetStateAction<SeriesInput[]>>;
  seriesData: SeriesInput[];
};

const RegenerateButton = ({ setter, seriesData }: RegenerateButtonParams) => {
  const handleClick = () => {
    setter(generateSeries(seriesData));
  };

  return (
    <oh-box justifyContent={whisper.JustifyContent.Center} direction={whisper.Direction.Horizontal}>
      <oh-button label="Regenerate Chart Data" onClick={handleClick} />
    </oh-box>
  );
};

export const testChart = (): Promise<boolean> =>
  new Promise(async (resolve, reject) => {
    const resolverMap = new Map([
      ['AreaGraph', false],
      ['BarGraph', false],
      ['LineGraph', false],
      ['MarkGraph', false],
      ['FourSeries', false],
    ]);

    const ConfirmationButtons = ({
      question,
      testName,
    }: {
      question: string;
      testName: string;
    }) => {
      const [isTested, setIsTested] = React.useState(false);

      const handleClick: whisper.WhisperHandler = (error, thisWhisper) => {
        onActionWrapper(error, testName, resolverMap, thisWhisper, resolve, reject);
        setIsTested(true);
      };

      return (
        <>
          <oh-box
            justifyContent={whisper.JustifyContent.Center}
            direction={whisper.Direction.Horizontal}
          >
            <oh-markdown body={question} />
          </oh-box>
          <oh-box
            justifyContent={whisper.JustifyContent.Center}
            direction={whisper.Direction.Horizontal}
          >
            {isTested ? (
              <oh-icon name="done" />
            ) : (
              <>
                <oh-button label="Yes" onClick={handleClick} />
                <oh-button label="No" onClick={() => reject(new Error(`${testName} failed`))} />
              </>
            )}
          </oh-box>
        </>
      );
    };

    try {
      const AreaGraph = () => {
        const series = [
          {
            data: [
              { x: 1, y: 0 },
              { x: 1, y: 10 },
              { x: 2, y: 5 },
              { x: 3, y: 15 },
            ],
            title: 'Test Area 1',
            type: SeriesType.Area,
          },
          {
            data: [
              { x: 1, y: 0 },
              { x: 1, y: 3 },
              { x: 2, y: 1 },
              { x: 3, y: 6 },
            ],
            title: 'Test Area 2',
            type: SeriesType.Area,
          },
        ];

        return (
          <>
            <oh-chart
              chartTitle="Area Graph Test"
              series={series}
              xAxisLabel="Custom X Axis Label"
              yAxisLabel="Custom Y Axis Label"
            />
            <ConfirmationButtons
              question="Does the chart display an area graph, custom axis labels, and a tooltip when you hover your mouse?"
              testName="AreaGraph"
            />
            <oh-divider />
          </>
        );
      };

      const BarGraph = () => {
        const seriesData = [
          {
            barWidth: 2,
            numberOfPoints: 5,
            title: 'Test Bars 1',
            type: SeriesType.VerticalBar,
          },
          {
            barWidth: 1,
            numberOfPoints: 5,
            title: 'Test Bars 2',
            type: SeriesType.VerticalBar,
          },
        ];

        const [series, setSeries] = React.useState(generateSeries(seriesData));

        return (
          <>
            <oh-chart
              chartTitle="Bar Graph Test"
              series={series}
              xAxisLabel="Custom X Axis Label"
              yAxisLabel="Custom Y Axis Label"
            />
            <ConfirmationButtons
              question="Does the chart display a bar graph, custom axis labels, and a tooltip when you hover your mouse? Are the bars for Test Bars 1 wider than Test Bars 2?"
              testName="BarGraph"
            />
            <RegenerateButton setter={setSeries} seriesData={seriesData} />
            <oh-divider />
          </>
        );
      };

      const LineGraph = () => {
        const seriesData = [
          {
            numberOfPoints: 5,
            title: 'Test Lines 1',
            type: SeriesType.Line,
          },
          {
            numberOfPoints: 5,
            title: 'Test Lines 2',
            type: SeriesType.Line,
          },
        ];

        const [series, setSeries] = React.useState(generateSeries(seriesData));
        const [sortedSeries, setSortedSeries] = React.useState(series);

        React.useEffect(() => {
          setSortedSeries(
            series.map((unsortedSeries) => {
              const data = unsortedSeries.data.sort((a, b) => a.x - b.x);
              return {
                ...unsortedSeries,
                data,
              };
            }),
          );
        }, [series]);

        return (
          <>
            <oh-chart
              chartTitle="Line Graph Test"
              series={sortedSeries}
              xAxisLabel="Custom X Axis Label"
              yAxisLabel="Custom Y Axis Label"
            />
            <ConfirmationButtons
              question="Does the chart display a line graph, custom axis labels, and a tooltip when you hover your mouse?"
              testName="LineGraph"
            />
            <RegenerateButton setter={setSeries} seriesData={seriesData} />
            <oh-divider />
          </>
        );
      };

      const MarkGraph = () => {
        const seriesData = [
          {
            numberOfPoints: 5,
            title: 'Test Mark 1',
            type: SeriesType.Mark,
          },
          {
            numberOfPoints: 5,
            title: 'Test Mark 2',
            type: SeriesType.Mark,
          },
        ];

        const [series, setSeries] = React.useState(generateSeries(seriesData));

        return (
          <>
            <oh-chart
              chartTitle="Mark Graph Test"
              series={series}
              xAxisLabel="Custom X Axis Label"
              yAxisLabel="Custom Y Axis Label"
            />
            <ConfirmationButtons
              question="Does the chart display a mark graph, custom axis labels, and a tooltip when you hover your mouse?"
              testName="MarkGraph"
            />
            <RegenerateButton setter={setSeries} seriesData={seriesData} />
            <oh-divider />
          </>
        );
      };

      const FourSeries = () => {
        const seriesData: SeriesInput[] = [
          {
            numberOfPoints: 5,
            title: 'Area Graph',
            type: SeriesType.Area,
          },
          {
            numberOfPoints: 5,
            title: 'Bar Graph',
            type: SeriesType.VerticalBar,
          },
          {
            numberOfPoints: 5,
            title: 'Line Graph',
            type: SeriesType.Line,
          },
          {
            numberOfPoints: 5,
            title: 'Mark Graph',
            type: SeriesType.Mark,
          },
        ];

        const [series, setSeries] = React.useState(generateSeries(seriesData));

        return (
          <>
            <oh-chart
              chartTitle="Four Series Test"
              series={series}
              xAxisLabel="Custom X Axis Label"
              yAxisLabel="Custom Y Axis Label"
            />
            <ConfirmationButtons
              question="Does the chart display area, bar, line, and mark graphs?"
              testName="FourSeries"
            />
            <RegenerateButton setter={setSeries} seriesData={seriesData} />
            <oh-divider />
          </>
        );
      };

      const ChartTest = () => (
        <oh-whisper label="Chart Test" onClose={() => console.debug('closed')}>
          <AreaGraph />
          <BarGraph />
          <LineGraph />
          <MarkGraph />
          <FourSeries />
        </oh-whisper>
      );
      ReactWhisper.renderNewWhisper(<ChartTest />);
    } catch (e) {
      console.error(e);
      reject(e);
    }
  });

PreviousButtonNextCollapseBox

Last updated 3 years ago

Was this helpful?