Highcharts test tool
by oysteinmoseng
HTML
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="columnChart" class="container"></div>
<div id="scatterChart" class="container"></div>
<div id="lineChart" class="container"></div>
CSS
.container {
min-width: 300px;
max-width: 800px;
height: 300px;
margin: 1em auto;
}
JavaScript
// Plugin to visualize the chart using basic sonification
var each = Highcharts.each,
merge = Highcharts.merge,
audio = new (window.AudioContext || window.webkitAudioContext)();
Highcharts.Series.prototype.sonify = function (options, callback) {
var gainNode = audio.createGain(),
panNode = audio.createStereoPanner(), // Note: Panning might not be accessible to mono users
oscillator = audio.createOscillator(), // Initial oscillator. Updated or replaced depending on smooth setting
series = this,
numPoints = series.points.length,
valueToFreq = function (val) {
var valMin = options.rangeMin || series.dataMin,
valMax = options.rangeMax || series.dataMax,
freqStep = (options.maxFrequency - options.minFrequency) / (valMax - valMin);
return options.minFrequency + (val - valMin) * freqStep;
},
timePerPoint = Math.min(options.maxDuration / numPoints, options.maxPointDuration),
maxPointsNum = options.maxDuration / options.maxPointDuration,
pointSkip = 1;
// Skip over points if we have too many
// We might want to use data grouping here
if (timePerPoint < options.minPointDuration) {
pointSkip = numPoints / maxPointsNum;
}
// Init audio nodes
panNode.pan.value = 0; // TODO
gainNode.gain.value = options.volume;
oscillator.type = options.waveType;
oscillator.frequency.value = 0;
oscillator.connect(gainNode);
gainNode.connect(panNode);
panNode.connect(audio.destination);
if (options.smooth) {
oscillator.start(audio.currentTime);
for (var i = 0, point; i < numPoints; i += pointSkip) {
point = this.points[i];
oscillator.frequency.linearRampToValueAtTime(
valueToFreq(point.y),
audio.currentTime + i * timePerPoint / 1000
);
}
gainNode.gain.setTargetAtTime(0, audio.currentTime + i * timePerPoint / 1000, 0.1); // Fade
...