Documentation Index Fetch the complete documentation index at: https://mintlify.com/highcharts/highcharts/llms.txt
Use this file to discover all available pages before exploring further.
Audio Representation (Sonification)
Sonification transforms chart data into audio, making data accessible to users with visual impairments and providing an alternative way to explore data patterns through sound.
Overview
The Sonification module (from ts/Extensions/Sonification/Sonification.ts:94-109) enables you to:
Convert data points to musical notes
Map data values to audio parameters (pitch, volume, duration)
Create audio earcons (notification sounds)
Navigate charts using audio cues
Make data accessible through sound
Setup
The sonification module is included in the accessibility module:
import Highcharts from 'highcharts' ;
import Accessibility from 'highcharts/modules/accessibility' ;
Accessibility ( Highcharts );
Highcharts . chart ( 'container' , {
accessibility: {
enabled: true
},
sonification: {
enabled: true
},
// Chart configuration
});
Basic Sonification
Enable Sonification
Highcharts . chart ( 'container' , {
sonification: {
enabled: true ,
duration: 5000 , // Play for 5 seconds
defaultInstrumentOptions: {
instrument: 'piano' ,
minPitch: 'c3' ,
maxPitch: 'c6'
}
},
series: [{
data: [ 1 , 2 , 4 , 5 , 7 , 9 , 11 , 13 ]
}]
});
Play Chart as Audio
From the Sonification API (ts/Extensions/Sonification/Sonification.ts:63-90):
// Get chart instance
const chart = Highcharts . chart ( 'container' , { /* config */ });
// Play the entire chart
chart . sonify ();
// Play with callback when finished
chart . sonify ( function () {
console . log ( 'Sonification complete' );
});
// Toggle play/pause
chart . toggleSonify ();
// Cancel playback
chart . sonification . cancel ();
Play Individual Series
// Sonify a specific series
chart . series [ 0 ]. sonify ();
// With callback
chart . series [ 0 ]. sonify ( function () {
console . log ( 'Series sonification complete' );
});
Audio Mapping
Pitch Mapping
Map data values to musical pitches:
{
sonification : {
defaultInstrumentOptions : {
mapping : {
pitch : {
min : 'c3' , // Lowest note
max : 'c6' , // Highest note
// Map to y-value by default
mapTo : 'y' ,
// Or use custom mapping function
mapFunction : 'linear' // or 'logarithmic'
}
}
}
}
}
Volume Mapping
{
sonification : {
defaultInstrumentOptions : {
mapping : {
volume : {
min : 0.2 , // Quietest
max : 1.0 , // Loudest
mapTo : 'y'
}
}
}
}
}
Duration and Timing
{
sonification : {
duration : 8000 , // Total duration in milliseconds
pointGrouping : {
enabled : true ,
groupTimespan : 100 , // Group points within 100ms
algorithm : 'minmax' // or 'first', 'last', 'average'
},
defaultInstrumentOptions : {
mapping : {
noteDuration : 200 , // Each note plays for 200ms
gapBetweenNotes : 50 // 50ms gap between notes
}
}
}
}
Instruments and Sounds
Available Instruments
Highcharts includes several preset instruments:
Piano
Flute
Vibraphone
Saxophone
{
sonification : {
defaultInstrumentOptions : {
instrument : 'piano'
}
}
}
Custom Instruments
Define custom synthesizer patches:
{
sonification : {
defaultInstrumentOptions : {
instrument : {
oscillators : [{
type: 'sine' ,
frequency: 1
}],
envelope : {
attack : 0.01 ,
decay : 0.1 ,
sustain : 0.3 ,
release : 0.3
}
}
}
}
}
Advanced Features
Earcons (Audio Notifications)
From the earcon demo (samples/highcharts/sonification/chart-earcon/demo.js:11-42):
Highcharts . chart ( 'container' , {
sonification: {
duration: 11000 ,
afterSeriesWait: 1100 ,
events: {
onEnd : function () {
console . log ( 'Sonification ended' );
}
},
// Global track that plays for specific conditions
globalTracks: [{
type: 'instrument' ,
instrument: 'vibraphone' ,
showPlayMarker: false ,
mapping: {
pitch: [ 'g6' , 'g6' ],
playDelay: 60 ,
gapBetweenNotes: 100
},
// Only play when this condition is true
activeWhen : function ( context ) {
const point = context . point ;
const series = point . series ;
// Play earcon when point is the max in series
return point . y === Math . max . apply ( Math ,
series . points . map ( p => p . y )
);
}
}]
},
series: [{
data: [ 1 , 2 , 4 , 5 , 7 , 9 , 11 , 13 ]
}, {
data: [ 4 , 5 , 9 , 5 , 2 , 1 , 4 , 6 ]
}]
});
Multiple Tracks
Create multiple simultaneous audio tracks:
{
sonification : {
globalTracks : [
{
// Melody track
type: 'instrument' ,
instrument: 'piano' ,
mapping: {
pitch: {
mapTo: 'y' ,
min: 'c4' ,
max: 'c6'
},
volume: 0.8
}
},
{
// Bass track
type: 'instrument' ,
instrument: 'bass' ,
mapping: {
pitch: {
mapTo: 'y' ,
min: 'c2' ,
max: 'c4'
},
volume: 0.6
}
},
{
// Speech track
type: 'speech' ,
mapping: {
text: '{point.name}: {point.y}' ,
rate: 1.2 ,
volume: 0.7
}
}
]
}
}
Context Track Mapping
Map audio parameters based on context:
{
sonification : {
defaultInstrumentOptions : {
mapping : {
pitch : function ( context ) {
// Access point data
const value = context . point . y ;
const min = context . point . series . yAxis . min ;
const max = context . point . series . yAxis . max ;
// Custom pitch calculation
const range = max - min ;
const normalized = ( value - min ) / range ;
const semitones = normalized * 24 ; // 2 octave range
return 'c4+' + semitones ;
},
volume : function ( context ) {
// Vary volume based on x-position
const xPercent = context . point . plotX / context . chart . plotWidth ;
return 0.4 + ( xPercent * 0.6 );
}
}
}
}
}
Sonification Events (from ts/Extensions/Sonification/Sonification.ts:14-21)
{
sonification : {
events : {
onSeriesStart : function ( e ) {
console . log ( 'Starting series:' , e . series . name );
},
onSeriesEnd : function ( e ) {
console . log ( 'Finished series:' , e . series . name );
},
onPointStart : function ( e ) {
console . log ( 'Playing point:' , e . point . category , e . point . y );
},
onPointEnd : function ( e ) {
console . log ( 'Finished point:' , e . point . category );
},
onEnd : function () {
console . log ( 'Sonification complete' );
// Re-enable play button
document . getElementById ( 'play-btn' ). disabled = false ;
}
}
}
}
Interactive Controls
Create playback controls for users:
< button id = "play" > Play </ button >
< button id = "pause" > Pause </ button >
< button id = "stop" > Stop </ button >
< input type = "range" id = "speed" min = "0.5" max = "2" step = "0.1" value = "1" >
const chart = Highcharts . chart ( 'container' , { /* config */ });
// Play button
document . getElementById ( 'play' ). onclick = function () {
chart . sonify ();
};
// Pause/Resume button
document . getElementById ( 'pause' ). onclick = function () {
chart . toggleSonify ();
};
// Stop button
document . getElementById ( 'stop' ). onclick = function () {
chart . sonification . cancel ();
};
// Speed control
document . getElementById ( 'speed' ). oninput = function ( e ) {
const speed = parseFloat ( e . target . value );
chart . update ({
sonification: {
duration: 5000 / speed
}
});
};
Scrubbing Navigation
Allow users to scrub through the chart (from ts/Extensions/Sonification/Sonification.ts:183-200):
// Play a specific segment (0-100)
chart . sonification . playSegment ( 50 ); // Play middle segment
// Scrubbing with slider
document . getElementById ( 'scrubber' ). oninput = function ( e ) {
const segment = parseInt ( e . target . value );
chart . sonification . playSegment ( segment );
};
Accessibility Integration
Combine sonification with accessibility features:
{
accessibility : {
enabled : true ,
keyboardNavigation : {
enabled : true
},
screenReaderSection : {
beforeChartFormat : '<div>Use arrow keys to navigate. ' +
'Press P to play sonification.</div>'
}
},
sonification : {
enabled : true ,
showCrosshair : true , // Show position during playback
showTooltip : true // Show tooltip during playback
}
}
// Add keyboard shortcut
document . addEventListener ( 'keydown' , function ( e ) {
if ( e . key === 'p' || e . key === 'P' ) {
chart . toggleSonify ();
}
});
Best Practices
Sonification Design Tips
Use appropriate pitch ranges (avoid extremes)
Keep duration reasonable (5-15 seconds for most charts)
Provide play/pause controls
Show visual feedback during playback
Use earcons sparingly for important events
Test with headphones and speakers
Consider users with hearing impairments
Provide alternative text descriptions
Use familiar instruments for better understanding
Important Considerations
Browser audio support varies (test across browsers)
Audio may not autoplay due to browser policies
Requires user interaction to start in most browsers
Can be CPU intensive for large datasets
May not work properly in all screen readers
Consider providing mute option
Loud or jarring sounds can be startling
Complete Example
const chart = Highcharts . chart ( 'container' , {
chart: {
type: 'spline'
},
title: {
text: 'Temperature Trends with Sonification'
},
subtitle: {
text: 'Click Play to hear the data'
},
accessibility: {
enabled: true ,
landmarkVerbosity: 'one' ,
description: 'Temperature chart with audio representation'
},
sonification: {
enabled: true ,
duration: 8000 ,
afterSeriesWait: 500 ,
// Show visual feedback
showCrosshair: true ,
showTooltip: true ,
// Events
events: {
onPointStart : function ( e ) {
console . log ( 'Temperature:' , e . point . y + '°C' );
},
onEnd : function () {
document . getElementById ( 'play-btn' ). textContent = 'Play Again' ;
}
},
// Default instrument settings
defaultInstrumentOptions: {
instrument: 'piano' ,
mapping: {
pitch: {
mapTo: 'y' ,
min: 'c3' ,
max: 'c6'
},
volume: {
mapTo: 'y' ,
min: 0.4 ,
max: 0.9
},
noteDuration: 200 ,
gapBetweenNotes: 50
}
},
// Earcon for maximum temperature
globalTracks: [{
type: 'instrument' ,
instrument: 'vibraphone' ,
showPlayMarker: false ,
mapping: {
pitch: [ 'g6' , 'g6' ],
playDelay: 80 ,
gapBetweenNotes: 100
},
activeWhen : function ( context ) {
const point = context . point ;
const series = point . series ;
return point . y === Math . max . apply ( Math ,
series . points . map ( p => p . y )
);
}
}]
},
series: [{
name: 'Temperature' ,
data: [ 15 , 18 , 22 , 25 , 28 , 32 , 30 , 27 , 23 , 19 , 16 , 14 ]
}]
});
// Control buttons
document . getElementById ( 'play-btn' ). onclick = function () {
chart . sonify ();
this . textContent = 'Playing...' ;
};
document . getElementById ( 'stop-btn' ). onclick = function () {
chart . sonification . cancel ();
document . getElementById ( 'play-btn' ). textContent = 'Play' ;
};