Config
When calling c2mChart
, there are several different config items that you can provide:
Required
Optional
Type
Required
Format:
- String:
bar
|band
|box
|candlestick
|histogram
|line
|matrix
|pie
|scatter
|treemap
|unsupported
- Array: any combination of the above
A "matrix" chart can work for heatmaps and correlation matrices.
Examples:
type: "line";
type: ["bar", "line"];
If your type
is an array, it must be a 1-to-1 with your data groups. If your array length doesn't match the number chart groups you have, you will receive an error.
For example, let's say you have a chart with 3 groups: A, B, and C. A and B are both line charts, and C is a bar chart. The type you would use is ["line", "line", "bar"]
.
For more information on the unsupported
chart type, see our "Unsupported groups of data" section.
Data
Required
Format:
- Array of numbers
- Array of object of type SupportedDataPoint
- Dictionary of array of numbers, with the dictionary key being the name of the category
- Dictionary of array of SupportedDataPoint, with the dictionary key being the name of the category
null
- used forunsupported
chart types
SupportedDataPoint comes in the following forms:
SimpleDataPoint
{
x: number;
y: number;
label?: string;
custom?: any;
children?: string;
}
AlternativeAxisDataPoint
{
x: number;
y2: number;
label?: string;
custom?: any;
children?: string;
}
HighLowDataPoint
{
x: number;
high: number;
low: number;
label?: string;
custom?: any;
children?: string;
}
OHLCDataPoint
{
x: number;
open: number;
high: number;
low: number;
close: number;
label?: string;
custom?: any;
children?: string;
}
BoxDataPoint
{
x: number;
low: number;
q1: number;
median: number;
q3: number;
high: number;
outlier?: number[];
label?: string;
custom?: any;
children?: string;
}
See Data for usage info
Element
Required
Format:
- An HTML or SVG Element
We recommend you provide one of the following common HTML elements:
- IMG
- CANVAS
- SVG
While you could provide something else, like <div>
element, you risk confusion with users, based on how screen readers read out different kinds of elements.
Do not use structural, or otherwise non-visual, tags. For example:
- HTML
- HEAD
- BODY
- SCRIPT
- LINK
- BR
These may provide a confusing user experience, prevent user interaction altogether, or just otherwise cause errors.
Axes
Optional
Format:
- An object with any of the following keys:
x
,y
, ory2
. The values must be of type AxisData.
AxisData
All AxisData properties are optional.
Property | Type | Description |
---|---|---|
minimum | number | The minimum value on the axis. This will automatically be calculated as the minimum of the data, but if you want to explicitly set a minimum that may be different from the data minimum, use this property. |
maximum | number | The maximum value on the axis. This will automatically be calculated as the maximum of the data, but if you want to explicitly set a maximum that may be different from the data maximum, use this property. |
label | string | The axis label, like "Month" or "Price" |
format | (value: number) => string | A formatting function for data point values |
valueLabels | string[] | The string values you want associated with particular number values. This value is ignored if format is provided. |
type | "linear" or "log10" | Is the axis linear or logarithmic? Default is linear. |
continuous | boolean | Should the chart use continuous mode? Only valid for the x-axis. See description of continuous mode Default is false. |
For example, if you provide a data point like this:
{
"x": 1,
"y": 123456
}
and you provide an axes value like this:
y: {
label: "Population",
format: (value) => {
return value.toLocaleString();
}
}
Your y-value will be described as 123,456
or 123.456
, depending on your locality. This will make the value much easier for a screen reader to verbalize.
Note that data point values are always numeric. If you use values on the X axis that are strings, you will need to provide the data points as numbers, and then use the valueLabels
property to provide their string equivalents.
Here's an example where the X-axis represents Month:
const months = ["January", "February", "March"];
c2mChart({
title: "Holidays",
type: "bar",
element: myElement,
data: [2, 3, 2], // Note that the x-values will be assigned as [0, 1, 2]
axes: {
x: {
label: "Month",
valueLabels: months
},
},
});
If your chart visual has labels for the axis, try to make your axis labels match.
Sometimes, axes don't have labels. Usually, this is because the data makes it obvious. If the X axis values are "January", "February", "March", etc, a chart author may skip adding the label "Month" to the visual because that's clear from context. Even in those cases, it's still best to provide the axis label "Month".
Title
Optional
Format:
- String
Example:
{
"title": "MSFT Stock Price"
}
- Synchronized. If possible, use the same title as your visual chart.
- Distinguishable. If you have multiple charts on the page, make sure they're easily distinguished. For example, having 3 copies of "Stock Chart" is unhelpful. Having "MSFT", "GOOG", and "IBM" helps distinguish the charts.
- Terse. If you don't need a word, don't use it. You don't need something like "Chart of Movie Ratings" when you can just say "Movie Ratings".
Lang
Optional
Format:
- String
Default: en
Example:
{
"lang": "es"
}
Currently supported languages:
en
(default)de
es
fr
it
CC
Optional
Format:
- An HTML element, ideally a
<div>
This is the "closed caption" element. When a user navigates around the chart, their screen reader will read custom text we provide it. The CC element is where the screen reader's script is going to be printed. This element is the magic of how everything works.
Why is it optional? Because we'll generate an element if you don't provide us one. However, if you provide us one, you can style it more effectively.
While developing and debugging, you may want to include this element in a central, visible location. This helps you make sure things like number formatting is going correctly. This is where the "closed caption" sentiment comes from - it can provide a sighted developer a closed caption of what the screen reader is saying.
You can have one CC element on a page, and point all of your charts that that single element.
For Firefox users, the CC element must be visible on the screen in order for the screen reader to know what to say. Reasons it may not be on screen include:
- The CC element was positioned off-screen to hide it from sighted users. (This tactic works for Chrome users, just not Firefox users.)
- The chart is at the bottom of the screen, and the CC element is beneath it, so it hasn't been scrolled into view.
AudioEngine
Optional
Format:
- Class implementation with the following public method:
playDataPoint(frequency: number, panning: number, duration: number): void
If you'd like to write your own sounds to match your branding or personal taste, this option will let you override sounds.
Also, if you want to write automated test cases for a page with charts, and your test system doesn't like chart2music's use of the WebAudioAPI, you can write an audio engine mockup for testing purposes.
Example testing mockup:
let lastDuration = 0;
let lastFrequency = 0;
let lastPanning = 0;
let playHistory = [];
/**
* Mock audio engine. Built for testing purposes.
*/
class MockAudioEngine {
constructor() {
lastDuration = -10;
lastFrequency = -10;
lastPanning = -10;
}
/**
* The instructions to play a data point. The details are being recorded for the test system.
*
* @param {number} frequency - hertz to play
* @param {number} panning - panning (-1 to 1) to play at
* @param {number} duration - how long to play
*/
playDataPoint(frequency, panning, duration) {
lastFrequency = frequency;
lastPanning = panning;
lastDuration = duration;
playHistory.push({ frequency, panning, duration });
}
}
c2mChart({
type: "line",
data: [1, 2, 3],
element: myElement,
audioEngine: new MockAudioEngine(),
});
// Write test cases where data points are played, then test the lastDuration,
// lastFrequency, and lastPanning variables to confirm the expected values were passed
Info
Optional
The info
property provides a space for you to give context, references, footnotes, or other pieces of information you expect the user to want to reference.
You can provide this in 2 ways: notes
and annotations
.
Notes
Optional
Format:
- Array of strings
Example:
{
type: "line",
title: "How Fast? How Furious?",
axes: {
y: {
label: "Movie ratings"
}
},
data: [6.8, 5.9, 6, 6.5, 7.3, 7, 7.1, 6.6, 5.2],
info: {
notes: [
"Got ratings from IMDB"
]
}
}
When you add notes, a few things will happen for the end-user:
- The chart's summary (what the user hears when they first get to the chart) will include the phrase "Has notes".
- When users press "i", they will be able to open the info dialog. This is not available if there are no notes.
- The info dialog will list the notes you provide. Be advised, no formatting is supported. All notes will be treated as plain text.
Annotations
Optional
Format:
- An array of objects with the following keys:
x
andlabel
. Both are required.
You can provide additional details about events that happened along the X-axis. Currently, annotations are only supported on the X-axis.
Property | Type | Description |
---|---|---|
x | number | Where the event happened |
label | string | A label for the event |
Example:
{
type: "line",
title: "How Fast? How Furious?",
data: [6.8, 5.9, 6, 6.5, 7.3, 7, 7.1, 6.6, 5.2],
info: {
notes: [
"Got ratings from IMDB"
],
annotations: [
{
x: 6, // The index for the 7th movie
label: "Paul Walker's last movie"
}
]
}
}
Options
When you call c2mChart
, you can provide several different options, all optional:
Option | Type | Default | Description |
---|---|---|---|
customHotkeys | array of HotkeyType | nothing | List of custom hotkeys. See Developer section |
enableSound | boolean | true | When true, sound is played. When false, sonification is muted. This does not impact if screen readers verbalize anything. |
enableSpeech | boolean | true | When true, screen readers are given text to read. When false, chart2music will not provide screen readers anything to say (though they may continue speaking based on other context on the page.) |
hertzes | number[] | an array of 88 hertz values for a standard A440-tuned piano | The array of hertz values you want to have available to play from. If you would prefer a different pitch standard, such as A415 or A466, you can use this option to provide the hertzes of your alternative tuning. |
live | boolean | false | When true, the user is told that it is a live chart. It is expected that streaming data will be added to the chart using the appendData method. |
maxWidth | number | nothing | Only relevant for live charts. This indicates the maximum number of data points to be displayed on a chart. For example, if you're streaming to a live chart once every second, you may want to cap the number of data points at 100. Otherwise, the chart will become too unwieldy. |
onFocusCallback | function | nothing | Provides a callback as a user is navigating a chart. (This is the equivalent of a mouse user hovering over a data point.) Use this if you'd like to keep your visuals synchronized with the user. This is especially helpful for low vision users or blind users who collaborate with sighted users. |
onSelectCallback | function | nothing | Provides a callback as a user presses enter while navigating a chart. (This is the equivalent of a mouse user clicking on a data point.) Use this if you've implemented brushing or other data visualization interactions. |
root | string | nothing | Which group should be used as the root in a hierarchy. When assigned, the chart is considered to be hierarchical, and only active levels will be displayed. |
stack | boolean | false | Should all the groups be treated as a stack? When true , this will generate an additional group, "All", that sums all of the other groups. Only SimpleDataPoint-type points will be stacked. |
translationCallback | function | () => false | Intercepts translations, so that the developer can provide their own custom translations. Proceed with extreme caution. |
HotkeyType
Option | Type | Required? | Description |
---|---|---|---|
key | {key: string; altKey?: boolean; shiftKey?: boolean; ctrlKey?: boolean; metaKey?: boolean} | Required | The relevant KeyboardEvent details for the hotkey you want to register. |
callback | function | Required | The function called when the user activates the hotkey |
title | string | Required | The name for your hotkey (like, "Drill down" or "Zoom in"). This will appear in the Help dialog. |
description | string | optional | Additional descriptive information to go with the title. This will appear in the Help Dialog. |
keyDescription | string | optional | An alternative description of the hotkey, if you don't like the automated description. For example, you could provide "Alt + Spacebar" instead of the auto-generated "Alt+ ". |
force | boolean | optional | Default: false . If you are overwriting an existing hotkey, you must set force: true to force the overwrite. |
caseSensitive | boolean | optional | Default: true . If the hotkey should be case sensitive. |