Links

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.
Javascript
React
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);
}
});