Carga
Carga
This commit is contained in:
@@ -0,0 +1,391 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2009-2021 Øystein Moseng
|
||||
*
|
||||
* Code for sonifying single points.
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
import Instrument from './Instrument.js';
|
||||
import U from '../../Core/Utilities.js';
|
||||
var error = U.error, merge = U.merge, pick = U.pick;
|
||||
import SU from './SonificationUtilities.js';
|
||||
/* *
|
||||
*
|
||||
* Constants
|
||||
*
|
||||
* */
|
||||
var composedClasses = [];
|
||||
// Defaults for the instrument options
|
||||
// NOTE: Also change defaults in Highcharts.PointInstrumentOptionsObject if
|
||||
// making changes here.
|
||||
var defaultInstrumentOptions = {
|
||||
minDuration: 20,
|
||||
maxDuration: 2000,
|
||||
minVolume: 0.1,
|
||||
maxVolume: 1,
|
||||
minPan: -1,
|
||||
maxPan: 1,
|
||||
minFrequency: 220,
|
||||
maxFrequency: 2200
|
||||
};
|
||||
/* eslint-disable valid-jsdoc */
|
||||
/* *
|
||||
*
|
||||
* Composition
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
var PointSonify;
|
||||
(function (PointSonify) {
|
||||
/* *
|
||||
*
|
||||
* Declarations
|
||||
*
|
||||
* */
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Extends the axis with ordinal support.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param PointClass
|
||||
* Point class to extend.
|
||||
*/
|
||||
function compose(PointClass) {
|
||||
if (composedClasses.indexOf(PointClass) === -1) {
|
||||
composedClasses.push(PointClass);
|
||||
var pointProto = PointClass.prototype;
|
||||
pointProto.sonify = pointSonify;
|
||||
pointProto.cancelSonify = pointCancelSonify;
|
||||
}
|
||||
return PointClass;
|
||||
}
|
||||
PointSonify.compose = compose;
|
||||
/**
|
||||
* Sonify a single point.
|
||||
*
|
||||
* @sample highcharts/sonification/point-basic/
|
||||
* Click on points to sonify
|
||||
* @sample highcharts/sonification/point-advanced/
|
||||
* Sonify bubbles
|
||||
*
|
||||
* @requires module:modules/sonification
|
||||
*
|
||||
* @function Highcharts.Point#sonify
|
||||
*
|
||||
* @param {Highcharts.PointSonifyOptionsObject} options
|
||||
* Options for the sonification of the point.
|
||||
*/
|
||||
function pointSonify(options) {
|
||||
var point = this, chart = point.series.chart, masterVolume = pick(options.masterVolume, chart.options.sonification &&
|
||||
chart.options.sonification.masterVolume), dataExtremes = options.dataExtremes || {},
|
||||
// Get the value to pass to instrument.play from the mapping value
|
||||
// passed in.
|
||||
getMappingValue = function (value, makeFunction, allowedExtremes) {
|
||||
// Function. Return new function if we try to use callback,
|
||||
// otherwise call it now and return result.
|
||||
if (typeof value === 'function') {
|
||||
return makeFunction ?
|
||||
function (time) {
|
||||
return value(point, dataExtremes, time);
|
||||
} :
|
||||
value(point, dataExtremes);
|
||||
}
|
||||
// String, this is a data prop. Potentially with negative
|
||||
// polarity.
|
||||
if (typeof value === 'string') {
|
||||
var hasInvertedPolarity = value.charAt(0) === '-';
|
||||
var dataProp = hasInvertedPolarity ?
|
||||
value.slice(1) : value;
|
||||
var pointValue = pick(point[dataProp], point.options[dataProp]);
|
||||
// Find data extremes if we don't have them
|
||||
dataExtremes[dataProp] = dataExtremes[dataProp] ||
|
||||
SU.calculateDataExtremes(point.series.chart, dataProp);
|
||||
// Find the value
|
||||
return SU.virtualAxisTranslate(pointValue, dataExtremes[dataProp], allowedExtremes, hasInvertedPolarity);
|
||||
}
|
||||
// Fixed number or something else weird, just use that
|
||||
return value;
|
||||
};
|
||||
// Register playing point on chart
|
||||
chart.sonification.currentlyPlayingPoint = point;
|
||||
// Keep track of instruments playing
|
||||
point.sonification = point.sonification || {};
|
||||
point.sonification.instrumentsPlaying =
|
||||
point.sonification.instrumentsPlaying || {};
|
||||
// Register signal handler for the point
|
||||
var signalHandler = point.sonification.signalHandler =
|
||||
point.sonification.signalHandler ||
|
||||
new SU.SignalHandler(['onEnd']);
|
||||
signalHandler.clearSignalCallbacks();
|
||||
signalHandler.registerSignalCallbacks({ onEnd: options.onEnd });
|
||||
// If we have a null point or invisible point, just return
|
||||
if (point.isNull || !point.visible || !point.series.visible) {
|
||||
signalHandler.emitSignal('onEnd');
|
||||
return;
|
||||
}
|
||||
// Go through instruments and play them
|
||||
options.instruments.forEach(function (instrumentDefinition) {
|
||||
var instrument = (typeof instrumentDefinition.instrument === 'string') ?
|
||||
Instrument.definitions[instrumentDefinition.instrument] :
|
||||
instrumentDefinition.instrument, mapping = instrumentDefinition.instrumentMapping || {}, extremes = merge(defaultInstrumentOptions, instrumentDefinition.instrumentOptions), id = instrument.id, onEnd = function (cancelled) {
|
||||
// Instrument on end
|
||||
if (instrumentDefinition.onEnd) {
|
||||
instrumentDefinition.onEnd.apply(this, arguments);
|
||||
}
|
||||
// Remove currently playing point reference on chart
|
||||
if (chart.sonification &&
|
||||
chart.sonification.currentlyPlayingPoint) {
|
||||
delete chart.sonification.currentlyPlayingPoint;
|
||||
}
|
||||
// Remove reference from instruments playing
|
||||
if (point.sonification &&
|
||||
point.sonification.instrumentsPlaying) {
|
||||
delete point.sonification.instrumentsPlaying[id];
|
||||
// This was the last instrument?
|
||||
if (!Object.keys(point.sonification.instrumentsPlaying).length) {
|
||||
signalHandler.emitSignal('onEnd', cancelled);
|
||||
}
|
||||
}
|
||||
};
|
||||
// Play the note on the instrument
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Cancel sonification of a point. Calls onEnd functions.
|
||||
*
|
||||
* @requires module:modules/sonification
|
||||
*
|
||||
* @function Highcharts.Point#cancelSonify
|
||||
*
|
||||
* @param {boolean} [fadeOut=false]
|
||||
* Whether or not to fade out as we stop. If false, the points are
|
||||
* cancelled synchronously.
|
||||
*
|
||||
*/
|
||||
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');
|
||||
}
|
||||
}
|
||||
})(PointSonify || (PointSonify = {}));
|
||||
/* *
|
||||
*
|
||||
* Default Export
|
||||
*
|
||||
* */
|
||||
export default PointSonify;
|
||||
/* *
|
||||
*
|
||||
* API Declarations
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Define the parameter mapping for an instrument.
|
||||
*
|
||||
* @requires module:modules/sonification
|
||||
*
|
||||
* @interface Highcharts.PointInstrumentMappingObject
|
||||
*/ /**
|
||||
* Define the volume of the instrument. This can be a string with a data
|
||||
* property name, e.g. `'y'`, in which case this data property is used to define
|
||||
* the volume relative to the `y`-values of the other points. A higher `y` value
|
||||
* would then result in a higher volume. Alternatively, `'-y'` can be used,
|
||||
* which inverts the polarity, so that a higher `y` value results in a lower
|
||||
* volume. This option can also be a fixed number or a function. If it is a
|
||||
* function, this function is called in regular intervals while the note is
|
||||
* playing. It receives three arguments: The point, the dataExtremes, and the
|
||||
* current relative time - where 0 is the beginning of the note and 1 is the
|
||||
* end. The function should return the volume of the note as a number between
|
||||
* 0 and 1.
|
||||
* @name Highcharts.PointInstrumentMappingObject#volume
|
||||
* @type {string|number|Function}
|
||||
*/ /**
|
||||
* Define the duration of the notes for this instrument. This can be a string
|
||||
* with a data property name, e.g. `'y'`, in which case this data property is
|
||||
* used to define the duration relative to the `y`-values of the other points. A
|
||||
* higher `y` value would then result in a longer duration. Alternatively,
|
||||
* `'-y'` can be used, in which case the polarity is inverted, and a higher
|
||||
* `y` value would result in a shorter duration. This option can also be a
|
||||
* fixed number or a function. If it is a function, this function is called
|
||||
* once before the note starts playing, and should return the duration in
|
||||
* milliseconds. It receives two arguments: The point, and the dataExtremes.
|
||||
* @name Highcharts.PointInstrumentMappingObject#duration
|
||||
* @type {string|number|Function}
|
||||
*/ /**
|
||||
* Define the panning of the instrument. This can be a string with a data
|
||||
* property name, e.g. `'x'`, in which case this data property is used to define
|
||||
* the panning relative to the `x`-values of the other points. A higher `x`
|
||||
* value would then result in a higher panning value (panned further to the
|
||||
* right). Alternatively, `'-x'` can be used, in which case the polarity is
|
||||
* inverted, and a higher `x` value would result in a lower panning value
|
||||
* (panned further to the left). This option can also be a fixed number or a
|
||||
* function. If it is a function, this function is called in regular intervals
|
||||
* while the note is playing. It receives three arguments: The point, the
|
||||
* dataExtremes, and the current relative time - where 0 is the beginning of
|
||||
* the note and 1 is the end. The function should return the panning of the
|
||||
* note as a number between -1 and 1.
|
||||
* @name Highcharts.PointInstrumentMappingObject#pan
|
||||
* @type {string|number|Function|undefined}
|
||||
*/ /**
|
||||
* Define the frequency of the instrument. This can be a string with a data
|
||||
* property name, e.g. `'y'`, in which case this data property is used to define
|
||||
* the frequency relative to the `y`-values of the other points. A higher `y`
|
||||
* value would then result in a higher frequency. Alternatively, `'-y'` can be
|
||||
* used, in which case the polarity is inverted, and a higher `y` value would
|
||||
* result in a lower frequency. This option can also be a fixed number or a
|
||||
* function. If it is a function, this function is called in regular intervals
|
||||
* while the note is playing. It receives three arguments: The point, the
|
||||
* dataExtremes, and the current relative time - where 0 is the beginning of
|
||||
* the note and 1 is the end. The function should return the frequency of the
|
||||
* note as a number (in Hz).
|
||||
* @name Highcharts.PointInstrumentMappingObject#frequency
|
||||
* @type {string|number|Function}
|
||||
*/
|
||||
/**
|
||||
* @requires module:modules/sonification
|
||||
*
|
||||
* @interface Highcharts.PointInstrumentOptionsObject
|
||||
*/ /**
|
||||
* The minimum duration for a note when using a data property for duration. Can
|
||||
* be overridden by using either a fixed number or a function for
|
||||
* instrumentMapping.duration. Defaults to 20.
|
||||
* @name Highcharts.PointInstrumentOptionsObject#minDuration
|
||||
* @type {number|undefined}
|
||||
*/ /**
|
||||
* The maximum duration for a note when using a data property for duration. Can
|
||||
* be overridden by using either a fixed number or a function for
|
||||
* instrumentMapping.duration. Defaults to 2000.
|
||||
* @name Highcharts.PointInstrumentOptionsObject#maxDuration
|
||||
* @type {number|undefined}
|
||||
*/ /**
|
||||
* The minimum pan value for a note when using a data property for panning. Can
|
||||
* be overridden by using either a fixed number or a function for
|
||||
* instrumentMapping.pan. Defaults to -1 (fully left).
|
||||
* @name Highcharts.PointInstrumentOptionsObject#minPan
|
||||
* @type {number|undefined}
|
||||
*/ /**
|
||||
* The maximum pan value for a note when using a data property for panning. Can
|
||||
* be overridden by using either a fixed number or a function for
|
||||
* instrumentMapping.pan. Defaults to 1 (fully right).
|
||||
* @name Highcharts.PointInstrumentOptionsObject#maxPan
|
||||
* @type {number|undefined}
|
||||
*/ /**
|
||||
* The minimum volume for a note when using a data property for volume. Can be
|
||||
* overridden by using either a fixed number or a function for
|
||||
* instrumentMapping.volume. Defaults to 0.1.
|
||||
* @name Highcharts.PointInstrumentOptionsObject#minVolume
|
||||
* @type {number|undefined}
|
||||
*/ /**
|
||||
* The maximum volume for a note when using a data property for volume. Can be
|
||||
* overridden by using either a fixed number or a function for
|
||||
* instrumentMapping.volume. Defaults to 1.
|
||||
* @name Highcharts.PointInstrumentOptionsObject#maxVolume
|
||||
* @type {number|undefined}
|
||||
*/ /**
|
||||
* The minimum frequency for a note when using a data property for frequency.
|
||||
* Can be overridden by using either a fixed number or a function for
|
||||
* instrumentMapping.frequency. Defaults to 220.
|
||||
* @name Highcharts.PointInstrumentOptionsObject#minFrequency
|
||||
* @type {number|undefined}
|
||||
*/ /**
|
||||
* The maximum frequency for a note when using a data property for frequency.
|
||||
* Can be overridden by using either a fixed number or a function for
|
||||
* instrumentMapping.frequency. Defaults to 2200.
|
||||
* @name Highcharts.PointInstrumentOptionsObject#maxFrequency
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
/**
|
||||
* An instrument definition for a point, specifying the instrument to play and
|
||||
* how to play it.
|
||||
*
|
||||
* @interface Highcharts.PointInstrumentObject
|
||||
*/ /**
|
||||
* An Instrument instance or the name of the instrument in the
|
||||
* Highcharts.sonification.instruments map.
|
||||
* @name Highcharts.PointInstrumentObject#instrument
|
||||
* @type {Highcharts.Instrument|string}
|
||||
*/ /**
|
||||
* Mapping of instrument parameters for this instrument.
|
||||
* @name Highcharts.PointInstrumentObject#instrumentMapping
|
||||
* @type {Highcharts.PointInstrumentMappingObject}
|
||||
*/ /**
|
||||
* Options for this instrument.
|
||||
* @name Highcharts.PointInstrumentObject#instrumentOptions
|
||||
* @type {Highcharts.PointInstrumentOptionsObject|undefined}
|
||||
*/ /**
|
||||
* Callback to call when the instrument has stopped playing.
|
||||
* @name Highcharts.PointInstrumentObject#onEnd
|
||||
* @type {Function|undefined}
|
||||
*/
|
||||
/**
|
||||
* Options for sonifying a point.
|
||||
* @interface Highcharts.PointSonifyOptionsObject
|
||||
*/ /**
|
||||
* The instrument definitions for this point.
|
||||
* @name Highcharts.PointSonifyOptionsObject#instruments
|
||||
* @type {Array<Highcharts.PointInstrumentObject>}
|
||||
*/ /**
|
||||
* Optionally provide the minimum/maximum values for the points. If this is not
|
||||
* supplied, it is calculated from the points in the chart on demand. This
|
||||
* option is supplied in the following format, as a map of point data properties
|
||||
* to objects with min/max values:
|
||||
* ```js
|
||||
* dataExtremes: {
|
||||
* y: {
|
||||
* min: 0,
|
||||
* max: 100
|
||||
* },
|
||||
* z: {
|
||||
* min: -10,
|
||||
* max: 10
|
||||
* }
|
||||
* // Properties used and not provided are calculated on demand
|
||||
* }
|
||||
* ```
|
||||
* @name Highcharts.PointSonifyOptionsObject#dataExtremes
|
||||
* @type {object|undefined}
|
||||
*/ /**
|
||||
* Callback called when the sonification has finished.
|
||||
* @name Highcharts.PointSonifyOptionsObject#onEnd
|
||||
* @type {Function|undefined}
|
||||
*/
|
||||
(''); // detach doclets above
|
||||
Reference in New Issue
Block a user