1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370 |
- 'use strict';
- (function (factory) {
- if (typeof module === 'object' && module.exports) {
- factory['default'] = factory;
- module.exports = factory;
- } else if (typeof define === 'function' && define.amd) {
- define('highcharts/modules/sonification', ['highcharts'], function (Highcharts) {
- factory(Highcharts);
- factory.Highcharts = Highcharts;
- return factory;
- });
- } else {
- factory(typeof Highcharts !== 'undefined' ? Highcharts : undefined);
- }
- }(function (Highcharts) {
- var _modules = Highcharts ? Highcharts._modules : {};
- function _registerModule(obj, path, args, fn) {
- if (!obj.hasOwnProperty(path)) {
- obj[path] = fn.apply(null, args);
- }
- }
- _registerModule(_modules, 'Extensions/Sonification/Instrument.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
-
- var error = U.error,
- merge = U.merge,
- pick = U.pick,
- uniqueKey = U.uniqueKey;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- var defaultOptions = {
- type: 'oscillator',
- playCallbackInterval: 20,
- masterVolume: 1,
- oscillator: {
- waveformShape: 'sine'
- }
- };
-
-
- function Instrument(options) {
- this.init(options);
- }
- Instrument.prototype.init = function (options) {
- if (!this.initAudioContext()) {
- error(29);
- return;
- }
- this.options = merge(defaultOptions, options);
- this.id = this.options.id = options && options.id || uniqueKey();
- this.masterVolume = this.options.masterVolume || 0;
-
- var ctx = H.audioContext;
-
-
-
-
- var destination = this.destinationNode || ctx.destination;
- this.gainNode = ctx.createGain();
- this.setGain(0);
- this.panNode = ctx.createStereoPanner && ctx.createStereoPanner();
- if (this.panNode) {
- this.setPan(0);
- this.gainNode.connect(this.panNode);
- this.panNode.connect(destination);
- }
- else {
- this.gainNode.connect(destination);
- }
-
- if (this.options.type === 'oscillator') {
- this.initOscillator(this.options.oscillator);
- }
-
- this.playCallbackTimers = [];
- };
-
- Instrument.prototype.copy = function (options) {
- return new Instrument(merge(this.options, { id: null }, options));
- };
-
- Instrument.prototype.initAudioContext = function () {
- var Context = H.win.AudioContext || H.win.webkitAudioContext,
- hasOldContext = !!H.audioContext;
- if (Context) {
- H.audioContext = H.audioContext || new Context();
- if (!hasOldContext &&
- H.audioContext &&
- H.audioContext.state === 'running') {
- H.audioContext.suspend();
- }
- return !!(H.audioContext &&
- H.audioContext.createOscillator &&
- H.audioContext.createGain);
- }
- return false;
- };
-
- Instrument.prototype.initOscillator = function (options) {
- var ctx = H.audioContext;
- this.oscillator = ctx.createOscillator();
- this.oscillator.type = options.waveformShape;
- this.oscillator.connect(this.gainNode);
- this.oscillatorStarted = false;
- };
-
- Instrument.prototype.setPan = function (panValue) {
- if (this.panNode) {
- this.panNode.pan.setValueAtTime(panValue, H.audioContext.currentTime);
- }
- };
-
- Instrument.prototype.setGain = function (gainValue, rampTime) {
- var gainNode = this.gainNode;
- var newVal = gainValue * this.masterVolume;
- if (gainNode) {
- if (newVal > 1.2) {
- console.warn(
- 'Highcharts sonification warning: ' +
- 'Volume of instrument set too high.');
- newVal = 1.2;
- }
- if (rampTime) {
- gainNode.gain.setValueAtTime(gainNode.gain.value, H.audioContext.currentTime);
- gainNode.gain.linearRampToValueAtTime(newVal, H.audioContext.currentTime + rampTime / 1000);
- }
- else {
- gainNode.gain.setValueAtTime(newVal, H.audioContext.currentTime);
- }
- }
- };
-
- Instrument.prototype.cancelGainRamp = function () {
- if (this.gainNode) {
- this.gainNode.gain.cancelScheduledValues(0);
- }
- };
-
- Instrument.prototype.setMasterVolume = function (volumeMultiplier) {
- this.masterVolume = volumeMultiplier || 0;
- };
-
- Instrument.prototype.getValidFrequency = function (frequency, min, max) {
- var validFrequencies = this.options.allowedFrequencies,
- maximum = pick(max,
- Infinity),
- minimum = pick(min, -Infinity);
- return !validFrequencies || !validFrequencies.length ?
-
- frequency :
-
- validFrequencies.reduce(function (acc, cur) {
-
- return Math.abs(cur - frequency) < Math.abs(acc - frequency) &&
- cur < maximum && cur > minimum ?
- cur : acc;
- }, Infinity);
- };
-
- Instrument.prototype.clearPlayCallbackTimers = function () {
- this.playCallbackTimers.forEach(function (timer) {
- clearInterval(timer);
- });
- this.playCallbackTimers = [];
- };
-
- Instrument.prototype.setFrequency = function (frequency, frequencyLimits) {
- var limits = frequencyLimits || {},
- validFrequency = this.getValidFrequency(frequency,
- limits.min,
- limits.max);
- if (this.options.type === 'oscillator') {
- this.oscillatorPlay(validFrequency);
- }
- };
-
- Instrument.prototype.oscillatorPlay = function (frequency) {
- if (!this.oscillatorStarted) {
- this.oscillator.start();
- this.oscillatorStarted = true;
- }
- this.oscillator.frequency.setValueAtTime(frequency, H.audioContext.currentTime);
- };
-
- Instrument.prototype.preparePlay = function () {
- this.setGain(0.001);
- if (H.audioContext.state === 'suspended') {
- H.audioContext.resume();
- }
- if (this.oscillator && !this.oscillatorStarted) {
- this.oscillator.start();
- this.oscillatorStarted = true;
- }
- };
-
- Instrument.prototype.play = function (options) {
- var instrument = this,
- duration = options.duration || 0,
-
-
-
- setOrStartTimer = function (value,
- setter,
- setterData) {
- var target = options.duration,
- currentDurationIx = 0,
- callbackInterval = instrument.options.playCallbackInterval;
- if (typeof value === 'function') {
- var timer_1 = setInterval(function () {
- currentDurationIx++;
- var curTime = (currentDurationIx * callbackInterval / target);
- if (curTime >= 1) {
- instrument[setter](value(1), setterData);
- clearInterval(timer_1);
- }
- else {
- instrument[setter](value(curTime), setterData);
- }
- }, callbackInterval);
- instrument.playCallbackTimers.push(timer_1);
- }
- else {
- instrument[setter](value, setterData);
- }
- };
- if (!instrument.id) {
-
- return;
- }
-
- if (H.audioContext.state === 'suspended' ||
- this.oscillator && !this.oscillatorStarted) {
- instrument.preparePlay();
-
- setTimeout(function () {
- instrument.play(options);
- }, 10);
- return;
- }
-
- if (instrument.playCallbackTimers.length) {
- instrument.clearPlayCallbackTimers();
- }
-
- instrument.cancelGainRamp();
-
- if (instrument.stopOscillatorTimeout) {
- clearTimeout(instrument.stopOscillatorTimeout);
- delete instrument.stopOscillatorTimeout;
- }
-
-
- if (instrument.stopTimeout) {
- clearTimeout(instrument.stopTimeout);
- delete instrument.stopTimeout;
- if (instrument.stopCallback) {
-
-
-
-
- instrument._play = instrument.play;
- instrument.play = function () { };
- instrument.stopCallback('cancelled');
- instrument.play = instrument._play;
- }
- }
-
-
- var immediate = duration < H.sonification.fadeOutDuration + 20;
-
- instrument.stopCallback = options.onEnd;
- var onStop = function () {
- delete instrument.stopTimeout;
- instrument.stop(immediate);
- };
- if (duration) {
- instrument.stopTimeout = setTimeout(onStop, immediate ? duration :
- duration - H.sonification.fadeOutDuration);
-
- setOrStartTimer(options.frequency, 'setFrequency', {
- minFrequency: options.minFrequency,
- maxFrequency: options.maxFrequency
- });
-
- setOrStartTimer(pick(options.volume, 1), 'setGain', 4);
- setOrStartTimer(pick(options.pan, 0), 'setPan');
- }
- else {
-
- onStop();
- }
- };
-
- Instrument.prototype.mute = function () {
- this.setGain(0.0001, H.sonification.fadeOutDuration * 0.8);
- };
-
- Instrument.prototype.stop = function (immediately, onStopped, callbackData) {
- var instr = this,
- reset = function () {
-
- if (instr.stopOscillatorTimeout) {
- delete instr.stopOscillatorTimeout;
- }
-
-
- try {
- instr.oscillator.stop();
- }
- catch (e) {
-
- }
- instr.oscillator.disconnect(instr.gainNode);
-
- instr.initOscillator(instr.options.oscillator);
-
- if (onStopped) {
- onStopped(callbackData);
- }
-
- if (instr.stopCallback) {
- instr.stopCallback(callbackData);
- }
- };
-
- if (instr.playCallbackTimers.length) {
- instr.clearPlayCallbackTimers();
- }
- if (instr.stopTimeout) {
- clearTimeout(instr.stopTimeout);
- }
- if (immediately) {
- instr.setGain(0);
- reset();
- }
- else {
- instr.mute();
-
- instr.stopOscillatorTimeout =
- setTimeout(reset, H.sonification.fadeOutDuration + 100);
- }
- };
- return Instrument;
- });
- _registerModule(_modules, 'Extensions/Sonification/MusicalFrequencies.js', [], function () {
-
- var frequencies = [
- 16.351597831287414,
- 17.323914436054505,
- 18.354047994837977,
- 19.445436482630058,
- 20.601722307054366,
- 21.826764464562746,
- 23.12465141947715,
- 24.499714748859326,
- 25.956543598746574,
- 27.5,
- 29.13523509488062,
- 30.86770632850775,
- 32.70319566257483,
- 34.64782887210901,
- 36.70809598967594,
- 38.890872965260115,
- 41.20344461410875,
- 43.653528929125486,
- 46.2493028389543,
- 48.999429497718666,
- 51.91308719749314,
- 55,
- 58.27047018976124,
- 61.7354126570155,
- 65.40639132514966,
- 69.29565774421802,
- 73.41619197935188,
- 77.78174593052023,
- 82.4068892282175,
- 87.30705785825097,
- 92.4986056779086,
- 97.99885899543733,
- 103.82617439498628,
- 110,
- 116.54094037952248,
- 123.47082531403103,
- 130.8127826502993,
- 138.59131548843604,
- 146.8323839587038,
- 155.56349186104046,
- 164.81377845643496,
- 174.61411571650194,
- 184.9972113558172,
- 195.99771799087463,
- 207.65234878997256,
- 220,
- 233.08188075904496,
- 246.94165062806206,
- 261.6255653005986,
- 277.1826309768721,
- 293.6647679174076,
- 311.1269837220809,
- 329.6275569128699,
- 349.2282314330039,
- 369.9944227116344,
- 391.99543598174927,
- 415.3046975799451,
- 440,
- 466.1637615180899,
- 493.8833012561241,
- 523.2511306011972,
- 554.3652619537442,
- 587.3295358348151,
- 622.2539674441618,
- 659.2551138257398,
- 698.4564628660078,
- 739.9888454232688,
- 783.9908719634985,
- 830.6093951598903,
- 880,
- 932.3275230361799,
- 987.7666025122483,
- 1046.5022612023945,
- 1108.7305239074883,
- 1174.6590716696303,
- 1244.5079348883237,
- 1318.5102276514797,
- 1396.9129257320155,
- 1479.9776908465376,
- 1567.981743926997,
- 1661.2187903197805,
- 1760,
- 1864.6550460723597,
- 1975.533205024496,
- 2093.004522404789,
- 2217.4610478149766,
- 2349.31814333926,
- 2489.0158697766474,
- 2637.02045530296,
- 2793.825851464031,
- 2959.955381693075,
- 3135.9634878539946,
- 3322.437580639561,
- 3520,
- 3729.3100921447194,
- 3951.066410048992,
- 4186.009044809578
- ];
- return frequencies;
- });
- _registerModule(_modules, 'Extensions/Sonification/Utilities.js', [_modules['Extensions/Sonification/MusicalFrequencies.js'], _modules['Core/Utilities.js']], function (musicalFrequencies, U) {
-
- var clamp = U.clamp;
-
-
- function SignalHandler(supportedSignals) {
- this.init(supportedSignals || []);
- }
- SignalHandler.prototype.init = function (supportedSignals) {
- this.supportedSignals = supportedSignals;
- this.signals = {};
- };
-
- SignalHandler.prototype.registerSignalCallbacks = function (signals) {
- var signalHandler = this;
- signalHandler.supportedSignals.forEach(function (supportedSignal) {
- var signal = signals[supportedSignal];
- if (signal) {
- (signalHandler.signals[supportedSignal] =
- signalHandler.signals[supportedSignal] || []).push(signal);
- }
- });
- };
-
- SignalHandler.prototype.clearSignalCallbacks = function (signalNames) {
- var signalHandler = this;
- if (signalNames) {
- signalNames.forEach(function (signalName) {
- if (signalHandler.signals[signalName]) {
- delete signalHandler.signals[signalName];
- }
- });
- }
- else {
- signalHandler.signals = {};
- }
- };
-
- SignalHandler.prototype.emitSignal = function (signalName, data) {
- var retval;
- if (this.signals[signalName]) {
- this.signals[signalName].forEach(function (handler) {
- var result = handler(data);
- retval = typeof result !== 'undefined' ? result : retval;
- });
- }
- return retval;
- };
- var utilities = {
-
- musicalFrequencies: musicalFrequencies,
-
- SignalHandler: SignalHandler,
-
- getMusicalScale: function (semitones) {
- return musicalFrequencies.filter(function (freq,
- i) {
- var interval = i % 12 + 1;
- return semitones.some(function (allowedInterval) {
- return allowedInterval === interval;
- });
- });
- },
-
- calculateDataExtremes: function (chart, prop) {
- return chart.series.reduce(function (extremes, series) {
-
-
- series.points.forEach(function (point) {
- var val = typeof point[prop] !== 'undefined' ?
- point[prop] : point.options[prop];
- extremes.min = Math.min(extremes.min, val);
- extremes.max = Math.max(extremes.max, val);
- });
- return extremes;
- }, {
- min: Infinity,
- max: -Infinity
- });
- },
-
- virtualAxisTranslate: function (value, dataExtremes, limits, invert) {
- var lenValueAxis = dataExtremes.max - dataExtremes.min,
- lenVirtualAxis = Math.abs(limits.max - limits.min),
- valueDelta = invert ?
- dataExtremes.max - value :
- value - dataExtremes.min,
- virtualValueDelta = lenVirtualAxis * valueDelta / lenValueAxis,
- virtualAxisValue = limits.min + virtualValueDelta;
- return lenValueAxis > 0 ?
- clamp(virtualAxisValue, limits.min, limits.max) :
- limits.min;
- }
- };
- return utilities;
- });
- _registerModule(_modules, 'Extensions/Sonification/InstrumentDefinitions.js', [_modules['Extensions/Sonification/Instrument.js'], _modules['Extensions/Sonification/Utilities.js']], function (Instrument, utilities) {
-
- var instruments = {};
- ['sine', 'square', 'triangle', 'sawtooth'].forEach(function (waveform) {
-
- instruments[waveform] = new Instrument({
- oscillator: { waveformShape: waveform }
- });
-
- instruments[waveform + 'Musical'] = new Instrument({
- allowedFrequencies: utilities.musicalFrequencies,
- oscillator: { waveformShape: waveform }
- });
-
- instruments[waveform + 'Major'] = new Instrument({
- allowedFrequencies: utilities.getMusicalScale([1, 3, 5, 6, 8, 10, 12]),
- oscillator: { waveformShape: waveform }
- });
- });
- return instruments;
- });
- _registerModule(_modules, 'Extensions/Sonification/Earcon.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
-
- var error = U.error,
- merge = U.merge,
- pick = U.pick,
- uniqueKey = U.uniqueKey;
-
-
-
-
-
-
-
-
-
-
-
- function Earcon(options) {
- this.init(options || {});
- }
- Earcon.prototype.init = function (options) {
- this.options = options;
- if (!this.options.id) {
- this.options.id = this.id = uniqueKey();
- }
- this.instrumentsPlaying = {};
- };
-
- Earcon.prototype.sonify = function (options) {
- var playOptions = merge(this.options,
- options);
-
- var masterVolume = pick(playOptions.volume, 1),
- masterPan = playOptions.pan,
- earcon = this,
- playOnEnd = options && options.onEnd,
- masterOnEnd = earcon.options.onEnd;
-
- playOptions.instruments.forEach(function (opts) {
- var instrument = typeof opts.instrument === 'string' ?
- H.sonification.instruments[opts.instrument] : opts.instrument,
- instrumentOpts = merge(opts.playOptions),
- instrOnEnd,
- instrumentCopy,
- copyId = '';
- if (instrument && instrument.play) {
- if (opts.playOptions) {
- instrumentOpts.pan = pick(masterPan, instrumentOpts.pan);
-
- instrOnEnd = instrumentOpts.onEnd;
- instrumentOpts.onEnd = function () {
- delete earcon.instrumentsPlaying[copyId];
- if (instrOnEnd) {
- instrOnEnd.apply(this, arguments);
- }
- if (!Object.keys(earcon.instrumentsPlaying).length) {
- if (playOnEnd) {
- playOnEnd.apply(this, arguments);
- }
- if (masterOnEnd) {
- masterOnEnd.apply(this, arguments);
- }
- }
- };
-
-
- instrumentCopy = instrument.copy();
- instrumentCopy.setMasterVolume(masterVolume);
- copyId = instrumentCopy.id;
- earcon.instrumentsPlaying[copyId] = instrumentCopy;
- instrumentCopy.play(instrumentOpts);
- }
- }
- else {
- error(30);
- }
- });
- };
-
- Earcon.prototype.cancelSonify = function (fadeOut) {
- var playing = this.instrumentsPlaying,
- instrIds = playing && Object.keys(playing);
- if (instrIds && instrIds.length) {
- instrIds.forEach(function (instr) {
- playing[instr].stop(!fadeOut, null, 'cancelled');
- });
- this.instrumentsPlaying = {};
- }
- };
- return Earcon;
- });
- _registerModule(_modules, 'Extensions/Sonification/PointSonify.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Extensions/Sonification/Utilities.js']], function (H, U, utilities) {
-
- var error = U.error,
- merge = U.merge,
- pick = U.pick;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- var defaultInstrumentOptions = {
- minDuration: 20,
- maxDuration: 2000,
- minVolume: 0.1,
- maxVolume: 1,
- minPan: -1,
- maxPan: 1,
- minFrequency: 220,
- maxFrequency: 2200
- };
-
-
- function pointSonify(options) {
- var point = this,
- chart = point.series.chart,
- masterVolume = pick(options.masterVolume,
- chart.options.sonification &&
- chart.options.sonification.masterVolume),
- dataExtremes = options.dataExtremes || {},
-
-
- getMappingValue = function (value,
- makeFunction,
- allowedExtremes) {
-
-
- if (typeof value === 'function') {
- return makeFunction ?
- function (time) {
- return value(point,
- dataExtremes,
- time);
- } :
- value(point, dataExtremes);
- }
-
- if (typeof value === 'string') {
- var hasInvertedPolarity = value.charAt(0) === '-';
- var dataProp = hasInvertedPolarity ? value.slice(1) : value;
- var pointValue = pick(point[dataProp],
- point.options[dataProp]);
-
- dataExtremes[dataProp] = dataExtremes[dataProp] ||
- utilities.calculateDataExtremes(point.series.chart, dataProp);
-
- return utilities.virtualAxisTranslate(pointValue, dataExtremes[dataProp], allowedExtremes, hasInvertedPolarity);
- }
-
- return value;
- };
-
- chart.sonification.currentlyPlayingPoint = point;
-
- point.sonification = point.sonification || {};
- point.sonification.instrumentsPlaying =
- point.sonification.instrumentsPlaying || {};
-
- var signalHandler = point.sonification.signalHandler =
- point.sonification.signalHandler ||
- new utilities.SignalHandler(['onEnd']);
- signalHandler.clearSignalCallbacks();
- signalHandler.registerSignalCallbacks({ onEnd: options.onEnd });
-
- if (point.isNull || !point.visible || !point.series.visible) {
- signalHandler.emitSignal('onEnd');
- return;
- }
-
- options.instruments.forEach(function (instrumentDefinition) {
- var instrument = typeof instrumentDefinition.instrument === 'string' ?
- H.sonification.instruments[instrumentDefinition.instrument] :
- instrumentDefinition.instrument,
- mapping = instrumentDefinition.instrumentMapping || {},
- extremes = merge(defaultInstrumentOptions,
- instrumentDefinition.instrumentOptions),
- id = instrument.id,
- onEnd = function (cancelled) {
-
- if (instrumentDefinition.onEnd) {
- instrumentDefinition.onEnd.apply(this,
- arguments);
- }
-
- if (chart.sonification &&
- chart.sonification.currentlyPlayingPoint) {
- delete chart.sonification.currentlyPlayingPoint;
- }
-
- if (point.sonification && point.sonification.instrumentsPlaying) {
- delete point.sonification.instrumentsPlaying[id];
-
- if (!Object.keys(point.sonification.instrumentsPlaying).length) {
- signalHandler.emitSignal('onEnd', cancelled);
- }
- }
- };
-
- if (instrument && instrument.play) {
- if (typeof masterVolume !== 'undefined') {
- instrument.setMasterVolume(masterVolume);
- }
- point.sonification.instrumentsPlaying[instrument.id] =
- instrument;
- instrument.play({
- frequency: getMappingValue(mapping.frequency, true, { min: extremes.minFrequency, max: extremes.maxFrequency }),
- duration: getMappingValue(mapping.duration, false, { min: extremes.minDuration, max: extremes.maxDuration }),
- pan: getMappingValue(mapping.pan, true, { min: extremes.minPan, max: extremes.maxPan }),
- volume: getMappingValue(mapping.volume, true, { min: extremes.minVolume, max: extremes.maxVolume }),
- onEnd: onEnd,
- minFrequency: extremes.minFrequency,
- maxFrequency: extremes.maxFrequency
- });
- }
- else {
- error(30);
- }
- });
- }
-
- function pointCancelSonify(fadeOut) {
- var playing = this.sonification && this.sonification.instrumentsPlaying,
- instrIds = playing && Object.keys(playing);
- if (instrIds && instrIds.length) {
- instrIds.forEach(function (instr) {
- playing[instr].stop(!fadeOut, null, 'cancelled');
- });
- this.sonification.instrumentsPlaying = {};
- this.sonification.signalHandler.emitSignal('onEnd', 'cancelled');
- }
- }
- var pointSonifyFunctions = {
- pointSonify: pointSonify,
- pointCancelSonify: pointCancelSonify
- };
- return pointSonifyFunctions;
- });
- _registerModule(_modules, 'Extensions/Sonification/ChartSonify.js', [_modules['Core/Globals.js'], _modules['Core/Series/Point.js'], _modules['Core/Utilities.js'], _modules['Extensions/Sonification/Utilities.js']], function (H, Point, U, utilities) {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '';
- var find = U.find,
- isArray = U.isArray,
- merge = U.merge,
- pick = U.pick,
- splat = U.splat,
- objectEach = U.objectEach;
-
- function getPointTimeValue(point, timeProp) {
- return typeof timeProp === 'function' ?
- timeProp(point) :
- pick(point[timeProp], point.options[timeProp]);
- }
-
- function getTimeExtremes(series, timeProp) {
-
- return series.points.reduce(function (acc, point) {
- var value = getPointTimeValue(point,
- timeProp);
- acc.min = Math.min(acc.min, value);
- acc.max = Math.max(acc.max, value);
- return acc;
- }, {
- min: Infinity,
- max: -Infinity
- });
- }
-
- function getExtremesForInstrumentProps(chart, instruments, dataExtremes) {
- var allInstrumentDefinitions = (instruments || []).slice(0);
- var defaultInstrumentDef = (chart.options.sonification &&
- chart.options.sonification.defaultInstrumentOptions);
- var optionDefToInstrDef = function (optionDef) { return ({
- instrumentMapping: optionDef.mapping
- }); };
- if (defaultInstrumentDef) {
- allInstrumentDefinitions.push(optionDefToInstrDef(defaultInstrumentDef));
- }
- chart.series.forEach(function (series) {
- var instrOptions = (series.options.sonification &&
- series.options.sonification.instruments);
- if (instrOptions) {
- allInstrumentDefinitions = allInstrumentDefinitions.concat(instrOptions.map(optionDefToInstrDef));
- }
- });
- return (allInstrumentDefinitions).reduce(function (newExtremes, instrumentDefinition) {
- Object.keys(instrumentDefinition.instrumentMapping || {}).forEach(function (instrumentParameter) {
- var value = instrumentDefinition.instrumentMapping[instrumentParameter];
- if (typeof value === 'string' && !newExtremes[value]) {
-
-
- newExtremes[value] = utilities.calculateDataExtremes(chart, value);
- }
- });
- return newExtremes;
- }, merge(dataExtremes));
- }
-
- function getPointEarcons(point, earconDefinitions) {
- return earconDefinitions.reduce(function (earcons, earconDefinition) {
- var cond,
- earcon = earconDefinition.earcon;
- if (earconDefinition.condition) {
-
- cond = earconDefinition.condition(point);
- if (cond instanceof H.sonification.Earcon) {
-
- earcons.push(cond);
- }
- else if (cond) {
-
- earcons.push(earcon);
- }
- }
- else if (earconDefinition.onPoint &&
- point.id === earconDefinition.onPoint) {
-
- earcons.push(earcon);
- }
- return earcons;
- }, []);
- }
-
- function makeInstrumentCopies(instruments) {
- return instruments.map(function (instrumentDef) {
- var instrument = instrumentDef.instrument,
- copy = (typeof instrument === 'string' ?
- H.sonification.instruments[instrument] :
- instrument).copy();
- return merge(instrumentDef, { instrument: copy });
- });
- }
-
- function applyMasterVolumeToInstruments(instruments, masterVolume) {
- instruments.forEach(function (instrOpts) {
- var instr = instrOpts.instrument;
- if (typeof instr !== 'string') {
- instr.setMasterVolume(masterVolume);
- }
- });
- return instruments;
- }
-
- function getFinalNoteDuration(series, instruments, dataExtremes) {
- var finalPoint = series.points[series.points.length - 1];
- return instruments.reduce(function (duration, instrument) {
- var mapping = instrument.instrumentMapping.duration;
- var instrumentDuration;
- if (typeof mapping === 'string') {
- instrumentDuration = 0;
- }
- else if (typeof mapping === 'function') {
- instrumentDuration = mapping(finalPoint, dataExtremes);
- }
- else {
- instrumentDuration = mapping;
- }
- return Math.max(duration, instrumentDuration);
- }, 0);
- }
-
- function buildTimelinePathFromSeries(series, options) {
-
-
- var timeExtremes = options.timeExtremes || getTimeExtremes(series,
- options.pointPlayTime),
-
- dataExtremes = getExtremesForInstrumentProps(series.chart,
- options.instruments,
- options.dataExtremes),
- minimumSeriesDurationMs = 10,
-
- finalNoteDuration = getFinalNoteDuration(series,
- options.instruments,
- dataExtremes),
-
- pointToTime = function (point) {
- return utilities.virtualAxisTranslate(getPointTimeValue(point,
- options.pointPlayTime),
- timeExtremes, { min: 0,
- max: Math.max(options.duration - finalNoteDuration,
- minimumSeriesDurationMs) });
- }, masterVolume = pick(options.masterVolume, 1),
-
-
- instrumentCopies = makeInstrumentCopies(options.instruments), instruments = applyMasterVolumeToInstruments(instrumentCopies, masterVolume),
-
- timelineEvents = series.points.reduce(function (events, point) {
- var earcons = getPointEarcons(point,
- options.earcons || []),
- time = pointToTime(point);
- return events.concat(
-
- new H.sonification.TimelineEvent({
- eventObject: point,
- time: time,
- id: point.id,
- playOptions: {
- instruments: instruments,
- dataExtremes: dataExtremes,
- masterVolume: masterVolume
- }
- }),
-
- earcons.map(function (earcon) {
- return new H.sonification.TimelineEvent({
- eventObject: earcon,
- time: time,
- playOptions: {
- volume: masterVolume
- }
- });
- }));
- }, []);
-
- return new H.sonification.TimelinePath({
- events: timelineEvents,
- onStart: function () {
- if (options.onStart) {
- options.onStart(series);
- }
- },
- onEventStart: function (event) {
- var eventObject = event.options && event.options.eventObject;
- if (eventObject instanceof Point) {
-
- if (!eventObject.series.visible &&
- !eventObject.series.chart.series.some(function (series) {
- return series.visible;
- })) {
-
- event.timelinePath.timeline.pause();
- event.timelinePath.timeline.resetCursor();
- return false;
- }
-
- if (options.onPointStart) {
- options.onPointStart(event, eventObject);
- }
- }
- },
- onEventEnd: function (eventData) {
- var eventObject = eventData.event && eventData.event.options &&
- eventData.event.options.eventObject;
- if (eventObject instanceof Point && options.onPointEnd) {
- options.onPointEnd(eventData.event, eventObject);
- }
- },
- onEnd: function () {
- if (options.onEnd) {
- options.onEnd(series);
- }
- },
- targetDuration: options.duration
- });
- }
-
-
- function seriesSonify(options) {
- var mergedOptions = getSeriesSonifyOptions(this,
- options);
- var timelinePath = buildTimelinePathFromSeries(this,
- mergedOptions);
- var chartSonification = this.chart.sonification;
-
-
- if (chartSonification.timeline) {
- chartSonification.timeline.pause();
- }
-
- chartSonification.duration = mergedOptions.duration;
-
- chartSonification.timeline = new H.sonification.Timeline({
- paths: [timelinePath]
- });
- chartSonification.timeline.play();
- }
-
- function buildChartSonifySeriesOptions(series, dataExtremes, chartSonifyOptions) {
- var additionalSeriesOptions = chartSonifyOptions.seriesOptions || {};
- var pointPlayTime = (series.chart.options.sonification &&
- series.chart.options.sonification.defaultInstrumentOptions &&
- series.chart.options.sonification.defaultInstrumentOptions.mapping &&
- series.chart.options.sonification.defaultInstrumentOptions.mapping.pointPlayTime ||
- 'x');
- var configOptions = chartOptionsToSonifySeriesOptions(series);
- return merge(
-
- configOptions,
-
- {
-
- dataExtremes: dataExtremes,
-
-
-
- timeExtremes: getTimeExtremes(series, pointPlayTime),
-
- instruments: chartSonifyOptions.instruments || configOptions.instruments,
- onStart: chartSonifyOptions.onSeriesStart || configOptions.onStart,
- onEnd: chartSonifyOptions.onSeriesEnd || configOptions.onEnd,
- earcons: chartSonifyOptions.earcons || configOptions.earcons,
- masterVolume: pick(chartSonifyOptions.masterVolume, configOptions.masterVolume)
- },
-
- isArray(additionalSeriesOptions) ? (find(additionalSeriesOptions, function (optEntry) {
- return optEntry.id === pick(series.id, series.options.id);
- }) || {}) : additionalSeriesOptions, {
-
- pointPlayTime: pointPlayTime
- });
- }
-
- function buildPathOrder(orderOptions, chart, seriesOptionsCallback) {
- var order;
- if (orderOptions === 'sequential' || orderOptions === 'simultaneous') {
-
- order = chart.series.reduce(function (seriesList, series) {
- if (series.visible &&
- (series.options.sonification &&
- series.options.sonification.enabled) !== false) {
- seriesList.push({
- series: series,
- seriesOptions: seriesOptionsCallback(series)
- });
- }
- return seriesList;
- }, []);
-
- if (orderOptions === 'simultaneous') {
- order = [order];
- }
- }
- else {
-
-
- order = orderOptions.reduce(function (orderList, orderDef) {
-
- var simulItems = splat(orderDef).reduce(function (items,
- item) {
- var itemObject;
-
- if (typeof item === 'string') {
- var series = chart.get(item);
- if (series.visible) {
- itemObject = {
- series: series,
- seriesOptions: seriesOptionsCallback(series)
- };
- }
-
- }
- else if (item instanceof H.sonification.Earcon) {
-
- itemObject = new H.sonification.TimelinePath({
- events: [new H.sonification.TimelineEvent({
- eventObject: item
- })]
- });
- }
-
- if (item.silentWait) {
- itemObject = new H.sonification.TimelinePath({
- silentWait: item.silentWait
- });
- }
-
- if (itemObject) {
- items.push(itemObject);
- }
- return items;
- }, []);
-
- if (simulItems.length) {
- orderList.push(simulItems);
- }
- return orderList;
- }, []);
- }
- return order;
- }
-
- function addAfterSeriesWaits(order, wait) {
- if (!wait) {
- return order;
- }
- return order.reduce(function (newOrder, orderDef, i) {
- var simultaneousPaths = splat(orderDef);
- newOrder.push(simultaneousPaths);
-
- if (i < order.length - 1 &&
- simultaneousPaths.some(function (item) {
- return item.series;
- })) {
-
-
- newOrder.push(new H.sonification.TimelinePath({
- silentWait: wait
- }));
- }
- return newOrder;
- }, []);
- }
-
- function getWaitTime(order) {
- return order.reduce(function (waitTime, orderDef) {
- var def = splat(orderDef);
- return waitTime + (def.length === 1 &&
- def[0].options &&
- def[0].options.silentWait || 0);
- }, 0);
- }
-
- function syncSimultaneousPaths(paths) {
-
- var extremes = paths.reduce(function (extremes,
- path) {
- var events = path.events;
- if (events && events.length) {
- extremes.min = Math.min(events[0].time, extremes.min);
- extremes.max = Math.max(events[events.length - 1].time, extremes.max);
- }
- return extremes;
- }, {
- min: Infinity,
- max: -Infinity
- });
-
- paths.forEach(function (path) {
- var events = path.events,
- hasEvents = events && events.length,
- eventsToAdd = [];
- if (!(hasEvents && events[0].time <= extremes.min)) {
- eventsToAdd.push(new H.sonification.TimelineEvent({
- time: extremes.min
- }));
- }
- if (!(hasEvents && events[events.length - 1].time >= extremes.max)) {
- eventsToAdd.push(new H.sonification.TimelineEvent({
- time: extremes.max
- }));
- }
- if (eventsToAdd.length) {
- path.addTimelineEvents(eventsToAdd);
- }
- });
- }
-
- function getSimulPathDurationTotal(order) {
- return order.reduce(function (durationTotal, orderDef) {
- return durationTotal + splat(orderDef).reduce(function (maxPathDuration, item) {
- var timeExtremes = (item.series &&
- item.seriesOptions &&
- item.seriesOptions.timeExtremes);
- return timeExtremes ?
- Math.max(maxPathDuration, timeExtremes.max - timeExtremes.min) : maxPathDuration;
- }, 0);
- }, 0);
- }
-
- function getSeriesDurationMs(seriesValueDuration, totalValueDuration, totalDurationMs) {
-
- return utilities.virtualAxisTranslate(seriesValueDuration, { min: 0, max: totalValueDuration }, { min: 0, max: totalDurationMs });
- }
-
- function buildPathsFromOrder(order, duration) {
-
-
- var totalAvailableDurationMs = Math.max(duration - getWaitTime(order), 0),
-
-
- totalUsedDuration = getSimulPathDurationTotal(order);
-
- return order.reduce(function (allPaths, orderDef) {
- var simultaneousPaths = splat(orderDef).reduce(function (simulPaths,
- item) {
- if (item instanceof H.sonification.TimelinePath) {
-
- simulPaths.push(item);
- }
- else if (item.series) {
-
-
- item.seriesOptions.duration =
- item.seriesOptions.duration || getSeriesDurationMs(item.seriesOptions.timeExtremes.max -
- item.seriesOptions.timeExtremes.min, totalUsedDuration, totalAvailableDurationMs);
-
- simulPaths.push(buildTimelinePathFromSeries(item.series, item.seriesOptions));
- }
- return simulPaths;
- }, []);
-
- allPaths.push(simultaneousPaths);
- return allPaths;
- }, []);
- }
-
- function getSeriesInstrumentOptions(series, options) {
- if (options && options.instruments) {
- return options.instruments;
- }
- var defaultInstrOpts = (series.chart.options.sonification &&
- series.chart.options.sonification.defaultInstrumentOptions ||
- {});
- var seriesInstrOpts = (series.options.sonification &&
- series.options.sonification.instruments ||
- [{}]);
- var removeNullsFromObject = function (obj) {
- objectEach(obj,
- function (val,
- key) {
- if (val === null) {
- delete obj[key];
- }
- });
- };
-
-
- return (seriesInstrOpts).map(function (optionSet) {
-
- removeNullsFromObject(optionSet.mapping || {});
- removeNullsFromObject(optionSet);
- return {
- instrument: optionSet.instrument || defaultInstrOpts.instrument,
- instrumentOptions: merge(defaultInstrOpts, optionSet, {
-
-
-
- mapping: void 0,
- instrument: void 0
- }),
- instrumentMapping: merge(defaultInstrOpts.mapping, optionSet.mapping)
- };
- });
- }
-
- function chartOptionsToSonifySeriesOptions(series) {
- var seriesOpts = series.options.sonification || {};
- var chartOpts = series.chart.options.sonification || {};
- var chartEvents = chartOpts.events || {};
- var seriesEvents = seriesOpts.events || {};
- return {
- onEnd: seriesEvents.onSeriesEnd || chartEvents.onSeriesEnd,
- onStart: seriesEvents.onSeriesStart || chartEvents.onSeriesStart,
- onPointEnd: seriesEvents.onPointEnd || chartEvents.onPointEnd,
- onPointStart: seriesEvents.onPointStart || chartEvents.onPointStart,
- pointPlayTime: (chartOpts.defaultInstrumentOptions &&
- chartOpts.defaultInstrumentOptions.mapping &&
- chartOpts.defaultInstrumentOptions.mapping.pointPlayTime),
- masterVolume: chartOpts.masterVolume,
- instruments: getSeriesInstrumentOptions(series),
- earcons: seriesOpts.earcons || chartOpts.earcons
- };
- }
-
- function getSeriesSonifyOptions(series, options) {
- var chartOpts = series.chart.options.sonification;
- var seriesOpts = series.options.sonification;
- return merge({
- duration: ((seriesOpts && seriesOpts.duration) ||
- (chartOpts && chartOpts.duration))
- }, chartOptionsToSonifySeriesOptions(series), options);
- }
-
- function getChartSonifyOptions(chart, options) {
- var chartOpts = chart.options.sonification || {};
- return merge({
- duration: chartOpts.duration,
- afterSeriesWait: chartOpts.afterSeriesWait,
- pointPlayTime: (chartOpts.defaultInstrumentOptions &&
- chartOpts.defaultInstrumentOptions.mapping &&
- chartOpts.defaultInstrumentOptions.mapping.pointPlayTime),
- order: chartOpts.order,
- onSeriesStart: (chartOpts.events && chartOpts.events.onSeriesStart),
- onSeriesEnd: (chartOpts.events && chartOpts.events.onSeriesEnd),
- onEnd: (chartOpts.events && chartOpts.events.onEnd)
- }, options);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- function chartSonify(options) {
- var opts = getChartSonifyOptions(this,
- options);
-
- if (this.sonification.timeline) {
- this.sonification.timeline.pause();
- }
-
- this.sonification.duration = opts.duration;
-
- var dataExtremes = getExtremesForInstrumentProps(this,
- opts.instruments,
- opts.dataExtremes);
-
- var order = buildPathOrder(opts.order,
- this,
- function (series) {
- return buildChartSonifySeriesOptions(series,
- dataExtremes,
- opts);
- });
-
- order = addAfterSeriesWaits(order, opts.afterSeriesWait || 0);
-
-
- var paths = buildPathsFromOrder(order,
- opts.duration);
-
- paths.forEach(function (simultaneousPaths) {
- syncSimultaneousPaths(simultaneousPaths);
- });
-
- this.sonification.timeline = new H.sonification.Timeline({
- paths: paths,
- onEnd: opts.onEnd
- });
- this.sonification.timeline.play();
- }
-
- function getCurrentPoints() {
- var cursorObj;
- if (this.sonification.timeline) {
- cursorObj = this.sonification.timeline.getCursor();
- return Object.keys(cursorObj).map(function (path) {
-
- return cursorObj[path].eventObject;
- }).filter(function (eventObj) {
-
- return eventObj instanceof Point;
- });
- }
- return [];
- }
-
- function setCursor(points) {
- var timeline = this.sonification.timeline;
- if (timeline) {
- splat(points).forEach(function (point) {
-
-
- timeline.setCursor(point.id);
- });
- }
- }
-
- function pause(fadeOut) {
- if (this.sonification.timeline) {
- this.sonification.timeline.pause(pick(fadeOut, true));
- }
- else if (this.sonification.currentlyPlayingPoint) {
- this.sonification.currentlyPlayingPoint.cancelSonify(fadeOut);
- }
- }
-
- function resume(onEnd) {
- if (this.sonification.timeline) {
- this.sonification.timeline.play(onEnd);
- }
- }
-
- function rewind(onEnd) {
- if (this.sonification.timeline) {
- this.sonification.timeline.rewind(onEnd);
- }
- }
-
- function cancel(fadeOut) {
- this.pauseSonify(fadeOut);
- this.resetSonifyCursor();
- }
-
- function resetCursor() {
- if (this.sonification.timeline) {
- this.sonification.timeline.resetCursor();
- }
- }
-
- function resetCursorEnd() {
- if (this.sonification.timeline) {
- this.sonification.timeline.resetCursorEnd();
- }
- }
-
- var chartSonifyFunctions = {
- chartSonify: chartSonify,
- seriesSonify: seriesSonify,
- pause: pause,
- resume: resume,
- rewind: rewind,
- cancel: cancel,
- getCurrentPoints: getCurrentPoints,
- setCursor: setCursor,
- resetCursor: resetCursor,
- resetCursorEnd: resetCursorEnd
- };
- return chartSonifyFunctions;
- });
- _registerModule(_modules, 'Extensions/Sonification/Timeline.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Extensions/Sonification/Utilities.js']], function (H, U, utilities) {
-
- var merge = U.merge,
- splat = U.splat,
- uniqueKey = U.uniqueKey;
-
-
-
-
-
-
-
-
- function TimelineEvent(options) {
- this.init(options || {});
- }
- TimelineEvent.prototype.init = function (options) {
- this.options = options;
- this.time = options.time || 0;
- this.id = this.options.id = options.id || uniqueKey();
- };
-
- TimelineEvent.prototype.play = function (options) {
- var eventObject = this.options.eventObject,
- masterOnEnd = this.options.onEnd,
- playOnEnd = options && options.onEnd,
- playOptionsOnEnd = this.options.playOptions &&
- this.options.playOptions.onEnd,
- playOptions = merge(this.options.playOptions,
- options);
- if (eventObject && eventObject.sonify) {
-
- playOptions.onEnd = masterOnEnd || playOnEnd || playOptionsOnEnd ?
- function () {
- var args = arguments;
- [masterOnEnd, playOnEnd, playOptionsOnEnd].forEach(function (onEnd) {
- if (onEnd) {
- onEnd.apply(this, args);
- }
- });
- } : void 0;
- eventObject.sonify(playOptions);
- }
- else {
- if (playOnEnd) {
- playOnEnd();
- }
- if (masterOnEnd) {
- masterOnEnd();
- }
- }
- };
-
- TimelineEvent.prototype.cancel = function (fadeOut) {
- this.options.eventObject.cancelSonify(fadeOut);
- };
-
-
-
-
-
-
-
-
-
- function TimelinePath(options) {
- this.init(options);
- }
- TimelinePath.prototype.init = function (options) {
- this.options = options;
- this.id = this.options.id = options.id || uniqueKey();
- this.cursor = 0;
- this.eventsPlaying = {};
-
- this.events = options.silentWait ?
- [
- new TimelineEvent({ time: 0 }),
- new TimelineEvent({ time: options.silentWait })
- ] :
- this.options.events;
-
-
- this.targetDuration = options.targetDuration || options.silentWait;
-
- this.sortEvents();
-
- this.updateEventIdMap();
-
- this.signalHandler = new utilities.SignalHandler(['playOnEnd', 'masterOnEnd', 'onStart', 'onEventStart', 'onEventEnd']);
- this.signalHandler.registerSignalCallbacks(merge(options, { masterOnEnd: options.onEnd }));
- };
-
- TimelinePath.prototype.sortEvents = function () {
- this.events = this.events.sort(function (a, b) {
- return a.time - b.time;
- });
- };
-
- TimelinePath.prototype.updateEventIdMap = function () {
- this.eventIdMap = this.events.reduce(function (acc, cur, i) {
- acc[cur.id] = i;
- return acc;
- }, {});
- };
-
- TimelinePath.prototype.addTimelineEvents = function (newEvents) {
- this.events = this.events.concat(newEvents);
- this.sortEvents();
- this.updateEventIdMap();
- };
-
- TimelinePath.prototype.getCursor = function () {
- return this.events[this.cursor];
- };
-
- TimelinePath.prototype.setCursor = function (eventId) {
- var ix = this.eventIdMap[eventId];
- if (typeof ix !== 'undefined') {
- this.cursor = ix;
- return true;
- }
- return false;
- };
-
- TimelinePath.prototype.play = function (onEnd) {
- this.pause();
- this.signalHandler.emitSignal('onStart');
- this.signalHandler.clearSignalCallbacks(['playOnEnd']);
- this.signalHandler.registerSignalCallbacks({ playOnEnd: onEnd });
- this.playEvents(1);
- };
-
- TimelinePath.prototype.rewind = function (onEnd) {
- this.pause();
- this.signalHandler.emitSignal('onStart');
- this.signalHandler.clearSignalCallbacks(['playOnEnd']);
- this.signalHandler.registerSignalCallbacks({ playOnEnd: onEnd });
- this.playEvents(-1);
- };
-
- TimelinePath.prototype.resetCursor = function () {
- this.cursor = 0;
- };
-
- TimelinePath.prototype.resetCursorEnd = function () {
- this.cursor = this.events.length - 1;
- };
-
- TimelinePath.prototype.pause = function (fadeOut) {
- var timelinePath = this;
-
- clearTimeout(timelinePath.nextScheduledPlay);
-
- Object.keys(timelinePath.eventsPlaying).forEach(function (id) {
- if (timelinePath.eventsPlaying[id]) {
- timelinePath.eventsPlaying[id].cancel(fadeOut);
- }
- });
- timelinePath.eventsPlaying = {};
- };
-
- TimelinePath.prototype.playEvents = function (direction) {
- var timelinePath = this,
- curEvent = timelinePath.events[this.cursor],
- nextEvent = timelinePath.events[this.cursor + direction],
- timeDiff,
- onEnd = function (signalData) {
- timelinePath.signalHandler.emitSignal('masterOnEnd',
- signalData);
- timelinePath.signalHandler.emitSignal('playOnEnd', signalData);
- };
-
- curEvent.timelinePath = timelinePath;
-
- if (timelinePath.signalHandler.emitSignal('onEventStart', curEvent) === false) {
- onEnd({
- event: curEvent,
- cancelled: true
- });
- return;
- }
-
- timelinePath.eventsPlaying[curEvent.id] = curEvent;
- curEvent.play({
- onEnd: function (cancelled) {
- var signalData = {
- event: curEvent,
- cancelled: !!cancelled
- };
-
- delete timelinePath.eventsPlaying[curEvent.id];
-
- timelinePath.signalHandler.emitSignal('onEventEnd', signalData);
-
- if (!nextEvent) {
- onEnd(signalData);
- }
- }
- });
-
- if (nextEvent) {
- timeDiff = Math.abs(nextEvent.time - curEvent.time);
- if (timeDiff < 1) {
-
- timelinePath.cursor += direction;
- timelinePath.playEvents(direction);
- }
- else {
-
- this.nextScheduledPlay = setTimeout(function () {
- timelinePath.cursor += direction;
- timelinePath.playEvents(direction);
- }, timeDiff);
- }
- }
- };
-
-
-
-
-
-
-
- function Timeline(options) {
- this.init(options || {});
- }
- Timeline.prototype.init = function (options) {
- this.options = options;
- this.cursor = 0;
- this.paths = options.paths || [];
- this.pathsPlaying = {};
- this.signalHandler = new utilities.SignalHandler(['playOnEnd', 'masterOnEnd', 'onPathStart', 'onPathEnd']);
- this.signalHandler.registerSignalCallbacks(merge(options, { masterOnEnd: options.onEnd }));
- };
-
- Timeline.prototype.play = function (onEnd) {
- this.pause();
- this.signalHandler.clearSignalCallbacks(['playOnEnd']);
- this.signalHandler.registerSignalCallbacks({ playOnEnd: onEnd });
- this.playPaths(1);
- };
-
- Timeline.prototype.rewind = function (onEnd) {
- this.pause();
- this.signalHandler.clearSignalCallbacks(['playOnEnd']);
- this.signalHandler.registerSignalCallbacks({ playOnEnd: onEnd });
- this.playPaths(-1);
- };
-
- Timeline.prototype.playPaths = function (direction) {
- var timeline = this;
- var signalHandler = timeline.signalHandler;
- if (!timeline.paths.length) {
- var emptySignal = {
- cancelled: false
- };
- signalHandler.emitSignal('playOnEnd', emptySignal);
- signalHandler.emitSignal('masterOnEnd', emptySignal);
- return;
- }
- var curPaths = splat(this.paths[this.cursor]),
- nextPaths = this.paths[this.cursor + direction],
- pathsEnded = 0,
-
- playPath = function (path) {
-
- signalHandler.emitSignal('onPathStart',
- path);
- timeline.pathsPlaying[path.id] = path;
-
- path[direction > 0 ? 'play' : 'rewind'](function (callbackData) {
-
-
- var cancelled = callbackData && callbackData.cancelled,
- signalData = {
- path: path,
- cancelled: cancelled
- };
-
- delete timeline.pathsPlaying[path.id];
- signalHandler.emitSignal('onPathEnd', signalData);
-
- pathsEnded++;
- if (pathsEnded >= curPaths.length) {
-
- if (nextPaths && !cancelled) {
-
- timeline.cursor += direction;
-
- splat(nextPaths).forEach(function (nextPath) {
- nextPath[direction > 0 ? 'resetCursor' : 'resetCursorEnd']();
- });
-
- timeline.playPaths(direction);
- }
- else {
-
- signalHandler.emitSignal('playOnEnd', signalData);
- signalHandler.emitSignal('masterOnEnd', signalData);
- }
- }
- });
- };
-
- curPaths.forEach(function (path) {
- if (path) {
-
- path.timeline = timeline;
-
- setTimeout(function () {
- playPath(path);
- }, H.sonification.fadeOutDuration);
- }
- });
- };
-
- Timeline.prototype.pause = function (fadeOut) {
- var timeline = this;
-
- Object.keys(timeline.pathsPlaying).forEach(function (id) {
- if (timeline.pathsPlaying[id]) {
- timeline.pathsPlaying[id].pause(fadeOut);
- }
- });
- timeline.pathsPlaying = {};
- };
-
- Timeline.prototype.resetCursor = function () {
- this.paths.forEach(function (paths) {
- splat(paths).forEach(function (path) {
- path.resetCursor();
- });
- });
- this.cursor = 0;
- };
-
- Timeline.prototype.resetCursorEnd = function () {
- this.paths.forEach(function (paths) {
- splat(paths).forEach(function (path) {
- path.resetCursorEnd();
- });
- });
- this.cursor = this.paths.length - 1;
- };
-
- Timeline.prototype.setCursor = function (eventId) {
- return this.paths.some(function (paths) {
- return splat(paths).some(function (path) {
- return path.setCursor(eventId);
- });
- });
- };
-
- Timeline.prototype.getCursor = function () {
- return this.getCurrentPlayingPaths().reduce(function (acc, cur) {
- acc[cur.id] = cur.getCursor();
- return acc;
- }, {});
- };
-
- Timeline.prototype.atStart = function () {
- if (this.cursor) {
- return false;
- }
- return !splat(this.paths[0]).some(function (path) {
- return path.cursor;
- });
- };
-
- Timeline.prototype.getCurrentPlayingPaths = function () {
- if (!this.paths.length) {
- return [];
- }
- return splat(this.paths[this.cursor]);
- };
-
- var timelineClasses = {
- TimelineEvent: TimelineEvent,
- TimelinePath: TimelinePath,
- Timeline: Timeline
- };
- return timelineClasses;
- });
- _registerModule(_modules, 'Extensions/Sonification/Options.js', [], function () {
-
-
- var options = {
- sonification: {
- enabled: false,
- duration: 2500,
- afterSeriesWait: 700,
- masterVolume: 1,
- order: 'sequential',
- defaultInstrumentOptions: {
- instrument: 'sineMusical',
-
- minFrequency: 392,
- maxFrequency: 1046,
- mapping: {
- pointPlayTime: 'x',
- duration: 200,
- frequency: 'y'
- }
- }
- }
- };
- return options;
- });
- _registerModule(_modules, 'Extensions/Sonification/Sonification.js', [_modules['Core/Chart/Chart.js'], _modules['Core/Globals.js'], _modules['Core/DefaultOptions.js'], _modules['Core/Series/Point.js'], _modules['Core/Series/Series.js'], _modules['Core/Utilities.js'], _modules['Extensions/Sonification/Instrument.js'], _modules['Extensions/Sonification/InstrumentDefinitions.js'], _modules['Extensions/Sonification/Earcon.js'], _modules['Extensions/Sonification/PointSonify.js'], _modules['Extensions/Sonification/ChartSonify.js'], _modules['Extensions/Sonification/Utilities.js'], _modules['Extensions/Sonification/Timeline.js'], _modules['Extensions/Sonification/Options.js']], function (Chart, H, D, Point, Series, U, Instrument, instruments, Earcon, pointSonifyFunctions, chartSonifyFunctions, utilities, TimelineClasses, sonificationOptions) {
-
- var defaultOptions = D.defaultOptions;
- var addEvent = U.addEvent,
- extend = U.extend,
- merge = U.merge;
-
-
-
-
-
-
-
-
-
-
-
- H.sonification = {
- fadeOutDuration: 20,
-
- utilities: utilities,
- Instrument: Instrument,
- instruments: instruments,
- Earcon: Earcon,
- TimelineEvent: TimelineClasses.TimelineEvent,
- TimelinePath: TimelineClasses.TimelinePath,
- Timeline: TimelineClasses.Timeline
- };
-
- merge(true, defaultOptions, sonificationOptions);
-
- Point.prototype.sonify = pointSonifyFunctions.pointSonify;
- Point.prototype.cancelSonify = pointSonifyFunctions.pointCancelSonify;
- Series.prototype.sonify = chartSonifyFunctions.seriesSonify;
- extend(Chart.prototype, {
- sonify: chartSonifyFunctions.chartSonify,
- pauseSonify: chartSonifyFunctions.pause,
- resumeSonify: chartSonifyFunctions.resume,
- rewindSonify: chartSonifyFunctions.rewind,
- cancelSonify: chartSonifyFunctions.cancel,
- getCurrentSonifyPoints: chartSonifyFunctions.getCurrentPoints,
- setSonifyCursor: chartSonifyFunctions.setCursor,
- resetSonifyCursor: chartSonifyFunctions.resetCursor,
- resetSonifyCursorEnd: chartSonifyFunctions.resetCursorEnd
- });
-
-
- addEvent(Chart, 'init', function () {
- this.sonification = {};
- });
-
- addEvent(Chart, 'update', function (e) {
- var newOptions = e.options.sonification;
- if (newOptions) {
- merge(true, this.options.sonification, newOptions);
- }
- });
- });
- _registerModule(_modules, 'masters/modules/sonification.src.js', [], function () {
- });
- }));
|