Carga
Carga
This commit is contained in:
488
static/lib/Highcharts-10.2.1/es-modules/Data/DataConverter.js
Normal file
488
static/lib/Highcharts-10.2.1/es-modules/Data/DataConverter.js
Normal file
@@ -0,0 +1,488 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2012-2021 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Sophie Bremer
|
||||
* - Gøran Slettemark
|
||||
* - Torstein Hønsi
|
||||
* - Wojciech Chmiel
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
import U from './../Core/Utilities.js';
|
||||
var merge = U.merge, isNumber = U.isNumber;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Class to convert between common value types.
|
||||
*/
|
||||
var DataConverter = /** @class */ (function () {
|
||||
/* *
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructs an instance of the Data Converter.
|
||||
*
|
||||
* @param {DataConverter.Options} [options]
|
||||
* Options for the Data Converter.
|
||||
*
|
||||
* @param {DataConverter.ParseDateCallbackFunction} [parseDate]
|
||||
* A function to parse string representations of dates
|
||||
* into JavaScript timestamps.
|
||||
*/
|
||||
function DataConverter(options, parseDate) {
|
||||
/**
|
||||
* A collection of available date formats.
|
||||
*
|
||||
* @name Highcharts.Data#dateFormats
|
||||
* @type {Highcharts.Dictionary<Highcharts.DataDateFormatObject>}
|
||||
*/
|
||||
this.dateFormats = {
|
||||
'YYYY/mm/dd': {
|
||||
regex: /^([0-9]{4})[\-\/\.]([0-9]{1,2})[\-\/\.]([0-9]{1,2})$/,
|
||||
parser: function (match) {
|
||||
return (match ?
|
||||
Date.UTC(+match[1], match[2] - 1, +match[3]) :
|
||||
NaN);
|
||||
}
|
||||
},
|
||||
'dd/mm/YYYY': {
|
||||
regex: /^([0-9]{1,2})[\-\/\.]([0-9]{1,2})[\-\/\.]([0-9]{4})$/,
|
||||
parser: function (match) {
|
||||
return (match ?
|
||||
Date.UTC(+match[3], match[2] - 1, +match[1]) :
|
||||
NaN);
|
||||
},
|
||||
alternative: 'mm/dd/YYYY' // different format with the same regex
|
||||
},
|
||||
'mm/dd/YYYY': {
|
||||
regex: /^([0-9]{1,2})[\-\/\.]([0-9]{1,2})[\-\/\.]([0-9]{4})$/,
|
||||
parser: function (match) {
|
||||
return (match ?
|
||||
Date.UTC(+match[3], match[1] - 1, +match[2]) :
|
||||
NaN);
|
||||
}
|
||||
},
|
||||
'dd/mm/YY': {
|
||||
regex: /^([0-9]{1,2})[\-\/\.]([0-9]{1,2})[\-\/\.]([0-9]{2})$/,
|
||||
parser: function (match) {
|
||||
var d = new Date();
|
||||
if (!match) {
|
||||
return NaN;
|
||||
}
|
||||
var year = +match[3];
|
||||
if (year > (d.getFullYear() - 2000)) {
|
||||
year += 1900;
|
||||
}
|
||||
else {
|
||||
year += 2000;
|
||||
}
|
||||
return Date.UTC(year, match[2] - 1, +match[1]);
|
||||
},
|
||||
alternative: 'mm/dd/YY' // different format with the same regex
|
||||
},
|
||||
'mm/dd/YY': {
|
||||
regex: /^([0-9]{1,2})[\-\/\.]([0-9]{1,2})[\-\/\.]([0-9]{2})$/,
|
||||
parser: function (match) {
|
||||
return (match ?
|
||||
Date.UTC(+match[3] + 2000, match[1] - 1, +match[2]) :
|
||||
NaN);
|
||||
}
|
||||
}
|
||||
};
|
||||
var decimalPoint;
|
||||
this.options = merge(DataConverter.defaultOptions, options);
|
||||
this.parseDateFn = parseDate;
|
||||
decimalPoint = this.options.decimalPoint;
|
||||
if (decimalPoint !== '.' && decimalPoint !== ',') {
|
||||
decimalPoint = void 0;
|
||||
}
|
||||
this.decimalRegex = (decimalPoint &&
|
||||
new RegExp('^(-?[0-9]+)' + decimalPoint + '([0-9]+)$'));
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Getter for a date format.
|
||||
*/
|
||||
DataConverter.prototype.getDateFormat = function () {
|
||||
return this.options.dateFormat;
|
||||
};
|
||||
/**
|
||||
* Converts a value to a boolean.
|
||||
*
|
||||
* @param {DataConverter.Type} value
|
||||
* Value to convert.
|
||||
*
|
||||
* @return {boolean}
|
||||
* Converted value as a boolean.
|
||||
*/
|
||||
DataConverter.prototype.asBoolean = function (value) {
|
||||
if (typeof value === 'boolean') {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
return value !== '' && value !== '0' && value !== 'false';
|
||||
}
|
||||
return !!this.asNumber(value);
|
||||
};
|
||||
/**
|
||||
* Converts a value to a Date.
|
||||
*
|
||||
* @param {DataConverter.Type} value
|
||||
* Value to convert.
|
||||
*
|
||||
* @return {globalThis.Date}
|
||||
* Converted value as a Date.
|
||||
*/
|
||||
DataConverter.prototype.asDate = function (value) {
|
||||
var timestamp;
|
||||
if (typeof value === 'string') {
|
||||
timestamp = this.parseDate(value);
|
||||
}
|
||||
else if (typeof value === 'number') {
|
||||
timestamp = value;
|
||||
}
|
||||
else if (value instanceof Date) {
|
||||
return value;
|
||||
}
|
||||
else {
|
||||
timestamp = this.parseDate(this.asString(value));
|
||||
}
|
||||
return new Date(timestamp);
|
||||
};
|
||||
/**
|
||||
* Converts a value to a number.
|
||||
*
|
||||
* @param {DataConverter.Type} value
|
||||
* Value to convert.
|
||||
*
|
||||
* @return {number}
|
||||
* Converted value as a number.
|
||||
*/
|
||||
DataConverter.prototype.asNumber = function (value) {
|
||||
if (typeof value === 'number') {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === 'boolean') {
|
||||
return value ? 1 : 0;
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
if (value.indexOf(' ') > -1) {
|
||||
value = value.replace(/\s+/g, '');
|
||||
}
|
||||
if (this.decimalRegex) {
|
||||
value = value.replace(this.decimalRegex, '$1.$2');
|
||||
}
|
||||
return parseFloat(value);
|
||||
}
|
||||
if (value instanceof Date) {
|
||||
return value.getDate();
|
||||
}
|
||||
if (value) {
|
||||
return value.getRowCount();
|
||||
}
|
||||
return NaN;
|
||||
};
|
||||
/**
|
||||
* Converts a value to a string.
|
||||
*
|
||||
* @param {DataConverter.Type} value
|
||||
* Value to convert.
|
||||
*
|
||||
* @return {string}
|
||||
* Converted value as a string.
|
||||
*/
|
||||
DataConverter.prototype.asString = function (value) {
|
||||
return "".concat(value);
|
||||
};
|
||||
/**
|
||||
* Trim a string from whitespaces.
|
||||
*
|
||||
* @param {string} str
|
||||
* String to trim.
|
||||
*
|
||||
* @param {boolean} [inside=false]
|
||||
* Remove all spaces between numbers.
|
||||
*
|
||||
* @return {string}
|
||||
* Trimed string
|
||||
*/
|
||||
DataConverter.prototype.trim = function (str, inside) {
|
||||
var converter = this;
|
||||
if (typeof str === 'string') {
|
||||
str = str.replace(/^\s+|\s+$/g, '');
|
||||
// Clear white space insdie the string, like thousands separators
|
||||
if (inside && /^[0-9\s]+$/.test(str)) {
|
||||
str = str.replace(/\s/g, '');
|
||||
}
|
||||
if (converter.decimalRegex) {
|
||||
str = str.replace(converter.decimalRegex, '$1.$2');
|
||||
}
|
||||
}
|
||||
return str;
|
||||
};
|
||||
/**
|
||||
* Guesses the potential type of a string value
|
||||
* (for parsing CSV etc)
|
||||
*
|
||||
* @param {string} value
|
||||
* The string to examine
|
||||
* @return {'number'|'string'|'Date'}
|
||||
* `string`, `Date` or `number`
|
||||
*/
|
||||
DataConverter.prototype.guessType = function (value) {
|
||||
var converter = this, trimVal = converter.trim(value), trimInsideVal = converter.trim(value, true), floatVal = parseFloat(trimInsideVal);
|
||||
var result = 'string', dateVal;
|
||||
// is numeric
|
||||
if (+trimInsideVal === floatVal) {
|
||||
// If the number is greater than milliseconds in a year, assume
|
||||
// datetime.
|
||||
if (floatVal > 365 * 24 * 3600 * 1000) {
|
||||
result = 'Date';
|
||||
}
|
||||
else {
|
||||
result = 'number';
|
||||
}
|
||||
// String, continue to determine if it is
|
||||
// a date string or really a string.
|
||||
}
|
||||
else {
|
||||
if (trimVal && trimVal.length) {
|
||||
dateVal = converter.parseDate(value);
|
||||
}
|
||||
if (dateVal && isNumber(dateVal)) {
|
||||
result = 'Date';
|
||||
}
|
||||
else {
|
||||
result = 'string';
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
/**
|
||||
* Casts a string value to it's guessed type
|
||||
* @param {string} value
|
||||
* The string to examine
|
||||
*
|
||||
* @return {number|string|Date}
|
||||
* The converted value
|
||||
*/
|
||||
DataConverter.prototype.asGuessedType = function (value) {
|
||||
var converter = this, typeMap = {
|
||||
'number': converter.asNumber,
|
||||
'Date': converter.asDate,
|
||||
'string': converter.asString
|
||||
};
|
||||
return typeMap[converter.guessType(value)].call(converter, value);
|
||||
};
|
||||
/**
|
||||
* Parse a date and return it as a number.
|
||||
*
|
||||
* @function Highcharts.Data#parseDate
|
||||
*
|
||||
* @param {string} value
|
||||
* Value to parse.
|
||||
*
|
||||
* @param {string} dateFormatProp
|
||||
* Which of the predefined date formats
|
||||
* to use to parse date values.
|
||||
*/
|
||||
DataConverter.prototype.parseDate = function (value, dateFormatProp) {
|
||||
var converter = this;
|
||||
var dateFormat = dateFormatProp || converter.options.dateFormat, result = NaN, key, format, match;
|
||||
if (converter.parseDateFn) {
|
||||
result = converter.parseDateFn(value);
|
||||
}
|
||||
else {
|
||||
// Auto-detect the date format the first time
|
||||
if (!dateFormat) {
|
||||
for (key in converter.dateFormats) { // eslint-disable-line guard-for-in
|
||||
format = converter.dateFormats[key];
|
||||
match = value.match(format.regex);
|
||||
if (match) {
|
||||
// converter.options.dateFormat = dateFormat = key;
|
||||
dateFormat = key;
|
||||
// converter.options.alternativeFormat =
|
||||
// format.alternative || '';
|
||||
result = format.parser(match);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Next time, use the one previously found
|
||||
}
|
||||
else {
|
||||
format = converter.dateFormats[dateFormat];
|
||||
if (!format) {
|
||||
// The selected format is invalid
|
||||
format = converter.dateFormats['YYYY/mm/dd'];
|
||||
}
|
||||
match = value.match(format.regex);
|
||||
if (match) {
|
||||
result = format.parser(match);
|
||||
}
|
||||
}
|
||||
// Fall back to Date.parse
|
||||
if (!match) {
|
||||
match = Date.parse(value);
|
||||
// External tools like Date.js and MooTools extend Date object
|
||||
// and returns a date.
|
||||
if (typeof match === 'object' &&
|
||||
match !== null &&
|
||||
match.getTime) {
|
||||
result = (match.getTime() -
|
||||
match.getTimezoneOffset() *
|
||||
60000);
|
||||
// Timestamp
|
||||
}
|
||||
else if (isNumber(match)) {
|
||||
result = match - (new Date(match)).getTimezoneOffset() * 60000;
|
||||
if ( // reset dates without year in Chrome
|
||||
value.indexOf('2001') === -1 &&
|
||||
(new Date(result)).getFullYear() === 2001) {
|
||||
result = NaN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
/**
|
||||
* Tries to guess the date format
|
||||
* - Check if either month candidate exceeds 12
|
||||
* - Check if year is missing (use current year)
|
||||
* - Check if a shortened year format is used (e.g. 1/1/99)
|
||||
* - If no guess can be made, the user must be prompted
|
||||
* data is the data to deduce a format based on
|
||||
* @private
|
||||
*
|
||||
* @param {Array<string>} data
|
||||
* Data to check the format.
|
||||
*
|
||||
* @param {number} limit
|
||||
* Max data to check the format.
|
||||
*
|
||||
* @param {boolean} save
|
||||
* Whether to save the date format in the converter options.
|
||||
*/
|
||||
DataConverter.prototype.deduceDateFormat = function (data, limit, save) {
|
||||
var parser = this, stable = [], max = [];
|
||||
var format = 'YYYY/mm/dd', thing, guessedFormat = [], i = 0, madeDeduction = false,
|
||||
// candidates = {},
|
||||
elem, j;
|
||||
if (!limit || limit > data.length) {
|
||||
limit = data.length;
|
||||
}
|
||||
for (; i < limit; i++) {
|
||||
if (typeof data[i] !== 'undefined' &&
|
||||
data[i] && data[i].length) {
|
||||
thing = data[i]
|
||||
.trim()
|
||||
.replace(/\//g, ' ')
|
||||
.replace(/\-/g, ' ')
|
||||
.replace(/\./g, ' ')
|
||||
.split(' ');
|
||||
guessedFormat = [
|
||||
'',
|
||||
'',
|
||||
''
|
||||
];
|
||||
for (j = 0; j < thing.length; j++) {
|
||||
if (j < guessedFormat.length) {
|
||||
elem = parseInt(thing[j], 10);
|
||||
if (elem) {
|
||||
max[j] = (!max[j] || max[j] < elem) ? elem : max[j];
|
||||
if (typeof stable[j] !== 'undefined') {
|
||||
if (stable[j] !== elem) {
|
||||
stable[j] = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
stable[j] = elem;
|
||||
}
|
||||
if (elem > 31) {
|
||||
if (elem < 100) {
|
||||
guessedFormat[j] = 'YY';
|
||||
}
|
||||
else {
|
||||
guessedFormat[j] = 'YYYY';
|
||||
}
|
||||
// madeDeduction = true;
|
||||
}
|
||||
else if (elem > 12 &&
|
||||
elem <= 31) {
|
||||
guessedFormat[j] = 'dd';
|
||||
madeDeduction = true;
|
||||
}
|
||||
else if (!guessedFormat[j].length) {
|
||||
guessedFormat[j] = 'mm';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (madeDeduction) {
|
||||
// This handles a few edge cases with hard to guess dates
|
||||
for (j = 0; j < stable.length; j++) {
|
||||
if (stable[j] !== false) {
|
||||
if (max[j] > 12 &&
|
||||
guessedFormat[j] !== 'YY' &&
|
||||
guessedFormat[j] !== 'YYYY') {
|
||||
guessedFormat[j] = 'YY';
|
||||
}
|
||||
}
|
||||
else if (max[j] > 12 && guessedFormat[j] === 'mm') {
|
||||
guessedFormat[j] = 'dd';
|
||||
}
|
||||
}
|
||||
// If the middle one is dd, and the last one is dd,
|
||||
// the last should likely be year.
|
||||
if (guessedFormat.length === 3 &&
|
||||
guessedFormat[1] === 'dd' &&
|
||||
guessedFormat[2] === 'dd') {
|
||||
guessedFormat[2] = 'YY';
|
||||
}
|
||||
format = guessedFormat.join('/');
|
||||
// If the caculated format is not valid, we need to present an
|
||||
// error.
|
||||
}
|
||||
// Save the deduced format in the converter options.
|
||||
if (save) {
|
||||
parser.options.dateFormat = format;
|
||||
}
|
||||
return format;
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Default options
|
||||
*/
|
||||
DataConverter.defaultOptions = {
|
||||
dateFormat: '',
|
||||
alternativeFormat: ''
|
||||
};
|
||||
return DataConverter;
|
||||
}());
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default DataConverter;
|
||||
252
static/lib/Highcharts-10.2.1/es-modules/Data/DataPromise.js
Normal file
252
static/lib/Highcharts-10.2.1/es-modules/Data/DataPromise.js
Normal file
@@ -0,0 +1,252 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2020-2022 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Sophie Bremer
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
/* *
|
||||
*
|
||||
* Imports
|
||||
*
|
||||
* */
|
||||
import H from '../Core/Globals.js';
|
||||
/* *
|
||||
*
|
||||
* Constants
|
||||
*
|
||||
* */
|
||||
var win = H.win;
|
||||
var delay = setTimeout;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Simplified wrapper for Promise-support in outdated browsers.
|
||||
*/
|
||||
var DataPromise = /** @class */ (function () {
|
||||
/* *
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* */
|
||||
function DataPromise(executor) {
|
||||
/* *
|
||||
*
|
||||
* Properties
|
||||
*
|
||||
* */
|
||||
this.jobs = [];
|
||||
this.state = DataPromise.State.Pending;
|
||||
this.value = void 0;
|
||||
if (win.Promise && !DataPromise.onlyPolyfill) {
|
||||
return new win.Promise(executor);
|
||||
}
|
||||
var promise = this;
|
||||
delay(function () {
|
||||
try {
|
||||
executor(function (value) { return promise.resolved(value); }, function (reason) { return promise.rejected(reason); });
|
||||
}
|
||||
catch (e) {
|
||||
promise.rejected(e);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Static Functions
|
||||
*
|
||||
* */
|
||||
DataPromise.isPromiseLike = function (promise) {
|
||||
return (typeof promise === 'object' &&
|
||||
promise !== null &&
|
||||
typeof promise.then === 'function');
|
||||
};
|
||||
DataPromise.reject = function (reason) {
|
||||
if (win.Promise && !DataPromise.onlyPolyfill) {
|
||||
return win.Promise.reject(reason);
|
||||
}
|
||||
return new DataPromise(function (resolve, reject) { return reject(reason); });
|
||||
};
|
||||
DataPromise.resolve = function (value) {
|
||||
if (win.Promise && !DataPromise.onlyPolyfill) {
|
||||
return win.Promise.resolve(value);
|
||||
}
|
||||
if (DataPromise.isPromiseLike(value)) {
|
||||
return new DataPromise(function (resolve, reject) {
|
||||
value.then(resolve, reject);
|
||||
});
|
||||
}
|
||||
return new DataPromise(function (resolve) { return resolve(value); });
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
DataPromise.prototype['catch'] = function (onrejected) {
|
||||
return this.then(null, onrejected);
|
||||
};
|
||||
DataPromise.prototype.rejected = function (reason) {
|
||||
var promise = this;
|
||||
if (promise.state === DataPromise.State.Pending) {
|
||||
promise.state = DataPromise.State.Rejected;
|
||||
promise.reason = reason;
|
||||
delay(function () { return promise.work(); }, 0);
|
||||
}
|
||||
};
|
||||
DataPromise.prototype.resolved = function (value) {
|
||||
var promise = this;
|
||||
if (promise.state === DataPromise.State.Pending) {
|
||||
if (DataPromise.isPromiseLike(value)) {
|
||||
value.then(function (value) { return promise.resolved(value); }, function (reason) { return promise.rejected(reason); });
|
||||
}
|
||||
else {
|
||||
promise.state = DataPromise.State.Fulfilled;
|
||||
promise.value = value;
|
||||
delay(function () { return promise.work(); }, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
DataPromise.prototype.then = function (onfulfilled, onrejected) {
|
||||
var promise = this, newPromise = new DataPromise(function () { return void 0; }), rejecter = function (reason) {
|
||||
if (onrejected) {
|
||||
try {
|
||||
var result = onrejected(reason);
|
||||
if (result instanceof DataPromise) {
|
||||
result.then(function (value) {
|
||||
return newPromise.resolved(value);
|
||||
}, function (reason) {
|
||||
return newPromise.rejected(reason);
|
||||
});
|
||||
}
|
||||
else {
|
||||
newPromise.resolved(result);
|
||||
}
|
||||
return;
|
||||
}
|
||||
catch (e) {
|
||||
reason = e;
|
||||
}
|
||||
}
|
||||
if (newPromise.jobs.length) {
|
||||
newPromise.rejected(reason);
|
||||
}
|
||||
else if (reason) {
|
||||
throw reason;
|
||||
}
|
||||
else {
|
||||
throw new Error('Unhandled exception');
|
||||
}
|
||||
}, resolver = function (value) {
|
||||
if (onfulfilled) {
|
||||
try {
|
||||
var result = onfulfilled(value);
|
||||
if (result instanceof DataPromise) {
|
||||
result.then(function (value) {
|
||||
return newPromise.resolved(value);
|
||||
}, function (reason) {
|
||||
return newPromise.rejected(reason);
|
||||
});
|
||||
}
|
||||
else {
|
||||
newPromise.resolved(result);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
rejecter(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
newPromise.resolved(value);
|
||||
}
|
||||
};
|
||||
switch (promise.state) {
|
||||
case DataPromise.State.Fulfilled:
|
||||
resolver(promise.value);
|
||||
break;
|
||||
case DataPromise.State.Rejected:
|
||||
rejecter(promise.reason);
|
||||
break;
|
||||
default:
|
||||
promise.jobs.push({
|
||||
resolve: resolver,
|
||||
reject: rejecter
|
||||
});
|
||||
break;
|
||||
}
|
||||
return newPromise;
|
||||
};
|
||||
DataPromise.prototype.work = function () {
|
||||
var promise = this, jobs = promise.jobs;
|
||||
var job, rejectHandled;
|
||||
while ((job = jobs.shift())) {
|
||||
try {
|
||||
if (promise.state === DataPromise.State.Fulfilled) {
|
||||
job.resolve(promise.value);
|
||||
}
|
||||
else if (job.reject) {
|
||||
rejectHandled = true;
|
||||
job.reject(promise.reason);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
rejectHandled = false;
|
||||
promise.reason = e;
|
||||
promise.state = DataPromise.State.Rejected;
|
||||
}
|
||||
}
|
||||
if (rejectHandled === false) {
|
||||
if (promise.reason) {
|
||||
throw promise.reason;
|
||||
}
|
||||
else {
|
||||
throw new Error('Unhandled rejection');
|
||||
}
|
||||
}
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
DataPromise.onlyPolyfill = false;
|
||||
return DataPromise;
|
||||
}());
|
||||
/* *
|
||||
*
|
||||
* Class Namespace
|
||||
*
|
||||
* */
|
||||
(function (DataPromise) {
|
||||
/* *
|
||||
*
|
||||
* Declarations
|
||||
*
|
||||
* */
|
||||
/* *
|
||||
*
|
||||
* Enumerations
|
||||
*
|
||||
* */
|
||||
var State;
|
||||
(function (State) {
|
||||
State[State["Fulfilled"] = 2] = "Fulfilled";
|
||||
State[State["Pending"] = 0] = "Pending";
|
||||
State[State["Rejected"] = 1] = "Rejected";
|
||||
})(State = DataPromise.State || (DataPromise.State = {}));
|
||||
})(DataPromise || (DataPromise = {}));
|
||||
/* *
|
||||
*
|
||||
* Default Export
|
||||
*
|
||||
* */
|
||||
export default DataPromise;
|
||||
@@ -0,0 +1,288 @@
|
||||
/* *
|
||||
*
|
||||
* Imports
|
||||
*
|
||||
* */
|
||||
import DataTable from './DataTable.js';
|
||||
import U from '../Core/Utilities.js';
|
||||
var addEvent = U.addEvent, fireEvent = U.fireEvent, isNumber = U.isNumber, merge = U.merge, wrap = U.wrap;
|
||||
/* *
|
||||
*
|
||||
* Constants
|
||||
*
|
||||
* */
|
||||
var composedClasses = [];
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function wrapSeriesGeneratePoints(proceed) {
|
||||
if (this.hasGroupedData) {
|
||||
return proceed.call(this);
|
||||
}
|
||||
var PointClass = this.pointClass, cropStart = this.cropStart || 0, data = this.data || [], points = [], processedXData = this.processedXData, processedYData = this.processedYData;
|
||||
var cursor, point;
|
||||
for (var i = 0, iEnd = processedXData.length; i < iEnd; ++i) {
|
||||
cursor = cropStart + i;
|
||||
point = data[cursor];
|
||||
if (!point) {
|
||||
point = data[cursor] = (new PointClass()).init(this, processedYData[cursor], processedXData[i]);
|
||||
}
|
||||
point.index = cursor;
|
||||
points[i] = point;
|
||||
}
|
||||
this.data = data;
|
||||
this.points = points;
|
||||
fireEvent(this, 'afterGeneratePoints');
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function wrapSeriesSetData(proceed, data, redraw, animation) {
|
||||
if (data === void 0) { data = []; }
|
||||
if (redraw === void 0) { redraw = true; }
|
||||
var datas = this.datas;
|
||||
if (this.hasGroupedData || !this.options.dataAsColumns) {
|
||||
return proceed.call(this, data, redraw, animation);
|
||||
}
|
||||
data = this.options.data = this.userOptions.data = (this.chart.options.chart.allowMutatingData ?
|
||||
(data || []) :
|
||||
merge(true, data));
|
||||
var columns = {}, keys = (this.options.keys || this.parallelArrays).slice();
|
||||
if (isNumber(data[0]) || keys.length === 1) {
|
||||
// first column is implicit index
|
||||
var xData = columns.x = [];
|
||||
for (var i = 0, iEnd = data.length; i < iEnd; ++i) {
|
||||
xData.push(this.autoIncrement());
|
||||
}
|
||||
columns[keys[1] || 'y'] = data;
|
||||
}
|
||||
else {
|
||||
if (keys.indexOf('x') === -1 && keys.length > data.length) {
|
||||
// first column is implicit index
|
||||
var xData = columns.x = [];
|
||||
for (var i = 0, iEnd = data.length; i < iEnd; ++i) {
|
||||
xData.push(this.autoIncrement());
|
||||
}
|
||||
}
|
||||
for (var i = 0, iEnd = Math.min(data.length, keys.length); i < iEnd; ++i) {
|
||||
if (data[i] instanceof Array) {
|
||||
columns[keys[i]] = data[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
datas.setTable(new DataTable(columns, this.name));
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
var DataSeriesAdditions = /** @class */ (function () {
|
||||
/* *
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* */
|
||||
function DataSeriesAdditions(series) {
|
||||
this.unlisteners = [];
|
||||
var columns = {}, keys = series.parallelArrays;
|
||||
for (var i = 0, iEnd = keys.length; i < iEnd; ++i) {
|
||||
columns[keys[i]] = [];
|
||||
}
|
||||
this.series = series;
|
||||
this.table = new DataTable();
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Static Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
DataSeriesAdditions.compose = function (SeriesClass) {
|
||||
if (composedClasses.indexOf(SeriesClass) === -1) {
|
||||
composedClasses.push(SeriesClass);
|
||||
addEvent(SeriesClass, 'init', function () {
|
||||
this.datas = new DataSeriesAdditions(this);
|
||||
});
|
||||
var seriesProto = SeriesClass.prototype;
|
||||
wrap(seriesProto, 'generatePoints', wrapSeriesGeneratePoints);
|
||||
wrap(seriesProto, 'setData', wrapSeriesSetData);
|
||||
}
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Triggers processing and redrawing
|
||||
* @private
|
||||
*/
|
||||
DataSeriesAdditions.prototype.processTable = function (redraw, animation) {
|
||||
var series = this.series;
|
||||
if (series.options.legendType === 'point') {
|
||||
series.processData();
|
||||
series.generatePoints();
|
||||
}
|
||||
if (redraw) {
|
||||
var chart = series.chart;
|
||||
series.isDirty = chart.isDirtyBox = true;
|
||||
series.isDirtyData = true;
|
||||
chart.redraw(animation);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Experimental integration of the data layer
|
||||
* @private
|
||||
*/
|
||||
DataSeriesAdditions.prototype.setTable = function (table, redraw, animation) {
|
||||
if (redraw === void 0) { redraw = true; }
|
||||
var series = this.series, anySeries = series, oldData = series.points, keys = series.parallelArrays, rowCount = table.getRowCount();
|
||||
var key;
|
||||
if (oldData) {
|
||||
var xAxis = series.xAxis;
|
||||
series.colorCounter = 0;
|
||||
series.data = [];
|
||||
delete anySeries.points;
|
||||
delete anySeries.processedXData;
|
||||
delete anySeries.processedYData;
|
||||
delete anySeries.xIncrement;
|
||||
for (var i = 0, iEnd = keys.length; i < iEnd; ++i) {
|
||||
key = keys[i];
|
||||
anySeries["".concat(key, "Data")] = [];
|
||||
}
|
||||
for (var i = 0, iEnd = oldData.length; i < iEnd; ++i) {
|
||||
if (oldData[i] && (oldData[i].destroy)) {
|
||||
oldData[i].destroy();
|
||||
}
|
||||
}
|
||||
if (xAxis) {
|
||||
xAxis.minRange = xAxis.userMinRange;
|
||||
}
|
||||
}
|
||||
var column, failure = false, indexAsX = false;
|
||||
for (var i = 0, iEnd = keys.length; i < iEnd; ++i) {
|
||||
key = keys[i];
|
||||
column = table.getColumn(key, true);
|
||||
if (!column) {
|
||||
if (key === 'x') {
|
||||
indexAsX = true;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
failure = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
anySeries["".concat(key, "Data")] = column;
|
||||
}
|
||||
if (failure) {
|
||||
// fallback to index
|
||||
var columnNames = table.getColumnNames(), emptyColumn = [];
|
||||
emptyColumn.length = rowCount;
|
||||
var columnOffset = 0;
|
||||
if (columnNames.length === keys.length - 1) {
|
||||
// table index becomes x
|
||||
columnOffset = 1;
|
||||
indexAsX = true;
|
||||
}
|
||||
for (var i = columnOffset, iEnd = keys.length; i < iEnd; ++i) {
|
||||
column = table.getColumn(columnNames[i], true);
|
||||
key = keys[i];
|
||||
anySeries["".concat(key, "Data")] = column || emptyColumn.slice();
|
||||
}
|
||||
}
|
||||
this.indexAsX = indexAsX;
|
||||
if (indexAsX && keys.indexOf('x') !== -1) {
|
||||
column = [];
|
||||
for (var x = 0; x < rowCount; ++x) {
|
||||
column.push(series.autoIncrement());
|
||||
}
|
||||
anySeries.xData = column;
|
||||
}
|
||||
this.syncOff();
|
||||
this.table = table;
|
||||
if (redraw) {
|
||||
this.syncOn();
|
||||
}
|
||||
this.processTable(redraw, oldData && animation);
|
||||
};
|
||||
/**
|
||||
* Stops synchronisation of table changes with series.
|
||||
* @private
|
||||
*/
|
||||
DataSeriesAdditions.prototype.syncOff = function () {
|
||||
var unlisteners = this.unlisteners;
|
||||
for (var i = 0, iEnd = unlisteners.length; i < iEnd; ++i) {
|
||||
unlisteners[i]();
|
||||
}
|
||||
unlisteners.length = 0;
|
||||
};
|
||||
/**
|
||||
* Activates synchronization of table changes with series.
|
||||
* @private
|
||||
*/
|
||||
DataSeriesAdditions.prototype.syncOn = function () {
|
||||
var _this = this;
|
||||
if (this.unlisteners.length) {
|
||||
return;
|
||||
}
|
||||
var series = this.series, table = this.table, anySeries = series, onChange = function (e) {
|
||||
if (e.type === 'afterDeleteColumns') {
|
||||
// deletion affects all points
|
||||
_this.setTable(table, true);
|
||||
return;
|
||||
}
|
||||
if (e.type === 'afterDeleteRows') {
|
||||
if (e.rowIndex > 0 &&
|
||||
e.rowIndex + e.rowCount < series.points.length) {
|
||||
// deletion affects trailing points
|
||||
_this.setTable(table, true);
|
||||
return;
|
||||
}
|
||||
for (var i = e.rowIndex, iEnd = i + e.rowCount; i < iEnd; ++i) {
|
||||
series.removePoint(i, false);
|
||||
}
|
||||
}
|
||||
if (_this.indexAsX) {
|
||||
if (e.type === 'afterSetCell') {
|
||||
anySeries.xData[e.rowIndex] = e.rowIndex;
|
||||
}
|
||||
else if (e.type === 'afterSetRows') {
|
||||
for (var i = e.rowIndex, iEnd = i + e.rowCount; i < iEnd; ++i) {
|
||||
anySeries.xData[i] = series.autoIncrement();
|
||||
}
|
||||
}
|
||||
}
|
||||
_this.processTable(true);
|
||||
};
|
||||
this.unlisteners.push(table.on('afterDeleteColumns', onChange), table.on('afterDeleteRows', onChange), table.on('afterSetCell', onChange), table.on('afterSetRows', onChange));
|
||||
};
|
||||
return DataSeriesAdditions;
|
||||
}());
|
||||
/* *
|
||||
*
|
||||
* Default Export
|
||||
*
|
||||
* */
|
||||
export default DataSeriesAdditions;
|
||||
/* *
|
||||
*
|
||||
* API Options
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Indicates data is structured as columns instead of rows.
|
||||
*
|
||||
* @type {boolean}
|
||||
* @requires es-modules/Data/DataSeriesComposition.js
|
||||
* @apioption plotOptions.series.dataAsColumns
|
||||
*/
|
||||
(''); // keeps doclets above in JS file
|
||||
@@ -0,0 +1,207 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2020-2022 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Sebastian Bochan
|
||||
* - Wojciech Chmiel
|
||||
* - Sophie Bremer
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
import DataTable from './DataTable.js';
|
||||
import U from '../Core/Utilities.js';
|
||||
var defined = U.defined, uniqueKey = U.uniqueKey;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Class to convert Highcharts series data to table and get series data from the
|
||||
* table.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var DataSeriesConverter = /** @class */ (function () {
|
||||
/* *
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructs an instance of the DataSeriesConverter class.
|
||||
*
|
||||
* @param {DataTable} [table]
|
||||
* DataSeriesConverter table to store series data.
|
||||
*
|
||||
* @param {DataSeriesConverter.Options} [options]
|
||||
* DataSeriesConverter options.
|
||||
*/
|
||||
function DataSeriesConverter(table, options) {
|
||||
if (table === void 0) { table = new DataTable(); }
|
||||
if (options === void 0) { options = {}; }
|
||||
this.table = table;
|
||||
this.options = options;
|
||||
this.seriesIdMap = {};
|
||||
this.seriesMeta = [];
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Get the specific series data stored in the converter.
|
||||
*
|
||||
* @param {string} seriesId
|
||||
* The id of the series.
|
||||
*
|
||||
* @return {Array<PointOptions>}
|
||||
* Returns an array of series points opitons.
|
||||
*/
|
||||
DataSeriesConverter.prototype.getSeriesData = function (seriesId) {
|
||||
var converter = this, table = converter.table, seriesData = [];
|
||||
var pointOptions, cellName, cell, isCellFound, pointArrayMap;
|
||||
if (seriesId) {
|
||||
pointArrayMap = converter.seriesIdMap[seriesId].pointArrayMap || ['y'];
|
||||
for (var i = 0, iEnd = table.getRowCount(); i < iEnd; i++) {
|
||||
isCellFound = false;
|
||||
pointOptions = {
|
||||
x: table.getCellAsNumber('x', i, true)
|
||||
};
|
||||
for (var j = 0, jEnd = pointArrayMap.length; j < jEnd; j++) {
|
||||
cellName = pointArrayMap[j] + '_' + seriesId;
|
||||
cell = table.getCell(cellName, i);
|
||||
if (typeof cell !== 'undefined') {
|
||||
isCellFound = true;
|
||||
pointOptions[pointArrayMap[j]] = table.getCellAsNumber(cellName, i);
|
||||
}
|
||||
}
|
||||
if (isCellFound) {
|
||||
seriesData.push(pointOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
return seriesData;
|
||||
};
|
||||
/**
|
||||
* Get all series data stored in the converter.
|
||||
*
|
||||
* @return {Array<SeriesOptions>}
|
||||
* Returns an array of series opitons.
|
||||
*/
|
||||
DataSeriesConverter.prototype.getAllSeriesData = function () {
|
||||
var converter = this, seriesOptions = [];
|
||||
var id;
|
||||
for (var i = 0, iEnd = converter.seriesMeta.length; i < iEnd; i++) {
|
||||
id = converter.seriesMeta[i].id;
|
||||
seriesOptions.push({
|
||||
id: id,
|
||||
data: converter.getSeriesData(id)
|
||||
});
|
||||
}
|
||||
return seriesOptions;
|
||||
};
|
||||
/**
|
||||
* Update the converter with passed series options.
|
||||
*
|
||||
* @param {Array<LineSeries>} allSeries
|
||||
* Array of series options to store in the converter.
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} eventDetail
|
||||
* Custom information for pending events.
|
||||
*/
|
||||
DataSeriesConverter.prototype.updateTable = function (allSeries, eventDetail) {
|
||||
var table = this.table;
|
||||
var columns, series, seriesMeta, pointArrayMap, pointArrayMapLength, options, keys, data, elem, rowIndex, y, needsArrayMap, xIndex, yIndex, yValueName, yValueIndex, yValueId, id;
|
||||
if (allSeries && allSeries.length) {
|
||||
this.options.seriesOptions = [];
|
||||
this.seriesMeta = [];
|
||||
this.seriesIdMap = {};
|
||||
for (var i = 0, iEnd = allSeries.length; i < iEnd; i++) {
|
||||
series = allSeries[i];
|
||||
// Add a unique ID to the series if none is assigned.
|
||||
series.id = defined(series.id) ? series.id : uniqueKey();
|
||||
yValueId = '_' + series.id;
|
||||
pointArrayMap = series.pointArrayMap || ['y'];
|
||||
pointArrayMapLength = pointArrayMap.length;
|
||||
options = series.options;
|
||||
keys = options.keys;
|
||||
data = series.options.data || [];
|
||||
seriesMeta = {
|
||||
id: series.id,
|
||||
pointArrayMap: pointArrayMap,
|
||||
options: series.options
|
||||
};
|
||||
this.options.seriesOptions.push(series.options);
|
||||
this.seriesMeta.push(seriesMeta);
|
||||
this.seriesIdMap[series.id] = seriesMeta;
|
||||
for (var j = 0, jEnd = data.length; j < jEnd; j++) {
|
||||
elem = data[j];
|
||||
y = 'y' + yValueId;
|
||||
columns = {};
|
||||
needsArrayMap = pointArrayMapLength > 1;
|
||||
if (typeof elem === 'number') {
|
||||
columns[y] = elem;
|
||||
columns.x = j;
|
||||
}
|
||||
else if (elem instanceof Array) {
|
||||
xIndex = keys && keys.indexOf('x') > -1 ?
|
||||
keys.indexOf('x') : 0;
|
||||
yIndex = keys && keys.indexOf('y') > -1 ?
|
||||
keys.indexOf('y') : 1;
|
||||
if (needsArrayMap) {
|
||||
for (var k = 0; k < pointArrayMapLength; k++) {
|
||||
yValueIndex = keys && keys.indexOf(pointArrayMap[k]) > -1 ?
|
||||
keys.indexOf(pointArrayMap[k]) :
|
||||
k + elem.length - pointArrayMapLength;
|
||||
yValueName = pointArrayMap[k];
|
||||
columns[yValueName + yValueId] = elem[yValueIndex];
|
||||
}
|
||||
}
|
||||
else {
|
||||
columns[y] = elem[yIndex];
|
||||
}
|
||||
columns.x = elem.length - pointArrayMapLength > 0 ?
|
||||
elem[xIndex] :
|
||||
j;
|
||||
}
|
||||
else if (elem instanceof Object) {
|
||||
if (needsArrayMap) {
|
||||
var elemSet = elem;
|
||||
for (var k = 0; k < pointArrayMapLength; k++) {
|
||||
yValueName = pointArrayMap[k];
|
||||
columns[yValueName + yValueId] = elemSet[yValueName];
|
||||
}
|
||||
}
|
||||
else {
|
||||
columns[y] = elem.y;
|
||||
}
|
||||
columns.x = elem.x || j;
|
||||
}
|
||||
id = '' + columns.x;
|
||||
rowIndex = table.getRowIndexBy('id', id);
|
||||
if (!rowIndex) {
|
||||
columns.id = id;
|
||||
table.setRows([columns], void 0, eventDetail);
|
||||
}
|
||||
else if (columns[y]) {
|
||||
table.setCell(y, rowIndex, columns[y], eventDetail);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return DataSeriesConverter;
|
||||
}());
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default DataSeriesConverter;
|
||||
1207
static/lib/Highcharts-10.2.1/es-modules/Data/DataTable.js
Normal file
1207
static/lib/Highcharts-10.2.1/es-modules/Data/DataTable.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,301 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2020-2022 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Sophie Bremer
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
import DataModifier from './DataModifier.js';
|
||||
import U from '../../Core/Utilities.js';
|
||||
var merge = U.merge;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Modifies a table with the help of modifiers in an ordered chain.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var ChainModifier = /** @class */ (function (_super) {
|
||||
__extends(ChainModifier, _super);
|
||||
/* *
|
||||
*
|
||||
* Constructors
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructs an instance of the modifier chain.
|
||||
*
|
||||
* @param {DeepPartial<ChainModifier.Options>} [options]
|
||||
* Options to configure the modifier chain.
|
||||
*
|
||||
* @param {...DataModifier} [modifiers]
|
||||
* Modifiers in order for the modifier chain.
|
||||
*/
|
||||
function ChainModifier(options) {
|
||||
var modifiers = [];
|
||||
for (var _i = 1; _i < arguments.length; _i++) {
|
||||
modifiers[_i - 1] = arguments[_i];
|
||||
}
|
||||
var _this = _super.call(this) || this;
|
||||
_this.modifiers = modifiers;
|
||||
_this.options = merge(ChainModifier.defaultOptions, options);
|
||||
return _this;
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Adds a configured modifier to the end of the modifier chain. Please note,
|
||||
* that the modifier can be added multiple times.
|
||||
*
|
||||
* @param {DataModifier} modifier
|
||||
* Configured modifier to add.
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*/
|
||||
ChainModifier.prototype.add = function (modifier, eventDetail) {
|
||||
this.emit({
|
||||
type: 'addModifier',
|
||||
detail: eventDetail,
|
||||
modifier: modifier
|
||||
});
|
||||
this.modifiers.push(modifier);
|
||||
this.emit({
|
||||
type: 'addModifier',
|
||||
detail: eventDetail,
|
||||
modifier: modifier
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Clears all modifiers from the chain.
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*/
|
||||
ChainModifier.prototype.clear = function (eventDetail) {
|
||||
this.emit({
|
||||
type: 'clearChain',
|
||||
detail: eventDetail
|
||||
});
|
||||
this.modifiers.length = 0;
|
||||
this.emit({
|
||||
type: 'afterClearChain',
|
||||
detail: eventDetail
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Applies partial modifications of a cell change to the property `modified`
|
||||
* of the given modified table.
|
||||
*
|
||||
* *Note:* The `modified` property of the table gets replaced.
|
||||
*
|
||||
* @param {Highcharts.DataTable} table
|
||||
* Modified table.
|
||||
*
|
||||
* @param {string} columnName
|
||||
* Column name of changed cell.
|
||||
*
|
||||
* @param {number|undefined} rowIndex
|
||||
* Row index of changed cell.
|
||||
*
|
||||
* @param {Highcharts.DataTableCellType} cellValue
|
||||
* Changed cell value.
|
||||
*
|
||||
* @param {Highcharts.DataTableEventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {Highcharts.DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
ChainModifier.prototype.modifyCell = function (table, columnName, rowIndex, cellValue, eventDetail) {
|
||||
var modifiers = (this.options.reverse ?
|
||||
this.modifiers.reverse() :
|
||||
this.modifiers);
|
||||
if (modifiers.length) {
|
||||
var clone = table.clone();
|
||||
for (var i = 0, iEnd = modifiers.length; i < iEnd; ++i) {
|
||||
modifiers[i].modifyCell(clone, columnName, rowIndex, cellValue, eventDetail);
|
||||
clone = clone.modified;
|
||||
}
|
||||
table.modified = clone;
|
||||
}
|
||||
return table;
|
||||
};
|
||||
/**
|
||||
* Applies partial modifications of column changes to the property
|
||||
* `modified` of the given table.
|
||||
*
|
||||
* *Note:* The `modified` property of the table gets replaced.
|
||||
*
|
||||
* @param {Highcharts.DataTable} table
|
||||
* Modified table.
|
||||
*
|
||||
* @param {Highcharts.DataTableColumnCollection} columns
|
||||
* Changed columns as a collection, where the keys are the column names.
|
||||
*
|
||||
* @param {number} [rowIndex=0]
|
||||
* Index of the first changed row.
|
||||
*
|
||||
* @param {Highcharts.DataTableEventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {Highcharts.DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
ChainModifier.prototype.modifyColumns = function (table, columns, rowIndex, eventDetail) {
|
||||
var modifiers = (this.options.reverse ?
|
||||
this.modifiers.reverse() :
|
||||
this.modifiers.slice());
|
||||
if (modifiers.length) {
|
||||
var clone = table.clone();
|
||||
for (var i = 0, iEnd = modifiers.length; i < iEnd; ++i) {
|
||||
modifiers[i].modifyColumns(clone, columns, rowIndex, eventDetail);
|
||||
clone = clone.modified;
|
||||
}
|
||||
table.modified = clone;
|
||||
}
|
||||
return table;
|
||||
};
|
||||
/**
|
||||
* Applies partial modifications of row changes to the property `modified`
|
||||
* of the given table.
|
||||
*
|
||||
* *Note:* The `modified` property of the table gets replaced.
|
||||
*
|
||||
* @param {Highcharts.DataTable} table
|
||||
* Modified table.
|
||||
*
|
||||
* @param {Array<(Highcharts.DataTableRow|Highcharts.DataTableRowObject)>} rows
|
||||
* Changed rows.
|
||||
*
|
||||
* @param {number} [rowIndex]
|
||||
* Index of the first changed row.
|
||||
*
|
||||
* @param {Highcharts.DataTableEventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {Highcharts.DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
ChainModifier.prototype.modifyRows = function (table, rows, rowIndex, eventDetail) {
|
||||
var modifiers = (this.options.reverse ?
|
||||
this.modifiers.reverse() :
|
||||
this.modifiers.slice());
|
||||
if (modifiers.length) {
|
||||
var clone = table.clone();
|
||||
for (var i = 0, iEnd = modifiers.length; i < iEnd; ++i) {
|
||||
modifiers[i].modifyRows(clone, rows, rowIndex, eventDetail);
|
||||
clone = clone.modified;
|
||||
}
|
||||
table.modified = clone;
|
||||
}
|
||||
return table;
|
||||
};
|
||||
/**
|
||||
* Applies several modifications to the table.
|
||||
*
|
||||
* *Note:* The `modified` property of the table gets replaced.
|
||||
*
|
||||
* @param {DataTable} table
|
||||
* Table to modify.
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {DataTable}
|
||||
* Table as a reference.
|
||||
*
|
||||
* @emits ChainDataModifier#execute
|
||||
* @emits ChainDataModifier#afterExecute
|
||||
*/
|
||||
ChainModifier.prototype.modifyTable = function (table, eventDetail) {
|
||||
var chain = this;
|
||||
chain.emit({ type: 'modify', detail: eventDetail, table: table });
|
||||
var modifiers = (chain.options.reverse ?
|
||||
chain.modifiers.reverse() :
|
||||
chain.modifiers.slice());
|
||||
var modified = table.modified;
|
||||
for (var i = 0, iEnd = modifiers.length, modifier = void 0; i < iEnd; ++i) {
|
||||
modifier = modifiers[i];
|
||||
modified = modifier.modifyTable(modified).modified;
|
||||
}
|
||||
table.modified = modified;
|
||||
chain.emit({ type: 'afterModify', detail: eventDetail, table: table });
|
||||
return table;
|
||||
};
|
||||
/**
|
||||
* Removes a configured modifier from all positions of the modifier chain.
|
||||
*
|
||||
* @param {DataModifier} modifier
|
||||
* Configured modifier to remove.
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*/
|
||||
ChainModifier.prototype.remove = function (modifier, eventDetail) {
|
||||
var modifiers = this.modifiers;
|
||||
this.emit({
|
||||
type: 'removeModifier',
|
||||
detail: eventDetail,
|
||||
modifier: modifier
|
||||
});
|
||||
modifiers.splice(modifiers.indexOf(modifier), 1);
|
||||
this.emit({
|
||||
type: 'afterRemoveModifier',
|
||||
detail: eventDetail,
|
||||
modifier: modifier
|
||||
});
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Default option for the ordered modifier chain.
|
||||
*/
|
||||
ChainModifier.defaultOptions = {
|
||||
modifier: 'Chain',
|
||||
reverse: false
|
||||
};
|
||||
return ChainModifier;
|
||||
}(DataModifier));
|
||||
/* *
|
||||
*
|
||||
* Register
|
||||
*
|
||||
* */
|
||||
DataModifier.addModifier(ChainModifier);
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default ChainModifier;
|
||||
@@ -0,0 +1,303 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2020-2022 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Sophie Bremer
|
||||
* - Gøran Slettemark
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
import DataPromise from '../DataPromise.js';
|
||||
import U from '../../Core/Utilities.js';
|
||||
var addEvent = U.addEvent, fireEvent = U.fireEvent, merge = U.merge;
|
||||
/** eslint-disable valid-jsdoc */
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Abstract class to provide an interface for modifying a table.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var DataModifier = /** @class */ (function () {
|
||||
function DataModifier() {
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Static Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Adds a modifier class to the registry. The modifier has to provide the
|
||||
* `DataModifier.options` property and the `DataModifier.execute` method to
|
||||
* modify the table.
|
||||
*
|
||||
* @param {DataModifier} modifier
|
||||
* Modifier class (aka class constructor) to register.
|
||||
*
|
||||
* @return {boolean}
|
||||
* Returns true, if the registration was successful. False is returned, if
|
||||
* their is already a modifier registered with this name.
|
||||
*/
|
||||
DataModifier.addModifier = function (modifier) {
|
||||
var name = DataModifier.getName(modifier), registry = DataModifier.registry;
|
||||
if (typeof name === 'undefined' ||
|
||||
registry[name]) {
|
||||
return false;
|
||||
}
|
||||
registry[name] = modifier;
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
* Returns all registered modifier names.
|
||||
*
|
||||
* @return {Array<string>}
|
||||
* All registered modifier names.
|
||||
*/
|
||||
DataModifier.getAllModifierNames = function () {
|
||||
return Object.keys(DataModifier.registry);
|
||||
};
|
||||
/**
|
||||
* Returns a copy of the modifier registry as record object with
|
||||
* modifier names and their modifier class.
|
||||
*
|
||||
* @return {Record<string,DataModifierRegistryType>}
|
||||
* Copy of the modifier registry.
|
||||
*/
|
||||
DataModifier.getAllModifiers = function () {
|
||||
return merge(DataModifier.registry);
|
||||
};
|
||||
/**
|
||||
* Returns a modifier class (aka class constructor) of the given modifier
|
||||
* name.
|
||||
*
|
||||
* @param {string} name
|
||||
* Registered class name of the class type.
|
||||
*
|
||||
* @return {DataModifier|undefined}
|
||||
* Class type, if the class name was found, otherwise `undefined`.
|
||||
*/
|
||||
DataModifier.getModifier = function (name) {
|
||||
return DataModifier.registry[name];
|
||||
};
|
||||
/**
|
||||
* Extracts the name from a given modifier class.
|
||||
*
|
||||
* @param {DataModifier} modifier
|
||||
* Modifier class to extract the name from.
|
||||
*
|
||||
* @return {string}
|
||||
* Modifier name, if the extraction was successful, otherwise an empty
|
||||
* string.
|
||||
*/
|
||||
DataModifier.getName = function (modifier) {
|
||||
return (modifier.toString().match(DataModifier.nameRegExp) ||
|
||||
['', ''])[1];
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Runs a timed execution of the modifier on the given datatable.
|
||||
* Can be configured to run multiple times.
|
||||
*
|
||||
* @param {DataTable} dataTable
|
||||
* The datatable to execute
|
||||
*
|
||||
* @param {DataModifier.BenchmarkOptions} options
|
||||
* Options. Currently supports `iterations` for number of iterations.
|
||||
*
|
||||
* @return {Array<number>}
|
||||
* An array of times in milliseconds
|
||||
*
|
||||
*/
|
||||
DataModifier.prototype.benchmark = function (dataTable, options) {
|
||||
var results = [];
|
||||
var modifier = this;
|
||||
var execute = function () {
|
||||
modifier.modifyTable(dataTable);
|
||||
modifier.emit({ type: 'afterBenchmarkIteration' });
|
||||
};
|
||||
var defaultOptions = {
|
||||
iterations: 1
|
||||
};
|
||||
var iterations = merge(defaultOptions, options).iterations;
|
||||
modifier.on('afterBenchmarkIteration', function () {
|
||||
if (results.length === iterations) {
|
||||
modifier.emit({ type: 'afterBenchmark', results: results });
|
||||
return;
|
||||
}
|
||||
// Run again
|
||||
execute();
|
||||
});
|
||||
var times = {
|
||||
startTime: 0,
|
||||
endTime: 0
|
||||
};
|
||||
// Add timers
|
||||
modifier.on('modify', function () {
|
||||
times.startTime = window.performance.now();
|
||||
});
|
||||
modifier.on('afterModify', function () {
|
||||
times.endTime = window.performance.now();
|
||||
results.push(times.endTime - times.startTime);
|
||||
});
|
||||
// Initial run
|
||||
execute();
|
||||
return results;
|
||||
};
|
||||
/**
|
||||
* Emits an event on the modifier to all registered callbacks of this event.
|
||||
*
|
||||
* @param {DataEventEmitter.Event} [e]
|
||||
* Event object containing additonal event information.
|
||||
*/
|
||||
DataModifier.prototype.emit = function (e) {
|
||||
fireEvent(this, e.type, e);
|
||||
};
|
||||
/**
|
||||
* Returns a modified copy of the given table.
|
||||
*
|
||||
* @param {Highcharts.DataTable} table
|
||||
* Table to modify.
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {Promise<Highcharts.DataTable>}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
DataModifier.prototype.modify = function (table, eventDetail) {
|
||||
var modifier = this;
|
||||
return new DataPromise(function (resolve, reject) {
|
||||
if (table.modified === table) {
|
||||
table.modified = table.clone(false, eventDetail);
|
||||
}
|
||||
try {
|
||||
resolve(modifier.modifyTable(table, eventDetail));
|
||||
}
|
||||
catch (e) {
|
||||
modifier.emit({
|
||||
type: 'error',
|
||||
detail: eventDetail,
|
||||
table: table
|
||||
});
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Applies partial modifications of a cell change to the property `modified`
|
||||
* of the given modified table.
|
||||
*
|
||||
* @param {Highcharts.DataTable} table
|
||||
* Modified table.
|
||||
*
|
||||
* @param {string} columnName
|
||||
* Column name of changed cell.
|
||||
*
|
||||
* @param {number|undefined} rowIndex
|
||||
* Row index of changed cell.
|
||||
*
|
||||
* @param {Highcharts.DataTableCellType} cellValue
|
||||
* Changed cell value.
|
||||
*
|
||||
* @param {Highcharts.DataTableEventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {Highcharts.DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
DataModifier.prototype.modifyCell = function (table, columnName, rowIndex, cellValue, eventDetail) {
|
||||
return this.modifyTable(table);
|
||||
};
|
||||
/**
|
||||
* Applies partial modifications of column changes to the property
|
||||
* `modified` of the given table.
|
||||
*
|
||||
* @param {Highcharts.DataTable} table
|
||||
* Modified table.
|
||||
*
|
||||
* @param {Highcharts.DataTableColumnCollection} columns
|
||||
* Changed columns as a collection, where the keys are the column names.
|
||||
*
|
||||
* @param {number} [rowIndex=0]
|
||||
* Index of the first changed row.
|
||||
*
|
||||
* @param {Highcharts.DataTableEventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {Highcharts.DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
DataModifier.prototype.modifyColumns = function (table, columns, rowIndex, eventDetail) {
|
||||
return this.modifyTable(table);
|
||||
};
|
||||
/**
|
||||
* Applies partial modifications of row changes to the property `modified`
|
||||
* of the given table.
|
||||
*
|
||||
* @param {Highcharts.DataTable} table
|
||||
* Modified table.
|
||||
*
|
||||
* @param {Array<(Highcharts.DataTableRow|Highcharts.DataTableRowObject)>} rows
|
||||
* Changed rows.
|
||||
*
|
||||
* @param {number} [rowIndex]
|
||||
* Index of the first changed row.
|
||||
*
|
||||
* @param {Highcharts.DataTableEventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {Highcharts.DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
DataModifier.prototype.modifyRows = function (table, rows, rowIndex, eventDetail) {
|
||||
return this.modifyTable(table);
|
||||
};
|
||||
/**
|
||||
* Registers a callback for a specific modifier event.
|
||||
*
|
||||
* @param {string} type
|
||||
* Event type as a string.
|
||||
*
|
||||
* @param {DataEventEmitter.EventCallback} callback
|
||||
* Function to register for an modifier callback.
|
||||
*
|
||||
* @return {Function}
|
||||
* Function to unregister callback from the modifier event.
|
||||
*/
|
||||
DataModifier.prototype.on = function (type, callback) {
|
||||
return addEvent(this, type, callback);
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Regular expression to extract the modifier name (group 1) from the
|
||||
* stringified class type.
|
||||
*/
|
||||
DataModifier.nameRegExp = (/^function\s+(\w*?)(?:Data)?(?:Modifier)?\s*\(/);
|
||||
/**
|
||||
* Registry as a record object with modifier names and their class.
|
||||
*/
|
||||
DataModifier.registry = {};
|
||||
return DataModifier;
|
||||
}());
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default DataModifier;
|
||||
@@ -0,0 +1,146 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2020-2022 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Sophie Bremer
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
import DataModifier from './DataModifier.js';
|
||||
import DataTable from '../DataTable.js';
|
||||
import U from '../../Core/Utilities.js';
|
||||
var merge = U.merge;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Groups table rows into subtables depending on column values.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var GroupModifier = /** @class */ (function (_super) {
|
||||
__extends(GroupModifier, _super);
|
||||
/* *
|
||||
*
|
||||
* Constructors
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructs an instance of the group modifier.
|
||||
*
|
||||
* @param {GroupModifier.Options} [options]
|
||||
* Options to configure the group modifier.
|
||||
*/
|
||||
function GroupModifier(options) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this.options = merge(GroupModifier.defaultOptions, options);
|
||||
return _this;
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Applies modifications to the table rows and returns a new table with
|
||||
* subtable, containing the grouped rows. The rows of the new table contain
|
||||
* three columns:
|
||||
* - `groupBy`: Column name used to group rows by.
|
||||
* - `table`: Subtable containing the grouped rows.
|
||||
* - `value`: containing the common value of the group
|
||||
*
|
||||
* @param {DataTable} table
|
||||
* Table to modify.
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
GroupModifier.prototype.modifyTable = function (table, eventDetail) {
|
||||
var modifier = this;
|
||||
modifier.emit({ type: 'modify', detail: eventDetail, table: table });
|
||||
var byGroups = [], tableGroups = [], valueGroups = [], groupColumn = (modifier.options.groupColumn ||
|
||||
table.getColumnNames()[0]), valueColumn = (table.getColumn(groupColumn) ||
|
||||
[]), _a = modifier.options, invalidValues = _a.invalidValues, validValues = _a.validValues, modified = table.modified = table.clone(true, eventDetail);
|
||||
var value, valueIndex;
|
||||
for (var i = 0, iEnd = valueColumn.length; i < iEnd; ++i) {
|
||||
value = valueColumn[i];
|
||||
if (typeof value !== 'undefined') {
|
||||
if (value instanceof DataTable ||
|
||||
(invalidValues &&
|
||||
invalidValues.indexOf(value) >= 0) || (validValues &&
|
||||
validValues.indexOf(value) === -1)) {
|
||||
continue;
|
||||
}
|
||||
valueIndex = valueGroups.indexOf(value);
|
||||
if (valueIndex === -1) {
|
||||
var newTable = new DataTable();
|
||||
newTable.setRows([table.getRowObject(i) || {}]);
|
||||
byGroups.push(groupColumn);
|
||||
tableGroups.push(newTable);
|
||||
valueGroups.push(value);
|
||||
}
|
||||
else {
|
||||
tableGroups[valueIndex].setRows([table.getRow(i) || []]);
|
||||
}
|
||||
}
|
||||
}
|
||||
modified.deleteColumns();
|
||||
modified.setColumns({
|
||||
groupBy: byGroups,
|
||||
table: tableGroups,
|
||||
value: valueGroups
|
||||
});
|
||||
modifier.emit({ type: 'afterModify', detail: eventDetail, table: table });
|
||||
return table;
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Default options to group table rows.
|
||||
*/
|
||||
GroupModifier.defaultOptions = {
|
||||
modifier: 'Group',
|
||||
groupColumn: ''
|
||||
};
|
||||
return GroupModifier;
|
||||
}(DataModifier));
|
||||
/* *
|
||||
*
|
||||
* Register
|
||||
*
|
||||
* */
|
||||
DataModifier.addModifier(GroupModifier);
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default GroupModifier;
|
||||
@@ -0,0 +1,256 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2020-2022 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Wojciech Chmiel
|
||||
* - Sophie Bremer
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
import DataModifier from './DataModifier.js';
|
||||
import U from '../../Core/Utilities.js';
|
||||
var merge = U.merge;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Inverts columns and rows in a table.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var InvertModifier = /** @class */ (function (_super) {
|
||||
__extends(InvertModifier, _super);
|
||||
/* *
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructs an instance of the invert modifier.
|
||||
*
|
||||
* @param {InvertModifier.Options} [options]
|
||||
* Options to configure the invert modifier.
|
||||
*/
|
||||
function InvertModifier(options) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this.options = merge(InvertModifier.defaultOptions, options);
|
||||
return _this;
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Applies partial modifications of a cell change to the property `modified`
|
||||
* of the given modified table.
|
||||
*
|
||||
* @param {Highcharts.DataTable} table
|
||||
* Modified table.
|
||||
*
|
||||
* @param {string} columnName
|
||||
* Column name of changed cell.
|
||||
*
|
||||
* @param {number|undefined} rowIndex
|
||||
* Row index of changed cell.
|
||||
*
|
||||
* @param {Highcharts.DataTableCellType} cellValue
|
||||
* Changed cell value.
|
||||
*
|
||||
* @param {Highcharts.DataTableEventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {Highcharts.DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
InvertModifier.prototype.modifyCell = function (table, columnName, rowIndex, cellValue, eventDetail) {
|
||||
var modified = table.modified, modifiedRowIndex = modified.getRowIndexBy('columnNames', columnName);
|
||||
if (typeof modifiedRowIndex === 'undefined') {
|
||||
modified.setColumns(this.modifyTable(table.clone()).getColumns(), void 0, eventDetail);
|
||||
}
|
||||
else {
|
||||
modified.setCell("".concat(rowIndex), modifiedRowIndex, cellValue, eventDetail);
|
||||
}
|
||||
return table;
|
||||
};
|
||||
/**
|
||||
* Applies partial modifications of column changes to the property
|
||||
* `modified` of the given table.
|
||||
*
|
||||
* @param {Highcharts.DataTable} table
|
||||
* Modified table.
|
||||
*
|
||||
* @param {Highcharts.DataTableColumnCollection} columns
|
||||
* Changed columns as a collection, where the keys are the column names.
|
||||
*
|
||||
* @param {number} [rowIndex=0]
|
||||
* Index of the first changed row.
|
||||
*
|
||||
* @param {Highcharts.DataTableEventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {Highcharts.DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
InvertModifier.prototype.modifyColumns = function (table, columns, rowIndex, eventDetail) {
|
||||
var modified = table.modified, modifiedColumnNames = (modified.getColumn('columnNames') || []);
|
||||
var columnNames = table.getColumnNames(), reset = (table.getRowCount() !== modifiedColumnNames.length);
|
||||
if (!reset) {
|
||||
for (var i = 0, iEnd = columnNames.length; i < iEnd; ++i) {
|
||||
if (columnNames[i] !== modifiedColumnNames[i]) {
|
||||
reset = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reset) {
|
||||
return this.modifyTable(table, eventDetail);
|
||||
}
|
||||
columnNames = Object.keys(columns);
|
||||
for (var i = 0, iEnd = columnNames.length, column = void 0, columnName = void 0, modifiedRowIndex = void 0; i < iEnd; ++i) {
|
||||
columnName = columnNames[i];
|
||||
column = columns[columnName];
|
||||
modifiedRowIndex = (modified.getRowIndexBy('columnNames', columnName) ||
|
||||
modified.getRowCount());
|
||||
for (var j = 0, j2 = rowIndex, jEnd = column.length; j < jEnd; ++j, ++j2) {
|
||||
modified.setCell("".concat(j2), modifiedRowIndex, column[j], eventDetail);
|
||||
}
|
||||
}
|
||||
return table;
|
||||
};
|
||||
/**
|
||||
* Applies partial modifications of row changes to the property `modified`
|
||||
* of the given table.
|
||||
*
|
||||
* @param {Highcharts.DataTable} table
|
||||
* Modified table.
|
||||
*
|
||||
* @param {Array<(Highcharts.DataTableRow|Highcharts.DataTableRowObject)>} rows
|
||||
* Changed rows.
|
||||
*
|
||||
* @param {number} [rowIndex]
|
||||
* Index of the first changed row.
|
||||
*
|
||||
* @param {Highcharts.DataTableEventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {Highcharts.DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
InvertModifier.prototype.modifyRows = function (table, rows, rowIndex, eventDetail) {
|
||||
var columnNames = table.getColumnNames(), modified = table.modified, modifiedColumnNames = (modified.getColumn('columnNames') || []);
|
||||
var reset = (table.getRowCount() !== modifiedColumnNames.length);
|
||||
if (!reset) {
|
||||
for (var i = 0, iEnd = columnNames.length; i < iEnd; ++i) {
|
||||
if (columnNames[i] !== modifiedColumnNames[i]) {
|
||||
reset = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reset) {
|
||||
return this.modifyTable(table, eventDetail);
|
||||
}
|
||||
for (var i = 0, i2 = rowIndex, iEnd = rows.length, row = void 0; i < iEnd; ++i, ++i2) {
|
||||
row = rows[i];
|
||||
if (row instanceof Array) {
|
||||
modified.setColumn("".concat(i2), row);
|
||||
}
|
||||
else {
|
||||
for (var j = 0, jEnd = columnNames.length; j < jEnd; ++j) {
|
||||
modified.setCell("".concat(i2), j, row[columnNames[j]], eventDetail);
|
||||
}
|
||||
}
|
||||
}
|
||||
return table;
|
||||
};
|
||||
/**
|
||||
* Inverts rows and columns in the table.
|
||||
*
|
||||
* @param {DataTable} table
|
||||
* Table to invert.
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {DataTable}
|
||||
* Table with inverted `modified` property as a reference.
|
||||
*/
|
||||
InvertModifier.prototype.modifyTable = function (table, eventDetail) {
|
||||
var modifier = this;
|
||||
modifier.emit({ type: 'modify', detail: eventDetail, table: table });
|
||||
var modified = table.modified;
|
||||
if (table.hasColumns(['columnNames'])) { // inverted table
|
||||
var columnNames = ((table.deleteColumns(['columnNames']) || {})
|
||||
.columnNames || []).map(function (column) { return "".concat(column); }), columns = {};
|
||||
for (var i = 0, iEnd = table.getRowCount(), row = void 0; i < iEnd; ++i) {
|
||||
row = table.getRow(i);
|
||||
if (row) {
|
||||
columns[columnNames[i]] = row;
|
||||
}
|
||||
}
|
||||
modified.deleteColumns();
|
||||
modified.setColumns(columns);
|
||||
}
|
||||
else { // regular table
|
||||
var columns = {};
|
||||
for (var i = 0, iEnd = table.getRowCount(), row = void 0; i < iEnd; ++i) {
|
||||
row = table.getRow(i);
|
||||
if (row) {
|
||||
columns["".concat(i)] = row;
|
||||
}
|
||||
}
|
||||
columns.columnNames = table.getColumnNames();
|
||||
modified.deleteColumns();
|
||||
modified.setColumns(columns);
|
||||
}
|
||||
modifier.emit({ type: 'afterModify', detail: eventDetail, table: table });
|
||||
return table;
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Default options for the invert modifier.
|
||||
*/
|
||||
InvertModifier.defaultOptions = {
|
||||
modifier: 'InvertModifier'
|
||||
};
|
||||
return InvertModifier;
|
||||
}(DataModifier));
|
||||
/* *
|
||||
*
|
||||
* Register
|
||||
*
|
||||
* */
|
||||
DataModifier.addModifier(InvertModifier);
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default InvertModifier;
|
||||
@@ -0,0 +1,145 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2020-2022 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Sophie Bremer
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
import DataModifier from './DataModifier.js';
|
||||
import U from '../../Core/Utilities.js';
|
||||
var merge = U.merge;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Filters out table rows with a specific value range.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var RangeModifier = /** @class */ (function (_super) {
|
||||
__extends(RangeModifier, _super);
|
||||
/* *
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructs an instance of the range modifier.
|
||||
*
|
||||
* @param {RangeModifier.Options} [options]
|
||||
* Options to configure the range modifier.
|
||||
*/
|
||||
function RangeModifier(options) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this.options = merge(RangeModifier.defaultOptions, options);
|
||||
return _this;
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Replaces table rows with filtered rows.
|
||||
*
|
||||
* @param {DataTable} table
|
||||
* Table to modify.
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
RangeModifier.prototype.modifyTable = function (table, eventDetail) {
|
||||
var modifier = this;
|
||||
modifier.emit({ type: 'modify', detail: eventDetail, table: table });
|
||||
var _a = modifier.options, ranges = _a.ranges, strict = _a.strict;
|
||||
if (ranges.length) {
|
||||
var columns = table.getColumns(), rows = [], modified = table.modified;
|
||||
for (var i = 0, iEnd = ranges.length, range = void 0, rangeColumn = void 0; i < iEnd; ++i) {
|
||||
range = ranges[i];
|
||||
if (strict &&
|
||||
typeof range.minValue !== typeof range.maxValue) {
|
||||
continue;
|
||||
}
|
||||
rangeColumn = (columns[range.column] || []);
|
||||
for (var j = 0, jEnd = rangeColumn.length, cell = void 0, row = void 0; j < jEnd; ++j) {
|
||||
cell = rangeColumn[j];
|
||||
switch (typeof cell) {
|
||||
default:
|
||||
continue;
|
||||
case 'boolean':
|
||||
case 'number':
|
||||
case 'string':
|
||||
break;
|
||||
}
|
||||
if (strict &&
|
||||
typeof cell !== typeof range.minValue) {
|
||||
continue;
|
||||
}
|
||||
if (cell >= range.minValue &&
|
||||
cell <= range.maxValue) {
|
||||
row = table.getRow(j);
|
||||
if (row) {
|
||||
rows.push(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
modified.deleteRows();
|
||||
modified.setRows(rows);
|
||||
}
|
||||
modifier.emit({ type: 'afterModify', detail: eventDetail, table: table });
|
||||
return table;
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Default options for the range modifier.
|
||||
*/
|
||||
RangeModifier.defaultOptions = {
|
||||
modifier: 'Range',
|
||||
strict: false,
|
||||
ranges: []
|
||||
};
|
||||
return RangeModifier;
|
||||
}(DataModifier));
|
||||
/* *
|
||||
*
|
||||
* Register
|
||||
*
|
||||
* */
|
||||
DataModifier.addModifier(RangeModifier);
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default RangeModifier;
|
||||
@@ -0,0 +1,112 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2020-2022 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Wojciech Chmiel
|
||||
* - Sophie Bremer
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
import DataModifier from './DataModifier.js';
|
||||
import U from '../../Core/Utilities.js';
|
||||
var merge = U.merge;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
var SeriesPointsModifier = /** @class */ (function (_super) {
|
||||
__extends(SeriesPointsModifier, _super);
|
||||
/* *
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructs an instance of the series points modifier.
|
||||
*
|
||||
* @param {SeriesPointsModifier.Options} [options]
|
||||
* Options to configure the series points modifier.
|
||||
*/
|
||||
function SeriesPointsModifier(options) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this.options = merge(SeriesPointsModifier.defaultOptions, options);
|
||||
return _this;
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Renames columns to alternative column names (alias) depending on mapping
|
||||
* option.
|
||||
*
|
||||
* @param {DataTable} table
|
||||
* Table to modify.
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
SeriesPointsModifier.prototype.modifyTable = function (table, eventDetail) {
|
||||
var modifier = this;
|
||||
modifier.emit({ type: 'modify', detail: eventDetail, table: table });
|
||||
var aliasMap = modifier.options.aliasMap || {}, aliases = Object.keys(aliasMap), modified = table.modified = table.clone(false, eventDetail);
|
||||
for (var i = 0, iEnd = aliases.length, alias = void 0; i < iEnd; ++i) {
|
||||
alias = aliases[i];
|
||||
modified.renameColumn(aliasMap[alias], alias);
|
||||
}
|
||||
modifier.emit({ type: 'afterModify', detail: eventDetail, table: table });
|
||||
return table;
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Default options for the series points modifier.
|
||||
*/
|
||||
SeriesPointsModifier.defaultOptions = {
|
||||
modifier: 'SeriesPoints'
|
||||
};
|
||||
return SeriesPointsModifier;
|
||||
}(DataModifier));
|
||||
/* *
|
||||
*
|
||||
* Register
|
||||
*
|
||||
* */
|
||||
DataModifier.addModifier(SeriesPointsModifier);
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default SeriesPointsModifier;
|
||||
@@ -0,0 +1,251 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2020-2022 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Sophie Bremer
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
import DataModifier from './DataModifier.js';
|
||||
import DataTable from '../DataTable.js';
|
||||
import U from '../../Core/Utilities.js';
|
||||
var merge = U.merge;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Sort table rows according to values of a column.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var SortModifier = /** @class */ (function (_super) {
|
||||
__extends(SortModifier, _super);
|
||||
/* *
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructs an instance of the range modifier.
|
||||
*
|
||||
* @param {RangeDataModifier.Options} [options]
|
||||
* Options to configure the range modifier.
|
||||
*/
|
||||
function SortModifier(options) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this.options = merge(SortModifier.defaultOptions, options);
|
||||
return _this;
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Static Functions
|
||||
*
|
||||
* */
|
||||
SortModifier.ascending = function (a, b) {
|
||||
return ((a || 0) < (b || 0) ? -1 :
|
||||
(a || 0) > (b || 0) ? 1 :
|
||||
0);
|
||||
};
|
||||
SortModifier.descending = function (a, b) {
|
||||
return ((b || 0) < (a || 0) ? -1 :
|
||||
(b || 0) > (a || 0) ? 1 :
|
||||
0);
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Applies partial modifications of a cell change to the property `modified`
|
||||
* of the given modified table.
|
||||
*
|
||||
* @param {Highcharts.DataTable} table
|
||||
* Modified table.
|
||||
*
|
||||
* @param {string} columnName
|
||||
* Column name of changed cell.
|
||||
*
|
||||
* @param {number|undefined} rowIndex
|
||||
* Row index of changed cell.
|
||||
*
|
||||
* @param {Highcharts.DataTableCellType} cellValue
|
||||
* Changed cell value.
|
||||
*
|
||||
* @param {Highcharts.DataTableEventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {Highcharts.DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
SortModifier.prototype.modifyCell = function (table, columnName, rowIndex, cellValue, eventDetail) {
|
||||
var modifier = this, _a = modifier.options, orderByColumn = _a.orderByColumn, orderInColumn = _a.orderInColumn;
|
||||
if (columnName === orderByColumn) {
|
||||
if (orderInColumn) {
|
||||
table.modified.setCell(columnName, rowIndex, cellValue);
|
||||
table.modified.setColumn(orderInColumn, modifier
|
||||
.modifyTable(new DataTable(table.getColumns([orderByColumn, orderInColumn])))
|
||||
.modified
|
||||
.getColumn(orderInColumn));
|
||||
}
|
||||
else {
|
||||
modifier.modifyTable(table, eventDetail);
|
||||
}
|
||||
}
|
||||
return table;
|
||||
};
|
||||
/**
|
||||
* Applies partial modifications of column changes to the property
|
||||
* `modified` of the given table.
|
||||
*
|
||||
* @param {Highcharts.DataTable} table
|
||||
* Modified table.
|
||||
*
|
||||
* @param {Highcharts.DataTableColumnCollection} columns
|
||||
* Changed columns as a collection, where the keys are the column names.
|
||||
*
|
||||
* @param {number} [rowIndex=0]
|
||||
* Index of the first changed row.
|
||||
*
|
||||
* @param {Highcharts.DataTableEventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {Highcharts.DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
SortModifier.prototype.modifyColumns = function (table, columns, rowIndex, eventDetail) {
|
||||
var modifier = this, _a = modifier.options, orderByColumn = _a.orderByColumn, orderInColumn = _a.orderInColumn, columnNames = Object.keys(columns);
|
||||
if (columnNames.indexOf(orderByColumn) > -1) {
|
||||
if (orderInColumn &&
|
||||
columns[columnNames[0]].length) {
|
||||
table.modified.setColumns(columns, rowIndex);
|
||||
table.modified.setColumn(orderInColumn, modifier
|
||||
.modifyTable(new DataTable(table.getColumns([orderByColumn, orderInColumn])))
|
||||
.modified
|
||||
.getColumn(orderInColumn));
|
||||
}
|
||||
else {
|
||||
modifier.modifyTable(table, eventDetail);
|
||||
}
|
||||
}
|
||||
return table;
|
||||
};
|
||||
/**
|
||||
* Applies partial modifications of row changes to the property `modified`
|
||||
* of the given table.
|
||||
*
|
||||
* @param {Highcharts.DataTable} table
|
||||
* Modified table.
|
||||
*
|
||||
* @param {Array<(Highcharts.DataTableRow|Highcharts.DataTableRowObject)>} rows
|
||||
* Changed rows.
|
||||
*
|
||||
* @param {number} [rowIndex]
|
||||
* Index of the first changed row.
|
||||
*
|
||||
* @param {Highcharts.DataTableEventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {Highcharts.DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
SortModifier.prototype.modifyRows = function (table, rows, rowIndex, eventDetail) {
|
||||
var modifier = this, _a = modifier.options, orderByColumn = _a.orderByColumn, orderInColumn = _a.orderInColumn;
|
||||
if (orderInColumn &&
|
||||
rows.length) {
|
||||
table.modified.setRows(rows, rowIndex);
|
||||
table.modified.setColumn(orderInColumn, modifier
|
||||
.modifyTable(new DataTable(table.getColumns([orderByColumn, orderInColumn])))
|
||||
.modified
|
||||
.getColumn(orderInColumn));
|
||||
}
|
||||
else {
|
||||
modifier.modifyTable(table, eventDetail);
|
||||
}
|
||||
return table;
|
||||
};
|
||||
/**
|
||||
* Sorts rows in the table.
|
||||
*
|
||||
* @param {DataTable} table
|
||||
* Table to sort in.
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {DataTable}
|
||||
* Table with `modified` property as a reference.
|
||||
*/
|
||||
SortModifier.prototype.modifyTable = function (table, eventDetail) {
|
||||
var _a;
|
||||
var modifier = this;
|
||||
modifier.emit({ type: 'modify', detail: eventDetail, table: table });
|
||||
var columnNames = table.getColumnNames(), rowCount = table.getRowCount(), rowReferences = table.getRows().map(function (row, index) { return ({
|
||||
index: index,
|
||||
row: row
|
||||
}); }), _b = modifier.options, direction = _b.direction, orderByColumn = _b.orderByColumn, orderInColumn = _b.orderInColumn, compare = (direction === 'asc' ?
|
||||
SortModifier.ascending :
|
||||
SortModifier.descending), orderByColumnIndex = columnNames.indexOf(orderByColumn), modified = table.modified;
|
||||
if (orderByColumnIndex !== -1) {
|
||||
rowReferences.sort(function (a, b) { return compare(a.row[orderByColumnIndex], b.row[orderByColumnIndex]); });
|
||||
}
|
||||
if (orderInColumn) {
|
||||
var column = [];
|
||||
for (var i = 0; i < rowCount; ++i) {
|
||||
column[rowReferences[i].index] = i;
|
||||
}
|
||||
modified.setColumns((_a = {}, _a[orderInColumn] = column, _a));
|
||||
}
|
||||
else {
|
||||
var rows = [];
|
||||
for (var i = 0; i < rowCount; ++i) {
|
||||
rows.push(rowReferences[i].row);
|
||||
}
|
||||
modified.setRows(rows, 0);
|
||||
}
|
||||
modifier.emit({ type: 'afterModify', detail: eventDetail, table: table });
|
||||
return table;
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Default options to group table rows.
|
||||
*/
|
||||
SortModifier.defaultOptions = {
|
||||
modifier: 'Order',
|
||||
direction: 'desc',
|
||||
orderByColumn: 'y'
|
||||
};
|
||||
return SortModifier;
|
||||
}(DataModifier));
|
||||
/* *
|
||||
*
|
||||
* Default Export
|
||||
*
|
||||
* */
|
||||
export default SortModifier;
|
||||
@@ -0,0 +1,402 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2012-2021 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Torstein Hønsi
|
||||
* - Christer Vasseng
|
||||
* - Gøran Slettemark
|
||||
* - Sophie Bremer
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var __assign = (this && this.__assign) || function () {
|
||||
__assign = Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
import DataParser from './DataParser.js';
|
||||
import DataConverter from '../DataConverter.js';
|
||||
import U from '../../Core/Utilities.js';
|
||||
var merge = U.merge;
|
||||
/* eslint-disable no-invalid-this, require-jsdoc, valid-jsdoc */
|
||||
/**
|
||||
* Handles parsing and transforming CSV to a table.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var CSVParser = /** @class */ (function (_super) {
|
||||
__extends(CSVParser, _super);
|
||||
/* *
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructs an instance of the CSV parser.
|
||||
*
|
||||
* @param {CSVParser.OptionsType} [options]
|
||||
* Options for the CSV parser.
|
||||
*
|
||||
* @param {DataConverter} converter
|
||||
* Parser data converter.
|
||||
*/
|
||||
function CSVParser(options, converter) {
|
||||
var _this = _super.call(this) || this;
|
||||
/* *
|
||||
*
|
||||
* Properties
|
||||
*
|
||||
* */
|
||||
_this.columns = [];
|
||||
_this.headers = [];
|
||||
_this.dataTypes = [];
|
||||
_this.options = merge(CSVParser.defaultOptions, options);
|
||||
_this.converter = converter || new DataConverter();
|
||||
return _this;
|
||||
}
|
||||
/**
|
||||
* Initiates parsing of CSV
|
||||
*
|
||||
* @param {CSVParser.OptionsType}[options]
|
||||
* Options for the parser
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @emits CSVDataParser#parse
|
||||
* @emits CSVDataParser#afterParse
|
||||
*/
|
||||
CSVParser.prototype.parse = function (options, eventDetail) {
|
||||
var parser = this, dataTypes = parser.dataTypes, converter = parser.converter, parserOptions = merge(this.options, options), beforeParse = parserOptions.beforeParse, lineDelimiter = parserOptions.lineDelimiter, firstRowAsNames = parserOptions.firstRowAsNames, itemDelimiter = parserOptions.itemDelimiter;
|
||||
var lines, rowIt = 0, csv = parserOptions.csv, startRow = parserOptions.startRow, endRow = parserOptions.endRow, column;
|
||||
parser.columns = [];
|
||||
parser.emit({
|
||||
type: 'parse',
|
||||
columns: parser.columns,
|
||||
detail: eventDetail,
|
||||
headers: parser.headers
|
||||
});
|
||||
if (csv && beforeParse) {
|
||||
csv = beforeParse(csv);
|
||||
}
|
||||
if (csv) {
|
||||
lines = csv
|
||||
.replace(/\r\n/g, '\n') // Unix
|
||||
.replace(/\r/g, '\n') // Mac
|
||||
.split(lineDelimiter || '\n');
|
||||
if (!startRow || startRow < 0) {
|
||||
startRow = 0;
|
||||
}
|
||||
if (!endRow || endRow >= lines.length) {
|
||||
endRow = lines.length - 1;
|
||||
}
|
||||
if (!itemDelimiter) {
|
||||
parser.guessedItemDelimiter = parser.guessDelimiter(lines);
|
||||
}
|
||||
// If the first row contain names, add them to the
|
||||
// headers array and skip the row.
|
||||
if (firstRowAsNames) {
|
||||
var headers = lines[0]
|
||||
.split(itemDelimiter || parser.guessedItemDelimiter || ',');
|
||||
// Remove ""s from the headers
|
||||
for (var i = 0; i < headers.length; i++) {
|
||||
headers[i] = headers[i].replace(/^["']|["']$/g, '');
|
||||
}
|
||||
parser.headers = headers;
|
||||
startRow++;
|
||||
}
|
||||
var offset = 0;
|
||||
for (rowIt = startRow; rowIt <= endRow; rowIt++) {
|
||||
if (lines[rowIt][0] === '#') {
|
||||
offset++;
|
||||
}
|
||||
else {
|
||||
parser.parseCSVRow(lines[rowIt], rowIt - startRow - offset);
|
||||
}
|
||||
}
|
||||
if (dataTypes.length &&
|
||||
dataTypes[0].length &&
|
||||
dataTypes[0][1] === 'date' && // format is a string date
|
||||
!parser.converter.getDateFormat()) {
|
||||
parser.converter.deduceDateFormat(parser.columns[0], null, true);
|
||||
}
|
||||
// Guess types.
|
||||
for (var i = 0, iEnd = parser.columns.length; i < iEnd; ++i) {
|
||||
column = parser.columns[i];
|
||||
for (var j = 0, jEnd = column.length; j < jEnd; ++j) {
|
||||
if (column[j] && typeof column[j] === 'string') {
|
||||
var cellValue = converter.asGuessedType(column[j]);
|
||||
if (cellValue instanceof Date) {
|
||||
cellValue = cellValue.getTime();
|
||||
}
|
||||
parser.columns[i][j] = cellValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
parser.emit({
|
||||
type: 'afterParse',
|
||||
columns: parser.columns,
|
||||
detail: eventDetail,
|
||||
headers: parser.headers
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Internal method that parses a single CSV row
|
||||
*/
|
||||
CSVParser.prototype.parseCSVRow = function (columnStr, rowNumber) {
|
||||
var parser = this, converter = this.converter, columns = parser.columns || [], dataTypes = parser.dataTypes, _a = parser.options, startColumn = _a.startColumn, endColumn = _a.endColumn, itemDelimiter = (parser.options.itemDelimiter ||
|
||||
parser.guessedItemDelimiter);
|
||||
var decimalPoint = parser.options.decimalPoint;
|
||||
if (!decimalPoint || decimalPoint === itemDelimiter) {
|
||||
decimalPoint = parser.guessedDecimalPoint || '.';
|
||||
}
|
||||
var i = 0, c = '', cl = '', cn = '', token = '', actualColumn = 0, column = 0;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function read(j) {
|
||||
c = columnStr[j];
|
||||
cl = columnStr[j - 1];
|
||||
cn = columnStr[j + 1];
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function pushType(type) {
|
||||
if (dataTypes.length < column + 1) {
|
||||
dataTypes.push([type]);
|
||||
}
|
||||
if (dataTypes[column][dataTypes[column].length - 1] !== type) {
|
||||
dataTypes[column].push(type);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function push() {
|
||||
if (startColumn > actualColumn || actualColumn > endColumn) {
|
||||
// Skip this column, but increment the column count (#7272)
|
||||
++actualColumn;
|
||||
token = '';
|
||||
return;
|
||||
}
|
||||
// Save the type of the token.
|
||||
if (typeof token === 'string') {
|
||||
if (!isNaN(parseFloat(token)) && isFinite(token)) {
|
||||
token = parseFloat(token);
|
||||
pushType('number');
|
||||
}
|
||||
else if (!isNaN(Date.parse(token))) {
|
||||
token = token.replace(/\//g, '-');
|
||||
pushType('date');
|
||||
}
|
||||
else {
|
||||
pushType('string');
|
||||
}
|
||||
}
|
||||
else {
|
||||
pushType('number');
|
||||
}
|
||||
if (columns.length < column + 1) {
|
||||
columns.push([]);
|
||||
}
|
||||
// Try to apply the decimal point, and check if the token then is a
|
||||
// number. If not, reapply the initial value
|
||||
if (typeof token !== 'number' &&
|
||||
converter.guessType(token) !== 'number' &&
|
||||
decimalPoint) {
|
||||
var initialValue = token;
|
||||
token = token.replace(decimalPoint, '.');
|
||||
if (converter.guessType(token) !== 'number') {
|
||||
token = initialValue;
|
||||
}
|
||||
}
|
||||
columns[column][rowNumber] = token;
|
||||
token = '';
|
||||
++column;
|
||||
++actualColumn;
|
||||
}
|
||||
if (!columnStr.trim().length) {
|
||||
return;
|
||||
}
|
||||
if (columnStr.trim()[0] === '#') {
|
||||
return;
|
||||
}
|
||||
for (; i < columnStr.length; i++) {
|
||||
read(i);
|
||||
if (c === '#') {
|
||||
// If there are hexvalues remaining (#13283)
|
||||
if (!/^#[0-F]{3,3}|[0-F]{6,6}/i.test(columnStr.substr(i))) {
|
||||
// The rest of the row is a comment
|
||||
push();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Quoted string
|
||||
if (c === '"') {
|
||||
read(++i);
|
||||
while (i < columnStr.length) {
|
||||
if (c === '"' && cl !== '"' && cn !== '"') {
|
||||
break;
|
||||
}
|
||||
if (c !== '"' || (c === '"' && cl !== '"')) {
|
||||
token += c;
|
||||
}
|
||||
read(++i);
|
||||
}
|
||||
}
|
||||
else if (c === itemDelimiter) {
|
||||
push();
|
||||
// Actual column data
|
||||
}
|
||||
else {
|
||||
token += c;
|
||||
}
|
||||
}
|
||||
push();
|
||||
};
|
||||
/**
|
||||
* Internal method that guesses the delimiter from the first
|
||||
* 13 lines of the CSV
|
||||
* @param {Array<string>} lines
|
||||
* The CSV, split into lines
|
||||
*/
|
||||
CSVParser.prototype.guessDelimiter = function (lines) {
|
||||
var points = 0, commas = 0, guessed;
|
||||
var potDelimiters = {
|
||||
',': 0,
|
||||
';': 0,
|
||||
'\t': 0
|
||||
}, linesCount = lines.length;
|
||||
for (var i = 0; i < linesCount; i++) {
|
||||
var inStr = false, c = void 0, cn = void 0, cl = void 0, token = '';
|
||||
// We should be able to detect dateformats within 13 rows
|
||||
if (i > 13) {
|
||||
break;
|
||||
}
|
||||
var columnStr = lines[i];
|
||||
for (var j = 0; j < columnStr.length; j++) {
|
||||
c = columnStr[j];
|
||||
cn = columnStr[j + 1];
|
||||
cl = columnStr[j - 1];
|
||||
if (c === '#') {
|
||||
// Skip the rest of the line - it's a comment
|
||||
break;
|
||||
}
|
||||
if (c === '"') {
|
||||
if (inStr) {
|
||||
if (cl !== '"' && cn !== '"') {
|
||||
while (cn === ' ' && j < columnStr.length) {
|
||||
cn = columnStr[++j];
|
||||
}
|
||||
// After parsing a string, the next non-blank
|
||||
// should be a delimiter if the CSV is properly
|
||||
// formed.
|
||||
if (typeof potDelimiters[cn] !== 'undefined') {
|
||||
potDelimiters[cn]++;
|
||||
}
|
||||
inStr = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
inStr = true;
|
||||
}
|
||||
}
|
||||
else if (typeof potDelimiters[c] !== 'undefined') {
|
||||
token = token.trim();
|
||||
if (!isNaN(Date.parse(token))) {
|
||||
potDelimiters[c]++;
|
||||
}
|
||||
else if (isNaN(Number(token)) ||
|
||||
!isFinite(Number(token))) {
|
||||
potDelimiters[c]++;
|
||||
}
|
||||
token = '';
|
||||
}
|
||||
else {
|
||||
token += c;
|
||||
}
|
||||
if (c === ',') {
|
||||
commas++;
|
||||
}
|
||||
if (c === '.') {
|
||||
points++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Count the potential delimiters.
|
||||
// This could be improved by checking if the number of delimiters
|
||||
// equals the number of columns - 1
|
||||
if (potDelimiters[';'] > potDelimiters[',']) {
|
||||
guessed = ';';
|
||||
}
|
||||
else if (potDelimiters[','] > potDelimiters[';']) {
|
||||
guessed = ',';
|
||||
}
|
||||
else {
|
||||
// No good guess could be made..
|
||||
guessed = ',';
|
||||
}
|
||||
// Try to deduce the decimal point if it's not explicitly set.
|
||||
// If both commas or points is > 0 there is likely an issue
|
||||
if (points > commas) {
|
||||
this.guessedDecimalPoint = '.';
|
||||
}
|
||||
else {
|
||||
this.guessedDecimalPoint = ',';
|
||||
}
|
||||
return guessed;
|
||||
};
|
||||
/**
|
||||
* Handles converting the parsed data to a table.
|
||||
*
|
||||
* @return {DataTable}
|
||||
* Table from the parsed CSV.
|
||||
*/
|
||||
CSVParser.prototype.getTable = function () {
|
||||
return DataParser.getTableFromColumns(this.columns, this.headers);
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Default options
|
||||
*/
|
||||
CSVParser.defaultOptions = __assign(__assign({}, DataParser.defaultOptions), { lineDelimiter: '\n' });
|
||||
return CSVParser;
|
||||
}(DataParser));
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default CSVParser;
|
||||
@@ -0,0 +1,101 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2020-2022 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Sophie Bremer
|
||||
* - Sebastian Bochan
|
||||
* - Gøran Slettemark
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
import DataTable from '../DataTable.js';
|
||||
import U from '../../Core/Utilities.js';
|
||||
var addEvent = U.addEvent, fireEvent = U.fireEvent, uniqueKey = U.uniqueKey;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Abstract class providing an interface and basic methods for a DataParser
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var DataParser = /** @class */ (function () {
|
||||
function DataParser() {
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Static Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Converts an array of columns to a table instance. Second dimension of the
|
||||
* array are the row cells.
|
||||
*
|
||||
* @param {Array<DataTable.Column>} [columns]
|
||||
* Array to convert.
|
||||
*
|
||||
* @param {Array<string>} [headers]
|
||||
* Column names to use.
|
||||
*
|
||||
* @return {DataTable}
|
||||
* Table instance from the arrays.
|
||||
*/
|
||||
DataParser.getTableFromColumns = function (columns, headers) {
|
||||
if (columns === void 0) { columns = []; }
|
||||
if (headers === void 0) { headers = []; }
|
||||
var table = new DataTable();
|
||||
for (var i = 0, iEnd = Math.max(headers.length, columns.length); i < iEnd; ++i) {
|
||||
table.setColumn(headers[i] || "".concat(i), columns[i]);
|
||||
}
|
||||
return table;
|
||||
};
|
||||
/**
|
||||
* Emits an event on the DataParser instance.
|
||||
*
|
||||
* @param {DataParser.Event} [e]
|
||||
* Event object containing additional event data
|
||||
*/
|
||||
DataParser.prototype.emit = function (e) {
|
||||
fireEvent(this, e.type, e);
|
||||
};
|
||||
/**
|
||||
* Registers a callback for a specific parser event.
|
||||
*
|
||||
* @param {string} type
|
||||
* Event type as a string.
|
||||
*
|
||||
* @param {DataEventEmitter.EventCallback} callback
|
||||
* Function to register for an modifier callback.
|
||||
*
|
||||
* @return {Function}
|
||||
* Function to unregister callback from the modifier event.
|
||||
*/
|
||||
DataParser.prototype.on = function (type, callback) {
|
||||
return addEvent(this, type, callback);
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Default options
|
||||
*/
|
||||
DataParser.defaultOptions = {
|
||||
startColumn: 0,
|
||||
endColumn: Number.MAX_VALUE,
|
||||
startRow: 0,
|
||||
endRow: Number.MAX_VALUE,
|
||||
firstRowAsNames: true,
|
||||
switchRowsAndColumns: false
|
||||
};
|
||||
return DataParser;
|
||||
}());
|
||||
export default DataParser;
|
||||
@@ -0,0 +1,224 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2012-2021 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Torstein Hønsi
|
||||
* - Gøran Slettemark
|
||||
* - Wojciech Chmiel
|
||||
* - Sophie Bremer
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var __assign = (this && this.__assign) || function () {
|
||||
__assign = Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
import DataParser from './DataParser.js';
|
||||
import DataConverter from '../DataConverter.js';
|
||||
import U from '../../Core/Utilities.js';
|
||||
var merge = U.merge, uniqueKey = U.uniqueKey;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Handles parsing and transformation of an Google Sheets to a table.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var GoogleSheetsParser = /** @class */ (function (_super) {
|
||||
__extends(GoogleSheetsParser, _super);
|
||||
/* *
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructs an instance of the GoogleSheetsParser.
|
||||
*
|
||||
* @param {GoogleSheetsParser.OptionsType} [options]
|
||||
* Options for the Google Sheets parser.
|
||||
*
|
||||
* @param {DataConverter} converter
|
||||
* Parser data converter.
|
||||
*/
|
||||
function GoogleSheetsParser(options, converter) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this.columns = [];
|
||||
_this.headers = [];
|
||||
_this.options = merge(GoogleSheetsParser.defaultOptions, options);
|
||||
_this.converter = converter || new DataConverter();
|
||||
return _this;
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
GoogleSheetsParser.prototype.getSheetColumns = function (json) {
|
||||
var parser = this, _a = parser.options, startColumn = _a.startColumn, endColumn = _a.endColumn, startRow = _a.startRow, endRow = _a.endRow, columns = [], cells = json.feed.entry, cellCount = (cells || []).length;
|
||||
var cell, colCount = 0, rowCount = 0, val, gr, gc, cellInner, i, j;
|
||||
// First, find the total number of columns and rows that
|
||||
// are actually filled with data
|
||||
for (i = 0; i < cellCount; i++) {
|
||||
cell = cells[i];
|
||||
colCount = Math.max(colCount, cell.gs$cell.col);
|
||||
rowCount = Math.max(rowCount, cell.gs$cell.row);
|
||||
}
|
||||
// Set up arrays containing the column data
|
||||
for (i = 0; i < colCount; i++) {
|
||||
if (i >= startColumn && i <= endColumn) {
|
||||
// Create new columns with the length of either
|
||||
// end-start or rowCount
|
||||
columns[i - startColumn] = [];
|
||||
}
|
||||
}
|
||||
// Loop over the cells and assign the value to the right
|
||||
// place in the column arrays
|
||||
for (i = 0; i < cellCount; i++) {
|
||||
cell = cells[i];
|
||||
gr = cell.gs$cell.row - 1; // rows start at 1
|
||||
gc = cell.gs$cell.col - 1; // columns start at 1
|
||||
// If both row and col falls inside start and end set the
|
||||
// transposed cell value in the newly created columns
|
||||
if (gc >= startColumn && gc <= endColumn &&
|
||||
gr >= startRow && gr <= endRow) {
|
||||
cellInner = cell.gs$cell || cell.content;
|
||||
val = null;
|
||||
if (cellInner.numericValue) {
|
||||
if (cellInner.$t.indexOf('/') >= 0 || (cellInner.$t.indexOf('-') >= 0 &&
|
||||
cellInner.$t.indexOf('.') === -1)) {
|
||||
// This is a date - for future reference.
|
||||
val = cellInner.$t;
|
||||
}
|
||||
else if (cellInner.$t.indexOf('%') > 0) {
|
||||
// Percentage
|
||||
val = parseFloat(cellInner.numericValue) * 100;
|
||||
}
|
||||
else {
|
||||
val = parseFloat(cellInner.numericValue);
|
||||
}
|
||||
}
|
||||
else if (cellInner.$t && cellInner.$t.length) {
|
||||
val = cellInner.$t;
|
||||
}
|
||||
columns[gc - startColumn][gr - startRow] = val;
|
||||
}
|
||||
}
|
||||
// Insert null for empty spreadsheet cells (#5298)
|
||||
for (i = 0; i < colCount; i++) {
|
||||
var column = columns[i];
|
||||
// TODO: should this check be necessary?
|
||||
if (column.length) {
|
||||
for (i = 0; i < column.length; i++) {
|
||||
if (typeof column[i] === 'undefined') {
|
||||
column[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return columns;
|
||||
};
|
||||
/**
|
||||
* Initiates the parsing of the Google Sheet
|
||||
*
|
||||
* @param {GoogleSheetsParser.OptionsType}[options]
|
||||
* Options for the parser
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @emits GoogleSheetsParser#parse
|
||||
* @emits GoogleSheetsParser#afterParse
|
||||
*/
|
||||
GoogleSheetsParser.prototype.parse = function (jsonProp, eventDetail) {
|
||||
var parser = this, parserOptions = merge(true, parser.options, { json: jsonProp }), converter = parser.converter, json = parserOptions.json, cells = json.feed.entry, headers = parser.headers;
|
||||
var column;
|
||||
if (!cells || cells.length === 0) {
|
||||
return false;
|
||||
}
|
||||
parser.headers = [];
|
||||
parser.columns = [];
|
||||
parser.emit({
|
||||
type: 'parse',
|
||||
columns: parser.columns,
|
||||
detail: eventDetail,
|
||||
headers: parser.headers
|
||||
});
|
||||
parser.columns = parser.getSheetColumns(json);
|
||||
for (var i = 0, iEnd = parser.columns.length; i < iEnd; i++) {
|
||||
column = parser.columns[i];
|
||||
parser.headers[i] = parserOptions.firstRowAsNames ?
|
||||
column.splice(0, 1).toString() :
|
||||
uniqueKey();
|
||||
for (var j = 0, jEnd = column.length; j < jEnd; ++j) {
|
||||
if (column[j] && typeof column[j] === 'string') {
|
||||
var cellValue = converter.asGuessedType(column[j]);
|
||||
if (cellValue instanceof Date) {
|
||||
cellValue = cellValue.getTime();
|
||||
}
|
||||
parser.columns[i][j] = cellValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
parser.emit({
|
||||
type: 'afterParse',
|
||||
columns: parser.columns,
|
||||
detail: eventDetail,
|
||||
headers: parser.headers
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Handles converting the parsed data to a table.
|
||||
*
|
||||
* @return {DataTable}
|
||||
* Table from the parsed Google Sheet
|
||||
*/
|
||||
GoogleSheetsParser.prototype.getTable = function () {
|
||||
return DataParser.getTableFromColumns(this.columns, this.headers);
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Default options
|
||||
*/
|
||||
GoogleSheetsParser.defaultOptions = __assign(__assign({}, DataParser.defaultOptions), { json: {} });
|
||||
return GoogleSheetsParser;
|
||||
}(DataParser));
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default GoogleSheetsParser;
|
||||
@@ -0,0 +1,215 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2012-2021 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Torstein Hønsi
|
||||
* - Gøran Slettemark
|
||||
* - Wojciech Chmiel
|
||||
* - Sophie Bremer
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var __assign = (this && this.__assign) || function () {
|
||||
__assign = Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
import DataParser from './DataParser.js';
|
||||
import DataConverter from '../DataConverter.js';
|
||||
import U from '../../Core/Utilities.js';
|
||||
var merge = U.merge;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Handles parsing and transformation of an HTML table to a table.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var HTMLTableParser = /** @class */ (function (_super) {
|
||||
__extends(HTMLTableParser, _super);
|
||||
/* *
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructs an instance of the HTML table parser.
|
||||
*
|
||||
* @param {HTMLTableParser.OptionsType} [options]
|
||||
* Options for the CSV parser.
|
||||
*
|
||||
* @param {HTMLElement | null} tableElement
|
||||
* The HTML table to parse
|
||||
*
|
||||
* @param {DataConverter} converter
|
||||
* Parser data converter.
|
||||
*/
|
||||
function HTMLTableParser(options, tableElement, converter) {
|
||||
if (tableElement === void 0) { tableElement = null; }
|
||||
var _this = _super.call(this) || this;
|
||||
_this.columns = [];
|
||||
_this.headers = [];
|
||||
_this.options = merge(HTMLTableParser.defaultOptions, options);
|
||||
_this.converter = converter || new DataConverter();
|
||||
if (tableElement) {
|
||||
_this.tableElement = tableElement;
|
||||
_this.tableElementID = tableElement.id;
|
||||
}
|
||||
else if (options && options.tableHTML) {
|
||||
_this.tableElement = options.tableHTML;
|
||||
_this.tableElementID = options.tableHTML.id;
|
||||
}
|
||||
return _this;
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Initiates the parsing of the HTML table
|
||||
*
|
||||
* @param {HTMLTableParser.OptionsType}[options]
|
||||
* Options for the parser
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @emits CSVDataParser#parse
|
||||
* @emits CSVDataParser#afterParse
|
||||
* @emits HTMLTableParser#parseError
|
||||
*/
|
||||
HTMLTableParser.prototype.parse = function (options, eventDetail) {
|
||||
var parser = this, converter = this.converter, columns = [], headers = [], parseOptions = merge(parser.options, options), endRow = parseOptions.endRow, startColumn = parseOptions.startColumn, endColumn = parseOptions.endColumn, firstRowAsNames = parseOptions.firstRowAsNames, tableHTML = parseOptions.tableHTML || this.tableElement;
|
||||
if (!(tableHTML instanceof HTMLElement)) {
|
||||
parser.emit({
|
||||
type: 'parseError',
|
||||
columns: columns,
|
||||
detail: eventDetail,
|
||||
headers: headers,
|
||||
error: 'Not a valid HTML Table'
|
||||
});
|
||||
return;
|
||||
}
|
||||
parser.tableElement = this.tableElement;
|
||||
parser.tableElementID = tableHTML.id;
|
||||
this.emit({
|
||||
type: 'parse',
|
||||
columns: parser.columns,
|
||||
detail: eventDetail,
|
||||
headers: parser.headers
|
||||
});
|
||||
var rows = tableHTML.getElementsByTagName('tr'), rowsCount = rows.length;
|
||||
var rowIndex = 0, item, startRow = parseOptions.startRow;
|
||||
// Insert headers from the first row
|
||||
if (firstRowAsNames && rowsCount) {
|
||||
var items = rows[0].children, itemsLength = items.length;
|
||||
for (var i = startColumn; i < itemsLength; i++) {
|
||||
if (i > endColumn) {
|
||||
break;
|
||||
}
|
||||
item = items[i];
|
||||
if (item.tagName === 'TD' ||
|
||||
item.tagName === 'TH') {
|
||||
headers.push(item.innerHTML);
|
||||
}
|
||||
}
|
||||
startRow++;
|
||||
}
|
||||
while (rowIndex < rowsCount) {
|
||||
if (rowIndex >= startRow && rowIndex <= endRow) {
|
||||
var columnsInRow = rows[rowIndex].children, columnsInRowLength = columnsInRow.length;
|
||||
var columnIndex = 0;
|
||||
while (columnIndex < columnsInRowLength) {
|
||||
var relativeColumnIndex = columnIndex - startColumn, row = columns[relativeColumnIndex];
|
||||
item = columnsInRow[columnIndex];
|
||||
if ((item.tagName === 'TD' ||
|
||||
item.tagName === 'TH') &&
|
||||
(columnIndex >= startColumn &&
|
||||
columnIndex <= endColumn)) {
|
||||
if (!columns[relativeColumnIndex]) {
|
||||
columns[relativeColumnIndex] = [];
|
||||
}
|
||||
var cellValue = converter.asGuessedType(item.innerHTML);
|
||||
if (cellValue instanceof Date) {
|
||||
cellValue = cellValue.getTime();
|
||||
}
|
||||
columns[relativeColumnIndex][rowIndex - startRow] = cellValue;
|
||||
// Loop over all previous indices and make sure
|
||||
// they are nulls, not undefined.
|
||||
var i = 1;
|
||||
while (rowIndex - startRow >= i &&
|
||||
row[rowIndex - startRow - i] === void 0) {
|
||||
row[rowIndex - startRow - i] = null;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
columnIndex++;
|
||||
}
|
||||
}
|
||||
rowIndex++;
|
||||
}
|
||||
this.columns = columns;
|
||||
this.headers = headers;
|
||||
this.emit({
|
||||
type: 'afterParse',
|
||||
columns: columns,
|
||||
detail: eventDetail,
|
||||
headers: headers
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Handles converting the parsed data to a table.
|
||||
*
|
||||
* @return {DataTable}
|
||||
* Table from the parsed HTML table
|
||||
*/
|
||||
HTMLTableParser.prototype.getTable = function () {
|
||||
return DataParser.getTableFromColumns(this.columns, this.headers);
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Default options
|
||||
*/
|
||||
HTMLTableParser.defaultOptions = __assign({}, DataParser.defaultOptions);
|
||||
return HTMLTableParser;
|
||||
}(DataParser));
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default HTMLTableParser;
|
||||
320
static/lib/Highcharts-10.2.1/es-modules/Data/Stores/CSVStore.js
Normal file
320
static/lib/Highcharts-10.2.1/es-modules/Data/Stores/CSVStore.js
Normal file
@@ -0,0 +1,320 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2012-2021 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Torstein Hønsi
|
||||
* - Christer Vasseng
|
||||
* - Gøran Slettemark
|
||||
* - Sophie Bremer
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
import CSVParser from '../Parsers/CSVParser.js';
|
||||
import DataStore from './DataStore.js';
|
||||
import DataTable from '../DataTable.js';
|
||||
import HU from '../../Core/HttpUtilities.js';
|
||||
var ajax = HU.ajax;
|
||||
import U from '../../Core/Utilities.js';
|
||||
var merge = U.merge, objectEach = U.objectEach;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/* eslint-disable no-invalid-this, require-jsdoc, valid-jsdoc */
|
||||
/**
|
||||
* Class that handles creating a datastore from CSV
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var CSVStore = /** @class */ (function (_super) {
|
||||
__extends(CSVStore, _super);
|
||||
/* *
|
||||
*
|
||||
* Constructors
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructs an instance of CSVDataStore.
|
||||
*
|
||||
* @param {DataTable} table
|
||||
* Optional table to create the store from.
|
||||
*
|
||||
* @param {CSVStore.OptionsType} options
|
||||
* Options for the store and parser.
|
||||
*
|
||||
* @param {DataParser} parser
|
||||
* Optional parser to replace the default parser.
|
||||
*/
|
||||
function CSVStore(table, options, parser) {
|
||||
if (table === void 0) { table = new DataTable(); }
|
||||
if (options === void 0) { options = {}; }
|
||||
var _this = _super.call(this, table) || this;
|
||||
var csv = options.csv, csvURL = options.csvURL, enablePolling = options.enablePolling, dataRefreshRate = options.dataRefreshRate, parserOptions = __rest(options, ["csv", "csvURL", "enablePolling", "dataRefreshRate"]);
|
||||
_this.parserOptions = parserOptions;
|
||||
_this.options = merge(CSVStore.defaultOptions, { csv: csv, csvURL: csvURL, enablePolling: enablePolling, dataRefreshRate: dataRefreshRate });
|
||||
_this.parser = parser || new CSVParser(parserOptions);
|
||||
return _this;
|
||||
}
|
||||
/**
|
||||
* Handles polling of live data
|
||||
*/
|
||||
CSVStore.prototype.poll = function () {
|
||||
var _this = this;
|
||||
var _a = this.options, dataRefreshRate = _a.dataRefreshRate, enablePolling = _a.enablePolling, csvURL = _a.csvURL;
|
||||
var updateIntervalMs = (dataRefreshRate > 1 ? dataRefreshRate : 1) * 1000;
|
||||
if (enablePolling && csvURL === this.liveDataURL) {
|
||||
// We need to stop doing this if the URL has changed
|
||||
this.liveDataTimeout = setTimeout(function () {
|
||||
_this.fetchCSV();
|
||||
}, updateIntervalMs);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Fetches CSV from external source
|
||||
*
|
||||
* @param {boolean} initialFetch
|
||||
* Indicates whether this is a single fetch or a repeated fetch
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @emits CSVDataStore#load
|
||||
* @emits CSVDataStore#afterLoad
|
||||
* @emits CSVDataStore#loadError
|
||||
*/
|
||||
CSVStore.prototype.fetchCSV = function (initialFetch, eventDetail) {
|
||||
var store = this, maxRetries = 3, csvURL = store.options.csvURL;
|
||||
var currentRetries;
|
||||
// Clear the table
|
||||
store.table.deleteColumns();
|
||||
if (initialFetch) {
|
||||
clearTimeout(store.liveDataTimeout);
|
||||
store.liveDataURL = csvURL;
|
||||
}
|
||||
store.emit({ type: 'load', detail: eventDetail, table: store.table });
|
||||
ajax({
|
||||
url: store.liveDataURL || '',
|
||||
dataType: 'text',
|
||||
success: function (csv) {
|
||||
csv = "".concat(csv);
|
||||
store.parser.parse({ csv: csv });
|
||||
// On inital fetch we need to set the columns
|
||||
store.table.setColumns(store.parser.getTable().getColumns());
|
||||
if (store.liveDataURL) {
|
||||
store.poll();
|
||||
}
|
||||
store.emit({
|
||||
type: 'afterLoad',
|
||||
csv: csv,
|
||||
detail: eventDetail,
|
||||
table: store.table
|
||||
});
|
||||
},
|
||||
error: function (xhr, error) {
|
||||
if (++currentRetries < maxRetries) {
|
||||
store.poll();
|
||||
}
|
||||
store.emit({
|
||||
type: 'loadError',
|
||||
detail: eventDetail,
|
||||
error: error,
|
||||
table: store.table,
|
||||
xhr: xhr
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Initiates the loading of the CSV source to the store
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @emits CSVParser#load
|
||||
* @emits CSVParser#afterLoad
|
||||
*/
|
||||
CSVStore.prototype.load = function (eventDetail) {
|
||||
var store = this, parser = store.parser, table = store.table, _a = store.options, csv = _a.csv, csvURL = _a.csvURL;
|
||||
if (csv) {
|
||||
// If already loaded, clear the current rows
|
||||
table.deleteRows();
|
||||
store.emit({
|
||||
type: 'load',
|
||||
csv: csv,
|
||||
detail: eventDetail,
|
||||
table: table
|
||||
});
|
||||
parser.parse({ csv: csv });
|
||||
table.setColumns(parser.getTable().getColumns());
|
||||
store.emit({
|
||||
type: 'afterLoad',
|
||||
csv: csv,
|
||||
detail: eventDetail,
|
||||
table: table
|
||||
});
|
||||
}
|
||||
else if (csvURL) {
|
||||
store.fetchCSV(true, eventDetail);
|
||||
}
|
||||
else {
|
||||
store.emit({
|
||||
type: 'loadError',
|
||||
detail: eventDetail,
|
||||
error: 'Unable to load: no CSV string or URL was provided',
|
||||
table: table
|
||||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Creates a CSV string from the datatable on the store instance.
|
||||
*
|
||||
* @param {CSVStore.ExportOptions} exportOptions
|
||||
* The options used for the export.
|
||||
*
|
||||
* @return {string}
|
||||
* A CSV string from the table.
|
||||
*/
|
||||
CSVStore.prototype.getCSVForExport = function (exportOptions) {
|
||||
var useLocalDecimalPoint = exportOptions.useLocalDecimalPoint, lineDelimiter = exportOptions.lineDelimiter, exportNames = (this.parserOptions.firstRowAsNames !== false);
|
||||
var decimalPoint = exportOptions.decimalPoint, itemDelimiter = exportOptions.itemDelimiter;
|
||||
if (!decimalPoint) {
|
||||
decimalPoint = itemDelimiter !== ',' && useLocalDecimalPoint ?
|
||||
(1.1).toLocaleString()[1] :
|
||||
'.';
|
||||
}
|
||||
if (!itemDelimiter) {
|
||||
itemDelimiter = decimalPoint === ',' ? ';' : ',';
|
||||
}
|
||||
var _a = this.getColumnsForExport(exportOptions.usePresentationOrder), columnNames = _a.columnNames, columnValues = _a.columnValues;
|
||||
var csvRows = [], columnsCount = columnNames.length;
|
||||
var rowArray = [];
|
||||
// Add the names as the first row if they should be exported
|
||||
if (exportNames) {
|
||||
csvRows.push(columnNames.map(function (columnName) { return "\"".concat(columnName, "\""); }).join(itemDelimiter));
|
||||
}
|
||||
for (var columnIndex = 0; columnIndex < columnsCount; columnIndex++) {
|
||||
var columnName = columnNames[columnIndex], column = columnValues[columnIndex], columnLength = column.length;
|
||||
var columnMeta = this.whatIs(columnName);
|
||||
var columnDataType = void 0;
|
||||
if (columnMeta) {
|
||||
columnDataType = columnMeta.dataType;
|
||||
}
|
||||
for (var rowIndex = 0; rowIndex < columnLength; rowIndex++) {
|
||||
var cellValue = column[rowIndex];
|
||||
if (!rowArray[rowIndex]) {
|
||||
rowArray[rowIndex] = [];
|
||||
}
|
||||
// Prefer datatype from metadata
|
||||
if (columnDataType === 'string') {
|
||||
cellValue = "\"".concat(cellValue, "\"");
|
||||
}
|
||||
else if (typeof cellValue === 'number') {
|
||||
cellValue = String(cellValue).replace('.', decimalPoint);
|
||||
}
|
||||
else if (typeof cellValue === 'string') {
|
||||
cellValue = "\"".concat(cellValue, "\"");
|
||||
}
|
||||
rowArray[rowIndex][columnIndex] = cellValue;
|
||||
// On the final column, push the row to the CSV
|
||||
if (columnIndex === columnsCount - 1) {
|
||||
// Trim repeated undefined values starting at the end
|
||||
// Currently, we export the first "comma" even if the
|
||||
// second value is undefined
|
||||
var i = columnIndex;
|
||||
while (rowArray[rowIndex].length > 2) {
|
||||
var cellVal = rowArray[rowIndex][i];
|
||||
if (cellVal !== void 0) {
|
||||
break;
|
||||
}
|
||||
rowArray[rowIndex].pop();
|
||||
i--;
|
||||
}
|
||||
csvRows.push(rowArray[rowIndex].join(itemDelimiter));
|
||||
}
|
||||
}
|
||||
}
|
||||
return csvRows.join(lineDelimiter);
|
||||
};
|
||||
/**
|
||||
* Exports the datastore as a CSV string, using the options
|
||||
* provided on import unless other options are provided.
|
||||
*
|
||||
* @param {CSVStore.ExportOptions} [csvExportOptions]
|
||||
* Options to use instead of those used on import.
|
||||
*
|
||||
* @return {string}
|
||||
* CSV from the store's current table.
|
||||
*
|
||||
*/
|
||||
CSVStore.prototype.save = function (csvExportOptions) {
|
||||
var exportOptions = CSVStore.defaultExportOptions;
|
||||
// Merge in the provided parser options
|
||||
objectEach(this.parserOptions, function (value, key) {
|
||||
if (key in exportOptions) {
|
||||
exportOptions[key] = value;
|
||||
}
|
||||
});
|
||||
return this.getCSVForExport(merge(exportOptions, csvExportOptions));
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
CSVStore.defaultOptions = {
|
||||
csv: '',
|
||||
csvURL: '',
|
||||
enablePolling: false,
|
||||
dataRefreshRate: 1
|
||||
};
|
||||
CSVStore.defaultExportOptions = {
|
||||
decimalPoint: null,
|
||||
itemDelimiter: null,
|
||||
lineDelimiter: '\n'
|
||||
};
|
||||
return CSVStore;
|
||||
}(DataStore));
|
||||
/* *
|
||||
*
|
||||
* Registry
|
||||
*
|
||||
* */
|
||||
DataStore.addStore(CSVStore);
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default CSVStore;
|
||||
276
static/lib/Highcharts-10.2.1/es-modules/Data/Stores/DataStore.js
Normal file
276
static/lib/Highcharts-10.2.1/es-modules/Data/Stores/DataStore.js
Normal file
@@ -0,0 +1,276 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2020-2022 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Sophie Bremer
|
||||
* - Wojciech Chmiel
|
||||
* - Gøran Slettemark
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
import DataTable from '../DataTable.js';
|
||||
import U from '../../Core/Utilities.js';
|
||||
var addEvent = U.addEvent, fireEvent = U.fireEvent, merge = U.merge, pick = U.pick;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Abstract class providing an interface for managing a DataStore.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var DataStore = /** @class */ (function () {
|
||||
/* *
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructor for the store class.
|
||||
*
|
||||
* @param {DataTable} table
|
||||
* Optional table to use in the store.
|
||||
*
|
||||
* @param {DataStore.Metadata} metadata
|
||||
* Optional metadata to use in the store.
|
||||
*/
|
||||
function DataStore(table, metadata) {
|
||||
if (table === void 0) { table = new DataTable(); }
|
||||
if (metadata === void 0) { metadata = { columns: {} }; }
|
||||
this.table = table;
|
||||
this.metadata = metadata;
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Static Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Adds a store class to the registry. The store has to provide the
|
||||
* `DataStore.options` property and the `DataStore.load` method to
|
||||
* modify the table.
|
||||
*
|
||||
* @param {DataStore} dataStore
|
||||
* Store class (aka class constructor) to register.
|
||||
*
|
||||
* @return {boolean}
|
||||
* Returns true, if the registration was successful. False is returned, if
|
||||
* their is already a store registered with this name.
|
||||
*/
|
||||
DataStore.addStore = function (dataStore) {
|
||||
var name = DataStore.getName(dataStore), registry = DataStore.registry;
|
||||
if (typeof name === 'undefined' ||
|
||||
registry[name]) {
|
||||
return false;
|
||||
}
|
||||
registry[name] = dataStore;
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
* Returns all registered dataStore names.
|
||||
*
|
||||
* @return {Array<string>}
|
||||
* All registered store names.
|
||||
*/
|
||||
DataStore.getAllStoreNames = function () {
|
||||
return Object.keys(DataStore.registry);
|
||||
};
|
||||
/**
|
||||
* Returns a copy of the dataStore registry as record object with
|
||||
* dataStore names and their dataStore class.
|
||||
*
|
||||
* @return {Record<string,DataStoreRegistryType>}
|
||||
* Copy of the dataStore registry.
|
||||
*/
|
||||
DataStore.getAllStores = function () {
|
||||
return merge(DataStore.registry);
|
||||
};
|
||||
/**
|
||||
* Extracts the name from a given dataStore class.
|
||||
*
|
||||
* @param {DataStore} dataStore
|
||||
* DataStore class to extract the name from.
|
||||
*
|
||||
* @return {string}
|
||||
* DataStore name, if the extraction was successful, otherwise an empty
|
||||
* string.
|
||||
*/
|
||||
DataStore.getName = function (dataStore) {
|
||||
return (dataStore.toString().match(DataStore.nameRegExp) ||
|
||||
['', ''])[1];
|
||||
};
|
||||
/**
|
||||
* Returns a dataStore class (aka class constructor) of the given dataStore
|
||||
* name.
|
||||
*
|
||||
* @param {string} name
|
||||
* Registered class name of the class type.
|
||||
*
|
||||
* @return {DataStoreRegistryType|undefined}
|
||||
* Class type, if the class name was found, otherwise `undefined`.
|
||||
*/
|
||||
DataStore.getStore = function (name) {
|
||||
return DataStore.registry[name];
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Method for adding metadata for a single column.
|
||||
*
|
||||
* @param {string} name
|
||||
* The name of the column to be described.
|
||||
*
|
||||
* @param {DataStore.MetaColumn} columnMeta
|
||||
* The metadata to apply to the column.
|
||||
*/
|
||||
DataStore.prototype.describeColumn = function (name, columnMeta) {
|
||||
var store = this, columns = store.metadata.columns;
|
||||
columns[name] = merge(columns[name] || {}, columnMeta);
|
||||
};
|
||||
/**
|
||||
* Method for applying columns meta information to the whole datastore.
|
||||
*
|
||||
* @param {Record<string, DataStore.MetaColumn>} columns
|
||||
* Pairs of column names and MetaColumn objects.
|
||||
*/
|
||||
DataStore.prototype.describeColumns = function (columns) {
|
||||
var store = this, columnNames = Object.keys(columns);
|
||||
var columnName;
|
||||
while (typeof (columnName = columnNames.pop()) === 'string') {
|
||||
store.describeColumn(columnName, columns[columnName]);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Emits an event on the store to all registered callbacks of this event.
|
||||
*
|
||||
* @param {DataStore.Event} [e]
|
||||
* Event object containing additional event information.
|
||||
*/
|
||||
DataStore.prototype.emit = function (e) {
|
||||
fireEvent(this, e.type, e);
|
||||
};
|
||||
/**
|
||||
* Returns the order of columns.
|
||||
*
|
||||
* @param {boolean} [usePresentationState]
|
||||
* Whether to use the column order of the presentation state of the table.
|
||||
*
|
||||
* @return {Array<string>}
|
||||
* Order of columns.
|
||||
*/
|
||||
DataStore.prototype.getColumnOrder = function (usePresentationState) {
|
||||
var store = this, metadata = store.metadata, columns = metadata.columns, columnNames = Object.keys(columns), columnOrder = [];
|
||||
var columnName;
|
||||
for (var i = 0, iEnd = columnNames.length; i < iEnd; ++i) {
|
||||
columnName = columnNames[i];
|
||||
columnOrder[pick(columns[columnName].index, i)] = columnName;
|
||||
}
|
||||
return columnOrder;
|
||||
};
|
||||
/**
|
||||
* Retrieves the columns of the the dataTable,
|
||||
* applies column order from meta.
|
||||
*
|
||||
* @param {boolean} [usePresentationOrder]
|
||||
* Whether to use the column order of the presentation state of the table.
|
||||
*
|
||||
* @return {{}}
|
||||
* An object with the properties `columnNames` and `columnValues`
|
||||
*/
|
||||
DataStore.prototype.getColumnsForExport = function (usePresentationOrder) {
|
||||
var table = this.table, columnsRecord = table.getColumns(), columnNames = table.getColumnNames();
|
||||
var columnOrder = this.getColumnOrder(usePresentationOrder);
|
||||
if (columnOrder.length) {
|
||||
columnNames.sort(function (a, b) {
|
||||
if (columnOrder.indexOf(a) < columnOrder.indexOf(b)) {
|
||||
return 1;
|
||||
}
|
||||
if (columnOrder.indexOf(a) > columnOrder.indexOf(b)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
return ({
|
||||
columnNames: columnNames,
|
||||
columnValues: columnNames.map(function (name) { return columnsRecord[name]; })
|
||||
});
|
||||
};
|
||||
/**
|
||||
* The default load method, which fires the `afterLoad` event
|
||||
* @emits DataStore#afterLoad
|
||||
*/
|
||||
DataStore.prototype.load = function () {
|
||||
fireEvent(this, 'afterLoad', { table: this.table });
|
||||
};
|
||||
/**
|
||||
* Registers a callback for a specific store event.
|
||||
*
|
||||
* @param {string} type
|
||||
* Event type as a string.
|
||||
*
|
||||
* @param {DataEventEmitter.EventCallback} callback
|
||||
* Function to register for the store callback.
|
||||
*
|
||||
* @return {Function}
|
||||
* Function to unregister callback from the store event.
|
||||
*/
|
||||
DataStore.prototype.on = function (type, callback) {
|
||||
return addEvent(this, type, callback);
|
||||
};
|
||||
/**
|
||||
* Sets the index and order of columns.
|
||||
*
|
||||
* @param {Array<string>} columnNames
|
||||
* Order of columns.
|
||||
*/
|
||||
DataStore.prototype.setColumnOrder = function (columnNames) {
|
||||
var store = this;
|
||||
for (var i = 0, iEnd = columnNames.length; i < iEnd; ++i) {
|
||||
store.describeColumn(columnNames[i], { index: i });
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Method for retriving metadata from a single column.
|
||||
*
|
||||
* @param {string} name
|
||||
* The identifier for the column that should be described
|
||||
*
|
||||
* @return {DataStore.MetaColumn | undefined}
|
||||
* Returns a MetaColumn object if found.
|
||||
*/
|
||||
DataStore.prototype.whatIs = function (name) {
|
||||
return this.metadata.columns[name];
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Registry as a record object with store names and their class.
|
||||
*/
|
||||
DataStore.registry = {};
|
||||
/**
|
||||
* Regular expression to extract the store name (group 1) from the
|
||||
* stringified class type.
|
||||
*/
|
||||
DataStore.nameRegExp = (/^function\s+(\w*?)(?:DataStore)?\s*\(/);
|
||||
return DataStore;
|
||||
}());
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default DataStore;
|
||||
@@ -0,0 +1,171 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2012-2021 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Torstein Hønsi
|
||||
* - Gøran Slettemark
|
||||
* - Wojciech Chmiel
|
||||
* - Sophie Bremer
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
import DataStore from './DataStore.js';
|
||||
import GoogleSheetsParser from '../Parsers/GoogleSheetsParser.js';
|
||||
import HU from '../../Core/HttpUtilities.js';
|
||||
var ajax = HU.ajax;
|
||||
import U from '../../Core/Utilities.js';
|
||||
var merge = U.merge;
|
||||
/* *
|
||||
*
|
||||
* Class
|
||||
*
|
||||
* *7
|
||||
|
||||
/* eslint-disable no-invalid-this, require-jsdoc, valid-jsdoc */
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
var GoogleSheetsStore = /** @class */ (function (_super) {
|
||||
__extends(GoogleSheetsStore, _super);
|
||||
/* *
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructs an instance of GoogleSheetsStore
|
||||
*
|
||||
* @param {DataTable} table
|
||||
* Optional table to create the store from.
|
||||
*
|
||||
* @param {CSVStore.OptionsType} options
|
||||
* Options for the store and parser.
|
||||
*
|
||||
* @param {DataParser} parser
|
||||
* Optional parser to replace the default parser
|
||||
*/
|
||||
function GoogleSheetsStore(table, options, parser) {
|
||||
var _this = _super.call(this, table) || this;
|
||||
_this.options = merge(GoogleSheetsStore.defaultOptions, options);
|
||||
_this.parser = parser || new GoogleSheetsParser({
|
||||
firstRowAsNames: _this.options.firstRowAsNames
|
||||
});
|
||||
return _this;
|
||||
}
|
||||
/* *
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*/
|
||||
GoogleSheetsStore.prototype.fetchSheet = function (eventDetail) {
|
||||
var store = this, _a = store.options, enablePolling = _a.enablePolling, dataRefreshRate = _a.dataRefreshRate, googleSpreadsheetKey = _a.googleSpreadsheetKey, worksheet = _a.worksheet, url = [
|
||||
'https://spreadsheets.google.com/feeds/cells',
|
||||
googleSpreadsheetKey,
|
||||
worksheet,
|
||||
'public/values?alt=json'
|
||||
].join('/');
|
||||
// If already loaded, clear the current table
|
||||
store.table.deleteColumns();
|
||||
store.emit({
|
||||
type: 'load',
|
||||
detail: eventDetail,
|
||||
table: store.table,
|
||||
url: url
|
||||
});
|
||||
ajax({
|
||||
url: url,
|
||||
dataType: 'json',
|
||||
success: function (json) {
|
||||
store.parser.parse(json);
|
||||
store.table.setColumns(store.parser.getTable().getColumns());
|
||||
// Polling
|
||||
if (enablePolling) {
|
||||
setTimeout(function () {
|
||||
store.fetchSheet();
|
||||
}, dataRefreshRate * 1000);
|
||||
}
|
||||
store.emit({
|
||||
type: 'afterLoad',
|
||||
detail: eventDetail,
|
||||
table: store.table,
|
||||
url: url
|
||||
});
|
||||
},
|
||||
error: function (xhr, error) {
|
||||
/* *
|
||||
* TODO:
|
||||
* catch error
|
||||
* ...
|
||||
*
|
||||
* */
|
||||
// console.log(text);
|
||||
store.emit({
|
||||
type: 'loadError',
|
||||
detail: eventDetail,
|
||||
error: error,
|
||||
table: store.table,
|
||||
xhr: xhr
|
||||
});
|
||||
}
|
||||
});
|
||||
// return true;
|
||||
};
|
||||
/**
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*/
|
||||
GoogleSheetsStore.prototype.load = function (eventDetail) {
|
||||
if (this.options.googleSpreadsheetKey) {
|
||||
this.fetchSheet(eventDetail);
|
||||
}
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
GoogleSheetsStore.defaultOptions = {
|
||||
googleSpreadsheetKey: '',
|
||||
worksheet: 1,
|
||||
enablePolling: false,
|
||||
dataRefreshRate: 2,
|
||||
firstRowAsNames: true
|
||||
};
|
||||
return GoogleSheetsStore;
|
||||
}(DataStore));
|
||||
/* *
|
||||
*
|
||||
* Registry
|
||||
*
|
||||
* */
|
||||
DataStore.addStore(GoogleSheetsStore);
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default GoogleSheetsStore;
|
||||
@@ -0,0 +1,355 @@
|
||||
/* *
|
||||
*
|
||||
* (c) 2012-2021 Highsoft AS
|
||||
*
|
||||
* License: www.highcharts.com/license
|
||||
*
|
||||
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
||||
*
|
||||
* Authors:
|
||||
* - Torstein Hønsi
|
||||
* - Gøran Slettemark
|
||||
* - Wojciech Chmiel
|
||||
* - Sophie Bremer
|
||||
*
|
||||
* */
|
||||
'use strict';
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
import DataStore from './DataStore.js';
|
||||
import DataTable from '../DataTable.js';
|
||||
import H from '../../Core/Globals.js';
|
||||
var win = H.win;
|
||||
import HTMLTableParser from '../Parsers/HTMLTableParser.js';
|
||||
import U from '../../Core/Utilities.js';
|
||||
var merge = U.merge, objectEach = U.objectEach;
|
||||
/** eslint-disable valid-jsdoc */
|
||||
/**
|
||||
* Class that handles creating a datastore from an HTML table
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var HTMLTableStore = /** @class */ (function (_super) {
|
||||
__extends(HTMLTableStore, _super);
|
||||
/* *
|
||||
*
|
||||
* Constructors
|
||||
*
|
||||
* */
|
||||
/**
|
||||
* Constructs an instance of HTMLTableDataStore
|
||||
*
|
||||
* @param {DataTable} table
|
||||
* Optional table to create the store from
|
||||
*
|
||||
* @param {HTMLTableStore.OptionsType} options
|
||||
* Options for the store and parser
|
||||
*
|
||||
* @param {DataParser} parser
|
||||
* Optional parser to replace the default parser
|
||||
*/
|
||||
function HTMLTableStore(table, options, parser) {
|
||||
if (table === void 0) { table = new DataTable(); }
|
||||
if (options === void 0) { options = {}; }
|
||||
var _this = _super.call(this, table) || this;
|
||||
_this.tableElement = null;
|
||||
_this.options = merge(HTMLTableStore.defaultOptions, options);
|
||||
_this.parserOptions = _this.options;
|
||||
_this.parser = parser || new HTMLTableParser(_this.options, _this.tableElement);
|
||||
return _this;
|
||||
}
|
||||
/**
|
||||
* Handles retrieving the HTML table by ID if an ID is provided
|
||||
*/
|
||||
HTMLTableStore.prototype.fetchTable = function () {
|
||||
var store = this, tableHTML = store.options.table;
|
||||
var tableElement;
|
||||
if (typeof tableHTML === 'string') {
|
||||
store.tableID = tableHTML;
|
||||
tableElement = win.document.getElementById(tableHTML);
|
||||
}
|
||||
else {
|
||||
tableElement = tableHTML;
|
||||
store.tableID = tableElement.id;
|
||||
}
|
||||
store.tableElement = tableElement;
|
||||
};
|
||||
/**
|
||||
* Initiates creating the datastore from the HTML table
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @emits HTMLTableDataStore#load
|
||||
* @emits HTMLTableDataStore#afterLoad
|
||||
* @emits HTMLTableDataStore#loadError
|
||||
*/
|
||||
HTMLTableStore.prototype.load = function (eventDetail) {
|
||||
var store = this;
|
||||
store.fetchTable();
|
||||
// If already loaded, clear the current rows
|
||||
store.table.deleteColumns();
|
||||
store.emit({
|
||||
type: 'load',
|
||||
detail: eventDetail,
|
||||
table: store.table,
|
||||
tableElement: store.tableElement
|
||||
});
|
||||
if (!store.tableElement) {
|
||||
store.emit({
|
||||
type: 'loadError',
|
||||
detail: eventDetail,
|
||||
error: 'HTML table not provided, or element with ID not found',
|
||||
table: store.table
|
||||
});
|
||||
return;
|
||||
}
|
||||
store.parser.parse(merge({ tableHTML: store.tableElement }, store.options), eventDetail);
|
||||
store.table.setColumns(store.parser.getTable().getColumns());
|
||||
store.emit({
|
||||
type: 'afterLoad',
|
||||
detail: eventDetail,
|
||||
table: store.table,
|
||||
tableElement: store.tableElement
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Creates an HTML table from the datatable on the store instance.
|
||||
*
|
||||
* @param {HTMLTableStore.ExportOptions} [exportOptions]
|
||||
* Options used for exporting.
|
||||
*
|
||||
* @return {string}
|
||||
* The HTML table.
|
||||
*/
|
||||
HTMLTableStore.prototype.getHTMLTableForExport = function (exportOptions) {
|
||||
if (exportOptions === void 0) { exportOptions = {}; }
|
||||
var options = exportOptions, decimalPoint = options.useLocalDecimalPoint ?
|
||||
(1.1).toLocaleString()[1] :
|
||||
'.', exportNames = (this.parserOptions.firstRowAsNames !== false), useMultiLevelHeaders = options.useMultiLevelHeaders, useRowspanHeaders = options.useRowspanHeaders;
|
||||
var isRowEqual = function (row1, row2) {
|
||||
var i = row1.length;
|
||||
if (row2.length === i) {
|
||||
while (i--) {
|
||||
if (row1[i] !== row2[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
// Get table header markup from row data
|
||||
var getTableHeaderHTML = function (topheaders, subheaders, rowLength) {
|
||||
var html = '<thead>', i = 0, len = rowLength || subheaders && subheaders.length, next, cur, curColspan = 0, rowspan;
|
||||
// Clean up multiple table headers. Chart.getDataRows() returns two
|
||||
// levels of headers when using multilevel, not merged. We need to
|
||||
// merge identical headers, remove redundant headers, and keep it
|
||||
// all marked up nicely.
|
||||
if (useMultiLevelHeaders &&
|
||||
topheaders &&
|
||||
subheaders &&
|
||||
!isRowEqual(topheaders, subheaders)) {
|
||||
html += '<tr>';
|
||||
for (; i < len; ++i) {
|
||||
cur = topheaders[i];
|
||||
next = topheaders[i + 1];
|
||||
if (cur === next) {
|
||||
++curColspan;
|
||||
}
|
||||
else if (curColspan) {
|
||||
// Ended colspan
|
||||
// Add cur to HTML with colspan.
|
||||
html += getCellHTMLFromValue('th', 'highcharts-table-topheading', 'scope="col" ' +
|
||||
'colspan="' + (curColspan + 1) + '"', cur);
|
||||
curColspan = 0;
|
||||
}
|
||||
else {
|
||||
// Cur is standalone. If it is same as sublevel,
|
||||
// remove sublevel and add just toplevel.
|
||||
if (cur === subheaders[i]) {
|
||||
if (useRowspanHeaders) {
|
||||
rowspan = 2;
|
||||
delete subheaders[i];
|
||||
}
|
||||
else {
|
||||
rowspan = 1;
|
||||
subheaders[i] = '';
|
||||
}
|
||||
}
|
||||
else {
|
||||
rowspan = 1;
|
||||
}
|
||||
html += getCellHTMLFromValue('th', 'highcharts-table-topheading', 'scope="col"' +
|
||||
(rowspan > 1 ?
|
||||
' valign="top" rowspan="' + rowspan + '"' :
|
||||
''), cur);
|
||||
}
|
||||
}
|
||||
html += '</tr>';
|
||||
}
|
||||
// Add the subheaders (the only headers if not using multilevels)
|
||||
if (subheaders) {
|
||||
html += '<tr>';
|
||||
for (i = 0, len = subheaders.length; i < len; ++i) {
|
||||
if (typeof subheaders[i] !== 'undefined') {
|
||||
html += getCellHTMLFromValue('th', null, 'scope="col"', subheaders[i]);
|
||||
}
|
||||
}
|
||||
html += '</tr>';
|
||||
}
|
||||
html += '</thead>';
|
||||
return html;
|
||||
};
|
||||
var getCellHTMLFromValue = function (tag, classes, attrs, value) {
|
||||
var val = value, className = 'text' + (classes ? ' ' + classes : '');
|
||||
// Convert to string if number
|
||||
if (typeof val === 'number') {
|
||||
val = val.toString();
|
||||
if (decimalPoint === ',') {
|
||||
val = val.replace('.', decimalPoint);
|
||||
}
|
||||
className = 'number';
|
||||
}
|
||||
else if (!value) {
|
||||
val = '';
|
||||
className = 'empty';
|
||||
}
|
||||
return '<' + tag + (attrs ? ' ' + attrs : '') +
|
||||
' class="' + className + '">' +
|
||||
val + '</' + tag + '>';
|
||||
};
|
||||
var _a = this.getColumnsForExport(options.usePresentationOrder), columnNames = _a.columnNames, columnValues = _a.columnValues, htmlRows = [], columnsCount = columnNames.length;
|
||||
var rowArray = [];
|
||||
var tableHead = '';
|
||||
// Add the names as the first row if they should be exported
|
||||
if (exportNames) {
|
||||
var subcategories_1 = [];
|
||||
// If using multilevel headers, the first value
|
||||
// of each column is a subcategory
|
||||
if (useMultiLevelHeaders) {
|
||||
columnValues.forEach(function (column) {
|
||||
var subhead = (column.shift() || '').toString();
|
||||
subcategories_1.push(subhead);
|
||||
});
|
||||
tableHead = getTableHeaderHTML(columnNames, subcategories_1);
|
||||
}
|
||||
else {
|
||||
tableHead = getTableHeaderHTML(null, columnNames);
|
||||
}
|
||||
}
|
||||
for (var columnIndex = 0; columnIndex < columnsCount; columnIndex++) {
|
||||
var columnName = columnNames[columnIndex], column = columnValues[columnIndex], columnLength = column.length;
|
||||
var columnMeta = this.whatIs(columnName);
|
||||
var columnDataType = void 0;
|
||||
if (columnMeta) {
|
||||
columnDataType = columnMeta.dataType;
|
||||
}
|
||||
for (var rowIndex = 0; rowIndex < columnLength; rowIndex++) {
|
||||
var cellValue = column[rowIndex];
|
||||
if (!rowArray[rowIndex]) {
|
||||
rowArray[rowIndex] = [];
|
||||
}
|
||||
// Handle datatype
|
||||
// if(columnDataType && typeof cellValue !== columnDataType) {
|
||||
// do something?
|
||||
// }
|
||||
if (!(typeof cellValue === 'string' ||
|
||||
typeof cellValue === 'number' ||
|
||||
typeof cellValue === 'undefined')) {
|
||||
cellValue = (cellValue || '').toString();
|
||||
}
|
||||
rowArray[rowIndex][columnIndex] = getCellHTMLFromValue(columnIndex ? 'td' : 'th', null, columnIndex ? '' : 'scope="row"', cellValue);
|
||||
// On the final column, push the row to the array
|
||||
if (columnIndex === columnsCount - 1) {
|
||||
htmlRows.push('<tr>' +
|
||||
rowArray[rowIndex].join('') +
|
||||
'</tr>');
|
||||
}
|
||||
}
|
||||
}
|
||||
var caption = '';
|
||||
// Add table caption
|
||||
// Current exportdata falls back to chart title
|
||||
// but that should probably be handled elsewhere?
|
||||
if (options.tableCaption) {
|
||||
caption = '<caption class="highcharts-table-caption">' +
|
||||
options.tableCaption +
|
||||
'</caption>';
|
||||
}
|
||||
return ('<table>' +
|
||||
caption +
|
||||
tableHead +
|
||||
'<tbody>' +
|
||||
htmlRows.join('') +
|
||||
'</tbody>' +
|
||||
'</table>');
|
||||
};
|
||||
/**
|
||||
* Exports the datastore as an HTML string, using the options
|
||||
* provided on import unless other options are provided.
|
||||
*
|
||||
* @param {HTMLTableStore.ExportOptions} [htmlExportOptions]
|
||||
* Options that override default or existing export options.
|
||||
*
|
||||
* @param {DataEventEmitter.EventDetail} [eventDetail]
|
||||
* Custom information for pending events.
|
||||
*
|
||||
* @return {string}
|
||||
* HTML from the current dataTable.
|
||||
*
|
||||
*/
|
||||
HTMLTableStore.prototype.save = function (htmlExportOptions, eventDetail) {
|
||||
var exportOptions = HTMLTableStore.defaultExportOptions;
|
||||
// Merge in the provided parser options
|
||||
objectEach(this.parserOptions, function (value, key) {
|
||||
if (key in exportOptions) {
|
||||
exportOptions[key] = value;
|
||||
}
|
||||
});
|
||||
// Merge in provided options
|
||||
return this.getHTMLTableForExport(merge(exportOptions, htmlExportOptions));
|
||||
};
|
||||
/* *
|
||||
*
|
||||
* Static Properties
|
||||
*
|
||||
* */
|
||||
HTMLTableStore.defaultOptions = {
|
||||
table: ''
|
||||
};
|
||||
HTMLTableStore.defaultExportOptions = {
|
||||
decimalPoint: null,
|
||||
exportIDColumn: false,
|
||||
useRowspanHeaders: true,
|
||||
useMultiLevelHeaders: true
|
||||
};
|
||||
return HTMLTableStore;
|
||||
}(DataStore));
|
||||
/* *
|
||||
*
|
||||
* Register
|
||||
*
|
||||
* */
|
||||
DataStore.addStore(HTMLTableStore);
|
||||
/* *
|
||||
*
|
||||
* Export
|
||||
*
|
||||
* */
|
||||
export default HTMLTableStore;
|
||||
Reference in New Issue
Block a user