Musical chart
const masterVolume = 0.85; // ------------------------------------------------------------------------ // Controls // Mute/unmute an instrument without stopping play function setInstrumentMute(targetSeriesIx, channels, mute) { channels.forEach(function (ch) { if (ch.events[0].relatedPoint.series.index === targetSeriesIx) { ch.engine.setMasterVolume(mute ? 0 : masterVolume); } }); } // Called on chart render function onRender() { const chart = this; // Chart play button document.getElementById('play').onclick = function () { chart.toggleSonify(true, function () { // Reset crosshair on end since we are animating it chart.series[0].xAxis.drawCrosshair( void 0, chart.series[0].points[0] ); chart.series[0].xAxis.hideCrosshair(); }); }; // Handle checkbox clicks for each instrument [ 'bass-on', 'chimes-on', 'shaker1-on', 'piano-on', 'flute-on', 'synth-on', 'shaker2-on', 'pad-on', 'basspad-on' ].forEach(function (id, seriesIx) { const series = chart.series[seriesIx]; document.getElementById(id).onclick = function () { const timeline = chart.sonification.timeline, muted = !this.checked; if (timeline) { if ( series.options.sonification && series.options.sonification.enabled === false && !muted ) { // Series was muted before timeline was made, have to do // update & rebuild series.update({ sonification: { enabled: true } }); } setInstrumentMute(seriesIx, timeline.channels, muted); } else { // Timeline not built yet - user interaction needed on page series.update({ sonification: { enabled: !muted } }, false); } series.setState(muted ? 'inactive' : 'normal'); }; }); // Set plot border radius chart.plotBackground.attr('r', '9px'); // Expose y axis titles to screen readers directly chart.yAxis.forEach(function (a) { a.axisGroup.div.setAttribute('aria-hidden', 'false'); }); } // ------------------------------------------------------------------------ // Chart Highcharts.SVGRenderer.prototype.symbols.box = function (x, y, w, h) { const x2 = w * 2; return ['M', x, y, 'L', x + x2, y, 'L', x + x2, y + h, 'L', x, y + h, 'z']; }; // Allow input tags in axis labels Highcharts.AST.allowedTags.push('input'); Highcharts.AST.allowedTags.push('label'); Highcharts.AST.allowedAttributes.push('checked'); // Convenience function to get y axis options, since we have 9 of them function buildYAxisOpts(height, top, labelText, checkboxId, iconSrc) { return { height: height + '%', // Axis height top: top + '%', // Axis offset from top offset: 0, labels: { enabled: false }, accessibility: { description: labelText }, gridLineWidth: 0, title: { rotation: 0, offset: 70, useHTML: true, style: { width: 120 }, // Checkbox, icon and axis title combined here text: '<label class="hc-axis-title"><input id="' + checkboxId + '" type="checkbox" checked><img alt="" src="' + iconSrc + '" class="hc-axis-icon"> <span ' + 'class="hc-axis-title-text">' + labelText + '</span></label>' } }; } Highcharts.chart('container', { chart: { type: 'scatter', marginLeft: 150, marginBottom: 25, events: { render: onRender }, plotBackgroundColor: '#F7F7F8', plotShadow: { color: '#aaa', opacity: 0.1, width: 10 }, scrollablePlotArea: { minWidth: 700, opacity: 0.94 } }, title: { text: 'Musical Chart', align: 'left', margin: 25, style: { fontSize: '1.4rem' } }, subtitle: { text: 'Using the built-in Highcharts Synthesizer', align: 'left' }, sonification: { duration: 14400, order: 'simultaneous', showTooltip: false, masterVolume: masterVolume, defaultInstrumentOptions: { // Only show for one track since we have some delayed tracks showPlayMarker: false } }, accessibility: { keyboardNavigation: { enabled: false }, screenReaderSection: { beforeChartFormat: '<{headingTagName}>' + '{chartTitle}</{headingTagName}><div>{typeDescription}</div>' + '<div>{chartSubtitle}</div><div>{chartLongdesc}</div><div>' + '{xAxisDescription}</div><div>{yAxisDescription}</div>' }, landmarkVerbosity: 'one' }, lang: { accessibility: { axis: { xAxisDescriptionSingular: 'The chart has 1 X axis displaying ' + 'time.' } } }, data: { csv: document.getElementById('csv').textContent, complete: function (opts) { delete opts.xAxis; // Assign each series to their own y-axes opts.series.forEach(function (s, ix) { s.yAxis = ix; }); } }, legend: { enabled: false }, tooltip: { enabled: false }, xAxis: { crosshair: { enabled: true, width: 10, color: '#609A5E', className: 'hc-crosshair' // Smoothed with CSS transitions }, visible: false, minPadding: 0.02 }, // Each series gets its own y axis yAxis: [ buildYAxisOpts( 9, 1, 'Bass', 'bass-on', 'https://upload.wikimedia.org/wikipedia/commons/3/37/Papapishu-double-bass-1.svg' ), buildYAxisOpts( 9, 11, 'Chimes', 'chimes-on', 'https://upload.wikimedia.org/wikipedia/commons/e/ee/Bell_by_hatalar205.svg' ), buildYAxisOpts( 5, 21, 'Shaker 1', 'shaker1-on', 'https://upload.wikimedia.org/wikipedia/commons/a/a1/Maracas.svg' ), buildYAxisOpts( 9, 27, 'Piano', 'piano-on', 'https://upload.wikimedia.org/wikipedia/commons/5/50/Piano.svg' ), Highcharts.merge( buildYAxisOpts( 26, 37, 'Flute', 'flute-on', 'https://upload.wikimedia.org/wikipedia/commons/c/ce/Quena.svg' ), { plotBands: [{ from: -10, to: 20, color: '#404543' }], min: -1, max: 13 } ), buildYAxisOpts( 9, 64, 'Synth', 'synth-on', 'https://upload.wikimedia.org/wikipedia/commons/9/99/Nuvola_apps_kcmmidi.svg' ), buildYAxisOpts( 5, 74, 'Shaker 2', 'shaker2-on', 'https://upload.wikimedia.org/wikipedia/commons/a/a1/Maracas.svg' ), buildYAxisOpts( 9, 80, 'Pad', 'pad-on', 'https://upload.wikimedia.org/wikipedia/commons/9/99/Nuvola_apps_kcmmidi.svg' ), buildYAxisOpts( 9, 90, 'Bass Pad', 'basspad-on', 'https://upload.wikimedia.org/wikipedia/commons/9/99/Nuvola_apps_kcmmidi.svg' ) ], plotOptions: { series: { enableMouseTracking: false, accessibility: { exposeAsGroupOnly: true } } }, // Sonification mappings for each series // ---------------------------------------------------------------------- series: [{ // Bass sonification: { defaultInstrumentOptions: { instrument: 'vibraphone', mapping: { pitch: { mapTo: 'y', min: 'd2', max: 'd3' }, pan: 0, volume: 0.4 } } }, color: 'transparent', marker: { symbol: 'circle', radius: 5, lineColor: '#505F55', lineWidth: 3 } }, { // Chimes sonification: { defaultInstrumentOptions: { instrument: 'vibraphone', mapping: { pitch: { mapTo: 'y', min: 'd5', max: 'g6' }, volume: 0.08, pan: 0.95 } }, tracks: [{ // Default }, { mapping: { pitch: { min: 'd6', max: 'g7' }, volume: 0.06, playDelay: 11 } }] }, colorByPoint: true, colors: ['#c0f090', '#b0c0f0', '#f0c090', '#f0f070'], marker: { symbol: 'diamond', radius: 4, lineColor: '#608060', lineWidth: 2 } }, { // Shaker 1 sonification: { defaultInstrumentOptions: { instrument: 'shaker', mapping: { volume: 0.25, pan: -1 } }, tracks: [{ // Default }, { instrument: 'kick', mapping: { pan: 0, volume: 0.2, pitch: { // Map to Y, but always map to the same pitch, // so we play only when there is a Y value min: 'd5', max: 'd5' } }, activeWhen: { prop: 'x', min: 24 } }] }, color: '#204020', marker: { symbol: 'box', radius: 2 } }, { // Piano sonification: { defaultInstrumentOptions: { instrument: 'piano', mapping: { pitch: { mapTo: 'y', min: 'd3', max: 'e4' }, highpass: { frequency: 300 }, lowpass: { frequency: 6000, resonance: 9 }, pan: -1, volume: 0.12 } }, tracks: [{ // We use this track for play marker since it plays constantly showPlayMarker: true }, { // Delay mapping: { volume: 0.05, playDelay: 169 } }, { // Plucked double comes in eventually instrument: 'plucked', mapping: { volume: 0.12, lowpass: { frequency: 6000 }, pan: 1, playDelay: -4 }, // This track comes in when x = 24 activeWhen: { prop: 'x', min: 24 } }, { // Delay for plucked instrument: 'plucked', mapping: { lowpass: { frequency: 4000 }, highpass: { frequency: 300 }, volume: 0.07, pan: 1, playDelay: 338 }, activeWhen: { prop: 'x', min: 24 } }] }, type: 'spline', color: '#42b862', marker: { symbol: 'circle', radius: 3, lineColor: '#408050', lineWidth: 2 } }, { // Flute sonification: { defaultInstrumentOptions: { instrument: 'flute', mapping: { pitch: { mapTo: 'y', min: 'd5', max: 'd6' }, pan: 0, noteDuration: 280, volume: 0.6, playDelay: -2 } }, tracks: [{ // Default }, { // Delay 1 mapping: { volume: 0.2, playDelay: 169, pan: -0.3, highpass: { frequency: 300 } } }, { // Delay 2 mapping: { volume: 0.12, playDelay: 338, pan: 0.3, highpass: { frequency: 600 }, lowpass: { frequency: 7000 } } }, { // Delay 3 mapping: { volume: 0.05, playDelay: 676, pan: -0.3, highpass: { frequency: 800 }, lowpass: { frequency: 4000 } } }] }, type: 'spline', dashStyle: 'Solid', color: '#EAFFEA', lineWidth: 3, shadow: { color: '#cfe', offsetY: 5, width: 5 }, marker: { enabled: false } }, { // Synth sonification: { defaultInstrumentOptions: { instrument: 'sawsynth', mapping: { pitch: { mapTo: 'y', min: 'd4', max: 'e5' }, lowpass: { frequency: 8000 }, highpass: { frequency: 800 }, pan: { mapTo: 'y', within: 'series', min: -1, max: 1 }, volume: { mapTo: 'y', within: 'series', min: 0.05, max: 0.15 }, playDelay: 4 } }, tracks: [{ // Default }, { // Negative delay mapping: { playDelay: -338, volume: 0.09, pan: -1, pitch: { min: 'd5', max: 'e6' } } }, { // Delay mapping: { playDelay: 169, volume: 0.07, pan: -0.5, pitch: { min: 'd5', max: 'e6' } } }] }, type: 'spline', color: '#42b862', marker: { symbol: 'circle', radius: 3, lineColor: '#408050', lineWidth: 2 } }, { // Shaker 2 sonification: { tracks: [{ instrument: 'chop', mapping: { volume: 0.35, pan: 1 } }, { instrument: 'shaker', mapping: { volume: 0.05, pan: -1 } }] }, color: '#204020', marker: { symbol: 'box', radius: 2 } }, { // Pad sonification: { defaultInstrumentOptions: { instrument: 'triangle', mapping: { pitch: { mapTo: 'y', min: 'd3', max: 'd4' }, noteDuration: 1350, lowpass: { frequency: 1000 }, pan: { mapTo: 'y', within: 'series', min: 0, max: 1 }, volume: { mapTo: 'y', within: 'series', min: 0.04, max: 0.1 } } }, tracks: [{ // Default }, { mapping: { pitch: { min: 'd2', max: 'd3' }, playDelay: 6, pan: -1 } }, { mapping: { pitch: { min: 'd4', max: 'd5' }, playDelay: 9 } }] }, type: 'spline', connectNulls: true, color: '#42b862', marker: { symbol: 'circle', radius: 3, lineColor: '#408050', lineWidth: 2 } }, { // Bass pad sonification: { defaultInstrumentOptions: { instrument: 'triangle', mapping: { pitch: { mapTo: 'y', min: 'd1', max: 'd2' }, volume: 0.16, noteDuration: 1300, lowpass: { frequency: 500 }, tremolo: { speed: 0.23, depth: 0.1 }, pan: 0, playDelay: 15 } } }, type: 'spline', connectNulls: true, color: '#327862', marker: { symbol: 'square', radius: 4, lineColor: '#408050', lineWidth: 2 } }] });
CoreAudio charts
Install with NPM
The official Highcharts NPM package comes with support for CommonJS and contains Highcharts, and its Stock, Maps and Gantt packages.
npm install highcharts --save
See more installation optionsDownload our library
The zip archive contains Javascript files and examples. Unzip the zip package and open index.html in your browser to see the examples.
DownloadBuy a license
You can download and try out all Highcharts products for free. Once your project/product is ready for launch, purchase a commercial license.
See License Pricing