/****************************************************************************** Copyright (c) 2016, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format ////////////////////////////////////////////////////////////////////////////// //# sourceMappingURL=highcharts.js.map /** The main highcharts editor namespace * @ignore */ var highed = { schemas: {}, meta: { chartTemplates: {}, fonts: [] }, plugins: {}, resources: { logo: ' ', icons: { line: ' ', area: ' ', bar: ' ', column: ' ', more: ' ', pie: ' ', polar: ' ', 'scatter and bubble': ' ', stock: ' ' } }, /** Trigger file download * @namespace highed * @param filename {string} - the filename * @param data {string} - the contained data */ download: function(filename, data, mime) { var l = highed.dom.cr('a'); mime = mime || 'application/octet-stream'; l.download = filename || 'unkown'; l.href = 'data:' + mime + ',' + encodeURIComponent(data); highed.dom.ap(document.body, l); l.click(); document.body.removeChild(l); }, /** Clear an object * Deletes all the object attributes. * Useful when needing to clear an object without invalidating references to it * @namespace highed * @param obj {object} - the object to clear */ clearObj: function(obj) { Object.keys(obj).forEach(function(key) { delete obj[key]; }); }, /** Preform an AJAX request. Same syntax as jQuery. * @namespace highed * @param p {object} - options * > url {string} - the URL to call * > type {enum} - the type of request * > dataType {enum} - the type of data expected * > success {function} - function to call on success * > error {function} - function to call on request fail * > data {object} - the payload * > autoFire {boolean} - whether or not to fire the request right away * * @emits Error {string} - when there's an error * @emits OK {string} - when the request succeeded * @returns {object} - interface to the request */ ajax: function(p) { var props = highed.merge( { url: false, type: 'GET', dataType: 'json', success: false, error: false, data: {}, autoFire: true, headers: {} }, p ), headers = { json: 'application/json', xml: 'application/xml', text: 'text/plain', octet: 'application/octet-stream' }, r = new XMLHttpRequest(), events = highed.events(); if (!props.url) return false; r.open(props.type, props.url, true); r.setRequestHeader('Content-Type', headers[props.dataType] || headers.text); Object.keys(props.headers).forEach(function(key) { r.setRequestHeader(key, props.headers[key]); }); r.onreadystatechange = function() { events.emit('ReadyStateChange', r.readyState, r.status); if (r.readyState === 4 && r.status === 200) { if (props.dataType === 'json') { try { var json = JSON.parse(r.responseText); if (highed.isFn(props.success)) { props.success(json); } events.emit('OK', json); } catch (e) { console.log('parse error', e); if (highed.isFn(props.error)) { props.error(e.toString(), r.responseText); } events.emit('Error', e.toString(), r.status); } } else { if (highed.isFn(props.success)) { props.success(r.responseText); } events.emit('OK', r.responseText); } } else if (r.readyState === 4) { events.emit('Error', r.status, r.statusText); if (highed.isFn(props.error)) { props.error(r.status, r.statusText); } } }; function fire() { try { r.send(JSON.stringify(props.data)); } catch (e) { r.send(props.data || true); } } if (props.autoFire) { fire(); } return { on: events.on, fire: fire, request: r }; }, /** Generate a uuid * Borrowed from http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript * @namespace highed * @returns {string} - a UUID string */ uuid: function() { var d = new Date().getTime(), uuid; if (window.performance && typeof window.performance.now === 'function') { d += window.performance.now(); //use high-precision timer if available } uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = ((d + Math.random() * 16) % 16) | 0; d = Math.floor(d / 16); return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16); }); return uuid; }, /** Map an array to an object * @namespace highed * @param {array} arr - the array to map * @return {object} - an object with the array contents as keys, and their value set to true */ arrToObj: function(arr) { var obj = {}; if ((!highed.isArr(arr) && !highed.isBasic(arr)) || arr === false) { return arr; } if (highed.isStr(arr)) { arr = arr.split(' '); } arr.forEach(function(thing) { obj[thing] = true; }); return obj; }, /** Make a camel back string pretty * Transforms e.g. `imACamelBackString` to `Im a camelback string`. * @namespace highed * @param str {string} - the input string * @return {string} - the transformed string */ uncamelize: function(str) { var s = ''; if (!str) { return str; } if (str.length < 0 || !str) { return str; } for (var i = 0; i < str.length; i++) { if (str[i] === str[i].toUpperCase()) { if ( (str[i + 1] && str[i + 1] === str[i + 1].toUpperCase()) || (str[i - 1] && str[i - 1] === str[i - 1].toUpperCase()) ) { } else { s += ' '; } } s += str[i]; } return s[0].toUpperCase() + s.substr(1); }, /** Clamp a number between min/max * @namespace highed * @param min {number} - minimum value * @param max {number} - maximum value * @param value {number} - the value to clamp * @returns {number} - the clamped value */ clamp: function(min, max, value) { if (value < min) return min; if (value > max) return max; return value; }, /** Convert a hex value to RGB * * @namespace highed * @param {string} hex - the hex string * @return {object} - an object with rgb components * > r {number} - red * > g {number} - green * > b {number} - blue */ hexToRgb: function(hex) { if (!hex || highed.isObj(hex)) { return { r: 0, g: 0, b: 0 }; } if (hex.indexOf('rgba') === 0) { hex = hex .substr(5) .replace(')', '') .split(','); return { r: parseInt(hex[0], 10), g: parseInt(hex[1], 10), b: parseInt(hex[2], 10), a: parseInt(hex[3], 10) }; } if (hex.length === 4) { hex += hex[hex.length - 1]; hex += hex[hex.length - 1]; hex += hex[hex.length - 1]; } var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : { r: 0, g: 0, b: 0 }; }, /** Invert a color * @namespace highed * @param {string} hex - the color to invert * @return {string} - new hex color */ invertHexColor: function(hex) { var rgb = highed.hexToRgb(hex), res = 0; rgb.r = 255 - rgb.r; rgb.g = 255 - rgb.g; rgb.b = 255 - rgb.b; res = rgb.r << 16; res |= rgb.g << 8; res |= rgb.b; return '#' + res; }, /** Return #FFF or #000 based on the intensity of a color * @namespace highed * @param {string} hex - input color * @return {string} - the new hex color */ getContrastedColor: function(hex) { var rgb = highed.hexToRgb(hex), avarage = (rgb.r + rgb.g + rgb.b) / 3; if (avarage > 150) { return '#000'; } return '#FFF'; }, /** Convert a string to a bool * @namespace highed * @param {string} what - the string to convert * @return {bool} - the resulting bool */ toBool: function(what) { return what === 'true' || what === true || what === 'on'; }, /** Set a property based on -- delimited path * @namespace highed * @param {object} obj - the object to modify * @param {string} path - the path to the attribute to change * @param {anything} value - the value to set * @param {number} index - if we're accessing an array, this is the index */ setAttr: function(obj, path, value, index) { var current = obj; if (!current) return; if (highed.isArr(obj)) { obj.forEach(function(thing) { highed.setAttr(thing, path, value, index); }); return; } path = path .replace(/\-\-/g, '.') .replace(/\-/g, '.') .split('.'); path.forEach(function(p, i) { if (i === path.length - 1) { current[p] = value; } else { if (typeof current[p] === 'undefined') { current = current[p] = {}; } else { current = current[p]; if (highed.isArr(current)) { if (index > current.length - 1) { for (var j = current.length; j <= index; j++) { current.push({}); } } if (index >= 0) { current = current[index]; } } } } }); }, /** Get a property based on -- delimited path * @namespace highed * @param {object} obj - the object to traverse * @param {string} path - the path to the attribute to get * @param {number} index - if we're accessing an array, this is the index * @returns {anything} - the value or false */ getAttr: function(obj, path, index) { var current = obj, result = undefined; if (!current) return result; if (highed.isArr(obj)) { obj.forEach(function(thing) { result = highed.getAttr(thing, path); }); return result; } path = path .replace(/\-\-/g, '.') .replace(/\-/g, '.') .split('.'); path.forEach(function(p, i) { if (i === path.length - 1) { if (typeof current !== 'undefined') { result = current[p]; } } else { if (typeof current[p] === 'undefined') { current = current[p] = {}; } else { current = current[p]; if (highed.isArr(current) && index >= 0 && index < current.length) { current = current[index]; } } } }); return result; }, isEmptyObjectArray: function(arr) { return highed.isObj(arr[0]) && arr.some(function(b) { return Object.keys(b).length === 0; }); }, isObj: function(what) { return what && what.constructor.toString().indexOf('Object') > -1; }, /** Deep merge two objects. * Note: this modifies object `a`! * @namespace highed * @param {object} a - the destination object * @param {object} b - the source object * @param {bool} ignoreEmpty - Ignore empty things * @param {object} excludeMap - Map of properties to exclude from the merge * @return {object} - argument a */ merge: function(a, b, ignoreEmpty, excludeMap) { if (!a || !b) return a || b; if (ignoreEmpty && Object.keys(b).length === 0) { return; } Object.keys(b).forEach(function(bk) { if (excludeMap && excludeMap[bk]) { } else if (highed.isNull(b[bk]) || highed.isBasic(b[bk])) { a[bk] = b[bk]; } else if (highed.isArr(b[bk])) { if (highed.isEmptyObjectArray(b[bk])) return; a[bk] = []; b[bk].forEach(function(i) { if (highed.isNull(i) || highed.isBasic(i)) { a[bk].push(i); } else { a[bk].push(highed.merge(highed.isArr(i) ? [] : {}, i)); } }); } else if ( b[bk].tagName && b[bk].appendChild && b[bk].removeChild && b[bk].style ) { a[bk] = b[bk]; } else { if (ignoreEmpty && Object.keys(b[bk]).length === 0) { return; } a[bk] = a[bk] || {}; highed.merge(a[bk], b[bk]); } }); return a; }, /** Check if something is null or undefined * @namespace highed * @param {anything} what - the value to check * @return {bool} - true if null */ isNull: function(what) { return typeof what === 'undefined' || what === null; }, /** Check if something is a string * @namespace highed * @param {anything} what - the value to check * @return {bool} - true if string */ isStr: function(what) { return typeof what === 'string' || what instanceof String; }, /** Check if something is a number * @namespace highed * @param {anything} what - the value to check * @return {bool} - true if number */ isNum: function(what) { return !isNaN(parseFloat(what)) && isFinite(what); }, /** Check if a value is a function * @namespace highed * @param {anything} what - the value to check * @return {bool} - true if function */ isFn: function(what) { return (what && typeof what === 'function') || what instanceof Function; }, /** Check if a value is an array * @namespace highed * @param {anything} what - the value to check * @return {bool} - true if array */ isArr: function(what) { return ( !highed.isNull(what) && what.constructor.toString().indexOf('Array') > -1 ); }, /** Check if a value is a boolean * @namespace highed * @param {anything} what - the value to check * @return {bool} - true if bool */ isBool: function(what) { return what === true || what === false; }, /** Check if a value is a basic type * A basic type is either a bool, string, or a number * @namespace highed * @param {anything} what - the value to check * @return {bool} - true if basic */ isBasic: function(what) { return ( !highed.isArr(what) && (highed.isStr(what) || highed.isNum(what) || highed.isBool(what) || highed.isFn(what)) ); }, /** Parse CSV Data * @namespace highed * @param {string} - inData * @return {string} - delimiter */ parseCSV: function(inData, delimiter) { var isStr = highed.isStr, isArr = highed.isArray, isNum = highed.isNum, csv = inData || '', result = [], options = { delimiter: delimiter }, potentialDelimiters = { ',': true, ';': true, '\t': true }, delimiterCounts = { ',': 0, ';': 0, '\t': 0 }, rows; //The only thing CSV formats have in common.. rows = (csv || '').replace(/\r\n/g, '\n').split('\n'); // If there's no delimiter, look at the first few rows to guess it. if (!options.delimiter) { rows.some(function(row, i) { if (i > 10) return true; var inStr = false, c, cn, cl, token = ''; for (var j = 0; j < row.length; j++) { c = row[j]; cn = row[j + 1]; cl = row[j - 1]; if (c === '"') { if (inStr) { if (cl !== '"' && cn !== '"') { // The next non-blank character is likely the delimiter. while (cn === ' ') { cn = row[++j]; } if (potentialDelimiters[cn]) { delimiterCounts[cn]++; return true; } inStr = false; } } else { inStr = true; } } else if (potentialDelimiters[c]) { if (!isNaN(Date.parse(token))) { // Yup, likely the right delimiter token = ''; delimiterCounts[c]++; } else if (!isNum(token) && token.length) { token = ''; delimiterCounts[c]++; } } else { token += c; } } }); options.delimiter = ';'; if ( delimiterCounts[','] > delimiterCounts[';'] && delimiterCounts[','] > delimiterCounts['\t'] ) { options.delimiter = ','; } if ( delimiterCounts['\t'] >= delimiterCounts[';'] && delimiterCounts['\t'] >= delimiterCounts[','] ) { options.delimiter = '\t'; } } rows.forEach(function(row, rowNumber) { var cols = [], inStr = false, i = 0, j, token = '', guessedDel, c, cp, cn; function pushToken() { if (!token.length) { token = null; // return; } if (isNum(token)) { token = parseFloat(token); } cols.push(token); token = ''; } for (i = 0; i < row.length; i++) { c = row[i]; cn = row[i + 1]; cp = row[i - 1]; if (c === '"') { if (inStr) { pushToken(); } else { inStr = false; } //Everything is allowed inside quotes } else if (inStr) { token += c; //Check if we're done reading a token } else if (c === options.delimiter) { pushToken(); //Append to token } else { token += c; } // Push if this was the last character if (i === row.length - 1) { pushToken(); } } result.push(cols); }); return result; }, removeNulls: function(dataSet){ const newDataArr = []; dataSet.forEach(function(e){ var rarr = [], hasData = false; e.forEach(function(v) { if (v) { hasData = true; } if (!highed.isNum(v) && highed.isStr(v)) { v = v.replace(/\"/g, '"'); } if (highed.isNum(v)) { v = parseFloat(v); } if (highed.isStr(v) && Date.parse(v) !== NaN) { //v = (new Date(v)).getTime(); } rarr.push(v); }); if (hasData) { newDataArr.push(rarr); } }); return newDataArr; } }; // Stateful functions (function() { var logLevels = ['error', 'warn', 'notice', 'verbose'], currentLogLevel = 0, initQueue = [], isReady = false, includedScripts = {}, isOnPhone = false, isOnTablet = false, options = { codeMirrorTheme: 'neo', helpURL: 'https://www.highcharts.com/products/highcharts-editor', defaultLanguage: 'en', includeCDNInExport: true, stickyChartProperties: {}, includeHighcharts: true, cloudAPIURL: 'https://cloud-api.highcharts.com/', helpImgPath: 'help/', thumbnailURL: 'https://cloud.highcharts.com/static/thumbnails/', autoIncludeDependencies: true }, cdnScripts = [ 'https://code.highcharts.com/stock/highstock.js', 'https://code.highcharts.com/highcharts-more.js', 'https://code.highcharts.com/highcharts-3d.js', 'https://code.highcharts.com/modules/data.js', 'https://code.highcharts.com/modules/exporting.js' ]; /////////////////////////////////////////////////////////////////////////// function pollForReady() { if (!isReady) { if (document.body) { isReady = true; initQueue.forEach(function(fn) { fn(); }); } else { window.setTimeout(pollForReady, 100); } } } pollForReady(); /////////////////////////////////////////////////////////////////////////// /** * Whitelist an option in simple view */ highed.exposeOption = function(option) {}; /** Set/get an option * Skip `value` to get the value * @param option {string} - the option to set * @param value {anything} - the value to set * @returns {anything} - the option value */ highed.option = function(option, value) { if (!highed.isBasic(option)) { highed.merge(options, option); } else if (options[option]) { if (typeof value !== 'undefined') { options[option] = value; } return options[option]; } return false; }; /** Set a set of options * @param options {object} - an object of options to set */ highed.options = function(options) { Object.keys(options || {}).forEach(function(key) { highed.option(key, options[key]); }); }; /** Serialize the global options * @returns {object} - a copy of the global options */ highed.serializeEditorOptions = function() { return highed.merge({}, options); }; /** Add a function to call when the document is ready * @param {function} fn - the function to call */ highed.ready = function(fn) { if (highed.isFn(fn)) { if (isReady) { fn(); } else { initQueue.push(fn); } } }; /** Log something * Accepts a variable amount of arguments after `level` which will be * the log message (similar to `console.log`). * @param {number} level - the log level 1..4 */ highed.log = function(level) { var things = Array.prototype.slice.call(arguments); things.splice(0, 1); if (level <= currentLogLevel) { console.log.apply(undefined, [logLevels[level - 1] + ':'].concat(things)); //eslint-disable-line no-console } }; /** Set the current log level * @param level {number} - the current log level */ highed.setLogLevel = function(level) { if (level <= logLevels.length) { currentLogLevel = level; } }; /** Include something * @namespace highed * @param what {string} - URL to a css or javascript file * @param fn {function} - function to call when done including the script * @param asCSS {boolean} - force including as css */ highed.include = function(what, fn, asCSS) { var n; if (!highed.isStr(what)) { return highed.isFn(fn) && fn(); } function next() { if (n < what.length - 1) { highed.include(what[++n], next); } return highed.isFn(fn) && fn(); } if (highed.isArr(what)) { n = -1; return next(); } if (includedScripts[what]) { highed.log(3, 'script already included, skipping:', what); return fn(); } highed.log(3, 'including script', what); includedScripts[what] = true; if (asCSS || what.lastIndexOf('.css') === what.length - 4) { n = document.createElement('link'); n.rel = 'stylesheet'; n.type = 'text/css'; n.href = what; n.onload = fn; } else { n = document.createElement('script'); n.src = what; n.onload = fn; } document.head.appendChild(n); }; highed.getLetterIndex = function (char) { return char.charCodeAt() - 65; } /** Returns true if running on a phone * @namespace highed * @returns {boolean} - true if running on a phone */ highed.onPhone = function() { return isOnPhone; }; /** Returns true if running on a screen size is within tablets range and checks user agent * @namespace highed * @returns {boolean} - true if running on a tablet */ highed.onTablet = function() { return isOnTablet; }; function checkIfPhone() { var check = false; (function(a) { if ( /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test( a ) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test( a.substr(0, 4) ) ) check = true; })(navigator.userAgent || navigator.vendor || window.opera); return check; } function checkIfTabletDimensions() { var userAgent = navigator.userAgent.toLowerCase(); return /(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/.test(userAgent); } isOnPhone = checkIfPhone(); isOnTablet = checkIfTabletDimensions(); /////////////////////////////////////////////////////////////////////////// //Inject dependencies highed.ready(function() { if (!options.autoIncludeDependencies) { return false; } highed.include( 'https://maxcdn.bootstrapcdn.com/font-awesome/4.6.0/css/font-awesome.min.css' ); highed.include( 'https://fonts.googleapis.com/css?family=Roboto:400,300,100,700|Source Sans:400,300,100', false, true ); }); // highed.ready(function () { //Include the highcharts scripts // function tryAddScripts() { // if (document.head) { // cdnScripts.forEach(function (script) { // var s = document.createElement('script'); // s.src = script; // document.head.appendChild(s); // }); // } else { // window.setTimeout(tryAddScripts, 10); // } // } // tryAddScripts(); // function include(script, next) { // var sc=document.createElement("script"); // sc.src = script; // sc.type="text/javascript"; // sc.onload=function() { // if (++next < incl.length) { // include(incl[next], next); // } else { // loadedScripts = true; // } // }; // document.head.appendChild(sc); // } // var inc = {}, // incl = [] // ; // document.querySelectorAll("script").forEach(function(t) {inc[t.src.substr(0, t.src.indexOf("?"))] = 1;}); // Object.keys(cdnScripts).forEach(function (k){ // if (!inc[k] && k && k.length > 0) { // incl.push(k) // } // }); // if (incl.length > 0) { include(incl[0], 0); } else {loadedScripts = true;} })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /* Note that the localization system uses attribute names rather than a default string. This is to make it easier to modify translations. */ (function() { var currentLang = highed.option('defaultLanguage'), langTree = {}; /** Get a localized string based on the current global language * @param id {string} - the ID of the string to get */ highed.getLocalizedStr = function(id) { if (langTree[currentLang]) { if (langTree[currentLang][id]) { return langTree[currentLang][id]; } } else { //The current language is invalid, fall back to 'en' if (langTree.en[id]) { return langTree.en[id]; } } //404 return 'bad localized string: ' + id; }; /** This is an alias for highed.getLocalizedStr * @type {function} * @param id {string} - the string to get */ highed.L = highed.getLocalizedStr; /** Install a language pack from a json object * @param translations {object} - translation object */ highed.installLanguage = function(translations) { if (translations && translations.language && translations.entries) { langTree[translations.language] = translations.entries; } }; /** Install a language pack from a url * @param url {string} - the location of the pack */ highed.installLanguageFromURL = function(url, fn) { highed.ajax({ url: url, success: function(res) { if (res) { if (highed.installLanguage(res)) { return fn && fn(false); } return fn && fn(true); } }, error: function(err) { return fn && fn(err); } }); }; /** Set the active language * @param lang {string} - the language to activate * @return {boolean} - true if the language exists, and was applied */ highed.setLang = function(lang) { if (langTree[lang]) { currentLang = lang; return true; } return false; }; })(); /* en Language Pack for the Highcharts Editor This file was generated by tools/gen.localization.js from en.json, Thu Mar 15 2018 10:04:15 GMT+0100 (CET) */ //模板 //Install "en" translations highed.installLanguage({ language: 'en', entries: { "confirmNewChart": "确定放弃当前图表并重新开始?", "previewChart": "预览", "newChart": "新建", "saveProject": "保存项目", "loadProject": "加载项目", "exportPNG": "导出为PNG", "exportJPEG": "导出为JPEG", "exportSVG": "导出为SVG", "exportPDF": "导出为PDF", "help": "帮助", "licenseInfo": "许可信息", "stepDone": "完成", "stepStart": "开始", "stepImport": "导入", "stepTemplates": "模板", "stepCustomize": "自定义", "stepExport": "导出", "stepData": "数据", "doneCaption": "关闭并生成图表", "dgDeleteRow": "确定删除已选行?", "dgWithSelected": "对已选择的行:", "dgImportBtn": "导入", "dgExportBtn": "导出", "dgNewBtn": "新建", "dgAddRow": "增加行", "dgDataImported": "数据已导入", "dgDataImporting": "数据导入中", "dgNewCol": "新增列", "dgSortAsc": "升序", "dgSortDec": "倒序", "dgSortAscMonth": "按月升序", "dgSortDecMonth": "按月倒序", "dgDelCol": "删除列", "dgDelColConfirm": "确定删除该列?", "dgInsColBefore": "前插列", "dgInsColAfter": "后插列", "customizeSimple": "简单", "customizeAdvanced": "高级", "option.cat.title": "标题", "option.subcat.titles": "主标题", "option.cat.general": "通用", "option.subcat.size": "图表尺寸", "option.subcat.interaction": "图表交互", "option.cat.appearance": "外观", "option.subcat.fonts": "字体", "option.subcat.titlestyle": "标题样式", "option.subcat.seriescolors": "系列颜色", "option.subcat.chartarea": "图表区域", "option.subcat.plotarea": "绘图区域", "option.cat.axes": "轴", "option.subcat.axessetup": "轴设置", "option.subcat.xaxis": "X轴", "option.subcat.yaxis": "Y轴", "option.cat.series": "数据系列", "option.cat.labels": "数据标签", "option.subcat.labels": "数据标签", "option.cat.legend": "图例", "option.subcat.general": "通用", "option.subcat.placement": "位置", "option.subcat.legendappearance": "外观", "option.cat.tooltip": "提示", "option.subcat.colorborder": "颜色和边框", "option.cat.exporting": "导出", "option.cat.localization": "本地化", "option.subcat.numberformat": "数值格式", "option.subcat.exportbutton": "导出按钮及菜单", "option.subcat.zoombutton": "缩放按钮", "option.cat.credits": "著作权", "option.text.title.text": "图表标题", "option.tooltip.title.text": "主标题", "option.text.subtitle.text": "副标题", "option.tooltip.subtitle.text": "图表的副标题,以较小的字体显示在主标题下方", "option.text.yAxis.title.text": "Y轴标题", "option.tooltip.yAxis.title.text": "Y轴标题,沿Y轴方向显示", "option.text.chart.width": "图表宽度", "option.tooltip.chart.width": "图表的确切宽度。默认(null)根据包含元素的偏移宽度计算。", "option.text.chart.height": "图表高度", "option.tooltip.chart.height": "图表的确切高度。默认(null)根据包含元素的偏移高度计算,若包含元素高度为0则采用400像素。", "option.text.chart.zoomType": "允许缩放", "option.tooltip.chart.zoomType": "用户可以通过鼠标拖拽缩放的维度。可选值为:x, y or xy.", "option.text.chart.polar": "极坐标(雷达)投影", "option.tooltip.chart.polar": "若勾选,线图、样条图、堆积图和柱状图将会按照极坐标系统进行转换。需要highcharts-more.js支持。", "option.text.chart.style": "所有字体", "option.tooltip.chart.style": "整个使用的字体", "option.text.title.style": "主标题样式", "option.tooltip.title.style": "控制主标题的样式", "option.text.subtitle.style": "副标题样式", "option.tooltip.subtitle.style": "控制副标题的样式,通常以更小的字体在主标题下方显示", "option.text.colors": "颜色", "option.tooltip.colors": "数据系列默认的颜色,或者针对饼图或柱状图单个点的颜色。色彩会被按顺序选择。如果在数据系列中对系列进行设置,则以之为准。", "option.text.chart.backgroundColor": "背景颜色", "option.tooltip.chart.backgroundColor": "整个图表区域的背景颜色", "option.text.chart.borderWidth": "边框宽度", "option.tooltip.chart.borderWidth": "图表外边框宽度(像素)。", "option.text.chart.borderRadius": "边角半径", "option.tooltip.chart.borderRadius": "图表外边框角半径。", "option.text.chart.borderColor": "边框颜色", "option.tooltip.chart.borderColor": "图表外边框颜色。", "option.text.chart.plotBackgroundColor": "背景颜色", "option.tooltip.chart.plotBackgroundColor": "绘图区域(坐标内区域)背景色", "option.text.chart.plotBackgroundImage": "背景图片链接", "option.tooltip.chart.plotBackgroundImage": "作为绘图区域背景图片的在线URL", "option.text.chart.plotBorderWidth": "边框宽度", "option.tooltip.chart.plotBorderWidth": "绘图区域边框宽度(像素)。", "option.text.chart.plotBorderColor": "边框颜色", "option.tooltip.chart.plotBorderColor": "绘图区域边框颜色。", "option.text.chart.inverted": "交换轴", "option.tooltip.chart.inverted": "

是否交换轴以使得x轴垂直而y轴水平。When true, the x axis is reversed by default. If a bar series is present in the chart, it will be inverted automatically.

\r\n\r\n

Inverting the chart doesn't have an effect if there are no cartesian series in the chart, or if the chart is polar.

", "option.text.xAxis.title.style": "X轴标题样式", "option.tooltip.xAxis.title.style": "X轴标题的样式", "option.text.xAxis.title.text": "文本", "option.tooltip.xAxis.title.text": "该轴标题的具体文本。它可以含有基础的HTML标签,如:<b>, <i> ", "option.text.xAxis.type": "类型", "option.tooltip.xAxis.type": "轴的类型", "option.text.xAxis.opposite": "对侧显示", "option.tooltip.xAxis.opposite": "是否将坐标轴显示在图表的另一侧。一般来说,垂直的坐标在左侧,水平的坐标在下侧,所以另一侧相应地是指右侧和上侧。一般在双坐标或多坐标场景下使用。", "option.text.xAxis.reversed": "逆向显示", "option.tooltip.xAxis.reversed": "是否将坐标逆向以使得最大坐标值离原点最近。若图表逆向,默认将X轴逆向。", "option.text.xAxis.labels.format": "轴标签格式", "option.tooltip.xAxis.labels.format": "

轴标签的格式字符串。实际数据可通过变量{value}来获得。

例如可以使用{value} USD来增加单位。

在变量内部也可以使用冒号来对数据进行格式化,如:USD {value:.2f}可展现两位有效数字,{value:%Y-%m-%d}可进行日期字符串格式化。", "option.text.yAxis.title.style": "Y轴标题样式", "option.tooltip.yAxis.title.style": "Y轴标题的样式", "option.text.yAxis.type": "类型", "option.tooltip.yAxis.type": "轴的类型", "option.text.yAxis.opposite": "对侧显示", "option.tooltip.yAxis.opposite": "是否将坐标轴显示在图表的另一侧。一般来说,垂直的坐标在左侧,水平的坐标在下侧,所以另一侧相应地是指右侧和上侧。一般在双坐标或多坐标场景下使用。", "option.text.yAxis.reversed": "逆向显示", "option.tooltip.yAxis.reversed": "是否将坐标逆向以使得最大坐标值离原点最近。若图表逆向,默认将Y轴逆向。", "option.text.yAxis.labels.format": "轴标签格式", "option.tooltip.yAxis.labels.format": "

轴标签的格式字符串。实际数据可通过变量{value}来获得。

例如可以使用{value} USD来增加单位。

在变量内部也可以使用冒号来对数据进行格式化,如:USD {value:.2f}可展现两位有效数字,{value:%Y-%m-%d}可进行日期字符串格式化。", "option.text.series.type": "系列类型", "option.tooltip.series.type": "该系列的类型", "option.text.series.color": "颜色", "option.tooltip.series.color": "该系列的主颜色。若此处不指定,则从\"外观\"中的默认颜色中选取。", "option.text.series.negativeColor": "负色", "option.tooltip.series.negativeColor": "该系列低于阈值的负颜色。阈值默认是0,在高级设定中可以修改。", "option.text.series.colorByPoint": "单点着色", "option.tooltip.series.colorByPoint": "每一个点使用一种颜色。颜色可以在\"外观\"中修改。", "option.text.series.dashStyle": "短划线风格", "option.tooltip.series.dashStyle": "图中短划线风格。仅对具有图的系列有作用,如线图, 样条图, 面积图散点图,并且具有lineWidth短划线风格有:\r\n\t\t

", "option.text.series.marker.enabled": "启用点标记", "option.tooltip.series.marker.enabled": "是否启用点标记。如果是null,若数据稠密则标记隐藏,否则展现。", "option.text.series.marker.symbol": "标记符号", "option.tooltip.series.marker.symbol": "

为标记预定义的形状或符号。若空,则顺序使用options.symbols中的符号。其他可选值为:\"circle\", \"square\", \"diamond\", \"triangle\" 以及 \"triangle-down\".

\r\n\r\n

Additionally, the URL to a graphic can be given on this form: \"url(graphic.png)\". Note that for the image to be applied to exported charts, its URL needs to be accessible by the export server.

\r\n\r\n

Custom callbacks for symbol path generation can also be added to Highcharts.SVGRenderer.prototype.symbols. The callback is then used by its method name, as shown in the demo.

", "option.text.plotOptions.series.dataLabels.enabled": "对所有系列启用数据标签", "option.tooltip.plotOptions.series.dataLabels.enabled": "在每个数据值(点、柱、饼图切片等)旁边显示一个小标签。", "option.text.plotOptions.series.dataLabels.style": "文本样式", "option.tooltip.plotOptions.series.dataLabels.style": "标签的样式。", "option.text.legend.enabled": "启用图例", "option.tooltip.legend.enabled": "是否启用图例。", "option.text.legend.layout": "图例布局", "option.tooltip.legend.layout": "图例项的布局。可选为: \"horizontal\" , \"vertical\".", "option.text.legend.align": "水平对齐", "option.tooltip.legend.align": "

图例在图表区域内的水平对齐。合法取值为:left, center 以及 right

\r\n\r\n

若图例对齐到角落位置,layout选项将决定图例展现在绘图区域的上侧或下侧。

", "option.text.legend.x": "水平偏移", "option.tooltip.legend.x": "图例相较于它的对齐的偏移量(像素)", "option.text.legend.verticalAlign": "垂直对齐", "option.tooltip.legend.verticalAlign": "

图例的垂直对齐。合法取值为:top, middlebottom。垂直位置可以通过y选项进一步调整。

\r\n\r\n

若图例对齐到角落位置,layout选项将决定图例展现在绘图区域的上侧或下侧。

", "option.text.legend.y": "垂直偏移", "option.tooltip.legend.y": "图例相较于它的对齐的偏移量(像素)", "option.text.legend.floating": "在绘图区域内显示", "option.tooltip.legend.floating": "若勾选,则绘图区域不会考虑图例,且绘图可能覆盖图例。", "option.text.legend.itemStyle": "文本样式", "option.tooltip.legend.itemStyle": "每个图例项的CSS样式。仅支持CSS的一个子集,特别是和文本相关的选项。", "option.text.legend.itemHiddenStyle": "隐藏时文本样式", "option.tooltip.legend.itemHiddenStyle": "若系列或点隐藏了,其相关的图例项的CSS样式。仅支持CSS的一个子集,特别是和文本相关的选项。除非此处配置,否则属性从style继承。", "option.text.legend.backgroundColor": "背景颜色", "option.tooltip.legend.backgroundColor": "图例的背景颜色。", "option.text.legend.borderWidth": "边框宽度", "option.tooltip.legend.borderWidth": "图例边框的宽度。", "option.text.legend.borderRadius": "边框角半径", "option.tooltip.legend.borderRadius": "图例的边框角半径。", "option.text.legend.borderColor": "边框颜色", "option.tooltip.legend.borderColor": "图例边框的颜色。", "option.text.tooltip.enabled": "启用提示", "option.tooltip.tooltip.enabled": "是否启用提示。提示指的是当鼠标悬停或者触摸一个点时显示的信息框。", "option.text.tooltip.shared": "系列间共享", "option.tooltip.tooltip.shared": "若勾选,整个绘图区域将捕获鼠标移动或者触摸事件。具有有序数据的系列(非饼图、散点图等)的提示信息将在同一个信息框中展现。推荐对于单系列以及为移动设备优化的图表启用。", "option.text.tooltip.backgroundColor": "背景颜色", "option.tooltip.tooltip.backgroundColor": "提示框的背景颜色", "option.text.tooltip.borderWidth": "边框宽度", "option.tooltip.tooltip.borderWidth": "

提示边框的宽度(像素)。

\r\n\r\n

In styled mode, the stroke width is set in the .highcharts-tooltip-box class.

", "option.text.tooltip.borderRadius": "边框角半径", "option.tooltip.tooltip.borderRadius": "提示框的边框角半径。", "option.text.tooltip.borderColor": "边框颜色", "option.tooltip.tooltip.borderColor": "提示框边框颜色。若不设置,则使用与之关联的系列的颜色。", "option.text.exporting.enabled": "启用导出", "option.tooltip.exporting.enabled": "若勾选,则启用图表右上角的上下文按钮以允许终端用户以不同格式下载图表。", "option.text.exporting.sourceWidth": "导出宽度", "option.tooltip.exporting.sourceWidth": "导出时原图的宽度。导出后的图片宽度(像素)等于该值乘以缩放因子。", "option.text.exporting.scale": "缩放因子", "option.tooltip.exporting.scale": "导出时的缩放因子. 若宽度已经设置,则该设置无效。", "option.text.lang.decimalPoint": "小数点", "option.tooltip.lang.decimalPoint": "所有数字使用的小数点", "option.text.lang.thousandsSep": "千位分隔符", "option.tooltip.lang.thousandsSep": "所有数字使用的千位分隔符", "option.text.lang.contextButtonTitle": "上下文按钮标题", "option.tooltip.lang.contextButtonTitle": "导出模块菜单。包含打印和导出菜单项的提示框标题。", "option.text.lang.printChart": "打印图表", "option.tooltip.lang.printChart": "仅用于导出模块。打印图表菜单项的文本内容。", "option.text.lang.downloadPNG": "下载PNG", "option.tooltip.lang.downloadPNG": "仅用于导出模块。PNG下载菜单项的文本内容。", "option.text.lang.downloadJPEG": "下载JPEG", "option.tooltip.lang.downloadJPEG": "仅用于导出模块。JPEG下载菜单项的文本内容。", "option.text.lang.downloadPDF": "下载PDF", "option.tooltip.lang.downloadPDF": "仅用于导出模块。PDF下载菜单项的文本内容。", "option.text.lang.downloadSVG": "下载SVG", "option.tooltip.lang.downloadSVG": "仅用于导出模块。SVG下载菜单项的文本内容。", "option.text.lang.resetZoom": "重置缩放按钮", "option.tooltip.lang.resetZoom": "图表被缩放时展现的标签文本内容。", "option.text.credits.enabled": "启用著作权信息", "option.tooltip.credits.enabled": "是否显示著作权信息", "option.text.credits.text": "著作权信息", "option.tooltip.credits.text": "著作权标签文本内容。", "option.text.credits.href": "链接", "option.tooltip.credits.href": "著作权标签的URL" } }); /******************************************************************************* Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** Namespace for DOM helper functions * @ignore */ highed.dom = { /** Check if a node is visible * @namespace highed.dom * @param node {domnode} - the node to check */ isVisible: function(node) { var style = window.getComputedStyle(node); return style.display !== 'none'; }, /** Append a set of nodes to another node. * Arguments supplied after the @param {} target represents the children to append. * @namespace highed.dom * @param target {object} - the node to append to * @return {domnode} - the target */ ap: function(target) { var children = Array.prototype.slice.call(arguments); children.splice(0, 1); target = highed.dom.get(target); if (!highed.isNull(target) && typeof target.appendChild !== 'undefined') { children.forEach(function(child) { if (highed.isArr(child)) { child.forEach(function(sc) { highed.dom.ap(target, sc); }); } else if ( typeof child !== 'undefined' && typeof child.appendChild !== 'undefined' ) { target.appendChild(child); } else if (child !== false) { highed.log(1, 'child is not valid (highed.dom.ap)'); } }); } else { highed.log(1, 'target is not a valid DOM node (highed.dom.ap)'); } return target; }, /** Create a set of options for a select * @namespace highed.dom * @param select {HTMLSelect} - the dropdown to add options to * @param options {(array|object)} - the options as an array or as an object keyed on ID * @param selected {number} - the index of the selected option */ options: function(select, options, selected) { if (highed.isNull(options)) { } else if (highed.isArr(options)) { options.forEach(function(option) { highed.dom.ap(select, highed.dom.cr('option', '', option, option)); }); if (selected) { select.selectedIndex = selected; } } else if (highed.isStr(options)) { try { highed.dom.options(select, JSON.parse(options)); } catch (e) { highed.log(e + ' in highed.options (json parser)'); } } else { Object.keys(options).forEach(function(key) { highed.dom.ap(select, highed.dom.cr('option', '', options[key], key)); }); } }, /** Show a node when another is hovered * @namespace highed.dom * @param parent {object} - the node to listen for the hover on * @param child {object} - the node to show when the parent is hovered */ showOnHover: function(parent, child) { if (highed.isArr(child)) { child.forEach(function(c) { highed.dom.showOnHover(parent, c); }); return; } highed.dom.on(parent, 'mouseover', function() { highed.dom.style(child, { //display: 'block', opacity: 1, // background: 'rgba(46, 46, 46, 0.85)', 'pointer-events': 'auto' }); }); highed.dom.on(parent, 'mouseout', function() { highed.dom.style(child, { //display: 'none', opacity: 0, //background: 'rgba(0, 0, 0, 0)', 'pointer-events': 'none' }); }); }, /** Create a new HTML node * @namespace highed.dom * @param type {string} - the type of node to create * @param cssClass {string} (optional) - the css class to use for the node * @param innerHTML {string} (optional) - the inner html of the new node * @param id {string} (optional) - the id of the new node * * @return {domnode} - the new dom node */ cr: function(type, cssClass, innerHTML, id) { var res = false; if (typeof type !== 'undefined') { res = document.createElement(type); if (typeof cssClass !== 'undefined') { res.className = cssClass; } if (typeof innerHTML !== 'undefined' && typeof innerHTML !== 'object') { res.innerHTML = innerHTML; } if (typeof id !== 'undefined') { res.id = id; } } else { highed.log(1, 'no node type supplied (highed.dom.cr'); } return res; }, /** Style a node * @namespace highed.dom * @param nodes {(object|array)} - the node to style. Can also be an array * @param style {object} - object containing style properties * * @return {anything} - whatever was supplied to @param {} nodes */ style: function(nodes, style) { if (highed.isArr(nodes)) { nodes.forEach(function(node) { highed.dom.style(node, style); }); return nodes; } if (nodes && nodes.style) { Object.keys(style).forEach(function(p) { nodes.style[p] = style[p]; }); return nodes; } return false; }, /** Attach an event listener to a dom node * @namespace highed.dom * @param target {object} - the dom node to attach to * @param event {string} - the event to listen for * @param callback {function} - the function to call when the event is emitted * @param context {object} (optional) - the context of the callback function * * @return {function} - a function that can be called to unbind the handler */ on: function(target, event, callback, context) { var s = []; if (!target) { return function() {}; } if (highed.isArr(event)) { event.forEach(function(event) { s.push(highed.dom.on(target, event, callback, context)); }); return function() { s.forEach(function(f) { f(); }); }; } if (target === document.body && event === 'resize') { //Need some special magic here eventually. } if (target && target.forEach) { target.forEach(function(t) { s.push(highed.dom.on(t, event, callback)); }); } if (s.length > 0) { return function() { s.forEach(function(f) { f(); }); }; } function actualCallback() { if (highed.isFn(callback)) { return callback.apply(context, arguments); } return; } if (target.addEventListener) { target.addEventListener(event, actualCallback, false); } else { target.attachEvent('on' + event, actualCallback, false); } return function() { if (window.removeEventListener) { target.removeEventListener(event, actualCallback, false); } else { target.detachEvent('on' + event, actualCallback); } }; }, nodefault: function(e) { e.cancelBubble = true; e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); return false; }, /** Get or set the value of a node * @namespace highed.dom * @param node {object} - the node to get the value of * @param value {(string|bool|number)} (optional) - the value to set * @return {anything} - the value */ val: function(node, value) { if (node.tagName === 'SELECT') { if (node.selectedIndex >= 0) { if (!highed.isNull(value)) { for (var i = 0; i < node.options.length; i++) { if (node.options[i].id === value) { node.selectedIndex = i; break; } } } return node.options[node.selectedIndex].id; } } else if (node.tagName === 'INPUT') { if (node.type === 'checkbox') { if (!highed.isNull(value)) { node.checked = highed.toBool(value); } return node.checked; } if (!highed.isNull(value)) { node.value = value; } return node.value; } else { if (!highed.isNull(value)) { node.innerHTML = value; } return node.innerText; } return false; }, /** Get the size of a node * @namespace highed.dom * @param node {object} - the node to get the size of * @return {object} - the size as an object `{w, h}` */ size: function(node) { return { w: node.clientWidth, h: node.clientHeight }; }, /** Get the position of a node * @namespace highed.dom * @param node {object} - the node to get the position of * @param abs {boolean} - absolute calculation rather than parent relative * @return {object} - the position as an object `{x, y}` */ pos: function(node, abs) { var x = 0, y = 0; if (abs) { var b = node.getBoundingClientRect(); return { x: b.left + (window.scrollX || 0), y: b.top + (window.scrollY || 0) }; } return { x: node.offsetLeft, y: node.offsetTop }; }, /** Find a node * @namespace highed.dom * @param node {object} - the node to find. Either a string or an actual node instance * @return {object} - the node or false if the node was not found */ get: function(node) { if (node && node.appendChild) { return node; } return document.getElementById(node) || false; } }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** Event dispatcher object * Constructs an instance of an event dispatcher when called. * @constructor * @example * var events = highed.events(); * events.on('foobar', function () {console.log('Hello world!')}); * events.emit('foobar'); */ highed.events = function() { var callbacks = {}, listenerCounter = 0; /** Listen to an event * @memberof highed.events * @param event {string} - the event to listen for * @param callback {function} - the function to call when the event is emitted * @param context {anything} - the calling context (`this` reference) for the callback * @returns {function} - function that can be called to unbind the listener */ function on(event, callback, context) { var id = ++listenerCounter; if (highed.isArr(callback)) { return callback.forEach(function(cb) { on(event, cb, context); }); } callbacks[event] = callbacks[event] || []; callbacks[event].push({ id: id, fn: callback, context: context }); return function() { callbacks[event] = callbacks[event].filter(function(e) { return e.id !== id; }); }; } return { on: on, /** Emit an event * Note that the function accepts a variable amount of arguments. Any arguments after the event name will be passed on to any event listeners attached to the event being emitted. * @memberof highed.events * @param event {string} - the event to emit * @return {number} - The number of events dispatched */ emit: function(event) { var args = Array.prototype.slice.call(arguments); args.splice(0, 1); if (typeof callbacks[event] !== 'undefined') { callbacks[event].forEach(function(event) { if (highed.isFn(event.fn)) { event.fn.apply(event.context, args); } }); return callbacks[event].length; } return 0; } }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** * @ignore */ highed.ready(function() { var uploader = highed.dom.cr('input'), cb = false; uploader.type = 'file'; uploader.accept = '.csv'; highed.dom.ap(document.body, uploader); highed.dom.style(uploader, { display: 'none' }); /** Upload and parse a local file * Borrowed from almostvanilla which is licensed under MIT. * @param props {object} - the upload settings * > type {string} - the type of data to load * > accept {string} - the accepted file extensions * > multiple {boolean} - allow multiple files * > progress {function} - progress callback * > {number} - the progress in percent * > success {function} - function called when the file is uploaded * > {object} - the file information * > filename {string} - the name of the file * > size {number} - the size of the file in bytes * > data {string} - the file data */ highed.readLocalFile = function(props) { var p = highed.merge( { type: 'text', multiple: false, accept: '.csv' }, props ); uploader.accept = p.accept; if (highed.isFn(cb)) { cb(); } cb = highed.dom.on(uploader, 'change', function() { function crReader(file) { var reader = new FileReader(); reader.onloadstart = function(evt) { if (highed.isFn(p.progress)) { p.progress(Math.round(evt.loaded / evt.total * 100)); } }; reader.onload = function(event) { var data = reader.result; if (p.type === 'json') { try { data = JSON.parse(data); } catch (e) { if (highed.isFn(p.error)) { p.error(e); } } } if (highed.isFn(p.success)) { p.success({ filename: file.name, size: file.size, data: data }); } }; return reader; } for (var i = 0; i < uploader.files.length; i++) { if (!p.type || p.type === 'text' || p.type === 'json') { crReader(uploader.files[i]).readAsText(uploader.files[i]); } else if (p.type === 'binary') { crReader(uploader.files[i]).readAsBinaryString(uploader.files[i]); } else if (p.type === 'b64') { crReader(uploader.files[i]).readAsDataURL(uploader.files[i]); } } cb(); uploader.value = ''; }); uploader.multiple = p.multiple; uploader.click(); }; }); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format highed.templates = {}; (function() { /* Templates */ var templates = {}, mostPopularTemplates = {}; /** Install a new template * * @example * highed.installTemplate('custom', { * title: 'My company template', * tooltipText: 'Company template: requires no particular data', * config: { * 'chart--title': 'Company Chart' * } * }); * * @param type {string} - template type: `line area column bar scatter pie polar stock` * @param def {object} - the template definition * > title {string} - the template title * > config {object} - the highcharts attributes * > tooltipText {string} - the tooltip text */ highed.templates.add = function(type, def) { var properties = highed.merge( { title: '', description: '', constructor: '', thumbnail: '', icon: '', sampleSets: [], validator: false, config: {} }, def ); if (!highed.isBasic(type)) { return false; } templates[type] = templates[type] || { description: '', icon: '', sampleData: [], templates: {} }; if (properties.title.length) { if (properties.popular) { properties.parent = type; mostPopularTemplates[type] = properties; } if (properties.icon) templates[type].icon = properties.icon; templates[type].templates[properties.title] = properties; highed.log(4, '[templateman] - added template', properties.title); return true; } return false; }; /** * Do something for each template * @param fn {function} - the callback */ highed.templates.each = function(fn) { if (highed.isFn(fn)) { Object.keys(templates).forEach(function(cat) { Object.keys(templates[cat].templates).forEach(function(id) { fn(cat, templates[cat].templates[id]); }); }); } }; /** * Do something for each template within a given category * @param cat {string} - the category to filter by * @param fn {function} - the callback */ highed.templates.eachInCategory = function(cat, fn) { if (highed.isFn(fn) && templates[cat]) { Object.keys(templates[cat].templates).forEach(function(id) { fn(templates[cat].templates[id]); }); } }; /** * Get a reference to the templates within a given category */ highed.templates.getAllInCat = function(cat) { return templates[cat] ? templates[cat].templates : false; }; /** * Get category meta */ highed.templates.getCatInfo = function(cat) { return highed.merge( { id: cat }, templates[cat] || {} ); }; highed.templates.getMostPopular = function() { return mostPopularTemplates; } /** * Get a list of id/title pairs for templates */ highed.templates.getCatArray = function() { return Object.keys(templates).map(function(cat) { return { id: cat, title: cat, icon: templates[cat].icon }; }); }; /** * Add meta information to a category */ highed.templates.addCategory = function(id, meta) { templates[id] = templates[id] || { templates: {} }; highed.merge(templates[id], meta, false, { templates: 1 }); }; /** * Do something with each category * @param fn {function} - the callback */ highed.templates.eachCategory = function(fn) { if (highed.isFn(fn)) { Object.keys(templates).forEach(function(id) { fn(id, templates[id]); }); } }; /** Flush templates */ highed.templates.flush = function() { templates = {}; }; /** Add a new template type * If the type already exists, nothing will happen * * @example * highed.addTemplateType('custom', 'My company templates'); * * @param type {string} - the type id * @param title {string} - the title as it appears in the category list */ highed.templates.addType = function(type, title) { if (typeof templates === 'undefined') { templates = {}; } if (typeof templates[type] === 'undefined') { templates[type] = { title: title, templates: {} }; } }; /** Add a set of templates * @example * highed.installMultipleTemplates([ * {type: 'line', template: {title: 'My Line Template', config: {}}} * ]); * * @param templates {array} - an array of templates * */ highed.templates.addMultiple = function(templates) { if (typeof templates === 'undefined') { templates = {}; } if (highed.isArr(templates)) { templates.forEach(function(template) { if (template.type && template.template) { highed.installTemplate(template.type, template.template); } }); } }; })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format // There be dragons here... (function() { var hasTransformedAdvanced = false; /** * Merges/extends advanced meta * 1. Find the source * 2. If source is also extending: * 2a. Recursively merge source * 3. Remove the extends attribute from target * 4. Merge source children */ function mergeAdv(superset, dest, src, trigger) { var path = src.split('.'), current = superset, seriesNames = { pie: true, line: true }; // console.log( // 'extending', // (dest.meta.ns ? dest.meta.ns + '.' : '') + dest.meta.name, // 'with', // src // ); path.some(function(p) { if (current.subtree[p]) { current = current.subtree[p]; } else { // console.log( // 'unable to resolve path for merge:', // src, // 'from', // dest.meta.name // ); current = false; return true; } }); // Stop from trying to extend this multiple times dest.meta.extends = dest.meta.extends.replace(src, ''); if (current) { // Extend the source if needed extend(superset, current); // Unfortunatly we need to take series into special consideration // until we have a more robust way of handling its meta if (trigger && trigger.indexOf('series') === 0) { Object.keys(current.subtree || {}).forEach(function(key) { dest.subtree[key] = dest.subtree[key] || highed.merge({}, current.subtree[key]); dest.subtree[key].meta.validFor = dest.subtree[key].meta.validFor || {}; if ( dest.meta.excludes && Object.keys(dest.meta.excludes).length > 0 ) { dest.subtree[key].meta.validFor[current.meta.name] = !dest.meta .excludes[key]; } else { dest.subtree[key].meta.validFor[current.meta.name] = 1; } }); } else if ((trigger && trigger.indexOf('plotOptions') === 0) || dest.meta.ns === undefined) { if (!dest.meta.validFor) dest.meta.validFor = {}; dest.meta.validFor[dest.meta.name] = 1; if (dest.meta.ns === undefined) { highed.merge(dest.subtree, current.subtree, false, dest.meta.excludes); } else { Object.keys(current.subtree || {}).forEach(function(key) { dest.subtree[key] = dest.subtree[key] || highed.merge({}, current.subtree[key]); dest.subtree[key].meta.validFor = dest.subtree[key].meta.validFor || {}; if ( dest.meta.excludes && Object.keys(dest.meta.excludes).length > 0 ) { dest.subtree[key].meta.validFor[current.meta.name] = !dest.meta .excludes[key]; } else { dest.subtree[key].meta.validFor[current.meta.name] = 1; } }); } } else { // Do actual extending highed.merge(dest.subtree, current.subtree, false, dest.meta.excludes); } } } /** * Extend a node */ function extend(superset, node, trigger) { if (trigger === undefined) { if (node.meta.ns && node.meta.ns === "plotOptions") { trigger = 'plotOptions'; } } if (node.meta.extends && node.meta.extends.length > 0) { node.meta.extends = node.meta.extends.replace('{', '').replace('}', ''); if (trigger === 'series') { node.meta.extends += ',plotOptions.line'; } node.meta.extends.split(',').forEach(function(part) { if (part && part.length > 0) { mergeAdv(superset, node, part.trim(), trigger); } }); } } /** * Transform the tree * - merges * - arrifies * - sorts * * Duplicating children is faster than arrifying and replacing * */ function transformAdv(input, onlyOnce) { var res; if (onlyOnce && hasTransformedAdvanced) { return input; } function visit(node, pname) { var children = (node.subtree = node.subtree || {}); node.meta = node.meta || {}; node.meta.default = node.meta.default; node.meta.ns = pname; node.children = []; // Take care of merging extend(input, node, (pname ? pname + '.' : '') + node.meta.name); node.meta.hasSubTree = false; node.children = []; Object.keys(children).forEach(function(child) { if (Object.keys(children[child].subtree).length > 0) { node.meta.hasSubTree = true; } node.children.push( visit( children[child], (pname ? pname + '.' : '') + (node.meta.name || '') ) ); }); node.children.sort(function(a, b) { return a.meta.name.localeCompare(b.meta.name); }); if (node.children.length === 0) { node.meta.leafNode = true; } return node; } // console.time('tree transform'); res = visit(input); // console.timeEnd('tree transform'); return res; } // Removes all empty objects and arrays from the input object function removeBlanks(input) { function rewind(stack) { if (!stack || stack.length === 0) return; var t = stack.pop(); if (Object.keys(t).length === 0) { rewind(stack); } else { Object.keys(t || {}).forEach(function(key) { var child = t[key]; if (key[0] === '_') { delete t[key]; } else if ( child && !highed.isBasic(child) && !highed.isArr(child) && Object.keys(child).length === 0 ) { delete t[key]; } else if (highed.isArr(child) && child.length === 0) { delete t[key]; } else if (highed.isArr(child)) { child = child.map(function(sub) { return removeBlanks(sub); }); } }); } rewind(stack); } function visit(node, parentStack) { parentStack = parentStack || []; if (node) { if (parentStack && Object.keys(node).length === 0) { rewind(parentStack.concat([node])); } else { Object.keys(node).forEach(function(key) { var child = node[key]; if (key[0] === '_') { rewind(parentStack.concat([node])); } else if (!highed.isBasic(child) && !highed.isArr(child)) { visit(child, parentStack.concat([node])); } }); } } } visit(input); return input; } highed.transform = { advanced: transformAdv, remBlanks: removeBlanks }; })(); /******************************************************************************* Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format (function() { // Samples, keyed on ID var samples = {}; highed.samples = { /** * Add a sample to the sample collection * * This should be linked to templates too, * both in the sense that templates should have a list of * ID's for suitable sample data, and in the sense that * when displaying sample data it should display what kind of * chart types the data is valid for. * * The latter can be done automatically by cross-checking templates. * * @param {object} sample - the sample definition * > id {anything} - the ID of the sample * > title {anything} - the sample title * > description {string} - the sample description * > dataset {array>} - the sample data * > suitableSeries {object} - the kind of series this is suitable for */ add: function(sample) { var options = highed.merge( { title: 'Untitled Sample', description: 'Untitled Sample', dataset: [], suitableSeries: false, products: false }, sample ); if (options.id && !samples[options.id]) { samples[options.id] = options; return true; } return false; }, /** * Do something for each sample * @param fn {function} - the callback * @param productFilter {string} - the product(s) to include (optional) * @param typeFilter {string} - the series type(s) to include (optional) */ each: function(fn, productFilter, typeFilter) { if (highed.isFn(fn)) { Object.keys(samples).forEach(function(id) { fn(samples[id]); }); } }, /** * Get a single sample set * @param id {string} - the id of the sample set to get * @returns {sample|false} - false if 404, sample if found */ get: function(id) { return samples[id] || false; } }; })(); /******************************************************************************* Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /* Keeps track of validations */ (function() { // Keyed on ID var validators = {}; highed.validators = { /** * Add a validator * @param id {string} - the id * @param fn {function} - the validator function */ add: function(id, fn) { if (id && !validators[id] && highed.isFn(fn)) { validators[id] = fn; return true; } return false; }, /** * Execute a validator * @param id {string} - the id of the validator * @param chart {Chart} - the charts whose data to validate * @return {boolean} - true if valid */ validate: function(id, chart) { return validators[id] ? validators[id](chart) : true; } }; })(); /******************************************************************************* Copyright (c) 2017-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ // @format (function() { var token = false, url = highed.option('cloudAPIURL'); // Set up namespace for the cloud API highed.cloud = {}; highed.cloud.isLoggedIn = function() { return token !== false; }; highed.cloud.login = function(username, password, fn) { url = highed.option('cloudAPIURL'); highed.ajax({ url: url + 'login', type: 'post', data: { username: username, password: password }, success: function(data) { if (data && data.token) { token = data.token; } return highed.isFn(fn) && fn(typeof data.token === 'undefined', data); }, error: function(err) { return highed.isFn(fn) && fn(err); } }); }; highed.cloud.getTeams = function(fn) { url = highed.option('cloudAPIURL'); highed.ajax({ url: url + 'teams', type: 'get', headers: { 'X-Auth-Token': token }, success: function(data) { if (data.error) { return highed.snackBar(data.message); } return highed.isFn(fn) && fn(data); } }); }; highed.cloud.getCharts = function(teamID, fn, page) { url = highed.option('cloudAPIURL'); highed.ajax({ url: url + 'team/' + teamID + '/charts/' + '?page=' + page, type: 'get', headers: { 'X-Auth-Token': token }, success: function(data) { if (data.error) { return highed.snackBar(data.message); } return highed.isFn(fn) && fn(data.data, data); } }); }; highed.cloud.getChart = function(teamID, chartID, fn) { url = highed.option('cloudAPIURL'); highed.ajax({ url: url + 'team/' + teamID + '/chart/' + chartID, type: 'get', headers: { 'X-Auth-Token': token }, success: function(data) { if (data.error) { return highed.snackBar(data.message); } return highed.isFn(fn) && fn(data); } }); }; highed.cloud.saveExistingChart = function(teamID, chartID, chart, fn) { url = highed.option('cloudAPIURL'); highed.ajax({ url: url + 'team/' + teamID + '/chart/' + chartID, type: 'post', headers: { 'X-Auth-Token': token }, data: { data: chart }, success: function(data) { if (data.error) { return highed.snackbar(data.message); } return highed.isFn(fn) && fn(data); } }); }; highed.cloud.saveNewChart = function(teamID, name, chart, fn) { url = highed.option('cloudAPIURL'); highed.ajax({ url: url + 'team/' + teamID + '/chart', type: 'post', headers: { 'X-Auth-Token': token }, data: { name: name, data: chart }, success: function(data) { if (data.error) { return highed.snackbar(data.message); } return highed.isFn(fn) && fn(data); } }); }; })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format (function() { var events = highed.events(); highed.on = events.on; highed.emit = events.emit; })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format (function() { /** Show a dimmer backdrop * * Used to catch input when showing modals, context menus etc. * * @example * highed.showDimmer(function () { * alert('You clicked the dimmer!'); * }); * * @param {function} fn - the function to call when the dimmer is clicked * @param {bool} autohide - set to true to hide the dimmer when it's clicked * @param {bool} transparent - set to true for the dimmer to be transparent * @param {number} zIndex - the z index *offset* * @return {function} - A function that can be called to hide the dimmer */ highed.showDimmer = function(fn, autohide, transparent, zIndex) { var dimmer = highed.dom.cr('div', 'highed-dimmer'), unbinder = false; highed.dom.ap(document.body, dimmer); highed.dom.style(dimmer, { opacity: 0.4, 'pointer-events': 'auto', 'z-index': 9999 + (zIndex || 0) }); if (transparent) { highed.dom.style(dimmer, { opacity: 0 }); } function hide() { highed.dom.style(dimmer, { opacity: 0, 'pointer-events': 'none' }); if (highed.isFn(unbinder)) { unbinder(); unbinder = false; } window.setTimeout(function() { if (dimmer.parentNode) { dimmer.parentNode.removeChild(dimmer); } }, 300); } unbinder = highed.dom.on(dimmer, 'click', function(e) { if (highed.isFn(fn)) { fn(); } if (autohide) { hide(); } }); return hide; }; })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** Turn a DOM node into an overlay "popup" * * @example * //Create an overlay with hello world in it * highed.OverlayModal(highed.dom.cr('h1', '', 'Hello World!')); * * @constructor * * @emits Show - when the overlay is shown * @emits Hide - when the overlay is hidden * * @param {domnode} contents - the DOM node to wrap. * @param {object} attributes - properties for the modal * > width {number} - the width of the modal * > height {number} - the height of the modal * > minWidth {number} - the minimum width of the modal * > minHeight {number} - the minimum height of the modal * > showOnInit {boolean} - if true, the modal will be shown after creation * > zIndex {number} - the Z-Index to use for the modal * @return {object} - A new instance of OverlayModal */ highed.OverlayModal = function(contents, attributes) { var container = highed.dom.cr('div', 'highed-overlay-modal '), events = highed.events(), properties = highed.merge( { width: 200, height: 200, minWidth: 10, minHeight: 10, showOnInit: true, zIndex: 10000, showCloseIcon: false, cancelButton: false }, attributes ), hideDimmer = false, visible = false; if (properties.class) { container.classList += properties.class; } /////////////////////////////////////////////////////////////////////////// /** resize the modal * @memberof highed.OverlayModal */ function resize(width, height) { properties.minWidth = width; properties.minHeight = height; } /** Show the modal * @memberof highed.OverlayModal */ function show() { if (visible) return; highed.dom.style(container, { width: properties.width + (properties.width.toString().indexOf('%') > 0 ? '' : 'px'), height: properties.height + (properties.height.toString().indexOf('%') > 0 ? '' : 'px'), opacity: 1, left: '50%', top: '50%', transform: 'translate(-50%, -50%)', 'pointer-events': 'auto', 'min-width': properties.minWidth + 'px', 'min-height': properties.minHeight + 'px', 'z-index': properties.zIndex }); highed.dom.style(document.body, { 'overflow-x': 'hidden', 'overflow-y': 'hidden' }); if (properties.showCloseIcon) { const icon = highed.dom.cr('span', 'highed-overlaymodal-close', ''); highed.dom.on(icon, 'click', function() { hide(); }); highed.dom.ap(container, icon); } hideDimmer = highed.showDimmer( hide, true, false, properties.zIndex - 10000 ); window.setTimeout(function() { events.emit('Show'); }, 300); visible = true; } /** Hide the modal * @memberof highed.OverlayModal * @param suppress {boolean} - suppress the hide event emitting */ function hide(suppress) { if (!visible) return; highed.dom.style(container, { width: '0px', height: '0px', opacity: 0, left: '-20000px', 'pointer-events': 'none' }); highed.dom.style(document.body, { 'overflow-x': '', 'overflow-y': '' }); if (highed.isFn(hideDimmer)) { hideDimmer(); } visible = false; if (!suppress) { events.emit('Hide'); } } /////////////////////////////////////////////////////////////////////////// highed.ready(function() { highed.dom.ap(document.body, container); }); if (contents) { // if (highed.isStr(contents)) { // contents = highed.dom.cr('div', '', contents); // } // highed.dom.ap(container, // contents // ); } hide(true); /////////////////////////////////////////////////////////////////////////// //Public interface return { on: events.on, show: show, hide: hide, resize: resize, /** The container DOM node * @memberof highed.OverlayModal */ body: container }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** Horizontal splitter * * Splits a view into two horizontal cells * * @example * var splitter = highed.HSplitter(document.body); * highed.dom.ap(splitter.left, highed.dom.cr('div', '', 'Left!')); * highed.dom.ap(splitter.right, highed.dom.cr('div', '', 'Right!')); * * @constructor * @param parent {domnode} - the parent to attach to * @param attributes {object} - the settings for the splitter * > leftWidth {number} - the width in percent of the left cell * > noOverflow {bool} - whether or not overflowing is allowed * > leftClasses {string} - additional css classes to use for the left body * > rightClasses {string} - additional css classes to use for the right body * > allowResize {boolean} - set to true to enable user-resizing * > leftMax {number} - the max width of the left panel * > rightMax {number} - the max width of the right panel */ highed.HSplitter = function(parent, attributes) { var properties = highed.merge( { leftWidth: 40, noOverflow: false, leftClasses: '', rightClasses: '', allowResize: false, responsive: false, leftMax: false, rightMax: false }, attributes ), container = highed.dom.cr('div', 'highed-hsplitter'), left = highed.dom.cr( 'div', 'highed-scrollbar panel left ' + properties.leftClasses ), right = highed.dom.cr( 'div', 'highed-scrollbar panel right ' + properties.rightClasses ), leftBody = highed.dom.cr( 'div', 'highed-scrollbar highed-hsplitter-body ' + properties.leftClasses ), rightBody = highed.dom.cr( 'div', 'highed-scrollbar highed-hsplitter-body ' + properties.rightClasses ), resizeBar = highed.dom.cr('div', 'highed-hsplitter-resize-bar'), mover; if (properties.responsive) { left.className += ' highed-hsplitter-body-responsive'; } /////////////////////////////////////////////////////////////////////////// function updateSizeFromMover(x) { var psize; if (properties.allowResize && highed.dom.isVisible(right)) { psize = highed.dom.size(container); x = x || highed.dom.pos(resizeBar).x; highed.dom.style(left, { width: x + 'px' }); highed.dom.style(right, { width: psize.w - x + 'px' }); highed.dom.style(resizeBar, { display: '' }); } } /** Force a resize of the splitter * @memberof highed.HSplitter * @param w {number} - the width of the splitter (will use parent if null) * @param h {number} - the height of the splitter (will use parent if null) */ function resize(w, h) { var s = highed.dom.size(parent), st, ps; //Check if the right side is visible if (!highed.dom.isVisible(right)) { highed.dom.style(left, { width: '100%' }); highed.dom.style(resizeBar, { display: 'none' }); } else { resetSize(); } if (properties.responsive) { st = window.getComputedStyle(left); if (st.float === 'none') { highed.dom.style(right, { width: '100%' }); highed.dom.style(resizeBar, { display: 'none' }); } else { resetSize(); } } highed.dom.style([left, right, container, resizeBar], { height: (h || s.h) + 'px' }); if (properties.rightMax) { highed.dom.style(right, { 'max-width': properties.rightMax + 'px' }); } if (properties.leftMax) { highed.dom.style(left, { 'max-width': properties.leftMax + 'px' }); } //If we're at right max, we need to resize the left panel ps = highed.dom.size(left); if (ps.w === properties.leftMax) { highed.dom.style(right, { width: s.w - properties.leftMax - 1 + 'px' }); } updateSizeFromMover(); } function resetSize() { highed.dom.style(left, { width: properties.leftWidth + '%' }); highed.dom.style(right, { width: (properties.rightWidth ? properties.rightWidth : 100 - properties.leftWidth) + '%' }); } /////////////////////////////////////////////////////////////////////////// parent = highed.dom.get(parent); highed.dom.ap( highed.dom.get(parent), highed.dom.ap( container, highed.dom.ap(left, leftBody), highed.dom.ap(right, rightBody) ) ); resetSize(); if (properties.noOverflow) { highed.dom.style([container, left, right], { 'overflow-y': 'hidden' }); } if (properties.allowResize) { highed.dom.ap(container, resizeBar); highed.dom.style(resizeBar, { left: properties.leftWidth + '%' }); mover = highed.Movable(resizeBar, 'x').on('Moving', function(x) { updateSizeFromMover(x); }); } //resize(); /////////////////////////////////////////////////////////////////////////// // Public interface return { resize: resize, /** The dom node for the left cell * @memberof highed.HSplitter * @type {domnode} */ left: leftBody, /** The dom node for the right cell * @memberof highed.HSplitter * @type {domnode} */ right: rightBody }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** Vertical splitter * Splits a view into two vertical cells * * @example * var splitter = highed.VSplitter(document.body); * highed.dom.ap(splitter.top, highed.dom.cr('div', '', 'Top!')); * highed.dom.ap(splitter.bottom, highed.dom.cr('div', '', 'Bottom!')); * * @constructor * @param parent {domnode} - the parent to attach to * @param attributes {object} - the settings for the splitter * > topHeight {number} - the height in percent of the left cell. Alternatively, use '123px' to set a capped size. * > noOverflow {bool} - whether or not overflowing is allowed */ highed.VSplitter = function(parent, attributes) { var properties = highed.merge( { topHeight: 40, noOverflow: false }, attributes ), container = highed.dom.cr('div', 'highed-vsplitter'), top = highed.dom.cr('div', 'panel top highed-scrollbar'), bottom = highed.dom.cr('div', 'panel bottom highed-scrollbar'), topBody = highed.dom.cr('div', 'highed-vsplitter-body highed-scrollbar'), bottomBody = highed.dom.cr('div', 'highed-vsplitter-body highed-scrollbar'); /////////////////////////////////////////////////////////////////////////// /** Force a resize of the splitter * @memberof highed.VSplitter * @param w {number} - the width of the splitter (will use parent if null) * @param h {number} - the height of the splitter (will use parent if null) */ function resize(w, h) { var s = highed.dom.size(parent); highed.dom.style(container, { height: '100%' }); if (!w && !h) { highed.dom.style(top, { height: (typeof properties.topHeight === 'string' ? properties.topHeight : properties.topHeight + '%' ) }) if (bottom) { highed.dom.style(bottom, { width: '100%', height: (typeof properties.topHeight === 'string' ? 'calc(100% - ' + properties.topHeight + ')' : 100 - properties.topHeight + '%' ) }); } return; } highed.dom.style(container, { width: (w || s.w) + 'px', height: ((h || s.h)) + 'px' }); if (properties.topHeight.toString().indexOf('px') > 0) { highed.dom.style(top, { height: properties.topHeight }); highed.dom.style(bottom, { height: (h || s.h) - parseInt(properties.topHeight, 10) + 'px' }); } else { highed.dom.style(top, { height: properties.topHeight + '%' }); highed.dom.style(bottom, { height: 100 - properties.topHeight + '%' }); } //highed.dom.style([top, bottom, container], { // width: (w || s.w) + 'px' //}); } /////////////////////////////////////////////////////////////////////////// highed.dom.ap( highed.dom.get(parent), highed.dom.ap( container, highed.dom.ap(top, topBody), highed.dom.ap(bottom, bottomBody) ) ); if (properties.noOverflow) { highed.dom.style([container, top, bottom], { 'overflow-y': 'hidden' }); } parent = highed.dom.get(parent); /////////////////////////////////////////////////////////////////////////// // Public interface return { resize: resize, /** The dom node for the top cell * @memberof highed.VSplitter * @type {domnode} */ top: topBody, /** The dom node for the bottom cell * @memberof highed.VSplitter * @type {domnode} */ bottom: bottomBody }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** Standard tabcontrol component * @example * var tabs = highed.TabControl(document.body), * tab1 = tabs.createTab({title: 'Tab 1'}), * tab2 = tabs.createTab({title: 'Tab 2'}) * ; * //Append things to tab1|tab2.body * * @constructor * * @emits Focus {object} - when a new tab gets focus. * * @param parent {domnode} - the node to attach to * @param noOverflow {boolean} - set to true to disable scrollbars * @param extraPadding {boolean} - set to true to have extra padding in bodies */ highed.TabControl = function(parent, noOverflow, extraPadding, skipTabs) { var container = highed.dom.cr('div', 'highed-tab-control'), paneBar = highed.dom.cr('div', (!skipTabs ? 'tabs' : '')), //Quck fix for now, will change once design finalised. body = highed.dom.cr('div', 'body'), indicator = highed.dom.cr('div', 'indicator'), more = highed.dom.cr('div', (!skipTabs ? 'highed-tab-control-more fa fa-chevron-right' : '')), events = highed.events(), selectedTab = false, tabs = [], ctx = highed.ContextMenu(); /////////////////////////////////////////////////////////////////////////// //Build ctx menu function buildCTX() { ctx.build( tabs.map(function(tab) { return { title: tab.title, click: tab.focus, selected: tab.selected }; }) ); } highed.dom.on(more, 'click', function(e) { buildCTX(); ctx.show(e.clientX, e.clientY); }); /** Force a resize of the tab control * @memberof highed.TabControl * @param w {number} - the width, uses parent width if null * @param h {number} - the height, uses parent width if null */ function resize(w, h) { var cs = highed.dom.size(parent), width = 0; if (!skipTabs) var ps = highed.dom.size(paneBar); highed.dom.style(container, { height: (h || cs.h) + 'px' }); highed.dom.style(body, { height: (h || cs.h) /*- ps.h*/ + 'px' }); //Also re-focus the active tab if (selectedTab) { selectedTab.focus(); } //clientWidth/scrollWidth doesn't produce what we need, //so let's check the accumulated width of the tabs. tabs.forEach(function(tab) { width += highed.dom.size(tab.node).w || 0; }); if (!skipTabs) { if (width > paneBar.scrollWidth) { highed.dom.style(more, { display: 'block' }); } else { highed.dom.style(more, { display: 'none' }); } } } /** Select the first tab * @memberof highed.TabControl */ function selectFirst() { tabs.some(function(tab) { if (tab.visible()) { tab.focus(); return true; } }); } function select(index) { if (tabs[index] && tabs[index].visible()) { tabs[index].focus(); } } /** Hide the tab control * @memberof highed.TabControl */ function hide() { highed.dom.style(container, { display: 'none' }); } /** Show the tab control * @memberof highed.TabControl */ function show() { highed.dom.style(container, { display: 'block' }); } function updateVisibility() { var c = tabs.filter(function(a) { return a.visible(); }).length; if (!skipTabs){ if (c < 2) { highed.dom.style(paneBar, { display: 'none' }); } else { highed.dom.style(paneBar, { display: '' }); } } } /* Create and return a new tab * @memberof highed.TabControl * @name createTab * @properties - the properties for the tab: * > title {string} - the title of the tab * @returns {object} - an interface to the tab * > hide {function} - hide the tab * > show {function} - show the tab * > focus {function} - make the tab active * > visible {function} - returns true if the tab is visible * > body {domnode} - the tab body */ function Tab(properties) { var tevents = highed.events(), tab = highed.dom.cr('div', 'tab', properties.title), tbody = highed.dom.cr('div', 'tab-body'), visible = true, texports = { selected: false }; if (extraPadding) { tbody.className += ' tab-body-padded'; } if (!skipTabs) { highed.dom.ap(paneBar, tab); } highed.dom.ap(body, tbody); function hide() { visible = false; highed.dom.style(tab, { display: 'none' }); updateVisibility(); } function show() { visible = true; highed.dom.style(tab, { display: '' }); updateVisibility(); } function resize(w, h) { highed.dom.style(container, { width: w + 'px', height: h + 'px' }); } function focus() { var tsize = highed.dom.size(tab), tpos = highed.dom.pos(tab); if (!visible) { return; } if (selectedTab) { selectedTab.node.className = 'tab'; selectedTab.selected = false; highed.dom.style(selectedTab.body, { opacity: 0, // 'pointer-events': 'none', display: 'none' }); } if (!tsize || !tpos || !tsize.w) { //We're not ready yet.. } highed.dom.style(indicator, { width: tsize.w + 'px', left: tpos.x + 'px' }); tab.className = 'tab tab-selected'; highed.dom.style(tbody, { opacity: 1, // 'pointer-events': 'auto', display: 'block' }); selectedTab = texports; selectedTab.selected = true; tevents.emit('Focus'); events.emit('Focus', texports); } highed.dom.on(tab, 'click', function() { focus(); highed.emit('UIAction', 'TabControlNavigation', properties.title); }); texports = { on: tevents.on, focus: focus, node: tab, body: tbody, hide: hide, show: show, resize: resize, title: properties.title, visible: function() { return visible; } }; if (!selectedTab) { focus(); } if (noOverflow) { highed.dom.style(tbody, { overflow: 'hidden' }); } tabs.push(texports); resize(); updateVisibility(); return texports; } /////////////////////////////////////////////////////////////////////////// if (!highed.isNull(parent)) { highed.ready(function() { highed.dom.ap( parent, highed.dom.ap(container, highed.dom.ap(paneBar, more, indicator), body) ); resize(); updateVisibility(); }); } /////////////////////////////////////////////////////////////////////////// return { container: container, on: events.on, createTab: Tab, resize: resize, select: select, selectFirst: selectFirst, show: show, hide: hide, /** Get the size of the title bar * @memberof highed.TabControl * @returns {object} * > w {number} - the width of the control * > h {number} - the height of the control */ barSize: function() { return highed.dom.size(paneBar); } }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** An editable field * * Creates a table row with three columns: * - label * - widget * - help icon * @todo This needs a proper cleaning now that the requirements are set. * @example * //Create a table, append to body, add a color picker to it. * highed.dom.ap(document.body, * highed.dom.ap(highed.dom.cr('table'), * highed.InspectorField('color', '#FFF', { * title: 'Set the color!' * }, function (newValue) { * highed.dom.style(document.body, { * backgroundColor: newValue * }); * }) * ) * ); * * @param type {enum} - the type of widget to use * > string * > number * > range * > boolean * > color * > font * > options * > object * @param value {anything} - the current value of the field * @param properties {object} - the properties for the widget * @param fn {function} - the function to call when the field is changed * > {anything} - the changed value * @param nohint {boolean} - if true, the help icon will be skipped * @param fieldID {anything} - the id of the field * @returns {domnode} - a DOM node containing the field + label wrapped in a tr */ highed.InspectorField = function(type, value, properties, fn, nohint, fieldID, planCode) { var createReset = function(resetTo, callback) { var node = highed.dom.cr('div', 'highed-field-reset fa fa-undo'); if (resetTo === 'null') { resetTo = null; } highed.dom.on(node, 'click', function() { if (highed.isFn(callback)) { callback(properties.defaults || resetTo); } }); return node; }, fields = { string: function(val, callback) { var input = highed.dom.cr('input', 'highed-field-input', '', fieldID), reset = createReset(properties.defaults || val || value, function(v) { input.value = val = v; tryCallback(callback, v); }); highed.dom.on(input, 'change', function(e) { tryCallback(callback, input.value); e.cancelBubble = true; }); if (typeof (val || value || '') === 'string' && (val || value || '').indexOf('\\u') > -1) input.value = decodeURIComponent(JSON.parse('"' + (val || value).replace(/\"/g, '\\"') + '"')); else input.value = (val || value); if (properties.warning && properties.warning.length > 0 && planCode && properties.warning.indexOf(planCode) > -1) { input.disabled = true; } return highed.dom.ap( highed.dom.cr('div', 'highed-field-container'),/* reset,*/ input ); }, header: function(val, callback) { return highed.dom.ap( highed.dom.cr('div', 'highed-field-container'),/* reset,*/ highed.dom.cr('div', 'highed-field-header', properties.header) ); }, number: function(val, callback) { var input = highed.dom.cr('input', 'highed-field-input', '', fieldID), reset = createReset(properties.defaults || val || value, function(v) { input.value = val = v; tryCallback(callback, parseFloat(v)); }); input.type = 'number'; if (!highed.isNull(properties.custom)) { input.step = properties.custom.step; input.min = properties.custom.minValue; input.max = properties.custom.maxValue; } highed.dom.on(input, 'change', function() { tryCallback(callback, parseFloat(input.value)); }); input.value = val || value; if (properties.warning && properties.warning.length > 0 && planCode && properties.warning.indexOf(planCode) > -1) { input.disabled = true; } return highed.dom.ap( highed.dom.cr('div', 'highed-field-container'),/* reset,*/ input ); }, range: function(val, callback) { var slider = highed.Slider(false, { min: properties.custom.minValue, max: properties.custom.maxValue, step: properties.custom.step, value: val || value, resetTo: properties.defaults }); slider.on('Change', function(v) { tryCallback(callback, v); }); return slider.container; }, boolean: function(val, callback) { var input = highed.dom.cr('input', '', '', fieldID), reset = createReset(properties.defaults || val || value, function(v) { input.checked = val = highed.toBool(v); tryCallback(callback, val); }); input.type = 'checkbox'; input.checked = highed.toBool(val || value); highed.dom.on(input, 'change', function() { tryCallback(callback, input.checked); }); if (properties.warning && properties.warning.length > 0 && planCode && properties.warning.indexOf(planCode) > -1) { input.disabled = true; } return highed.dom.ap( highed.dom.cr('div', 'highed-field-container'),/* reset,*/ input ); }, color: function(val, callback) { var box = highed.dom.cr('div', 'highed-field-colorpicker', '', fieldID), reset = highed.dom.cr('div', 'highed-field-reset fa fa-undo'), resetTo = val || value || properties.defaults; if (resetTo === 'null') { resetTo = null; } function update(col, callback) { if ( col && col !== 'null' && col !== 'undefined' && typeof col !== 'undefined' ) { box.innerHTML = ""; //box.innerHTML = col; } else { box.innerHTML = 'auto'; col = '#FFFFFF'; } highed.dom.style(box, { background: col, color: highed.getContrastedColor(col) }); } function fixVal() { //This is very ugly try { val = JSON.parse(val); } catch (e) {} if (highed.isArr(val)) { val = '#FFF'; } } fixVal(); highed.dom.on(box, 'click', function(e) { highed.pickColor(e.clientX, e.clientY, val || value, function(col) { if (highed.isArr(val)) { val = '#FFFFFF'; } val = col; update(col); tryCallback(callback, col); }); }); highed.dom.on(reset, 'click', function() { val = resetTo; fixVal(); update(val); tryCallback(callback, val); }); update(val || value); return highed.dom.ap( highed.dom.cr('div', 'highed-field-container'), box/*, reset*/ ); }, font: function(val, callback) { return fields.cssobject(val, callback); }, configset: function(val, callback) { return fields.string(val, callback); }, json: function(val, callback) { var textArea = highed.dom.cr( 'textarea', 'highed-field-input', '', fieldID ), errorBar = highed.dom.cr('div', 'highed-field-error'), editor = false, updateIt = function(v) { if (editor) { editor.setValue(JSON.stringify(v, undefined, '\t')); } else { textArea.value = JSON.stringify(v, undefined, '\t'); } }, reset = createReset(properties.defaults || val || value, function(v) { val = v; updateIt(v); tryCallback(callback, v); }), parent = highed.dom.ap( highed.dom.cr('div', 'highed-field-container', '', fieldID + '_container'), textArea, /* reset,*/ errorBar ); function resizePoll() { if (document.body && editor) { if (document.getElementById(fieldID)) { editor.refresh(); } else { setTimeout(resizePoll, 10); } } } function callHome(v) { try { v = JSON.parse(v); tryCallback(callback, v); errorBar.innerHTML = ''; highed.dom.style(errorBar, { display: 'none', opacity: 0 }); } catch (e) { //highed.snackBar('There\'s an error in your JSON: ' + e); errorBar.innerHTML = 'Syntax error: ' + e; highed.dom.style(errorBar, { display: 'block', opacity: 1 }); } } if (typeof window['CodeMirror'] !== 'undefined') { editor = CodeMirror.fromTextArea(textArea, { lineNumbers: true, mode: 'application/json', theme: highed.option('codeMirrorTheme') }); updateIt(val || value || properties.defaults); var timeout = null; editor.on('change', function() { clearTimeout(timeout); timeout = setTimeout(function () { callHome(editor.getValue()); }, 1000); }); resizePoll(); } else { updateIt(val || value || properties.defaults); highed.dom.on(textArea, 'change', function() { callHome(textArea.value); }); } return parent; }, cssobject: function(val, callback) { var picker = highed.FontPicker(callback || fn, val || value), reset = createReset(properties.defaults || val || value, function(v) { val = v; picker.set(val); tryCallback(callback, v); }); return highed.dom.ap( highed.dom.cr('div', 'highed-field-container'), /*reset,*/ picker.container ); }, options: function(val, callback) { var ddown = highed.DropDown(), reset = createReset(properties.defaults, function(v) { val = v; ddown.selectById(val); tryCallback(callback, v); }); if (highed.isStr(properties.values)) { try { properties.values = JSON.parse(properties.values); } catch (e) { properties.values = properties.values.split(' '); } } ddown.addItems(properties.values); ddown.addItem({ title: 'auto', id: properties.defaults }); ddown.selectById(val || value || properties.defaults); ddown.on('Change', function(selected) { tryCallback(callback, selected.id()); }); return highed.dom.ap( highed.dom.cr('div', 'highed-field-container'), ddown.container/*, reset*/ ); }, object: function(val, callback) { //Create a sub-table of options var stable = highed.dom.cr( 'table', 'highed-customizer-table', '', fieldID ), wasUndefined = highed.isNull(val || value); val = val || value || {}; if (highed.isStr(val)) { try { val = JSON.parse(val); } catch (e) {} } if (properties && highed.isArr(properties.attributes)) { properties.attributes.forEach(function(attr) { val[attr.name || attr.id] = val[attr.name || attr.id] || attr.defaults || (attr.dataType.indexOf('object') >= 0 ? {} : ''); attr.title = highed.uncamelize(attr.title); highed.dom.ap( stable, highed.InspectorField( attr.dataType, val[attr.name || attr.id] || attr.defaults, attr, function(nval) { val[attr.name || attr.id] = nval; tryCallback(callback, val); } ) ); }); } if (wasUndefined) { // tryCallback(callback, val); } return stable; }, function: function(val, callback) { var container = highed.dom.cr( 'div', 'highed-field-container highed-field-code-container' ), field = highed.dom.cr('textarea', 'highed-field-code', '', fieldID), editor = false, reset = createReset(properties.defaults || val || value, function(v) { val = v; updateIt(v); callHome(v); }); function updateIt(v) { if (highed.isFn(v)) { v = v.toString(); } if (editor) { editor.setValue(v); editor.refresh(); } else { field.value = v; } } function callHome(v) { var args = []; var argStart = v.indexOf('('); var argEnd = v.substr(argStart + 1).indexOf(')'); var body = ''; var balance = 0; var parsing = false; try { args = v .substr(argStart + 1, argEnd - 1) .trim() .split(','); args = args.filter(function(b) { return b && b.length > 0 && b.indexOf('/*') === -1; }); for (var i = 0; i < v.length; i++) { if (v[i] === '{') { balance++; parsing = true; } else if (v[i] === '}') { balance--; if (balance === 0) { parsing = false; } } else if (parsing) { body += v[i]; } } v = new Function(args, body); } catch (e) { console.log(e); return; } tryCallback(callback, v); } function resizePoll() { if (editor && document.body) { if (container.parentNode) { editor.refresh(); } else { setTimeout(resizePoll, 50); } } } highed.dom.ap(container, field); if (typeof window['CodeMirror'] !== 'undefined') { editor = CodeMirror.fromTextArea(field, { lineNumbers: true, mode: 'javascript', theme: highed.option('codeMirrorTheme') }); editor.on('change', function() { callHome(editor.getValue()); }); resizePoll(); } else { highed.dom.on(field, 'change', function() { callHome(field.value); }); } updateIt(val || value || properties.defaults || function() {}); return container; }, array: function() { var container = highed.dom.cr('div', '', '', fieldID), add = highed.dom.cr('span', 'highed-field-array-add fa fa-plus', ''), itemsNode = highed.dom.cr('div', 'highed-inline-blocks'), items = {}, itemCounter = 0, itemTable = highed.dom.cr('table', 'highed-field-table'); if (highed.isStr(value)) { try { value = JSON.parse(value); } catch (e) { return container; } } if (value && !highed.isArr(value) && !highed.isBasic(value)) { // This is an object. value = Object.keys(value).map(function(e) { return value[e]; }); } function addCompositeItem(val, suppressCallback) { var item, rem = highed.dom.cr('span', 'highed-icon fa fa-trash highed-trash-button'), row = highed.dom.cr('div', 'color-row'), //tr id = ++itemCounter; function processChange(newVal) { if (newVal) { items[id].value = newVal; doEmitCallback(); } } function doEmitCallback() { if (highed.isFn(fn)) { fn( Object.keys(items).map(function(key) { return items[key].value; }) ); } } if (highed.isArr(val)) { val = val[id]; } items[id] = { id: id, row: row, value: val }; item = fields[properties.subType] ? fields[properties.subType]( val || value[id] || properties.defaults, processChange ) : fields.string(val, processChange); highed.dom.ap( itemTable, highed.dom.ap( row, highed.dom.ap(highed.dom.cr('div'), item), //td highed.dom.ap(highed.dom.cr('div'), rem) //td ) ); highed.dom.on(rem, 'click', function(e) { delete items[id]; itemTable.removeChild(row); doEmitCallback(); e.cancelBubble = true; e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); return false; }); if (!suppressCallback) { processChange(); } } highed.dom.ap(container, itemTable); highed.dom.on(add, 'click', function() { addCompositeItem(); }); if (highed.isArr(value)) { value.forEach(function(item) { addCompositeItem(item, true); }); } highed.dom.ap(container, itemsNode, add); return container; } }, help = highed.dom.cr( 'span', 'highed-icon highed-field-help fa fa-question-circle' ), helpTD = highed.dom.cr('div', 'highed-customizer-table-help'), //td widgetTD = highed.dom.cr('div', 'highed-field-table-widget-column'), //td titleCol = highed.dom.cr('div'), //td typeIndicator = highed.dom.cr('span', 'highed-customize-type'); function tryCallback(cb, val) { cb = cb || fn; if (highed.isFn(cb)) { cb(val); } } function deduceObject() { if ( (!properties.attributes || !properties.attributes.length) && properties.defaults ) { properties.attributes = []; //There's no attributes but it's an object. //Check if there are default values we can use //to figure out the structure. if (properties.defaults) { try { properties.defaults = JSON.parse(properties.defaults); Object.keys(properties.defaults).forEach(function(k) { var tp = 'string', def = properties.defaults[k], up = k.toUpperCase(), vals; //This is hackish. if (highed.isNum(def)) { tp = 'number'; } if ( def.length && def[0] === '#' && (up.indexOf('BACKGROUND') >= 0 || up.indexOf('COLOR') >= 0) ) { tp = 'color'; } properties.attributes.push({ id: k, title: k, dataType: tp, defaults: properties.defaults[k], tooltip: '', values: vals }); }); } catch (e) { highed.log( 3, 'property', properties.id, 'skipped, no way to deduce the object members' ); return; } } } else { type = 'json'; properties.defaults = properties.defaults || {}; } } if (highed.isNull(value)) { value = ''; } if (type === 'cssobject' || type === 'highcharts.cssobject') { //So there are more than one version of this thing - one of them //requires a font picker, the other is dynamic. //Figure out which one we're dealing with here. // properties = properties || {}; // properties.attributes = [ // {name: 'x', title: 'x', title: 'X', values: '0', dataType: 'number'} // ]; type = 'object'; } //Choose a type if (type && type.indexOf('|') >= 0) { type = type.indexOf('object') >= 0 ? 'object' : type.split('|')[0]; } if ( !highed.isNull(properties.custom) && !highed.isNull(properties.custom.minValue) && !highed.isNull(properties.custom.maxValue) && !highed.isNull(properties.custom.step) ) { type = 'range'; } if (type && type.indexOf('array') === 0) { properties.subType = type.substr(6, type.length - 7); type = 'array'; if (properties.subType === 'object') { deduceObject(); } } if (type === 'object') { deduceObject(); } if (!properties.tooltip && !properties.tooltipText) { nohint = true; } else { // properties.tooltip = properties.tooltip.replace(/\n/g, '

'); } if (highed.onPhone()) { highed.dom.on(help, 'click', function() { var hide = highed.Tooltip(0, 0, properties.tooltip || properties.tooltipText, true); highed.dom.on([help], 'mouseout', hide); }); } else { highed.dom.on([help], 'mouseover', function(e) { var hide = highed.Tooltip( e.clientX + 20, e.clientY, properties.tooltip || properties.tooltipText ); highed.dom.on([help], 'mouseout', hide); // highed.showDimmer(highed.hideAllTooltips, true, true); }); } if (nohint) { highed.dom.style(help, { display: 'none' }); widgetTD.colSpan = 2; } typeIndicator.className += ' highed-customize-type-' + type; const parent = highed.dom.cr('div', 'highed-customizer-table-parent', '', fieldID + '_container'); highed.dom.style(parent, { width: (properties.width || 100) + '%' }); if (type === 'header') { return highed.dom.ap( highed.dom.ap( parent, //tr highed.dom.ap(widgetTD, fields[type] ? fields[type]() : fields.string()) ) ); } else if (type === 'boolean') { titleCol.className = 'highed-customize-field-boolean'; return highed.dom.ap( highed.dom.ap( parent, //tr highed.dom.ap(widgetTD, highed.dom.ap(fields[type] ? fields[type]() : fields.string(), highed.dom.ap( titleCol, highed.dom.cr('span', 'highed-customize-field-label', properties.title), !nohint ? highed.dom.ap( helpTD, //highed.dom.cr('span', 'highed-field-tooltip', properties.tooltip) help ) : false )) ) ) ); } else { return highed.dom.ap( highed.dom.ap( parent, //tr highed.dom.ap( titleCol, highed.dom.cr('span', 'highed-customize-field-label', properties.title), !nohint ? highed.dom.ap( helpTD, //highed.dom.cr('span', 'highed-field-tooltip', properties.tooltip) help ) : false ), highed.dom.ap(widgetTD, fields[type] ? fields[type]() : fields.string()) ) ); } }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** A list component * * Creates a list with selectable items * * @example * var list = highed.List(document.body).addItem({ * title: 'My Item', * click: function() { * alert('You clicked the item!'); * } * }); * * @constructor * @param parent {domnode} - the node to attach the list to * @param responsive {boolean} - set to true to get JS-based responsive functionality */ highed.List = function(parent, responsive, props, planCode) { var container = highed.dom.cr('div', 'highed-list'), compactIndicator = highed.dom.cr('div', 'highed-list-compact', 'compact'), ctx = highed.ContextMenu(), selectedItem = false, events = highed.events(), items = [], dropdowns = {}, properties = props; /////////////////////////////////////////////////////////////////////////// /** Add an item to the list * @memberof highed.List * @param item {object} - the item meta for the item to add * > title {string} - the title as displayed in the list * > id {anything} - the id of the item: used for `highed.List.on('Select')` * > click {function} - function to call when clicking the item * @returns {object} - an interface to interact with the item * > id {anything} - the item id * > title {string} - the title of the item * > node {domnode} - the dom node for the item * > select {function} - selects the item if called */ function addItem(item, children, chartPreview) { var node = highed.dom.cr('a', 'item', item.title), nodeArrow = highed.dom.cr('span', 'item-arrow', ''), nodeChildren = highed.dom.cr('span', 'highed-list-suboptions', ''), iexports = {}; highed.dom.style(nodeChildren, { display: 'none' }); highed.dom.ap(node, nodeArrow); (children || []).forEach(function(thing) { selectGroup(thing); }); function shouldInclude(group) { var doInclude = false; if (Object.keys(properties.availableSettings || {}).length > 0) { if (highed.isArr(group)) { group.forEach(function(sub) { if (shouldInclude(sub)) { doInclude = true; } }); } else if (highed.isArr(group.options)) { group.options.forEach(function(sub) { if (shouldInclude(sub)) { doInclude = true; } }); } else if ( properties.availableSettings[group.id] || properties.availableSettings[group.pid] ) { doInclude = true; } return doInclude; } return true; } function applyFilter(detailIndex, filteredBy, filter) { var selected = selectedItem, //list.selected(), id = selected.id, entry = highed.meta.optionsExtended.options[id]; if (!selected) return false; //body.innerHTML = ''; entry.forEach(function(thing) { selectGroup(thing, false, false, detailIndex, filteredBy, filter); }); highlighted = false; } //This function has mutated into a proper mess. Needs refactoring. function selectGroup(group, table, options, detailIndex, filteredBy, filter) { var master, vals, doInclude = true, container, masterNode, def; options = chartPreview.options.getCustomized(); //userOptions;//chartPreview.options.getCustomized(); if (highed.isArr(group.options)) { table = highed.dom.cr('div', 'highed-customizer-table'); warningContainer = highed.dom.cr('div', 'highed-customize-warning-container'), warning = highed.dom.cr('div', 'highed-customize-warning', 'You need to be on a paid plan for this to work in production'); doInclude = shouldInclude(group); if (group.warning && group.warning.length > 0 && planCode && group.warning.indexOf(planCode) > -1) { highed.dom.ap(table, highed.dom.ap(warningContainer, warning)); } if (!doInclude) { return; } container = highed.dom.cr('div', 'highed-customize-group' + (group.dropdown ? ' highed-list-general-drop-down' : ' highed-list-normal'), null, 'highed-list-header-' + highed.L(group.text)); masterNode = highed.dom.cr('div', 'highed-customize-master-dropdown'); nodeHeading = highed.dom.cr( 'div', 'highed-customizer-table-heading' + (group.dropdown ? ' highed-list-general-drop-down-header' : ''), highed.L(group.text) ); if (group.dropdown) { dropdowns[highed.L(group.text)] = container; highed.dom.on(nodeHeading, 'click', function(e) { if (e.target !== this) { Object.keys(dropdowns).forEach(function(d) { if (dropdowns[d] !== container) dropdowns[d].classList.remove('active'); }); if (container.classList.contains('active')) { container.classList.remove('active'); } else { container.className += ' active'; } } }); } highed.dom.ap( nodeChildren, highed.dom.ap( container, nodeHeading, masterNode, table ) ); if (group.filteredBy) { filter = highed.getAttr(options, group.filteredBy, detailIndex); } if (group.controlledBy) { master = highed.DropDown(); highed.dom.style(masterNode, { display: 'block' }); if (highed.isStr(group.controlledBy.options)) { vals = highed.getAttr( options, group.controlledBy.options, detailIndex ); if (highed.isArr(vals)) { if (vals.length === 0) { highed.dom.ap( parent, highed.dom.cr('i', '', 'No data to display..') ); return; } master.addItems( vals.map(function(t, i) { return ( (group.controlledBy.optionsTitle ? t[group.controlledBy.optionsTitle] : '#' + (i + 1)) || '#' + (i + 1) ); }) ); master.selectByIndex(detailIndex || 0); master.on('Change', function(selected) { detailIndex = selected.index(); table.innerHTML = ''; group.options.forEach(function(sub) { if (group.filteredBy) { filter = highed.getAttr( options, group.filteredBy, detailIndex ); } selectGroup( sub, table, options, detailIndex, group.filteredBy, filter ); }); }); highed.dom.ap(masterNode, master.container); detailIndex = detailIndex || 0; } else { return; } } } //highed.dom.ap(body, table); group.options.forEach(function(sub) { selectGroup(sub, table, options, detailIndex, group.filteredBy, filter); }); } else if (typeof group.id !== 'undefined') { //Check if we should filter out this column if (filter && group.subType && group.subType.length) { if (!highed.arrToObj(group.subType)[filter]) { return; } } if (Object.keys(properties.availableSettings || {}).length > 0) { if ( !properties.availableSettings[group.id] && !properties.availableSettings[group.pid] ) { return; } } if (typeof group.dataIndex !== 'undefined') { detailIndex = group.dataIndex; } def = highed.getAttr(options, group.id, detailIndex); //highed.dom.ap(sub, highed.dom.cr('span', '', referenced[0].returnType)); highed.dom.ap( table, highed.InspectorField( group.values ? 'options' : group.dataType, typeof def !== 'undefined' ? def : filter && group.subTypeDefaults[filter] ? group.subTypeDefaults[filter] : group.defaults, { title: highed.L('option.text.' + group.pid), tooltip: highed.L('option.tooltip.' + group.pid), values: group.values, custom: group.custom, defaults: group.defaults, width: group.width || 100, attributes: group.attributes || [], warning: group.warning || [], header: highed.L(group.pid) }, function(newValue) { if (group.header) return; if (group.plugins && group.plugins.length > 0) { events.emit('TogglePlugins', group.id, newValue); } if (!group.noChange) events.emit('PropertyChange', group.id, newValue, detailIndex); highed.emit( 'UIAction', 'SimplePropSet', highed.L('option.text.' + group.pid), newValue ); if (group.id === filteredBy) { //This is a master for the rest of the childs, //which means that we need to rebuild everything //here somehow and check their subType nodeChildren.innerHTML = ''; applyFilter(detailIndex, filteredBy, newValue); } }, false, group.id, planCode ) ); } } function select(e) { if (selectedItem) { selectedItem.selected = false; selectedItem.node.className = 'item'; selectedItem.nodeArrow.innerHTML = ''; highed.dom.style(selectedItem.nodeChildren, { display: "none" }); } dropdowns = {}; nodeArrow.innerHTML = ''; nodeChildren.innerHTML = ''; var entry = highed.meta.optionsExtended.options[item.id]; (entry || []).forEach(function(thing) { selectGroup(thing); }); highed.dom.style(nodeChildren, { display: 'block' }); selectedItem = iexports; selectedItem.selected = true; node.className = 'item item-selected'; events.emit('Select', item.id); compactIndicator.innerHTML = '' + item.title; if (highed.isFn(item.click)) { return item.click(e); } } if (!item.annotations) { highed.dom.on(node, 'click', item.onClick || select); } highed.dom.ap(container, node, nodeChildren); iexports = { id: item.id, title: item.title, node: node, nodeArrow: nodeArrow, nodeChildren: nodeChildren, select: select, selected: false }; items.push(iexports); if (!selectedItem) { select(); } return iexports; } /** Add a set of items to the list * @memberof highed.List * @param items {array} - an array of items to add */ function addItems(items) { if (highed.isArr(items)) { items.forEach(function(item) { addItem(item); }); } } /** Clear all the items in the list * @memberof highed.List */ function clear() { container.innerHTML = ''; } /** Force resize of the list * @memberof highed.List */ function resize() { var ps = highed.dom.size(parent), cs = highed.dom.size(container); if (responsive && ps.h < 50 && ps.h !== 0 && ps.h) { highed.dom.style(compactIndicator, { display: 'block' }); highed.dom.style(container, { display: 'none' }); } else if (responsive) { highed.dom.style(compactIndicator, { display: 'none' }); highed.dom.style(container, { display: '' }); } // highed.dom.style(container, { // //height: ps.height + 'px' // height: '100%' // }); } /** Show the list * @memberof highed.List */ function show() { highed.dom.style(container, {}); } /** Hide the list * @memberof highed.List */ function hide() {} /** Select the first item * @memberof highed.List */ function selectFirst() { if (items.length > 0) { items[0].select(); } } /** Select an item * @memberof highed.List * @param which {string} - the id of the item to select */ function select(which) { items.some(function(item) { if (which === item.title) { if (item.selected) return true; item.select(); return true; } }); } function selectDropdown(dropdownKey) { if (dropdowns[dropdownKey].classList.contains('active')) { return true; } Object.keys(dropdowns).forEach(function(d) { if (dropdowns[d] !== dropdowns[dropdownKey]) dropdowns[d].classList.remove('active'); }); if (!dropdowns[dropdownKey].classList.contains('active')) { dropdowns[dropdownKey].className += ' active'; } } /** Reselect the current item * @memberof highed.List */ function reselect() { if (selectedItem) { selectedItem.select(); } } /** Count the number of items currently in the list * @memberof highed.List */ function countItems() { return items.length; } /** Get the selected item * @memberof highed.List * @returns {object} - the selected item */ function selected() { return selectedItem; } /////////////////////////////////////////////////////////////////////////// highed.dom.on(compactIndicator, 'click', function(e) { ctx.build( items.map(function(item) { return { title: item.title, click: item.select, selected: item.selected }; }) ); ctx.show(e.clientX, e.clientY); }); highed.dom.ap(parent, container, compactIndicator); /////////////////////////////////////////////////////////////////////////// //Public interface return { on: events.on, addItem: addItem, addItems: addItems, clear: clear, resize: resize, show: show, hide: hide, selectFirst: selectFirst, select: select, selectDropdown: selectDropdown, reselect: reselect, selected: selected, count: countItems, container: container }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format (function() { var container = highed.dom.cr( 'div', 'highed-colorpicker highed-colorpicker-responsive' ), canvas = highed.dom.cr('canvas', 'picker'), closeBtn = highed.dom.cr('div', 'highed-ok-button', 'Close'), ctx = canvas.getContext('2d'), manualInput = highed.dom.cr('input', 'manual'); //Attach the container to the document when the document is ready highed.ready(function() { highed.dom.ap(document.body, container); }); function updatePickerBackground(current) { highed.dom.style(manualInput, { background: current, color: highed.getContrastedColor(current) }); } /** Color picker * Component to pick colors from the google material design color palette. * User input is also possible. * * The color palette is defined in meta/highed.meta.colors.js, * and is divided into groups of 14 hues per. color. * * @example * //Show a color picker at [10,10] * highed.pickColor(10, 10, '#fff', function (color) { * alert('You selected ' + color + ', great choice!'); * }); * * @param x {number} - the x position to display the picker at * @param y {number} - the y position to display the picker at * @param current {string} - the current color * @param fn {function} - the function to call when the color changes * > newColor {string} - the color selected by the user */ highed.pickColor = function(x, y, current, fn) { var windowSize = highed.dom.size(document.body), containerSize = highed.dom.size(container), pickerSize = highed.dom.size(canvas), binder = false, pbinder = false, cbinder = false, dbinder = false; /////////////////////////////////////////////////////////////////////// /* Draws the color picker itself */ function drawPicker() { //There's 14 hues per. color, 19 colors in total. var x, y, tx = Math.floor(pickerSize.w / 14), ty = Math.floor(pickerSize.h / 19), col = -1; canvas.width = pickerSize.w; canvas.height = pickerSize.h; //To avoid picking null ctx.fillStyle = '#FFF'; ctx.fillRect(0, 0, pickerSize.w, pickerSize.h); for (y = 0; y < 19; y++) { for (x = 0; x < 15; x++) { ctx.fillStyle = highed.meta.colors[++col]; //highed.meta.colors[x + y * tx]; ctx.fillRect(x * tx, y * ty, tx, ty); } } } /* Hide the picker */ function hide() { highed.dom.style(container, { opacity: 0, left: '-20000px', 'pointer-events': 'none' }); binder(); pbinder(); cbinder(); dbinder(); } function rgbToHex(r, g, b) { var res = '#' + ((r << 16) | (g << 8) | b).toString(16); if (res.length === 5) { return res.replace('#', '#00'); } else if (res.length === 6) { return res.replace('#', '#0'); } return res; } function pickColor(e) { var px = e.clientX || e.touches[0].clientX || 0, py = e.clientY || e.touches[0].clientY || 0, cp = highed.dom.pos(canvas), id = ctx.getImageData(px - cp.x - x, py - cp.y - y, 1, 1).data, col = rgbToHex(id[0] || 0, id[1], id[2]); manualInput.value = col; updatePickerBackground(col); if (highed.isFn(fn)) { fn(col); } e.cancelBubble = true; e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); return false; } /////////////////////////////////////////////////////////////////////// //Make sure we're not off screen if (x > windowSize.w - containerSize.w) { x = windowSize.w - containerSize.w - 10; } if (y > windowSize.h - containerSize.h) { y = windowSize.h - containerSize.h - 10; } highed.dom.style(container, { left: x + 'px', top: y + 'px', opacity: 1, 'pointer-events': 'auto' }); dbinder = highed.showDimmer(hide, true, true, 5); cbinder = highed.dom.on(closeBtn, 'click', hide); binder = highed.dom.on(manualInput, 'keyup', function() { if (highed.isFn(fn)) { fn(manualInput.value); } }); pbinder = highed.dom.on(canvas, ['mousedown', 'touchstart'], function(e) { var mover = highed.dom.on(canvas, ['mousemove', 'touchmove'], pickColor), cancel = highed.dom.on( document.body, ['mouseup', 'touchend'], function() { mover(); cancel(); } ); pickColor(e); }); manualInput.value = current; updatePickerBackground(current); drawPicker(); /////////////////////////////////////////////////////////////////////// return {}; }; highed.dom.ap(container, canvas, manualInput, closeBtn); })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** A standard toolbar. * * @example * var toolbar = highed.Toolbar('my-node', { * additionalCSS: ['cool-toolbar'] * }); * * @constructor * @param parent {domnode} - the node to attach the toolbar to * @param attributes {object} - toolbar settings * > additionalCSS {array} - array of additional css classes to add to the toolbar */ highed.Toolbar = function(parent, attributes) { var properties = highed.merge( { additionalCSS: [] }, attributes ), container = highed.dom.cr( 'div', 'highed-toolbar ' + properties.additionalCSS.join(' ') ), left = highed.dom.cr('div', 'highed-toolbar-left'), right = highed.dom.cr('div', 'highed-toolbar-right'), center = highed.dom.cr('div', 'highed-toolbar-center'), iconsRight = highed.dom.cr('div', 'icons'); /////////////////////////////////////////////////////////////////////////// /** Add an icon to the toolbar * @memberof highed.Toolbar * @param icon {object} - an object containing the icon settings. * > css {array} - the additional css class(s) to use * > click {function} - the function to call when the icon is clicked */ function addIcon(icon, where) { var i = highed.dom.cr('div', 'icon highed-icon fa ' + (icon.css || '')); highed.dom.on(i, 'click', function(e) { if (highed.isFn(icon.click)) { icon.click(e); } }); i.title = icon.tooltip || icon.title; highed.dom.ap(where === 'left' ? left : right, i); } /** Add a button to the toolbar * @memberof highed.Toolbar * @param icon {object} - an object containing the icon settings. * > css {array} - the additional css class(s) to use * > click {function} - the function to call when the icon is clicked */ function addButton(icon, where) { var i = highed.dom.cr( 'div', 'highed-ok-button highed-toolbar-button', icon.title || '' ); highed.dom.on(i, 'click', function(e) { if (highed.isFn(icon.click)) { icon.click(e); } }); i.title = icon.tooltip; highed.dom.ap(where === 'left' ? left : right, i); } function addSeparator(where) { highed.dom.ap( where === 'left' ? left : right, highed.dom.cr('span', 'separator') ); } /////////////////////////////////////////////////////////////////////////// highed.dom.ap(parent, highed.dom.ap(container, left, center, right)); /////////////////////////////////////////////////////////////////////////// return { /** The toolbar container * @type {domnode} * @memberof highed.Toolbar */ container: container, addIcon: addIcon, addButton: addButton, addSeparator: addSeparator, /** The left part of the toolbar * @type {domnode} * @memberof highed.Toolbar */ left: left, /** The center part of the toolbar * @type {domnode} * @memberof highed.Toolbar */ center: center, /** The right part of the toolbar * @type {domnode} * @memberof highed.Toolbar */ right: right }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format (function() { /** Font picker * * Creates a small font picking widget editing of: * - bold * - font family * - font size * - color * * Note that this must be attached to the document manually by appending * the returned container to something. * * @example * var picker = highed.FontPicker(function (newStyle) { * highed.dom.style(document.body, newStyle); * }); * * highed.dom.ap(document.body, picker.container); * * @param fn {function} - the function to call when things change * @param style {object} - the current style object * > fontFamily {string} - the font family * > color {string} - the font color * > fontWeight {string} - the current font weight * > fontStyle {string} - the current font style * @returns {object} - an interface to the picker * > container {domnode} - the body of the picker */ highed.FontPicker = function(fn, style) { var container = highed.dom.cr('div', 'highed-font-picker'), fontFamily = highed.DropDown(), //highed.dom.cr('select', 'font-family'), fontSize = highed.DropDown(null, 'highed-font-size'), //highed.dom.cr('select', 'font-size'), boldBtn = highed.PushButton(false, 'bold'), italicBtn = highed.PushButton(false, 'italic'), color = highed.dom.cr('span', 'font-color', ' '); if (highed.isStr(style)) { try { style = JSON.parse(style); } catch (e) {} } /////////////////////////////////////////////////////////////////////// function callback() { if (highed.isFn(fn)) { fn(style); } } function updateColor(ncol, suppressCallback) { highed.dom.style(color, { background: ncol }); style.color = ncol; if (!suppressCallback) { callback(); } } /////////////////////////////////////////////////////////////////////// /** Set the current options * @memberof highed.FontPicker * @param options {object} - the options to set */ function set(options) { if (highed.isStr(options)) { try { options = JSON.parse(options); } catch (e) { highed.log(0, 'Error in FontPicker::set'); return; } } style = highed.merge( { fontFamily: 'Default',//'"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif', color: '#333', fontSize: '18px', fontWeight: 'normal', fontStyle: 'normal' }, options ); //Set the current values boldBtn.set(style.fontWeight === 'bold'); italicBtn.set(style.fontStyle === 'italic'); updateColor(style.color, true); fontFamily.selectById(style.fontFamily); fontSize.selectById(style.fontSize.replace('px', '')); } //Add fonts to font selector fontFamily.addItems(highed.meta.fonts); //Add font sizes fontSize.addItems([8, 10, 12, 14, 16, 18, 20, 22, 25, 26, 28, 30, 32, 34]); set(style); //Listen to font changes fontFamily.on('Change', function(selected) { if (selected.id() === 'Default') style.fontFamily = '"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif'; else style.fontFamily = selected.id(); return callback(); }); //Listen to font size changes fontSize.on('Change', function(selected) { style.fontSize = selected.id() + 'px'; return callback(); }); //Listen to bold changes boldBtn.on('Toggle', function(state) { style.fontWeight = state ? 'bold' : 'normal'; callback(); }); //Listen to italic changes italicBtn.on('Toggle', function(state) { style.fontStyle = state ? 'italic' : 'normal'; callback(); }); //Handle color picker highed.dom.on(color, 'click', function(e) { highed.pickColor(e.clientX, e.clientY, style.color, updateColor); }); //Create DOM highed.dom.ap( container, fontFamily.container, fontSize.container, highed.dom.ap( highed.dom.cr('div', 'highed-font-picker-buttons'), highed.dom.ap ( highed.dom.cr('div', 'highed-font-style'), boldBtn.button, italicBtn.button ), color ) ); /////////////////////////////////////////////////////////////////////// return { set: set, container: container }; }; })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** A wizard-type stepper * This is sort of like a tab control, but with a logical * x -> y flow. * * @emits Step - when going back/forth * @emits AddStep - when a new step is added * * @constructor * @param bodyParent {domnode} - the node to attach the body to * @param indicatorParent {domnode} - the node to attach the indicators to * @param attributes {object} - the settings for the stepper * > indicatorPos {enum} - the indicator alignment * > top * > bottom */ highed.WizardStepper = function(bodyParent, indicatorParent, attributes) { var properties = highed.merge( { indicatorPos: 'top' }, attributes ), events = highed.events(), body = highed.dom.cr('div', 'highed-wizstepper-body'), indicators = highed.dom.cr('div', 'highed-wizstepper-indicators'), currentIndicator = highed.dom.cr('div', 'highed-wizstepper-current'), currentBubble = highed.dom.cr('div', 'highed-wizstpper-current-bubble'), activeStep = false, stepCount = 0, steps = [], ctx = highed.ContextMenu(); /////////////////////////////////////////////////////////////////////////// /* Update the bar CSS - this is more stable than doing it in pure CS */ function updateBarCSS() { var fsteps = steps.filter(function(t) { return t.visible; }); stepCount = 0; fsteps.forEach(function(step, i) { if (i === 0) { step.bar.className = 'bar bar-first'; } else if (i === fsteps.length - 1) { step.bar.className = 'bar bar-last'; } else { step.bar.className = 'bar'; } step.number = ++stepCount; step.bar.className += ' ' + (properties.indicatorPos === 'bottom' ? 'bar-bottom' : 'bar-top'); }); } /** Add a new step * @memberof highed.WizardStepper * @param step {object} - an object describing the step * > title {string} - the step title * @returns {object} - interface to manipulate the step * > activate {function} - function to activate the step * > bubble {domnode} - the node for the bubble * > body {domnode} - the node for the step body */ function addStep(step) { var stepexports = { number: ++stepCount, node: highed.dom.cr('div', 'highed-wizstepper-item'), label: highed.dom.cr('div', '', step.title, 'label'), bubble: highed.dom.cr( 'div', 'bubble ' + (properties.indicatorPos === 'bottom' ? 'bubble-bottom' : 'bubble-top') ), bar: highed.dom.cr( 'div', 'bar ' + (properties.indicatorPos === 'bottom' ? 'bar-bottom' : 'bar-top') ), body: highed.dom.cr('div', 'highed-step-body'), visible: true }; stepexports.title = step.title; function activate() { if (activeStep) { activeStep.bubble.innerHTML = ''; highed.dom.style(activeStep.bubble, { height: '', width: '', bottom: '-4px', 'font-size': '0px' }); highed.dom.style(activeStep.body, { opacity: 0, display: 'none', 'pointer-events': 'none' }); if (properties.indicatorPos === 'top') { highed.dom.style(activeStep.bubble, { top: '-6px', bottom: '' }); } activeStep.label.className = 'label-inactive'; currentIndicator.innerHTML = step.title + ' - ' + stepexports.number + '/' + stepCount; //highed.dom.ap(currentIndicator, currentBubble); currentBubble.innerHTML = stepexports.number + '/' + stepCount; if (step.onshow) { step.onshow(); } } stepexports.bubble.innerHTML = stepexports.number; highed.dom.style(stepexports.bubble, { height: '25px', width: '25px', bottom: '-8px', 'font-size': '16px' }); highed.dom.style(stepexports.body, { opacity: 1, display: 'block', 'pointer-events': 'auto' }); if (properties.indicatorPos === 'top') { highed.dom.style(stepexports.bubble, { top: '-10px' }); } activeStep = stepexports; activeStep.label.className = 'label-active'; events.emit('Step', stepexports, stepCount, step); } stepexports.hide = function() { highed.dom.style(stepexports.node, { display: 'none' }); if (stepexports.visible) { //This needs fixing stepCount--; stepexports.visible = false; updateBarCSS(); } }; stepexports.show = function() { highed.dom.style(stepexports.node, { display: '' }); if (!stepexports.visible) { stepCount++; stepexports.visible = true; updateBarCSS(); if (step.onshow) { step.onshow(); } } }; stepexports.visible = function() { return visible; }; highed.dom.on(stepexports.node, 'click', activate); if (!activeStep) { activate(); } stepexports.activate = activate; steps.push(stepexports); updateBarCSS(); highed.dom.ap( indicators, highed.dom.ap( stepexports.node, stepexports.label, stepexports.bar, stepexports.bubble ) ); highed.dom.ap(body, stepexports.body); events.emit('AddStep', activeStep, stepCount); return stepexports; } /** Go to the next step * @memberof highed.WizardStepper */ function next() { var fsteps = steps.filter(function(t) { return t.visible; }); if (activeStep && activeStep.number < stepCount) { fsteps[activeStep.number].activate(); } } /** Go to the previous step * @memberof highed.WizardStepper */ function previous() { var fsteps = steps.filter(function(t) { return t.visible; }); if (activeStep && activeStep.number > 1) { fsteps[activeStep.number - 2].activate(); } } /** Force a resize of the splitter * @memberof highed.WizardStepper * @param w {number} - the width of the stepper (will use parent if null) * @param h {number} - the height of the stepper (will use parent if null) */ function resize(w, h) { var ps = highed.dom.size(bodyParent); highed.dom.style(body, { height: (h || ps.h) + 'px' }); } /** Select the first step * @memberof highed.WizardStepper */ function selectFirst() { steps.some(function(step, i) { if (step.visible) { step.activate(); return true; } }); } highed.dom.on(currentIndicator, 'click', function(e) { var fsteps = steps.filter(function(t) { return t.visible; }); ctx.build( fsteps.map(function(step) { return { title: step.title, click: step.activate, selected: activeStep.title === step.title }; }) ); ctx.show(e.clientX, e.clientY); }); /////////////////////////////////////////////////////////////////////////// highed.dom.ap( indicatorParent, indicators, highed.dom.ap(currentIndicator, currentBubble) ); highed.dom.ap(bodyParent, body); /////////////////////////////////////////////////////////////////////////// return { on: events.on, addStep: addStep, next: next, resize: resize, previous: previous, selectFirst: selectFirst, /** The main body * @memberof highed.WizardStepper * @type {domnode} */ body: body }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format (function() { var container = highed.dom.cr( 'div', 'highed-scrollbar highed-tooltip highed-tooltip-fixed' ); highed.ready(function() { highed.dom.ap(document.body, container); }); function hide() { highed.dom.style(container, { opacity: 0, 'pointer-events': 'none' }); } highed.dom.on(container, 'mouseout', hide); highed.dom.on(container, 'click', hide); /** Show a tooltip * @param x {number} - the x position of the tooltip * @param y {number} - the y position of the tooltip * @param tip {string} - the title * @param blowup {boolean} - blow the tooltip up */ highed.Tooltip = function(x, y, tip, blowup) { var ds = highed.dom.size(document.body); if (x < 0) x = 0; if (y < 0) y = 0; if (x > ds.w - 200) x = ds.w - 200; highed.dom.style(container, { opacity: 1, 'pointer-events': 'auto', left: x + 'px', top: y + 'px', 'max-width': '300px' }); if (blowup) { highed.dom.style(container, { opacity: 1, 'pointer-events': 'auto', width: '90%', height: '90%', left: '50%', top: '50%', transform: 'translate(-50%, -50%)' }); } container.innerHTML = tip; return hide; }; highed.hideAllTooltips = hide; })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** A simple toggle button component * * @example * //Create a push button with the gear icon attached * highed.PushButton(document.body, 'gear', false).on('Toggle', function (state) { * alert('Push button is now ' + state); * }); * * @constructor * * @emits Toggle {boolean} - when the state changes * * @param parent {domnode} (optional) - the parent to attach the button to * @param icon {string} - the button icon * @param state {boolean} - the initial state of the button */ highed.PushButton = function(parent, icon, state) { var button = highed.dom.cr('span', 'highed-pushbutton fa fa-' + icon), events = highed.events(); function updateCSS() { if (state) { button.className += ' highed-pushbutton-active'; } else { button.className = button.className.replace( ' highed-pushbutton-active', '' ); } } /** Set the current state * @memberof highed.PushButton * @param flag {boolean} - the new state */ function set(flag) { state = flag; updateCSS(); } highed.dom.on(button, 'click', function() { state = !state; updateCSS(); events.emit('Toggle', state); }); if (!highed.isNull(parent) && parent !== false) { highed.dom.ap(parent, button); } updateCSS(); return { set: set, /** The button * @memberof highed.PushButton * @type {domnode} */ button: button, on: events.on }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** Tree component * For an example of formatting, build the editor with `gulp with-advanced`, * and look in `src/meta/highed.options.advanced.js`. * * @emits Select {object} - when a node is selected * * @constructor * @param parent {domnode} - the node to attach the tree to */ highed.Tree = function(parent) { var container = highed.dom.cr('div', 'highed-tree'), selectedNode = false, events = highed.events(), expands = {}, expandState = {}, selectedID = false, selectedPath = false, attachedData = {}, filters = { //Filter the series properties based on the series.type property series: { controller: 'type', state: false, default: 'line' }, plotOptions: { controller: 'type', state: false, default: 'line' } }; //////////////////////////////////////////////////////////////////////////// function createNode(child, pnode, instancedData, productFilter, myIndex) { var id = (child.meta.ns ? child.meta.ns + '.' : '') + (!isNaN(myIndex) ? '[' + myIndex + '].' : '') + child.meta.name; var node = highed.dom.cr( 'div', 'node', '', id ), title = highed.dom.cr( 'div', 'parent-title', highed.uncamelize(child.meta.title || child.meta.name) ), body = highed.dom.cr('div', 'parent-body'), icon = highed.dom.cr('div', 'exp-col-icon fa fa-folder-o'), rightIcons = highed.dom.cr('div', 'right-icons'), remIcon = highed.dom.cr('div', 'highed-icon fa fa-minus-square-o'), addIcon = highed.dom.cr('div', 'highed-icon fa fa-plus-square-o'), index = (child.meta.ns ? child.meta.ns + '.' : '') + (myIndex ? '[' + myIndex + '].' : '') + //(!isNaN(myIndex) ? '[' + myIndex + '].' : '') + child.meta.name, expanded = true; //child.meta.fullname = index; child.meta.fullname = (myIndex ? child.meta.name : index); function pushExpandState() { if ( (!child.meta.types.array && typeof expandState[index] !== 'undefined') || expanded ) { expandState[index] = expanded; } } function select() { if (selectedNode) { selectedNode.className = 'parent-title'; } selectedNode = title; selectedPath = index; title.className = 'parent-title parent-title-selected'; events.emit( 'Select', child, title.innerHTML, child.data, productFilter, filters[index] ? child.data[filters[index].controller] || filters[index].default : false ); } function expand(noSelect, force) { if ( (force || !expanded) && child.children.length && child.meta.hasSubTree ) { icon.className = 'exp-col-icon fa fa-folder-open-o'; highed.dom.style(body, { display: 'block' }); expanded = true; pushExpandState(); } if (!noSelect) { select(); } highed.emit( 'UIAction', 'AdvancedTreeNavigation', (child.meta.ns ? child.meta.ns + '.' : '') + child.meta.name ); } function collapse(noSelect, noPush) { if (expanded && child.children.length && child.meta.hasSubTree) { icon.className = 'exp-col-icon fa fa-folder-o'; highed.dom.style(body, { display: 'none' }); expanded = false; if (!noPush) { pushExpandState(); } } if (!noSelect) { select(); } } function toggle(e) { if (expanded) { collapse(); } else { expand(); } if (e) { return highed.dom.nodefault(e); } } function buildSubtree(activeFilter) { body.innerHTML = ''; // Skip this element if it's not part of the current product if ( productFilter && Object.keys(child.meta.products || {}).length > 0 && !child.meta.products[productFilter] ) { //return false; } if (child.meta.isArrayElement) { highed.dom.ap(node, highed.dom.ap(rightIcons, remIcon)); highed.dom.on(remIcon, 'click', function(e) { if (confirm('Really delete the element? This cannot be undone!')) { var delIndex = false; if (selectedNode === node) { selectedNode.className = 'parent-title'; selectedNode = false; selectedPath = false; events.emit('ClearSelection'); } body.parentNode.removeChild(body); node.parentNode.removeChild(node); // This is a bit convuluted, but we can't do a filter child.meta.arrayData.some(function(a, i) { if (a === child.data) { delIndex = i; return true; } }); child.meta.arrayData.splice(delIndex, 1); events.emit('ForceSave', attachedData); highed.snackBar( 'Removed element ' + delIndex + ' from ' + (child.meta.ns ? child.meta.ns + '.' : '') + child.meta.name ); } return highed.dom.nodefault(e); }); } // This node contains an array of stuff if (child.meta.types.array) { highed.dom.ap(node, highed.dom.ap(rightIcons, addIcon)); icon.className = 'exp-col-icon fa fa-th-list'; // We need to create one child per. existing entry child.data = instancedData[child.meta.name] = instancedData[child.meta.name] || []; // Force it to be an array if (!highed.isArr(child.data)) { child.data = instancedData[child.meta.name] = [ instancedData[child.meta.name] ]; } function addArrayElementToList(data, i) { var cat = { meta: { name: child.meta.name, title: child.meta.name + '[' + i + ']', hasSubTree: true, arrayData: instancedData[child.meta.name], isArrayElement: true, types: { object: 1 } }, data: data, // We need to clone the children since the builders // add data attributes to them. // If we don't clone, all the sub-stuff will link to // the last child data accross all instances. children: highed.merge([], child.children) }, node = createNode(cat, body, data, productFilter, i); if (node) { build(cat, node.body, data, productFilter, i); } } highed.dom.on(addIcon, 'click', function() { var newElement = {}; highed.snackBar('Added new element to ' + child.meta.name); child.data.push(newElement); addArrayElementToList(newElement, child.data.length - 1); events.emit('ForceSave', attachedData); }); child.data.forEach(addArrayElementToList); } else { // Only allow expanding on non-array parents highed.dom.on(node, 'click', function() { expand(); }); highed.dom.on(icon, 'click', toggle); if (!child.meta.hasSubTree) { icon.className = 'exp-col-icon fa fa-sliders'; } // Add data instance if (!child.meta.isArrayElement) { child.data = instancedData[child.meta.name] = instancedData[child.meta.name] || {}; } // Collapsed by default if (!expandState[index]) { collapse(true, true); } else { expand(true, true); } if (index === selectedPath) { select(); } } } //////////////////////////////////////////////////////////////////////// highed.dom.ap(pnode, highed.dom.ap(node, icon, title), body); expands[index] = expand; buildSubtree(); return { data: child.data, body: body, rebuild: buildSubtree }; } /** Expand to show a given ID * @memberof highed.Tree * @param id {string} - the ID of the element to expand */ function expandTo(id) { var prev = ''; if (!id) return; id = id .replace(/\-\-/g, '.') .replace(/\-/g, '.') .split('.'); id.forEach(function(seg) { seg = prev + seg; if (expands[seg]) expands[seg](); prev += seg + '.'; }); } /** Build the tree * * This function takes in a transformed, compact, meta definitions * for all entries in the API. The definitions are structured as an actual * tree, where each node has an array of children, and a meta object with * meta information such as data type, default, and GH links. * * @memberof highed.Tree * @param tree {object} - the tree to display * > children {object} - the children of the node * > entries {array} - array of orphan children * @param pnode {domnode} - the parent node * @param instancedData {object} - the actual tree data * @param dataIndex {number} - the path to data in arrays */ function build(tree, pnode, instancedData, productFilter, myIndex) { if (!tree) { return; } // Handled in createNode, just skip. if (tree.meta.types['array']) { return; } if ( productFilter && Object.keys(tree.meta.products || {}).length > 0 && !tree.meta.products[productFilter] ) { //return; } if (highed.isArr(tree.children)) { tree.children.forEach(function(child) { var node, fstate; if (tree.meta.fullname && filters[tree.meta.fullname]) { if (child.meta && child.meta.validFor) { var customizedSeriesOption = productFilter.series; if (myIndex) customizedSeriesOption = [customizedSeriesOption[myIndex]]; var found = false; (customizedSeriesOption || []).forEach(function(serieOption) { fstate = serieOption[filters[tree.meta.fullname].controller] || filters[tree.meta.fullname].default; if (child.meta.validFor[fstate]) found = true; }); if (!found) { return; } } } if (!child.meta.leafNode) { node = createNode(child, pnode, instancedData, productFilter); if (node) { build(child, node.body, node.data, productFilter); } } }); } } function getMasterData() { return attachedData; } function isFilterController(ns, name) { if (typeof filters[ns] !== 'undefined') { return filters[ns].controller === name; } return false; } //////////////////////////////////////////////////////////////////////////// highed.dom.ap(parent, container); //////////////////////////////////////////////////////////////////////////// return { on: events.on, expandTo: expandTo, getMasterData: getMasterData, isFilterController: isFilterController, build: function(tree, data) { attachedData = data; container.innerHTML = ''; build(tree, container, data, data); } }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format (function() { var container = highed.dom.cr('div', 'highed-snackbar no-print'), title = highed.dom.cr('span', 'snackbar-title', ''), action = highed.dom.cr('span', 'snackbar-action', ''), closeNode = highed.dom.cr( 'span', 'highed-snackbar-close fa fa-times-circle', '' ), timeout = false, callback = false; highed.ready(function() { highed.dom.ap( document.body, highed.dom.ap(container, title, action, closeNode) ); }); highed.dom.on(container, 'mouseover', function() { window.clearTimeout(timeout); }); highed.dom.on(container, 'mouseout', function() { hide(); }); highed.dom.on(closeNode, 'click', function() { highed.dom.style(container, { bottom: '-68px' }); }); /////////////////////////////////////////////////////////////////////////// function hide() { timeout = window.setTimeout(function() { highed.dom.style(container, { bottom: '-68px' }); }, 5000); } /////////////////////////////////////////////////////////////////////////// /** Show a snackbar * A snack bar is those info rectangles showing up on the bottom left. * * @example * highed.snackBar('Hello world!'); * * @param stitle {string} (optional) - the snackbar title * @param saction {string} (optional) - the snackbar action text * @param fn {function} (optional) - the function to call when clicking the action */ highed.snackBar = function(stitle, saction, fn) { title.innerHTML = stitle; // .toUpperCase(); window.clearTimeout(timeout); if (saction) { action.innerHTML = saction.toUpperCase(); } if (callback) { callback(); } highed.dom.style(container, { bottom: '10px' }); highed.dom.style(action, { display: saction ? '' : 'none' }); callback = highed.dom.on(action, 'click', fn); hide(); }; })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** A context menu component * Does a typicall right-click menu. * Note that each instance get their own DOM node in the document body. * * @example * var ctx = highed.ContextMenu([ * { * title: "Hello World", * click: function (e) { * alert('hello world!'); * } * } * ]); * * @constructor * @param stuff {object} - things to add (optional) * > title {string} - the title of the entry * > click {function} - function to call when selecting the item */ highed.ContextMenu = function(stuff) { var container = highed.dom.cr( 'div', 'highed-ctx-container-common highed-ctx-container' ), closeBtn = highed.dom.cr('div', 'highed-ctx-close-button', 'Close'), visible = false, dimHide = false; /////////////////////////////////////////////////////////////////////////// /** Add an entry to the menu * @memberof highed.ContextMenu * @param entry {object} - the definition of the entry to add * > title {string} - the title of the entry * > click {function} - the function to call when clicking the item */ function addEntry(entry) { var item = highed.dom.cr( 'div', 'highed-ctx-item highed-ctx-item-responsive', entry.title ), right = highed.dom.cr('div', 'highed-ctx-child-icon fa fa-angle-right'), childCtx; if (entry === '-') { return highed.dom.ap(container, highed.dom.cr('div', 'highed-ctx-sep')); } highed.dom.on(item, 'click', function() { if (highed.isFn(entry.click)) { entry.click(); } hide(); }); if (entry.selected) { item.className += ' highed-ctx-item-selected'; } if (!highed.isNull(entry.children)) { childCtx = highed.ContextMenu(entry.children); highed.dom.on(item, 'mouseenter', function(e) { childCtx.show(e.clientX, e.clientY); }); } highed.dom.ap( container, highed.dom.ap( item, entry.icon ? highed.dom.cr( 'div', 'ctx-child-licon highed-ctx-child-licon-responsive fa fa-' + entry.icon ) : false, entry.children ? right : false ) ); } /** Show the menu * @memberof highed.ContextMenu * @param x {number} - the x position * @param y {number} - the y position */ function show(x, y, noDimmer) { var psize = highed.dom.size(document.body), size = highed.dom.size(container); if (!noDimmer && visible) return; if (x > psize.w - size.w - 20) { x = psize.w - size.w - 20; } if (y > psize.h - size.h - 20) { y = psize.h - size.h - 20; } highed.dom.style(container, { 'pointer-events': 'auto', opacity: 1, left: x + 'px', top: y + 'px' }); visible = true; if (!noDimmer) dimHide = highed.showDimmer(hide, true, true, 10); } /** Hide the menu * @memberof highed.ContextMenu */ function hide() { if (!visible) return; highed.dom.style(container, { left: '-2000px', 'pointer-events': 'none', opacity: 0 }); if (highed.isFn(dimHide)) { dimHide(); } visible = false; } /** Build a menu * @memberof highed.ContextMenu * @param def {array} - an array of entries */ function build(def) { container.innerHTML = ''; highed.dom.ap(container, closeBtn); if (highed.isArr(def)) { return def.forEach(addEntry); } Object.keys(def).forEach(function(key) { var entry = def[key]; addEntry(highed.merge({ title: key }, entry)); }); } /////////////////////////////////////////////////////////////////////////// if (stuff) { build(stuff); } highed.dom.on(closeBtn, 'click', hide); highed.ready(function() { highed.dom.ap(document.body, container); }); /////////////////////////////////////////////////////////////////////////// return { addEntry: addEntry, show: show, hide: hide, build: build }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format (function() { var dropdownItems = highed.dom.cr( 'div', 'highed-dropdown-items highed-dropdown-items-responsive' ); highed.ready(function() { highed.dom.ap(document.body, dropdownItems); }); /** A stylable dropdown * @constructor * * @emits Change - when the selection changes * @emits Open - when the dropdown is opened * @emits Close - when the dropdown is closed * * @param parent {domnode} - the node to attach the dropdown to */ highed.DropDown = function(parent, extraClasses, icons) { var events = highed.events(), container = highed.dom.cr('div', 'highed-dropdown ' + extraClasses), body = highed.dom.cr('div', 'highed-dropdown-body'), arrow = highed.dom.cr('div', 'highed-dropdown-arrow fa fa-caret-down'), items = [], selectedItem = false, expanded = false, catcher = false; //////////////////////////////////////////////////////////////////////// //Build the DOM function buildDOM() { dropdownItems.innerHTML = ''; items.forEach(function(item) { highed.dom.ap(dropdownItems, item.node); //IE fix item.node.innerHTML = ''; //item.title(); const icon = highed.dom.cr('span', 'highed-icon-container'); if (icons) { highed.dom.ap(icon, highed.dom.style(highed.dom.cr('span'), { 'margin-left': '2px', width: '15px', height: '15px', float: 'left', display: 'inline-block', "margin-right": "5px", "color": "rgb(66, 200, 192)", 'background-position': 'left middle', 'background-size': 'auto 100%', 'background-repeat': 'no-repeat', 'background-image': 'url("data:image/svg+xml;utf8,' + encodeURIComponent(icons[item.id().toLowerCase()]) + '")' })); } highed.dom.ap(item.node, icon, highed.dom.style(highed.dom.cr('span', '', item.title() || ''), { 'position': 'relative', 'top': '3px'})); }); } //Collapse the dropdown function collapse() { if (highed.isFn(catcher)) { catcher(); catcher = false; } //Should update the container if (selectedItem) { body.innerHTML = ''; if (icons) { highed.dom.ap(body, highed.dom.style(highed.dom.cr('span'), { 'margin-left': '2px', width: '15px', height: '15px', float: 'left', display: 'inline-block', "margin-right": "5px", "color": "rgb(66, 200, 192)", 'background-position': 'left middle', 'background-size': 'auto 100%', 'background-repeat': 'no-repeat', 'background-image': 'url("data:image/svg+xml;utf8,' + encodeURIComponent(icons[selectedItem.id().toLowerCase()]) + '")' })); } body.innerHTML += selectedItem.title(); } highed.dom.style(dropdownItems, { opacity: 0, left: '-20000px', 'pointer-events': 'none' }); expanded = false; } //Expand the dropdown function expand(e) { buildDOM(); var pos = highed.dom.pos(container, true), s = highed.dom.size(container); //Quick hack for IE... if (!pos || !pos.x) { pos = { x: 10, y: 10 }; } if (!s || !s.w) { s = { w: 200, h: 200 }; } //Need to check the height + y to see if we need to move it highed.dom.style(dropdownItems, { opacity: 1, 'pointer-events': 'auto', left: pos.x + 'px', top: pos.y + s.h + 4 + 'px', width: s.w - 1 + 'px', 'min-height': s.h + 'px' }); catcher = highed.showDimmer(collapse, true, true, 500); expanded = true; } //Toggle expansion function toggle(e) { expanded = !expanded; if (expanded) { return expand(e); } collapse(); return expanded; } /** Add an item to the dropdown * @memberof highed.DropDown * @param item {object} - the item to add * > title {string} - the title of the item * > id {anyting} - the id of the item * > select {function} - function to call when the item is selected */ function addItem(item) { if (item && item.id) { if (!highed.isBasic(item.id)) { item.id = '1234'; } } if (highed.isBasic(item)) { item = { id: item, title: item }; } if ( items.filter(function(b) { return b.id() === item.id; }).length > 0 ) { return false; } var node = highed.dom.cr('div', 'highed-dropdown-item'), id = highed.uuid(), index = items.length, itemInstance = { //The node node: node, //Get the index index: function() { return index; }, //Get the ID id: function() { return id; }, icon: function() { return item.icon; }, //Get the title title: function() { return highed.isStr(item) ? item : item.title || ''; }, //Unselect the item unselect: function() { node.className = 'highed-dropdown-item'; }, //Select the item select: function(dontEmit) { if (selectedItem) { selectedItem.unselect(); } node.className = 'highed-dropdown-item highed-dropdown-item-selected'; selectedItem = itemInstance; body.innerHTML = selectedItem.title(); if (!dontEmit) events.emit('Change', itemInstance); if (item && highed.isFn(item.select)) { item.select(itemInstance); } collapse(); }, updateOptions: function(updatedItem) { item = updatedItem; }, setId: function(newId) { id = newId; } }; if (!item) { return false; } if (highed.isStr(item) || highed.isNum(item)) { node.innerHTML = item; id = item; } else { const icon = highed.dom.cr('span', 'highed-icon-container', (item.icon ? '' : '')); highed.dom.style(icon, { "margin-right": "5px", "color": "rgb(66, 200, 192)" }); highed.dom.ap(node, icon, highed.dom.cr('span', '', item.title || '')); id = item.id; // || id; if (item.selected) { itemInstance.select(); } } highed.dom.on(node, 'click', function(e) { itemInstance.select(); e.cancelBubble = true; e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); return false; }); items.push(itemInstance); return itemInstance; } /** Clear the dropdown * @memberof highed.DropDown */ function clear() { items = []; } /** Add several items to the dropdown * @memberof highed.DropDown * @param itemsToAdd {array} - array of items to add */ function addItems(itemsToAdd) { if (highed.isArr(itemsToAdd)) { itemsToAdd.forEach(addItem); } } /** Set the current selection by id * @memberof highed.DropDown * @param id {anything} - the id to select */ function selectById(id, dontEmit) { items.some(function(item) { //This is not a typo.. if (item.id() == id) { item.select(dontEmit); return true; } }); } function updateByIndex(index, details, newId) { items[index].updateOptions(details); if (newId) items[index].setId(newId); } /** Set the current selection by index * @memberof highed.DropDown * @param index {number} - the index to select in range [0..item.length] */ function selectByIndex(index, dontEmit) { if (index >= 0 && index < items.length) { items[index].select(dontEmit); } } function selectAll() { return items; } function deleteByIndex(index) { items.splice(index, 1); } function sliceList(length) { items = items.slice(0, length); } function getSelectedItem() { return selectedItem; } /////////////////////////////////////////////////////////////////////////// if (parent) { parent = highed.dom.get(parent); highed.dom.ap(parent, container); } highed.dom.ap(container, body, arrow); highed.dom.on(container, 'click', toggle); return { container: container, selectById: selectById, selectByIndex: selectByIndex, selectAll: selectAll, updateByIndex: updateByIndex, deleteByIndex: deleteByIndex, sliceList: sliceList, addItems: addItems, getSelectedItem: getSelectedItem, addItem: addItem, clear: clear, on: events.on }; }; })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** Make a node movable * @constructor * * @emits StartMove - when starting to move * @emits Moving - when moving * @emits EndMove - when stopping to move * * @param target {domnode} - the node to make movable * @param constrain {string} - constrain moving: `XY`, `Y`, or `X` */ highed.Movable = function( target, constrain, constrainParent, parentNode, min, doOffset ) { var events = highed.events(), moving = false; constrain = (constrain || 'XY').toUpperCase(); target = highed.dom.get(target); if (target) { highed.dom.on(target, ['mousedown', 'touchstart'], function(e) { // if (moving) return; moving = true; var cp = highed.dom.pos(target), ps = highed.dom.size(parentNode || target.parentNode), ns = highed.dom.size(target), x = cp.x, y = cp.y, offsetX = 0, offsetY = 0, mover = highed.dom.on( document.body, ['mousemove', 'touchmove'], function(moveE) { if (constrain === 'X' || constrain === 'XY') { x = cp.x + ((moveE.clientX || moveE.touches[0].clientX) - offsetX); if (constrainParent) { if (x < 0) x = 0; if (x > ps.w - ns.w) x = ps.w - ns.w; } } if (constrain === 'Y' || constrain === 'XY') { y = cp.y + ((moveE.clientY || moveE.touches[0].clientY) - offsetY); if (constrainParent) { if (y < 0) y = 0; if (y > ps.h - ns.h) y = ps.h - ns.h; } } if (min && x < min.x) { x = min.x; } if (min && y < min.y) { y = min.y; } highed.dom.style(target, { left: x - (doOffset ? ns.w : 0) + 'px', top: y + 'px' }); events.emit('Moving', x, y); moveE.cancelBubble = true; moveE.preventDefault(); moveE.stopPropagation(); moveE.stopImmediatePropagation(); return false; } ), upper = highed.dom.on(document.body, ['mouseup', 'touchend'], function( upE ) { //Detach the document listeners upper(); mover(); moving = false; document.body.className = document.body.className.replace( ' highed-nosel', '' ); events.emit('EndMove', x, y); upE.cancelBubble = true; upE.preventDefault(); upE.stopPropagation(); upE.stopImmediatePropagation(); return false; }); document.body.className += ' highed-nosel'; offsetX = e.clientX || e.touches[0].clientX; offsetY = e.clientY || e.touches[0].clientY; events.emit('StartMove', cp.x, cp.y); e.cancelBubble = true; e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); return false; }); } //////////////////////////////////////////////////////////////////////////// return { on: events.on }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** Slider widget * @constructor * * @emits Change - when the value changes * * @param parent {domnode} - the parent of the slider * @param attributes {object} - the slider properties * > max {number} - the max value * > min {number} - the min value * > step {number} - the step size * > resetTo {anything} - value to reset to */ highed.Slider = function(parent, attributes) { var properties = highed.merge( { max: 100, min: 1, step: 1, resetTo: 0, value: 0 }, attributes ), events = highed.events(), value = properties.value || properties.resetTo, container = highed.dom.cr('div', 'highed-slider'), indicator = highed.dom.cr('div', 'highed-slider-indicator'), textIndicator = highed.dom.cr('div', 'highed-slider-text-indicator'), sliderBackground = highed.dom.cr('div', 'highed-slider-background'), resetIcon = highed.dom.cr('div', 'highed-slider-reset fa fa-undo'), numberInput = highed.dom.cr('input', 'highed-slider-input'), mover = highed.Movable(indicator, 'x', true, sliderBackground); numberInput.type = "number"; numberInput.value = value; numberInput.max = properties.max; numberInput.min = 0; //////////////////////////////////////////////////////////////////////////// function updateText() { textIndicator.innerHTML = value; if (value === 'null' || value === null) { textIndicator.innerHTML = 'auto'; } if (value === 'undefined' || typeof value === 'undefined') { textIndicator.innerHTML = 'auto'; } } // Calculate the indicator X function calcIndicator() { var x = 0, s = highed.dom.size(sliderBackground), ms = highed.dom.size(indicator); if (!highed.isNum(value) || !value) { x = 0; } else { x = (value - properties.min) / (properties.max - properties.min) * (s.w - ms.w); } highed.dom.style(indicator, { left: x + 'px' }); } //Waits until the slider is in the dom function tryUpdateIndicators() { updateText(); if (container.parentNode) { calcIndicator(); } else { window.setTimeout(tryUpdateIndicators, 10); } } /** Set the value * @memberof highed.Slider * @param newValue {number} - the new value */ function set(newValue) { value = highed.clamp(properties.min, properties.max, newValue); textIndicator.innerHTML = value; calcIndicator(); } mover.on('Moving', function(x) { var s = highed.dom.size(sliderBackground), ms = highed.dom.size(indicator); //Set the value based on the new X value = properties.min + Math.round(x / (s.w - ms.w) * (properties.max - properties.min)); numberInput.value = value; textIndicator.innerHTML = value; if (!highed.onPhone()) { events.emit('Change', value); } }); highed.dom.on(numberInput, 'keyup', function(e) { if (e.target.value && !isNaN(e.target.value)) { if (parseInt(e.target.value) > properties.max) { value = properties.max; } else value = parseInt(e.target.value); textIndicator.innerHTML = value; calcIndicator(); if (!highed.onPhone()) { events.emit('Change', value); } } }); mover.on('StartMove', function() { if (highed.onPhone()) { textIndicator.className = 'highed-slider-text-indicator highed-slider-text-indicator-popup'; } }); mover.on('EndMove', function() { if (highed.onPhone()) { textIndicator.className = 'highed-slider-text-indicator'; //We're not emitting changes until done on mobile events.emit('Change', value); } }); //////////////////////////////////////////////////////////////////////////// highed.dom.on(resetIcon, 'mouseover', function(e) { // highed.Tooltip(e.clientX, e.clientY, 'Reset to initial value'); }); highed.dom.on(resetIcon, 'click', function() { value = properties.resetTo; calcIndicator(); if (value === 'null') { value = null; } if (value === 'undefined') { value = undefined; } updateText(); events.emit('Change', value); }); if (parent) { parent = highed.dom.get(parent); highed.dom.ap(parent, container); } highed.dom.ap( container, sliderBackground, numberInput, resetIcon, highed.dom.ap(indicator, textIndicator) ); tryUpdateIndicators(); // Public interface return { on: events.on, set: set, container: container }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format function parseCSV(inData, delimiter) { var isStr = highed.isStr, isArr = highed.isArray, isNum = highed.isNum, csv = inData || '', result = [], options = { delimiter: delimiter }, potentialDelimiters = { ',': true, ';': true, '\t': true }, delimiterCounts = { ',': 0, ';': 0, '\t': 0 }; //The only thing CSV formats have in common.. rows = (csv || '').replace(/\r\n/g, '\n').split('\n'); // If there's no delimiter, look at the first few rows to guess it. if (!options.delimiter) { rows.some(function(row, i) { if (i > 10) return true; var inStr = false, c, cn, cl, token = ''; for (var j = 0; j < row.length; j++) { c = row[j]; cn = row[j + 1]; cl = row[j - 1]; if (c === '"') { if (inStr) { if (cl !== '"' && cn !== '"') { // The next non-blank character is likely the delimiter. while (cn === ' ') { cn = row[++j]; } if (potentialDelimiters[cn]) { delimiterCounts[cn]++; return true; } inStr = false; } } else { inStr = true; } } else if (potentialDelimiters[c]) { if (!isNaN(Date.parse(token))) { // Yup, likely the right delimiter token = ''; delimiterCounts[c]++; } else if (!isNum(token) && token.length) { token = ''; delimiterCounts[c]++; } } else { token += c; } } }); options.delimiter = ';'; if ( delimiterCounts[','] > delimiterCounts[';'] && delimiterCounts[','] > delimiterCounts['\t'] ) { options.delimiter = ','; } if ( delimiterCounts['\t'] >= delimiterCounts[';'] && delimiterCounts['\t'] >= delimiterCounts[','] ) { options.delimiter = '\t'; } } rows.forEach(function(row, rowNumber) { var cols = [], inStr = false, i = 0, j, token = '', guessedDel, c, cp, cn; function pushToken() { token = (token || '').replace(/\,/g, ''); if (!token.length) { token = null; // return; } if (isNum(token)) { token = parseFloat(token); } cols.push(token); token = ''; } for (i = 0; i < row.length; i++) { c = row[i]; cn = row[i + 1]; cp = row[i - 1]; if (c === '"') { if (inStr) { pushToken(); } else { inStr = false; } //Everything is allowed inside quotes } else if (inStr) { token += c; //Check if we're done reading a token } else if (c === options.delimiter) { pushToken(); //Append to token } else { token += c; } // Push if this was the last character if (i === row.length - 1) { pushToken(); } } result.push(cols); }); return result; } /** Data table * @constructor * @param {domnode} parent - the node to attach to * @param {object} attributes - the properties */ highed.DataTable = function(parent, attributes) { var properties = highed.merge( { checkable: true, importer: {} }, attributes ), events = highed.events(), container = highed.dom.cr('div', 'highed-dtable-container'), frame = highed.dom.cr('div', 'highed-dtable-table-frame highed-scrollbar'), movementBar = highed.dom.cr('div', 'highed-dtable-movement-bar', ''), table = highed.dom.cr('table', 'highed-dtable-table'), thead = highed.dom.cr('thead', 'highed-dtable-head'), tbody = highed.dom.cr('tbody', 'highed-dtable-body'), tableTail = highed.dom.cr( 'div', 'highed-dtable-table-tail', 'Only the first 500 rows are shown.' ), colgroup = highed.dom.cr('colgroup'), leftBar = highed.dom.cr('div', 'highed-dtable-left-bar'), hideCellsDiv = highed.dom.cr('div', 'highed-dtable-hide-cells'), topBar = highed.dom.cr('div', 'highed-dtable-top-bar'), topLetterBar = highed.dom.cr('div', 'highed-dtable-top-letter-bar'), topColumnBar = highed.dom.cr('div', 'highed-dtable-top-column-bar'), topLeftPanel = highed.dom.cr('div', 'highed-dtable-top-left-panel'), //checkAll = highed.dom.cr('input'), mainInput = highed.dom.cr('textarea', 'highed-dtable-input'), cornerPiece = highed.dom.cr('div', 'highed-dtable-corner-piece'), weirdDataModal = highed.OverlayModal(false, { // zIndex: 20000, showOnInit: false, width: 300, height: 350 }), weirdDataContainer = highed.dom.cr( 'div', 'highed-dtable-weird-data highed-box-size highed-errobar-body' ), weirdDataIgnore = highed.dom.cr( 'button', 'highed-ok-button', 'No, this looks right' ), weirdDataFix = highed.dom.cr( 'button', 'highed-ok-button', 'Yeah, this looks wrong' ), loadIndicator = highed.dom.cr( 'div', 'highed-dtable-load-indicator', ' Loading' ), dropZone = highed.dom.cr( 'div', 'highed-dtable-drop-zone highed-transition' ), liveDataFrame = highed.dom.cr( 'div', 'highed-box-size highed-dtable-gsheet-frame' ), gsheetFrame = highed.dom.cr( 'div', 'highed-box-size highed-dtable-gsheet-frame' ), gsheetContainer = highed.dom.cr( 'div', 'highed-box-size highed-prettyscroll highed-dtable-gsheet' ), liveDataContainer = highed.dom.cr( 'div', 'highed-box-size highed-prettyscroll highed-dtable-gsheet' ), liveDataInput = highed.dom.cr('input', 'highed-imp-input-stretch'), liveDataIntervalInput = highed.dom.cr('input', 'highed-imp-input-stretch'), liveDataTypeSelect = highed.DropDown(), liveDataTypeContainer = highed.dom.cr('div', 'highed-customize-group'), liveDataTypeMasterNode = highed.dom.cr('div', 'highed-customize-master-dropdown'), gsheetID = highed.dom.cr( 'input', 'highed-box-size highed-dtable-gsheet-id' ), gsheetWorksheetID = highed.dom.cr( 'input', 'highed-box-size highed-dtable-gsheet-id' ), gsheetRefreshTime = highed.dom.cr( 'input', 'highed-box-size highed-dtable-gsheet-id' ), gsheetStartRow = highed.dom.cr( 'input', 'highed-box-size highed-dtable-gsheet-id' ), gsheetEndRow = highed.dom.cr( 'input', 'highed-box-size highed-dtable-gsheet-id' ), gsheetStartCol = highed.dom.cr( 'input', 'highed-box-size highed-dtable-gsheet-id' ), gsheetEndCol = highed.dom.cr( 'input', 'highed-box-size highed-dtable-gsheet-id' ), gsheetCancelButton = highed.dom.cr( 'button', 'highed-import-button green padded', 'Detach Sheet From Chart' ), switchRowColumns = highed.dom.cr( 'button', 'switch-column-button highed-template-tooltip', ' Switch Rows/Columns' ), gsheetLoadButton = highed.dom.cr( 'button', 'highed-import-button green padded', 'Load Spreadsheet' ), liveDataLoadButton = highed.dom.cr( 'button', 'highed-import-button green padded', 'Load Live Data' ), liveDataCancelButton = highed.dom.cr( 'button', 'highed-import-button green padded', 'Cancel' ), detailValue = 0, isInGSheetMode = false, isInLiveDataMode = false, mainInputCb = [], rawCSV = false, mainInputCloseCb = false, toolbar, importModal = highed.OverlayModal(false, { minWidth: 600, minHeight: 600 }), importer = highed.DataImporter(importModal.body, properties.importer), rows = [], gcolumns = [], changeTimeout = false, dataModal, surpressChangeEvents = false, monthNumbers = { JAN: 1, FEB: 2, MAR: 3, APR: 4, MAY: 5, JUN: 6, JUL: 7, AUG: 8, SEP: 9, OCT: 10, NOV: 11, DEC: 12 }, selectedRowIndex = 0, keyValue = "A", tempKeyValue = "A", //checkAll.type = 'checkbox', selectedFirstCell = [], selectedEndCell = [], selectedCopyFirstCell = [], selectedCopyEndCell = [], lastSelectedCell = [null, null], allSelectedCells = [], allSelectedCopyCells = [], selectedHeaders = [], columnsToHighlight = [], dataFieldsUsed = [], inCopyOverCellMode = false; moveToColumn = null, dragHeaderMode = false, globalContextMenu = highed.ContextMenu([ { title: "Insert Row Above", icon: 'plus', click: function() { events.emit('ColumnMoving'); addRowBefore(selectedFirstCell[1]); highed.emit('UIAction', 'AddRowBeforeHighlight'); events.emit('ColumnMoved'); } }, { title: "Insert Row Below", icon: 'plus', click: function() { events.emit('ColumnMoving'); addRowAfter(selectedEndCell[1]); highed.emit('UIAction', 'AddRowAfterHighlight'); events.emit('ColumnMoved'); } }, '-', { title: 'Remove Row', icon: 'trash', click: function() { highed.emit('UIAction', 'BtnDeleteRow'); if (!confirm(highed.L('dgDeleteRow'))) { return; } highed.emit('UIAction', 'DeleteRowConfirm'); rows.forEach(function(row, index) { //if (row.isChecked()) { if(row.number === selectedFirstCell[1]) { row.destroy(); emitChanged(); } //} }); rebuildRows(); } }, { title: highed.L('dgDelCol'), icon: 'trash', click: function() { if (confirm(highed.L('dgDelColConfirm'))) { events.emit('ColumnMoving'); delCol(selectedFirstCell[0]); updateColumns(); events.emit('ColumnMoved'); } } }, '-', { title: highed.L('dgInsColBefore'), icon: 'plus', click: function() { events.emit('ColumnMoving'); insertCol(selectedFirstCell[0]); events.emit('ColumnMoved'); } }, { title: highed.L('dgInsColAfter'), icon: 'plus', click: function() { events.emit('ColumnMoving'); insertCol(selectedFirstCell[0] + 1); events.emit('ColumnMoved'); } } ]); const DEFAULT_COLUMN = 9, DEFAULT_ROW = 20; highed.dom.ap(hideCellsDiv, switchRowColumns) highed.dom.on(mainInput, 'click', function(e) { return highed.dom.nodefault(e); }); highed.dom.style(liveDataIntervalInput, { padding: '8px' }); var mouseDown = false; document.body.onmousedown = function() { mouseDown = true; } document.body.onmouseup = function() { mouseDown = false; } document.addEventListener('keydown', function (e) { if(e.keyCode === 8 || e.keyCode === 46){ allSelectedCells.forEach(function(cell){ cell.deleteContents(); }); } }, false); document.addEventListener('contextmenu', function(e) { if (e.path && e.path.indexOf(container) > -1) { globalContextMenu.show(e.clientX, e.clientY, true); return highed.dom.nodefault(e); } }, false); highed.dom.on(document.querySelector('body'), 'click', function(){ globalContextMenu.hide(); }); highed.dom.on(cornerPiece, 'mousedown', function(e){ inCopyOverCellMode = true; deselectAllCells(); }); highed.dom.ap(frame, cornerPiece); //////////////////////////////////////////////////////////////////////////// // Handle drag 'n drop of files function handleFileUpload(f, cb) { if (f.type !== 'text/csv') { return highed.snackBar('The file is not a valid CSV file'); } var reader = new FileReader(); reader.onload = function(e) { clear(); //events.emit('ClearSeriesForImport'); loadCSV({ csv: e.target.result }, null, true, cb); }; reader.readAsText(f); } frame.ondrop = function(e) { e.preventDefault(); var d = e.dataTransfer; var f; var i; if (d.items) { for (i = 0; i < d.items.length; i++) { f = d.items[i]; if (f.kind === 'file') { handleFileUpload(f.getAsFile()); } } } else { for (i = 0; i < d.files.length; i++) { f = d.files[i]; handleFileUpload(f); } } }; frame.ondragover = function(e) { e.preventDefault(); }; //////////////////////////////////////////////////////////////////////////// function showDataImportError() { highed.dom.style(weirdDataContainer, { display: 'block' }); } function hideDataImportError() { highed.dom.style(weirdDataContainer, { display: 'none' }); } function emitChanged(noDelay) { window.clearTimeout(changeTimeout); if (isInGSheetMode) { return; } if (isInLiveDataMode) { return; } if (surpressChangeEvents) { return; } if (noDelay) { return events.emit('Change', getHeaderTextArr(), toData()); } //We use an interval to stop a crazy amount of changes to be //emitted in succession when e.g. loading sets. changeTimeout = window.setTimeout(function() { if (!isInGSheetMode && !isInLiveDataMode) { events.emit('Change', getHeaderTextArr()); } }, 1000); } function makeEditable(target, value, fn, keyup, close, dontFocus) { if (mainInputCb.length) { mainInputCb = mainInputCb.filter(function(fn) { fn(); return false; }); } if (mainInputCloseCb) { mainInputCloseCb(); } mainInputCloseCb = close; mainInput.value = value; //mainInput.setSelectionRange(0, mainInput.value.length); mainInputCb.push( highed.dom.on(mainInput, 'keydown', function(e) { //(highed.isFn(fn) && fn(mainInput.value)); if (highed.isFn(keyup)) { return keyup(e); } }) ); mainInputCb.push( highed.dom.on(mainInput, 'keyup', function(e) { // Super hack to allow pasting CSV into cells var ps = highed.parseCSV(mainInput.value); if (ps.length > 1) { //TODO: Need to fix this... if ( confirm( 'You are about to load CSV data. This will overwrite your current data. Continue?' ) ) { rawCSV = mainInput.value; highed.emit('UIAction', 'PasteCSVAttempt'); loadCSV({ csv: rawCSV }, null, true, function() { }); /* return loadRows(ps, function() { if (rows.length > 0) rows[0].columns[0].focus(); events.emit('InitLoaded'); events.emit('AssignDataForFileUpload', rows[0].length); });*/ } return; } return highed.isFn(fn) && fn(mainInput.value); }) ); highed.dom.ap(target, mainInput); if (!dontFocus) mainInput.focus(); } //////////////////////////////////////////////////////////////////////////// function highlightLeft(colNumber) { columnsToHighlight.forEach(function(highlightedColumn) { highlightedColumn.element.classList.remove('highlight-right'); }); rows.forEach(function(row) { if (row.columns[colNumber].element.className.indexOf('highlight-right') === -1) { row.columns[colNumber].element.className += ' highlight-right'; columnsToHighlight.push(row.columns[colNumber]); } }); if (gcolumns[colNumber].header.className.indexOf('highlight-right') === -1) { gcolumns[colNumber].header.className += ' highlight-right'; columnsToHighlight.push({ element: gcolumns[colNumber].header }); } if (gcolumns[colNumber].letter.className.indexOf('highlight-right') === -1) { gcolumns[colNumber].letter.className += ' highlight-right'; columnsToHighlight.push({ element: gcolumns[colNumber].letter }); moveToColumn = colNumber; } } //////////////////////////////////////////////////////////////////////////// function Column(row, colNumber, val, keyVal) { var value = typeof val === 'undefined' || typeof val === 'object' || (val === 'null') ? null : val, //object check for ie11/edge col = highed.dom.cr('td', 'highed-dtable-cell'), colVal = highed.dom.cr('div', 'highed-dtable-col-val', value), input = highed.dom.cr('input'), exports = {}; function goLeft() { if (colNumber >= 1) { row.columns[colNumber - 1].focus(); } else { //Go up to the last column if (row.number - 1 >= 0) { rows[row.number - 1].columns[ rows[row.number - 1].columns.length - 1 ].focus(); } } } function goRight() { if (colNumber < row.columns.length - 1) { row.columns[colNumber + 1].focus(); } else { //Go down on the first column if (row.number < rows.length - 1) { rows[row.number + 1].columns[0].focus(); } } } function goUp() { if (row.number > 0 && rows[row.number - 1].columns.length > colNumber) { rows[row.number - 1].columns[colNumber].focus(); } } function goBelow() { if ( row.number < rows.length - 1 && rows[row.number + 1].columns.length > colNumber ) { rows[row.number + 1].columns[colNumber].focus(); } } function handleKeyup(e) { //Go the the column to the left if (e.keyCode === 37) { goLeft(); return highed.dom.nodefault(e); //Go to the column above } else if (e.keyCode === 38) { goUp(); return highed.dom.nodefault(e); //Go to the column to the right } else if (e.keyCode === 39 || e.keyCode === 9) { goRight(); return highed.dom.nodefault(e); //Go to the column below } else if (e.keyCode === 40) { goBelow(); return highed.dom.nodefault(e); //Go to next row } else if (e.keyCode === 13) { //If we're standing in the last column of the last row, //insert a new row. if (row.number === rows.length - 1) { // && colNumber === rows.columns.length - 1) { events.emit('ColumnMoving'); addRow(); rows[row.number + 1].columns[0].focus(); events.emit('ColumnMoved'); } else { goBelow(); } return highed.dom.nodefault(e); } } function selContents() { input.setSelectionRange(0, input.value.length); } function deleteContents() { colVal.innerHTML = ''; mainInput.value = ''; value = null; emitChanged(); } function setValue(newValue) { colVal.innerHTML = newValue; mainInput.value = newValue; value = newValue; emitChanged(); } function focus(dontFocus) { deselectAllCells(); function checkNull(value) { return value === null || value === ''; } mainInput.className = 'highed-dtable-input'; mainInput.draggable = false; highed.dom.on(mainInput, 'dragstart', function(e){ highed.dom.nodefault(e); return false; }); highed.dom.on(mainInput, 'ondrop', function(e){ highed.dom.nodefault(e); return false; }); makeEditable( col, value, function(val) { var changed = value !== val; value = checkNull(val) ? null : val; colVal.innerHTML = value; if (changed) { emitChanged(); } }, handleKeyup, dontFocus ); highed.dom.style(cornerPiece, { top: ((highed.dom.pos(col).y + highed.dom.size(col).h - 3)) + "px", left: ((highed.dom.pos(col).x + highed.dom.size(col).w - 3)) + "px", display: "block" }); row.select(); } function deselectCell() { col.classList.remove('cell-selected'); } function deselectCopyCell() { col.classList.remove('cell-copy-selected'); } function selectCell() { if(col.className.indexOf('cell-selected') === -1) { col.className += ' cell-selected'; if (allSelectedCells.indexOf(exports) === -1) allSelectedCells.push(exports); } } function select() { selectedEndCell[0] = colNumber; selectedEndCell[1] = row.number; selectNewCells(selectedFirstCell, selectedEndCell); } function selectCellToCopy() { if(col.className.indexOf('cell-copy-selected') === -1) { col.className += ' cell-copy-selected'; if (allSelectedCopyCells.indexOf(exports) === -1) allSelectedCopyCells.push(exports); } } function destroy() { row.node.removeChild(col); col.innerHTML = ''; colVal.innerHTML = ''; } function getVal() { return value; } function addToDOM(me) { colNumber = me || colNumber; highed.dom.ap(row.node, highed.dom.ap(col, colVal)); } highed.dom.on(col, 'mouseup', function(e) { if (inCopyOverCellMode) { inCopyOverCellMode = false; const newValue = rows[selectedCopyFirstCell[1]].columns[selectedCopyFirstCell[0]].value(); allSelectedCopyCells.forEach(function(cell) { cell.setValue(newValue); cell.deselectCopyCell(); }); allSelectedCopyCells = []; } else if (selectedFirstCell[0] === selectedEndCell[0] && selectedFirstCell[1] === selectedEndCell[1]) { //Have not dragged anywhere else on the grid. So the user has just clicked on a cell. lastSelectedCell[0] = colNumber; lastSelectedCell[1] = row.number; selectedCopyFirstCell[0] = selectedFirstCell[0]; selectedCopyFirstCell[1] = selectedFirstCell[1]; selectedCopyEndCell[1] = selectedEndCell[1]; selectedCopyEndCell[0] = selectedEndCell[0]; selectedHeaders = []; focus(); globalContextMenu.hide(); } }); highed.dom.on([col, colVal], 'mouseover', function(e) { if(mouseDown) { if (inCopyOverCellMode) { if (colNumber === selectedCopyEndCell[0]) { selectedCopyEndCell[1] = row.number; selectedCopyEndCell[0] = selectedCopyFirstCell[0]; } else if (selectedCopyEndCell[1] === row.number) { selectedCopyEndCell[1] = selectedCopyFirstCell[1]; selectedCopyEndCell[0] = colNumber; } selectCellsToMove(selectedCopyFirstCell, selectedCopyEndCell); } else if (dragHeaderMode) { highlightLeft(colNumber); } else { select(); } } }); highed.dom.on(col, 'mousedown', function() { if (lastSelectedCell[0] !== colNumber && lastSelectedCell[1] !== row.number) { focus(); } selectedFirstCell[0] = colNumber;//keyVal; selectedEndCell[0] = colNumber;//keyVal; selectedFirstCell[1] = row.number; selectedEndCell[1] = row.number; selectedCopyFirstCell[0] = selectedFirstCell[0]; selectedCopyFirstCell[1] = selectedFirstCell[1]; selectedCopyEndCell[1] = selectedEndCell[1]; selectedCopyEndCell[0] = selectedEndCell[0]; }); if (rows.length <= 500) { addToDOM(); } exports = { focus: focus, value: getVal, destroy: destroy, addToDOM: addToDOM, selectCell: selectCell, deleteContents: deleteContents, deselectCell: deselectCell, deselectCopyCell: deselectCopyCell, element: col, setValue: setValue, rowNumber: row.number, colNumber: colNumber, selectCellToCopy: selectCellToCopy, updateColNumber: function(i){ colNumber = i; exports.colNumber = i; } }; return exports; } function deselectAllCells() { allSelectedCells.forEach(function(cells) { cells.deselectCell(); }); allSelectedCells = []; selectedEndCell[0] = null; selectedEndCell[1] = null; selectedFirstCell[0] = null; selectedFirstCell[1] = null; } function selectCellsToMove(firstCell, endCell){ // selectedCopyFirstCell, selectedCopyEndCell allSelectedCopyCells = allSelectedCopyCells.filter(function(cell) { if ((cell.rowNumber > endCell[1] || cell.colNumber > endCell[0]) || (cell.rowNumber < firstCell[1] || cell.colNumber < firstCell[0])) { cell.deselectCopyCell(); return false; } return cell; }); var tempColValue, lowCell, highCell, cell; if (firstCell[0] <= endCell[0]) { tempColValue = firstCell[0]; cell = endCell; } else if (firstCell[0] > endCell[0]) { tempColValue = endCell[0]; cell = firstCell; } lowCell = (firstCell[1] > endCell[1] ? endCell : firstCell); highCell = (firstCell[1] < endCell[1] ? endCell : firstCell); while(tempColValue <= cell[0]) { for(var i = lowCell[1];i<= highCell[1]; i++) { if (rows[i]) rows[i].columns[tempColValue].selectCellToCopy(); } tempColValue++; } } function selectNewCells(firstCell, endCell) { //firstCell, endCell if (firstCell.length === 0 || endCell.length === 0 || // Weird bug when opening the console and hovering over cells (firstCell[0] === null || firstCell[1] === null) ) return; allSelectedCells = allSelectedCells.filter(function(cell) { if ((cell.rowNumber > endCell[1] || cell.colNumber > endCell[0]) || (cell.rowNumber < firstCell[1] || cell.colNumber < firstCell[0])) { cell.deselectCell(); return false; } return cell; }); var tempColValue, lowCell, highCell, cell; if (firstCell[0] <= endCell[0]) { tempColValue = firstCell[0]; cell = endCell; } else if (firstCell[0] > endCell[0]) { tempColValue = endCell[0]; cell = firstCell; } lowCell = (firstCell[1] > endCell[1] ? endCell : firstCell); highCell = (firstCell[1] < endCell[1] ? endCell : firstCell); while(tempColValue <= cell[0]) { for(var i = lowCell[1];i<= highCell[1]; i++) { if (rows[i]) rows[i].columns[tempColValue].selectCell(); } tempColValue++; } } //////////////////////////////////////////////////////////////////////////// function Row(skipAdd) { var columns = [], row = highed.dom.cr('tr'), leftItem = highed.dom.cr('div', 'highed-dtable-left-bar-row', ''), checker = highed.dom.cr('div', 'highed-dtable-row'), checked = false, didAddHTML = false, exports = {}; highed.dom.on(leftItem, 'mouseover', function(e) { if(mouseDown) { selectedEndCell[1] = checker.value; selectNewCells(selectedFirstCell, selectedEndCell); } }); highed.dom.on(leftItem, 'mousedown', function(e) { //if (e.button === 2 && selectedFirstCell.length > 0 && selectedEndCell.length > 0 && selectedFirstCell[0] === 0 && selectedEndCell[0] === (rows[0].columns.length - 1)) { deselectAllCells(); selectedFirstCell[0] = 0 selectedEndCell[0] = rows[0].columns.length - 1; selectedFirstCell[1] = e.target.value; selectedEndCell[1] = e.target.value; selectNewCells(selectedFirstCell, selectedEndCell); }); function addCol(val, keyValue) { columns.push(Column(exports, columns.length, val, keyValue)); } function insertCol(where) { var col = Column(exports, columns.length); columns.splice(where, 0, col); } function select() { var o = tbody.querySelector('.highed-dtable-body-selected-row'); if (o) { o.className = ''; } row.className = 'highed-dtable-body-selected-row'; selectedRowIndex = exports.rowIndex; } function isChecked() { return checked; } function check(state) { checker.checked = checked = state; } function destroy() { if (didAddHTML) { leftBar.removeChild(leftItem); tbody.removeChild(row); row.innerHTML = ''; } rows = rows.filter(function(b) { return b !== exports; }); if (rows.length < 2) { showDropzone(); } } function addToDOM(number) { didAddHTML = true; exports.number = number; checker.innerHTML = number + 1; checker.value = number; leftItem.value = number; highed.dom.ap(tbody, row); highed.dom.ap(leftBar, highed.dom.ap(leftItem, checker)); } function rebuildColumns() { row.innerHTML = ''; columns.forEach(function(col, i) { col.updateColNumber(i); col.addToDOM(i); }); } function delCol(which) { if (which >= 0 && which < columns.length) { columns[which].destroy(); columns.splice(which, 1); } } highed.dom.on(checker, 'change', function() { checked = checker.checked; }); if (rows.length < 500) { addToDOM(rows.length); } else if (rows.length === 500) { highed.dom.style(tableTail, { display: 'block' }); } exports = { destroy: destroy, select: select, columns: columns, number: rows.length, addCol: addCol, isChecked: isChecked, check: check, node: row, addToDOM: addToDOM, insertCol: insertCol, rebuildColumns: rebuildColumns, delCol: delCol, rowIndex: rows.length }; if (!skipAdd) { rows.push(exports); } resize(); return exports; } //////////////////////////////////////////////////////////////////////////// function rebuildRows() { rows.forEach(function(row, i) { if (rows.length < 500) { row.addToDOM(i); } row.rowIndex = i; }); emitChanged(); } function rebuildColumns() { rows.forEach(function(row) { row.rebuildColumns(); }); } function addRowBefore(index) { if (index > 0 && index < rows.length) { rows.splice(index - 0, 0, addRow(true, true)); rebuildRows(); } } function addRowAfter(index) { if (index >= 0 && index < rows.length) { rows.splice(index + 1, 0, addRow(true, true)); rebuildRows(); } } function init() { clear(); surpressChangeEvents = true; setTimeout(function(){ events.emit('InitLoaded'); }, 10); for (var i = 0; i < DEFAULT_ROW; i++) { var r = Row(false, keyValue); } tempKeyValue = "A"; for (var j = 0; j < DEFAULT_COLUMN; j++) { addCol('Column ' + (j + 1)); } highed.dom.ap(colgroup, highed.dom.cr('col')); resize(); surpressChangeEvents = false; } function updateColumns() { colgroup.innerHTML = ''; topColumnBar.innerHTML = ''; topLetterBar.innerHTML = ''; var resetLetters = 'A'; gcolumns.forEach(function(col, i) { col.colNumber = i; col.setLetter(resetLetters); resetLetters = getNextLetter(resetLetters); col.addToDOM(); }); rebuildColumns(); highed.dom.ap(colgroup, highed.dom.cr('col')); resize(); } function getNextLetter(key) { if (key === 'Z' || key === 'z') { return String.fromCharCode(key.charCodeAt() - 25) + String.fromCharCode(key.charCodeAt() - 25); } else { var lastChar = key.slice(-1); var sub = key.slice(0, -1); if (lastChar === 'Z' || lastChar === 'z') { return getNextLetter(sub) + String.fromCharCode(lastChar.charCodeAt() - 25); } else { return sub + String.fromCharCode(lastChar.charCodeAt() + 1); } } return key; }; function addCol(value, where) { //The header columns control the colgroup var col = highed.dom.cr('col'), colNumber = gcolumns.length, header = highed.dom.cr('span', 'highed-dtable-top-bar-col'), letter = highed.dom.cr('span', 'highed-dtable-top-bar-letter'), headerTitle = highed.dom.cr('div', '', (typeof value === 'undefined' || value === 'null' ? null : value)), moveHandle = highed.dom.cr('div', 'highed-dtable-resize-handle'), options = highed.dom.cr( 'div', 'highed-dtable-top-bar-col-options fa fa-chevron-down' ), exports = { col: col, header: header, headerTitle: headerTitle, colNumber: gcolumns.length, letter: letter, test: true }, mover = highed.Movable( moveHandle, 'X', false, false, { x: 20, y: 0 }, true ), ctx = highed.ContextMenu([ { title: highed.L('dgSortAsc'), icon: 'sort-amount-asc', click: function() { sortRows(exports.colNumber, 'asc'); } }, { title: highed.L('dgSortDec'), icon: 'sort-amount-desc', click: function() { sortRows(exports.colNumber, 'desc'); } }, '-', { title: highed.L('dgSortAscMonth'), icon: 'sort-amount-asc', click: function() { sortRows(exports.colNumber, 'asc', true); } }, { title: highed.L('dgSortDecMonth'), icon: 'sort-amount-desc', click: function() { sortRows(exports.colNumber, 'desc', true); } }, '-', { title: highed.L('dgDelCol'), icon: 'trash', click: function() { if (confirm(highed.L('dgDelColConfirm'))) { delCol(exports.colNumber); } } }, // { // title: 'Clone Column', // icon: 'clone' // }, '-', { title: highed.L('dgInsColBefore'), icon: 'plus', click: function() { events.emit('ColumnMoving'); insertCol(exports.colNumber); events.emit('ColumnMoved') } }, { title: highed.L('dgInsColAfter'), icon: 'plus', click: function() { events.emit('ColumnMoving'); insertCol(exports.colNumber + 1); events.emit('ColumnMoved') } } ]), ox, keyCell = highed.dom.cr('span', 'highed-dtable-cell-value', keyValue); //letter.innerHTML = keyValue; letter.value = highed.getLetterIndex(keyValue); exports.setLetter = function (str) { keyCell.innerHTML = str; letter.value = highed.getLetterIndex(str); //exports.colNumber = highed.getLetterIndex(str); } exports.hideColumns = function() { if (!col.classList.contains('cell-hide')) { col.classList.add('cell-hide'); header.classList.add('cell-hide'); letter.classList.add('cell-hide'); } } exports.showColumns = function() { if (col.classList.contains('cell-hide')) { col.classList.remove('cell-hide'); header.classList.remove('cell-hide'); letter.classList.remove('cell-hide'); } } highed.dom.on(letter, 'mouseover', function(e) { if(mouseDown && (e.target !== options && e.target !== moveHandle)) { if (dragHeaderMode) { if (movementBar.className.indexOf('active') === -1) { movementBar.className += ' active'; highed.dom.style(movementBar, { width: 140 * ((selectedHeaders[0] < selectedHeaders[1] ? selectedHeaders[1] - selectedHeaders[0] : selectedHeaders[0] - selectedHeaders[1]) +1) + 'px' //width: 140 * selectedHeaders.length + 'px' }); } highlightLeft(letter.value); highed.dom.style(movementBar, { left: (e.clientX - highed.dom.size(movementBar).w / 2) + 'px' }); } else { selectedEndCell[0] = letter.value; selectedHeaders[1] = letter.value; selectNewCells(selectedFirstCell, selectedEndCell); } } }); highed.dom.on(letter, 'mousedown', function(e) { deselectAllCells(); if (selectedHeaders.length > 0 && ( e.target.value >= selectedHeaders[0] && e.target.value <= selectedHeaders[1])) { //User is trying to drag headers left and right. dragHeaderMode = true; } else { //deselectAllCells(); if(e.target !== options && e.target !== moveHandle) { selectedHeaders = []; selectedHeaders[0] = e.target.value; selectedHeaders[1] = e.target.value; selectedFirstCell[0] = e.target.value; selectedEndCell[0] = e.target.value; selectedFirstCell[1] = 0; selectedEndCell[1] = rows.length - 1; selectNewCells(selectedFirstCell, selectedEndCell); } } }); highed.dom.on(container, 'mouseover', function(e) { if (dragHeaderMode) { highed.dom.style(movementBar, { left: (e.clientX - highed.dom.size(movementBar).w / 2) + 'px' }); } }); function shuffleArray(arr, min, amount, moveTo) { var x = arr.splice(min, amount); var args = [moveTo, 0].concat(x); Array.prototype.splice.apply(arr, args); } function moveCells() { if (moveToColumn !== null) { events.emit('ColumnMoving'); const min = selectedHeaders[0/*(moveToColumn < selectedHeaders[0] ? 1 : 0)*/], max = (selectedHeaders[0] < selectedHeaders[1] ? selectedHeaders[1] - selectedHeaders[0] : selectedHeaders[0] - selectedHeaders[1]) +1, total = (selectedHeaders[0] < selectedHeaders[1] ? selectedHeaders[1] - selectedHeaders[0] : selectedHeaders[0] - selectedHeaders[1]); shuffleArray(gcolumns, min, max, (moveToColumn < selectedHeaders[0] ? moveToColumn + 1 : moveToColumn - total)); rows.forEach(function(row) { shuffleArray(row.columns, min, max, (moveToColumn < selectedHeaders[0] ? moveToColumn + 1 : moveToColumn - total)); }); if (rows.length > 0) rows[0].columns[0].focus(); updateColumns(); emitChanged(); events.emit('ColumnMoved'); } } highed.dom.on(container, 'mouseup', function(e) { if (dragHeaderMode) { moveCells(); selectedHeaders = []; dragHeaderMode = false; movementBar.classList.remove('active'); columnsToHighlight.forEach(function(highlightedColumn) { highlightedColumn.element.classList.remove('highlight-right'); }); columnsToHighlight = []; moveToColumn = null; } globalContextMenu.hide(); }) highed.dom.on(header, 'mouseover', function(e) { if(mouseDown) { if (dragHeaderMode) { highlightLeft(exports.colNumber); } } }); keyValue = getNextLetter(keyValue); //////////////////////////////////////////////////////////////////////// exports.addToDOM = function() { highed.dom.ap(colgroup, col); highed.dom.ap( topLetterBar, highed.dom.ap(letter, keyCell, options, moveHandle) ); highed.dom.ap( topColumnBar, highed.dom.ap(header, headerTitle) ); }; exports.destroy = function() { colgroup.removeChild(col); topColumnBar.removeChild(header); topLetterBar.removeChild(letter); gcolumns = gcolumns.filter(function(b) { return b !== exports; }); }; //////////////////////////////////////////////////////////////////////// exports.addToDOM(); // highed.dom.showOnHover(header, options); col.width = 140; highed.dom.style([col, header, letter], { width: col.width + 'px', 'max-width': col.width + 'px' }); mover.on('StartMove', function(x) { ox = x; if (!header.classList.contains('no-transition')) { header.classList += ' no-transition'; letter.classList += ' no-transition'; col.classList += ' no-transition'; } if (rows.length > 0) rows[0].columns[0].focus(); highed.dom.style(cornerPiece, { display: 'none' }) highed.dom.style(document.body, { cursor: 'ew-resize' }); }); mover.on('Moving', function(x) { col.width = x; highed.dom.style(cornerPiece, { display: 'none' }) highed.dom.style([col, header, letter], { width: x + 'px', 'max-width': x + 'px' }); moveHandle.className = 'highed-dtable-resize-handle highed-dtable-resize-handle-moving'; }); mover.on('EndMove', function(x) { highed.dom.style(document.body, { cursor: '' }); if (header.classList.contains('no-transition')) { header.classList.remove('no-transition'); letter.classList.remove('no-transition'); col.classList.remove('no-transition'); } moveHandle.className = 'highed-dtable-resize-handle'; if (rows.length > 0) rows[0].columns[0].focus(); }); highed.dom.on(options, 'click', function(e) { ctx.show(e.clientX, e.clientY); return highed.dom.nodefault(e); }); highed.dom.on(header, 'click', function(e) { //Ugly. mainInput.className = 'highed-dtable-input highed-dtable-input-header'; //Spawn an edit box in the node highed.dom.style(cornerPiece, { display: "none" }); deselectAllCells(); makeEditable( header, value, function(val) { headerTitle.innerHTML = value = val; emitChanged(); }, function(e) { if (e.keyCode === 13) { mainInput.className = 'highed-dtable-input'; header.removeChild(mainInput); } } ); }); rows.forEach(function(row) { if (where) { row.insertCol(where); } else { row.addCol(null, tempKeyValue); } tempKeyValue = getNextLetter(tempKeyValue); }); if (!isNaN(where)) { gcolumns.splice(where, 0, exports); } else { gcolumns.push(exports); } emitChanged(); } function showDropzone() { highed.dom.style(dropZone, { opacity: 1 }); } function hideDropzone() { highed.dom.style(dropZone, { opacity: 0 }); } //////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS FOLLOW /** Sort rows * @memberof highed.DataTable * @param column {number} - the column to sort on * @param direction {string} - the direction: `asc` or `desc` * @param asMonths {boolean} - if true, sort by month */ function sortRows(column, direction, asMonths) { tbody.innerHTML = ''; direction = (direction || '').toUpperCase(); rows.sort(function(a, b) { var ad = a.columns[column].value(), bd = b.columns[column].value(); if ((highed.isNum(ad) && highed.isNum(bd)) || asMonths) { if (asMonths) { ad = monthNumbers[ad.toUpperCase().substr(0, 3)] || 13; bd = monthNumbers[bd.toUpperCase().substr(0, 3)] || 13; } else { ad = parseFloat(ad); bd = parseFloat(bd); } if (direction === 'ASC') { return ad - bd; } return bd < ad ? -1 : bd > ad ? 1 : 0; } if (direction === 'ASC') { if (!ad) return bd; return ad.localeCompare(bd); } if (bd) { if (!ad) return bd; return bd.localeCompare(ad); } else { if (ad) return ad.localeCompare(bd); } }); rebuildRows(); if (rows.length > 0) rows[0].columns[column].focus(); emitChanged(); } /** Clear the table * @memberof highed.DataTable */ function clear(noWait) { rows = rows.filter(function(row) { row.destroy(); return false; }); gcolumns = gcolumns.filter(function(row) { //Destroy col here return false; }); tbody.innerHTML = ''; leftBar.innerHTML = ''; topColumnBar.innerHTML = ''; topLetterBar.innerHTML = ''; colgroup.innerHTML = ''; keyValue = "A"; highed.dom.style(tableTail, { display: '' }); events.emit('ClearData', true); emitChanged(noWait); showDropzone(); } /** Add a new row * @memberof highed.DataTable */ function addRow(supressChange, skipAdd) { var r = Row(skipAdd); gcolumns.forEach(function() { r.addCol(); }); if (!supressChange) { emitChanged(); } if (rows.length > 1) { hideDropzone(); } return r; } /** Insert a new column * @memberof highed.DataTable * @param {number} where - is the position where to add it */ function insertCol(where) { if (where === null) where = gcolumns.length; if (where <= 0) where = 0; if (where >= gcolumns.length) where = gcolumns.length; //Insert into gcolumns and on each row, then call updateColumns() addCol(highed.L('dgNewCol'), where); updateColumns(); } /** Delete a column * @memberof highed.DataTable * @param {number} which - the index of the column to delete */ function delCol(which) { if (which >= 0 && which < gcolumns.length) { rows.forEach(function(row) { row.delCol(which); }); gcolumns[which].destroy(); updateColumns(); emitChanged(); } } /** Resize the table based on the container size * @memberof highed.DataTable */ function resize() { var ps = highed.dom.size(parent), hs = highed.dom.size(topBar); //tb = highed.dom.size(toolbar.container); highed.dom.style(frame, { height: ps.h - hs.h - 55 - 17 + 'px' //55 is padding from top for data column and letter }); highed.dom.style([container, gsheetFrame, liveDataFrame], { height: ps.h - hs.h - 22 /*- tb.h*/ + 'px' }); highed.dom.style(table, { width: ps.w + 'px' }); } /** Returns the header titles as an array * @memberof highed.DataTable * @returns {array} - the headers */ function getHeaderTextArr(quoteStrings, section) { var columnNames = []; function cleanData(data) { var title = data && data.headerTitle.innerHTML.length ? data.headerTitle.innerHTML : null; if (quoteStrings) { title = '"' + title + '"'; } columnNames.push(title); } if (section) { //Add in label data first //cleanData(gcolumns[section.labelColumn]); } gcolumns.reduce(function(result, item, index) { if ( section && !checkSections(section, index)) { return; } cleanData(item); }, []); return columnNames; } function checkSections(sections, index) { return (sections || []).some(function(section) { return (section.dataColumns.indexOf(index) > -1 || section.extraColumns.indexOf(index) > -1 || section.labelColumn === index); }); } /** Get the table contents as an array of arrays * @memberof highed.DataTable * @param {boolean} quoteStrings - if true, strings are wrapped in double quotes * @param {boolean} includeHeaders - if true, the header texts will be included as the first row * @returns {array>} */ function toData(quoteStrings, includeHeaders, section) { var data = []; if (includeHeaders) { data.push(getHeaderTextArr(quoteStrings, section)); } dataFieldsUsed = []; function addData(column, arr) { if (quoteStrings && !highed.isNum(column) && highed.isStr(column)) { column = '"' + column.replace(/\"/g, '"') + '"'; } if (highed.isNum(column)) { column = parseFloat(column); } if (highed.isStr(column) && Date.parse(column) !== NaN) { //v = (new Date(v)).getTime(); } arr.push(column); } rows.forEach(function(row) { var rarr = [], hasData = false; if (section) { //Add in label data first //addData(row.columns[section[0].labelColumn].value(), rarr); } row.columns.forEach(function(col, index) { if (section && !checkSections(section, index)) return; var v = col.value(); if (v) { hasData = true; } if (dataFieldsUsed.indexOf(index) === -1) { dataFieldsUsed.push(index); if (!v) { hasData = true; v = undefined; } } addData(v, rarr); }); if (hasData) { data.push(rarr); } }); return data; } /** Get the table contents as series * @memberof highed.DataTable */ function toDataSeries(ignoreFirst) { var res = { categories: [], series: [] }; gcolumns.forEach(function(item, i) { if (i > 0) { res.series.push({ name: item.headerTitle.innerHTML.length ? item.headerTitle.innerHTML : null, data: [] }); } }); rows.forEach(function(row, i) { row.columns.forEach(function(col, ci) { var v = col.value(); if (!ci) { if (v && highed.isStr(v) && Date.parse(v) !== NaN) { // v = new Date(v); } res.categories.push(v); return; } ci--; if (v && highed.isNum(v)) { v = parseFloat(v); } if (v && highed.isStr(v) && Date.parse(v) !== NaN) { // v = (new Date(v)).getTime(); } res.series[ci].data.push(v); }); }); return res; } /** Get the table contents as standard CSV * @memberof highed.DataTable * @param delimiter {string} - the delimiter to use. Defaults to `,`. * @param section {array} - the section of the data table which is the data. */ function toCSV(delimiter, quoteStrings, section) { delimiter = delimiter || ','; return toData(quoteStrings, true, section) .map(function(cols) { return cols.join(delimiter); }) .join('\n'); } function loadRows(rows, done) { var sanityCounts = {}; clear(); if (rows.length > 1) { hideDropzone(); } // Do a sanity check on rows. // If the column count varries between rows, there may be something wrong. // In those cases we should pop up a dialog allow to specify what the // delimiter should be manually. rows.some(function(row, i) { var count = row.length; sanityCounts[count] = typeof sanityCounts[count] === 'undefined' ? 0 : sanityCounts[count]; ++sanityCounts[count]; return i > 20; }); if (Object.keys(sanityCounts).length > 4) { // Four or more rows have varrying amounts of columns. // Something is wrong. showDataImportError(); } highed.dom.style(loadIndicator, { opacity: 1 }); highed.dom.style(hideCellsDiv, { opacity: 0 }); setTimeout(function() { if(rows[0] && rows.length < DEFAULT_ROW) { var counter = DEFAULT_ROW - rows.length, length = (rows[0].length > DEFAULT_COLUMN ? rows[0].length : DEFAULT_COLUMN); rows.forEach(function(row) { if (row.length < DEFAULT_COLUMN) { const len = DEFAULT_COLUMN - row.length; for(var i=0;i DEFAULT_COLUMN ? rows[0].length : DEFAULT_COLUMN); rows.forEach(function(row) { if (row.length < DEFAULT_COLUMN) { const len = DEFAULT_COLUMN - row.length; for(var i=0;i DEFAULT_COLUMN) events.emit('AssignDataForFileUpload', rows[0].length); if (cb) cb(); }); } else { // surpressChangeEvents = false; // if (!surpressEvents) { // emitChanged(true); // } } surpressChangeEvents = false; if (!surpressEvents) { emitChanged(true); } } function initGSheet( id, worksheet, startRow, endRow, startColumn, endColumn, skipLoad, dataRefreshRate ) { gsheetID.value = id; gsheetWorksheetID.value = worksheet || ''; gsheetRefreshTime.value = dataRefreshRate || ''; gsheetStartRow.value = startRow || 0; gsheetEndRow.value = (endRow === Number.MAX_VALUE ? '' : endRow) || ''; gsheetStartCol.value = startColumn || 0; gsheetEndCol.value = (endColumn === Number.MAX_VALUE ? '' : endColumn) || ''; isInGSheetMode = true; isInLiveDataMode = false; highed.dom.style(gsheetFrame, { display: 'block' }); highed.dom.style(container, { display: 'none' }); highed.dom.style(liveDataFrame, { display: 'none' }); if (!skipLoad) { events.emit('LoadGSheet', { googleSpreadsheetKey: gsheetID.value, googleSpreadsheetWorksheet: gsheetWorksheetID.value || false, dataRefreshRate: gsheetRefreshTime.value || false, enablePolling: (parseInt(gsheetRefreshTime.value) !== 0), startRow: gsheetStartRow.value || 0, endRow: gsheetEndRow.value || undefined, startColumn: gsheetStartCol.value || 0, endColumn: gsheetEndCol.value || undefined }); } } function showDataTableError() { highed.dom.style(container, { border: '1px solid #aa5555' }); } function hideDataTableError() { highed.dom.style(container, { border: 'initial' }); } function addImportTab(tabOptions){ importer.addImportTab(tabOptions); } function hideImportModal(){ importModal.hide(); } function showImportModal(index) { importModal.show(); if (!isNaN(index)) { importer.selectTab(index); } events.emit('initExporter', importer.exporter); importer.resize(); } function showLiveData(skipConfirm) { if ( skipConfirm || rows.length <= 1 || confirm('This will clear your existing data. Continue?') ) { clear(true); events.emit('ClearSeries'); liveDataInput.value = ''; liveDataIntervalInput.value = ''; liveDataTypeSelect.selectByIndex(0); highed.dom.style(gsheetFrame, { display: 'none' }); highed.dom.style(container, { display: 'none' }); highed.dom.style(liveDataFrame, { display: 'block' }); importModal.hide(); isInGSheetMode = false; isInLiveDataMode = true; } } function showGSheet(skipConfirm) { if ( skipConfirm || rows.length <= 1 || confirm('This will clear your existing data. Continue?') ) { clear(true); events.emit('ClearSeries'); gsheetID.value = ''; gsheetWorksheetID.value = ''; gsheetRefreshTime.value = ''; highed.dom.style(gsheetFrame, { display: 'block' }); highed.dom.style(container, { display: 'none' }); highed.dom.style(liveDataFrame, { display: 'none' }); importModal.hide(); isInGSheetMode = true; isInLiveDataMode = false; } } function hideLiveData() { if ( !liveDataInput.value || confirm('Are you sure you want to remove your live data?') ) { // Should emit a gsheet clear events.emit('LoadLiveData', { url: '' }); highed.dom.style(gsheetFrame, { display: 'none' }); highed.dom.style(container, { display: 'block' }); highed.dom.style(liveDataFrame, { display: 'none' }); isInLiveDataMode = false; init(); } } function hideGSheet() { if ( !gsheetID.value || confirm('Are you sure you want to detach the current spreadsheet?') ) { // Should emit a gsheet clear events.emit('LoadGSheet', { googleSpreadsheetKey: '', googleSpreadsheetWorksheet: false }); highed.dom.style(gsheetFrame, { display: 'none' }); highed.dom.style(container, { display: 'block' }); highed.dom.style(liveDataFrame, { display: 'none' }); isInGSheetMode = false; init(); highed.emit('UIAction', 'DetachGoogleSheet'); } } //////////////////////////////////////////////////////////////////////////// importer.on('ExportComma', function(data) { highed.emit('UIAction', 'ExportComma'); highed.download('data.csv', toCSV(','), 'application/csv'); events.emit('EnableAssignDataPanel'); importModal.hide(); }); importer.on('ExportSemiColon', function(data) { highed.emit('UIAction', 'ExportSemiColon'); highed.download('data.csv', toCSV(';'), 'application/csv'); events.emit('EnableAssignDataPanel'); importModal.hide(); }); importer.on('ImportCSV', function(data, cb) { highed.emit('UIAction', 'ImportCSV'); events.emit('EnableAssignDataPanel'); loadCSV(data, null, true, cb); }); importer.on('ImportGoogleSpreadsheet', function() { highed.emit('UIAction', 'BtnGoogleSheet'); events.emit('DisableAssignDataPanel'); showGSheet(); }); importer.on('ImportLiveData', function(data) { isInLiveDataMode = true; events.emit('DisableAssignDataPanel'); showLiveData(); //loadLiveDataFromURL(data.url); }); importer.on('ImportChartSettings', function(settings, format) { // Do something with the data here events.emit('ImportChartSettings', settings, format); importModal.hide(); }); highed.dom.on(switchRowColumns, 'click', function() { selectSwitchRowsColumns() }) highed.dom.on(gsheetCancelButton, 'click', function() { hideGSheet(); events.emit('CancelDataInput'); events.emit('EnableAssignDataPanel'); }); highed.dom.on(liveDataCancelButton, 'click', function() { hideLiveData(); events.emit('CancelDataInput'); events.emit('EnableAssignDataPanel'); }); highed.dom.on(liveDataLoadButton, 'click', function() { loadLiveDataFromURL(liveDataInput.value, liveDataIntervalInput.value, detailValue || 'columnsURL'); }); highed.dom.on(gsheetLoadButton, 'click', function() { var value = parseInt(gsheetRefreshTime.value); events.emit('LoadGSheet', { googleSpreadsheetKey: gsheetID.value, googleSpreadsheetWorksheet: gsheetWorksheetID.value || false, dataRefreshRate: (!isNaN(value) && value !== 0 ? value : false), enablePolling: (!isNaN(value) && value !== 0), startRow: gsheetStartRow.value || 0, endRow: gsheetEndRow.value || Number.MAX_VALUE, startColumn: gsheetStartCol.value || 0, endColumn: gsheetEndCol.value || Number.MAX_VALUE }); }); highed.dom.on(weirdDataIgnore, 'click', hideDataImportError); highed.dom.on(weirdDataFix, 'click', function() { // Pop open a modal with the option of supplying a delimiter manually. var dropdownParent = highed.dom.cr('div'), dropdown = highed.DropDown(dropdownParent), okBtn = highed.dom.cr('button', 'highed-ok-button', 'Rerun Import'), nevermindBtn = highed.dom.cr('button', 'highed-ok-button', 'Nevermind'), selectedDelimiter = undefined; weirdDataModal.body.innerHTML = ''; weirdDataModal.show(); dropdown.addItems([ { title: 'Tab', id: 'tab', select: function() { selectedDelimiter = '\t'; } }, { title: 'Comma', id: 'comma', select: function() { selectedDelimiter = ','; } }, { title: 'Semicolon', id: 'semicolon', select: function() { selectedDelimiter = ';'; } } ]); dropdown.selectByIndex(0); highed.dom.ap( weirdDataModal.body, highed.dom.cr('h3', '', 'Data Import Fixer'), highed.dom.cr( 'div', 'highed-dtable-weird-data-body', [ 'We could not properly determine how your columns are separated.', '

', 'Usually this is caused by commas as thousand separators,', 'or something similar. Please choose which delimiter you want to use,', 'and click the Rerun button.

' ].join(' ') ), dropdownParent, highed.dom.style(okBtn, { marginRight: '5px' }), nevermindBtn ); highed.dom.on(nevermindBtn, 'click', weirdDataModal.hide); highed.dom.on(okBtn, 'click', function() { weirdDataModal.hide(); hideDataImportError(); loadCSV({ csv: rawCSV, delimiter: selectedDelimiter }, null, true); }); }); //////////////////////////////////////////////////////////////////////////// dropZone.innerHTML = 'Drop CSV files here.
' + 'You can also paste CSV or Excel data into any cell'; table.cellPadding = 0; table.cellSpacing = 0; highed.dom.on(frame, 'scroll', function(e) { leftBar.style.top = -frame.scrollTop + 'px'; topBar.style.left = -frame.scrollLeft + 40 + 'px'; }); parent = highed.dom.get(parent); highed.dom.ap( parent, gsheetFrame, liveDataFrame, highed.dom.ap( container, highed.dom.ap( frame, highed.dom.ap(table, colgroup, thead, tbody), tableTail, dropZone, movementBar ), hideCellsDiv, leftBar, highed.dom.ap(topBar, topLetterBar, topColumnBar) //highed.dom.ap(topLeftPanel, checkAll) ), highed.dom.ap( weirdDataContainer, highed.dom.cr( 'div', 'highed-dtable-weird-data-body', [ 'Uh-oh! It looks like our data importer may have had some issues', 'processing your data.', 'Usually this means that we were unable to deduce how the columns', 'are separated.' ].join(' ') ), weirdDataIgnore, weirdDataFix ), loadIndicator ); gsheetID.placeholder = 'Spreadsheet ID'; gsheetWorksheetID.placeholder = 'Worksheet (leave blank for first)'; gsheetRefreshTime.placeholder = 'Refresh Time (leave blank for no refresh)'; highed.dom.ap( gsheetFrame, highed.dom.ap( gsheetContainer, highed.dom.cr( 'div', 'highed-dtable-gsheet-heading', 'Link Google Spreadsheet' ), highed.dom.ap( highed.dom.cr('div', 'highed-dtable-gsheet-inner'), // highed.dom.cr('div', 'highed-dtable-gsheet-centered', 'You have loaded a Google Spreadsheet.'), // highed.dom.cr( // 'div', // 'highed-dtable-gsheet-desc', // [ // 'Google Spreadsheets are referenced, meaning that the data is imported', // 'on the fly. When viewing the chart, the latest version of your sheet', // 'will always be used!

' // ].join(' ') // ), highed.dom.cr( 'div', 'highed-dtable-gsheet-label', 'Google Spreadsheet ID' ), highed.dom.ap(highed.dom.cr('div'), gsheetID), highed.dom.ap( highed.dom.cr('table', 'highed-stretch'), highed.dom.ap( highed.dom.cr('tr'), highed.dom.cr('td', 'highed-dtable-gsheet-label', 'Worksheet'), highed.dom.cr('td', 'highed-dtable-gsheet-label', 'Refresh Time (Seconds)') ), highed.dom.ap( highed.dom.cr('tr'), highed.dom.ap(highed.dom.cr('td', '', ''), gsheetWorksheetID), highed.dom.ap(highed.dom.cr('td', '', ''), gsheetRefreshTime) ), highed.dom.ap( highed.dom.cr('tr'), highed.dom.cr('td', 'highed-dtable-gsheet-label', 'Start Row'), highed.dom.cr('td', 'highed-dtable-gsheet-label', 'End Row') ), highed.dom.ap( highed.dom.cr('tr'), highed.dom.ap(highed.dom.cr('td', '', ''), gsheetStartRow), highed.dom.ap(highed.dom.cr('td', '', ''), gsheetEndRow) ), highed.dom.ap( highed.dom.cr('tr'), highed.dom.cr('td', 'highed-dtable-gsheet-label', 'Start Column'), highed.dom.cr('td', 'highed-dtable-gsheet-label', 'End Column') ), highed.dom.ap( highed.dom.cr('tr'), highed.dom.ap(highed.dom.cr('td', '', ''), gsheetStartCol), highed.dom.ap(highed.dom.cr('td', '', ''), gsheetEndCol) ) ), highed.dom.ap( highed.dom.cr('div', 'highed-gsheet-btn-container'), gsheetLoadButton, gsheetCancelButton ), highed.dom.cr( 'div', 'highed-gsheet-text', [ 'When using Google Spreadsheet, Highcharts references the sheet directly.

', 'This means that the published chart always loads the latest version of the sheet.

', 'For more information on how to set up your spreadsheet, visit', 'the documentation.' ].join(' ') ) ) ) ); liveDataTypeSelect.addItems([ {id: 'columnsURL', title: "JSON (Column Ordered)"}, {id: 'rowsURL', title: "JSON (Row Ordered)"}, {id: 'csvURL', title: "CSV"} ] ); liveDataTypeSelect.on('Change', function(selected) { //detailIndex = selected.index(); detailValue = selected.id(); //liveDataTypeSelect.selectById(detailValue || 'json'); }); highed.dom.ap(liveDataTypeMasterNode, liveDataTypeSelect.container); highed.dom.style(liveDataTypeMasterNode, { display: 'block' }); highed.dom.ap( liveDataFrame, highed.dom.ap( liveDataContainer, highed.dom.cr( 'div', 'highed-dtable-gsheet-heading', 'Live Data' ), highed.dom.ap( highed.dom.cr('div', 'highed-dtable-gsheet-inner'), // highed.dom.cr('div', 'highed-dtable-gsheet-centered', 'You have loaded a Google Spreadsheet.'), // highed.dom.cr( // 'div', // 'highed-dtable-gsheet-desc', // [ // 'Google Spreadsheets are referenced, meaning that the data is imported', // 'on the fly. When viewing the chart, the latest version of your sheet', // 'will always be used!

' // ].join(' ') // ), highed.dom.cr( 'div', 'highed-dtable-gsheet-label', 'URL' ), highed.dom.ap(highed.dom.cr('div'), liveDataInput), highed.dom.ap( highed.dom.cr('table', 'highed-stretch'), highed.dom.ap( highed.dom.cr('tr'), highed.dom.cr('td', 'highed-dtable-gsheet-label', 'Chart Refresh Time (Seconds)'), highed.dom.cr('td', 'highed-dtable-gsheet-label', 'Data Type') ), highed.dom.ap( highed.dom.cr('tr'), highed.dom.ap(highed.dom.cr('td', '', ''), liveDataIntervalInput), highed.dom.ap(highed.dom.cr('td', '', ''), liveDataTypeMasterNode) ) ), highed.dom.ap( highed.dom.cr('div', 'highed-gsheet-btn-container'), liveDataLoadButton, liveDataCancelButton ), highed.dom.cr('div', 'highed-gsheet-text', [ 'Live data needs a url to your JSON data to reference.

', 'This means that the published chart always loads the latest version of your data.

' ].join(' ')) ) ) ); function selectSwitchRowsColumns() { var csvData = rowsToColumns(highed.parseCSV(toCSV())) .map(function(cols) { return cols.join(';'); }).join('\n') clearData() loadCSV({ csv: csvData }, null, true); } function rowsToColumns(rows) { var row, rowsLength, col, colsLength, columns; if (rows) { columns = []; rowsLength = rows.length; for (row = 0; row < rowsLength; row++) { colsLength = rows[row].length; for (col = 0; col < colsLength; col++) { if (!columns[col]) { columns[col] = []; } columns[col][row] = rows[row][col]; } } } return columns; } function getRawCSV() { return rawCSV; } function clearData() { highed.emit('UIAction', 'FlushDataConfirm'); init(); emitChanged(); if (rows.length > 0) rows[0].columns[0].focus(); } function colorHeader(values, color) { var tempValue = values[0]; if (values.length > 0) { while (tempValue <= values[values.length - 1]) { if (gcolumns[tempValue]) { highed.dom.style(gcolumns[tempValue].letter, { "background-color": color.light, "border-left": "1px double " + color.dark, "border-top": "1px double " + color.dark, "border-bottom": "1px double " + color.dark, "border-right": "1px double " + color.dark, }); highed.dom.style(gcolumns[tempValue].header, { "background-color": color.light, "border-left": "1px double " + color.dark, "border-right": "1px double " + color.dark, "border-bottom": "1px double " + color.dark, }); } tempValue++; } } } function colorCells(values, color) { if (values.length > 0) { rows.forEach(function(row) { var tempValue = values[0]; while (tempValue <= values[values.length - 1]) { if (row.columns[tempValue]) { highed.dom.style(row.columns[tempValue].element, { "background-color": color.light }); } tempValue++; } }); } } function outlineCell(values, color) { values.forEach(function(value, index) { rows.forEach(function(row) { if (row.columns[value]) { highed.dom.style(row.columns[value].element, { "border-right": (index === (values.length - 1) ? '1px double ' + color.dark : ''), "border-left": (index === 0 ? '1px double ' + color.dark : ''), }); } }); }); } function decolorCells(previousValues) { if (previousValues && previousValues.length > 0) { rows.forEach(function(row) { var tempValue = previousValues[0]; if (previousValues.length > 0) { while (tempValue <= previousValues[previousValues.length - 1]) { if (row.columns[tempValue]) { highed.dom.style(row.columns[tempValue].element, { "background-color": '' }); } tempValue++; //= getNextLetter(tempValue); } } }); } } function decolorHeader(previousValues) { if (previousValues && previousValues.length > 0){ var tempValue = previousValues[0]; if (previousValues.length > 0) { while (tempValue <= previousValues[previousValues.length - 1]) { if (gcolumns[tempValue]) { highed.dom.style([gcolumns[tempValue].letter, gcolumns[tempValue].header], { "background-color": '', "border": '', }); } tempValue++; //= getNextLetter(tempValue); } } } } function removeOutlineFromCell(values) { (values || []).forEach(function(value) { (rows || []).forEach(function(row){ if (row.columns[value]) { //May have been deleted on startup highed.dom.style(row.columns[value].element, { "border-right": '', "border-left": '', }); } }); }); } function removeCellColoring(previousValues) { removeOutlineFromCell(previousValues); decolorHeader(previousValues); decolorCells(previousValues); } function colorFields(values, color) { outlineCell(values, color); colorCells(values, color); colorHeader(values, color); } function highlightCells(previousValues, values, input, newOptions) { removeCellColoring(previousValues); colorFields(values, input.colors); //events.emit('AssignDataChanged', input, newOptions); } function removeAllCellsHighlight(previousValues, values, input, newOptions) { removeCellColoring(values); } function toggleUnwantedCells(values, toggle) { var found = false; gcolumns.forEach(function(col, index) { if (!values.indexOf(index) === -1) { toggle ? col.hideColumns() : col.showColumns(); } else { col.showColumns(); if (!found && rows[0]) { rows[0].columns[index].focus(); found = true; } } }); } function getColumnLength(){ return (rows[0] && rows[0].columns ? rows[0].columns.length : 2); } function areColumnsEmpty(colNumber) { return !rows.some(function(row){ return row.columns[colNumber].value() !== null; }); } function areRowsEmpty(rowNumber) { return !rows[rowNumber].columns.some(function(column){ return column.value() !== null; }); } function getDataFieldsUsed() { return dataFieldsUsed; } function isInCSVMode() { return (!isInGSheetMode && !isInLiveDataMode); } // Getting kinda long, probably need to move this all out of here to createchartpage function createTableInputs(inputs, maxColSpan, extraClass) { var table = highed.dom.cr('table', 'highed-createchartwizard-table'), maxColSpan = maxColSpan, currentColSpan = maxColSpan, tr; inputs.forEach(function(input) { if (currentColSpan >= maxColSpan) { tr = highed.dom.cr('tr', extraClass); highed.dom.ap(table, tr); currentColSpan = 0; } currentColSpan += input.colspan; input.element = {}; if (input.type && input.type === 'select') { input.element.dropdown = highed.DropDown(null, 'highed-wizard-dropdown-container'); input.element.dropdown.addItems([ {id: 'columnsURL', title: "JSON (Column Ordered)"}, {id: 'rowsURL', title: "JSON (Row Ordered)"}, {id: 'csvURL', title: "CSV"} ]); input.element.dropdown.selectByIndex(0); input.element.dropdown.on('Change', function(selected) { detailValue = selected.id(); }); input.element.input = input.element.dropdown.container; } else input.element.input = highed.dom.cr('input','highed-imp-input-stretch'); if (input.placeholder) input.element.input.placeholder = input.placeholder input.element.label = highed.dom.cr('span', '', input.label); const tdLabel = highed.dom.ap(highed.dom.cr('td', 'highed-modal-label'), input.element.label), tdInput = highed.dom.ap(highed.dom.cr('td', ''), input.element.input); tdLabel.colSpan = 1; tdInput.colSpan = input.colspan - 1; highed.dom.ap(tr, tdLabel, tdInput); }); return table; } function createCancelBtn() { cancel = highed.dom.cr('button', 'highed-ok-button highed-import-button grey', 'Cancel'); highed.dom.on(cancel, 'click', function() { dataModal.hide(); }); return cancel; } function createLiveDataContainer(toNextPage) { const container = highed.dom.cr('div', 'highed-modal-container'), inputs = [ { label: 'URL', placeholder: 'Spreadsheet ID', colspan: 2, linkedTo: liveDataInput}, { label: 'Refresh Time in Seconds', placeholder: 'Refresh time (leave blank for no refresh)', colspan: 2, linkedTo: liveDataIntervalInput}, { label: 'Type', colspan: 2, linkedTo: liveDataTypeSelect, type:'select'}], table = createTableInputs(inputs, 2, 'highed-live-data'), importData = highed.dom.cr('button', 'highed-ok-button highed-import-button negative', 'Import Data'), cancel = createCancelBtn(); highed.dom.on(importData, 'click', function() { showLiveData(true); dataModal.hide(); inputs.forEach(function(input) { if (input.type && input.type === 'select') { input.linkedTo.selectByIndex(input.element.dropdown.getSelectedItem().index()); } else input.linkedTo.value = input.element.input.value; }); liveDataLoadButton.click(); toNextPage(); }); highed.dom.ap(container, highed.dom.cr('div', 'highed-modal-title highed-help-toolbar', 'Import Live Data'), highed.dom.ap(highed.dom.cr('div'), highed.dom.cr('div', 'highed-modal-text', 'Live data needs a url to your JSON data to reference.'), highed.dom.cr('div', 'highed-modal-text', 'This means that the published chart always loads the latest version of your data.')), highed.dom.ap(highed.dom.cr('div', 'highed-table-container'), table), highed.dom.ap(highed.dom.cr('div', 'highed-button-container'), importData, cancel)); return container; } function createGSheetContainer(toNextPage) { const container = highed.dom.cr('div', 'highed-modal-container'); inputs = [ { label: 'Google Spreadsheet ID', placeholder: 'Spreadsheet ID', colspan: 4, linkedTo: gsheetID}, { label: 'Worksheet', placeholder: 'Worksheet (leave blank for first)', colspan: 4, linkedTo: gsheetWorksheetID}, { label: 'Refresh Time in Seconds', placeholder: 'Refresh time (leave blank for no refresh)', colspan: 4, linkedTo: gsheetRefreshTime}, { label: 'Start Row', colspan: 2, linkedTo: gsheetStartRow}, { label: 'End Row', colspan: 2, linkedTo: gsheetEndRow}, { label: 'Start Column', colspan: 2, linkedTo: gsheetStartCol}, { label: 'End Column', colspan: 2, linkedTo: gsheetEndCol}], table = createTableInputs(inputs, 4), connectSheet = highed.dom.cr('button', 'highed-ok-button highed-import-button negative', 'Connect Sheet'); cancel = createCancelBtn(); highed.dom.on(connectSheet, 'click', function() { showGSheet(true); dataModal.hide(); inputs.forEach(function(input) { input.linkedTo.value = input.element.input.value; }); gsheetLoadButton.click(); toNextPage(); }); highed.dom.ap(container, highed.dom.cr('div', 'highed-modal-title highed-help-toolbar', 'Connect Google Sheet'), highed.dom.ap(highed.dom.cr('div'), highed.dom.cr('div', 'highed-modal-text', 'When using Google Spreadsheet, Highcharts references the sheet directly.'), highed.dom.cr('div', 'highed-modal-text', 'This means that the published chart always loads the latest version of the sheet.'), highed.dom.cr('div', 'highed-modal-text', 'For more information on how to set up your spreadsheet, visit the documentation.')), highed.dom.ap(highed.dom.cr('div', 'highed-table-container'), table), highed.dom.ap(highed.dom.cr('div', 'highed-button-container'), connectSheet, cancel)); return container; } function createCutAndPasteContainer(toNextPage) { const container = highed.dom.cr('div', 'highed-modal-container'); importData = highed.dom.cr('button', 'highed-ok-button highed-import-button negative', 'Import Data'); input = highed.dom.cr('textarea', 'highed-table-input'), cancel = createCancelBtn(); highed.dom.on(importData, 'click', function() { importer.emitCSVImport(input.value); dataModal.hide(); toNextPage(); }); highed.dom.ap(container, highed.dom.cr('div', 'highed-modal-title highed-help-toolbar', 'Cut And Paste Data'), highed.dom.ap( highed.dom.cr('div'), highed.dom.cr('div', 'highed-modal-text', 'Paste CSV into the below box, or upload a file. Click Import to import your data.') ), highed.dom.ap(highed.dom.cr('div'), input), highed.dom.ap(highed.dom.cr('div', 'highed-button-container'), importData, cancel)); return container; } function createSampleData(toNextPage, loading) { const container = highed.dom.cr('div', 'highed-modal-container'), buttonsContainer = highed.dom.cr('div', 'highed-modal-buttons-container'); highed.samples.each(function(sample) { var data = sample.dataset.join('\n'), loadBtn = highed.dom.cr( 'button', 'highed-box-size highed-imp-button', sample.title ); highed.dom.style(loadBtn, { width: '99%' }); highed.dom.on(loadBtn, 'click', function() { loading(true); dataModal.hide(); importer.emitCSVImport(data, function() { loading(false); if (toNextPage) toNextPage(); }); }); highed.dom.ap( buttonsContainer, //highed.dom.cr('div', '', name), //highed.dom.cr('br'), loadBtn, highed.dom.cr('br') ); }); highed.dom.ap(container, buttonsContainer); return container; } function createSimpleDataTable(toNextPage, loading) { var container = highed.dom.cr('div', 'highed-table-dropzone-container'), selectFile = highed.dom.cr('button', 'highed-ok-button highed-import-button', 'Select File'), buttonsContainer = highed.dom.cr('div'), modalContainer = highed.dom.cr('div', 'highed-table-modal'), gSheetContainer = createGSheetContainer(toNextPage), liveContainer = createLiveDataContainer(toNextPage), sampleDataContainer = createSampleData(toNextPage, loading); cutAndPasteContainer = createCutAndPasteContainer(toNextPage); var buttons = [{ title: 'Connect Google Sheet', linkedTo: gSheetContainer}, { title: 'Import Live Data', linkedTo: liveContainer, height: 321}, { title: 'Cut and Paste Data', linkedTo: cutAndPasteContainer, height: 448, width: 518}, { title: 'Load Sample Data', linkedTo: sampleDataContainer}]; buttons.forEach(function(buttonProp) { const button = highed.dom.cr('button', 'highed-ok-button highed-import-button', buttonProp.title); highed.dom.on(button, 'click', function() { dataModal.resize(buttonProp.width || 530, buttonProp.height || 530); modalContainer.innerHTML = ''; highed.dom.ap(modalContainer, buttonProp.linkedTo); dataModal.show(); }); highed.dom.ap(buttonsContainer, button); }); highed.dom.on(selectFile, 'click', function(){ highed.readLocalFile({ type: 'text', accept: '.csv', success: function(info) { highed.snackBar('File uploaded'); importer.emitCSVImport(info.data); //events.emit("AssignDataForFileUpload", info.data); - Does this later in loadCSV toNextPage(); } }); }); dataModal = highed.OverlayModal(false, { minWidth: 530, minHeight: 530, showCloseIcon: true }); highed.dom.ap(dataModal.body, modalContainer); container.ondragover = function(e) { e.preventDefault(); }; container.ondrop = function(e) { e.preventDefault(); var d = e.dataTransfer; var f; var i; if (d.items) { for (i = 0; i < d.items.length; i++) { f = d.items[i]; if (f.kind === 'file') { handleFileUpload(f.getAsFile(), function() { highed.snackBar('File uploaded'); toNextPage(); }); } } } else { for (i = 0; i < d.files.length; i++) { f = d.files[i]; handleFileUpload(f, function() { highed.snackBar('File uploaded'); toNextPage(); }); } } //events.emit('AssignDataForFileUpload'); //toNextPage(); }; highed.dom.ap(container, highed.dom.ap( highed.dom.cr('div','highed-table-dropzone'), highed.dom.cr('div', 'highed-table-dropzone-title', 'Drop CSV files here'), highed.dom.cr('div', 'highed-table-dropzone-subtitle', 'or'), highed.dom.ap( highed.dom.cr('div', 'highed-table-dropzone-button'), selectFile ), highed.dom.cr('div', 'highed-table-dropzone-subtitle highed-table-dropzone-message', 'You can also:'), buttonsContainer ) ); return container; } //////////////////////////////////////////////////////////////////////////// highed.ready(function() { init(); }); //////////////////////////////////////////////////////////////////////////// return { toolbar: toolbar, sortRows: sortRows, clear: clear, addRow: addRow, insCol: insertCol, delCol: delCol, loadCSV: loadCSV, getRawCSV: getRawCSV, toData: toData, toCSV: toCSV, toDataSeries: toDataSeries, getHeaderTextArr: getHeaderTextArr, addImportTab: addImportTab, hideImportModal: hideImportModal, showImportModal: showImportModal, initGSheet: initGSheet, on: events.on, resize: resize, loadLiveDataFromURL: loadLiveDataFromURL, loadLiveDataPanel: loadLiveDataPanel, isInCSVMode: isInCSVMode, //highlightSelectedFields: highlightSelectedFields, highlightCells: highlightCells, removeAllCellsHighlight: removeAllCellsHighlight, toggleUnwantedCells: toggleUnwantedCells, getColumnLength: getColumnLength, getDataFieldsUsed: getDataFieldsUsed, createSimpleDataTable: createSimpleDataTable, areColumnsEmpty: areColumnsEmpty, clearData: clearData, showDataTableError: showDataTableError, hideDataTableError: hideDataTableError, selectSwitchRowsColumns: selectSwitchRowsColumns }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /* global window */ highed.DataPage = function(parent, options, chartPreview, chartFrame, props) { var events = highed.events(), // Main properties properties = highed.merge( { defaultChartOptions: {}, useHeader: true, features: [ 'data', 'templates', 'customize', 'customcode', 'advanced', 'export' ], importer: {}, dataGrid: {}, customizer: {}, toolbarIcons: [] }, options ), container = highed.dom.cr( 'div', 'highed-transition highed-toolbox highed-box-size' ), title = highed.dom.cr('div', 'highed-dtable-title'), chartTitle = highed.dom.cr('div', 'highed-toolbox-body-chart-title'), chartTitleInput = highed.dom.cr('input', 'highed-toolbox-chart-title-input'), contents = highed.dom.cr( 'div', 'highed-box-size highed-toolbox-inner-body' ), userContents = highed.dom.cr( 'div', 'highed-box-size highed-toolbox-user-contents highed-toolbox-dtable' ), helpIcon = highed.dom.cr( 'div', 'highed-toolbox-help highed-icon fa fa-question-circle' ), iconClass = 'highed-box-size highed-toolbox-bar-icon fa ' + props.icon, icon = highed.dom.cr('div', iconClass), helpModal = highed.HelpModal(props.help || []), // Data table dataTableContainer = highed.dom.cr('div', 'highed-box-size highed-fill'), body = highed.dom.cr( 'div', 'highed-toolbox-body highed-datapage-body highed-box-size highed-transition' ), dataTable = highed.DataTable( dataTableContainer, highed.merge( { importer: properties.importer }, properties.dataGrid ) ), addRowInput = highed.dom.cr('input', 'highed-field-input highed-add-row-input'), addRowBtn = highed.dom.cr('button', 'highed-import-button highed-ok-button highed-add-row-btn small', 'Add'), addRowDiv = highed.dom.ap(highed.dom.cr('div', 'highed-dtable-extra-options'), highed.dom.ap(highed.dom.cr('div', 'highed-add-row-container'), highed.dom.cr('span', 'highed-add-row-text highed-hide-sm', 'Add Rows'), addRowInput, addRowBtn ) ), assignDataPanel = highed.AssignDataPanel(parent, dataTable), dataImportBtn = highed.dom.cr( 'button', 'highed-import-button highed-ok-button highed-sm-button', 'Import'); dataExportBtn = highed.dom.cr( 'button', 'highed-import-button highed-ok-button highed-hide-sm', 'Export Data'); dataClearBtn = highed.dom.cr( 'button', 'highed-import-button highed-ok-button highed-sm-button', highed.L('dgNewBtn')), blacklist = [ 'candlestick', 'bubble', 'pie' ]; dataImportBtn.innerHTML += ' Data'; dataClearBtn.innerHTML += ' Data'; addRowInput.value = 1; highed.dom.on(addRowBtn, 'click', function(e) { assignDataPanel.getFieldsToHighlight(dataTable.removeAllCellsHighlight, true); for(var i=0;i -1) { serieOption[option.linkedTo] = dataTableFields.indexOf(option.rawValue[0]); } } else { if (option.linkedTo === 'label') hasLabels = true; if (dataTableFields.indexOf(option.rawValue[0]) > -1) { serieOption[option.linkedTo] = dataTableFields.indexOf(option.rawValue[0]); } //serieOption[option.linkedTo] = option.rawValue[0]; } } }); tempOption.push(serieOption); }; if (tempOption.length > 0) { if (hasLabels) { const dataLabelOptions = { dataLabels: { enabled: true, format: '{point.label}' } }; if(chartOptions.plotOptions) { const seriesPlotOptions = chartOptions.plotOptions.series; highed.merge(seriesPlotOptions, dataLabelOptions); chartPreview.options.setAll(chartOptions); } else { chartPreview.options.setAll(highed.merge({ plotOptions: { series: dataLabelOptions } }, chartOptions)); } } if (chartOptions.data) { chartOptions.data.seriesMapping = tempOption; chartPreview.options.setAll(chartOptions); } } } function redrawGrid(clearGridFirst) { if (clearGridFirst) { var columns = []; for(var i = 0; i < dataTable.getColumnLength(); i++) { columns.push(i); } dataTable.removeAllCellsHighlight(null, columns); } assignDataPanel.checkToggleCells(); assignDataPanel.getFieldsToHighlight(dataTable.highlightCells, true, true); chartPreview.data.setAssignDataFields(assignDataPanel.getAssignDataFields()); } function loadProject(projectData, aggregated) { if (projectData.settings && projectData.settings.dataProvider && projectData.settings.dataProvider.csv) { dataTable.loadCSV({ csv: projectData.settings.dataProvider.csv }, null, null, function() { assignDataPanel.enable(); assignDataPanel.setAssignDataFields(projectData, dataTable.getColumnLength(), true, null, true, true, aggregated); assignDataPanel.getFieldsToHighlight(dataTable.highlightCells, true); chartPreview.data.setDataTableCSV(dataTable.toCSV(';', true, assignDataPanel.getAllMergedLabelAndData())); }); //chartPreview.data.setAssignDataFields(assignDataPanel.getAssignDataFields()); } } ////////////////////////////////////////////////////////////////////////////// assignDataPanel.on('GoToTemplatePage', function() { events.emit("GoToTemplatePage"); }) assignDataPanel.on('AddSeries', function(index, type) { chartPreview.options.addBlankSeries(index, type); }) assignDataPanel.on('GetLastType', function() { var chartOptions = chartPreview.options.getCustomized(); var type = chartOptions.series[chartOptions.series.length - 1].type; if (blacklist.includes(type)) type = null; assignDataPanel.setColumnLength(dataTable.getColumnLength()); assignDataPanel.addNewSerie(type); }) chartPreview.on('LoadProjectData', function(csv) { dataTable.loadCSV( { csv: csv }, true ); }); chartPreview.on('ChartChange', function(newData) { events.emit('ChartChangedLately', newData); }); assignDataPanel.on('DeleteSeries', function(index) { clearSeriesMapping(); chartPreview.data.deleteSerie(index); const data = dataTable.toCSV(';', true, assignDataPanel.getAllMergedLabelAndData()); chartPreview.data.csv({ csv: data }, null, false, function() { setSeriesMapping(assignDataPanel.getAllOptions()); }); }); assignDataPanel.on('SeriesChanged', function(index) { events.emit('SeriesChanged', index); }); assignDataPanel.on('ToggleHideCells', function(options, toggle) { var userActiveCells = Object.keys(options).filter(function(key) { if(options[key].rawValue && options[key].rawValue.length > 0) return true; }).map(function(key) { return options[key].rawValue[0] }); dataTable.toggleUnwantedCells(userActiveCells, toggle); }); assignDataPanel.on('AssignDataChanged', function() { clearSeriesMapping(); const data = dataTable.toCSV(';', true, assignDataPanel.getAllMergedLabelAndData()); chartPreview.data.csv({ csv: data }, null, false, function() { setSeriesMapping(assignDataPanel.getAllOptions()); }); assignDataPanel.getFieldsToHighlight(dataTable.highlightCells); chartPreview.data.setAssignDataFields(assignDataPanel.getAssignDataFields()); //dataTable.highlightSelectedFields(input); }); assignDataPanel.on('RedrawGrid', function(clearGridFirst) { redrawGrid(clearGridFirst); }); assignDataPanel.on('ChangeData', function(allOptions) { //Series map all of the "linkedTo" options const data = dataTable.toCSV(';', true, assignDataPanel.getAllMergedLabelAndData()); chartPreview.data.setAssignDataFields(assignDataPanel.getAssignDataFields()); chartPreview.data.csv({ csv: data }, null, false, function() { setSeriesMapping(allOptions); }); }); dataTable.on('DisableAssignDataPanel', function() { assignDataPanel.disable(); }); dataTable.on('EnableAssignDataPanel', function() { assignDataPanel.enable(); }); dataTable.on('ColumnMoving', function() { //assignDataPanel.resetValues(); assignDataPanel.getFieldsToHighlight(dataTable.removeAllCellsHighlight, true); }); dataTable.on('ColumnMoved', function() { //assignDataPanel.resetValues(); assignDataPanel.getFieldsToHighlight(dataTable.highlightCells, true); }); dataTable.on('InitLoaded', function() { assignDataPanel.getFieldsToHighlight(dataTable.highlightCells, true); //dataTable.highlightSelectedFields(assignDataPanel.getOptions()); }); dataTable.on('initExporter', function(exporter){ exporter.init( chartPreview.export.json(), chartPreview.export.html(), chartPreview.export.svg(), chartPreview ); }); dataTable.on('AssignDataForFileUpload', function(rowsLength) { if (!rowsLength) rowsLength = dataTable.getColumnLength(); //Remove first column for the categories, and second as its already added assignDataPanel.setColumnLength(rowsLength); rowsLength -= 2; var chartOptions = chartPreview.options.getCustomized(); var type = chartOptions.series[chartOptions.series.length - 1].type; if (!blacklist.includes(type)) { assignDataPanel.addSeries(rowsLength, type); } }); dataTable.on('AssignDataChanged', function(input, options) { chartOptions = chartPreview.toProject().options; if (chartOptions.data && chartOptions.data.seriesMapping) { // Causes an issue when a user has added a assigndata input with seriesmapping, so just clear and it will add it in again later chartOptions.data.seriesMapping = null; chartPreview.options.setAll(chartOptions); } chartPreview.data.setAssignDataFields(assignDataPanel.getAssignDataFields()); return chartPreview.data.csv({ csv: dataTable.toCSV(';', true, options) }); }); dataTable.on('LoadLiveData', function(settings) { //chartPreview.data.live(settings); const liveDataSetting = {}; liveDataSetting[settings.type] = settings.url; if (settings.interval && settings.interval > 0){ liveDataSetting.enablePolling = true; liveDataSetting.dataRefreshRate = settings.interval } chartPreview.data.live(liveDataSetting); }); /* dataTable.on('UpdateLiveData', function(p){ chartPreview.data.liveURL(p); }); */ dataTable.on('LoadGSheet', function(settings) { assignDataPanel.disable(); chartPreview.data.gsheet(settings); }); dataTable.on('Change', function(headers, data) { chartPreview.data.setDataTableCSV(dataTable.toCSV(';', true)); chartPreview.data.csv({ csv: dataTable.toCSV(';', true, assignDataPanel.getAllMergedLabelAndData()) }, null, true, function() { setSeriesMapping(assignDataPanel.getAllOptions()); // Not the most efficient way to do this but errors if a user just assigns a column with no data in. }); }); dataTable.on('ClearData', function() { chartPreview.data.clear(); }); dataTable.on('ClearSeriesForImport', function() { var options = chartPreview.options.getCustomized(); options.series = []; assignDataPanel.restart(); }); dataTable.on('ClearSeries', function() { var options = chartPreview.options.getCustomized(); options.series = []; }); chartPreview.on('ProviderGSheet', function(p) { assignDataPanel.disable(); dataTable.initGSheet( p.id || p.googleSpreadsheetKey, p.worksheet || p.googleSpreadsheetWorksheet, p.startRow, p.endRow, p.startColumn, p.endColumn, true, p.dataRefreshRate ); }); chartPreview.on('ProviderLiveData', function(p) { assignDataPanel.disable(); dataTable.loadLiveDataPanel(p); }); function createSimpleDataTable(toNextPage, cb) { return dataTable.createSimpleDataTable(toNextPage, cb); } function selectSwitchRowsColumns() { dataTable.selectSwitchRowsColumns() } function resizeChart(newWidth) { highed.dom.style(chartFrame, { /*left: newWidth + 'px',*/ width: '28%', height: '38%' }); chartPreview.resize(); setTimeout(function() { chartPreview.resize(); }, 200); } chartPreview.on('SetResizeData', function () { //setToActualSize(); }); return { on: events.on, destroy: destroy, addImportTab: addImportTab, hideImportModal: hideImportModal, chart: chartPreview, resize: resize, data: { on: dataTable.on, showLiveStatus: function(){}, //toolbox.showLiveStatus, hideLiveStatus: function(){}//toolbox.hideLiveStatus }, hide: hide, show: show, dataTable: dataTable, isVisible: function() { return isVisible; }, init: init, setChartTitle: setChartTitle, getChartTitle: getChartTitle, getIcons: getIcons, changeAssignDataTemplate: changeAssignDataTemplate, createSimpleDataTable: createSimpleDataTable, loadProject: loadProject, showDataTableError: showDataTableError, hideDataTableError: hideDataTableError, selectSwitchRowsColumns: selectSwitchRowsColumns }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /* global window */ highed.SimpleDataPage = function(parent,assignDataParent, options, chartPreview, chartFrame, props) { var events = highed.events(), // Main properties properties = highed.merge( { defaultChartOptions: {}, useHeader: true, features: [ 'data', 'templates', 'customize', 'customcode', 'advanced', 'export' ], importer: {}, dataGrid: {}, customizer: {}, toolbarIcons: [] }, options ), container = highed.dom.cr( 'div', 'highed-transition highed-toolbox highed-simple-toolbox highed-box-size' ), title = highed.dom.cr('div', 'highed-dtable-title'), chartTitle = highed.dom.cr('div', 'highed-toolbox-body-chart-title'), chartTitleInput = highed.dom.cr('input', 'highed-toolbox-chart-title-input'), contents = highed.dom.cr( 'div', 'highed-box-size highed-toolbox-inner-body' ), userContents = highed.dom.cr( 'div', 'highed-box-size highed-toolbox-user-contents highed-toolbox-dtable' ), helpIcon = highed.dom.cr( 'div', 'highed-toolbox-help highed-icon fa fa-question-circle' ), iconClass = 'highed-box-size highed-toolbox-bar-icon fa ' + props.icon, icon = highed.dom.cr('div', iconClass), helpModal = highed.HelpModal(props.help || []), // Data table dataTableContainer = highed.dom.cr('div', 'highed-box-size highed-fill'), body = highed.dom.cr( 'div', 'highed-toolbox-body highed-simple-toolbox-body highed-datapage-body highed-box-size highed-transition' ), dataTable = highed.DataTable( dataTableContainer, highed.merge( { importer: properties.importer }, properties.dataGrid ) ), addRowInput = highed.dom.cr('input', 'highed-field-input highed-add-row-input'), addRowBtn = highed.dom.cr('button', 'highed-import-button highed-ok-button highed-add-row-btn small', 'Add'), addRowDiv = highed.dom.ap(highed.dom.cr('div', 'highed-dtable-extra-options'), highed.dom.ap(highed.dom.cr('div', 'highed-add-row-container'), highed.dom.cr('span', 'highed-add-row-text highed-hide-sm', 'Add Rows'), addRowInput, addRowBtn ) ), assignDataPanel = highed.AssignDataPanel(assignDataParent, dataTable, 'simple'), dataImportBtn = highed.dom.cr( 'button', 'highed-import-button highed-ok-button highed-sm-button', 'Import'); dataExportBtn = highed.dom.cr( 'button', 'highed-import-button highed-ok-button highed-hide-sm', 'Export Data'); dataClearBtn = highed.dom.cr( 'button', 'highed-import-button highed-ok-button highed-sm-button', highed.L('dgNewBtn')), blacklist = [ 'candlestick', 'bubble', 'pie' ]; dataImportBtn.innerHTML += ' Data'; dataClearBtn.innerHTML += ' Data'; addRowInput.value = 1; highed.dom.on(addRowBtn, 'click', function(e) { assignDataPanel.getFieldsToHighlight(dataTable.removeAllCellsHighlight, true); for(var i=0;i -1) { serieOption[option.linkedTo] = dataTableFields.indexOf(option.rawValue[0]); } } else { if (option.linkedTo === 'label') hasLabels = true; if (dataTableFields.indexOf(option.rawValue[0]) > -1) { serieOption[option.linkedTo] = dataTableFields.indexOf(option.rawValue[0]); } //serieOption[option.linkedTo] = option.rawValue[0]; } } }); tempOption.push(serieOption); }; if (tempOption.length > 0) { if (hasLabels) { const dataLabelOptions = { dataLabels: { enabled: true, format: '{point.label}' } }; if(chartOptions.plotOptions) { const seriesPlotOptions = chartOptions.plotOptions.series; highed.merge(seriesPlotOptions, dataLabelOptions); chartPreview.options.setAll(chartOptions); } else { chartPreview.options.setAll(highed.merge({ plotOptions: { series: dataLabelOptions } }, chartOptions)); } } if (chartOptions.data) { chartOptions.data.seriesMapping = tempOption; chartPreview.options.setAll(chartOptions); } } } function redrawGrid(clearGridFirst) { if (clearGridFirst) { var columns = []; for(var i = 0; i < dataTable.getColumnLength(); i++) { columns.push(i); } dataTable.removeAllCellsHighlight(null, columns); } assignDataPanel.checkToggleCells(); assignDataPanel.getFieldsToHighlight(dataTable.highlightCells, true); chartPreview.data.setAssignDataFields(assignDataPanel.getAssignDataFields()); } function loadProject(projectData, aggregated) { if (projectData.settings && projectData.settings.dataProvider && projectData.settings.dataProvider.csv) { dataTable.loadCSV({ csv: projectData.settings.dataProvider.csv }, null, null, function() { assignDataPanel.enable(); assignDataPanel.setAssignDataFields(projectData, dataTable.getColumnLength(), true, null, true, true, aggregated); assignDataPanel.getFieldsToHighlight(dataTable.highlightCells, true); chartPreview.data.setDataTableCSV(dataTable.toCSV(';', true, assignDataPanel.getAllMergedLabelAndData())); }); //chartPreview.data.setAssignDataFields(assignDataPanel.getAssignDataFields()); } } ////////////////////////////////////////////////////////////////////////////// assignDataPanel.on('GoToTemplatePage', function() { events.emit("GoToTemplatePage"); }) assignDataPanel.on('AddSeries', function(index, type) { chartPreview.options.addBlankSeries(index, type); }) assignDataPanel.on('GetLastType', function() { var chartOptions = chartPreview.options.getCustomized(); var type = chartOptions.series[chartOptions.series.length - 1]; if (type){ type = type.type; } if (blacklist.includes(type)) type = null; assignDataPanel.setColumnLength(dataTable.getColumnLength()); assignDataPanel.addNewSerie(type); }) chartPreview.on('LoadProjectData', function(csv) { dataTable.loadCSV( { csv: csv }, true ); }); chartPreview.on('ChartChange', function(newData) { events.emit('ChartChangedLately', newData); }); assignDataPanel.on('DeleteSeries', function(index) { clearSeriesMapping(); chartPreview.data.deleteSerie(index); const data = dataTable.toCSV(';', true, assignDataPanel.getAllMergedLabelAndData()); chartPreview.data.csv({ csv: data }, null, false, function() { setSeriesMapping(assignDataPanel.getAllOptions()); }); }); assignDataPanel.on('SeriesChanged', function(index) { events.emit('SeriesChanged', index); }); assignDataPanel.on('ToggleHideCells', function(options, toggle) { var userActiveCells = Object.keys(options).filter(function(key) { if(options[key].rawValue && options[key].rawValue.length > 0) return true; }).map(function(key) { return options[key].rawValue[0] }); dataTable.toggleUnwantedCells(userActiveCells, toggle); }); assignDataPanel.on('AssignDataChanged', function() { clearSeriesMapping(); const data = dataTable.toCSV(';', true, assignDataPanel.getAllMergedLabelAndData()); chartPreview.data.csv({ csv: data }, null, false, function() { setSeriesMapping(assignDataPanel.getAllOptions()); }); assignDataPanel.getFieldsToHighlight(dataTable.highlightCells); chartPreview.data.setAssignDataFields(assignDataPanel.getAssignDataFields()); //dataTable.highlightSelectedFields(input); }); assignDataPanel.on('RedrawGrid', function(clearGridFirst) { redrawGrid(clearGridFirst); }); assignDataPanel.on('ChangeData', function(allOptions) { //Series map all of the "linkedTo" options const data = dataTable.toCSV(';', true, assignDataPanel.getAllMergedLabelAndData()); chartPreview.data.setAssignDataFields(assignDataPanel.getAssignDataFields()); chartPreview.data.csv({ csv: data }, null, false, function() { setSeriesMapping(allOptions); }); }); dataTable.on('DisableAssignDataPanel', function() { assignDataPanel.disable(); }); dataTable.on('EnableAssignDataPanel', function() { assignDataPanel.enable(); }); dataTable.on('ColumnMoving', function() { //assignDataPanel.resetValues(); assignDataPanel.getFieldsToHighlight(dataTable.removeAllCellsHighlight, true); }); dataTable.on('ColumnMoved', function() { //assignDataPanel.resetValues(); assignDataPanel.getFieldsToHighlight(dataTable.highlightCells, true); }); dataTable.on('InitLoaded', function() { assignDataPanel.getFieldsToHighlight(dataTable.highlightCells, true); //dataTable.highlightSelectedFields(assignDataPanel.getOptions()); }); dataTable.on('initExporter', function(exporter){ exporter.init( chartPreview.export.json(), chartPreview.export.html(), chartPreview.export.svg(), chartPreview ); }); dataTable.on('AssignDataForFileUpload', function(rowsLength) { if (!rowsLength) rowsLength = dataTable.getColumnLength(); //Remove first column for the categories, and second as its already added assignDataPanel.setColumnLength(rowsLength); rowsLength -= 2; var chartOptions = chartPreview.options.getCustomized(); var type = chartOptions.series[chartOptions.series.length - 1].type; if (!blacklist.includes(type)) { assignDataPanel.addSeries(rowsLength, type); } }); dataTable.on('AssignDataChanged', function(input, options) { chartOptions = chartPreview.toProject().options; if (chartOptions.data && chartOptions.data.seriesMapping) { // Causes an issue when a user has added a assigndata input with seriesmapping, so just clear and it will add it in again later chartOptions.data.seriesMapping = null; chartPreview.options.setAll(chartOptions); } chartPreview.data.setAssignDataFields(assignDataPanel.getAssignDataFields()); return chartPreview.data.csv({ csv: dataTable.toCSV(';', true, options) }); }); dataTable.on('LoadLiveData', function(settings) { //chartPreview.data.live(settings); const liveDataSetting = {}; liveDataSetting[settings.type] = settings.url; if (settings.interval && settings.interval > 0){ liveDataSetting.enablePolling = true; liveDataSetting.dataRefreshRate = settings.interval } chartPreview.data.live(liveDataSetting); }); /* dataTable.on('UpdateLiveData', function(p){ chartPreview.data.liveURL(p); }); */ dataTable.on('LoadGSheet', function(settings) { assignDataPanel.disable(); chartPreview.data.gsheet(settings); }); dataTable.on('Change', function(headers, data) { chartPreview.data.setDataTableCSV(dataTable.toCSV(';', true)); chartPreview.data.csv({ csv: dataTable.toCSV(';', true, assignDataPanel.getAllMergedLabelAndData()) }, null, true, function() { setSeriesMapping(assignDataPanel.getAllOptions()); // Not the most efficient way to do this but errors if a user just assigns a column with no data in. }); }); dataTable.on('ClearData', function() { chartPreview.data.clear(); }); dataTable.on('ClearSeriesForImport', function() { var options = chartPreview.options.getCustomized(); options.series = []; assignDataPanel.restart(); }); dataTable.on('ClearSeries', function() { var options = chartPreview.options.getCustomized(); options.series = []; }); chartPreview.on('ProviderGSheet', function(p) { assignDataPanel.disable(); dataTable.initGSheet( p.id || p.googleSpreadsheetKey, p.worksheet || p.googleSpreadsheetWorksheet, p.startRow, p.endRow, p.startColumn, p.endColumn, true, p.dataRefreshRate ); }); chartPreview.on('ProviderLiveData', function(p) { assignDataPanel.disable(); dataTable.loadLiveDataPanel(p); }); function createSimpleDataTable(toNextPage, cb) { return dataTable.createSimpleDataTable(toNextPage, cb); } function selectSwitchRowsColumns() { dataTable.selectSwitchRowsColumns() } function resizeChart(newWidth) { highed.dom.style(chartFrame, { /*left: newWidth + 'px',*/ width: '28%', height: '38%' }); chartPreview.resize(); setTimeout(function() { chartPreview.resize(); }, 200); } chartPreview.on('SetResizeData', function () { //setToActualSize(); }); return { on: events.on, destroy: destroy, addImportTab: addImportTab, hideImportModal: hideImportModal, chart: chartPreview, resize: resize, data: { on: dataTable.on, showLiveStatus: function(){}, //toolbox.showLiveStatus, hideLiveStatus: function(){}//toolbox.hideLiveStatus }, hide: hide, show: show, dataTable: dataTable, isVisible: function() { return isVisible; }, init: init, setChartTitle: setChartTitle, getChartTitle: getChartTitle, getIcons: getIcons, changeAssignDataTemplate: changeAssignDataTemplate, createSimpleDataTable: createSimpleDataTable, loadProject: loadProject, showDataTableError: showDataTableError, hideDataTableError: hideDataTableError, selectSwitchRowsColumns: selectSwitchRowsColumns }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /* global window */ highed.CreateChartPage = function(parent, userOptions, props) { var events = highed.events(), builtInOptions = [ { id: 1, title: 'Choose Template', permission: 'templates', create: function(body) { highed.dom.ap(body, templateContainer); } }, { id: 2, title: 'Title Your Chart', create: function(body) { highed.dom.ap(body, titleContainer); } }, { id: 3, title: 'Import Data', create: function(body) { highed.dom.ap(body, dataTableContainer); } }, { id: 4, title: 'Customize', permission: 'customize', hideTitle: true, create: function(body) { highed.dom.ap(body, customizerContainer); } } ], container = highed.dom.cr( 'div', 'highed-transition highed-toolbox wizard highed-box-size ' ), title = highed.dom.cr('div', 'highed-toolbox-body-title'), contents = highed.dom.cr( 'div', 'highed-box-size highed-toolbox-inner-body' ), userContents = highed.dom.cr( 'div', 'highed-box-size highed-toolbox-user-contents test-test' ), body = highed.dom.cr( 'div', 'highed-toolbox-body highed-box-size highed-transition' ), listContainer = highed.dom.cr('div', 'highed-toolbox-createchart-list'), isVisible = false, customizerContainer = highed.dom.cr('div', 'highed-toolbox-customise'), titleContainer = highed.dom.cr('div', 'highed-toolbox-title'), templateContainer = highed.dom.cr('div', 'highed-toolbox-template'), dataTableContainer = highed.dom.cr('div', 'highed-toolbox-data'), //toolbox = highed.Toolbox(userContents), options = []; function init(dataPage,templatePage, customizePage) { var counter = 1; toolbox = highed.Toolbox(userContents); builtInOptions.forEach(function(option, index) { if (option.permission && userOptions.indexOf(option.permission) === -1) return; var o = toolbox.addEntry({ title: option.title, number: counter,//option.id, onClick: manualSelection, hideTitle: option.hideTitle }); if (highed.isFn(option.create)) { option.create(o.body); } options.push(o); counter++; }); options[0].expand(); createTitleSection(); createImportDataSection(dataPage); createTemplateSection(templatePage); createCustomizeSection(); highed.dom.ap(contents, userContents); highed.dom.ap(body, contents); //highed.dom.ap(userContents, listContainer); highed.dom.ap(parent, highed.dom.ap(container, body)); expand(); } function createTitleSection() { var titleInput = highed.dom.cr('input', 'highed-imp-input'), subtitleInput = highed.dom.cr('input', 'highed-imp-input'), nextButton = highed.dom.cr( 'button', 'highed-ok-button highed-import-button negative', 'Next' ), skipAll = highed.dom.cr('span', 'highed-toolbox-skip-all', 'Skip All'); titleInput.placeholder = 'Enter chart title'; subtitleInput.placeholder = 'Enter chart subtitle'; titleInput.value = ''; subtitleInput.value = ''; highed.dom.on(nextButton, 'click', function() { if(userOptions && (userOptions.indexOf('templates') === -1)) { options[1].expand(); } else options[2].expand(); events.emit("SimpleCreateChangeTitle", { title: titleInput.value, subtitle: subtitleInput.value }); }); highed.dom.on(skipAll, 'click', function() { events.emit("SimpleCreateChartDone", true); }); highed.dom.ap(titleContainer, highed.dom.cr( 'table' ), highed.dom.ap( highed.dom.cr('tr', 'highed-toolbox-input-container'), highed.dom.cr( 'td', 'highed-toolbox-label', 'Chart Title' ), highed.dom.ap(highed.dom.cr('td'), titleInput) ), highed.dom.ap( highed.dom.cr('tr', 'highed-toolbox-input-container'), highed.dom.cr( 'td', 'highed-toolbox-label', 'Subtitle' ), highed.dom.ap(highed.dom.cr('td'), subtitleInput) ), highed.dom.ap( highed.dom.cr('tr'), highed.dom.cr('td'), highed.dom.ap( highed.dom.cr('td','highed-toolbox-button-container'), skipAll, nextButton ) ) ); } function createImportDataSection(dataPage) { var nextButton = highed.dom.cr( 'button', 'highed-ok-button highed-import-button negative', 'No thanks, I will enter my data manually' ), loader = highed.dom.cr('span','highed-wizard-loader', ''), dataTableDropzoneContainer = dataPage.createSimpleDataTable(function() { if(userOptions && (userOptions.indexOf('templates') === -1)) { options[2].expand(); } else if(userOptions && (userOptions.indexOf('customize') === -1)) { events.emit("SimpleCreateChartDone", true); } else options[3].expand(); }, function(loading) { if (loading) loader.classList += ' active'; else loader.classList.remove('active'); }); highed.dom.on(nextButton, 'click', function() { if(userOptions && (userOptions.indexOf('templates') === -1)) { options[2].expand(); } else if(userOptions && (userOptions.indexOf('customize') === -1)) { events.emit("SimpleCreateChartDone", true); } else options[3].expand(); }); highed.dom.ap(dataTableContainer, highed.dom.ap(dataTableDropzoneContainer, highed.dom.ap( highed.dom.cr('div','highed-toolbox-button-container'), loader, nextButton ) ) ); } function createTemplateSection(templatePage) { var nextButton = highed.dom.cr( 'button', 'highed-ok-button highed-import-button negative', 'Choose A Template Later' ), skipAll = highed.dom.ap(highed.dom.cr('div', 'highed-toolbox-skip-all'), highed.dom.cr('span','', 'Skip All')); loader = highed.dom.cr('span','highed-wizard-loader ', ''), templatesContainer = templatePage.createMostPopularTemplates(function() { setTimeout(function() { options[1].expand(); },200); }, function(loading) { if (loading) loader.classList += ' active'; else loader.classList.remove('active'); }); highed.dom.on(skipAll, 'click', function() { events.emit("SimpleCreateChartDone", true); }); highed.dom.on(nextButton, 'click', function() { options[1].expand(); }); highed.dom.ap(templateContainer, highed.dom.ap(highed.dom.cr('div', 'highed-toolbox-template-body'), highed.dom.ap( highed.dom.cr('div', 'highed-toolbox-text'), highed.dom.cr('div', 'highed-toolbox-template-text', 'Pick a basic starter template. You can change it later.'), highed.dom.cr('div', 'highed-toolbox-template-text', "If you're not sure, just hit Choose A Template Later.") ), highed.dom.ap( highed.dom.cr('div', 'highed-toolbox-extras'), nextButton, highed.dom.ap( skipAll, loader ) ) ), templatesContainer ); } function createCustomizeSection() { var nextButton = highed.dom.cr( 'button', 'highed-ok-button highed-import-button negative', 'Customize Your Chart' );//, // dataTableDropzoneContainer = dataPage.createSimpleDataTable(); highed.dom.on(nextButton, 'click', function() { events.emit("SimpleCreateChartDone"); }); highed.dom.ap(customizerContainer, highed.dom.cr('div', 'highed-toolbox-customize-header', "You're Done!"), highed.dom.ap( highed.dom.cr('div','highed-toolbox-button-container'), nextButton ) ); } function manualSelection(number) { options.forEach(function(option, i){ if (i+1 <= number) option.disselect(); else option.removeCompleted(); }); } function resize() { if (isVisible) { expand(); } } highed.dom.on(window, 'resize', resize); function expand() { //var bsize = highed.dom.size(bar); var newWidth = props.widths.desktop; if (highed.onTablet() && props.widths.tablet) newWidth = props.widths.tablet; else if (highed.onPhone() && props.widths.phone) newWidth = props.widths.phone; highed.dom.style(body, { width: 100 + '%', //height: //(bsize.h - 55) + 'px', opacity: 1 }); highed.dom.style(container, { width: newWidth + '%' }); events.emit('BeforeResize', newWidth); function resizeBody() { var bsize = highed.dom.size(body), tsize = highed.dom.size(title), size = { w: bsize.w, h: (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - highed.dom.pos(body, true).y }; highed.dom.style(contents, { width: size.w + 'px', height: ((size.h - 16)) + 'px' }); } setTimeout(resizeBody, 300); highed.emit('UIAction', 'ToolboxNavigation', props.title); } function show() { highed.dom.style(container, { display: 'block' }); isVisible = true; //expand(); } function hide() { highed.dom.style(container, { display: 'none' }); isVisible = false; } function destroy() {} function getIcons() { return null; } ////////////////////////////////////////////////////////////////////////////// return { on: events.on, destroy: destroy, hide: hide, show: show, isVisible: function() { return isVisible; }, init: init, getIcons: getIcons }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /* global window */ highed.TemplatePage = function(parent, options, chartPreview, chartFrame, props) { var events = highed.events(), // Main properties properties = highed.merge( { defaultChartOptions: {}, useHeader: true, features: [ 'data', 'templates', 'customize', 'customcode', 'advanced', 'export' ], importer: {}, dataGrid: {}, customizer: {}, toolbarIcons: [] }, options ), container = highed.dom.cr( 'div', 'highed-transition highed-toolbox highed-box-size' ), title, // = highed.dom.cr('div', 'highed-toolbox-body-title', props.title), contents = highed.dom.cr( 'div', 'highed-box-size highed-toolbox-inner-body' ), userContents = highed.dom.cr( 'div', 'highed-box-size highed-toolbox-user-contents highed-toolbox-defaultpage highed-toolbox-templatepage' ), helpIcon = highed.dom.cr( 'div', 'highed-toolbox-help highed-icon fa fa-question-circle' ), iconClass, icon = highed.dom.cr('div', iconClass), helpModal, // Data table templatesContainer = highed.dom.cr('div', 'highed-box-size highed-fill'), templates, /*customizer = highed.ChartCustomizer( customizerContainer, properties.customizer, chartPreview ),*/ body = highed.dom.cr( 'div', 'highed-toolbox-body highed-box-size highed-transition' ), iconsContainer = highed.dom.cr('div', 'highed-toolbox-icons'), isVisible = false; //customizer.on('PropertyChange', chartPreview.options.set); //customizer.on('PropertySetChange', chartPreview.options.setAll); function init() { title = highed.dom.cr('div', 'highed-toolbox-body-title'/*, props.title*/); iconClass = 'highed-box-size highed-toolbox-bar-icon fa ' + props.icon; templatesContainer.innerHTML = ''; templates = highed.ChartTemplateSelector(templatesContainer, chartPreview); helpModal = highed.HelpModal(props.help || []); templates.on('Select', function(template) { //chartPreview.loadTemplate(template); events.emit('TemplateChanged', template); }); templates.on('LoadDataSet', function(sample) { if (sample.type === 'csv') { if (highed.isArr(sample.dataset)) { chartPreview.data.csv(sample.dataset.join('\n')); } else { chartPreview.data.csv(sample.dataset); } chartPreview.options.set('subtitle-text', ''); chartPreview.options.set('title-text', sample.title); } }); contents.innerHTML = ''; highed.dom.ap(userContents, templatesContainer); highed.dom.ap(contents, /*highed.dom.ap(title, highed.dom.ap(iconsContainer, helpIcon)),*/ userContents); highed.dom.ap(body, contents); highed.dom.ap(parent, highed.dom.ap(container,body)); templates.resize(); expand(); hide(); } function selectSeriesTemplate(index, projectData) { templates.selectSeriesTemplate(index, projectData); } function createTemplates(container, titleHeader, options, setLoading, toNextPage) { const headerBar = highed.dom.cr('div', 'highed-template-header', titleHeader), templatesContainer = highed.dom.cr('div', 'highed-templates-container'); highed.dom.ap(container, highed.dom.ap(highed.dom.cr('div', 'highed-toolbox-template-container'), headerBar, templatesContainer)); if (options.id) options = highed.templates.getAllInCat(options.id); Object.keys(options).forEach(function(key) { const templateContainer = highed.dom.cr('div', 'highed-template-container'), preview = highed.dom.cr('div', 'highed-chart-template-thumbnail'); const t = options[key]; if (highed.meta.images && highed.meta.images[t.thumbnail]) { highed.dom.style(preview, { 'background-image': 'url("data:image/svg+xml;utf8,' + highed.meta.images[t.thumbnail] + '")' }); } else { highed.dom.style(preview, { 'background-image': 'url(' + highed.option('thumbnailURL') + t.thumbnail + ')' }); } highed.dom.on(templateContainer, 'click', function() { setLoading(true); setTimeout(function() { t.header = t.parent; events.emit('TemplateChanged', highed.merge({}, t), true, function() { setLoading(false); toNextPage(); }); }, 1000); }); highed.dom.ap(templatesContainer, highed.dom.ap(templateContainer, preview, highed.dom.cr('div', 'highed-template-title', t.title))); }); } function createMostPopularTemplates(toNextPage, setLoading) { const templates = highed.templates.getCatArray(); const container = highed.dom.cr('div', 'highed-toolbox-templates-container'); const mostPopular = highed.templates.getMostPopular(); createTemplates(container, 'Most Popular', mostPopular, setLoading, toNextPage); Object.keys(templates).forEach(function(key) { const t = templates[key]; createTemplates(container, t.id, t, setLoading, toNextPage); }); return container; } function getIcons() { return null; } function resize() { if (isVisible){ expand() setTimeout(function() { resizeChart((((window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - highed.dom.pos(body, true).y) - 16)); }); } } if (!highed.onPhone()) { highed.dom.on(window, 'resize', afterResize(function(e){ resize(); })); } function afterResize(func){ var timer; return function(event){ if(timer) clearTimeout(timer); timer = setTimeout(func,100,event); }; } function expand() { var newWidth = props.widths.desktop; if (highed.onTablet() && props.widths.tablet) newWidth = props.widths.tablet; else if (highed.onPhone() && props.widths.phone) newWidth = props.widths.phone; highed.dom.style(body, { width: 100 + '%', opacity: 1 }); /* highed.dom.style(container, { width: newWidth + '%' }); */ if (!highed.onPhone()) { const windowWidth = highed.dom.size(parent).w; const percentage = ((100 - 68) / 100); var styles = window.getComputedStyle(chartFrame); var containerStyles = window.getComputedStyle(container); var chartMargin = parseFloat(styles['marginLeft']) + parseFloat(styles['marginRight']), containerMargin = parseFloat(containerStyles['marginLeft']) + parseFloat(containerStyles['marginRight']); highed.dom.style(container, { width: ((windowWidth*percentage) - (chartMargin + containerMargin + 35) - 3/*margin*/ /*padding*/) + 'px' }); } events.emit('BeforeResize', newWidth); // expanded = true; function resizeBody() { var bsize = highed.dom.size(body), tsize = highed.dom.size(title), size = { w: bsize.w, h: (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - highed.dom.pos(body, true).y }; highed.dom.style(contents, { width: "100%", height: ((size.h - 16)) + 'px' }); highed.dom.style(userContents, { width: size.w + 'px', height: ((size.h - 16) - 47) + 'px' }); templates.resize(newWidth, (size.h - 17) - tsize.h); return size; } setTimeout(resizeBody, 300); highed.emit('UIAction', 'ToolboxNavigation', props.title); } function show() { highed.dom.style(container, { display: 'block' }); expand(); setTimeout(function() { resizeChart(((window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - highed.dom.pos(body, true).y) - 16); }, 200); isVisible = true; } function hide() { highed.dom.style(container, { display: 'none' }); isVisible = false } function destroy() {} chartPreview.on('ChartChange', function(newData) { events.emit('ChartChangedLately', newData); }); ////////////////////////////////////////////////////////////////////////////// /** * Resize the chart preview based on a given width */ function resizeChart(newHeight) { highed.dom.style(chartFrame, { /*left: newWidth + 'px',*/ width: '68%', height: newHeight + 'px' }); setTimeout(chartPreview.resize, 200); } chartPreview.on('SetResizeData', function () { //setToActualSize(); }); return { on: events.on, destroy: destroy, chart: chartPreview, getIcons: getIcons, resize: resize, hide: hide, show: show, createMostPopularTemplates: createMostPopularTemplates, isVisible: function() { return isVisible; }, init: init, selectSeriesTemplate: selectSeriesTemplate //toolbar: toolbar }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /* global window */ highed.CustomizePage = function(parent, options, chartPreview, chartFrame, props, chartContainer, planCode) { var events = highed.events(), // Main properties container = highed.dom.cr( 'div', 'highed-transition highed-toolbox highed-box-size' ), title = highed.dom.cr('div', 'highed-toolbox-body-title'), customizeTitle, contents = highed.dom.cr( 'div', 'highed-box-size highed-toolbox-inner-body' ), userContents = highed.dom.cr( 'div', 'highed-box-size highed-toolbox-user-contents test' ), helpIcon = highed.dom.cr( 'div', 'highed-toolbox-help highed-icon fa fa-question-circle' ), width, chartWidth = 68, iconClass, autoAppearanceTab = true, icon = highed.dom.cr('div', iconClass), helpModal, // Data table customizerContainer = highed.dom.cr('div', 'highed-box-size highed-fill'), customizer, body = highed.dom.cr( 'div', 'highed-toolbox-body highed-box-size highed-transition' ), iconsContainer = highed.dom.cr('div', 'highed-icons-container'), annotationContainer, activeAnnotation = null, annotationOptions = [{ tooltip: 'Add Circle', icon: 'circle', value: 'circle', draggable: true }, { tooltip: 'Add Square', icon: 'stop', value: 'rect', draggable: true }, { tooltip: 'Add Annotations', icon: 'comment', value: 'label', draggable: true }, { tooltip: 'Move', icon: 'arrows', value: 'drag' }, { tooltip: 'Remove', icon: 'trash', value: 'delete', }, { tooltip: 'Close', icon: 'times', onClick: function() { annotationOptions.forEach(function(o) { o.element.classList.remove('active'); }); chartPreview.setIsAnnotating(false); annotationContainer.classList.remove('active'); } }], buttons = [ { tooltip: 'Basic', onClick: function() { reduceSize(customizer.showSimpleEditor); }, icon: 'cog' }, { tooltip: 'Advanced', noPermission: options.noAdvanced, onClick: function() { customizer.showAdvancedEditor(); }, icon: 'cogs' }, { tooltip: 'Custom Code', noPermission: options.noCustomCode, onClick: function() { reduceSize(customizer.showCustomCode); }, icon: 'code' }, { tooltip: 'Preview Options', noPermission: options.noPreview, onClick: function() { reduceSize(customizer.showPreviewOptions); }, icon: 'eye' } ], isVisible = false, searchAdvancedOptions = highed.SearchAdvancedOptions(parent), resolutionSettings = highed.dom.cr('span', 'highed-resolution-settings'), phoneIcon = highed.dom.cr('span', '', ''); tabletIcon = highed.dom.cr('span', '', ''), tabletIcon = highed.dom.cr('span', '', ''), stretchToFitIcon = highed.dom.cr('span', '', ''), chartSizeText = highed.dom.cr('span', 'text', 'Chart Size:'), resWidth = highed.dom.cr('input', 'highed-res-number'), resHeight = highed.dom.cr('input', 'highed-res-number'), resolutions = [ { iconElement: phoneIcon, width: 414, height: 736 }, { iconElement: tabletIcon, width: 1024, height: 768 } ], overlayAddTextModal = highed.OverlayModal(false, { // zIndex: 20000, showOnInit: false, width: 300, height: 350, class: ' highed-annotations-modal' }), activeColor = 'rgba(0, 0, 0, 0.75)', addTextModalContainer = highed.dom.cr('div', 'highed-add-text-popup'), addTextModalInput = highed.dom.cr('textarea', 'highed-imp-input-stretch'), colorDropdownParent = highed.dom.cr('div'), typeDropdownParent = highed.dom.cr('div'), addTextModalHeader = highed.dom.cr('div', 'highed-modal-header', 'Add Annotation'), addTextModalColorSelect = highed.DropDown(colorDropdownParent), addTextModalTypeOptions = [{ text: 'Callout', icon: 'comment-o', value: 'callout' },{ text: 'Connector', icon: 'external-link', value: 'connector' }, { text: 'Circle', icon: 'circle-o', value: 'circle' }], addTextModalTypeValue = 'callout', addTextModalColorValue = '#000000', addTextModalColorContainer = highed.dom.cr('div', 'highed-modal-color-container'), addTextModalColorInput = highed.dom.cr('input', 'highed-color-input'), box = highed.dom.cr('div', 'highed-field-colorpicker', ''), addTextModalBtnContainer = highed.dom.cr('div', 'highed-modal-button-container'), addTextModalSubmit = highed.dom.cr('button', 'highed-ok-button highed-import-button mini', 'Save'), addTextModalCancel = highed.dom.cr('button', 'highed-ok-button highed-import-button grey negative mini', 'Cancel'), addLabelX = null, addLabelY = null; resWidth.placeholder = 'W'; resHeight.placeholder = 'H'; addTextModalColorSelect.addItems([ { title: 'Black', id: 'black', select: function() { activeColor = 'rgba(0, 0, 0, 0.75)'; } }, { title: 'Red', id: 'red', select: function() { activeColor = 'rgba(255, 0, 0, 0.75)'; } }, { title: 'Blue', id: 'blue', select: function() { activeColor = 'rgba(0, 0, 255, 0.75)'; } } ]); addTextModalColorSelect.selectByIndex(0); addTextModalColorInput.value = addTextModalColorValue; highed.dom.on(addTextModalCancel, 'click', function() { overlayAddTextModal.hide(); }); highed.dom.style(box, { background: addTextModalColorValue, color: highed.getContrastedColor(addTextModalColorValue) }); addTextModalTypeOptions.forEach(function(option) { var container = highed.dom.cr('div', 'highed-annotation-modal-container ' + (addTextModalTypeValue === option.value ? ' active' : '')), icon = highed.dom.cr('div', 'highed-modal-icon fa fa-' + option.icon), text = highed.dom.cr('div', 'highed-modal-text', option.text); option.element = container; highed.dom.on(container, 'click', function() { addTextModalTypeOptions.forEach(function(o) { if (o.element.classList.contains('active')) o.element.classList.remove('active'); }) option.element.classList += ' active'; addTextModalTypeValue = option.value; }) highed.dom.ap(typeDropdownParent, highed.dom.ap(container, icon, text)); }); addTextModalInput.placeholder = 'Write annotation here'; function update(col) { if ( col && col !== 'null' && col !== 'undefined' && typeof col !== 'undefined' ) { box.innerHTML = ""; //box.innerHTML = col; } else { box.innerHTML = 'auto'; col = '#FFFFFF'; } highed.dom.style(box, { background: col, color: highed.getContrastedColor(col) }); } var timeout = null; highed.dom.on(addTextModalColorInput, 'change', function(e) { clearTimeout(timeout); timeout = setTimeout(function () { addTextModalColorValue = addTextModalColorInput.value; update(addTextModalColorValue); }, 500); }); highed.dom.on(box, 'click', function(e) { highed.pickColor(e.clientX, e.clientY, addTextModalColorValue, function(col) { if (highed.isArr(addTextModalColorValue)) { addTextModalColorValue = '#000000'; } addTextModalColorValue = col; addTextModalColorInput.value = addTextModalColorValue; update(col); }); }); highed.dom.ap(overlayAddTextModal.body, highed.dom.ap(addTextModalContainer, addTextModalHeader, addTextModalInput, highed.dom.cr('div', 'highed-add-text-label', 'Type:'), typeDropdownParent, highed.dom.cr('div', 'highed-add-text-label', 'Color:'), //colorDropdownParent, highed.dom.ap(addTextModalColorContainer, box, addTextModalColorInput), highed.dom.ap(addTextModalBtnContainer, addTextModalSubmit, addTextModalCancel ) ) ); highed.dom.on(addTextModalSubmit, 'click', function() { overlayAddTextModal.hide(); chartPreview.addAnnotationLabel(addLabelX, addLabelY, addTextModalInput.value.replace('\n', '
'), addTextModalColorValue, addTextModalTypeValue); addTextModalInput.value = ''; }); function usingSafari() { return (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Mac') != -1 && navigator.userAgent.indexOf('Chrome') == -1) } function init() { width = props.width, customizeTitle = highed.dom.cr('div', 'highed-customize-title'/*, props.title*/), iconClass = 'highed-box-size highed-toolbox-bar-icon fa ' + props.icon; customizerContainer.innerHTML = ''; customizer = highed.ChartCustomizer( customizerContainer, options, chartPreview, planCode ), helpModal = highed.HelpModal(props.help || []); customizer.on('PropertyChange', chartPreview.options.set); customizer.on('PropertySetChange', chartPreview.options.setAll); customizer.on('TogglePlugins', chartPreview.options.togglePlugins); customizer.on('AdvancedBuilt', function() { var bsize = highed.dom.size(body), size = { w: bsize.w, h: (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - highed.dom.pos(body, true).y }; searchAdvancedOptions.resize(width, (size.h - highed.dom.size(chartFrame).h) - 15); searchAdvancedOptions.setOptions(customizer.getAdvancedOptions()); }); customizer.on('AnnotationsClicked', function() { chartPreview.options.togglePlugins('annotations', 1); }); customizer.on('AdvanceClicked', function() { width = 66; if (highed.onTablet()) width = 64; chartWidth = 28; highed.dom.style(backIcon, { display: "inline-block" }); expand(); resizeChart(300); setTimeout(chartPreview.resize, 1000); searchAdvancedOptions.show(); }); highed.dom.ap(resolutionSettings, chartSizeText, stretchToFitIcon, tabletIcon, phoneIcon, resWidth, resHeight); title.innerHTML = ''; iconsContainer.innerHTML = ''; if (!highed.onPhone()) { buttons.forEach(function(button, i) { if (button.noPermission) return; button.element = highed.dom.cr('span', 'highed-toolbox-custom-code-icon highed-template-tooltip ' + ( i === 0 ? ' active' : ''), '' + button.tooltip + ''); highed.dom.on(button.element, 'click', function() { buttons.forEach(function(b){ if (!b.noPermission) b.element.classList.remove('active'); }); button.element.classList.add('active'); button.onClick(); }); highed.dom.ap(iconsContainer, button.element); }); } var annotationButton = highed.dom.cr('span', 'highed-template-tooltip annotation-buttons ' + (usingSafari() ? ' usingsafari ' : '') , 'Annotations'); highed.dom.on(annotationButton, 'click', function() { if (annotationContainer.classList.contains('active')) annotationContainer.classList.remove('active'); else annotationContainer.classList.add('active'); }); if (!annotationContainer) { annotationContainer = highed.dom.cr('div', 'highed-transition highed-annotation-container'); highed.dom.ap(annotationContainer, annotationButton); annotationOptions.forEach(function(option) { var btn = highed.dom.cr('span', 'highed-template-tooltip annotation-buttons ' + (usingSafari() ? ' usingsafari ' : '') , '' + option.tooltip + ''); if (option.onClick || !option.draggable) { highed.dom.on(btn, 'click', function() { if (option.onClick) option.onClick(); else { var isAnnotating = !(option.element.className.indexOf('active') > -1); annotationOptions.forEach(function(o) { o.element.classList.remove('active'); }); chartPreview.setIsAnnotating(isAnnotating); if (isAnnotating) { chartPreview.options.togglePlugins('annotations', 1); chartPreview.setAnnotationType(option.value); option.element.className += ' active'; } } }); } else { highed.dom.on(btn, 'mousedown', function (e) { activeAnnotation = highed.dom.cr('div', 'highed-active-annotation fa fa-' + option.icon); highed.dom.ap(document.body, activeAnnotation); function moveAt(pageX, pageY) { highed.dom.style(activeAnnotation, { left: pageX - (btn.offsetWidth / 2 - 10) + 'px', top: pageY - (btn.offsetHeight / 2 - 10) + 'px' }); } moveAt(e.pageX, e.pageY); function onMouseMove(event) { if(event.stopPropagation) event.stopPropagation(); if(event.preventDefault) event.preventDefault(); moveAt(event.pageX, event.pageY); } document.addEventListener('mousemove', onMouseMove); highed.dom.on(activeAnnotation, 'mouseup', function (e) { e = chartPreview.options.all().pointer.normalize(e); document.removeEventListener('mousemove', onMouseMove); activeAnnotation.onmouseup = null; activeAnnotation.remove(); activeAnnotation = null; chartPreview.options.togglePlugins('annotations', 1); chartPreview.setAnnotationType(option.value); chartPreview.addAnnotation(e); }); }); } option.element = btn; highed.dom.ap(annotationContainer, btn); }); } highed.dom.ap(iconsContainer, annotationContainer); highed.dom.ap(contents, userContents); highed.dom.ap(body, contents); highed.dom.ap(userContents, customizerContainer); highed.dom.ap(parent, highed.dom.ap(container,body)); //customizer.resize(); expand(); hide(); } function getResolutionContainer() { return resolutionSettings; } function afterResize(func){ var timer; return function(event){ if(timer) clearTimeout(timer); timer = setTimeout(func,100,event); }; } function reduceSize(fn) { width = props.widths.desktop; if (highed.onTablet() && props.widths.tablet) width = props.widths.tablet; else if (highed.onPhone() && props.widths.phone) width = props.widths.phone; chartWidth = 68; expand(); setTimeout(function() { if (fn) fn(); resizeChart(((window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - highed.dom.pos(body, true).y) - 16); }, 200); } function resize() { if (isVisible){ expand() setTimeout(function() { resizeChart((((window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - highed.dom.pos(body, true).y) - 16)); }, 500); //expand(); } } if (!highed.onPhone()) { highed.dom.on(window, 'resize', afterResize(function(e){ resize(); })); } resolutions.forEach(function(res) { highed.dom.on(res.iconElement, 'click', function(){ sizeChart(res.width, res.height); resWidth.value = res.width; resHeight.value = res.height; }); }); highed.dom.on(stretchToFitIcon, 'click', function() { resWidth.value = ''; resHeight.value = ''; highed.dom.style(chartContainer, { width: '100%', height: '100%', }); setTimeout(chartPreview.resize, 300); }), backIcon = highed.dom.cr('div','highed-back-icon', ''); highed.dom.style(backIcon, { display: "none" }); highed.dom.on(backIcon, 'click', function(){ width = props.widths.desktop; if (highed.onTablet() && props.widths.tablet) width = props.widths.tablet; else if (highed.onPhone() && props.widths.phone) width = props.widths.phone; chartWidth = 68; highed.dom.style(backIcon, { display: "none" }); searchAdvancedOptions.hide(); expand(); resizeChart(((window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - highed.dom.pos(body, true).y) - 16); setTimeout(customizer.showSimpleEditor, 200); }); function expand() { var newWidth = width; //props.width; highed.dom.style(body, { width: 100 + '%', opacity: 1 }); if (!highed.onPhone()) { const windowWidth = highed.dom.size(parent).w; const percentage = ((100 - chartWidth) / 100); var styles = window.getComputedStyle(chartFrame); var containerStyles = window.getComputedStyle(container); var chartMargin = parseFloat(styles['marginLeft']) + parseFloat(styles['marginRight']), containerMargin = parseFloat(containerStyles['marginLeft']) + parseFloat(containerStyles['marginRight']); highed.dom.style(container, { width: ((windowWidth*percentage) - (chartMargin + containerMargin + 35) - 3 /*padding*/) + 'px' }); } events.emit('BeforeResize', newWidth); function resizeBody() { var bsize = highed.dom.size(body), tsize = highed.dom.size(title), size = { w: bsize.w, h: (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - highed.dom.pos(body, true).y }; highed.dom.style(contents, { width: "100%", height: ((size.h - 16)) + 'px' }); customizer.resize(size.w, (size.h - 17) - tsize.h); return size; } setTimeout(resizeBody, 300); highed.emit('UIAction', 'ToolboxNavigation', props.title); } function show() { highed.dom.style(container, { display: 'block' }); expand(); resizeChart(((window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - highed.dom.pos(body, true).y) - 16); isVisible = true; highed.dom.style(resolutionSettings, { display: 'block' }); if (autoAppearanceTab) { setTimeout(function() { if (!document.getElementById('highed-list-header-Appearance').classList.contains('active')){ document.getElementById('highed-list-header-Appearance').children[0].click() } }, 300) } } function hide() { customizer.showSimpleEditor(); width = props.widths.desktop; if (highed.onTablet() && props.widths.tablet) width = props.widths.tablet; else if (highed.onPhone() && props.widths.phone) width = props.widths.phone; chartWidth = 68; highed.dom.style(backIcon, { display: "none" }); searchAdvancedOptions.hide(); expand(); highed.dom.style(container, { display: 'none' }); isVisible = false; searchAdvancedOptions.hide(); if (resolutionSettings) { highed.dom.style(resolutionSettings, { display: 'none' }); } if (!highed.onPhone()){ buttons.forEach(function(button, i) { if (button.noPermission) return; if (button.element) { button.element.classList.remove('active'); } if (i === 0) button.element.classList += ' active'; }); } resHeight.value = ''; resWidth.value = ''; } function selectOption(event, x, y) { customizer.focus(event, x, y); } function setTabBehaviour(behaviour) { autoAppearanceTab = behaviour } function destroy() {} function showError(title, message) { highed.dom.style(errorBar, { opacity: 1, 'pointer-events': 'auto' }); errorBarHeadline.innerHTML = title; errorBarBody.innerHTML = message; } function sizeChart(w, h) { if ((!w || w.length === 0) && (!h || h.length === 0)) { fixedSize = false; resHeight.value = ''; resWidth.value = ''; resizeChart(); } else { var s = highed.dom.size(chartFrame); // highed.dom.style(chartFrame, { // paddingLeft: (s.w / 2) - (w / 2) + 'px', // paddingTop: (s.h / 2) - (h / 2) + 'px' // }); fixedSize = { w: w, h: h }; w = (w === 'auto' ? s.w : w || s.w - 100); h = (h === 'auto' ? s.h : h || s.h - 100); highed.dom.style(chartContainer, { width: w + 'px', height: h + 'px' }); //chartPreview.chart.setWidth(); chartPreview.resize(w, h); } } highed.dom.on([resWidth, resHeight], 'change', function() { sizeChart(parseInt(resWidth.value, 10), parseInt(resHeight.value, 10)); }); chartPreview.on('ShowTextDialog', function(chart, x, y) { addLabelX = x; addLabelY = y; addTextModalInput.focus(); overlayAddTextModal.show(); }); chartPreview.on('ChartChange', function(newData) { events.emit('ChartChangedLately', newData); }); function getIcons(){ return iconsContainer; } function resizeChart(newHeight) { highed.dom.style(chartFrame, { /*left: newWidth + 'px',*/ width: chartWidth + '%', //'68%', height: newHeight + 'px' || '100%' }); /* highed.dom.style(chartContainer, { width: psize.w - newWidth - 100 + 'px', height: psize.h - 100 + 'px' });*/ setTimeout(chartPreview.resize, 200); } chartPreview.on('SetResizeData', function () { //setToActualSize(); }); return { on: events.on, destroy: destroy, hide: hide, show: show, resize: resize, isVisible: function() { return isVisible; }, init: init, getIcons: getIcons, selectOption: selectOption, getResolutionContainer: getResolutionContainer, setTabBehaviour: setTabBehaviour //toolbar: toolbar }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format highed.Toolbox = function(parent, attr) { var events = highed.events(), container = highed.dom.cr( 'div', 'highed-transition highed-toolbox highed-wizard highed-box-size' ), bar = highed.dom.cr('div', 'highed-toolbox-bar highed-box-size highed-wizard-title-container'), body = highed.dom.cr( 'div', 'highed-toolbox-body highed-toolbox-body-no-border highed-box-size highed-transition highed-wizard-body' ), activeTimeout, expanded = false, activeItem = false, properties = highed.merge( { animate: true }, attr ); function addEntry(def) { var props = highed.merge( { number: 0, title: 'Title Missing' }, def ), entryEvents = highed.events(), title = highed.dom.cr('div', 'highed-toolbox-body-title wizard', props.hideTitle ? '' : props.title), contents = highed.dom.cr( 'div', 'highed-box-size highed-toolbox-inner-body' ), userContents = highed.dom.cr( 'div', 'highed-box-size highed-toolbox-user-contents highed-createchart-body-container' ), iconClass = 'highed-toolbox-list-item-container', icon = highed.dom.cr('div', iconClass), resizeTimeout, exports = {}, circle = highed.dom.cr('div', 'highed-toolbox-list-circle', props.number); highed.dom.on(circle, 'click', function() { props.onClick(props.number); expand(); }); highed.dom.ap(icon, circle, highed.dom.cr('div', 'highed-toolbox-list-title', props.title)); highed.dom.on(icon, 'click', function() { entryEvents.emit('Click'); }); function resizeBody() { var bsize = highed.dom.size(body), tsize = highed.dom.size(title), size = { w: bsize.w, h: bsize.h - tsize.h - 55 }; /* highed.dom.style(contents, { width: size.w + 'px', height: size.h + 'px' }); */ return size; } function expand() { var bsize = highed.dom.size(bar); var newWidth = props.width; if (expanded && activeItem === exports) { return; } if (props.iconOnly) { return; } if (activeItem) { activeItem.disselect(); } entryEvents.emit('BeforeExpand'); body.innerHTML = ''; highed.dom.ap(body, contents); highed.dom.style(body, { height: (bsize.h - 55) + 'px', opacity: 1 }); highed.dom.style(container, { width: newWidth + '%' }); events.emit('BeforeResize', newWidth); expanded = true; setTimeout(function() { var height = resizeBody().h; events.emit('Expanded', exports, newWidth); entryEvents.emit('Expanded', newWidth, height - 20); }, 300); if (props.iconOnly) { activeItem = false; } else { icon.className = iconClass + ' active'; activeItem = exports; } highed.emit('UIAction', 'ToolboxNavigation', props.title); } function collapse() { var newWidth = highed.dom.size(bar).w; if (expanded) { highed.dom.style(body, { width: '0px', opacity: 0.1 }); highed.dom.style(container, { width: newWidth + '%' }); events.emit('BeforeResize', newWidth); disselect(); expanded = false; activeItem = false; } } function toggle() { expand(); } function disselect() { icon.className = iconClass + ' completed'; } function removeCompleted() { setTimeout(function() { icon.classList.remove('completed'); }, 50); } //highed.dom.on(icon, 'click', toggle); highed.dom.ap(bar, icon); highed.dom.ap(contents, title, userContents); function reflowEverything() { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(function() { highed.dom.style(body, { height: '' }); if (expanded) { var height = resizeBody().h; entryEvents.emit('Expanded', highed.dom.size(bar), height - 20); } }, 100); } highed.dom.on(window, 'resize', reflowEverything); exports = { on: entryEvents.on, expand: expand, collapse: collapse, body: userContents, removeCompleted: removeCompleted, disselect: disselect }; return exports; } function width() { var bodySize = highed.dom.size(body), barSize = highed.dom.size(bar); return bodySize.w + barSize.w; } function clear() { bar.innerHTML = ''; body.innerHTML = ''; } highed.dom.ap(parent, highed.dom.ap(container,bar,body)); return { clear: clear, on: events.on, addEntry: addEntry, width: width }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format highed.OptionsPanel = function(parent, attr) { var events = highed.events(), container = highed.dom.cr( 'div', 'highed-transition highed-optionspanel highed-box-size' ), body = highed.dom.cr( 'div', 'highed-box-size highed-transition' ), prev, options = {}, currentOption = null; highed.dom.ap(parent, highed.dom.ap(container, highed.dom.ap(body, highed.dom.cr('div', '', 'Workspace View:')))); function setDefault(option) { prev = option; } function addOption(option, id) { var btn = highed.dom.cr( 'a', 'highed-optionspanel-button ' + (id === 'data' ? 'active' : ''), option.text + ' ' ); (option.onClick || []).forEach(function(click) { highed.dom.on(btn, 'click', function() { Object.keys(options).forEach(function(o) { options[o].classList.remove('active'); }); currentOption = option; btn.classList.add('active'); click(prev, option); }); }); options[id] = btn; highed.dom.ap(body,btn); } function clearOptions() { body.innerHTML = ''; highed.dom.ap(body, highed.dom.cr('div', 'highed-optionspanel-header', 'Workspace View:')); } function getPrev() { return prev; } function getOptions() { return options; } function getCurrentOption() { return currentOption; } return { on: events.on, addOption: addOption, setDefault: setDefault, getPrev: getPrev, clearOptions: clearOptions, getOptions: getOptions, getCurrentOption: getCurrentOption }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format highed.AssignDataPanel = function(parent, dataTable, extraClass) { var defaultOptions = { 'labels': { 'name': "Categories", 'desc': 'Choose a column for the category types. Can be names or a date.', 'default': 'A', 'value': 'A', 'rawValue': [0], 'previousValue': null, 'linkedTo': 'x', 'mandatory': true, 'colors': { 'light': 'rgba(66, 200, 192, 0.2)', 'dark': 'rgb(66, 200, 192)', } }, 'values': { 'name': "Values", 'desc': 'Enter column with the values you want to chart.', 'default': 'B', 'linkedTo': 'y', 'isData': true, 'value': 'B', 'rawValue': [1], 'previousValue': null, 'mandatory': true, 'colors': { 'light': 'rgba(145, 151, 229, 0.2)', 'dark': 'rgb(145, 151, 229)', } }, 'label': { 'name': "Label", 'desc': 'The name of the point as shown in the legend, tooltip, data label etc.', 'default': '', 'value': '', 'rawValue': null, 'previousValue': null, 'mandatory': false, 'linkedTo': 'label', 'colors': { 'light': 'rgba(229, 145, 145, 0.2)', 'dark': 'rgb(229, 145, 145)', }, 'noNulls': true } }, options = [], toggled = false, columnLength = 0, index = 0, maxColumnLength = 1, showCells = false, disabled = false; var events = highed.events(), container = highed.dom.cr( 'div', 'highed-transition highed-assigndatapanel highed-box-size ' + extraClass ), bar = highed.dom.cr('div', 'highed-assigndatapanel-bar highed-box-size ' + extraClass), body = highed.dom.cr( 'div', 'highed-assigndatapanel-body highed-box-size highed-transition ' + extraClass ), headerToggle = highed.dom.cr('span', '', ''), header = highed.dom.ap( highed.dom.cr('div', 'highed-assigndatapanel-header-container'), highed.dom.ap(highed.dom.cr('h3', 'highed-assigndatapanel-header', 'Assign columns for this chart'), headerToggle)), labels = highed.dom.cr('div', 'highed-assigndatapanel-data-options'), selectContainer = highed.dom.cr('div', 'highed-assigndatapanel-select-container'), changeSeriesTypeContainer = highed.dom.cr('div', 'highed-assigndatapanel-change-series-type'), changeSeriesTypeLink = highed.dom.cr('a', 'highed-assigndatapanel-change-series-type-link', 'Click here to change series template type'), inputContainer = highed.dom.cr('div', 'highed-assigndatapanel-inputs-container'), addNewSeriesBtn = highed.dom.cr('button', 'highed-assigndatapanel-add-series', ''), deleteSeriesBtn = highed.dom.cr('button', 'highed-assigndatapanel-add-series', ''), toggleHideCellsBtn = highed.dom.cr('button', 'highed-assigndatapanel-add-series', ''), seriesTypeSelect = highed.DropDown(selectContainer, ' highed-assigndatapanel-series-dropdown'), hidden = highed.dom.cr('div', 'highed-assigndatapanel-hide'); highed.dom.style(hidden, { display: 'none' }); addSerie(); Object.keys(defaultOptions).forEach(function(key) { defaultOptions[key].colors = null; }); function init(colLength) { columnLength = colLength; highed.dom.ap(body, labels); resetDOM(); highed.dom.ap(parent, highed.dom.ap(container, bar, body)); if (!disabled) { events.emit('AssignDataChanged', options[index]); } } function resetValues() { Object.keys(options[index]).forEach(function(key) { options[index][key].previousValue = null; options[index][key].value = options[index][key].default; }); } function getAssignDataFields() { var all = []; options.forEach(function(option) { var arr = {}; Object.keys(option).forEach(function(key) { if (option[key].value === '' || option[key].value === null) return; arr[key] = option[key].value; }); all.push(highed.merge({}, arr)); }); return all; } function restart() { defaultOptions.labels.colors = { 'light': 'rgba(66, 200, 192, 0.2)', 'dark': 'rgb(66, 200, 192)', }; defaultOptions.values.colors = { 'light': 'rgba(145, 151, 229, 0.2)', 'dark': 'rgb(145, 151, 229)', }; defaultOptions.label.colors = { 'light': 'rgba(229, 145, 145, 0.2)', 'dark': 'rgb(229, 145, 145)', }; index = 0, columnLength = 0, maxColumnLength = 1; options = []; addSerie(); Object.keys(defaultOptions).forEach(function(key) { defaultOptions[key].colors = null; }); resetDOM(); } function getMergedLabelAndData() { var arr = {}, extraColumns = [], values = []; Object.keys(options[index]).forEach(function(optionKeys) { if (optionKeys === 'labels') { arr.labelColumn = highed.getLetterIndex(options[index][optionKeys].value.charAt(0)); } else if (options[index][optionKeys].isData) { //(highed.isArr(options[index][optionKeys])) { const allData = options[index][optionKeys]; values.push(allData.rawValue[0]); arr.dataColumns = values; arr.dataColumns.sort(); } else { // Check for any extra fields, eg. Name const extraValue = options[index][optionKeys]; if (extraValue.value !== '') { extraColumns.push(highed.getLetterIndex(extraValue.value)); } } }); arr.extraColumns = extraColumns.sort(); return arr; //arr.concat(values); } function getAllMergedLabelAndData() { var seriesValues = []; options.forEach(function(serie, i) { var arr = {}, extraColumns = [], values = []; Object.keys(serie).forEach(function(optionKeys) { if (optionKeys === 'labels') { arr.labelColumn = highed.getLetterIndex(options[i][optionKeys].value.charAt(0)); } else if (options[i][optionKeys].isData) { //(highed.isArr(options[i][optionKeys])) { const allData = options[i][optionKeys]; /* allData.forEach(function(data) { values.push(data.rawValue[0]); arr.dataColumns = values; });*/ values.push(allData.rawValue[0]); arr.dataColumns = values; arr.dataColumns.sort(); } else { // Check for any extra fields, eg. Name const extraValue = options[i][optionKeys]; if (extraValue.value !== '') { extraColumns.push(highed.getLetterIndex(extraValue.value)); } } }); arr.extraColumns = extraColumns.sort(); seriesValues.push(highed.merge({}, arr)); }); return seriesValues; } function getLetterIndex(char) { return char.charCodeAt() - 65; } function getLetterFromIndex(num) { return String.fromCharCode(num + 65); } function getActiveSerie() { return index; } function processField(input, overrideCheck, cb) { input.value = input.value.toUpperCase(); var newOptions = []; var previousValues = [], values = []; if (!overrideCheck) { if (input.previousValue === input.value || (input.value === '' && input.previousValue === null)) return; } values = [input.value.charAt(0)]; if (input.previousValue) previousValues = [input.previousValue]; if (!input.mandatory && input.value === '') { values = []; } newOptions = getMergedLabelAndData(); //else newOptions.push(highed.getLetterIndex(input.value.charAt(0))); input.previousValue = input.value.toUpperCase(); input.rawValue = values.map(function (x) { return highed.getLetterIndex(x); }); cb(previousValues.map(function (x) { return highed.getLetterIndex(x); }), input.rawValue, input, newOptions); } function getFieldsToHighlight(cb, overrideCheck, dontEmit) { if (!options[index]) return; Object.keys(options[index]).forEach(function(key) { var input = options[index][key]; processField(input, overrideCheck, cb); }); if (!disabled && !dontEmit) events.emit("ChangeData", options); } function generateColors() { const hue = Math.floor(Math.random()*(357-202+1)+202), // Want a blue/red/purple colour saturation = Math.floor(Math.random() * 100), lightness = 60, alpha = 0.5; return { "light": "hsla(" + hue + ", " + saturation + "%, " + (lightness + 20) + "%, " + alpha + ")", "dark": "hsl(" + hue + ", " + saturation + "%, " + lightness + "%)", }; } function addSeries(length, type) { if (length + 1 < options.length) { //Need to do some culling options = options.slice(0,length + 1); events.emit('RemoveSeries', length + 1); seriesTypeSelect.sliceList(length + 1); resetDOM(); } else { for(var i=options.length - 1; i -1 ? '-' : ','); const output = input.split(delimiter).sort(); output.forEach(function(value, index){ output[index] = getLetterIndex(value); }); return output; } function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } function clean(obj) { Object.keys(obj).forEach(function(key) { if (highed.isNull(obj[key])) delete obj[key]; }); } function getSeriesType(data, index, aggregatedOptions) { // Change this in future, data should handle 99% of cases but have had to use aggregatedoptions due to users setting chart type through custom code // Looks messy using both atm if (data.config) return data.config.chart.type; else { if (data.options && data.options.series && data.options.series[index] && data.options.series[index].type) return data.options.series[index].type; if (data.template && data.template.chart && data.template.chart.type) return data.template.chart.type; else if (data.options && data.options.chart && data.options.chart.type) return data.options.chart.type; else if (data.theme && data.theme.options.chart && data.theme.options.chart.type) return data.theme.options.chart.type; else if (aggregatedOptions && aggregatedOptions.chart && aggregatedOptions.chart.type) return aggregatedOptions.chart.type; else return 'line'; } } function setAssignDataFields(data, maxColumns, init, seriesIndex, skipEmit, serieValue, aggregatedOptions) { if (!data || disabled) return; columnLength = maxColumns; var seriesType = getSeriesType(data, 0, aggregatedOptions), previousValues = null; seriesTypeSelect.updateByIndex(seriesIndex || index, { title: 'Series ' + ((seriesIndex || index) + 1) + ' - ' + capitalizeFirstLetter(seriesType) }); seriesTypeSelect.selectByIndex(index); chartTypeOptions = highed.meta.charttype[seriesType.toLowerCase()]; if (options[seriesIndex || index] && options[seriesIndex || index].values) { previousValues = options[seriesIndex || index].values; } options[seriesIndex || index] = null; options[seriesIndex || index] = highed.merge({}, defaultOptions); if (!isNaN(serieValue)) { if (options[seriesIndex || index].values) { options[seriesIndex || index].values.value = getLetterFromIndex(serieValue); options[seriesIndex || index].values.rawValue = [serieValue]; } } if (previousValues && options[seriesIndex || index] && options[seriesIndex || index].values) { highed.merge(options[seriesIndex || index].values, previousValues); } /* if (chartTypeOptions && chartTypeOptions.data) { options[seriesIndex || index].data = null; }*/ highed.merge(options[seriesIndex || index], highed.meta.charttype[seriesType]); clean(options[seriesIndex || index]); if (init) { if (data.settings && data.settings.dataProvider && data.settings.dataProvider.assignDataFields) { const dataFields = data.settings.dataProvider.assignDataFields; dataFields.forEach(function(option, index) { const seriesType = getSeriesType(data, index); if(!options[index]) { addSerie(seriesType); } Object.keys(option).forEach(function(key) { if (options[index][key]) { options[index][key].value = option[key]; options[index][key].rawValue = [getLetterIndex(option[key])]; } }) }); } else { // Probably a legacy chart, change values to equal rest of chart var length = maxColumns - 1; if (data && data.options && data.options.series) { length = data.options.series.length; } for(var i=1; i maxColumnLength) { maxColumnLength = getLetterIndex(option.value.toUpperCase()); } } if (showCells) events.emit('ToggleHideCells', options[index], showCells); if (!disabled) { events.emit('AssignDataChanged', options[index], option, getLetterIndex(detailValue.toUpperCase()), key); } //liveDataTypeSelect.selectById(detailValue || 'json'); }); var colors = option.colors || generateColors(); option.colors = colors; labelInput.value = option.value; const colorDiv = highed.dom.cr('div', 'highed-assigndatapanel-color'); highed.dom.style(colorDiv, { "background-color": option.colors.light, "border": '1px solid ' + option.colors.dark, }); var label = highed.dom.ap(highed.dom.cr('div', 'highed-assigndatapanel-data-option'), colorDiv, highed.dom.ap(highed.dom.cr('p', '', option.name + ':'), highed.dom.cr('span', 'highed-assigndatapanel-data-mandatory', option.mandatory ? '*' : '')), valueContainer, highed.dom.cr('div', 'highed-assigndatapanel-data-desc', option.desc)); highed.dom.ap(inputContainer, label); } function resetDOM() { inputContainer.innerHTML = ''; if (options[index]){ Object.keys(options[index]).forEach(function(key) { var option = options[index][key]; generateInputs(option, key); }); } } function toggleCells() { if (showCells) { showCells = false; toggleHideCellsBtn.innerHTML = ''; } else { showCells = true; toggleHideCellsBtn.innerHTML = ''; } events.emit('ToggleHideCells', options[index], showCells); } function checkToggleCells() { if (showCells) events.emit('ToggleHideCells', options[index], showCells); } function getStatus() { return disabled; } function addNewSerie(lastType) { addSerie(lastType, true); events.emit('AssignDataChanged'); } function getElement() { return container; } function setColumnLength(length) { columnLength = length; } //////////////////////////////////////////////////////////////////////////////// highed.dom.ap(selectContainer, addNewSeriesBtn, deleteSeriesBtn, toggleHideCellsBtn); highed.dom.ap(changeSeriesTypeContainer, changeSeriesTypeLink); highed.dom.on(changeSeriesTypeLink, 'click', function() { events.emit('GoToTemplatePage'); }); highed.dom.on(toggleHideCellsBtn, 'click', function() { toggleCells(); }); highed.dom.on(deleteSeriesBtn, 'click', function() { if (index === 0) { highed.snackBar("Cannot delete this series"); return; } if (confirm("Are you sure you want to delete this series?")) { options.splice(index, 1); seriesTypeSelect.deleteByIndex(index); const allSeries = seriesTypeSelect.selectAll(); events.emit('DeleteSeries', index); setTimeout(function() { events.emit('AssignDataChanged'); }, 1000); for(var i=index; i < options.length; i++) { seriesTypeSelect.updateByIndex(i, { title: 'Series ' + (i + 1) + ' -' + allSeries[i].title().split('-')[1] }, i); } seriesTypeSelect.selectByIndex(index - 1); highed.snackBar("Series " + (index + 2) + " Deleted"); } }); highed.dom.on(addNewSeriesBtn, 'click', function() { events.emit('GetLastType'); }); seriesTypeSelect.on('Change', function(selected) { if (index !== selected.id()) { index = selected.id(); resetDOM(); if (showCells) events.emit('ToggleHideCells', options[index], showCells); if (!disabled) { events.emit('RedrawGrid', true); events.emit('SeriesChanged', index); } } }); highed.dom.on(headerToggle, 'click', function() { const height = (toggled ? '48px' : 'initial'); const overflow = (toggled ? 'hidden' : 'auto'); highed.dom.style(container, { height: height, overflow: overflow }); toggled = !toggled; }); seriesTypeSelect.addItems([{ id: 0, title: 'Series ' + (options.length) + ' - Line' }]); seriesTypeSelect.selectById(0); highed.dom.ap(body, header); highed.dom.ap(labels, selectContainer, changeSeriesTypeContainer, inputContainer); highed.dom.ap(body, hidden); return { on: events.on, hide: hide, show: show, getOptions: getOptions, resetValues: resetValues, resize: resize, getFieldsToHighlight: getFieldsToHighlight, getMergedLabelAndData: getMergedLabelAndData, getAllMergedLabelAndData: getAllMergedLabelAndData, setAssignDataFields: setAssignDataFields, getAssignDataFields: getAssignDataFields, getAllOptions: getAllOptions, getActiveSerie: getActiveSerie, addNewSerie: addNewSerie, addSeries: addSeries, setColumnLength: setColumnLength, checkToggleCells: checkToggleCells, init: init, enable: enable, disable: disable, getStatus: getStatus, getElement: getElement, restart: restart }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /* global window */ highed.DefaultPage = function(parent, options, chartPreview, chartFrame) { var events = highed.events(), // Main properties container = highed.dom.cr( 'div', 'highed-transition highed-toolbox highed-box-size' ), title = highed.dom.cr('div', 'highed-toolbox-body-title'), customizeTitle, contents = highed.dom.cr( 'div', 'highed-box-size highed-toolbox-inner-body' ), userContents = highed.dom.cr( 'div', 'highed-box-size highed-toolbox-user-contents highed-toolbox-defaultpage' ), width, chartWidth = '68%', iconClass, icon = highed.dom.cr('div', iconClass), // Data table iconsContainer = highed.dom.cr('div', 'highed-icons-container'), body = highed.dom.cr( 'div', 'highed-toolbox-body highed-box-size highed-transition' ), isVisible = false; function init() { width = options.widths.desktop; if (highed.onTablet() && options.widths.tablet) width = options.widths.tablet; else if (highed.onPhone() && options.widths.phone) width = options.widths.phone; customizeTitle = highed.dom.cr('div', 'highed-customize-title'/*, options.title*/), iconClass = 'highed-box-size highed-toolbox-bar-icon fa ' + options.icon; title.innerHTML = ''; if (options.create && highed.isFn(options.create)) options.create(userContents, chartPreview, iconsContainer); highed.dom.ap(contents, /*highed.dom.ap(title,backIcon, customizeTitle, highed.dom.ap(iconsContainer,helpIcon)),*/ userContents); highed.dom.ap(body, contents); highed.dom.ap(parent, highed.dom.ap(container,body)); expand(); hide(); } function afterResize(func){ var timer; return function(event){ if(timer) clearTimeout(timer); timer = setTimeout(func,100,event); }; } function resize() { if (isVisible){ expand() setTimeout(function() { resizeChart((((window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - highed.dom.pos(body, true).y) - 16)); }, 1000); //expand(); } } if (!highed.onPhone()) { highed.dom.on(window, 'resize', afterResize(function(e){ resize(); })); } function getIcons() { return iconsContainer; } function expand() { var newWidth = width; //props.width; highed.dom.style(body, { width: 100 + '%', opacity: 1 }); if (!highed.onPhone()) { const windowWidth = highed.dom.size(parent).w; const percentage = ((100 - 68) / 100); var styles = window.getComputedStyle(chartFrame); var containerStyles = window.getComputedStyle(container); var chartMargin = parseFloat(styles['marginLeft']) + parseFloat(styles['marginRight']), containerMargin = parseFloat(containerStyles['marginLeft']) + parseFloat(containerStyles['marginRight']); highed.dom.style(container, { width: ((windowWidth*percentage) - (chartMargin + containerMargin + 35) - 3/*margin*/ /*padding*/) + 'px' }); } events.emit('BeforeResize', newWidth); // expanded = true; function resizeBody() { var bsize = highed.dom.size(body), tsize = highed.dom.size(title), size = { w: bsize.w, h: (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - highed.dom.pos(body, true).y }; highed.dom.style(contents, { width: "100%", height: ((size.h - 16)) + 'px' }); highed.dom.style(userContents, { width: size.w + 'px', height: ((size.h - 16)) + 'px' }); //customizer.resize(newWidth, (size.h - 17) - tsize.h); return size; } setTimeout(resizeBody, 300); highed.emit('UIAction', 'ToolboxNavigation', options.title); } function show() { highed.dom.style(container, { display: 'block' }); expand(); setTimeout(function() { resizeChart(((window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - highed.dom.pos(body, true).y) - 16); }, 200); isVisible = true; } function hide() { //customizer.showSimpleEditor(); width = options.widths.desktop; if (highed.onTablet() && options.widths.tablet) width = options.widths.tablet; else if (highed.onPhone() && options.widths.phone) width = options.widths.phone; chartWidth = "68%"; highed.dom.style(backIcon, { display: "none" }); //searchAdvancedOptions.hide(); expand(); highed.dom.style(container, { display: 'none' }); isVisible = false; } function destroy() {} chartPreview.on('ChartChange', function(newData) { events.emit('ChartChangedLately', newData); }); ////////////////////////////////////////////////////////////////////////////// /** * Resize the chart preview based on a given width */ function resizeChart(newHeight) { highed.dom.style(chartFrame, { /*left: newWidth + 'px',*/ width: chartWidth, //'68%', height: newHeight + 'px' || '100%' }); /* highed.dom.style(chartContainer, { width: psize.w - newWidth - 100 + 'px', height: psize.h - 100 + 'px' });*/ setTimeout(chartPreview.resize, 200); } return { on: events.on, destroy: destroy, chart: chartPreview, hide: hide, show: show, resize: resize, isVisible: function() { return isVisible; }, init: init, getIcons: getIcons //toolbar: toolbar }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format highed.SearchAdvancedOptions = function(parent, attr) { var timeout = null, advancedOptions = null, filters = { //Filter the series properties based on the series.type property series: { controller: 'type', state: false, default: 'line' }, plotOptions: { controller: 'type', state: false, default: 'line' } };; function resize(w, h) { highed.dom.style(container, { height: (h - 5) + 'px' }); } function setOptions(options) { advancedOptions = options; /* advancedOptions = (options.series || []).map(function(serie) { return serie.type || 'line'; });*/ } var events = highed.events(), container = highed.dom.cr( 'div', 'highed-transition highed-assigndatapanel highed-searchadvancedoptions highed-box-size' ), bar = highed.dom.cr('div', 'highed-searchadvancedoptions-bar highed-box-size'), body = highed.dom.cr( 'div', 'highed-searchadvancedoptions-body highed-box-size highed-transition' ), header = highed.dom.ap( highed.dom.cr('div', 'highed-searchadvancedoptions-header-container'), highed.dom.cr('h3', 'highed-searchadvancedoptions-header', 'Search'), highed.dom.cr('p', 'highed-searchadvancedoptions-header-desc')), labels = highed.dom.cr('div', 'highed-searchadvancedoptions-data-options'), searchResultContainer = highed.dom.cr('div', 'highed-searchadvancedoptions-results'), inputContainer = highed.dom.cr('div', 'highed-searchadvancedoptions-inputs-container'), searchInput = highed.dom.cr('input', 'highed-searchadvancedoptions-search highed-field-input'), loading = highed.dom.cr( 'div', 'highed-customizer-adv-loader highed-searchadvancedoptions-loading', ' Loading'); highed.dom.style(loading, { opacity: 0 }); var searchResults = []; function compareValues(str, queryArr) { var foundCount = 0; queryArr.forEach(function(q) { if (str.indexOf(q) > - 1) { foundCount ++; } }); return foundCount; } function search(node, parent, str) { if (parent && parent.meta.fullname && filters[parent.meta.fullname]) { if (node.meta && node.meta.validFor) { var customizedSeriesOption = advancedOptions.series; var found = false; customizedSeriesOption.forEach(function(serieOption) { fstate = serieOption[filters[parent.meta.fullname].controller] || filters[parent.meta.fullname].default; if (node.meta.validFor[fstate]) found = true; }); if (!found) { return; } } } if (highed.isArr(node)) { node.forEach(function(child) { search(child, parent, str); }); } else { if (Object.keys(node.meta.types)[0] === 'function' || ( node.meta.products && Object.keys(node.meta.products) > 0)) { return; } var foundCount = compareValues(highed.uncamelize(node.meta.name).toLowerCase(), str); foundCount += compareValues(highed.uncamelize(node.meta.ns).toLowerCase(), str); if (node.meta.description) foundCount += compareValues(highed.uncamelize(node.meta.description).toLowerCase(), str); if (foundCount > 0) { searchResults.push({ name: highed.uncamelize(node.meta.name), rawName: node.meta.name, parents: (node.meta.ns.split('.')).map(function(e){ return highed.uncamelize(e); }), rawParent: (parent === null ? node.meta.name : parent.meta.ns + parent.meta.name), foundCount: foundCount, ns: node.meta.ns }); } if (node.children && node.children.length > 0) { search(node.children, node, str); } } } highed.dom.on(searchInput, 'keyup', function(e) { highed.dom.style(loading, { opacity: 1 }); clearTimeout(timeout); timeout = setTimeout(function () { const optionsAdvanced = highed.meta.optionsAdvanced.children, searchArray = searchInput.value.toLowerCase().split(' '); searchResults = []; optionsAdvanced.forEach(function(child) { search(child, null, searchArray); }); resetDOM(); }, 500); }); function hide() { highed.dom.style(container, { display: 'none' }); } function show() { highed.dom.style(container, { display: 'block' }); } highed.dom.ap(body, header); function firstToLowerCase( str ) { return str.substr(0, 1).toLowerCase() + str.substr(1); } function highlight(input) { input.classList += ' active-highlight'; setTimeout(function() { if (input) input.classList.remove('active-highlight'); }, 2000); } function resetDOM() { searchResultContainer.innerHTML = ''; searchResults.sort(function(a,b) {return (a.foundCount < b.foundCount) ? 1 : ((b.foundCount < a.foundCount) ? -1 : 0);} ); searchResults.forEach(function(result, i) { if (i > 50) return; const resultContainer = highed.dom.cr('div', 'highed-searchadvancedoptions-result-container'), resultTitle = highed.dom.cr('div', 'highed-searchadvancedoptions-result-title', result.name), resultParents = highed.dom.cr('div', 'highed-searchadvancedoptions-result-parents', result.parents.join(' ')); highed.dom.on(resultContainer, 'click', function() { const parents = result.parents, time = 500; var link = ''; for(var i=0; i Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ // @format highed.meta.optionsExtended = { options: { 'option.cat.chart': [ { text: 'option.subcat.dimension', dropdown: true, group: 1, options: [ { id: 'chart--width', custom: { minValue: 50, maxValue: 5000, step: 10 }, pid: 'chart.width', dataType: 'number', context: 'General', defaults: 'null', parent: 'chart' }, { id: 'chart--height', custom: { minValue: 50, maxValue: 5000, step: 10 }, pid: 'chart.height', dataType: 'number', context: 'General', defaults: 'null', parent: 'chart' } ] }, { text: 'option.subcat.title', dropdown: true, group: 1, options: [ { id: 'title--text', pid: 'title.text', dataType: 'string', context: 'General', defaults: 'Chart title', parent: 'title', width: 50 }, { id: 'subtitle--text', pid: 'subtitle.text', dataType: 'string', context: 'General', parent: 'subtitle', width: 50 }, { id: 'title--style', dataType: 'font', pid: 'title.style', context: 'General', defaults: '{ "color": "#333333", "fontSize": "18px" }', parent: 'title' }, { id: 'subtitle--style', dataType: 'font', pid: 'subtitle.style', context: 'General', defaults: '{ "color": "#666666", "fontSize": "12px" }', parent: 'subtitle' } ] }, { text: 'option.subcat.appearance', dropdown: true, options: [ { header: true, pid: 'option.subcat.chartarea', width: 100, id: 'chartarea-header', dataType: 'header', }, { id: 'chart--backgroundColor', pid: 'chart.backgroundColor', dataType: 'color', context: 'General', defaults: '#FFFFFF', parent: 'chart', width:50 }, { id: 'chart--borderColor', pid: 'chart.borderColor', dataType: 'color', context: 'General', defaults: '#335cad', parent: 'chart', width: 50 }, { id: 'chart--borderWidth', custom: { minValue: 0 }, pid: 'chart.borderWidth', dataType: 'number', context: 'General', defaults: '0', parent: 'chart', width: 50 }, { id: 'chart--borderRadius', custom: { minValue: 0 }, pid: 'chart.borderRadius', dataType: 'number', context: 'General', defaults: '0', parent: 'chart', width: 50 }, { header: true, pid: 'option.subcat.plotarea', width: 100, id: 'plotarea-header', dataType: 'header', }, { id: 'chart--plotBackgroundColor', pid: 'chart.plotBackgroundColor', dataType: 'color', context: 'General', parent: 'chart', width: 38 }, { id: 'chart--plotBorderWidth', pid: 'chart.plotBorderWidth', dataType: 'number', context: 'General', defaults: '0', parent: 'chart', width: 31 }, { id: 'chart--plotBorderColor', pid: 'chart.plotBorderColor', dataType: 'color', context: 'General', defaults: '#cccccc', parent: 'chart', width: 31 }, { id: 'chart--plotBackgroundImage', pid: 'chart.plotBackgroundImage', dataType: 'string', context: 'General', parent: 'chart' }, { id: 'colors', pid: 'colors', dataType: 'array', context: 'General', defaults: '[ "#7cb5ec" , "#434348" , "#90ed7d" , "#f7a35c" , "#8085e9" , "#f15c80" , "#e4d354" , "#2b908f" , "#f45b5b" , "#91e8e1"]' } ] }, { text: 'option.subcat.tooltip', dropdown: true, options: [ { id: 'tooltip--enabled', pid: 'tooltip.enabled', dataType: 'boolean', context: 'General', defaults: 'true', parent: 'tooltip', width: 50 }, { id: 'tooltip--shared', pid: 'tooltip.shared', dataType: 'boolean', context: 'General', defaults: 'false', parent: 'tooltip', width: 50 }, { id: 'tooltip--backgroundColor', pid: 'tooltip.backgroundColor', dataType: 'color', context: 'General', defaults: 'rgba(247,247,247,0.85)', parent: 'tooltip', width: 50 }, { id: 'tooltip--borderWidth', custom: { minValue: 0 }, pid: 'tooltip.borderWidth', dataType: 'number', context: 'General', defaults: '1', parent: 'tooltip', width: 50 }, { id: 'tooltip--borderRadius', custom: { minValue: 0 }, pid: 'tooltip.borderRadius', dataType: 'number', context: 'General', defaults: '3', parent: 'tooltip', width: 50 }, { id: 'tooltip--borderColor', pid: 'tooltip.borderColor', dataType: 'color', context: 'General', defaults: 'null', parent: 'tooltip', width: 50 }, { id: 'tooltip--valueSuffix', pid: 'tooltip.valueSuffix', dataType: 'string', context: 'General', defaults: '', parent: 'tooltip', width: 98 } ] }, { text: 'option.subcat.interaction', dropdown: true, group: 2, options: [ { id: 'chart--zoomType', pid: 'chart.zoomType', dataType: 'string', context: 'General', parent: 'chart', values: '[null, "x", "y", "xy"]' }, { id: 'chart--polar', pid: 'chart.polar', dataType: 'boolean', context: 'General', defaults: 'false', parent: 'chart' }, { id: 'plotOptions--series--states--inactive--opacity', pid: 'plotOptions.series.states.inactive.opacity', dataType: 'number', context: 'General', defaults: '0.2', parent: 'chart' } ] }, { text: 'option.subcat.credit', dropdown: true, group: 2, warning: [1], options: [ { id: 'credits--enabled', pid: 'credits.enabled', dataType: 'boolean', context: 'General', defaults: 'true', parent: 'credits', warning: [1] }, { id: 'credits--text', pid: 'credits.text', dataType: 'string', context: 'General', defaults: 'Highcharts.com', parent: 'credits', warning: [1] }, { id: 'credits--href', pid: 'credits.href', dataType: 'string', context: 'General', defaults: 'http://www.highcharts.com', parent: 'credits', warning: [1] } ] } ], 'option.cat.axes': [ { text: 'option.subcat.xaxis', dropdown: true, options: [ { id: 'xAxis-title--style', dataType: 'font', dataIndex: 0, pid: 'xAxis.title.style', context: 'General', defaults: '{ "color": "#666666" }', parent: 'xAxis-title' }, { id: 'xAxis-title--text', dataIndex: 0, pid: 'xAxis.title.text', dataType: 'string', context: 'General', parent: 'xAxis-title', width: 50 }, { id: 'xAxis-labels--format', dataIndex: 0, pid: 'xAxis.labels.format', dataType: 'string', context: 'General', defaults: '{value}', parent: 'xAxis-labels', width: 50 }, { id: 'xAxis--type', dataIndex: 0, pid: 'xAxis.type', dataType: 'string', context: 'General', defaults: 'linear', parent: 'xAxis', values: '["linear", "logarithmic", "datetime", "category"]' }, { id: 'xAxis--opposite', dataIndex: 0, pid: 'xAxis.opposite', dataType: 'boolean', context: 'General', defaults: 'false', parent: 'xAxis', width: 50 }, { id: 'xAxis--reversed', dataIndex: 0, pid: 'xAxis.reversed', dataType: 'boolean', context: 'General', defaults: 'false', parent: 'xAxis', width: 50 } ] }, { text: 'option.subcat.yaxis', dropdown: true, options: [ { id: 'yAxis-title--style', dataType: 'font', dataIndex: 0, pid: 'yAxis.title.style', context: 'General', defaults: '{ "color": "#666666" }', parent: 'yAxis-title' }, { id: 'yAxis-title--text', dataIndex: 0, pid: 'yAxis.title.text', dataType: 'string', context: 'General', defaults: 'Values', parent: 'yAxis-title', width: 50 }, { id: 'yAxis--type', dataIndex: 0, pid: 'yAxis.type', dataType: 'string', context: 'General', defaults: 'linear', parent: 'yAxis', values: '["linear", "logarithmic", "datetime", "category"]', width: 50 }, { id: 'yAxis-labels--format', dataIndex: 0, pid: 'yAxis.labels.format', dataType: 'string', context: 'General', defaults: '{value}', parent: 'yAxis-labels', width: 100 }, { id: 'yAxis--opposite', dataIndex: 0, pid: 'yAxis.opposite', dataType: 'boolean', context: 'General', defaults: 'false', parent: 'yAxis', width: 50 }, { id: 'yAxis--reversed', dataIndex: 0, pid: 'yAxis.reversed', dataType: 'boolean', context: 'General', defaults: 'false', parent: 'yAxis', width: 50 } ] } ], 'option.cat.series': [ { id: 'series', array: true, text: 'option.cat.series', controlledBy: { title: 'Select Series', options: 'series', optionsTitle: 'name' }, filteredBy: 'series--type', options: [ { id: 'series--type', pid: 'series.type', dataType: 'string', context: 'General', parent: 'series', values: '[null, "line", "spline", "column", "area", "areaspline", "pie", "arearange", "areasplinerange", "boxplot", "bubble", "columnrange", "errorbar", "funnel", "gauge", "scatter", "waterfall"]', subType: [ 'treemap', 'scatter', 'line', 'gauge', 'heatmap', 'spline', 'funnel', 'areaspline', 'area', 'bar', 'bubble', 'areasplinerange', 'boxplot', 'pie', 'arearange', 'column', 'waterfall', 'columnrange', 'pyramid', 'polygon', 'solidgauge', 'errorbar' ], subTypeDefaults: {}, width: 50 }, { id: 'series--dashStyle', pid: 'series.dashStyle', dataType: 'string', context: 'General', defaults: 'Solid', parent: 'series', values: '["Solid", "ShortDash", "ShortDot", "ShortDashDot", "ShortDashDotDot", "Dot", "Dash" ,"LongDash", "DashDot", "LongDashDot", "LongDashDotDot"]', subType: [ 'areasplinerange', 'polygon', 'areaspline', 'spline', 'scatter', 'area', 'bubble', 'arearange', 'waterfall', 'line' ], subTypeDefaults: { polygon: 'Solid', areaspline: 'Solid', spline: 'Solid', scatter: 'Solid', area: 'Solid', bubble: 'Solid', arearange: 'Solid', waterfall: 'Dot', line: 'Solid' }, width: 50 }, { id: 'series--color', pid: 'series.color', dataType: 'color', context: 'General', defaults: 'null', parent: 'series', subType: [ 'boxplot', 'column', 'waterfall', 'columnrange', 'heatmap', 'area', 'scatter', 'bar', 'treemap', 'arearange', 'bubble', 'errorbar', 'spline', 'polygon', 'line', 'gauge', 'areaspline', 'areasplinerange' ], subTypeDefaults: { heatmap: 'null', treemap: 'null', errorbar: '#000000' }, width: 18 }, { id: 'series--negativeColor', pid: 'series.negativeColor', dataType: 'color', context: 'General', defaults: 'null', parent: 'series', subType: [ 'gauge', 'arearange', 'areasplinerange', 'line', 'errorbar', 'boxplot', 'areaspline', 'spline', 'bar', 'scatter', 'polygon', 'bubble', 'area', 'column' ], subTypeDefaults: { arearange: 'null', areasplinerange: 'null', line: 'null', errorbar: 'null', boxplot: 'null', areaspline: 'null', spline: 'null', bar: 'null', scatter: 'null', polygon: 'null', bubble: 'null', area: 'null', column: 'null' }, width: 33 }, { id: 'series-marker--symbol', pid: 'series.marker.symbol', dataType: 'string', context: 'General', parent: 'series-marker', values: '[null, "circle", "square", "diamond", "triangle", "triangle-down"]', subType: [ 'bubble', 'polygon', 'line', 'scatter', 'spline', 'area', 'areaspline' ], subTypeDefaults: {}, width: 49 }, { id: 'series--colorByPoint', pid: 'series.colorByPoint', dataType: 'boolean', context: 'General', defaults: 'false', parent: 'series', subType: [ 'treemap', 'heatmap', 'column', 'errorbar', 'columnrange', 'boxplot', 'bar', 'waterfall' ], subTypeDefaults: { heatmap: 'false', column: 'false', errorbar: 'false', columnrange: 'false', boxplot: 'false', bar: 'false', waterfall: 'false' }, width: 50 }, { id: 'series-marker--enabled', pid: 'series.marker.enabled', dataType: 'boolean', context: 'General', defaults: 'null', parent: 'series-marker', subType: [ 'bubble', 'area', 'scatter', 'areaspline', 'spline', 'polygon', 'line' ], subTypeDefaults: { area: 'null', scatter: 'null', areaspline: 'null', spline: 'null', polygon: 'null', line: 'null' }, width: 50 }, // { // id: 'series-label--enabled', // pid: 'series.label.enabled', // defaults: 'true', // dataType: 'boolean', // subType: [ // 'line', // 'spline', // 'area', // 'arearange', // 'areaspline', // 'waterfall', // 'areasplinerange' // ], // subTypeDefaults: {} // } // { // id: 'series-label--style', // pid: 'series.label.style', // dataType: 'font' // } ] } ], 'option.cat.export': [ { text: 'option.cat.exporting', dropdown: true, options: [ { id: 'exporting--enabled', pid: 'exporting.enabled', dataType: 'boolean', context: 'General', defaults: 'true', parent: 'exporting', width: 50 }, { id: 'exporting--offlineExporting', pid: 'exporting.offlineExporting', dataType: 'boolean', context: 'General', defaults: 'false', parent: 'exporting', width: 50, plugins: [ 'modules/offline-exporting.js' ], noChange: true }, { id: 'exporting--sourceWidth', custom: { minValue: 10, maxValue: 2000, step: 10 }, pid: 'exporting.sourceWidth', dataType: 'number', context: 'General', parent: 'exporting', values: '' }, { id: 'exporting--scale', custom: { minValue: 1, maxValue: 4 }, pid: 'exporting.scale', dataType: 'number', context: 'General', defaults: '2', parent: 'exporting', values: '' } ] } ], 'option.cat.legend': [ { text: 'option.subcat.general', dropdown: true, group: 1, options: [ { id: 'legend--enabled', pid: 'legend.enabled', dataType: 'boolean', context: 'General', defaults: 'true', parent: 'legend' }, { id: 'legend--layout', pid: 'legend.layout', dataType: 'string', context: 'General', defaults: 'horizontal', width: 50, parent: 'legend', values: '["horizontal", "vertical"]' }, { id: 'legend--labelFormat', pid: 'legend.labelFormat', dataType: 'string', context: 'General', defaults: '{name}', width: 50, parent: 'legend', } ] }, { text: 'option.subcat.placement', dropdown: true, group: 1, options: [ { id: 'legend--align', pid: 'legend.align', dataType: 'string', context: 'General', defaults: 'center', parent: 'legend', values: '["left", "center", "right"]', width: 50 }, { id: 'legend--verticalAlign', pid: 'legend.verticalAlign', dataType: 'string', context: 'General', defaults: 'bottom', parent: 'legend', values: '["top", "middle", "bottom"]', width: 50 }, { id: 'legend--floating', pid: 'legend.floating', dataType: 'boolean', context: 'General', defaults: 'false', parent: 'legend' } ] }, { text: 'option.subcat.legendappearance', dropdown: true, options: [ { id: 'legend--itemStyle', dataType: 'font', pid: 'legend.itemStyle', context: 'General', defaults: '{ "color": "#333333", "cursor": "pointer", "fontSize": "12px", "fontWeight": "bold" }', parent: 'legend' }, { id: 'legend--backgroundColor', pid: 'legend.backgroundColor', dataType: 'color', context: 'General', parent: 'legend', width: 50 }, { id: 'legend--borderColor', pid: 'legend.borderColor', dataType: 'color', context: 'General', defaults: '#999999', parent: 'legend', width: 50 }, { id: 'legend--borderWidth', pid: 'legend.borderWidth', dataType: 'number', context: 'General', defaults: '0', parent: 'legend', width: 50 }, { id: 'legend--borderRadius', pid: 'legend.borderRadius', dataType: 'number', context: 'General', defaults: '0', parent: 'legend', width: 50 } ] } ], 'option.cat.localization': [ { text: 'option.subcat.numberformat', dropdown: true, group: 1, options: [ { id: 'lang--decimalPoint', pid: 'lang.decimalPoint', dataType: 'string', context: 'General', defaults: '.', parent: 'lang', width: 50 }, { id: 'lang--thousandsSep', pid: 'lang.thousandsSep', dataType: 'string', context: 'General', defaults: ' ', parent: 'lang', width: 50 } ] }, { text: 'option.subcat.zoombutton', dropdown: true, group: 1, options: [ { id: 'lang--resetZoom', pid: 'lang.resetZoom', dataType: 'string', context: 'General', defaults: 'Reset zoom', parent: 'lang' } ] }, { text: 'option.subcat.exportbutton', dropdown: true, options: [ { id: 'lang--contextButtonTitle', pid: 'lang.contextButtonTitle', dataType: 'string', context: 'General', defaults: 'Chart context menu', parent: 'lang', values: '', width: 50 }, { id: 'lang--printChart', pid: 'lang.printChart', dataType: 'string', context: 'General', defaults: 'Print chart', parent: 'lang', values: '', width: 50 }, { id: 'lang--downloadPNG', pid: 'lang.downloadPNG', dataType: 'string', context: 'General', defaults: 'Download PNG image', parent: 'lang', width: 50 }, { id: 'lang--downloadJPEG', pid: 'lang.downloadJPEG', dataType: 'string', context: 'General', defaults: 'Download JPEG image', parent: 'lang', width: 50 }, { id: 'lang--downloadPDF', pid: 'lang.downloadPDF', dataType: 'string', context: 'General', defaults: 'Download PDF document', parent: 'lang', width: 50 }, { id: 'lang--downloadSVG', pid: 'lang.downloadSVG', dataType: 'string', context: 'General', defaults: 'Download SVG vector image', parent: 'lang', width: 50 } ] } ], } }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format highed.meta.charttype = { arearange: { 'low': { 'name': "Low", 'desc': 'The low or minimum value for each data point.', 'default': 'B', 'value': 'B', 'mandatory': true, 'linkedTo': 'low', 'rawValue': [1] }, 'values': null, 'high': { 'name': "High", 'desc': 'The high or maximum value for each data point.', 'default': 'C', 'value': 'C', 'isData': true, 'mandatory': true, 'linkedTo': 'high', 'rawValue': [2] } }, boxplot: { 'low': { 'name': "Low", 'desc': 'The low value for each data point, signifying the lowest value in the sample set. The bottom whisker is drawn here.', 'default': 'B', 'value': 'B', 'isData': true, 'mandatory': true, 'linkedTo': 'low', 'rawValue': [1] }, 'values': null, 'high': { 'name': "High", 'desc': 'The rank for this points data label in case of collision. If two data labels are about to overlap, only the one with the highest labelrank will be drawn.', 'default': 'C', 'value': 'C', 'isData': true, 'mandatory': true, 'linkedTo': 'high', 'rawValue': [2] }, 'median': { 'name': "Median", 'desc': 'The median for each data point. This is drawn as a line through the middle area of the box.', 'default': 'D', 'value': 'D', 'mandatory': true, 'isData': true, 'linkedTo': 'median', 'rawValue': [3] }, 'q1': { 'name': "Q1", 'desc': 'The lower quartile for each data point. This is the bottom of the box.', 'default': 'E', 'value': 'E', 'mandatory': true, 'multipleValues': false, 'isData': true, 'previousValue': null, 'linkedTo': 'q1', 'rawValue': [4] }, 'q3': { 'name': "Q3", 'desc': 'The higher quartile for each data point. This is the top of the box.', 'default': 'F', 'value': 'F', 'mandatory': true, 'isData': true, 'linkedTo': 'q3', 'rawValue': [4] } }, candlestick: { 'values': null, 'close': { 'name': "Close", 'desc': 'The closing value of each data point.', 'default': 'B', 'value': 'B', 'mandatory': true, 'linkedTo': 'close', 'isData': true, 'rawValue': [1] }, 'open': { 'name': "Open", 'desc': 'The opening value of each data point.', 'default': 'C', 'value': 'C', 'mandatory': true, 'isData': true, 'linkedTo': 'open', 'rawValue': [2] }, 'low': { 'name': "Low", 'desc': 'The low or minimum value for each data point.', 'default': 'D', 'value': 'D', 'multipleValues': false, 'previousValue': null, 'mandatory': true, 'isData': true, 'linkedTo': 'low', 'rawValue': [3] }, 'high': { 'name': "High", 'desc': 'The high or maximum value for each data point.', 'default': 'E', 'value': 'E', 'mandatory': true, 'isData': true, 'linkedTo': 'high', 'rawValue': [4] } }, bubble: { 'values': null, 'y': { 'name': "Y", 'desc': 'Y Position', 'default': 'B', 'value': 'B', 'mandatory': true, 'isData': true, 'linkedTo': 'y', 'rawValue': [1] }, 'z': { 'name': "Z", 'desc': 'Z Position.', 'default': 'C', 'value': 'C', 'mandatory': true, 'isData': true, 'linkedTo': 'z', 'rawValue': [2] } }, columnrange: { 'values': null, 'low': { 'name': "Low", 'desc': 'The low or minimum value for each data point.', 'default': 'B', 'value': 'B', 'mandatory': true, 'isData': true, 'linkedTo': 'low', 'rawValue': [1] }, 'high': { 'name': "High", 'desc': 'The high or maximum value for each data point.', 'default': 'C', 'value': 'C', 'mandatory': true, 'isData': true, 'linkedTo': 'high', 'rawValue': [2] } }, }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format highed.meta.colors = [ //Red '#F44336', '#FFEBEE', '#FFCDD2', '#EF9A9A', '#E57373', '#EF5350', '#F44336', '#E53935', '#D32F2F', '#C62828', '#B71C1C', '#FF8A80', '#FF5252', '#FF1744', '#D50000', //Pink '#E91E63', '#FCE4EC', '#F8BBD0', '#F48FB1', '#F06292', '#EC407A', '#E91E63', '#D81B60', '#C2185B', '#AD1457', '#880E4F', '#FF80AB', '#FF4081', '#F50057', '#C51162', //Purple '#9C27B0', '#F3E5F5', '#E1BEE7', '#CE93D8', '#BA68C8', '#AB47BC', '#9C27B0', '#8E24AA', '#7B1FA2', '#6A1B9A', '#4A148C', '#EA80FC', '#E040FB', '#D500F9', '#AA00FF', //Deep Purple '#673AB7', '#EDE7F6', '#D1C4E9', '#B39DDB', '#9575CD', '#7E57C2', '#673AB7', '#5E35B1', '#512DA8', '#4527A0', '#311B92', '#B388FF', '#7C4DFF', '#651FFF', '#6200EA', //Indigo '#3F51B5', '#E8EAF6', '#C5CAE9', '#9FA8DA', '#7986CB', '#5C6BC0', '#3F51B5', '#3949AB', '#303F9F', '#283593', '#1A237E', '#8C9EFF', '#536DFE', '#3D5AFE', '#304FFE', //Blue '#2196F3', '#E3F2FD', '#BBDEFB', '#90CAF9', '#64B5F6', '#42A5F5', '#2196F3', '#1E88E5', '#1976D2', '#1565C0', '#0D47A1', '#82B1FF', '#448AFF', '#2979FF', '#2962FF', //Light Blue '#03A9F4', '#E1F5FE', '#B3E5FC', '#81D4FA', '#4FC3F7', '#29B6F6', '#03A9F4', '#039BE5', '#0288D1', '#0277BD', '#01579B', '#80D8FF', '#40C4FF', '#00B0FF', '#0091EA', //Cyan '#00BCD4', '#E0F7FA', '#B2EBF2', '#80DEEA', '#4DD0E1', '#26C6DA', '#00BCD4', '#00ACC1', '#0097A7', '#00838F', '#006064', '#84FFFF', '#18FFFF', '#00E5FF', '#00B8D4', //Teal '#009688', '#E0F2F1', '#B2DFDB', '#80CBC4', '#4DB6AC', '#26A69A', '#009688', '#00897B', '#00796B', '#00695C', '#004D40', '#A7FFEB', '#64FFDA', '#1DE9B6', '#00BFA5', //Green '#4CAF50', '#E8F5E9', '#C8E6C9', '#A5D6A7', '#81C784', '#66BB6A', '#4CAF50', '#43A047', '#388E3C', '#2E7D32', '#1B5E20', '#B9F6CA', '#69F0AE', '#00E676', '#00C853', //Light Green '#8BC34A', '#F1F8E9', '#DCEDC8', '#C5E1A5', '#AED581', '#9CCC65', '#8BC34A', '#7CB342', '#689F38', '#558B2F', '#33691E', '#CCFF90', '#B2FF59', '#76FF03', '#64DD17', //Lime '#CDDC39', '#F9FBE7', '#F0F4C3', '#E6EE9C', '#DCE775', '#D4E157', '#CDDC39', '#C0CA33', '#AFB42B', '#9E9D24', '#827717', '#F4FF81', '#EEFF41', '#C6FF00', '#AEEA00', //Yellow '#FFEB3B', '#FFFDE7', '#FFF9C4', '#FFF59D', '#FFF176', '#FFEE58', '#FFEB3B', '#FDD835', '#FBC02D', '#F9A825', '#F57F17', '#FFFF8D', '#FFFF00', '#FFEA00', '#FFD600', //Amber '#FFC107', '#FFF8E1', '#FFECB3', '#FFE082', '#FFD54F', '#FFCA28', '#FFC107', '#FFB300', '#FFA000', '#FF8F00', '#FF6F00', '#FFE57F', '#FFD740', '#FFC400', '#FFAB00', //Orange '#FF9800', '#FFF3E0', '#FFE0B2', '#FFCC80', '#FFB74D', '#FFA726', '#FF9800', '#FB8C00', '#F57C00', '#EF6C00', '#E65100', '#FFD180', '#FFAB40', '#FF9100', '#FF6D00', //Deep Orange '#FF5722', '#FBE9E7', '#FFCCBC', '#FFAB91', '#FF8A65', '#FF7043', '#FF5722', '#F4511E', '#E64A19', '#D84315', '#BF360C', '#FF9E80', '#FF6E40', '#FF3D00', '#DD2C00', //Brown '#795548', '#EFEBE9', '#D7CCC8', '#BCAAA4', '#A1887F', '#8D6E63', '#795548', '#6D4C41', '#5D4037', '#4E342E', '#3E2723', '#3E2723', '#3E2723', '#3E2723', '#3E2723', //Grey '#9E9E9E', '#FAFAFA', '#F5F5F5', '#EEEEEE', '#E0E0E0', '#BDBDBD', '#9E9E9E', '#757575', '#616161', '#424242', '#212121', '#212121', '#212121', '#212121', //Blue Grey '#607D8B', '#ECEFF1', '#CFD8DC', '#B0BEC5', '#90A4AE', '#78909C', '#607D8B', '#546E7A', '#455A64', '#37474F', '#37474F', '#37474F', '#37474F', '#263238' ]; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format highed.meta.fonts = [ 'Default', //'"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif', 'Courier', 'Arial', 'Verdana', 'Georgia', 'Palatino Linotype', 'Times New Roman', 'Comic Sans MS', 'Impact', 'Lucida Sans Unicode', 'Tahoma', 'Lucida Console', 'Courier New', 'Monaco', 'Monospace' ]; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ highed.highchartsErrors = { // Plotting zero or subzero value on a log axis 10: { title: "Can't plot zero or subzero values on a logarithmic axis", text: 'This error occurs in the following situations:
  • If a zero or subzero data value is added to a logarithmic axis
  • If the minimum of a logarithimic axis is set to 0 or less
  • If the threshold is set to 0 or less
As of Highcharts 5.0.8 it is possible to bypass this error message by setting Axis.prototype.allowNegativeLog totrue and add custom conversion functions. View live demo.' }, // Can't link axes of different types 11: { title: "Can't link axes of different type", text: 'This error occurs if you are using the linkedTo option to link two axes of different types, for example a logarithmic axis to a linear axis.' }, // series.data needs to be arrays or numbers when in turbo mode 12: { title: 'Highcharts expects point configuration to be numbers or arrays in turbo mode', text: 'This error occurs if the series data option contains object configurations and the number of points exceeds the turboThreshold. It can be fixed by either setting the turboThreshold option to a higher value' }, // Rendering div not found 13: { title: 'Rendering div not found', text: 'Highcharts cannot find a parent to render to' }, // Expected number, got string 14: { title: 'String value sent to series.data, expected Number', text: 'Highcharts expects there to be a number in the column you just entered. Please change this to a number to continue' }, // Expected sorted data, got non-sorted 15: { title: 'Highcharts expects data to be sorted', text: 'The data passed to your chart needs to be sorted. If you\'re using the datagrid, you can sort your data by clicking the arrow in the x-axis column header, and selecting "Sort Ascending".' }, // Highcharts already defined 16: { title: 'Highcharts already defined in the page', text: 'Highcharts has already been defined in the page. Keep in mind that all features of Highcharts are included in Highstock' }, // Requested type doesn't exist 17: { title: 'The requested series type does not exist', text: 'This error happens when you are setting chart.type or series.type to a series type that isnt defined in Highcharts.' }, // Requested axis doesn't exist 18: { title: 'The requested axis does not exist', text: 'Make sure that your only references existing axis in the series properties.' }, // Too many ticks (use bug spray) <- ¬_¬ 19: { title: 'Too many ticks', text: 'This error happens when you try to apply too many ticks to an axis, specifically when you add more ticks than the axis pixel length.' }, // Can't add point config to a long data series 20: { title: "Can't add object point configuration to a long data series", text: 'In Highstock, if you try to add a point using the object literal configuration syntax, it works only when the number of data points is below the series turboThreshold. Instead of the object syntax, use the Array syntax.' }, // Can't find Proj4js library 21: { title: "Can't find Proj4js library", text: 'Using latitude/longitude functionality in Highmaps requires the Proj4js library to be loaded.' }, // Map does not support lat/long 22: { title: 'Map does not support latitude/longitude', text: 'The loaded map does not support latitude/longitude functionality. This is only supported with maps from the official Highmaps map collection from version 1.1.0 onwards. If you are using a custom map, consider using the Proj4js library to convert between projections.' }, // Unsupported color format used for color 23: { title: 'Unsupported color format used for color interpolation', text: 'Highcharts supports three color formats primarily: hex (#FFFFFF), rgb (rgba(255,255,255) and rgba (rgba(255,255,255,1).' }, // Cannot run Point.update on a grouped point 24: { title: 'Cannot run Point.update on a grouped point', text: 'This happens in Highstock when a point is grouped by data grouping, so there is no reference to the raw points.' }, // Can't find moment.js 25: { title: "Can't find Moment.js library", text: 'Using the global.timezone option requires the Moment.js library to be loaded.' }, // WebGL not supported 26: { title: 'WebGL not supported, and no fallback module included', text: 'This happens when your browser does not support WebGL, and the canvas fallback module (boost-canvas.js) has not been included OR if the fallback module was included after the boost module.' }, // Browser does not support SVG 27: { title: 'This browser does not support SVG.', text: 'This happens in old IE when the oldie.js module is not loaded.' } }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** UI for selecting a chart template from the ones defined in meta/highed.meta.charts.js * * @example * var picker = highed.ChartTemplateSelector(document.body); * picker.on('Select', function (template) { * console.log('Selected new template:', template); * }); * * @constructor * * @param parent {domnode} - the parent to attach the selector to * * @emits Select - when selecting a template * > {object} - the template definition * @emits Hover - when hovering a template * > {object} - the template definition */ highed.ChartTemplateSelector = function(parent, chartPreview) { var events = highed.events(), container = highed.dom.cr('div', 'highed-chart-templates'), //splitter = highed.HSplitter(container, { leftWidth: 30 }), //list = highed.List(splitter.left), //templates = splitter.right, templates = highed.dom.cr('div', 'highed-chart-template-type-container'), catNode = highed.dom.cr('div', 'highed-chart-template-cat-desc'), selected = false, templateTypeSelect = highed.DropDown(container, null, { area: highed.resources.icons.area, line: highed.resources.icons.line, bar: highed.resources.icons.bar, column: highed.resources.icons.column, more: highed.resources.icons.more, pie: highed.resources.icons.pie, polar: highed.resources.icons.polar, stock: highed.resources.icons.stock, 'scatter and bubble': highed.resources.icons['scatter and bubble'] }), detailValue; highed.dom.ap(parent, highed.dom.ap(container, templates)); //splitter.right.className += ' highed-chart-template-frame'; /////////////////////////////////////////////////////////////////////////// function createSampleBtn(target, sample) { var btn, dset = highed.samples.get(sample); if (!dset) { return; } btn = sampleBtn = highed.dom.cr('div', 'highed-ok-button', dset.title); highed.dom.on(btn, 'click', function() { if ( confirm( 'You are about to load the ' + dset.title + ' sample set. This will purge any existing data in the chart. Continue?' ) ) { events.emit('LoadDataSet', dset); } }); highed.dom.ap(target, btn); } function buildCatMeta(catmeta) { var title = highed.dom.cr('h3', '', catmeta.id), desc = highed.dom.cr('div'), samples = highed.dom.cr('div'); desc.innerHTML = highed.isArr(catmeta.description) ? catmeta.description.join('

') : catmeta.description || ''; if (catmeta.samples && catmeta.samples.length > 0) { highed.dom.ap(samples, highed.dom.cr('h4', '', 'Sample Data Sets')); catmeta.samples.forEach(function(sample) { createSampleBtn(samples, sample); }); } highed.dom.ap(title, desc, samples); } function showTemplates(templateList, masterID, catmeta) { var compatible = 0; templates.innerHTML = ''; catNode.innerHTML = ''; if (catmeta) { buildCatMeta(catmeta); } highed.dom.ap(templates); Object.keys(templateList).forEach(function(key) { var t = templateList[key], node = highed.dom.cr('div', 'highed-chart-template-container highed-template-tooltip'), body = highed.dom.cr('div', 'highed-chart-template-body'), preview = highed.dom.cr('div', 'highed-chart-template-thumbnail'), titleBar = highed.dom.cr('div', 'highed-tooltip-text', t.title), description = highed.dom.cr('div', 'highed-chart-template-description'), samples = highed.dom.cr('div', 'highed-chart-template-samples'); if (t.validator) { if (!highed.validators.validate(t.validator, chartPreview || false)) { return; } } compatible++; (highed.isArr(t.sampleSets) ? t.sampleSets : (t.sampleSets || '').split('.') ).forEach(function(sample, i) { if (i === 0) { highed.dom.ap(samples, highed.dom.cr('h4', '', 'Sample Data Sets')); } createSampleBtn(samples, sample); }); description.innerHTML = highed.isArr(t.description) ? t.description.join('

') : t.description; if (selected && selected.id === masterID + key + t.title) { node.className = 'highed-chart-template-container highed-chart-template-preview-selected highed-template-tooltip'; selected.node = node; } if (highed.meta.images && highed.meta.images[t.thumbnail]) { highed.dom.style(preview, { 'background-image': 'url("data:image/svg+xml;utf8,' + highed.meta.images[t.thumbnail] + '")' }); } else { highed.dom.style(preview, { 'background-image': 'url(' + highed.option('thumbnailURL') + t.thumbnail + ')' }); } highed.dom.on(node, 'click', function() { if (selected) { selected.node.className = 'highed-chart-template-container highed-template-tooltip'; } node.className = 'highed-chart-template-container highed-chart-template-preview-selected highed-template-tooltip'; selected = { id: masterID + key + t.title, node: node }; // If this is a map, we need to include the map collection if (t.constructor === 'Map') { var loadedSeries = 0; (t.config.series || []).forEach(function(series) { function incAndCheck() { loadedSeries++; if (loadedSeries === t.config.series.length) { events.emit('Select', t); } } if (series.mapData) { if (highed.isStr(series.mapData)) { highed.include( 'https://code.highcharts.com/mapdata/' + series.mapData + '.js', function() { series.mapData = Highcharts.maps[series.mapData]; incAndCheck(); } ); } else { incAndCheck(); } } else { incAndCheck(); } }); } else { t.header = templateTypeSelect.getSelectedItem().title(); events.emit('Select', highed.merge({}, t)); } highed.emit('UIAction', 'TemplateChoose', t.title); }); highed.dom.ap( templates, highed.dom.ap( node, preview, titleBar/*, highed.dom.ap( body, titleBar//, //description, // highed.dom.cr('h4', '', 'Sample Data Sets'), //samples )*/ ) ); }); if (compatible === 0) { highed.dom.ap( templates, highed.dom.ap( highed.dom.cr('div', 'highed-chart-template-404'), highed.dom.cr( 'h4', '', 'None of the templates in this category fits your dataset.' ), highed.dom.cr('div', '', catmeta ? catmeta.nofits || '' : '') ) ); } else { } } /* Force a resize */ function resize(w, h) { var lsize; //splitter.resize(w, h); //list.resize(); /* lsize = highed.dom.size(list.container); highed.dom.style(templates, { minHeight: lsize.h + 'px' });*/ } /* Build the UI */ function build() { templateTypeSelect.addItems(highed.templates.getCatArray()); templateTypeSelect.selectByIndex(0); // TODO: Need to change this later //highed.dom.ap(container, templateTypeSelect); //list.addItems(highed.templates.getCatArray()); //list.selectFirst(); } function selectSeriesTemplate(index, projectData) { const settings = projectData; //projectData.settings && projectData.settings.template; var templateHeader, templateTitle; if (settings && !settings[index]) { templateHeader = 'Line'; templateTitle = 'Line chart'; } else if (settings && settings[index]) { //Select this template templateHeader = settings[index].templateHeader; templateTitle = settings[index].templateTitle; } else return ; templateTypeSelect.selectById(templateHeader); var templates = highed.templates.getAllInCat(templateHeader); selected = { id: templateHeader + templateTitle + templateTitle }; if (templates) { showTemplates(templates, templateHeader, highed.templates.getCatInfo(templateHeader)); } } /////////////////////////////////////////////////////////////////////////// templateTypeSelect.on('Change', function(selected) { detailValue = selected.id(); var templates = highed.templates.getAllInCat(detailValue); highed.emit('UIAction', 'TemplateCatChoose', detailValue); if (templates) { showTemplates(templates, detailValue, highed.templates.getCatInfo(detailValue)); } }); /* list.on('Select', function(id) { var templates = highed.templates.getAllInCat(id); highed.emit('UIAction', 'TemplateCatChoose', id); if (templates) { showTemplates(templates, id, highed.templates.getCatInfo(id)); } }); */ build(); /////////////////////////////////////////////////////////////////////////// return { on: events.on, resize: resize, rebuild: build, selectSeriesTemplate: selectSeriesTemplate }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** Create an instance of the default context menu * This is shared accross the simple and full editor. * @constructor * @param chartPreview {highed.ChartPreview} - the chart preview for the menu */ highed.DefaultContextMenu = function(chartPreview) { var events = highed.events(), cmenu = highed.ContextMenu([ { title: highed.getLocalizedStr('previewChart'), icon: 'bar-chart', click: function() { chartPreview.expand(); } }, '-', { title: highed.getLocalizedStr('newChart'), icon: 'file-o', click: function() { if (window.confirm(highed.getLocalizedStr('confirmNewChart'))) { chartPreview.new(); events.emit('NewChart'); } } }, '-', { title: highed.getLocalizedStr('saveProject'), icon: 'floppy-o', click: function() { highed.download('chart.json', chartPreview.toProjectStr()); } }, { title: highed.getLocalizedStr('loadProject'), icon: 'folder-open-o', click: function() { highed.readLocalFile({ type: 'text', accept: '.json', success: function(file) { try { file = JSON.parse(file.data); } catch (e) { return highed.snackBar('Error loading JSON: ' + e); } chartPreview.loadProject(file); } }); } }, '-', { title: 'Save to Cloud', icon: 'upload', click: function() { highed.cloud.save(chartPreview); } }, { title: highed.getLocalizedStr('loadCloud'), icon: 'cloud', click: function() { highed.cloud.showUI(chartPreview); } }, '-', { title: highed.getLocalizedStr('exportPNG'), icon: 'file-image-o', click: function() { chartPreview.data.export({}); } }, { title: highed.getLocalizedStr('exportJPEG'), icon: 'file-image-o', click: function() { chartPreview.data.export({ type: 'image/jpeg' }); } }, { title: highed.getLocalizedStr('exportSVG'), icon: 'file-image-o', click: function() { chartPreview.data.export({ type: 'image/svg+xml' }); } }, { title: highed.getLocalizedStr('exportPDF'), icon: 'file-pdf-o', click: function() { chartPreview.data.export({ type: 'application/pdf' }); } }, '-', { title: highed.getLocalizedStr('help'), icon: 'question-circle', click: function() { window.open(highed.option('helpURL')); } } //, // { // title: highed.getLocalizedStr('licenseInfo'), // icon: 'key', // click: function () { // highed.licenseInfo.show(); // } // } ]); return { on: events.on, show: cmenu.show }; }; /****************************************************************************** Copyright (c) 2016-2017, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** UI For customizing a chart * @todo there be dragons here. * @example * var chart = highed.ChartCustomizer(document.body, {}, chartPreview); * * @constructor * * @emits PropertyChange - when a property changes * > {string} - the path of the change * > {anything} - the new value * > {number} - the change array index * * @param parent {domnode} - the node to attach the editor to * @param attributes {object} - the attributes * > noAdvanced {bool} - set to true to force disable the advance view * > noCustomCode {bool} - set to true to disable custom code view * > noPreview {bool} - set to true to disable option preview view * > availableSettings {string|array} - whitelist of exposed settings * @param chartPreview {ChartPreview} - the chart preview instance */ highed.ChartCustomizer = function(parent, attributes, chartPreview, planCode) { var properties = highed.merge( { noAdvanced: false, noCustomCode: false, noPreview: false, availableSettings: [] }, attributes ), events = highed.events(), advancedLoader = highed.dom.cr( 'div', 'highed-customizer-adv-loader', ' Loading' ), tabs = highed.TabControl(parent, false, null, true), //Quck fix for now, will change once design finalised. simpleTab = tabs.createTab({ title: highed.getLocalizedStr('customizeSimple') }), advancedTab = tabs.createTab({ title: highed.getLocalizedStr('customizeAdvanced') }), customCodeTab = tabs.createTab({ title: highed.getLocalizedStr('customizeCustomCode') }), outputPreviewTab = tabs.createTab({ title: highed.getLocalizedStr('customizePreview') }), previewEditor = highed.dom.cr( 'textarea', 'highed-custom-code highed-box-size highed-stretch' ), previewCodeMirror = false, splitter = highed.dom.cr('div', 'highed-box-simple-container'), allOptions, /* splitter = highed.HSplitter(simpleTab.body, { leftWidth: 100, rightWidth: 100, responsive: true }), */ list = highed.List(splitter, true, properties, planCode), body = highed.dom.cr('div'),//splitter.right, advSplitter = highed.HSplitter(advancedTab.body, { leftWidth: 30 }), advBody = advSplitter.right, advTree = highed.Tree(advSplitter.left), flatOptions = {}, chartOptions = {}, customCodeSplitter = highed.VSplitter(customCodeTab.body, { topHeight: 90 }), customCodeDebug = highed.dom.cr('pre', 'highed-custom-debug'), codeMirrorBox = false, customCodeBox = highed.dom.cr( 'textarea', 'highed-custom-code highed-box-size highed-stretch' ), highlighted = false; //If we're on mobile, completely disable the advanced view if (highed.onPhone()) { properties.noAdvanced = true; properties.noCustomCode = true; properties.noPreview = true; } body.className += ' highed-customizer-body'; properties.availableSettings = highed.arrToObj(properties.availableSettings); highed.dom.ap(simpleTab.body, splitter); highed.dom.ap(parent, advancedLoader); highed.dom.ap(outputPreviewTab.body, previewEditor); /////////////////////////////////////////////////////////////////////////// advancedTab.on('Focus', function() { buildTree(); }); outputPreviewTab.on('Focus', function() { var prev = chartPreview.options.getPreview(); if (!previewCodeMirror && typeof window.CodeMirror !== 'undefined') { previewCodeMirror = CodeMirror.fromTextArea(previewEditor, { lineNumbers: true, mode: 'application/javascript', theme: highed.option('codeMirrorTheme'), readOnly: true }); previewCodeMirror.setSize('100%', '100%'); } if (previewCodeMirror) { previewCodeMirror.setValue(prev); } else { previewEditor.readonly = true; previewEditor.value = prev; } }); function loadCustomCode() { var code; if (chartPreview) { code = chartPreview.getCustomCode() || ''; if (codeMirrorBox) { codeMirrorBox.setValue(code); } else { customCodeBox.value = code; } } } /** * Init the custom code stuff */ function initCustomCode() { // Build the custom code tab highed.dom.ap(customCodeSplitter.top, customCodeBox); highed.dom.ap(customCodeSplitter.bottom, customCodeDebug); function setCustomCode() { highed.emit('UIAction', 'CustomCodeUpdate'); customCodeDebug.innerHTML = ''; if (chartPreview) { chartPreview.on('LoadCustomCode', function(options) { var code; if (chartPreview) { code = chartPreview.getCustomCode() || ''; if (codeMirrorBox) { codeMirrorBox.setValue(code); } else { customCodeBox.value = code; } } }); chartPreview.on('UpdateCustomCode', function() { chartPreview.setCustomCode( codeMirrorBox ? codeMirrorBox.getValue() : customCodeBox.value, function(err) { customCodeDebug.innerHTML = err; } ); }); chartPreview.setCustomCode( codeMirrorBox ? codeMirrorBox.getValue() : customCodeBox.value, function(err) { customCodeDebug.innerHTML = err; } ); } } var timeout = null; if (typeof window['CodeMirror'] !== 'undefined') { codeMirrorBox = CodeMirror.fromTextArea(customCodeBox, { lineNumbers: true, mode: 'application/javascript', theme: highed.option('codeMirrorTheme') }); codeMirrorBox.setSize('100%', '100%'); codeMirrorBox.on('change', function() { clearTimeout(timeout); timeout = setTimeout(function () { setCustomCode(); }, 500); }); } else { highed.dom.on(customCodeBox, 'change', function() { clearTimeout(timeout); timeout = setTimeout(function () { setCustomCode(); }, 500); }); } } /** Force a resize of the editor * @memberof highed.ChartCustomizer * @param w {number} - the new width * @param h {number} - the new height */ function resize(w, h) { var bsize, lsize; tabs.resize(w, h); bsize = tabs.barSize(); list.resize(w, h - bsize.h); //splitter.resize(w, h - bsize.h - 10); //The customize body needs to have a min-height of the list height lsize = highed.dom.size(list.container); highed.dom.style(body, { minHeight: lsize.h + 'px' }); customCodeSplitter.resize(w, h); if (codeMirrorBox) { codeMirrorBox.refresh(); } } /** Init the customizer * @memberof highed.ChartCustomizer * @param foptions {object} - the customized options * @param coptions {object} - the full chart options */ function init(foptions, coptions, chartp) { flatOptions = coptions || {}; chartOptions = highed.merge({}, foptions || {}); list.reselect(); // buildTree(); chartPreview = chartp || chartPreview; customCodeSplitter.resize(); loadCustomCode(); } function shouldInclude(group) { var doInclude = false; if (Object.keys(properties.availableSettings || {}).length > 0) { if (highed.isArr(group)) { group.forEach(function(sub) { if (shouldInclude(sub)) { doInclude = true; } }); } else if (highed.isArr(group.options)) { group.options.forEach(function(sub) { if (shouldInclude(sub)) { doInclude = true; } }); } else if ( properties.availableSettings[group.id] || properties.availableSettings[group.pid] ) { doInclude = true; } return doInclude; } return true; } function buildTree() { if (properties.noAdvanced) { return; } highed.dom.style(advancedLoader, { opacity: 1 }); if (properties.noAdvanced || highed.isNull(highed.meta.optionsAdvanced)) { advancedTab.hide(); } else { setTimeout(function() { highed.meta.optionsAdvanced = highed.transform.advanced( highed.meta.optionsAdvanced, true ); const series = chartPreview.options.all().series; allOptions = highed.merge({}, chartPreview.options.full);//highed.merge({}, chartPreview.options.getCustomized()); if (series && series.length > 0) { series.forEach(function(serie, i) { if (allOptions.series && allOptions.series[i]){ highed.merge(allOptions.series[i], { type: serie.type || 'line' }); } }); advTree.build( highed.meta.optionsAdvanced, allOptions ); highed.dom.style(advancedLoader, { opacity: 0 }); events.emit("AdvancedBuilt"); } }, 10); } } function build() { Object.keys(highed.meta.optionsExtended.options).forEach(function(key) { if (!shouldInclude(highed.meta.optionsExtended.options[key])) { return; } list.addItem({ id: key, title: highed.L(key) }, highed.meta.optionsExtended.options[key], chartPreview); }); /* list.addItem({ id: "Annotations", annotations: true, title: "Annotations ", onClick: function() { events.emit("AnnotationsClicked"); } }, null, chartPreview);*/ // buildTree(); } //Highlight a node function highlightNode(n, x, y) { if (!n) return; var p = highed.dom.pos(n); if (!simpleTab.selected) { simpleTab.focus(); } n.focus(); /* n.scrollIntoView({ inline: 'nearest' });*/ // Draw a dot where the item was clicked var attention = highed.dom.cr('div', 'highed-attention'); highed.dom.style(attention, { width: '10px', height: '10px', left: x - 5 + 'px', top: y - 5 + 'px', borderRadius: '50%' }); highed.dom.ap(document.body, attention); // Animate it to the corresponding element var pos = Highcharts.offset(n); var bgColor = n.style.backgroundColor; highed.dom.style(attention, { width: n.clientWidth + 'px', height: n.clientHeight + 'px', borderRadius: 0, left: pos.left + 'px', top: pos.top + 'px' }); window.setTimeout(function() { highed.dom.style(n, { backgroundColor: window.getComputedStyle(attention).backgroundColor, transition: '1s ease background-color' }); attention.parentNode.removeChild(attention); attention = null; window.setTimeout(function() { highed.dom.style(n, { backgroundColor: bgColor }); }, 250); }, 350); } ////////////////////////////////////////////////////////////////////////////// // P U B L I C F U N S /** Highlight a field in the customizer * @memberof highed.ChartCustomizer * @param id {string} - is the id of the field to highlight * @param x {number} - the x coordinate where the focus was triggered * @param y {number} - the y coordinate where the focus was triggered */ function highlightField(id, x, y) { if (id.indexOf('-') >= 0) { var n = advSplitter.left.querySelector( '#' + id.substr(0, id.indexOf('-')) ); highlightNode(simpleTab.body.querySelector('#' + id), x, y); highlightNode(advSplitter.right.querySelector('#' + id)); if (n) { n.scrollIntoView({ block: 'end' }); } } } /** Focus a category * @memberof highed.ChartCustomizer * @param thing {anything} - the category to focus * @param x {number} - the x coordinate where the focus was triggered * @param y {number} - the y coordinate where the focus was triggered */ function focus(thing, x, y) { var n; list.select(thing.tab); list.selectDropdown(thing.dropdown); advTree.expandTo(thing.id); highlightField(thing.id, x, y); } /////////////////////////////////////////////////////////////////////////// list.on('PropertyChange', function(groupId, newValue, detailIndex) { events.emit("PropertyChange", groupId, newValue, detailIndex); }); list.on('TogglePlugins', function(groupId, newValue) { events.emit("TogglePlugins", groupId, newValue); }); list.on('Select', function(id) { var entry = highed.meta.optionsExtended.options[id]; body.innerHTML = ''; entry.forEach(function(thing) { //selectGroup(thing); }); highlighted = false; highed.emit('UIAction', 'SimplePropCatChoose', id); }); function buildAdvTree(item, selected, instancedData, filter, propFilter) { var table = highed.dom.cr('table', 'highed-customizer-table'), componentCount = 0; advBody.innerHTML = ''; if (properties.noAdvanced) { return; } item.children.forEach(function(entry) { if (!entry.meta.leafNode) { return; } // Skip functions for now if (Object.keys(entry.meta.types)[0] === 'function') { return; } if (propFilter && entry.meta.validFor) { if (!entry.meta.validFor[propFilter]) { // console.log('filtered', entry.meta.name, 'based on', propFilter); return false; } } if ( filter && entry.meta.products && Object.keys(entry.meta.products) > 0 && !entry.meta.products[filter] ) { return; } componentCount++; entry.values = entry.meta.enumValues; highed.dom.ap( table, highed.InspectorField( entry.values ? 'options' : Object.keys(entry.meta.types)[0] || 'string', typeof instancedData[entry.meta.name] !== 'undefined' ? instancedData[entry.meta.name] : entry.meta.default, //(highed.getAttr(chartOptions, entry.id) || entry.defaults), { title: highed.uncamelize(entry.meta.name), tooltip: entry.meta.description, values: entry.meta.enumValues, defaults: entry.meta.default, custom: {}, attributes: entry.attributes || [] }, function(newValue) { if (typeof newValue === 'string') newValue = newValue.replace('', '<\\/script>'); //Bug in cloud highed.emit( 'UIAction', 'AdvancedPropSet', (entry.meta.ns ? entry.meta.ns + '.' : '') + highed.uncamelize(entry.meta.name), newValue ); instancedData[entry.meta.name] = newValue; events.emit('PropertySetChange', advTree.getMasterData()); if (advTree.isFilterController(entry.meta.ns, entry.meta.name)) { buildTree(); } }, false, entry.meta.name, planCode ) ); }); highed.dom.ap( advBody, highed.dom.ap( highed.dom.cr('div', 'highed-customize-group highed-customize-advanced'), highed.dom.cr('div', 'highed-customizer-table-heading', selected), table ) ); } advTree.on('ForceSave', function(data) { events.emit('PropertySetChange', data); }); advTree.on('ClearSelection', function() { advBody.innerHTML = ''; }); advTree.on('Select', buildAdvTree); advTree.on('DataUpdate', function(path, data) { events.emit('PropertyChange', path, data); }); advTree.on('Dirty', function() { init(flatOptions, chartOptions); }); tabs.on('Focus', function() { init(flatOptions, chartOptions); }); build(); initCustomCode(); if (properties.noCustomCode) { customCodeTab.hide(); } if (properties.noAdvanced) { advancedTab.hide(); } if (properties.noPreview) { outputPreviewTab.hide(); } function showCustomCode() { customCodeTab.focus(); } function showSimpleEditor() { simpleTab.focus(); } function showPreviewOptions() { outputPreviewTab.focus(); } function showAdvancedEditor() { events.emit("AdvanceClicked"); advancedTab.focus(); } function getAdvancedOptions() { return allOptions; } return { /* Listen to an event */ on: events.on, resize: resize, init: init, focus: focus, reselect: list.reselect, highlightField: highlightField, showCustomCode: showCustomCode, showSimpleEditor: showSimpleEditor, showAdvancedEditor: showAdvancedEditor, showPreviewOptions: showPreviewOptions, getAdvancedOptions: getAdvancedOptions }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** This is a component that implements a toolbar with wizard steps * Proxies the interface of the WizardStepper object. * @constructor * @emits Step - when stepping back or forth * @emits AddStep - when adding a step to the stepper * @param parent {domnode} - the dom node to attach the UI to * @param bodyParent {domnode} - the dom node to attach the stepper body to * @param attributes {object} - options for the object */ highed.WizardBar = function(parent, bodyParent, attributes) { var toolbar = highed.Toolbar(parent, { additionalCSS: ['highed-wizstepper-bar'] }), stepper = highed.WizardStepper(bodyParent, toolbar.center), next = highed.dom.cr( 'span', 'highed-wizstepper-next-prev fa fa-arrow-right' ), previous = highed.dom.cr( 'span', 'highed-wizstepper-next-prev fa fa-arrow-left' ); /////////////////////////////////////////////////////////////////////////// function handleStepEvent(step, count) { if (step.number > 1) { highed.dom.style(previous, { opacity: 1, 'pointer-events': 'auto', visibility: 'visible' }); } else { highed.dom.style(previous, { opacity: 0, 'pointer-events': 'none', visibility: 'hidden' }); } if (step.number < count) { highed.dom.style(next, { opacity: 1, 'pointer-events': 'auto', visibility: 'visible' }); } else { highed.dom.style(next, { opacity: 0, 'pointer-events': 'none', visibility: 'hidden' }); } } stepper.on('Step', handleStepEvent); stepper.on('AddStep', handleStepEvent); highed.dom.on(next, 'click', stepper.next); highed.dom.on(previous, 'click', stepper.previous); /////////////////////////////////////////////////////////////////////////// highed.dom.ap(toolbar.right, next); highed.dom.ap(toolbar.left, previous); highed.dom.style(previous, { opacity: 0, 'pointer-events': 'none' }); return { /** The container which the bar is attached to * @type {domnode} * @memberof highed.WizardBar */ container: toolbar.container, on: stepper.on, next: stepper.next, previous: stepper.previous, addStep: stepper.addStep, selectFirst: stepper.selectFirst }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format (function() { var webImports = {}; highed.plugins.import = { /** Install a data import plugin * @namespace highed.plugins.import * @param name {string} - the name of the plugin * @param defintion {object} - the plugin definition * > description {string} - the plugin description * > treatAs {string} - what to treat the import as: `json|csv` * > fetchAs {string} - what the expect request return is * > defaultURL {string} - the default URL * > depdendencies {array} - set of additional javascript/css to include * > options {object} - additional user-supplied options * > label {string} - the title of the option * > type {string} - the type of the option * > default {string} - the default value * > filter {function} - function to call when executing the plugin * > url {anything} - request url * > options {object} - contains user-defined options * > callback {function} - function to call when the import is done */ install: function(name, defintion) { if (highed.isNull(webImports[name])) { webImports[name] = highed.merge( { title: false, description: '', treatAs: 'csv', fetchAs: 'json', defaultURL: '', dependencies: [], options: {}, filter: function() {} }, defintion ); if (webImports[name].dependencies) { webImports[name].dependencies.forEach(function(d) { highed.include(d); }); } } else { highed.log( 1, 'tried to register an import plugin which already exists:', name ); } } }; /** Data importer widget * * @example * var dimp = highed.DataImporter(document.body); * dimp.on('ImportCSV', function (data) { * console.log('Importing csv:', data.csv); * }); * * @constructor * * @emits ImportChartSettings - when importing chart settings * @emits ImportCSV - when importing CSV * @emits ImportJSON - when importing JSON * @param parent {domnode} - the node to attach the widget to * @param attributes {object} - the settings * > options {string} - the options to include: `csv json plugins samples` * > plugins {string} - the plugins to activate (must have been installed first) */ highed.DataImporter = function(parent, attributes) { var events = highed.events(), properties = highed.merge( { options: ['csv', 'plugins', 'samples', 'export'], plugins: ['CSV', 'JSON', 'Difi', 'Socrata', 'Google Spreadsheets'] }, attributes ), tabs = highed.TabControl(parent, false, true), csvTab = tabs.createTab({ title: 'Import' }), exportTab = tabs.createTab({ title: 'Export' }), jsonTab = tabs.createTab({ title: 'JSON' }), webTab = tabs.createTab({ title: 'Plugins' }), samplesTab = tabs.createTab({ title: 'Sample Data' }), csvPasteArea = highed.dom.cr('textarea', 'highed-imp-pastearea'), csvImportBtn = highed.dom.cr( 'button', 'highed-imp-button highed-imp-pasted-button', 'Import Pasted Data' ), liveDataImportBtn = highed.dom.cr('button', 'highed-imp-button', 'Live Data'), csvImportFileBtn = highed.dom.cr( 'button', 'highed-imp-button', 'Import File' ), delimiter = highed.dom.cr('input', 'highed-imp-input'), dateFormat = highed.dom.cr('input', 'highed-imp-input'), decimalPoint = highed.dom.cr('input', 'highed-imp-input'), firstAsNames = highed.dom.cr('input', 'highed-imp-input'), jsonPasteArea = highed.dom.cr('textarea', 'highed-imp-pastearea'), jsonImportBtn = highed.dom.cr('button', 'highed-imp-button', 'Import'), jsonImportFileBtn = highed.dom.cr( 'button', 'highed-imp-button', 'Upload & Import File' ), spreadsheetImportBtn = highed.dom.cr( 'button', 'highed-imp-button', 'Google Spreadsheet' ), commaDelimitedBtn = highed.dom.cr( 'button', 'highed-imp-button highed-export-btn', 'Export comma delimited' ), semicolonDelimitedBtn = highed.dom.cr( 'button', 'highed-imp-button highed-export-btn', 'Export semi-colon delimited' ), webSplitter = highed.HSplitter(webTab.body, { leftWidth: 30 }), webList = highed.List(webSplitter.left); jsonPasteArea.value = JSON.stringify({}, undefined, 2); setDefaultTabSize(600, 600, [csvTab, exportTab, jsonTab, webTab, samplesTab]); /////////////////////////////////////////////////////////////////////////// highed.dom.style(samplesTab.body, { overflow: 'hidden' }); properties.options = highed.arrToObj(properties.options); properties.plugins = highed.arrToObj(properties.plugins); //Remove referenced un-installed plugins. Object.keys(properties.plugins).forEach(function(plugin) { if (highed.isNull(webImports[plugin])) { delete properties.plugins[plugin]; } }); function setDefaultTabSize(w, h, tabs) { tabs.forEach(function (tab) { tab.on('Focus',function() { highed.dom.style(parent, { width: 600 + 'px', height: 600 + 'px' }); tab.resize(600 - 10, 600 - 10); }); }); } function updateOptions() { if (!properties.options.csv) { csvTab.hide(); } if (!properties.options.export) { exportTab.hide(); } //Always disable json options.. if (1 === 1 || !properties.options.json) { jsonTab.hide(); } if ( Object.keys(properties.plugins).length === 0 || !properties.options.plugins ) { webTab.hide(); } if (!properties.options.samples) { samplesTab.hide(); } tabs.selectFirst(); } function buildWebTab() { Object.keys(webImports).forEach(function(name) { if (!properties.plugins[name]) { return; } function buildBody() { var options = webImports[name], url = highed.dom.cr('input', 'highed-imp-input-stretch'), urlTitle = highed.dom.cr('div', '', 'URL'), importBtn = highed.dom.cr( 'button', 'highed-imp-button', 'Import ' + name + ' from URL' ), dynamicOptionsContainer = highed.dom.cr( 'table', 'highed-customizer-table' ), dynamicOptions = {}; url.value = options.defaultURL || ''; Object.keys(options.options || {}).forEach(function(name) { dynamicOptions[name] = options.options[name].default; highed.dom.ap( dynamicOptionsContainer, highed.InspectorField( options.options[name].type, options.options[name].default, { title: options.options[name].label }, function(nval) { dynamicOptions[name] = nval; }, true ) ); }); if (options.surpressURL) { highed.dom.style([url, urlTitle], { display: 'none' }); } url.placeholder = 'Enter URL'; highed.dom.on(importBtn, 'click', function() { highed.snackBar('Importing ' + name + ' data'); if (highed.isFn(options.request)) { return options.request(url.value, dynamicOptions, function( err, chartProperties ) { if (err) return highed.snackBar('import error: ' + err); events.emit( 'ImportChartSettings', chartProperties, options.newFormat ); }); } highed.ajax({ url: url.value, type: 'get', dataType: options.fetchAs || 'text', success: function(val) { options.filter(val, highed.merge({}, dynamicOptions), function( error, val ) { if (error) return highed.snackBar('import error: ' + error); if (options.treatAs === 'csv') { csvTab.focus(); csvPasteArea.value = val; emitCSVImport(val); } else { processJSONImport(val); } }); }, error: function(err) { highed.snackBar('import error: ' + err); } }); }); webSplitter.right.innerHTML = ''; highed.dom.ap( webSplitter.right, highed.dom.ap( highed.dom.cr('div', 'highed-plugin-details'), highed.dom.cr( 'div', 'highed-customizer-table-heading', options.title || name ), highed.dom.cr('div', 'highed-imp-help', options.description), urlTitle, url, Object.keys(options.options || {}).length ? dynamicOptionsContainer : false, highed.dom.cr('br'), importBtn ) ); } webList.addItem({ id: name, title: webImports[name].title || name, click: buildBody }); }); webList.selectFirst(); } function buildSampleTab() { samplesTab.innerHTML = ''; highed.samples.each(function(sample) { var data = sample.dataset.join('\n'), loadBtn = highed.dom.cr( 'button', 'highed-box-size highed-imp-button', sample.title ); highed.dom.style(loadBtn, { width: '99%' }); highed.dom.on(loadBtn, 'click', function() { emitCSVImport(data); csvPasteArea.value = data; csvTab.focus(); }); highed.dom.ap( samplesTab.body, //highed.dom.cr('div', '', name), //highed.dom.cr('br'), loadBtn, highed.dom.cr('br') ); }); } function emitCSVImport(csv, cb) { events.emit('ImportCSV', { itemDelimiter: delimiter.value, firstRowAsNames: firstAsNames.checked, dateFormat: dateFormat.value, csv: csv || csvPasteArea.value, decimalPoint: decimalPoint.value }, cb); } function loadCSVExternal(csv) { csvPasteArea.value = csv; emitCSVImport(); } function processJSONImport(jsonString) { var json = jsonString; if (highed.isStr(json)) { try { json = JSON.parse(jsonString); } catch (e) { highed.snackBar('Error parsing json: ' + e); return false; } } events.emit('ImportJSON', json); highed.snackBar('imported json'); } /** Force a resize of the widget * @memberof highed.DataImporter * @param w {number} - the new width * @param h {number} - the new height */ function resize(w, h) { var bsize, ps = highed.dom.size(parent); tabs.resize(w || ps.w, h || ps.h); bsize = tabs.barSize(); webSplitter.resize(w || ps.w, (h || ps.h) - bsize.h - 20); webList.resize(w || ps.w, (h || ps.h) - bsize.h); exporter.resize(null, 300); } /** Show the importer * @memberof highed.DataImporter */ function show() { tabs.show(); } /** Hide the importer * @memberof highed.DataImporter */ function hide() { tabs.hide(); } function addImportTab(tabOptions){ var newTab = tabs.createTab({ title: tabOptions.name || 'Features' }); if (highed.isFn(tabOptions.create)) { tabOptions.create(newTab.body); } if (tabOptions.resize) { newTab.on('Focus',function() { highed.dom.style(parent, { width: tabOptions.resize.width + 'px', height: tabOptions.resize.height + 'px' }); newTab.resize(tabOptions.resize.width - 10, tabOptions.resize.height - 10); }); } } function selectTab(index) { tabs.select(index); } /////////////////////////////////////////////////////////////////////////// highed.dom.ap( exportTab.body, commaDelimitedBtn, semicolonDelimitedBtn, highed.dom.cr('hr', 'highed-imp-hr') ); var exporter = highed.Exporter(exportTab.body); exporter.resize(null, 300); highed.dom.ap( csvTab.body, spreadsheetImportBtn, liveDataImportBtn, csvImportFileBtn, highed.dom.cr('hr', 'highed-imp-hr'), highed.dom.cr( 'div', 'highed-imp-help', 'Paste CSV into the below box, or upload a file. Click Import to import your data.' ), csvPasteArea, // highed.dom.cr('span', 'highed-imp-label', 'Delimiter'), // delimiter, // highed.dom.cr('br'), // highed.dom.cr('span', 'highed-imp-label', 'Date Format'), // dateFormat, // highed.dom.cr('br'), // highed.dom.cr('span', 'highed-imp-label', 'Decimal Point Notation'), // decimalPoint, // highed.dom.cr('br'), // highed.dom.cr('span', 'highed-imp-label', 'First Row Is Series Names'), // firstAsNames, // highed.dom.cr('br'), csvImportBtn ); highed.dom.ap( jsonTab.body, highed.dom.cr( 'div', 'highed-imp-help', 'Paste JSON into the below box, or upload a file. Click Import to import your data.
The JSON is the data passed to the chart constructor, and may contain any of the valid options.' ), jsonPasteArea, jsonImportFileBtn, jsonImportBtn ); highed.dom.on(commaDelimitedBtn, 'click', function(){ events.emit('ExportComma'); }); highed.dom.on(semicolonDelimitedBtn, 'click', function(){ events.emit('ExportSemiColon'); }); highed.dom.on(spreadsheetImportBtn, 'click', function(){ events.emit('ImportGoogleSpreadsheet'); }); highed.dom.on(csvImportBtn, 'click', function() { emitCSVImport(); }); highed.dom.on(liveDataImportBtn, 'click', function () { events.emit('ImportLiveData', { // url: liveDataInput.value }); }); highed.dom.on(csvPasteArea, 'keyup', function(e) { if (e.keyCode === 13 || ((e.metaKey || e.ctrlKey) && e.key === 'z')) { emitCSVImport(csvPasteArea.value); } }); highed.dom.on(csvImportFileBtn, 'click', function() { highed.readLocalFile({ type: 'text', accept: '.csv', success: function(info) { csvPasteArea.value = info.data; highed.snackBar('File uploaded'); emitCSVImport(); } }); }); highed.dom.on(jsonImportBtn, 'click', function() { processJSONImport(jsonPasteArea.value); }); highed.dom.on(jsonImportFileBtn, 'click', function() { highed.readLocalFile({ type: 'text', accept: '.json', success: function(info) { jsonPasteArea.value = info.data; processJSONImport(info.data); } }); }); buildSampleTab(); buildWebTab(); updateOptions(); delimiter.value = ','; //dateFormat.value = 'YYYY-mm-dd'; firstAsNames.type = 'checkbox'; decimalPoint.value = '.'; firstAsNames.checked = true; //Should hide the web tab if running where cross-origin is an issue resize(); /////////////////////////////////////////////////////////////////////////// return { on: events.on, loadCSV: loadCSVExternal, resize: resize, show: show, hide: hide, addImportTab: addImportTab, exporter: exporter, selectTab: selectTab, emitCSVImport: emitCSVImport }; }; })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format (function() { var exportPlugins = {}; highed.plugins.export = { /** Install an export plugin * @namespace highed.plugins.export * @param name {string} - the name of the plugin * @param definition {object} - the plugin definition */ install: function(name, definition) { if (highed.isNull(exportPlugins[name])) { exportPlugins[name] = highed.merge( { description: '', options: {}, title: false, downloadOutput: false }, definition ); if (exportPlugins[name].dependencies) { highed.include(exportPlugins[name].dependencies); } } else { highed.log( 1, 'tried to register an export plugin which already exists:', name ); } } }; /** Export widget * * @example * var exporter = highed.Exporter(document.body), * preview = highed.ChartPreview(document.body) * ; * * exporter.init(preview.export.json(), preview.export.html(), preview.export.svg(), preview); * * @constructor * * @param parent {domnode} - the node to attach the widget to * @param attributes {object} - the options * > options {string} - things to include: `csv html json plugins` * > plugins {string|array} - plugins to activate */ highed.Exporter = function(parent, attributes) { var //splitter = highed.HSplitter(parent, {leftWidth: 50, noOverflow: true}), properties = highed.merge( { options: 'svg html json plugins', plugins: 'beautify-js beautify-json' }, attributes ), tctrl = highed.TabControl(parent, false, true), htmlTab = tctrl.createTab({ title: 'HTML' }), jsonTab = tctrl.createTab({ title: 'JSON' }), svgTab = tctrl.createTab({ title: 'SVG' }), pluginTab = tctrl.createTab({ title: 'Plugins' }), pluginSplitter = highed.HSplitter(pluginTab.body, { leftWidth: 30 }), pluginList = highed.List(pluginSplitter.left), exportJSON = highed.dom.cr('a', 'highed-imp-button highed-imp-pasted-button', 'Download'), //highed.dom.cr('a', '', 'Download'), exportHTML = highed.dom.cr('a', 'highed-imp-button highed-imp-pasted-button', 'Download'), exportSVG = highed.dom.cr('a', 'highed-imp-button highed-imp-pasted-button', 'Download'), jsonValue = highed.dom.cr( 'textarea', 'highed-imp-pastearea highed-scrollbar' ), htmlValue = highed.dom.cr( 'textarea', 'highed-imp-pastearea highed-scrollbar' ), svgValue = highed.dom.cr( 'textarea', 'highed-imp-pastearea highed-scrollbar' ), currentChartPreview = false, hasBuiltPlugins = false, hasBeenVisible = false, pluginData = {}, activePlugins = {}, activePlugin = false; properties.options = highed.arrToObj(properties.options); properties.plugins = highed.arrToObj(properties.plugins); /////////////////////////////////////////////////////////////////////////// //Hides unwanted stuff function updateOptions() { if (!properties.options.html) { htmlTab.hide(); } if (!properties.options.json) { jsonTab.hide(); } if (!properties.options.svg) { svgTab.hide(); } if (!properties.options.plugins) { pluginTab.hide(); } if (Object.keys(properties.plugins) === 0) { pluginTab.hide(); } tctrl.selectFirst(); } //Build plugin panel function buildPlugins() { if (hasBuiltPlugins) return; hasBuiltPlugins = true; Object.keys(exportPlugins).forEach(function(name) { var options = exportPlugins[name]; pluginData[name] = { options: {} }; if (!properties.plugins[name]) { return false; } function buildBody() { var container = highed.dom.cr('div', 'highed-plugin-details'), executeBtn = highed.dom.cr( 'button', 'highed-imp-button', options.exportTitle || 'Export' ), dynamicOptionsContainer = highed.dom.cr( 'table', 'highed-customizer-table' ), additionalUI = highed.dom.cr('div'), dynamicOptions = pluginData[name].options; // pluginSplitter.right.innerHTML = ''; Object.keys(options.options || {}).forEach(function(pname) { dynamicOptions[pname] = options.options[pname].default; highed.dom.ap( dynamicOptionsContainer, highed.InspectorField( options.options[pname].type, options.options[pname].default, { title: options.options[pname].label }, function(nval) { dynamicOptions[pname] = nval; if (highed.isFn(options.show)) { options.show.apply(pluginData[name], [currentChartPreview]); } }, true ) ); }); function doExport() { if (highed.isFn(options.export) && currentChartPreview) { options.export.apply(pluginData[name], [ dynamicOptions, currentChartPreview, function(err, data, filename) { if (err) return highed.snackBar('Export error: ' + err); if (options.downloadOutput) { highed.download(filename, data); } highed.snackBar((options.title || name) + ' export complete'); }, additionalUI ]); } } highed.dom.on(executeBtn, 'click', doExport); highed.dom.ap(pluginSplitter.right, container); highed.dom.style(container, { display: 'none' }); highed.dom.ap( container, highed.dom.cr( 'div', 'highed-customizer-table-heading', options.title || name ), highed.dom.cr('div', 'highed-imp-help', options.description), Object.keys(options.options || {}).length ? dynamicOptionsContainer : false, additionalUI, options.export ? executeBtn : false ); if (highed.isFn(options.create)) { options.create.apply(pluginData[name], [ currentChartPreview, additionalUI ]); } activePlugins[name] = { export: doExport, show: function() { if (activePlugin) { activePlugin.hide(); } highed.dom.style(container, { display: '' }); options.show.apply(pluginData[name], [currentChartPreview]); activePlugin = activePlugins[name]; }, hide: function() { highed.dom.style(container, { display: 'none' }); } }; } buildBody(); pluginList.addItem({ id: name, title: options.title || name, click: activePlugins[name].show }); }); } /** Set the export boxes based on chart JSON data (chart.options) * @memberof highed.Exporter * @param chartData {object} - the chart JSON * @param chartHTML {string} - chart HTML * @param chartSVG {string} - chart svg * @param chartPreview {object} - instance of highed.ChartPreview */ function init(chartData, chartHTML, chartSVG, chartPreview) { var title = '_export'; if (chartData.title && chartData.title.text) { title = chartData.title.text.replace(/\s/g, '_') + title; } else { title = 'untitled' + title; } jsonValue.value = JSON.stringify(chartData); exportJSON.href = 'data:application/octet-stream,' + encodeURIComponent(jsonValue.value); htmlValue.value = chartHTML; exportHTML.href = 'data:application/octet-stream,' + encodeURIComponent(chartHTML); svgValue.value = chartSVG; exportSVG.href = 'data:application/octet-stream,' + encodeURIComponent(chartSVG); exportJSON.download = title + '.json'; exportHTML.download = title + '.html'; exportSVG.download = title + '.svg'; highed.dom.on(exportJSON, 'click', function() { highed.events('UIAction', 'BtnDownloadJSON'); }); highed.dom.on(exportHTML, 'click', function() { highed.events('UIAction', 'BtnDownloadHTML'); }); highed.dom.on(exportSVG, 'click', function() { highed.events('UIAction', 'BtnDownloadSVG'); }); currentChartPreview = chartPreview; buildPlugins(); // Object.keys(activePlugins).forEach(function (name) { // activePlugins[name].show(); // }); if (activePlugin) { activePlugin.show(); } hasBeenVisible = true; } /** Force a resize of the UI * @memberof highed.Exporter * @param w {number} - the new width * @param h {number} - the new height */ function resize(w, h) { var bsize; //splitter.resize(w, h); tctrl.resize(w, h); bsize = tctrl.barSize(); pluginSplitter.resize(w, h - bsize.h - 20); pluginList.resize(w, h - bsize.h); } function doSelectOnClick(thing, id) { highed.dom.on(thing, 'click', function() { thing.focus(); thing.select(); highed.emit('UIAction', 'Copy' + id); }); } /////////////////////////////////////////////////////////////////////////// highed.dom.ap( htmlTab.body, // highed.dom.cr('div', 'highed-imp-headline', 'Export HTML'), highed.dom.ap(highed.dom.cr('div', 'highed-imp-spacer'), htmlValue), exportHTML ); highed.dom.ap( jsonTab.body, // highed.dom.cr('div', 'highed-imp-headline', 'Export JSON'), highed.dom.ap(highed.dom.cr('div', 'highed-imp-spacer'), jsonValue), exportJSON ); highed.dom.ap( svgTab.body, // highed.dom.cr('div', 'highed-imp-headline', 'Export JSON'), highed.dom.ap(highed.dom.cr('div', 'highed-imp-spacer'), svgValue), exportSVG ); resize(); updateOptions(); doSelectOnClick(jsonValue, 'JSON'); doSelectOnClick(htmlValue, 'HTML'); doSelectOnClick(svgValue, 'SVG'); /////////////////////////////////////////////////////////////////////////// return { init: init, resize: resize, buildPluginUI: buildPlugins }; }; })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** Basic chart preview * This is just a facade to Highcharts.Chart mostly. * It implements a sliding drawer type widget, * where the initial state can be as part of the main DOM, * and where the expanded state covers most of the screen (90%) * * @todo this is a proper mess right now - need a good refactoring * * @constructor * * @param parent {domnode} - the node to attach the preview to * @param attributes {object} - the settings * > defaultChartOptions {object} - the default chart options */ highed.ChartPreview = function(parent, attributes) { var properties = highed.merge( { defaultChartOptions: { title: { text: 'Chart Title' }, subtitle: { text: '' }, exporting: { // url: 'http://127.0.0.1:7801' } }, expandTo: parent }, attributes ), events = highed.events(), customizedOptions = {}, aggregatedOptions = {}, flatOptions = {}, templateOptions = [], chartOptions = {}, themeOptions = {}, themeCustomCode = '', themeMeta = {}, exports = {}, chartPlugins = {}, customCodeDefault = [ '/*', '// Sample of extending options:', 'Highcharts.merge(true, options, {', ' chart: {', ' backgroundColor: "#bada55"', ' },', ' plotOptions: {', ' series: {', ' cursor: "pointer",', ' events: {', ' click: function(event) {', ' alert(this.name + " clicked\\n" +', ' "Alt: " + event.altKey + "\\n" +', ' "Control: " + event.ctrlKey + "\\n" +', ' "Shift: " + event.shiftKey + "\\n");', ' }', ' }', ' }', ' }', '});', '*/' ].join('\n'), customCode = '', customCodeStr = '', lastLoadedCSV = false, lastLoadedSheet = false, lastLoadedLiveData = false, throttleTimeout = false, chart = false, preExpandSize = false, dataTableCSV = null, assignDataFields = null, templateSettings = {}, toggleButton = highed.dom.cr( 'div', 'highed-icon highed-chart-preview-expand fa fa-external-link-square' ), expanded = false, constr = ['Chart'], wysiwyg = { 'g.highcharts-legend': { tab: 'Legend', dropdown: 'General', id: 'legend--enabled' }, 'text.highcharts-title': { tab: 'Chart', dropdown: 'Title', id: 'title--text' }, 'text.highcharts-subtitle': { tab: 'Chart', dropdown: 'Title',id: 'subtitle--text' }, '.highcharts-yaxis-labels': { tab: 'Axes', dropdown: 'Y Axis', id: 'yAxis-labels--format' }, '.highcharts-xaxis-labels': { tab: 'Axes', dropdown: 'X Axis', id: 'xAxis-labels--format' }, '.highcharts-xaxis .highcharts-axis-title': { tab: 'Axes', dropdown: 'X Axis', id: 'xAxis-title--text' }, '.highcharts-yaxis .highcharts-axis-title': { tab: 'Axes', dropdown: 'Y Axis', id: 'yAxis-title--text' }, 'rect.highcharts-background': { tab: 'Chart', dropdown: 'Appearance', id: 'chart--backgroundColor' }, '.highcharts-series': { tab: 'Data series', id: 'series' }, 'g.highcharts-tooltip': { tab: 'Chart', dropdown: 'Tooltip', id: 'tooltip--enabled' } }, isAnnotating = false, annotationType = false; /////////////////////////////////////////////////////////////////////////// function attachWYSIWYG() { Object.keys(wysiwyg).forEach(function(key) { highed.dom.on(parent.querySelector(key), 'click', function(e) { if (isAnnotating) return; events.emit('RequestEdit', wysiwyg[key], e.clientX, e.clientY); e.cancelBubble = true; e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); return false; }); }); } function stringifyFn(obj, tabs) { return JSON.stringify( obj, function(key, value) { if (highed.isFn(value)) { return value.toString(); } return value; }, tabs ); } /* Get the chart if it's initied */ function gc(fn) { if (highed.isFn(fn)) { if (chart !== false) { return fn(chart); } return fn(init()); } return false; } /* Emit change events */ function emitChange() { events.emit('ChartChange', aggregatedOptions); //Throttled event - we use this when doing server stuff in the handler //since e.g. using the color picker can result in quite a lot of updates //within a short amount of time window.clearTimeout(throttleTimeout); throttleTimeout = window.setTimeout(function() { events.emit('ChartChangeLately', aggregatedOptions); }, 200); } function addShape(chart, type, x, y) { var options = { id: "shape_" + customizedOptions.annotations.length, //customizedOptions.annotations[0].shapes.length, type: type, point: { x: x, y: y, xAxis: 0, yAxis: 0 }, x: 0, y: 0 }; if (type === 'circle') { options.r = 10; } else if (type === 'rect') { options.width = 20; options.height = 20; options.x = -10; options.y = -10; } var annotation = chart.addAnnotation({ id: "shape_" + customizedOptions.annotations.length, //customizedOptions.annotations[0].shapes.length, shapes: [options], type: type }); var annotation = chart.addAnnotation({ id: "shape_" + customizedOptions.annotations.length, //customizedOptions.annotations[0].shapes.length, shapes: [options], type: type }); customizedOptions.annotations.push({ id: "shape_" + customizedOptions.annotations.length, shapes: [annotation.options.shapes[0]] }); //customizedOptions.annotations[0].shapes.push(annotation.options.shapes[0]); } /* Init the chart */ function init(options, pnode, noAnimation) { var i; //We want to work on a copy.. options = options || aggregatedOptions; if (highed.isArr(constr)) constr = constr; else constr = ['Chart']; // options = highed.merge({}, options || aggregatedOptions); // if (aggregatedOptions && aggregatedOptions.series) { // options = aggregatedOptions.series; // } if (noAnimation) { highed.setAttr(options, 'plotOptions--series--animation', false); } if (typeof window.Highcharts === 'undefined') { highed.snackBar('Highcharts.JS must be included to use the editor'); return; } // (pnode || parent).innerHTML = 'Chart not loaded yet'; // options.chart = options.chart || {}; // options.chart.width = '100%'; // options.chart.height = '100%'; // if (options && options.chart) { // delete options.chart.width; // delete options.chart.height; // } if (chart && chart.annotations) { var annotations = chart.annotations || []; for (var i = annotations.length - 1; i > -1; --i) { if (annotations[i].options) { chart.removeAnnotation(annotations[i].options.id); } } chart.annotations.length = 0; } try { const chartConstr = (constr.some(function(a) { return a === 'StockChart'; }) ? 'StockChart' : 'Chart'); chart = new Highcharts[chartConstr](pnode || parent, options); //This is super ugly. // customizedOptions.series = customizedOptions.series || []; // customizedOptions.series = chart.options.series || []; // highed.merge(customizedOptions.series, chart.options.series); //updateAggregated(); if (chart && chart.options) { highed.clearObj(chartOptions); highed.merge(chartOptions, chart.options); } attachWYSIWYG(); if (chart && chart.reflow) { //chart.reflow(); } Highcharts.error = function (code, stopLoading) { if (stopLoading) throw code; else { setTimeout(function() { events.emit('Error', { code: code, url : (code ? 'https://www.highcharts.com/errors/' + code : ''), warning: true }); }, 200); } }; function setupAnnotationEvents(eventName, type) { Highcharts.wrap(Highcharts.Annotation.prototype, eventName, function(proceed, shapeOptions) { proceed.apply(this, Array.prototype.slice.call(arguments, 1)) var annotation = this[type][this[type].length - 1]; (annotation.element).addEventListener('click', function(e) { highed.dom.nodefault(e); if (isAnnotating && annotationType === 'delete') { var optionIndex = customizedOptions.annotations.findIndex(function(element) { return element.id === annotation.options.id }); chart.removeAnnotation(annotation.options.id); customizedOptions.annotations.splice(optionIndex, 1); } }); (annotation.element).addEventListener('mousedown', function(e) { if (!chart.activeAnnotation && (isAnnotating && annotationType === 'drag')) { if (type === 'shapes') { chart.activeAnnotationOptions = highed.merge({}, annotation.options); if (annotation.type === 'rect') { chart.activeAnnotationOptions.width = 20; chart.activeAnnotationOptions.height = 20; } } else { chart.activeAnnotationOptions = { id: annotation.options.id, text: annotation.options.text, point: { x: annotation.options.point.x, y: annotation.options.point.y, xAxis: 0, yAxis: 0 }, backgroundColor: annotation.options.backgroundColor, shape: annotation.options.shape, borderWidth: annotation.options.borderWidth, x: 0, y: 0 }; } annotation.id = annotation.options.id; chart.activeAnnotation = annotation; chart.annotationType = type; } }); }) } setupAnnotationEvents('initLabel', 'labels'); setupAnnotationEvents('initShape', 'shapes'); Highcharts.addEvent(document, 'mousemove', function (e) { if (!chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) return; if (chart.activeAnnotationOptions && (isAnnotating && annotationType === 'drag')) { var s = chart.pointer.normalize(e), prevOptions = chart.activeAnnotationOptions, prevAnn = chart.activeAnnotation; prevOptions.point.x = chart.xAxis[0].toValue(s.chartX); prevOptions.point.y = chart.yAxis[0].toValue(s.chartY); if(prevAnn && prevAnn.id) { chart.removeAnnotation(prevAnn.id); } var newAnnotation; if (chart.annotationType === 'shapes') { newAnnotation = chart.addAnnotation({ id: prevOptions.id, shapes: [prevOptions] }); } else { newAnnotation = chart.addAnnotation({ id: prevOptions.id, labels: [prevOptions] }); } newAnnotation.id = prevOptions.id; chart.activeAnnotation = newAnnotation; } }); Highcharts.addEvent(document, 'mouseup', function (e) { if (chart.activeAnnotation && (isAnnotating && annotationType === 'drag')) { chart.removeAnnotation(chart.activeAnnotationOptions.id); if (chart.annotationType === 'shapes') { chart.activeAnnotation = chart.addAnnotation({ id: chart.activeAnnotationOptions.id, shapes: [chart.activeAnnotationOptions] }); customizedOptions.annotations.some(function(ann) { if (ann.shapes && ann.shapes[0].id === chart.activeAnnotationOptions.id) { ann.shapes[0].point.x = chart.activeAnnotation.options.shapes[0].point.x; ann.shapes[0].point.y = chart.activeAnnotation.options.shapes[0].point.y; return true; } }); } else { chart.activeAnnotation = chart.addAnnotation({ id: chart.activeAnnotationOptions.id, labels: [chart.activeAnnotationOptions] }); customizedOptions.annotations.some(function(ann) { if (ann.labels && ann.labels[0].id === chart.activeAnnotationOptions.id) { ann.labels[0].point.x = chart.activeAnnotation.options.labels[0].point.x; ann.labels[0].point.y = chart.activeAnnotation.options.labels[0].point.y; return true; } }); } chart.activeAnnotation = null; chart.activeAnnotationOptions = null; chart.annotationType = null; } }); Highcharts.addEvent(chart, 'click', function (e) { if (isAnnotating) { //events.emit('SetAnnotate', e); if (!customizedOptions.annotations) customizedOptions.annotations = []; //[{}]; //if (!customizedOptions.annotations[0].shapes) customizedOptions.annotations[0].shapes = []; if (annotationType === 'label') { events.emit('ShowTextDialog', this, e.xAxis[0].value, e.yAxis[0].value); } else if (annotationType === 'delete' || annotationType === 'drag'){ } else { addShape(this, annotationType, e.xAxis[0].value, e.yAxis[0].value); } } }); Highcharts.addEvent(chart, 'afterPrint', function() { events.emit('RequestResize'); // highed.dom.ap(pnode || parent, toggleButton); }); events.emit('ChartRecreated'); } catch (code) { events.emit('Error', { code: code, url : (code ? 'https://www.highcharts.com/errors/' + code : '') }); highed.emit('UIAction', 'UnsuccessfulChartGeneration'); (pnode || parent).innerHTML = ''; chart = false; } return chart; } /** Resize the preview * Resizes based on the parent size. * @memberof highed.ChartPreview */ function resize(width, height) { gc(function(chart) { if (chart && chart.reflow) { // && chart.options) { try { if (width && height) { chart.setSize(width, height, true); chart.options.chart.width = null; chart.options.chart.height = null; } else { chart.setSize(undefined, undefined, false); chart.reflow(); } } catch (e) { // No idea why this keeps failing } } }); } /** * Clear all themes from the chart. * Used by cloud to reset theme */ function clearTheme(theme, skipEmit) { themeOptions = false; if (!skipEmit) { updateAggregated(); init(aggregatedOptions); emitChange(); events.emit('SetResizeData'); } return true; } /** * Assign a theme to the chart * theme can either be a straight-up option set, or a theme object with * ID and so on. */ function assignTheme(theme, skipEmit) { if (highed.isStr(theme)) { return assignTheme(JSON.parse(theme)); } themeMeta = {}; if (highed.isBasic(theme) || highed.isArr(theme)) { return false; } if (Object.keys(theme).length === 0) { return false; } if (theme && theme.options && theme.id) { // Assume that this uses the new format themeMeta = { id: theme.id, name: theme.name || theme.id }; themeOptions = highed.merge({}, theme.options); themeCustomCode = theme.customCode || ''; } else { themeMeta = { id: highed.uuid(), name: 'Untitled Theme' }; themeOptions = highed.merge({}, theme); } if (!skipEmit) { events.emit('UpdateCustomCode'); updateAggregated(); init(aggregatedOptions); emitChange(); events.emit('SetResizeData'); } return true; } function updateAggregated(noCustomCode) { // customizedOptions.plotOptions = customizedOptions.plotOptions || {}; // customizedOptions.plotOptions.series = customizedOptions.plotOptions.series || []; // customizedOptions.series = customizedOptions.series || []; if ( customizedOptions && !highed.isArr(customizedOptions.yAxis) && customizedOptions.yAxis ) { customizedOptions.yAxis = [customizedOptions.yAxis || {}]; } if ( customizedOptions && !highed.isArr(customizedOptions.xAxis) && customizedOptions.xAxis ) { customizedOptions.xAxis = [customizedOptions.xAxis || {}]; } // templateOptions = templateOptions || {}; templateOptions = templateOptions || []; var aggregatedTemplate = {}; //Merge fest highed.clearObj(aggregatedOptions); highed.merge(aggregatedOptions, properties.defaultChartOptions); // Apply theme first if (themeOptions && Object.keys(themeOptions).length) { highed.merge( aggregatedOptions, highed.merge(highed.merge({}, themeOptions)) ); } templateOptions.forEach(function(arr) { if (arr) { if (arr.yAxis && !highed.isArr(arr.yAxis)) { arr.yAxis = [arr.yAxis]; } if (arr.xAxis && !highed.isArr(arr.xAxis)) { arr.xAxis = [arr.xAxis]; } aggregatedTemplate = highed.merge(aggregatedTemplate, arr); } }); highed.merge( aggregatedOptions, highed.merge(highed.merge({}, aggregatedTemplate), customizedOptions) ); if (!aggregatedOptions.yAxis && customizedOptions.yAxis) { aggregatedOptions.yAxis = customizedOptions.yAxis } if (!aggregatedOptions.xAxis && customizedOptions.xAxis) { aggregatedOptions.xAxis = customizedOptions.xAxis } //This needs to be cleaned up if (aggregatedOptions.yAxis && aggregatedTemplate.yAxis) { aggregatedOptions.yAxis.forEach(function(obj, i) { if (i < aggregatedTemplate.yAxis.length) { highed.merge(obj, aggregatedTemplate.yAxis[i]); } }); } if (aggregatedOptions.xAxis && aggregatedTemplate.xAxis && highed.isArr(aggregatedOptions.xAxis)) { (aggregatedOptions.xAxis).forEach(function(obj, i) { if (i < aggregatedTemplate.xAxis.length) { highed.merge(obj, aggregatedTemplate.xAxis[i]); } }); } if (themeOptions && themeOptions.xAxis) { themeOptions.xAxis = highed.isArr(themeOptions.xAxis) ? themeOptions.xAxis : [themeOptions.xAxis]; if (highed.isArr(aggregatedOptions.xAxis)) { (aggregatedOptions.xAxis).forEach(function(obj, i) { if (i < themeOptions.xAxis.length) { highed.merge(obj, themeOptions.xAxis[i]); } }); } } if (themeOptions && themeOptions.yAxis) { themeOptions.yAxis = highed.isArr(themeOptions.yAxis) ? themeOptions.yAxis : [themeOptions.yAxis]; if (highed.isArr(aggregatedOptions.yAxis)) { aggregatedOptions.yAxis.forEach(function(obj, i) { if (i < themeOptions.yAxis.length) { highed.merge(obj, themeOptions.yAxis[i]); } }); } } //Temporary hack //aggregatedOptions.series = customizedOptions.series;\ aggregatedOptions.series = []; if (highed.isArr(customizedOptions.series)) { customizedOptions.series.forEach(function(obj, i) { var mergeTarget = {}; if (themeOptions && highed.isArr(themeOptions.series)) { if (i < themeOptions.series.length) { mergeTarget = highed.merge({}, themeOptions.series[i]); } } aggregatedOptions.series.push(highed.merge(mergeTarget, obj)); }); } if (aggregatedTemplate.series) { aggregatedOptions.series = aggregatedOptions.series || []; aggregatedTemplate.series.forEach(function(obj, i) { if (i < aggregatedOptions.series.length) { highed.merge(aggregatedOptions.series[i], obj); } else { aggregatedOptions.series.push(highed.merge({}, obj)); } }); } highed.merge( aggregatedOptions, highed.merge({}, customizedOptions) ); if (themeOptions && themeOptions.series) { if (aggregatedOptions.series) { aggregatedOptions.series.forEach(function (serie, i) { if (!serie.type && themeOptions.series[i] && themeOptions.series[i].type) { serie.type = themeOptions.series[i].type } }); } } if (aggregatedOptions.yAxis && !highed.isArr(aggregatedOptions.yAxis)) { aggregatedOptions.yAxis = [aggregatedOptions.yAxis]; } if (aggregatedOptions.xAxis && !highed.isArr(aggregatedOptions.xAxis)) { aggregatedOptions.xAxis = [aggregatedOptions.xAxis]; } highed.merge(aggregatedOptions, highed.option('stickyChartProperties')); // Finally, do custom code if (!noCustomCode && highed.isFn(customCode)) { customCode(aggregatedOptions); } } function deleteSeries(length) { if (customizedOptions && customizedOptions.series) { customizedOptions.series = customizedOptions.series.slice(0, length); updateAggregated(); init(aggregatedOptions); emitChange(); } } function deleteSerie(index) { if (customizedOptions.series && customizedOptions.series[index]) { customizedOptions.series.splice(index, 1); delete templateSettings[index]; } updateAggregated(); init(aggregatedOptions); } function loadTemplateForSerie(template, seriesIndex) { const type = template.config.chart.type; delete template.config.chart.type; constr[seriesIndex] = template.constructor || 'Chart'; seriesIndex.forEach(function(index) { if (!templateSettings[index]) templateSettings[index] = {}; templateSettings[index].templateTitle = template.title; templateSettings[index].templateHeader = template.header; if (customizedOptions.series[index]) { customizedOptions.series[index].type = type; //template.config.chart.type; } else { customizedOptions.series[index] = { type: type, //template.config.chart.type, turboThreshold: 0, _colorIndex: customizedOptions.series.length, _symbolIndex: 0, compare: undefined }; } }); //templateOptions = highed.merge({}, template.config || {}); templateOptions[seriesIndex] = highed.merge({}, template.config || {}); updateAggregated(); init(aggregatedOptions); //loadSeries(); emitChange(); } /** Load a template from the meta * @memberof highed.ChartPreview * @param template - the template object */ function loadTemplate(template) { if (!template || !template.config) { return highed.log( 1, 'chart preview: templates must be an object {config: {...}}' ); } constr = [template.constructor || 'Chart']; //highed.clearObj(templateOptions); if (customizedOptions.xAxis) { delete customizedOptions.xAxis; } if (customizedOptions.yAxis) { delete customizedOptions.yAxis; } // highed.setAttr(customizedOptions, 'series', []); gc(function(chart) { //templateOptions = highed.merge({}, template.config || {}); templateOptions = [highed.merge({}, template.config || {})]; updateAggregated(); init(aggregatedOptions); emitChange(); }); } function loadSeriesFromDataSource(){ if ( !gc(function(chart) { if (chart.options && chart.options.series) { customizedOptions.series = chart.options.series; } return true; }) ) { customizedOptions.series = []; } updateAggregated(); } function loadSeries() {/* if ( !gc(function(chart) { if (chart.options && chart.options.series) { customizedOptions.series = chart.options.series; } return true; }) ) { customizedOptions.series = []; } updateAggregated();*/ } /** Load CSV data * @memberof highed.ChartPreview * @name data.csv * @param data {object} - the data to load */ function loadCSVData(data, emitLoadSignal, bypassClearSeries, cb) { var mergedExisting = false, seriesClones = []; if (!data || !data.csv) { if (highed.isStr(data)) { data = { csv: data, // itemDelimiter: ';', firstRowAsNames: true }; } else { return highed.log(1, 'chart load csv: data.csv is required'); } } lastLoadedCSV = data.csv; lastLoadedSheet = false; lastLoadedLiveData = false; gc(function(chart) { var axis; // highed.setAttr(customizedOptions, 'series', []); // highed.setAttr(aggregatedOptions, 'series', []); // highed.setAttr(customizedOptions, 'plotOptions--series--animation', true); // highed.setAttr(customizedOptions, 'data--csv', data.csv); // highed.setAttr(customizedOptions, 'data--googleSpreadsheetKey', undefined); // highed.setAttr(customizedOptions, 'data--itemDelimiter', data.itemDelimiter); // highed.setAttr(customizedOptions, 'data--firstRowAsNames', data.firstRowAsNames); // highed.setAttr(customizedOptions, 'data--dateFormat', data.dateFormat); // highed.setAttr(customizedOptions, 'data--decimalPoint', data.decimalPoint); if (customizedOptions && customizedOptions.series) { (highed.isArr(customizedOptions.series) ? customizedOptions.series : [customizedOptions.series] ).forEach(function(series) { seriesClones.push( highed.merge({}, series, false, { data: 1, name: 1 }) ); }); } customizedOptions.series = []; if (customizedOptions.xAxis) { (highed.isArr(customizedOptions.xAxis) ? customizedOptions.xAxis : [customizedOptions.xAxis] ).forEach(function(axis) { if (axis.categories) axis.categories = []; }); } if (customizedOptions.yAxis) { (highed.isArr(customizedOptions.yAxis) ? customizedOptions.yAxis : [customizedOptions.yAxis] ).forEach(function(axis) { if (axis.categories) axis.categories = []; }); } highed.merge(customizedOptions, { plotOptions: { series: { animation: false } }, data: { csv: data.csv, itemDelimiter: data.itemDelimiter, firstRowAsNames: data.firstRowAsNames, dateFormat: data.dateFormat, decimalPoint: data.decimalPoint, googleSpreadsheetKey: undefined, url: data.url } }); updateAggregated(); init(aggregatedOptions); loadSeries(); emitChange(); if (highed.isArr(seriesClones)) { (seriesClones || []).forEach(function(series, i) { mergedExisting = true; if (!customizedOptions.series[i]) { addBlankSeries(i); } highed.merge(customizedOptions.series[i], series); }); } if (mergedExisting) { updateAggregated(); init(aggregatedOptions); loadSeries(); emitChange(); } if (emitLoadSignal) { events.emit('LoadProjectData', data.csv); } if (cb) cb(); }); // setTimeout(function () { // gc(function (chart) { // if (chart && highed.isArr(chart.xAxis) && chart.xAxis.length > 0) { // customizedOptions.xAxis = customizedOptions.xAxis || []; // chart.xAxis.forEach(function (a, i) { // customizedOptions.xAxis[i] = customizedOptions.xAxis[i] || {}; // if (a.isDatetimeAxis) { // customizedOptions.xAxis[i].type = 'datetime'; // } else if (a.categories) { // customizedOptions.xAxis[i].type = 'categories'; // } else { // // customizedOptions.xAxis[i].type = 'linear'; // } // }); // } // console.log(chart); // }); // }, 1000); } /** Load project * @memberof highed.ChartPreview * @param projectData - the data to load */ function loadProject(projectData) { var hasData = false, htmlEntities = { '&': '&', '<': '<', '>': '>' }; highed.emit('UIAction', 'LoadProject'); lastLoadedCSV = false; lastLoadedSheet = false; lastLoadedLiveData = false; if (highed.isStr(projectData)) { try { return loadProject(JSON.parse(projectData)); } catch (e) { highed.snackBar('Invalid project'); } } if (projectData) { templateOptions = [{}]; if (projectData.template) { if (highed.isArr(projectData.template)) templateOptions = projectData.template; else templateOptions = [projectData.template]; } customizedOptions = {}; if (projectData.options) { customizedOptions = projectData.options; } // highed.merge(customizedOptions, { // data: { // csv: undefined // } // }); // if (customizedOptions && customizedOptions.data) { // customizedOptions.data.csv = undefined; // } if (customizedOptions.lang) { Highcharts.setOptions({ lang: customizedOptions.lang }); } if (typeof projectData.theme !== 'undefined') { assignTheme(projectData.theme, true); } if (customizedOptions && customizedOptions.series) { customizedOptions.series = highed.isArr(customizedOptions.series) ? customizedOptions.series : [customizedOptions.series]; customizedOptions.series.forEach(function(series) { if (typeof series._colorIndex !== 'undefined') { delete series._colorIndex; } }); } setCustomCode( projectData.customCode, function(err) { highed.snackBar('Error in custom code: ' + err); }, true ); events.emit('LoadCustomCode'); constr = ['Chart']; // Support legacy format if (projectData.settings && projectData.settings.templateView) { if (projectData.settings.templateView.activeSection === 'stock') { constr = ['StockChart']; } } if (projectData.settings && projectData.settings.template) { templateSettings = projectData.settings.template; } if(projectData.settings && projectData.settings.plugins) { chartPlugins = projectData.settings.plugins } if ( projectData.settings && highed.isStr(projectData.settings.constructor) ) { constr = [projectData.settings.constructor]; } if ( projectData.settings && highed.isArr(projectData.settings.constructor) ) { constr = projectData.settings.constructor; } if (projectData.settings && projectData.settings.dataProvider) { if (projectData.settings.dataProvider.seriesMapping) { highed.merge(customizedOptions, { data: { seriesMapping: projectData.settings.dataProvider.seriesMapping } }); } if (projectData.settings.dataProvider.assignDataFields) { assignDataFields = projectData.settings.dataProvider.assignDataFields; } if (projectData.settings.dataProvider.googleSpreadsheet) { var provider = projectData.settings.dataProvider; var sheet = provider.googleSpreadsheet; if (customizedOptions.data) { sheet.startRow = provider.startRow || customizedOptions.data.startRow; sheet.endRow = provider.endRow || customizedOptions.data.endRow; sheet.startColumn = provider.startColumn || customizedOptions.data.startColumn; sheet.endColumn = provider.endColumn || customizedOptions.data.endColumn; if (provider.dataRefreshRate && provider.dataRefreshRate > 0) { sheet.dataRefreshRate = provider.dataRefreshRate || customizedOptions.data.dataRefreshRate; sheet.enablePolling = true; } } events.emit( 'ProviderGSheet', projectData.settings.dataProvider.googleSpreadsheet ); loadGSpreadsheet(sheet); hasData = true; } else if (projectData.settings.dataProvider.liveData) { var provider = projectData.settings.dataProvider; var live = provider.liveData; loadLiveData(provider.liveData); } else if (projectData.settings.dataProvider.csv) { // We need to fix potential html-entities as they will mess up separators Object.keys(htmlEntities).forEach(function(ent) { projectData.settings.dataProvider.csv = projectData.settings.dataProvider.csv.replace( new RegExp(ent, 'g'), htmlEntities[ent] ); }); hasData = true; } } // Not sure if this should be part of the project files yet // if (projectData.editorOptions) { // Object.keys(projectData.editorOptions, function (key) { // highed.option(key, projectData.editorOptions[key]); // }); // } updateAggregated(); if (!hasData) { init(aggregatedOptions); } emitChange(); events.emit('LoadProject', projectData, aggregatedOptions); } } function loadLiveData(settings) { lastLoadedLiveData = settings; lastLoadedCSV = false; lastLoadedSheet = false; highed.merge(customizedOptions, { data: lastLoadedLiveData }); events.emit('ProviderLiveData', settings); updateAggregated(); init(aggregatedOptions); loadSeries(); emitChange(); // The sheet will be loaded async, so we should listen to the load event. gc(function(chart) { var found = Highcharts.addEvent(chart, 'load', function() { loadSeriesFromDataSource(); found(); }); }); } function loadGSpreadsheet(options) { var key; lastLoadedCSV = false; lastLoadedSheet = options; lastLoadedSheet.googleSpreadsheetKey = lastLoadedSheet.googleSpreadsheetKey || lastLoadedSheet.id; lastLoadedSheet.googleSpreadsheetWorksheet = lastLoadedSheet.googleSpreadsheetWorksheet || lastLoadedSheet.worksheet; if (options && (options.googleSpreadsheetKey || '').indexOf('http') === 0) { // Parse out the spreadsheet ID // Located between /d/ and the next slash after that key = options.googleSpreadsheetKey; key = key.substr(key.indexOf('/d/') + 3); key = key.substr(0, key.indexOf('/')); options.googleSpreadsheetKey = key; } highed.merge(customizedOptions, { data: lastLoadedSheet }); updateAggregated(); init(aggregatedOptions); loadSeries(); emitChange(); // The sheet will be loaded async, so we should listen to the load event. gc(function(chart) { var found = Highcharts.addEvent(chart, 'load', function() { loadSeriesFromDataSource(); //loadSeries(); found(); }); }); } function getCleanOptions(source) { return source; // return highed.merge(highed.merge({}, source), { // data: { // csv: false // } // }); // var clone = highed.merge({}, source || customizedOptions); // if (!highed.isArr(clone.yAxis)) { // clone.yAxis = [clone.yAxis]; // } // (clone.yAxis || []).forEach(function (axis) { // if (axis.series) { // delete axis.series.data; // } // }); // return clone; } /** Export project as JSON * @memberof highed.ChartPreview */ function toProject() { var loadedCSVRaw = false, gsheet = lastLoadedSheet, livedata = lastLoadedLiveData, themeData = false, seriesMapping = false; if ( (chart && chart.options && chart.options.data && chart.options.data.csv) || dataTableCSV !== null ) { loadedCSVRaw = dataTableCSV || (chart.options.data ? chart.options.data.csv : ''); if (chart.options.data && chart.options.data.seriesMapping) { seriesMapping = chart.options.data.seriesMapping; } } if ( chart && chart.options && chart.options.data && chart.options.data.googleSpreadsheetKey ) { gsheet = { googleSpreadsheetKey: chart.options.data.googleSpreadsheetKey, googleSpreadsheetWorksheet: chart.options.data.googleSpreadsheetWorksheet }; assignDataFields = false; } if (chart && chart.options && chart.options.data && chart.options.data.url ) { livedata = { url: chart.options.data.url, interval: chart.options.data.interval, type: chart.options.data.type }; assignDataFields = false; } if (themeMeta && themeMeta.id && themeOptions) { themeData = { id: themeMeta.id, name: themeMeta.name, options: themeOptions || {}, customCode: themeCustomCode || '' }; } if (chart && chart.options && chart.options.annotations) { chartPlugins.annotations = 1; } return { template: templateOptions, options: getCleanOptions(customizedOptions), customCode: highed.isFn(customCode) ? customCodeStr : '', theme: themeData, settings: { constructor: constr, template: templateSettings, plugins: chartPlugins,//getPlugins(), dataProvider: { csv: !gsheet && !livedata ? loadedCSVRaw || lastLoadedCSV : false, googleSpreadsheet: gsheet, liveData: livedata, assignDataFields: assignDataFields, seriesMapping: seriesMapping } } //editorOptions: highed.serializeEditorOptions() }; } function getTemplateSettings() { return templateSettings; } function clearData(skipReinit) { lastLoadedCSV = false; lastLoadedSheet = false; lastLoadedLiveData = false; if (customizedOptions && customizedOptions.data) { customizedOptions.data = {}; } if (customizedOptions.series) { customizedOptions.series = highed.isArr(customizedOptions.series) ? customizedOptions.series : [customizedOptions.series]; customizedOptions.series.forEach(function(series) { if (series.data) { delete series.data; } }); } if (!skipReinit) { updateAggregated(); init(aggregatedOptions); emitChange(); } } /** * Export project as a JSON string */ function toProjectStr(tabs) { return stringifyFn(toProject(), tabs); } /** Load JSON data * Functionally, this only instances a new * chart with the supplied data as its options. * It accepts both a string and and object * * @memberof highed.ChartPreview * @name data.json * @param data {object} - the data to load */ function loadJSONData(data) { lastLoadedCSV = false; gc(function(chart) { if (highed.isStr(data)) { try { loadJSONData(JSON.parse(data)); } catch (e) { highed.snackBar('invalid json: ' + e); } } else if (highed.isBasic(data)) { highed.snackBar('the data is not valid json'); } else { templateOptions = [{}]; highed.clearObj(customizedOptions); highed.merge(customizedOptions, highed.merge({}, data)); if (!highed.isNull(data.series)) { customizedOptions.series = data.series; } updateAggregated(); init(customizedOptions); loadSeries(); emitChange(); } }); } /** * Set Data table CSV as user could have unused columns that need saving too. */ function setDataTableCSV(csv) { dataTableCSV = csv; } /** * Set Assign Data fields from datatable */ function setAssignDataFields(fields) { assignDataFields = fields; } /** * Add/Remove a module from the charts config */ function togglePlugins(groupId, newValue) { if (newValue) { chartPlugins[groupId] = 1; } else { delete chartPlugins[groupId]; } } function getPlugins() { var arr = []; Object.keys(chartPlugins).filter(function(key) { chartPlugins[key].forEach(function(object) { if (arr.indexOf(object) === -1) arr.push(object); }); }); return arr; } /** * Load raw dataset (array of arrays) */ //function /** Set chart options from an object * */ function setChartOptions(options) { function emitWidthChange() { events.emit('AttrChange', { id: 'chart.width' }); } function emitHeightChange() { events.emit('AttrChange', { id: 'chart.height' }); } var doEmitHeightChange = false, doEmitWidthChange = false; // Temp. hack to deal with actual sizing if (options && options.chart) { if (typeof options.chart.width !== 'undefined') { if ( !customizedOptions.chart || typeof customizedOptions.chart === 'undefined' ) { doEmitWidthChange = true; } else if (customizedOptions.chart.width !== options.chart.width) { doEmitWidthChange = true; } } if (typeof options.chart.height !== 'undefined') { if ( !customizedOptions.chart || typeof customizedOptions.chart === 'undefined' ) { doEmitHeightChange = true; } else if (customizedOptions.chart.height !== options.chart.height) { doEmitHeightChange = true; } } } // console.time('remblanks'); customizedOptions = highed.transform.remBlanks( highed.merge({}, options, false) ); // console.timeEnd('remblanks'); if (customizedOptions && customizedOptions.lang) { Highcharts.setOptions({ lang: customizedOptions.lang }); } if (options && options.global) { } // This is nasty if (options && options.data && options.data.googleSpreadsheetKey) { events.emit('LoadedGoogleSpreadsheet'); } updateAggregated(); init(aggregatedOptions, false, true); emitChange(); if (doEmitHeightChange) { emitHeightChange(); } if (doEmitWidthChange) { emitWidthChange(); } } /** Load chart settings * Note that merges the incoming settings with the existing ones. * @memberof highed.ChartPreview * @name data.settings * @param settings {object} - the settings to load */ function loadChartSettings(settings) { gc(function(chart) { Object.keys(settings || {}).forEach(function(key) { highed.setAttr(customizedOptions, key, settings[key]); }); updateAggregated(); init(aggregatedOptions); emitChange(); }); } function loadSeriesData(seriesArr) { if (!highed.isArr(seriesArr)) return; customizedOptions.series = customizedOptions.series || []; if (seriesArr.length < customizedOptions.series.length) { //Need to delete some series customizedOptions.series.splice( seriesArr.length, customizedOptions.series.length - seriesArr.length ); } seriesArr.forEach(function(s, i) { if (s.name) { set('series-name', s.name, i); } if (s.data) { set('series-data', s.data, i); } }); } /** Set an attribute * @memberof highed.ChartPreview * @name options.set * @param id {string} - the path of the attribute * @param value {anything} - the value to set * @param index {number} - used if the option is an array */ function set(id, value, index) { gc(function(chart) { //highed.setAttr(chart.options, id, value, index); highed.setAttr( chart.options, 'plotOptions--series--animation', false, index ); }); //We want to be able to set the customized options even if the chart //doesn't exist highed.setAttr(customizedOptions, id, value, index); flatOptions[id] = value; if (id.indexOf('lang--') === 0 && customizedOptions.lang) { Highcharts.setOptions({ lang: customizedOptions.lang }); } updateAggregated(); init(aggregatedOptions, false, true); emitChange(); events.emit('AttrChange', { id: id.replace(/\-\-/g, '.').replace(/\-/g, '.'), value: value }); } /** Get embeddable JSON * This returns the merged chart, with both customized options * and options set indirectly through templates. * @memberof highed.ChartPreview * @name export.json * @returns {object} - the chart object */ function getEmbeddableJSON(noCustomCode) { var r; updateAggregated(noCustomCode); r = getCleanOptions(highed.merge({}, aggregatedOptions)); //This should be part of the series if (!highed.isNull(r.data)) { // Don't delete spreadsheet stuff if (!r.data.googleSpreadsheetKey) { r.data = undefined; } //delete r['data']; } if (r && highed.isArr(r.series)) { r.series = r.series.map(function(s) { var cloned = highed.merge({}, s); delete s.data; return s; }); } if (lastLoadedSheet) { highed.merge(r, { data: lastLoadedSheet }); } else if (lastLoadedLiveData) { highed.merge(r, { data: lastLoadedLiveData, googleSpreadsheetKey: false, googleSpreadsheetWorksheet: false }); } else if (lastLoadedCSV) { highed.merge(r, { data: { csv: lastLoadedCSV, googleSpreadsheetKey: false, googleSpreadsheetWorksheet: false } }); } return r; } /** * Convert the chart to a string */ function toString(tabs) { return stringifyFn(getEmbeddableJSON(), tabs); } /** Get embeddable SVG * @memberof highed.ChartPreview * @name export.svg * @returns {string} - the result from `Highcharts.Chart.getSVG()` */ function getEmbeddableSVG() { return gc(function(chart) { return highed.isFn(chart.getSVG) ? chart.getSVG() : ''; }); } /** Get embeddable JavaScript * @memberof highed.ChartPreview * @name export.js * @param id {string} - the ID of the node to attach the chart to * @returns {string} - a string containing JavaScript to reproduce the chart */ function getEmbeddableJavaScript(id) { return gc(function(chart) { var cdnIncludes = [ 'https://code.highcharts.com/stock/highstock.js', 'https://code.highcharts.com/highcharts-more.js', 'https://code.highcharts.com/highcharts-3d.js', 'https://code.highcharts.com/modules/data.js', 'https://code.highcharts.com/modules/exporting.js', 'https://code.highcharts.com/modules/funnel.js', 'https://code.highcharts.com/6.0.2/modules/annotations.js', 'https://code.highcharts.com/modules/accessibility.js', // 'https://code.highcharts.com/modules/series-label.js' 'https://code.highcharts.com/modules/solid-gauge.js' ], cdnIncludesArr = [], title = chart.options && chart.options.title ? chart.options.title.text || 'untitled chart' : 'untitled chart'; id = id || ''; /* This magic code will generate an injection script that will check if highcharts is included, and include it if not. Afterwards, it will create the chart, and insert it into the page. It's quite messy, could to client-side templating or something, but it works. */ if (highed.option('includeCDNInExport')) { cdnIncludesArr = [ 'var files = ', JSON.stringify(cdnIncludes), ',', 'loaded = 0; ', 'if (typeof window["HighchartsEditor"] === "undefined") {', 'window.HighchartsEditor = {', 'ondone: [cl],', 'hasWrapped: false,', 'hasLoaded: false', '};', 'include(files[0]);', '} else {', 'if (window.HighchartsEditor.hasLoaded) {', 'cl();', '} else {', 'window.HighchartsEditor.ondone.push(cl);', '}', '}', 'function isScriptAlreadyIncluded(src){', 'var scripts = document.getElementsByTagName("script");', 'for (var i = 0; i < scripts.length; i++) {', 'if (scripts[i].hasAttribute("src")) {', 'if ((scripts[i].getAttribute("src") || "").indexOf(src) >= 0 || (scripts[i].getAttribute("src") === "http://code.highcharts.com/highcharts.js" && src === "https://code.highcharts.com/stock/highstock.js")) {', 'return true;', '}', '}', '}', 'return false;', '}', 'function check() {', 'if (loaded === files.length) {', 'for (var i = 0; i < window.HighchartsEditor.ondone.length; i++) {', 'try {', 'window.HighchartsEditor.ondone[i]();', '} catch(e) {', 'console.error(e);', '}', '}', 'window.HighchartsEditor.hasLoaded = true;', '}', '}', 'function include(script) {', 'function next() {', '++loaded;', 'if (loaded < files.length) {', 'include(files[loaded]);', '}', 'check();', '}', 'if (isScriptAlreadyIncluded(script)) {', 'return next();', '}', 'var sc=document.createElement("script");', 'sc.src = script;', 'sc.type="text/javascript";', 'sc.onload=function() { next(); };', 'document.head.appendChild(sc);', '}', 'function each(a, fn){', 'if (typeof a.forEach !== "undefined"){a.forEach(fn);}', 'else{', 'for (var i = 0; i < a.length; i++){', 'if (fn) {fn(a[i]);}', '}', '}', '}', 'var inc = {},incl=[]; each(document.querySelectorAll("script"), function(t) {inc[t.src.substr(0, t.src.indexOf("?"))] = 1; ', '});' ]; } const chartConstr = (constr.some(function(a) { return a === 'StockChart'; }) ? 'StockChart' : 'Chart'); return ( '\n' + [ '(function(){ ', cdnIncludesArr.join(''), ' function cl() {', 'if(typeof window["Highcharts"] !== "undefined"){', //' && Highcharts.Data ? ', !customizedOptions.lang ? '' : 'Highcharts.setOptions({lang:' + JSON.stringify(customizedOptions.lang) + '});', 'var options=', stringifyFn(getEmbeddableJSON(true)), ';', highed.isFn(customCode) ? customCodeStr : '', 'new Highcharts.' + chartConstr + '("', id, '", options);', '}', '}', '})();' ].join('') + '\n' ); }); } function getCodePreview() { var options = getEmbeddableJSON(true); if (highed.isFn(customCode) && customCodeStr) { customCode(options); } return stringifyFn(options, ' '); } /** Get embeddable HTML * @memberof highed.ChartPreview * @name export.html * @param placehold {bool} - if true, SVG will also be embedded * @returns {string} - a string of embeddable HTML */ function getEmbeddableHTML(placehold) { return gc(function(chart) { var id = 'highcharts-' + highed.uuid(); return ( '\n' + [ '
', placehold ? getEmbeddableSVG() : '', '
' ].join('') + '' ); }); } /** * Expand the chart from its drawer * @memberof highed.ChartPreview */ function expand() { gc(function(chart) { if (!expanded) { highed.dom.style(properties.expandTo, { width: '100%', display: 'block' }); preExpandSize = highed.dom.size(parent); init(chart.options, properties.expandTo); expanded = true; toggleButton.className = 'highed-icon highed-chart-preview-expand fa fa-times-circle'; } }); } /** Collapse the chart into its drawer * @memberof highed.ChartPreview */ function collapse() { gc(function(chart) { if (preExpandSize && expanded) { highed.dom.style(properties.expandTo, { width: '0px', display: 'none' }); toggleButton.className = 'highed-icon highed-chart-preview-expand fa fa-external-link-square'; init(chart.options, parent); expanded = false; } }); } /** Flush all options and start over * @memberof highed.ChartPreview * @name new */ function newChart() { highed.cloud.flush(); templateOptions = []; highed.clearObj(customizedOptions); highed.clearObj(flatOptions); customCode = false; // highed.merge(customizedOptions, properties.defaultChartOptions); updateAggregated(); init(aggregatedOptions); emitChange(); events.emit('New'); } /** Export the chart - calls `Highcharts.Chart.exportChart(..)` * @memberof highed.ChartPreview * @name data.export * @param optons {object} - the export options */ function exportChart(options) { gc(function(chart) { chart.exportChart(options, aggregatedOptions); }); } /** Attach to a new DOM parent * @memberof highed.ChartPreview * @param newParent {DOMNode} - the node to attach to */ function changeParent(newParent) { parent = newParent; init(); } /** Returns the constructor currently in use * @memberof highed.ChartPreview * @returns {string} */ function getConstructor() { return (constr.some(function(a) { return a === 'StockChart'; }) ? 'StockChart' : 'Chart'); } function getTheme() { return { id: themeMeta.id, name: themeMeta.name, options: themeOptions }; } function getCustomCode() { return customCodeStr && customCodeStr.length ? customCodeStr : customCodeDefault; // return highed.isFn(customCode) ? // customCodeStr || customCodeDefault : // customCode || customCodeDefault; } function setCustomCode(newCode, errFn, skipEmit) { var fn; if (!newCode) { customCode = false; customCodeStr = ''; } try { // eval('(var options = {};' + newCode + ')'); customCode = new Function( 'options', [ 'if (options.yAxis && options.yAxis.length === 1) options.yAxis = options.yAxis[0];', 'if (options.xAxis && options.xAxis.length === 1) options.xAxis = options.xAxis[0];', 'if (options.zAxis && options.zAxis.length === 1) options.zAxis = options.zAxis[0];', 'if (!options.series || options.series.length === 0) return;', 'var encodedUrl = "";', themeCustomCode ].join('') + newCode ); customCodeStr = newCode; } catch (e) { customCode = false; customCodeStr = newCode; return highed.isFn(errFn) && errFn(e); } if (!skipEmit) { updateAggregated(); if (!customizedOptions.data || (customizedOptions && customizedOptions.data && !customizedOptions.data.googleSpreadsheetKey)) { init(aggregatedOptions); } emitChange(); } } function setIsAnnotating(isAnnotate) { isAnnotating = isAnnotate } function setAnnotationType(type) { annotationType = type; } function addLabel(x, y, text, color, type) { if (chart) { if (!customizedOptions.annotations) customizedOptions.annotations = []; var annotation = chart.addAnnotation({ id: "label_" + customizedOptions.annotations.length, labels: [{ id: "label_" + customizedOptions.annotations.length, text: text, point: { x: x, y: y, xAxis: 0, yAxis: 0 }, backgroundColor: color, shape: type, borderWidth: type !== 'connector' ? 0 : 1, x: 0, y: type === 'circle' ? 0 : -16 }] }); customizedOptions.annotations.push({ id: "label_" + customizedOptions.annotations.length, labels: [annotation.options.labels[0]] }); } } function addAnnotationLabel(x, y, text, color, type) { addLabel(x, y, text, color, type); } /////////////////////////////////////////////////////////////////////////// //Init the initial chart updateAggregated(); init(); highed.dom.on(toggleButton, 'click', function() { return expanded ? collapse() : expand(); }); function addBlankSeries(index, type) { if (!customizedOptions.series[index]) { customizedOptions.series[index] = { data:[], turboThreshold: 0, _colorIndex: index, _symbolIndex: 0, compare: undefined }; } if(type) customizedOptions.series[index].type = type; //Init the initial chart updateAggregated(); init(); } function addAnnotation(e) { var xValue = chart.xAxis[0].toValue(e.chartX), yValue = chart.yAxis[0].toValue(e.chartY); if (!chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) return; if (!customizedOptions.annotations) customizedOptions.annotations = []; //[{}]; if (annotationType === 'label') { events.emit('ShowTextDialog', chart, xValue, yValue); } else if (annotationType === 'delete'){ } else { addShape(chart, annotationType, xValue, yValue/*e.chartX - this.plotLeft, e.chartY - this.plotTop*/); } } /////////////////////////////////////////////////////////////////////////// exports = { assignTheme: assignTheme, clearTheme: clearTheme, getTheme: getTheme, getConstructor: getConstructor, on: events.on, expand: expand, collapse: collapse, new: newChart, changeParent: changeParent, getHighchartsInstance: gc, loadTemplate: loadTemplate, loadTemplateForSerie: loadTemplateForSerie, loadSeries: loadSeriesData, resize: resize, setCustomCode: setCustomCode, getCustomCode: getCustomCode, toProject: toProject, toProjectStr: toProjectStr, loadProject: loadProject, toString: toString, setIsAnnotating: setIsAnnotating, setAnnotationType: setAnnotationType, addAnnotationLabel: addAnnotationLabel, addAnnotation: addAnnotation, options: { set: set, setAll: setChartOptions, customized: customizedOptions, getCustomized: function() { return customizedOptions; }, full: aggregatedOptions, flat: flatOptions, chart: chartOptions, getPreview: getCodePreview, all: function(){ return chart; }, addBlankSeries: addBlankSeries, togglePlugins: togglePlugins, getTemplateSettings: getTemplateSettings }, data: { csv: loadCSVData, json: loadJSONData, settings: loadChartSettings, export: exportChart, gsheet: loadGSpreadsheet, clear: clearData, live: loadLiveData, setDataTableCSV: setDataTableCSV, setAssignDataFields: setAssignDataFields, deleteSerie: deleteSerie, deleteSeries: deleteSeries }, export: { html: getEmbeddableHTML, json: getEmbeddableJSON, svg: getEmbeddableSVG, js: getEmbeddableJavaScript } }; return exports; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format (function() { var modal = highed.OverlayModal(false, { showOnInit: false, zIndex: 11000, width: 300, height: 400 }); highed.dom.ap( modal.body, highed.dom.cr('span', '', 'License info goes here') ); highed.licenseInfo = { /** Show license information modal * @namespace highed.licenseInfo * @type function */ show: modal.show }; })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format (function() { var flatOptions = {}; function dive(tree) { if (tree) { if (highed.isArr(tree)) { tree.forEach(dive); } else if (tree.options) { if (highed.isArr(tree.options)) { tree.options.forEach(dive); } else { Object.keys(tree.options).forEach(function(key) { dive(tree.options[key]); }); } } else if (tree.id) { flatOptions[tree.id] = tree; } } } dive(highed.meta.optionsExtended); /** Simple version of the customizer. Whitelisted options * @constructor * @emits PropertyChange - when a property is modified * @param parent {domnode} - the node to append to * @param attributes {object} - settings * > availableSettings {array} - whitelist of options to include */ highed.SimpleCustomizer = function(parent, attributes) { var events = highed.events(), container = highed.dom.cr('div', 'highed-simple-customizer'), table = highed.dom.cr('table', 'highed-customizer-table'), properties = highed.merge( { availableSettings: [ 'title--text', 'subtitle--text', 'colors', 'chart--backgroundColor', 'yAxis-title--style', 'yAxis--type', 'yAxis--opposite', 'yAxis--reversed', 'yAxis-labels--format' ] }, attributes ); //////////////////////////////////////////////////////////////////////// /** Build the property setter * @memberof highed.SimpleCustomizer * @param options {object} - the current chart options */ function build(options) { table.innerHTML = ''; properties.availableSettings.forEach(function(name) { var group = highed.merge( { text: name.replace(/\-/g, ' '), id: name, tooltipText: false, dataType: 'string', defaults: false, custom: {}, values: false }, flatOptions[name] ); highed.dom.ap( table, highed.InspectorField( group.values ? 'options' : group.dataType, highed.getAttr(options, group.id, 0) || group.defaults, { title: group.text, tooltip: group.tooltipText, values: group.values, custom: group.custom, defaults: group.defaults, attributes: group.attributes || [] }, function(newValue) { events.emit('PropertyChange', group.id, newValue, 0); }, false, group.id ) ); }); } function highlightNode(n) { if (!n) return; highed.dom.style(n, { border: '2px solid #33aa33' }); n.focus(); n.scrollIntoView(true); window.setTimeout(function() { highed.dom.style(n, { border: '' }); }, 2000); } /** Focus a field in the inspector * @memberof highed.SimpleCustomizer * @param thing {object} - the thing to focus * > id {anything} - the id of the field * @param x {number} - the x position the request came from * @param y {number} - the y position the request came from */ function focus(thing, x, y) { var id = thing.id; if (id.indexOf('-') >= 0) { highlightNode(table.querySelector('#' + id)); } } //////////////////////////////////////////////////////////////////////// highed.ready(function() { highed.dom.ap( parent, highed.dom.ap( container, highed.dom.cr('div', 'highed-customizer-table-heading', 'Edit Chart'), table ) ); }); return { focus: focus, on: events.on, build: build }; }; })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format (function() { function createTeamDropDown(target) { var dropdown = highed.DropDown(target); function refresh() { dropdown.clear(); highed.cloud.getTeams(function(teamCollection) { teamCollection.forEach(function(team) { dropdown.addItem({ id: team.id, title: team.name }); }); dropdown.selectByIndex(0); }); } return { refresh: refresh, dropdown: dropdown }; } var chartPreview = false, modal = highed.OverlayModal(document.body, { //eslint-disable-line no-undef showOnInit: false, width: '90%', height: '90%', zIndex: 10001 }), mainContainer = highed.dom.cr('div'), charts = highed.dom.cr('div', 'highed-cloud-chart-container'), teams = createTeamDropDown(mainContainer), pageNavigation = highed.dom.cr('div', 'highed-cloud-paging'), activeTeam, activeChart, saveNewModal = highed.OverlayModal(document.body, { //eslint-disable-line no-undef showOnInt: false, width: 400, height: 300, zIndex: 10001 }), saveNewTeamsContainer = highed.dom.cr('div'), saveNewTeams = createTeamDropDown(saveNewTeamsContainer), saveNewName = highed.dom.cr('input', 'highed-field-input'), saveNewBtn = highed.dom.cr('button', 'highed-ok-button', 'Save to cloud'), loginForm = false; highed.dom.ap( saveNewModal.body, highed.dom.cr('h2', 'highed-titlebar', 'Save to Cloud'), highed.dom.cr('div', '', 'Team'), saveNewTeamsContainer, highed.dom.cr('br'), highed.dom.cr('div', '', 'Chart Name'), saveNewName, saveNewBtn ); highed.dom.on(saveNewBtn, 'click', function() { saveNewBtn.disabled = true; saveNewBtn.innerHTML = 'SAVING TO CLOUD...'; highed.cloud.saveNewChart( activeTeam, saveNewName.value, JSON.stringify(chartPreview.toProject()), function(data) { saveNewBtn.disabled = false; if (!data.error && data) { activeChart = data; saveNewModal.hide(); saveNewBtn.innerHTML = 'SAVE TO CLOUD'; highed.snackBar('SAVED TO CLOUD'); } else { highed.snackBar('Error saving to cloud'); } } ); }); saveNewTeams.dropdown.on('Change', function(item) { activeTeam = item.id(); }); function addChart(chart) { var container = highed.dom.cr('div', 'highed-cloud-chart'), thumbnail = highed.dom.cr('div', 'highed-cloud-thumbnail'); highed.dom.ap( charts, highed.dom.ap( container, thumbnail, highed.dom.cr('div', 'highed-cloud-chart-title', chart.name) ) ); highed.dom.style(thumbnail, { 'background-image': 'url(' + chart.thumbnail_url + '?t=' + new Date().getTime() + ')' }); highed.dom.on(thumbnail, 'click', function() { if (chartPreview) { highed.cloud.getChart(chart.team_owner, chart.id, function(data) { try { chartPreview.loadProject(JSON.parse(data.data)); activeChart = chart.id; activeTeam = chart.team_owner; modal.hide(); } catch (e) { highed.snackbar(e); } }); } }); } highed.dom.ap( modal.body, highed.dom.cr( 'h2', 'highed-titlebar', 'Load project from Highcharts Cloud' ), highed.dom.ap(mainContainer, charts, pageNavigation) ); function getCharts(page, teamID) { // Load charts here charts.innerHTML = 'Loading Charts'; highed.cloud.getCharts( teamID, function(chartCollection, full) { charts.innerHTML = ''; pageNavigation.innerHTML = ''; if (full.pageCount > 1) { for (var i = 1; i <= full.pageCount; i++) { (function(pageIndex) { var item = highed.dom.cr('span', 'highed-cloud-paging-item', i); if (pageIndex === page) { item.className += ' selected'; } highed.dom.on(item, 'click', function() { getCharts(pageIndex, teamID); }); highed.dom.ap(pageNavigation, item); })(i); } } chartCollection.forEach(addChart); }, page ); } teams.dropdown.on('Change', function(item) { getCharts(false, item.id()); }); highed.cloud.flush = function() { activeChart = false; activeTeam = false; }; highed.cloud.save = function(chartp) { highed.cloud.loginForm(function() { saveNewName.value = ''; saveNewName.focus(); chartPreview = chartp || chartPreview; if (activeChart && activeTeam) { // Save project highed.cloud.saveExistingChart( activeTeam, activeChart, JSON.stringify(chartPreview.toProject()), function() { highed.snackbar('CHART SAVED TO CLOUD'); } ); } else { // Show save as new UI saveNewModal.show(); saveNewTeams.refresh(); } }); }; highed.cloud.showUI = function(preview) { highed.cloud.loginForm(function() { chartPreview = preview; modal.show(); teams.refresh(); }); }; function createLoginForm() { var body = highed.dom.cr('div', 'highed-cloud-login-container'), username = highed.dom.cr('input', 'highed-cloud-input'), password = highed.dom.cr('input', 'highed-cloud-input'), btn = highed.dom.cr('button', 'highed-ok-button', 'LOGIN'), notice = highed.dom.cr('div', 'highed-cloud-login-error'), loginCallback = false, modal = highed.OverlayModal(false, { height: 300, width: 250, zIndex: 10001 }); username.name = 'cloud-username'; password.name = 'cloud-password'; username.placeholder = 'E-Mail'; password.placeholder = 'Your password'; password.type = 'password'; highed.dom.ap( modal.body, highed.dom.ap( body, highed.dom.cr('h3', '', 'Login to Highcharts Cloud'), notice, username, password, btn, highed.dom.cr( 'div', 'highed-cloud-login-notice', 'Requires a Highcharts Cloud account' ) ) ); highed.dom.on(btn, 'click', function() { btn.disabled = true; highed.dom.style(notice, { display: 'none' }); highed.cloud.login(username.value, password.value, function(err, res) { btn.disabled = false; if (err || !res || typeof res.token === 'undefined') { notice.innerHTML = 'Error: Check username/password (' + (err || res.message) + ')'; highed.dom.style(notice, { display: 'block' }); } else { modal.hide(); if (highed.isFn(loginCallback)) { loginCallback(); } } }); }); return function(fn) { loginCallback = fn || function() {}; if (highed.cloud.isLoggedIn()) { loginCallback(); } else { modal.show(); } }; } highed.cloud.loginForm = function(fn) { if (!loginForm) { loginForm = createLoginForm(); } loginForm(fn); }; })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /* global window */ highed.DrawerEditor = function(parent, options, planCode) { var events = highed.events(), // Main properties properties = highed.merge( { defaultChartOptions: {}, useHeader: true, features: [ 'data', 'templates', 'customize', 'customcode', 'advanced', 'export' ], importer: {}, dataGrid: {}, customizer: {}, toolbarIcons: [] }, options ), errorBar = highed.dom.cr( 'div', 'highed-errorbar highed-box-size highed-transition' ), errorBarHeadlineContainer = highed.dom.cr( 'div', 'highed-errorbar-headline' ), errorBarHeadline = highed.dom.cr( 'div', 'highed-errorbar-headline-text', 'This is an error!' ), errorBarClose = highed.dom.cr( 'div', 'highed-errorbar-close', '' ), errorBarBody = highed.dom.cr( 'div', 'highed-errorbar-body highed-scrollbar', 'Oh noes! something is very wrong!' ), lastSetWidth = false, fixedSize = false, splitter = highed.VSplitter(parent, { topHeight: properties.useHeader ? '60px' : '0px', noOverflow: true }), builtInOptions = { data: { icon: 'fa-table', title: 'Data', widths: { desktop: 66, tablet: 64, phone: 100 }, nav: { icon: 'table', text: 'Data', onClick: [] }, help: [ { title: 'Manually Add/Edit Data', gif: 'dataImport.gif', description: [ 'Click a cell to edit its contents.

', 'The cells can be navigated using the arrow keys.

', 'Pressing Enter creates a new row, or navigates to the row directly below the current row.' ] }, { title: 'Setting headings', gif: 'dataImport.gif', description: [ 'The headings are used as the series titles.

', 'They can be edited by left clicking them.

', 'Click the arrow symbol in the header to access column properties.' ] }, { title: 'Importing Data', gif: 'import.gif', description: [ 'To import data, simply drag and drop CSV files onto the table, or paste CSV/Excel data into any cell.

', 'For more advanced data import, click the IMPORT DATA button.' ] } ], showLiveStatus: true }, templates: { icon: 'fa-bar-chart', widths: { desktop: 26, tablet: 24, phone: 100 }, title: 'Templates', nav: { icon: 'bar-chart', text: 'Templates', onClick: [] }, help: [ { title: 'Templates', description: [ 'Templates are pre-defined bundles of configuration.

', 'Start by choosing the template category in the list to the left,', 'then pick a suitable template for your data and use case in the', 'template list.' ] } ] }, customize: { icon: 'fa-sliders', title: 'Customize Chart', nav: { icon: 'pie-chart', text: 'Customize', onClick: [] }, widths: { desktop: 27, tablet: 24, phone: 100 }, help: [ { title: 'Customize', description: [ 'The customize pane lets you customize your chart.

', 'The customizer has three different sections:
', '
  • Simple: A simple customizer with the most used options
  • ', '
  • Advanced: All options available in Highcharts/Highstock can be set here
  • ', '
  • Custom code: Here, properties can be overridden programatically
  • ' ] } ] }, }, workspaceBody = highed.dom.cr( 'div', 'highed-optionspanel-body highed-box-size highed-transition' ), workspaceButtons = highed.dom.cr( 'div', 'highed-optionspanel-buttons highed-optionspanel-cloud highed-box-size highed-transition' ), smallScreenWorkspaceButtons = highed.dom.cr( 'div', 'highed-xs-workspace-buttons highed-optionspanel-xs-cloud highed-box-size highed-transition' ), workspaceRes = highed.dom.cr( 'div', 'highed-optionspanel-buttons highed-optionspanel-res highed-box-size highed-transition' ), defaultPage, panel = highed.OptionsPanel(workspaceBody), toolbar = highed.Toolbar(splitter.top), // Chart preview highedChartContainer = highed.dom.cr('div', 'highed-chart-container highed-transition'), chartFrame = highed.dom.cr( 'div', 'highed-transition highed-box-size highed-chart-frame highed-scrollbar' ), showChartSmallScreen = highed.dom.cr( 'div', 'highed-transition highed-box-size highed-show-chart-xs', '' ), chartContainer = highed.dom.cr( 'div', 'highed-box-size highed-chart-frame-body' ), chartPreview = highed.ChartPreview(chartContainer, { defaultChartOptions: properties.defaultChartOptions }), suppressWarning = false, dataTableContainer = highed.dom.cr('div', 'highed-box-size highed-fill'), customizePage = highed.CustomizePage( splitter.bottom, highed.merge( { importer: properties.importer }, properties.customizer ), chartPreview, highedChartContainer, builtInOptions.customize, chartFrame, planCode ), dataPage = highed.DataPage( splitter.bottom, highed.merge( { importer: properties.importer }, properties.dataGrid ), chartPreview, highedChartContainer, builtInOptions.data ), templatePage = highed.TemplatePage( splitter.bottom, highed.merge( { importer: properties.importer }, properties.dataGrid ), chartPreview, highedChartContainer, builtInOptions.templates ); createChartPage = highed.CreateChartPage( splitter.bottom, properties.features, { title: 'Create Chart', widths: { desktop: 95 } } ), // Res preview bar resPreviewBar = highed.dom.cr('div', 'highed-res-preview'), resWidth = highed.dom.cr('input', 'highed-res-number'), resHeight = highed.dom.cr('input', 'highed-res-number'), // Exporter exporterContainer = highed.dom.cr('div', 'highed-box-size highed-fill'), exporter = highed.Exporter(exporterContainer), // Templates templatesContainer = highed.dom.cr('div', 'highed-box-size highed-fill'), templates = highed.ChartTemplateSelector(templatesContainer, chartPreview), // Customizer customizerContainer = highed.dom.cr('div', 'highed-box-size highed-fill'), customizer = highed.ChartCustomizer( customizerContainer, properties.customizer, chartPreview ), // Toolbar buttons toolbarButtons = [ { title: highed.L('newChart'), css: 'fa-file', click: function() { if (window.confirm(highed.getLocalizedStr('confirmNewChart'))) { chartPreview.new(); } } }, { title: highed.L('saveProject'), css: 'fa-floppy-o', click: function() { var name; if (chartPreview.options.full.title) { name = chartPreview.options.full.title.text; } name = (name || 'chart').replace(/\s/g, '_'); highed.download(name + '.json', chartPreview.toProjectStr()); } }, { title: highed.L('openProject'), css: 'fa-folder-open', click: function() { highed.readLocalFile({ type: 'text', accept: '.json', success: function(file) { try { file = JSON.parse(file.data); } catch (e) { return highed.snackBar('Error loading JSON: ' + e); } chartPreview.loadProject(file); } }); } }, '-', { title: highed.L('saveCloud'), css: 'fa-cloud-upload', click: function() { highed.cloud.save(chartPreview); } }, { title: highed.L('loadCloud'), css: 'fa-cloud-download', click: function() { highed.cloud.showUI(chartPreview); } }, '-', { title: 'Help', css: 'fa-question-circle', click: function() { window.open(highed.option('helpURL')); } } ].concat(properties.toolbarIcons), // Custom toolbox options customOptions = {}, // The toolbox options helpIcon = highed.dom.cr( 'div', 'highed-toolbox-help highed-icon fa fa-question-circle' ), titleHeader = highed.dom.cr('h3', '', 'Data'), iconContainer = highed.dom.cr('div', ''), titleContainer = highed.dom.ap(highed.dom.cr('div', 'highed-page-title'), titleHeader, helpIcon, iconContainer), helpModal = highed.HelpModal(builtInOptions.data.help || []); highed.dom.on(helpIcon, 'click', showHelp); highed.dom.ap(splitter.bottom, highed.dom.ap(workspaceBody, workspaceRes, workspaceButtons)); highed.dom.ap(splitter.bottom, titleContainer, smallScreenWorkspaceButtons); if (!properties.useHeader) { highed.dom.style(splitter.top.parentNode, { display: 'none' }); } highed.dom.on(showChartSmallScreen, 'click', function() { if (highedChartContainer.classList.contains('active')) { highedChartContainer.classList.remove('active'); } else { setTimeout(function(){ chartPreview.resize(); }, 200); highedChartContainer.classList += ' active'; } }); // Alias import to data builtInOptions.import = builtInOptions.data; panel.setDefault(dataPage); dataPage.show() /** * Creates the features defined in property.features * Call this after changing properties.features to update the options. */ function createFeatures() { var addedOptions = {}; panel.clearOptions(); properties.features = highed.isArr(properties.features) ? properties.features : properties.features.split(' '); function addOption(option, id) { if (!option || !option.icon || !option.nav) { return; } if (id === 'data') { option.nav.page = dataPage; dataPage.init(); option.nav.onClick.push( function() { highed.dom.style([highedChartContainer, chartContainer, chartFrame], { width: '100%', height: '100%', }); } ); } else if (id === 'templates') { option.nav.page = templatePage; templatePage.init(); } else if (id === 'customize') { option.nav.page = customizePage; customizePage.init(); highed.dom.ap(workspaceRes, customizePage.getResolutionContainer()); } else { // Create page defaultPage = highed.DefaultPage(splitter.bottom, option, chartPreview, highedChartContainer); defaultPage.init(); option.nav.page = defaultPage; } var func = function(prev, newOption) { prev.hide(); newOption.page.show(); panel.setDefault(newOption.page); titleHeader.innerHTML = newOption.text; helpModal = (option.help ? highed.HelpModal(option.help || []) : null); highed.dom.style(helpIcon, { display: (helpModal ? 'inline' : 'none') }); iconContainer.innerHTML = ''; if (newOption.page.getIcons()) { highed.dom.ap(iconContainer, newOption.page.getIcons()); } highed.dom.style(iconContainer, { display: (newOption.page.getIcons() ? 'inline' : 'none') }); } if (id == 'customize') { option.nav.onClick = [func]; } else { option.nav.onClick.push(func); } panel.addOption(option.nav, id); addedOptions[id] = id; } //toolbox.clear(); resize(); properties.features.forEach(function(feature) { addOption( builtInOptions[feature] || customOptions[feature] || false, feature ); }); toolboxEntries = addedOptions; // resizeChart(toolbox.width()); } function showHelp() { helpModal.show(); } /** * Create toolbar */ function createToolbar() { toolbarButtons.forEach(function(b) { if (b === '-') { toolbar.addSeparator(); } else { toolbar.addIcon(b); } }); } function showCreateChartPage() { createChartPage.init(dataPage, templatePage, customizePage); highed.dom.style([workspaceBody, showChartSmallScreen, smallScreenWorkspaceButtons], { opacity: 0 }); panel.getPrev().hide(); createChartPage.show(); highed.dom.style([chartFrame, titleContainer], { opacity: '0' }); if(highed.onPhone()) { highed.dom.style(titleContainer, { display: 'none' }); } createChartPage.on('SimpleCreateChartDone', function(goToDataPage) { createChartPage.hide(); highed.dom.style([chartFrame, titleContainer], { opacity: '1' }); highed.dom.style([workspaceBody, showChartSmallScreen, smallScreenWorkspaceButtons], { opacity: 1 }); if(highed.onPhone()) { highed.dom.style(titleContainer, { display: 'block' }); } if (goToDataPage) { dataPage.show(); panel.setDefault(dataPage); dataPage.resize(); } else { const customize = panel.getOptions().customize; if (customize) { customizePage.setTabBehaviour(true) customize.click(); } /* titleHeader.innerHTML = builtInOptions.customize.title; customizePage.show(); panel.setDefault(customizePage);*/ } }); createChartPage.on('SimpleCreateChangeTitle', function(options) { chartPreview.options.set('title--text', options.title); chartPreview.options.set('subtitle--text', options.subtitle); setChartTitle(options.title); }); } /** * Resize the chart preview based on a given width */ function resizeChart(newWidth) { var psize = highed.dom.size(splitter.bottom); lastSetWidth = newWidth; highed.dom.style(highedChartContainer, { /*left: newWidth + 'px',*/ width: '28%', height: '37%' }); if (fixedSize) { // Update size after the animation is done setTimeout(function() { sizeChart(fixedSize.w, fixedSize.h); }, 400); return; } /* highed.dom.style(chartContainer, { width: psize.w - newWidth - 100 + 'px', height: psize.h - 100 + 'px' });*/ chartPreview.resize(); } function sizeChart(w, h) { if ((!w || w.length === 0) && (!h || h.length === 0)) { fixedSize = false; resHeight.value = ''; resWidth.value = ''; resizeChart(lastSetWidth); } else { var s = highed.dom.size(highedChartContainer); // highed.dom.style(chartFrame, { // paddingLeft: (s.w / 2) - (w / 2) + 'px', // paddingTop: (s.h / 2) - (h / 2) + 'px' // }); fixedSize = { w: w, h: h }; w = w || s.w - 100; h = h || s.h - 100; /* highed.dom.style(chartContainer, { width: w + 'px', height: h + 'px' }); */ chartPreview.resize(); } } /** * Resize everything */ function resize() { splitter.resize(); panel.getPrev().resize() //resizeChart(toolbox.width()); } /** * Change the enabled features */ function setEnabledFeatures(feats) { properties.features = feats; createFeatures(); } /** * Add a new feature */ function addFeature(name, feat) { customOptions[name] = feat; //addPage(feat); createFeatures(); } function addToWorkspace(options) { const btn = highed.dom.cr('button', 'highed-import-button green action-btn', "Action "); const btn2 = highed.dom.cr('button', 'highed-import-button green action-btn', "Action "); highed.dom.on(btn, 'click', function() { highed.dom.style(workspaceButtons, { overflow: (workspaceButtons.style.overflow === '' || workspaceButtons.style.overflow === 'hidden' ? 'unset' : 'hidden') }); }); highed.dom.on(btn2, 'click', function() { highed.dom.style(smallScreenWorkspaceButtons, { overflow: (smallScreenWorkspaceButtons.style.overflow === '' || smallScreenWorkspaceButtons.style.overflow === 'hidden' ? 'unset' : 'hidden') }); }); highed.dom.ap(workspaceButtons, btn); highed.dom.ap(smallScreenWorkspaceButtons, btn2); options.forEach(function(option, index) { const btn = highed.dom.cr('button', 'highed-import-button green highed-sm-dropdown-button' + (!index ? ' highed-btn-dropdown-first' : ''), option.text); highed.dom.on(btn, 'click', option.onClick); const btn2 = highed.dom.cr('button', 'highed-import-button green highed-sm-dropdown-button' + (!index ? ' highed-btn-dropdown-first' : ''), option.text); highed.dom.on(btn2, 'click', option.onClick); highed.dom.ap(workspaceButtons, btn); highed.dom.ap(smallScreenWorkspaceButtons, btn2); }); } function destroy() {} function setChartTitle(title) { dataPage.setChartTitle(title); } function addImportTab(tabOptions) { dataPage.addImportTab(tabOptions); } function hideImportModal() { //dataTable.hideImportModal(); } function showError(title, message, warning, code) { if (warning) { if (suppressWarning) return; highed.dom.style(errorBarClose, { display: 'inline-block' }); if (!errorBar.classList.contains('highed-warningbar')) errorBar.classList += ' highed-warningbar'; } else { highed.dom.style(errorBarClose, { display: 'none' }); errorBar.classList.remove('highed-warningbar'); } highed.dom.style(errorBar, { opacity: 1, 'pointer-events': 'auto', }); errorBarHeadline.innerHTML = title; errorBarBody.innerHTML = message; if (code === 14) { dataPage.showDataTableError(); } } function hideError() { highed.dom.style(errorBar, { opacity: 0, 'pointer-events': 'none' }); dataPage.hideDataTableError(); } ////////////////////////////////////////////////////////////////////////////// // Event attachments dataPage.on('GoToTemplatePage', function() { const templates = panel.getOptions().templates; if (templates) templates.click(); }); dataPage.on('SeriesChanged', function(index) { if ((!options && !options.features) || (options.features && options.features.indexOf('templates') > -1)) { templatePage.selectSeriesTemplate(index, chartPreview.options.getTemplateSettings()); } }); chartPreview.on('LoadProject', function (projectData, aggregated) { dataPage.loadProject(projectData, aggregated); templatePage.selectSeriesTemplate(0, projectData); }); templatePage.on('TemplateChanged', function(newTemplate, loadTemplateForEachSerie, cb){ dataPage.changeAssignDataTemplate(newTemplate, loadTemplateForEachSerie, cb); }) chartPreview.on('ChartChange', function(newData) { events.emit('ChartChangedLately', newData); }); templates.on('Select', function(template) { chartPreview.loadTemplate(template); }); templates.on('LoadDataSet', function(sample) { if (sample.type === 'csv') { if (highed.isArr(sample.dataset)) { chartPreview.data.csv(sample.dataset.join('\n')); } else { chartPreview.data.csv(sample.dataset); } chartPreview.options.set('subtitle-text', ''); chartPreview.options.set('title-text', sample.title); } }); /* dataTable.on('LoadLiveData', function(settings){ //chartPreview.data.live(settings); const liveDataSetting = {}; liveDataSetting[settings.type] = settings.url; if (settings.interval && settings.interval > 0){ liveDataSetting.enablePolling = true; liveDataSetting.dataRefreshRate = settings.interval } chartPreview.data.live(liveDataSetting); });*/ /* dataTable.on('UpdateLiveData', function(p){ chartPreview.data.liveURL(p); }); */ chartPreview.on('LoadProject', function () { setTimeout(function () { // resQuickSel.selectByIndex(0); setToActualSize(); }, 2000); }); /* dataTable.on('LoadGSheet', function(settings) { //chartPreview.data.gsheet(settings); }); */ chartPreview.on('RequestEdit', function(event, x, y) { const customize = panel.getOptions().customize; if (!panel.getCurrentOption() || panel.getCurrentOption().text !== 'Customize') { if (customize) { customizePage.setTabBehaviour(false) customize.click(); } } setTimeout(function() { customizePage.selectOption(event, x, y); }, 500); }); /* dataTable.on('Change', function(headers, data) { return chartPreview.data.csv({ csv: dataTable.toCSV(';', true) }); });*/ /* dataTable.on('ClearData', function() { chartPreview.data.clear(); });*/ chartPreview.on('ProviderGSheet', function(p) { /* dataTable.initGSheet( p.id || p.googleSpreadsheetKey, p.worksheet || p.googleSpreadsheetWorksheet, p.startRow, p.endRow, p.startColumn, p.endColumn, true, p.dataRefreshRate );*/ }); chartPreview.on('ProviderLiveData', function(p) { //dataTable.loadLiveDataPanel(p); }); chartPreview.on('Error', function(e) { if (e && e.code && highed.highchartsErrors[e.code]) { var item = highed.highchartsErrors[e.code], url = ''; if (e.url >= 0) { url = ''; } return showError( (item.title || "There's a problem with your chart") + '!', (item.text) + url, e.warning, e.code ); } showError("There's a problem with your chart!", e); }); chartPreview.on('ChartRecreated', hideError); highed.dom.on(window, 'resize', resize); highed.dom.on(window, 'afterprint', function() { setTimeout(function() { const currentOption = (panel.getCurrentOption() ? panel.getCurrentOption().page : dataPage); setTimeout(currentOption.resize, 10); resize(); }, 1100); }) ////////////////////////////////////////////////////////////////////////////// highed.dom.ap( toolbar.left, highed.dom.style(highed.dom.cr('span'), { 'margin-left': '2px', width: '200px', height: '60px', float: 'left', display: 'inline-block', 'background-position': 'left middle', 'background-size': 'auto 100%', 'background-repeat': 'no-repeat', 'background-image': 'url("data:image/svg+xml;utf8,' + encodeURIComponent(highed.resources.logo) + '")' }) ); highed.dom.on(errorBarClose, 'click', function() { hideError(); suppressWarning = true; }); highed.dom.ap( splitter.bottom, highed.dom.ap( highedChartContainer, highed.dom.ap(chartFrame, chartContainer) ), showChartSmallScreen, highed.dom.ap(errorBar, highed.dom.ap(errorBarHeadlineContainer, errorBarHeadline, errorBarClose), errorBarBody) ); highed.dom.on([resWidth, resHeight], 'change', function() { sizeChart(parseInt(resWidth.value, 10), parseInt(resHeight.value, 10)); }); // Create the features createFeatures(); createToolbar(); resize(); function setToActualSize() { resWidth.disabled = resHeight.disabled = 'disabled'; chartPreview.getHighchartsInstance(function(chart) { var w, h; if (!chart || !chart.options || !chart.options.chart) { h = 400; } else { w = chart.options.chart.width; h = chart.options.chart.height || 400; } resWidth.value = w; resHeight.value = h; sizeChart(w, h); }); /* highed.dom.style(chartFrame, { 'overflow-x': 'auto' });*/ } chartPreview.on('AttrChange', function(option) { if (option.id === 'chart.height' || option.id === 'chart.width') { //resQuickSel.selectByIndex(0); // setToActualSize(); } }); chartPreview.on('SetResizeData', function () { setToActualSize(); }); return { on: events.on, resize: resize, destroy: destroy, /* Get embeddable javascript */ getEmbeddableHTML: chartPreview.export.html, /* Get embeddable json */ getEmbeddableJSON: chartPreview.export.json, /* Get embeddable SVG */ getEmbeddableSVG: chartPreview.export.svg, addImportTab: addImportTab, hideImportModal: hideImportModal, setEnabledFeatures: setEnabledFeatures, addFeature: addFeature, chart: chartPreview, toolbar: toolbar, getChartTitle: dataPage.getChartTitle, setChartTitle: setChartTitle, showCreateChartPage: showCreateChartPage, addToWorkspace: addToWorkspace, data: { on: function() {}, //dataTable.on, showLiveStatus: function() {}, //toolbox.showLiveStatus, hideLiveStatus: function() {} //toolbox.hideLiveStatus }, //dataTable: dataTable, toolbar: toolbar }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format // Alias to drawer editor highed.Editor = highed.DrawerEditor; (function() { var instanceCount = 0, installedPlugins = {}, activePlugins = {}, pluginEvents = highed.events(), stepPlugins = {}; /////////////////////////////////////////////////////////////////////////// /** Install an editor plugin * * Note that plugins must be enabled when creating the editor * for it to be active. * * @namespace highed.plugins.editor * * @param name {string} - the name of the plugin * @param definition {object} - the plugin definition * > meta {object} * > version {string} * > author {string} * > homepage {string} * > dependencies {array} - URLs of script dependencies * > options {object} * > option_name {object} * > type {string} - the type of the option * > label {string} - the label * > default {anything} - the default value */ function install(name, definition) { var properties = highed.merge( { meta: { version: 'unknown', author: 'unknown', homepage: 'unknown' }, dependencies: [], options: {} }, definition ); console.error('Warning: editor plugins are no longer supported.'); properties.dependencies.forEach(highed.include); if (!highed.isNull(installedPlugins[name])) { return highed.log(1, 'plugin -', name, 'is already installed'); } installedPlugins[name] = properties; } function use(name, options) { var plugin = installedPlugins[name], filteredOptions = {}; console.error('Warning: editor plugins are no longer supported.'); if (!highed.isNull(plugin)) { if (activePlugins[name]) { return highed.log(2, 'plugin -', name, 'is already active'); } //Verify options Object.keys(plugin.options).forEach(function(key) { var option = plugin.options[key]; if (highed.isBasic(option) || highed.isArr(option)) { highed.log( 2, 'plugin -', name, 'unexpected type definition for option', key, 'expected object' ); } else { filteredOptions[key] = options[key] || plugin.options[key].default || ''; if (option.required && highed.isNull(options[key])) { highed.log(1, 'plugin -', name, 'option', key, 'is required'); } } }); activePlugins[name] = { definition: plugin, options: filteredOptions }; filteredOptions; if (highed.isFn(plugin.activate)) { activePlugins[name].definition.activate(filteredOptions); } pluginEvents.emit('Use', activePlugins[name]); } else { highed.log(2, 'plugin -', name, 'is not installed'); } } //Public interface highed.plugins.editor = { install: install, use: use }; //UI plugin interface highed.plugins.step = { install: function(def) { stepPlugins[def.title] = def; } }; })(); /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** Simple one-pane editor * An essentials-only editor. * * @example * var simpleEditor = highed.SimpleEditor(document.body, { * availableSettings: [ * 'title--text', * 'subtitle--text' * ] * }); * * simpleEditor.on('Change', function (chart) { * console.log(chart.export.html()); * }); * * @constructor * @emits change - when the chart changes * > {highed.ChartPreview} - an instance of the chart preview * * @param parent {domnode} - the node to attach to * @param attributes {object} - the options for the editor * > availableSettings {array} - the settings to include * > defaultChartOptions {object} - default chart settings * > importer {object} - options passed to the importer widget * > options {string|array} - the options to include * > plugins {string|array} - the plugins to enable */ highed.SimpleEditor = function(parent, attributes) { var properties = highed.merge( { importer: { options: 'csv' }, features: 'import preview customize', availableSettings: [ 'title--text', 'subtitle--text', 'colors', 'chart--backgroundColor', 'yAxis-title--style', 'yAxis--type', 'yAxis--opposite', 'yAxis--reversed', 'yAxis-labels--format' ], defaultChartOptions: {} }, attributes ), events = highed.events(), container = highed.dom.cr('div', 'highed-container'), expandContainer = highed.dom.cr('div', 'highed-expand-container'), mainVSplitter = highed.VSplitter(container, { topHeight: '60px', noOverflow: true }), mainToolbar = highed.Toolbar(mainVSplitter.top, { additionalCSS: ['highed-header'] }), hsplitter = highed.HSplitter(mainVSplitter.bottom, { leftWidth: 30, noOverflow: false }), vsplitterRight = highed.VSplitter(hsplitter.right, { noOverflow: true }), vsplitterLeft = highed.VSplitter(hsplitter.left, { topHeight: 60 }), preview = highed.ChartPreview(vsplitterRight.top, { defaultChartOptions: properties.defaultChartOptions, expandTo: expandContainer }), importer = highed.SimpleDataPage(vsplitterRight.bottom, vsplitterLeft.bottom, properties.importer, preview, vsplitterRight.top, {}), //importer = highed.DataImporter(vsplitterRight.bottom, properties.importer), //importer = highed.DataTable(vsplitterRight.bottom), //dataPage = highed.SimpleDataPage(), customizer = highed.SimpleCustomizer(vsplitterLeft.top, { availableSettings: properties.availableSettings }), cmenu = highed.DefaultContextMenu(preview); /////////////////////////////////////////////////////////////////////////// properties.features = highed.arrToObj(properties.features.split(' ')); importer.init() /////////////////////////////////////////////////////////////////////////// function applyFeatures() { if (!properties.features.import) { importer.hide(); } if (!properties.features.preview) { } if (!properties.features.customize) { } } /** Force a resize of the editor * @memberof highed.SimpleEditor */ function resize() { var ps = highed.dom.size(container); mainVSplitter.resize(ps.w, ps.h); vsplitterRight.resize(false, ps.h - 60); vsplitterLeft.resize(); hsplitter.resize(ps.w, ps.h - 60); preview.resize(); importer.resize(); } function attachToCustomizer() { customizer.build(preview.options.customized); } /////////////////////////////////////////////////////////////////////////// customizer.on('PropertyChange', function(id, value, index) { preview.options.set(id, value, index); events.emit('Change', preview); }); // importer.on('ImportCSV', [preview.data.csv, attachToCustomizer]); // importer.on('ImportJSON', [preview.data.json, attachToCustomizer]); // importer.on('ImportChartSettings', [preview.data.settings, attachToCustomizer]); /* importer.on('Change', function(headers, data) { if (data.length) { var d = importer.toDataSeries(); preview.options.set('xAxis-categories', d.categories, 0); preview.loadSeries(d.series); } });*/ preview.on('RequestEdit', function(event, x, y) { customizer.focus(event, x, y); }); preview.on('New', attachToCustomizer); /////////////////////////////////////////////////////////////////////////// highed.dom.ap(highed.dom.get(parent), container, expandContainer); highed.dom.on(window, 'resize', resize); highed.dom.ap( mainToolbar.left, highed.dom.style(highed.dom.cr('div', 'highed-logo'), { 'background-image': 'url("data:image/svg+xml;utf8,' + encodeURIComponent( ' ' ) + '")' }) ); mainToolbar.addIcon({ css: 'fa-gear', click: function(e) { cmenu.show(e.clientX, e.clientY); } }); applyFeatures(); resize(); attachToCustomizer(); //Public interface return { resize: resize, on: events.on, /** Main toolbar * @type {domnode} * @memberof highed.SimpleEditor */ toolbar: mainToolbar, /** The chart preview * @type {highed.ChartPreview} * @memberof highed.SimpleEditor */ chart: preview }; }; /****************************************************************************** Copyright (c) 2016-2018, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ // @format /** A modal editor * The modal editor connects to a "summoner", which is the DOM node that should * spawn the editor. This arg is however optional, and if not present, * `show()` should be called instead when wanting to display it. * * The contained editor can either be a full editor, or a simple editor. * * @example * highed.ModalEditor('icon', {allowDone: true}, function (html) { * doSomethingWithTheExportedHTML(html); * }); * * @constructor * * @param summoner {domnode} - the node which spawns the editor * @param attributes {object} - properties. Note that this object is also passed to the editor constructor. * > type {string} - either `full` or `simple`. * > allowDone {bool} - if set to true (default is false) a "Close and use" button will appear on the top bar * @param fn {function} - function to call when done editing, argument is an instance of highed.ChartPreview * */ highed.ModalEditor = function(summoner, attributes, fn) { var properties = highed.merge( { type: 'full', allowDone: false }, attributes ), modal = highed.OverlayModal(false, { width: '95%', height: '95%', showOnInit: false }), editor = properties.type === 'full' ? highed.Editor(modal.body, attributes) : highed.SimpleEditor(modal.body, attributes), //We don't always know the summoner at create time.. sumFn = false, doneEditing = highed.dom.cr( 'button', 'highed-done-button', 'Close & Use' ); /////////////////////////////////////////////////////////////////////////// /** Attach to a new summoner * @memberof highed.ModalEditor * @param nn {domnode} - the new node to attach to */ function attachToSummoner(nn) { nn = nn || summoner; if (!nn) { return; } if (highed.isFn(sumFn)) { sumFn(); } //Show the modal when clicking the summoner sumFn = highed.dom.on(highed.dom.get(nn), 'click', function(){ modal.show(); editor.resize(); }); } function doDone() { if (highed.isFn(fn)) { fn(editor.chart); } modal.hide(); } //Resize the editor when showing the modal modal.on('Show', editor.resize); highed.dom.on(doneEditing, 'click', doDone); attachToSummoner(summoner); if (properties.allowDone) { highed.dom.ap(editor.toolbar.center, doneEditing); } editor.on('Done', doDone); editor.resize(); /////////////////////////////////////////////////////////////////////////// return { editor: editor, show: modal.show, hide: modal.hide, on: editor.on, resize: editor.resize, attachToSummoner: attachToSummoner }; }; /* Highcharts Editor v0.3.0 Copyright (c) 2016-2017, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* Highcharts Editor v0.3.0 Copyright (c) 2016-2017, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ highed.meta.optionsAdvanced={meta:{types:{},excludes:{}},subtree:{accessibility:{meta:{types:{object:1},name:"accessibility",excludes:{},description:"Options for configuring accessibility for the chart. Requires the\n[accessibility module](//code.highcharts.com/modules/accessibility.\njs) to be loaded. For a description of the module and information\non its features, see [Highcharts Accessibility](http://www.highcharts.\ncom/docs/chart-concepts/accessibility)."},subtree:{describeSingleSeries:{meta:{types:{boolean:1},name:"describeSingleSeries",excludes:{},default:"false",description:"Whether or not to add series descriptions to charts with a single\nseries."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",description:"Enable accessibility features for the chart."},subtree:{}},keyboardNavigation:{meta:{types:{object:1},name:"keyboardNavigation",excludes:{},description:"Options for keyboard navigation."},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",description:"Enable keyboard navigation for the chart."},subtree:{}},focusBorder:{meta:{types:{object:1},name:"focusBorder",excludes:{},description:"Options for the focus border drawn around elements while\nnavigating through them."},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",description:"Enable/disable focus border for chart."},subtree:{}},hideBrowserFocusOutline:{meta:{types:{boolean:1},name:"hideBrowserFocusOutline",excludes:{},default:"true",description:"Hide the browser's default focus indicator."},subtree:{}},margin:{meta:{types:{number:1},name:"margin",excludes:{},default:"2",description:"Focus border margin around the elements."},subtree:{}},style:{meta:{types:{object:1},name:"style",excludes:{},description:"Style options for the focus border drawn around elements\nwhile navigating through them. Note that some browsers in\naddition draw their own borders for focused elements. These\nautomatic borders can not be styled by Highcharts.\n\nIn styled mode, the border is given the\n`.highcharts-focus-border` class."},subtree:{borderRadius:{meta:{types:{number:1},name:"borderRadius",excludes:{},default:"3",description:"Border radius of the focus border."},subtree:{}},color:{meta:{types:{color:1},name:"color",excludes:{},default:"#000000",description:"Color of the focus border."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:"2",description:"Line width of the focus border."},subtree:{}}}}}},mode:{meta:{types:{string:1},name:"mode",excludes:{},default:"normal",description:'Set the keyboard navigation mode for the chart. Can be "normal"\nor "serialize". In normal mode, left/right arrow keys move\nbetween points in a series, while up/down arrow keys move between\nseries. Up/down navigation acts intelligently to figure out which\nseries makes sense to move to from any given point.\n\nIn "serialize" mode, points are instead navigated as a single\nlist. Left/right behaves as in "normal" mode. Up/down arrow keys\nwill behave like left/right. This is useful for unifying\nnavigation behavior with/without screen readers enabled.'},subtree:{}},skipNullPoints:{meta:{types:{boolean:1},name:"skipNullPoints",excludes:{},default:"true",description:"Skip null points when navigating through points with the\nkeyboard."},subtree:{}}}},onTableAnchorClick:{meta:{types:{function:1},name:"onTableAnchorClick",excludes:{},description:'Function to run upon clicking the "View as Data Table" link in the\nscreen reader region.\n\nBy default Highcharts will insert and set focus to a data table\nrepresentation of the chart.'},subtree:{}},pointDateFormat:{meta:{types:{string:1},name:"pointDateFormat",excludes:{},description:"Date format to use for points on datetime axes when describing them\nto screen reader users.\n\nDefaults to the same format as in tooltip.\n\nFor an overview of the replacement codes, see\n[dateFormat](/class-reference/Highcharts#dateFormat)."},subtree:{}},pointDateFormatter:{meta:{types:{function:1},name:"pointDateFormatter",excludes:{},description:"Formatter function to determine the date/time format used with\npoints on datetime axes when describing them to screen reader users.\nReceives one argument, `point`, referring to the point to describe.\nShould return a date format string compatible with\n[dateFormat](/class-reference/Highcharts#dateFormat)."},subtree:{}},pointDescriptionFormatter:{meta:{types:{function:1},name:"pointDescriptionFormatter",excludes:{},description:"Formatter function to use instead of the default for point\ndescriptions.\nReceives one argument, `point`, referring to the point to describe.\nShould return a String with the description of the point for a screen\nreader user."},subtree:{}},pointDescriptionThreshold:{meta:{types:{boolean:1,number:1},name:"pointDescriptionThreshold",excludes:{},default:!1,description:"When a series contains more points than this, we no longer expose\ninformation about individual points to screen readers.\n\nSet to `false` to disable."},subtree:{}},screenReaderSectionFormatter:{meta:{types:{function:1},name:"screenReaderSectionFormatter",excludes:{},default:"undefined",description:"A formatter function to create the HTML contents of the hidden screen\nreader information region. Receives one argument, `chart`, referring\nto the chart object. Should return a String with the HTML content\nof the region.\n\nThe link to view the chart as a data table will be added\nautomatically after the custom HTML content."},subtree:{}},seriesDescriptionFormatter:{meta:{types:{function:1},name:"seriesDescriptionFormatter",excludes:{},description:"Formatter function to use instead of the default for series\ndescriptions. Receives one argument, `series`, referring to the\nseries to describe. Should return a String with the description of\nthe series for a screen reader user."},subtree:{}}}},annotations:{meta:{types:{array:"Object"},name:"annotations",excludes:{},description:"Options for configuring annotations, for example labels, arrows or\nshapes. Annotations can be tied to points, axis coordinates or chart\npixel coordinates."},subtree:{labelOptions:{meta:{types:{object:1},name:"labelOptions",excludes:{},description:"Options for annotation's labels. Each label inherits options\nfrom the labelOptions object. An option from the labelOptions can be\noverwritten by config for a specific label."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"center",description:"The alignment of the annotation's label. If right,\nthe right side of the label should be touching the point."},subtree:{}},allowOverlap:{meta:{types:{boolean:1},name:"allowOverlap",excludes:{},default:!1,description:"Whether to allow the annotation's labels to overlap.\nTo make the labels less sensitive for overlapping,\nthe can be set to 0."},subtree:{}},backgroundColor:{meta:{types:{color:1},name:"backgroundColor",excludes:{},default:"rgba(0, 0, 0, 0.75)",description:"The background color or gradient for the annotation's label."},subtree:{}},borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},default:"black",description:"The border color for the annotation's label."},subtree:{}},borderRadius:{meta:{types:{number:1},name:"borderRadius",excludes:{},default:3,description:"The border radius in pixels for the annotaiton's label."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:1,description:"The border width in pixels for the annotation's label"},subtree:{}},className:{meta:{types:{string:1},name:"className",excludes:{},default:"",description:"A class name for styling by CSS."},subtree:{}},crop:{meta:{types:{boolean:1},name:"crop",excludes:{},default:!1,description:"Whether to hide the annotation's label that is outside the plot\narea."},subtree:{}},distance:{meta:{types:{number:1},name:"distance",excludes:{},default:"undefined",description:"The label's pixel distance from the point."},subtree:{}},format:{meta:{types:{string:1},name:"format",excludes:{},default:"undefined",description:"A [format](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting) string for the data label."},subtree:{}},formatter:{meta:{types:{function:1},name:"formatter",excludes:{},default:"function () {\n return defined(this.y) ? this.y : 'Annotation label';\n}",description:"Callback JavaScript function to format the annotation's label.\nNote that if a `format` or `text` are defined, the format or text\ntake precedence and the formatter is ignored. `This` refers to a\npoint object."},subtree:{}},overflow:{meta:{types:{string:1},name:"overflow",excludes:{},default:"justify",description:"How to handle the annotation's label that flow outside the plot\narea. The justify option aligns the label inside the plot area."},subtree:{}},padding:{meta:{types:{number:1},name:"padding",excludes:{},default:5,description:"When either the borderWidth or the backgroundColor is set,\nthis is the padding within the box."},subtree:{}},shadow:{meta:{types:{boolean:1,object:1},name:"shadow",excludes:{},default:!1,description:"The shadow of the box. The shadow can be an object configuration\ncontaining `color`, `offsetX`, `offsetY`, `opacity` and `width`."},subtree:{}},shape:{meta:{types:{string:1},name:"shape",excludes:{},default:"callout",description:"The name of a symbol to use for the border around the label.\nSymbols are predefined functions on the Renderer object."},subtree:{}},style:{meta:{types:{cssobject:1},name:"style",excludes:{},description:"Styles for the annotation's label."},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"contrast"},subtree:{}},fontSize:{meta:{types:{string:1},name:"fontSize",excludes:{},default:"11px"},subtree:{}},fontWeight:{meta:{types:{string:1},name:"fontWeight",excludes:{},default:"normal"},subtree:{}}}},text:{meta:{types:{string:1},name:"text",excludes:{},default:"undefined",description:"Alias for the format option."},subtree:{}},useHTML:{meta:{types:{boolean:1},name:"useHTML",excludes:{},default:"false",description:"Whether to [use HTML](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting#html)\nto render the annotation's label."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"bottom",description:"The vertical alignment of the annotation's label."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:0,description:"The x position offset of the label relative to the point.\nNote that if a `distance` is defined, the distance takes\nprecedence over `x` and `y` options."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:-16,description:"The y position offset of the label relative to the point.\nNote that if a `distance` is defined, the distance takes\nprecedence over `x` and `y` options."},subtree:{}}}},labels:{meta:{types:{array:"Object"},name:"labels",excludes:{},description:"An array of labels for the annotation. For options that apply to\nmultiple labels, they can be added to the\n[labelOptions](annotations.labelOptions.html).",extends:"annotations.labelOptions"},subtree:{point:{meta:{types:{object:1,string:1},name:"point",excludes:{},description:"This option defines the point to which the label will be connected.\nIt can be either the point which exists in the series - it is\nreferenced by the point's id - or a new point with defined x, y\nproperies and optionally axes."},subtree:{x:{meta:{types:{number:1},name:"x",excludes:{},description:"The x position of the point. Units can be either in axis\nor chart pixel coordinates."},subtree:{}},xAxis:{meta:{types:{number:1,string:1},name:"xAxis",excludes:{},description:"This number defines which xAxis the point is connected to. It refers\nto either the axis id or the index of the axis in the xAxis array.\nIf the option is not configured or the axis is not found the point's\nx coordinate refers to the chart pixels."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},description:"The y position of the point. Units can be either in axis\nor chart pixel coordinates."},subtree:{}},yAxis:{meta:{types:{number:1,string:1},name:"yAxis",excludes:{},description:"This number defines which yAxis the point is connected to. It refers\nto either the axis id or the index of the axis in the yAxis array.\nIf the option is not configured or the axis is not found the point's\ny coordinate refers to the chart pixels."},subtree:{}}}}}},shapeOptions:{meta:{types:{object:1},name:"shapeOptions",excludes:{},description:"Options for annotation's shapes. Each shape inherits options\nfrom the shapeOptions object. An option from the shapeOptions can be\noverwritten by config for a specific shape."},subtree:{fill:{meta:{types:{color:1},name:"fill",excludes:{},default:"rgba(0, 0, 0, 0.75)",description:"The color of the shape's fill."},subtree:{}},height:{meta:{types:{number:1},name:"height",excludes:{},description:"The height of the shape."},subtree:{}},r:{meta:{types:{number:1},name:"r",excludes:{},default:0,description:"The radius of the shape."},subtree:{}},stroke:{meta:{types:{color:1},name:"stroke",excludes:{},default:"rgba(0, 0, 0, 0.75)",description:"The color of the shape's stroke."},subtree:{}},strokeWidth:{meta:{types:{number:1},name:"strokeWidth",excludes:{},default:1,description:"The pixel stroke width of the shape."},subtree:{}},type:{meta:{types:{string:1},name:"type",excludes:{},default:"'rect'",description:"The type of the shape, e.g. circle or rectangle."},subtree:{}},width:{meta:{types:{number:1},name:"width",excludes:{},description:"The width of the shape."},subtree:{}}}},shapes:{meta:{types:{array:"Object"},name:"shapes",excludes:{},description:"An array of shapes for the annotation. For options that apply to\nmultiple shapes, then can be added to the\n[shapeOptions](annotations.shapeOptions.html).",extends:"annotations.shapeOptions"},subtree:{markerEnd:{meta:{types:{string:1},name:"markerEnd",excludes:{},description:"Id of the marker which will be drawn at the final vertex of the path.\nCustom markers can be defined in defs property."},subtree:{}},markerStart:{meta:{types:{string:1},name:"markerStart",excludes:{},description:"Id of the marker which will be drawn at the first vertex of the path.\nCustom markers can be defined in defs property."},subtree:{}},point:{meta:{types:{object:1,string:1},name:"point",excludes:{},description:"This option defines the point to which the shape will be connected.\nIt can be either the point which exists in the series - it is\nreferenced by the point's id - or a new point with defined x, y\nproperties and optionally axes.",extends:"annotations.labels.point"},subtree:{}},points:{meta:{types:{array:"object"},name:"points",excludes:{},description:"An array of points for the shape. This option is available for shapes\nwhich can use multiple points such as path. A point can be either\na point object or a point's id."},subtree:{}}}},visible:{meta:{types:{boolean:1},name:"visible",excludes:{},default:!0,description:"Whether the annotation is visible."},subtree:{}},zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},default:"6",description:"The Z index of the annotation."},subtree:{}}}},boost:{meta:{types:{object:1},name:"boost",excludes:{},products:{highcharts:1,highstock:1},description:"Options for the Boost module. The Boost module allows certain series types\nto be rendered by WebGL instead of the default SVG. This allows hundreds of\nthousands of data points to be rendered in milliseconds. In addition to the\nWebGL rendering it saves time by skipping processing and inspection of the\ndata wherever possible. This introduces some limitations to what features are\navailable in Boost mode. See [the docs](\nhttps://www.highcharts.com/docs/advanced-chart-features/boost-module) for\ndetails.\n\nIn addition to the global `boost` option, each series has a\n[boostThreshold](#plotOptions.series.boostThreshold) that defines when the\nboost should kick in.\n\nRequires the `modules/boost.js` module."},subtree:{allowForce:{meta:{types:{boolean:1},name:"allowForce",excludes:{},default:"true",description:"If set to true, the whole chart will be boosted if one of the series\ncrosses its threshold, and all the series can be boosted."},subtree:{}},debug:{meta:{types:{object:1},name:"debug",excludes:{},description:"Debugging options for boost.\nUseful for benchmarking, and general timing."},subtree:{showSkipSummary:{meta:{types:{boolean:1},name:"showSkipSummary",excludes:{},default:"false",description:"Show the number of points skipped through culling.\n\nWhen set to true, the number of points skipped in series processing\nis outputted. Points are skipped if they are closer than 1 pixel from\neach other."},subtree:{}},timeBufferCopy:{meta:{types:{boolean:1},name:"timeBufferCopy",excludes:{},default:"false",description:"Time the WebGL to SVG buffer copy\n\nAfter rendering, the result is copied to an image which is injected\ninto the SVG.\n\nIf this property is set to true, the time it takes for the buffer copy\nto complete is outputted."},subtree:{}},timeKDTree:{meta:{types:{boolean:1},name:"timeKDTree",excludes:{},default:"false",description:"Time the building of the k-d tree.\n\nThis outputs the time spent building the k-d tree used for\nmarkers etc.\n\nNote that the k-d tree is built async, and runs post-rendering.\nFollowing, it does not affect the performance of the rendering itself."},subtree:{}},timeRendering:{meta:{types:{boolean:1},name:"timeRendering",excludes:{},default:"false",description:"Time the series rendering.\n\nThis outputs the time spent on actual rendering in the console when\nset to true."},subtree:{}},timeSeriesProcessing:{meta:{types:{boolean:1},name:"timeSeriesProcessing",excludes:{},default:"false",description:"Time the series processing.\n\nThis outputs the time spent on transforming the series data to\nvertex buffers when set to true."},subtree:{}},timeSetup:{meta:{types:{boolean:1},name:"timeSetup",excludes:{},default:"false",description:"Time the the WebGL setup.\n\nThis outputs the time spent on setting up the WebGL context,\ncreating shaders, and textures."},subtree:{}}}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",description:"Enable or disable boost on a chart."},subtree:{}},seriesThreshold:{meta:{types:{number:1},name:"seriesThreshold",excludes:{},default:"null",description:"Set the series threshold for when the boost should kick in globally.\n\nSetting to e.g. 20 will cause the whole chart to enter boost mode\nif there are 20 or more series active. When the chart is in boost mode,\nevery series in it will be rendered to a common canvas. This offers\na significant speed improvment in charts with a very high\namount of series."},subtree:{}},useGPUTranslations:{meta:{types:{boolean:1},name:"useGPUTranslations",excludes:{},default:"false",description:"Enable or disable GPU translations. GPU translations are faster than doing\nthe translation in JavaScript.\n\nThis option may cause rendering issues with certain datasets.\nNamely, if your dataset has large numbers with small increments (such as\ntimestamps), it won't work correctly. This is due to floating point\nprecission."},subtree:{}}}},chart:{meta:{types:{"*":1},name:"chart",excludes:{},description:"General options for the chart."},subtree:{alignTicks:{meta:{types:{boolean:1},name:"alignTicks",excludes:{},default:"true",products:{highcharts:1,highstock:1},description:"When using multiple axis, the ticks of two or more opposite axes\nwill automatically be aligned by adding ticks to the axis or axes\nwith the least ticks, as if `tickAmount` were specified.\n\nThis can be prevented by setting `alignTicks` to false. If the grid\nlines look messy, it's a good idea to hide them for the secondary\naxis by setting `gridLineWidth` to 0.\n\nIf `startOnTick` or `endOnTick` in an Axis options are set to false,\nthen the `alignTicks ` will be disabled for the Axis.\n\nDisabled for logarithmic axes."},subtree:{}},animation:{meta:{types:{"highcharts.animationoptionsobject":1,boolean:1},name:"animation",excludes:{},default:"true",description:"Set the overall animation for all chart updating. Animation can be\ndisabled throughout the chart by setting it to false here. It can\nbe overridden for each individual API method as a function parameter.\nThe only animation not affected by this option is the initial series\nanimation, see [plotOptions.series.animation](\n#plotOptions.series.animation).\n\nThe animation can either be set as a boolean or a configuration\nobject. If `true`, it will use the 'swing' jQuery easing and a\nduration of 500 ms. If used as a configuration object, the following\nproperties are supported:\n\n
    \n\n
    duration
    \n\n
    The duration of the animation in milliseconds.
    \n\n
    easing
    \n\n
    A string reference to an easing function set on the `Math`\nobject. See [the easing\ndemo](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/series-animation-easing/).\n
    \n\n
    "},subtree:{}},backgroundColor:{meta:{types:{"highcharts.colorstring":1},name:"backgroundColor",excludes:{},default:"#FFFFFF",description:"The background color or gradient for the outer chart area."},subtree:{}},borderColor:{meta:{types:{"highcharts.colorstring":1},name:"borderColor",excludes:{},default:"#335cad",description:"The color of the outer chart border."},subtree:{}},borderRadius:{meta:{types:{number:1},name:"borderRadius",excludes:{},default:"0",description:"The corner radius of the outer chart border."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:"0",description:"The pixel width of the outer chart border."},subtree:{}},className:{meta:{types:{string:1},name:"className",excludes:{},description:"A CSS class name to apply to the charts container `div`, allowing\nunique CSS styling for each chart."},subtree:{}},colorCount:{meta:{types:{number:1},name:"colorCount",excludes:{},default:"10",description:"In styled mode, this sets how many colors the class names\nshould rotate between. With ten colors, series (or points) are\ngiven class names like `highcharts-color-0`, `highcharts-color-0`\n[...] `highcharts-color-9`. The equivalent in non-styled mode\nis to set colors using the [colors](#colors) setting."},subtree:{}},defaultSeriesType:{meta:{types:{string:1},name:"defaultSeriesType",excludes:{},default:"line",products:{highcharts:1},description:"Alias of `type`."},subtree:{}},description:{meta:{types:{string:1},name:"description",excludes:{},default:"undefined",description:"A text description of the chart.\n\nIf the Accessibility module is loaded, this is included by default\nas a long description of the chart and its contents in the hidden\nscreen reader information region."},subtree:{}},events:{meta:{types:{"*":1},name:"events",excludes:{},description:"Event listeners for the chart."},subtree:{addSeries:{meta:{types:{function:1},name:"addSeries",excludes:{},description:"Fires when a series is added to the chart after load time, using\nthe `addSeries` method. One parameter, `event`, is passed to the\nfunction, containing common event information.\nThrough `event.options` you can access the series options that was\npassed to the `addSeries` method. Returning false prevents the series\nfrom being added."},subtree:{}},afterPrint:{meta:{types:{function:1},name:"afterPrint",excludes:{},description:"Fires after a chart is printed through the context menu item or the\n`Chart.print` method. Requires the exporting module."},subtree:{}},beforePrint:{meta:{types:{function:1},name:"beforePrint",excludes:{},description:"Fires before a chart is printed through the context menu item or\nthe `Chart.print` method. Requires the exporting module."},subtree:{}},click:{meta:{types:{function:1},name:"click",excludes:{},description:"Fires when clicking on the plot background. One parameter, `event`,\nis passed to the function, containing common event information.\n\nInformation on the clicked spot can be found through `event.xAxis`\nand `event.yAxis`, which are arrays containing the axes of each\ndimension and each axis' value at the clicked spot. The primary axes\nare `event.xAxis[0]` and `event.yAxis[0]`. Remember the unit of a\ndatetime axis is milliseconds since 1970-01-01 00:00:00.\n\n
    click: function(e) {\n    console.log(\n        Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', e.xAxis[0].value),\n        e.yAxis[0].value\n    )\n}
    "},subtree:{}},drilldown:{meta:{types:{function:1},name:"drilldown",excludes:{},products:{highcharts:1,highmaps:1},description:"Fires when a drilldown point is clicked, before the new series is\nadded. This event is also utilized for async drilldown, where the\nseriesOptions are not added by option, but rather loaded async. Note\nthat when clicking a category label to trigger multiple series drilldown,\none `drilldown` event is triggered per point in the category.\n\nEvent arguments:\n\n
    \n\n
    `category`
    \n\n
    If a category label was clicked, which index.
    \n\n
    `point`
    \n\n
    The originating point.
    \n\n
    `originalEvent`
    \n\n
    The original browser event (usually click) that triggered the\ndrilldown.
    \n\n
    `points`
    \n\n
    If a category label was clicked, this array holds all points\ncorresponing to the category.
    \n\n
    `seriesOptions`
    \n\n
    Options for the new series
    \n\n
    "},subtree:{}},drillup:{meta:{types:{function:1},name:"drillup",excludes:{},products:{highcharts:1,highmaps:1},description:"Fires when drilling up from a drilldown series."},subtree:{}},drillupall:{meta:{types:{function:1},name:"drillupall",excludes:{},products:{highcharts:1,highmaps:1},description:"In a chart with multiple drilldown series, this event fires after\nall the series have been drilled up."},subtree:{}},load:{meta:{types:{function:1},name:"load",excludes:{},description:"Fires when the chart is finished loading. Since v4.2.2, it also waits\nfor images to be loaded, for example from point markers. One\nparameter, `event`, is passed to the function, containing common\nevent information.\n\nThere is also a second parameter to the chart constructor where a\ncallback function can be passed to be executed on chart.load."},subtree:{}},redraw:{meta:{types:{function:1},name:"redraw",excludes:{},description:"Fires when the chart is redrawn, either after a call to\n`chart.redraw()` or after an axis, series or point is modified with\nthe `redraw` option set to true. One parameter, `event`, is passed to\nthe function, containing common event information."},subtree:{}},render:{meta:{types:{function:1},name:"render",excludes:{},description:"Fires after initial load of the chart (directly after the `load`\nevent), and after each redraw (directly after the `redraw` event)."},subtree:{}},selection:{meta:{types:{function:1},name:"selection",excludes:{},description:"Fires when an area of the chart has been selected. Selection is\nenabled by setting the chart's zoomType. One parameter, `event`, is\npassed to the function, containing common event information. The\ndefault action for the selection event is to zoom the chart to the\nselected area. It can be prevented by calling\n`event.preventDefault()`.\n\nInformation on the selected area can be found through `event.xAxis`\nand `event.yAxis`, which are arrays containing the axes of each\ndimension and each axis' min and max values. The primary axes are\n`event.xAxis[0]` and `event.yAxis[0]`. Remember the unit of a\ndatetime axis is milliseconds since 1970-01-01 00:00:00.\n\n
    selection: function(event) {\n    // log the min and max of the primary, datetime x-axis\n    console.log(\n        Highcharts.dateFormat(\n            '%Y-%m-%d %H:%M:%S',\n            event.xAxis[0].min\n        ),\n        Highcharts.dateFormat(\n            '%Y-%m-%d %H:%M:%S',\n            event.xAxis[0].max\n        )\n    );\n    // log the min and max of the y axis\n    console.log(event.yAxis[0].min, event.yAxis[0].max);\n}
    "},subtree:{}}}},height:{meta:{types:{null:1,number:1,string:1},name:"height",excludes:{},default:"null",description:"An explicit height for the chart. If a _number_, the height is\ngiven in pixels. If given a _percentage string_ (for example\n`'56%'`), the height is given as the percentage of the actual chart\nwidth. This allows for preserving the aspect ratio across responsive\nsizes.\n\nBy default (when `null`) the height is calculated from the offset\nheight of the containing element, or 400 pixels if the containing\nelement's height is 0."},subtree:{}},ignoreHiddenSeries:{meta:{types:{boolean:1},name:"ignoreHiddenSeries",excludes:{},default:"true",products:{highcharts:1,highstock:1},description:"If true, the axes will scale to the remaining visible series once\none series is hidden. If false, hiding and showing a series will\nnot affect the axes or the other series. For stacks, once one series\nwithin the stack is hidden, the rest of the stack will close in\naround it even if the axis is not affected."},subtree:{}},inverted:{meta:{types:{boolean:1},name:"inverted",excludes:{},default:"false",products:{highcharts:1,highstock:1},description:"Whether to invert the axes so that the x axis is vertical and y axis\nis horizontal. When `true`, the x axis is [reversed](#xAxis.reversed)\nby default."},subtree:{}},map:{meta:{types:{array:"*",string:1},name:"map",excludes:{},products:{highmaps:1},description:"Default `mapData` for all series. If set to a string, it functions\nas an index into the `Highcharts.maps` array. Otherwise it is\ninterpreted s map data."},subtree:{}},mapTransforms:{meta:{types:{"*":1},name:"mapTransforms",excludes:{},products:{highmaps:1},description:"Set lat/lon transformation definitions for the chart. If not defined,\nthese are extracted from the map data."},subtree:{}},margin:{meta:{types:{array:"number",number:1},name:"margin",excludes:{},description:"The margin between the outer edge of the chart and the plot area.\nThe numbers in the array designate top, right, bottom and left\nrespectively. Use the options `marginTop`, `marginRight`,\n`marginBottom` and `marginLeft` for shorthand setting of one option.\n\nBy default there is no margin. The actual space is dynamically\ncalculated from the offset of axis labels, axis title, title,\nsubtitle and legend in addition to the `spacingTop`, `spacingRight`,\n`spacingBottom` and `spacingLeft` options."},subtree:{}},marginBottom:{meta:{types:{number:1},name:"marginBottom",excludes:{},description:"The margin between the bottom outer edge of the chart and the plot\narea. Use this to set a fixed pixel value for the margin as opposed\nto the default dynamic margin. See also `spacingBottom`."},subtree:{}},marginLeft:{meta:{types:{number:1},name:"marginLeft",excludes:{},description:"The margin between the left outer edge of the chart and the plot\narea. Use this to set a fixed pixel value for the margin as opposed\nto the default dynamic margin. See also `spacingLeft`."},subtree:{}},marginRight:{meta:{types:{number:1},name:"marginRight",excludes:{},description:"The margin between the right outer edge of the chart and the plot\narea. Use this to set a fixed pixel value for the margin as opposed\nto the default dynamic margin. See also `spacingRight`."},subtree:{}},marginTop:{meta:{types:{number:1},name:"marginTop",excludes:{},description:"The margin between the top outer edge of the chart and the plot area.\nUse this to set a fixed pixel value for the margin as opposed to\nthe default dynamic margin. See also `spacingTop`."},subtree:{}},options3d:{meta:{types:{object:1},name:"options3d",excludes:{},products:{highcharts:1},description:"Options to render charts in 3 dimensions. This feature requires\n`highcharts-3d.js`, found in the download package or online at\n[code.highcharts.com/highcharts-3d.js](http://code.highcharts.com/highcharts-\n3d.js)."},subtree:{alpha:{meta:{types:{number:1 },name:"alpha",excludes:{},default:"0",products:{highcharts:1},description:"One of the two rotation angles for the chart."},subtree:{}},axisLabelPosition:{meta:{types:{string:1},name:"axisLabelPosition",excludes:{},default:null,products:{highcharts:1},description:'Set it to `"auto"` to automatically move the labels to the best\nedge.'},subtree:{}},beta:{meta:{types:{number:1},name:"beta",excludes:{},default:"0",products:{highcharts:1},description:"One of the two rotation angles for the chart."},subtree:{}},depth:{meta:{types:{number:1},name:"depth",excludes:{},default:"100",products:{highcharts:1},description:"The total depth of the chart."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"false",products:{highcharts:1},description:"Wether to render the chart using the 3D functionality."},subtree:{}},fitToPlot:{meta:{types:{boolean:1},name:"fitToPlot",excludes:{},default:"true",products:{highcharts:1},description:"Whether the 3d box should automatically adjust to the chart plot\narea."},subtree:{}},frame:{meta:{types:{object:1},name:"frame",excludes:{},products:{highcharts:1},description:"Provides the option to draw a frame around the charts by defining\na bottom, front and back panel."},subtree:{back:{meta:{types:{},name:"back",excludes:{},description:"The back side of the frame around a 3D chart.",extends:"chart.options3d.frame.bottom"},subtree:{}},bottom:{meta:{types:{object:1},name:"bottom",excludes:{},description:"The bottom of the frame around a 3D chart."},subtree:{color:{meta:{types:{color:1},name:"color",excludes:{},default:"transparent",products:{highcharts:1},description:"The color of the panel."},subtree:{}},size:{meta:{types:{number:1},name:"size",excludes:{},default:"1",products:{highcharts:1},description:"The thickness of the panel."},subtree:{}},visible:{meta:{types:{boolean:1,string:1},name:"visible",excludes:{},default:"default",products:{highcharts:1},description:'Whether to display the frame. Possible values are `true`,\n`false`, `"auto"` to display only the frames behind the data,\nand `"default"` to display faces behind the data based on the\naxis layout, ignoring the point of view.'},subtree:{}}}},front:{meta:{types:{},name:"front",excludes:{},description:"The front of the frame around a 3D chart.",extends:"chart.options3d.frame.bottom"},subtree:{}},left:{meta:{types:{},name:"left",excludes:{},description:"The left side of the frame around a 3D chart.",extends:"chart.options3d.frame.bottom"},subtree:{}},right:{meta:{types:{},name:"right",excludes:{},description:"The right of the frame around a 3D chart.",extends:"chart.options3d.frame.bottom"},subtree:{}},side:{meta:{types:{object:1},name:"side",excludes:{},products:{highcharts:1},description:"Note: As of v5.0.12, `frame.left` or `frame.right` should be used\ninstead.\n\nThe side for the frame around a 3D chart."},subtree:{color:{meta:{types:{color:1},name:"color",excludes:{},default:"transparent",products:{highcharts:1},description:"The color of the panel."},subtree:{}},size:{meta:{types:{number:1},name:"size",excludes:{},default:"1",products:{highcharts:1},description:"The thickness of the panel."},subtree:{}}}},size:{meta:{types:{number:1},name:"size",excludes:{},default:1,description:"General pixel thickness for the frame faces."},subtree:{}},top:{meta:{types:{},name:"top",excludes:{},description:"The top of the frame around a 3D chart.",extends:"chart.options3d.frame.bottom"},subtree:{}},visible:{meta:{types:{string:1},name:"visible",excludes:{},default:"default",description:"Whether the frames are visible."},subtree:{}}}},viewDistance:{meta:{types:{number:1},name:"viewDistance",excludes:{},default:"100",products:{highcharts:1},description:"Defines the distance the viewer is standing in front of the\nchart, this setting is important to calculate the perspective\neffect in column and scatter charts. It is not used for 3D pie\ncharts."},subtree:{}}}},panKey:{meta:{types:{string:1},name:"panKey",excludes:{},products:{highcharts:1},description:"Allows setting a key to switch between zooming and panning. Can be\none of `alt`, `ctrl`, `meta` (the command key on Mac and Windows\nkey on Windows) or `shift`. The keys are mapped directly to the key\nproperties of the click event argument (`event.altKey`,\n`event.ctrlKey`, `event.metaKey` and `event.shiftKey`)."},subtree:{}},panning:{meta:{types:{boolean:1},name:"panning",excludes:{},products:{highcharts:1,highstock:1},description:"Allow panning in a chart. Best used with [panKey](#chart.panKey)\nto combine zooming and panning.\n\nOn touch devices, when the [tooltip.followTouchMove](\n#tooltip.followTouchMove) option is `true` (default), panning\nrequires two fingers. To allow panning with one finger, set\n`followTouchMove` to `false`."},subtree:{}},parallelAxes:{meta:{types:{object:1},name:"parallelAxes",excludes:{},products:{highcharts:1},description:"Common options for all yAxes rendered in a parallel coordinates plot.\nThis feature requires `modules/parallel-coordinates.js`.\n\nThe default options are:\n
    \nparallelAxes: {\n   lineWidth: 1,       // classic mode only\n   gridlinesWidth: 0,  // classic mode only\n   title: {\n       text: '',\n       reserveSpace: false\n   },\n   labels: {\n       x: 0,\n       y: 0,\n       align: 'center',\n       reserveSpace: false\n   },\n   offset: 0\n}
    ",extends:"yAxis"},subtree:{labels:{meta:{types:{object:1},name:"labels",excludes:{}},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"center"},subtree:{}},reserveSpace:{meta:{types:{boolean:1},name:"reserveSpace",excludes:{},default:!1},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:0},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:4},subtree:{}}}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1},subtree:{}},offset:{meta:{types:{number:1},name:"offset",excludes:{},default:0},subtree:{}},title:{meta:{types:{object:1},name:"title",excludes:{},description:"Titles for yAxes are taken from\n[xAxis.categories](#xAxis.categories). All options for\n`xAxis.labels` applies to parallel coordinates titles.\nFor example, to style categories, use\n[xAxis.labels.style](#xAxis.labels.style)."},subtree:{reserveSpace:{meta:{types:{boolean:1},name:"reserveSpace",excludes:{},default:!1},subtree:{}},text:{meta:{types:{string:1},name:"text",excludes:{},default:""},subtree:{}}}}}},parallelCoordinates:{meta:{types:{boolean:1},name:"parallelCoordinates",excludes:{},default:!1,products:{highcharts:1},description:"Flag to render charts as a parallel coordinates plot. In a parallel\ncoordinates plot (||-coords) by default all required yAxes are generated\nand the legend is disabled. This feature requires\n`modules/parallel-coordinates.js`."},subtree:{}},pinchType:{meta:{types:{string:1},name:"pinchType",excludes:{},products:{highcharts:1,highstock:1},description:"Equivalent to [zoomType](#chart.zoomType), but for multitouch\ngestures only. By default, the `pinchType` is the same as the\n`zoomType` setting. However, pinching can be enabled separately in\nsome cases, for example in stock charts where a mouse drag pans the\nchart, while pinching is enabled. When [tooltip.followTouchMove](\n#tooltip.followTouchMove) is true, pinchType only applies to\ntwo-finger touches."},subtree:{}},plotBackgroundColor:{meta:{types:{"highcharts.colorstring":1},name:"plotBackgroundColor",excludes:{},description:"The background color or gradient for the plot area."},subtree:{}},plotBackgroundImage:{meta:{types:{string:1},name:"plotBackgroundImage",excludes:{},description:"The URL for an image to use as the plot background. To set an image\nas the background for the entire chart, set a CSS background image\nto the container element. Note that for the image to be applied to\nexported charts, its URL needs to be accessible by the export server."},subtree:{}},plotBorderColor:{meta:{types:{"highcharts.colorstring":1},name:"plotBorderColor",excludes:{},default:"#cccccc",description:"The color of the inner chart or plot area border."},subtree:{}},plotBorderWidth:{meta:{types:{number:1},name:"plotBorderWidth",excludes:{},default:"0",description:"The pixel width of the plot area border."},subtree:{}},plotShadow:{meta:{types:{"highcharts.cssobject":1,boolean:1},name:"plotShadow",excludes:{},default:"false",description:"Whether to apply a drop shadow to the plot area. Requires that\nplotBackgroundColor be set. The shadow can be an object configuration\ncontaining `color`, `offsetX`, `offsetY`, `opacity` and `width`."},subtree:{}},polar:{meta:{types:{boolean:1},name:"polar",excludes:{},default:"false",products:{highcharts:1},description:"When true, cartesian charts like line, spline, area and column are\ntransformed into the polar coordinate system. Requires\n`highcharts-more.js`."},subtree:{}},reflow:{meta:{types:{boolean:1},name:"reflow",excludes:{},default:"true",description:"Whether to reflow the chart to fit the width of the container div\non resizing the window."},subtree:{}},renderTo:{meta:{types:{"highcharts.svgdomelement":1,string:1},name:"renderTo",excludes:{},description:"The HTML element where the chart will be rendered. If it is a string,\nthe element by that id is used. The HTML element can also be passed\nby direct reference, or as the first argument of the chart\nconstructor, in which case the option is not needed."},subtree:{}},resetZoomButton:{meta:{types:{"*":1},name:"resetZoomButton",excludes:{},description:"The button that appears after a selection zoom, allowing the user\nto reset zoom."},subtree:{position:{meta:{types:{"*":1},name:"position",excludes:{},description:"The position of the button."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"right",description:"The horizontal alignment of the button."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"top",description:"The vertical alignment of the button."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:-10,description:"The horizontal offset of the button."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:10,description:"The vertical offset of the button."},subtree:{}}}},relativeTo:{meta:{types:{string:1},name:"relativeTo",excludes:{},default:"plot",description:"What frame the button should be placed related to. Can be either\n`plot` or `chart`"},subtree:{}},theme:{meta:{types:{"*":1},name:"theme",excludes:{},description:"A collection of attributes for the button. The object takes SVG\nattributes like `fill`, `stroke`, `stroke-width` or `r`, the\nborder radius. The theme also supports `style`, a collection of\nCSS properties for the text. Equivalent attributes for the hover\nstate are given in `theme.states.hover`."},subtree:{zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},default:6,description:"The Z index for the reset zoom button. The default value\nplaces it below the tooltip that has Z index 7."},subtree:{}}}}}},scrollablePlotArea:{meta:{types:{object:1},name:"scrollablePlotArea",excludes:{},products:{highcharts:1},description:"Options for a scrollable plot area. This feature provides a minimum width for\nthe plot area of the chart. If the width gets smaller than this, typically\non mobile devices, a native browser scrollbar is presented below the chart.\nThis scrollbar provides smooth scrolling for the contents of the plot area,\nwhereas the title, legend and axes are fixed."},subtree:{minWidth:{meta:{types:{number:1},name:"minWidth",excludes:{},description:"The minimum width for the plot area. If it gets smaller than this, the plot\narea will become scrollable."},subtree:{}},scrollPositionX:{meta:{types:{number:1},name:"scrollPositionX",excludes:{},description:"The initial scrolling position of the scrollable plot area. Ranges from 0 to\n1, where 0 aligns the plot area to the left and 1 aligns it to the right.\nTypically we would use 1 if the chart has right aligned Y axes."},subtree:{}}}},selectionMarkerFill:{meta:{types:{"highcharts.colorstring":1},name:"selectionMarkerFill",excludes:{},default:"rgba(51,92,173,0.25)",description:"The background color of the marker square when selecting (zooming\nin on) an area of the chart."},subtree:{}},shadow:{meta:{types:{"highcharts.cssobject":1,boolean:1},name:"shadow",excludes:{},default:"false",description:"Whether to apply a drop shadow to the outer chart area. Requires\nthat backgroundColor be set. The shadow can be an object\nconfiguration containing `color`, `offsetX`, `offsetY`, `opacity` and\n`width`."},subtree:{}},showAxes:{meta:{types:{boolean:1},name:"showAxes",excludes:{},products:{highcharts:1},description:"Whether to show the axes initially. This only applies to empty charts\nwhere series are added dynamically, as axes are automatically added\nto cartesian series."},subtree:{}},spacing:{meta:{types:{array:"number"},name:"spacing",excludes:{},default:"[10, 10, 15, 10]",description:"The distance between the outer edge of the chart and the content,\nlike title or legend, or axis title and labels if present. The\nnumbers in the array designate top, right, bottom and left\nrespectively. Use the options spacingTop, spacingRight, spacingBottom\nand spacingLeft options for shorthand setting of one option."},subtree:{}},spacingBottom:{meta:{types:{number:1},name:"spacingBottom",excludes:{},default:"15",description:"The space between the bottom edge of the chart and the content (plot\narea, axis title and labels, title, subtitle or legend in top\nposition)."},subtree:{}},spacingLeft:{meta:{types:{number:1},name:"spacingLeft",excludes:{},default:"10",description:"The space between the left edge of the chart and the content (plot\narea, axis title and labels, title, subtitle or legend in top\nposition)."},subtree:{}},spacingRight:{meta:{types:{number:1},name:"spacingRight",excludes:{},default:"10",description:"The space between the right edge of the chart and the content (plot\narea, axis title and labels, title, subtitle or legend in top\nposition)."},subtree:{}},spacingTop:{meta:{types:{number:1},name:"spacingTop",excludes:{},default:"10",description:"The space between the top edge of the chart and the content (plot\narea, axis title and labels, title, subtitle or legend in top\nposition)."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},default:'{"fontFamily": "\\"Lucida Grande\\", \\"Lucida Sans Unicode\\", Verdana, Arial, Helvetica, sans-serif","fontSize":"12px"}',description:"Additional CSS styles to apply inline to the container `div`. Note\nthat since the default font styles are applied in the renderer, it\nis ignorant of the individual chart options and must be set globally."},subtree:{}},type:{meta:{types:{string:1},name:"type",excludes:{},description:"The default series type for the chart. Can be any of the chart types\nlisted under [plotOptions](#plotOptions)."},subtree:{}},typeDescription:{meta:{types:{string:1},name:"typeDescription",excludes:{},default:"undefined",description:"A text description of the chart type.\n\nIf the Accessibility module is loaded, this will be included in the\ndescription of the chart in the screen reader information region.\n\n\nHighcharts will by default attempt to guess the chart type, but for\nmore complex charts it is recommended to specify this property for\nclarity."},subtree:{}},width:{meta:{types:{null:1,number:1},name:"width",excludes:{},default:"null",description:"An explicit width for the chart. By default (when `null`) the width\nis calculated from the offset width of the containing element."},subtree:{}},zoomType:{meta:{types:{string:1},name:"zoomType",excludes:{},products:{highcharts:1,highstock:1},description:"Decides in what dimensions the user can zoom by dragging the mouse.\nCan be one of `x`, `y` or `xy`."},subtree:{}}}},colorAxis:{meta:{types:{object:1},name:"colorAxis",excludes:{},products:{highcharts:1,highmaps:1},description:"A color axis for choropleth maps and heat maps. Visually, the color\naxis will appear as a gradient or as separate items inside the\nlegend, depending on whether the axis is scalar or based on data\nclasses.\n\nFor supported color formats, see the\n[docs article about colors](https://www.highcharts.com/docs/chart-design-and-style/colors).\n\nA scalar color axis is represented by a gradient. The colors either\nrange between the [minColor](#colorAxis.minColor) and the\n[maxColor](#colorAxis.maxColor), or for more fine grained control the\ncolors can be defined in [stops](#colorAxis.stops). Often times, the\ncolor axis needs to be adjusted to get the right color spread for the\ndata. In addition to stops, consider using a logarithmic\n[axis type](#colorAxis.type), or setting [min](#colorAxis.min) and\n[max](#colorAxis.max) to avoid the colors being determined by\noutliers.\n\nWhen [dataClasses](#colorAxis.dataClasses) are used, the ranges are\nsubdivided into separate classes like categories based on their\nvalues. This can be used for ranges between two values, but also for\na true category. However, when your data is categorized, it may be as\nconvenient to add each category to a separate series.\n\nSee [the Axis object](/class-reference/Highcharts.Axis) for\nprogrammatic access to the axis.",extends:"xAxis"},subtree:{allowDecimals:{meta:{types:{boolean:1},name:"allowDecimals",excludes:{},default:"true",products:{highcharts:1,highmaps:1},description:"Whether to allow decimals on the color axis."},subtree:{}},dataClassColor:{meta:{types:{string:1},name:"dataClassColor",excludes:{},default:"tween",products:{highcharts:1,highmaps:1},description:"Determines how to set each data class' color if no individual\ncolor is set. The default value, `tween`, computes intermediate\ncolors between `minColor` and `maxColor`. The other possible\nvalue, `category`, pulls colors from the global or chart specific\n[colors](#colors) array."},subtree:{}},dataClasses:{meta:{types:{array:"Object"},name:"dataClasses",excludes:{},products:{highcharts:1,highmaps:1},description:"An array of data classes or ranges for the choropleth map. If\nnone given, the color axis is scalar and values are distributed\nas a gradient between the minimum and maximum colors."},subtree:{color:{meta:{types:{color:1},name:"color",excludes:{},products:{highcharts:1,highmaps:1},description:"The color of each data class. If not set, the color is pulled\nfrom the global or chart-specific [colors](#colors) array. In\nstyled mode, this option is ignored. Instead, use colors defined\nin CSS."},subtree:{}},from:{meta:{types:{number:1},name:"from",excludes:{},products:{highcharts:1,highmaps:1},description:"The start of the value range that the data class represents,\nrelating to the point value.\n\nThe range of each `dataClass` is closed in both ends, but can be\noverridden by the next `dataClass`."},subtree:{}},name:{meta:{types:{string:1},name:"name",excludes:{},products:{highcharts:1,highmaps:1},description:"The name of the data class as it appears in the legend.\nIf no name is given, it is automatically created based on the\n`from` and `to` values. For full programmatic control,\n[legend.labelFormatter](#legend.labelFormatter) can be used.\nIn the formatter, `this.from` and `this.to` can be accessed."},subtree:{}},to:{meta:{types:{number:1},name:"to",excludes:{},products:{highcharts:1,highmaps:1},description:"The end of the value range that the data class represents,\nrelating to the point value.\n\nThe range of each `dataClass` is closed in both ends, but can be\noverridden by the next `dataClass`."},subtree:{}}}},endOnTick:{meta:{types:{boolean:1},name:"endOnTick",excludes:{},default:"true",products:{highcharts:1,highmaps:1},description:"Whether to force the axis to end on a tick. Use this option with\nthe [maxPadding](#colorAxis.maxPadding) option to control the\naxis end."},subtree:{}},events:{meta:{types:{object:1},name:"events",excludes:{}},subtree:{legendItemClick:{meta:{types:{function:1},name:"legendItemClick",excludes:{},products:{highcharts:1,highmaps:1},description:"Fires when the legend item belonging to the colorAxis is clicked.\nOne parameter, `event`, is passed to the function."},subtree:{}}}},gridLineColor:{meta:{types:{color:1},name:"gridLineColor",excludes:{},default:"#e6e6e6",products:{highcharts:1,highmaps:1},description:"Color of the grid lines extending from the axis across the\ngradient."},subtree:{}},gridLineWidth:{meta:{types:{number:1},name:"gridLineWidth",excludes:{},default:"1",products:{highcharts:1,highmaps:1},description:"The width of the grid lines extending from the axis across the\ngradient of a scalar color axis."},subtree:{}},labels:{meta:{types:{object:1},name:"labels",excludes:{},products:{highcharts:1,highmaps:1},description:"The axis labels show the number for each tick.\n\nFor more live examples on label options, see [xAxis.labels in the\nHighcharts API.](/highcharts#xAxis.labels)",extends:"xAxis.labels"},subtree:{overflow:{meta:{types:{string:1},name:"overflow",excludes:{},default:"justify",products:{highcharts:1,highmaps:1},description:'How to handle overflowing labels on horizontal color axis.\nCan be undefined or "justify". If "justify", labels will not\nrender outside the legend area. If there is room to move it,\nit will be aligned to the edge, else it will be removed.'},subtree:{}},rotation:{meta:{types:{number:1},name:"rotation",excludes:{},default:0},subtree:{}}}},marker:{meta:{types:{object:1},name:"marker",excludes:{},products:{highcharts:1,highmaps:1},description:"The triangular marker on a scalar color axis that points to the\nvalue of the hovered area. To disable the marker, set\n`marker: null`."},subtree:{animation:{meta:{types:{animationoptions:1,boolean:1},name:"animation",excludes:{},products:{highcharts:1,highmaps:1},description:"Animation for the marker as it moves between values. Set to\n`false` to disable animation. Defaults to `{ duration: 50 }`."},subtree:{duration:{meta:{types:{number:1},name:"duration",excludes:{},default:50},subtree:{}}}},color:{meta:{types:{color:1},name:"color",excludes:{},default:"#999999",products:{highcharts:1,highmaps:1},description:"The color of the marker."},subtree:{}}}},max:{meta:{types:{number:1},name:"max",excludes:{},products:{highcharts:1,highmaps:1},description:"The maximum value of the axis in terms of map point values. If\n`null`, the max value is automatically calculated. If the\n`endOnTick` option is true, the max value might be rounded up."},subtree:{}},maxColor:{meta:{types:{color:1},name:"maxColor",excludes:{},default:"#003399",products:{highcharts:1,highmaps:1},description:"The color to represent the maximum of the color axis. Unless\n[dataClasses](#colorAxis.dataClasses) or\n[stops](#colorAxis.stops) are set, the gradient ends at this\nvalue.\n\nIf dataClasses are set, the color is based on minColor and\nmaxColor unless a color is set for each data class, or the\n[dataClassColor](#colorAxis.dataClassColor) is set."},subtree:{}},maxPadding:{meta:{types:{number:1},name:"maxPadding",excludes:{},default:0,products:{highcharts:1,highmaps:1},description:"Padding of the max value relative to the length of the axis. A\npadding of 0.05 will make a 100px axis 5px longer."},subtree:{}},min:{meta:{types:{number:1},name:"min",excludes:{},products:{highcharts:1,highmaps:1},description:"The minimum value of the axis in terms of map point values. If\n`null`, the min value is automatically calculated. If the\n`startOnTick` option is true, the min value might be rounded\ndown."},subtree:{}},minColor:{meta:{types:{color:1},name:"minColor",excludes:{},default:"#e6ebf5",products:{highcharts:1,highmaps:1},description:"The color to represent the minimum of the color axis. Unless\n[dataClasses](#colorAxis.dataClasses) or\n[stops](#colorAxis.stops) are set, the gradient starts at this\nvalue.\n\nIf dataClasses are set, the color is based on minColor and\nmaxColor unless a color is set for each data class, or the\n[dataClassColor](#colorAxis.dataClassColor) is set."},subtree:{}},minPadding:{meta:{types:{number:1},name:"minPadding",excludes:{},default:0,products:{highcharts:1,highmaps:1},description:"Padding of the min value relative to the length of the axis. A\npadding of 0.05 will make a 100px axis 5px longer."},subtree:{}},reversed:{meta:{types:{boolean:1},name:"reversed",excludes:{},products:{highcharts:1,highmaps:1},description:"Whether to reverse the axis so that the highest number is closest\nto the origin. Defaults to `false` in a horizontal legend and\n`true` in a vertical legend, where the smallest value starts on\ntop."},subtree:{}},showInLegend:{meta:{types:{boolean:1},name:"showInLegend",excludes:{},default:"true",products:{highcharts:1,highmaps:1},description:"Whether to display the colorAxis in the legend."},subtree:{}},startOnTick:{meta:{types:{boolean:1},name:"startOnTick",excludes:{},default:"true",products:{highcharts:1,highmaps:1},description:"Whether to force the axis to start on a tick. Use this option\nwith the `maxPadding` option to control the axis start."},subtree:{}},stops:{meta:{types:{array:"Array"},name:"stops",excludes:{},products:{highcharts:1,highmaps:1},description:"Color stops for the gradient of a scalar color axis. Use this in\ncases where a linear gradient between a `minColor` and `maxColor`\nis not sufficient. The stops is an array of tuples, where the\nfirst item is a float between 0 and 1 assigning the relative\nposition in the gradient, and the second item is the color."},subtree:{}},tickInterval:{meta:{types:{number:1},name:"tickInterval",excludes:{},products:{highcharts:1,highmaps:1},description:"The interval of the tick marks in axis units. When `null`, the\ntick interval is computed to approximately follow the\n`tickPixelInterval`."},subtree:{}},tickLength:{meta:{types:{number:1},name:"tickLength",excludes:{},default:5,description:"The pixel length of the main tick marks on the color axis."},subtree:{}},tickPixelInterval:{meta:{types:{number:1},name:"tickPixelInterval",excludes:{},default:"72",products:{highcharts:1,highmaps:1},description:"If [tickInterval](#colorAxis.tickInterval) is `null` this option\nsets the approximate pixel interval of the tick marks."},subtree:{}},type:{meta:{types:{string:1},name:"type",excludes:{},default:"linear",products:{highcharts:1,highmaps:1},description:"The type of interpolation to use for the color axis. Can be\n`linear` or `logarithmic`."},subtree:{}}}},colors:{meta:{types:{array:"Highcharts.ColorString"},name:"colors",excludes:{},default:'["#7cb5ec", "#434348", "#90ed7d", "#f7a35c", "#8085e9",\n "#f15c80", "#e4d354", "#2b908f", "#f45b5b", "#91e8e1"]',description:"An array containing the default colors for the chart's series. When\nall colors are used, new colors are pulled from the start again.\n\nDefault colors can also be set on a series or series.type basis,\nsee [column.colors](#plotOptions.column.colors),\n[pie.colors](#plotOptions.pie.colors).\n\nIn styled mode, the colors option doesn't exist. Instead, colors\nare defined in CSS and applied either through series or point class\nnames, or through the [chart.colorCount](#chart.colorCount) option.\n\n\n### Legacy\n\nIn Highcharts 3.x, the default colors were:\n\n
    colors: ['#2f7ed8', '#0d233a', '#8bbc21', '#910000', '#1aadce',\n    '#492970', '#f28f43', '#77a1e5', '#c42525', '#a6c96a']
    \n\nIn Highcharts 2.x, the default colors were:\n\n
    colors: ['#4572A7', '#AA4643', '#89A54E', '#80699B', '#3D96AE',\n   '#DB843D', '#92A8CD', '#A47D7C', '#B5CA92']
    "},subtree:{}},credits:{meta:{types:{"*":1},name:"credits",excludes:{},description:"Highchart by default puts a credits label in the lower right corner\nof the chart. This can be changed using these options."},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0,description:"Whether to show the credits text."},subtree:{}},href:{meta:{types:{string:1},name:"href",excludes:{},default:"https://www.highcharts.com",description:"The URL for the credits label."},subtree:{}},mapText:{meta:{types:{string:1},name:"mapText",excludes:{},default:'\\u00a9 {geojson.copyrightShort}',products:{highmaps:1},description:"Credits for map source to be concatenated with conventional credit\ntext. By default this is a format string that collects copyright\ninformation from the map if available."},subtree:{}},mapTextFull:{meta:{types:{string:1},name:"mapTextFull",excludes:{},default:"{geojson.copyright}",products:{highmaps:1},description:"Detailed credits for map source to be displayed on hover of credits\ntext. By default this is a format string that collects copyright\ninformation from the map if available."},subtree:{}},position:{meta:{types:{"*":1},name:"position",excludes:{},description:"Position configuration for the credits label."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"right",description:"Horizontal alignment of the credits."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"bottom",description:"Vertical alignment of the credits."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"-10",description:"Horizontal pixel offset of the credits."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:"-5",description:"Vertical pixel offset of the credits."},subtree:{}}}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},default:'{"cursor": "pointer", "color": "#999999", "fontSize": "10px"}',description:"CSS styles for the credits label."},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#999999"},subtree:{}},cursor:{meta:{types:{string:1},name:"cursor",excludes:{},default:"pointer"},subtree:{}},fontSize:{meta:{types:{string:1},name:"fontSize",excludes:{},default:"9px"},subtree:{}}}},text:{meta:{types:{string:1},name:"text",excludes:{},default:"Highcharts.com",description:"The text for the credits label."},subtree:{}}}},defs:{meta:{types:{"*":1},name:"defs",excludes:{},description:"Styled mode only. Configuration object for adding SVG definitions for\nreusable elements. See [gradients, shadows and\npatterns](https://www.highcharts.com/docs/chart-design-and-style/gradients-shadows-and-patterns)\nfor more information and code examples."},subtree:{}},drilldown:{meta:{types:{object:1},name:"drilldown",excludes:{},description:"Options for drill down, the concept of inspecting increasingly high\nresolution data through clicking on chart items like columns or pie slices.\n\nThe drilldown feature requires the drilldown.js file to be loaded,\nfound in the modules directory of the download package, or online at\n[code.highcharts.com/modules/drilldown.js\n](code.highcharts.com/modules/drilldown.js)."},subtree:{activeAxisLabelStyle:{meta:{types:{cssobject:1},name:"activeAxisLabelStyle",excludes:{},default:'{ "cursor": "pointer", "color": "#003399", "fontWeight": "bold", "textDecoration": "underline" }',products:{highcharts:1,highmaps:1},description:"Additional styles to apply to the X axis label for a point that\nhas drilldown data. By default it is underlined and blue to invite\nto interaction."},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#003399"},subtree:{}},cursor:{meta:{types:{string:1},name:"cursor",excludes:{},default:"pointer"},subtree:{}},fontWeight:{meta:{types:{string:1},name:"fontWeight",excludes:{},default:"bold"},subtree:{}},textDecoration:{meta:{types:{string:1},name:"textDecoration",excludes:{},default:"underline"},subtree:{}}}},activeDataLabelStyle:{meta:{types:{cssobject:1},name:"activeDataLabelStyle",excludes:{},default:'{ "cursor": "pointer", "color": "#003399", "fontWeight": "bold", "textDecoration": "underline" }',products:{highcharts:1,highmaps:1},description:"Additional styles to apply to the data label of a point that has\ndrilldown data. By default it is underlined and blue to invite to\ninteraction."},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#003399" },subtree:{}},cursor:{meta:{types:{string:1},name:"cursor",excludes:{},default:"pointer"},subtree:{}},fontWeight:{meta:{types:{string:1},name:"fontWeight",excludes:{},default:"bold"},subtree:{}},textDecoration:{meta:{types:{string:1},name:"textDecoration",excludes:{},default:"underline"},subtree:{}}}},allowPointDrilldown:{meta:{types:{boolean:1},name:"allowPointDrilldown",excludes:{},default:"true",products:{highcharts:1},description:"When this option is false, clicking a single point will drill down\nall points in the same category, equivalent to clicking the X axis\nlabel."},subtree:{}},animation:{meta:{types:{animationoptions:1,boolean:1},name:"animation",excludes:{},products:{highcharts:1,highmaps:1},description:"Set the animation for all drilldown animations. Animation of a drilldown\noccurs when drilling between a column point and a column series,\nor a pie slice and a full pie series. Drilldown can still be used\nbetween series and points of different types, but animation will\nnot occur.\n\nThe animation can either be set as a boolean or a configuration\nobject. If `true`, it will use the 'swing' jQuery easing and a duration\nof 500 ms. If used as a configuration object, the following properties\nare supported:\n\n
    \n\n
    duration
    \n\n
    The duration of the animation in milliseconds.
    \n\n
    easing
    \n\n
    A string reference to an easing function set on the `Math` object.\nSee [the easing demo](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/series-\nanimation-easing/).
    \n\n
    "},subtree:{duration:{meta:{types:{number:1,string:1},name:"duration",excludes:{},default:"500",description:"Duration for the drilldown animation."},subtree:{}}}},drillUpButton:{meta:{types:{object:1},name:"drillUpButton",excludes:{},products:{highcharts:1,highmaps:1},description:"Options for the drill up button that appears when drilling down\non a series. The text for the button is defined in\n[lang.drillUpText](#lang.drillUpText)."},subtree:{position:{meta:{types:{object:1},name:"position",excludes:{},products:{highcharts:1,highmaps:1},description:"Positioning options for the button within the `relativeTo` box.\nAvailable properties are `x`, `y`, `align` and `verticalAlign`."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"right",description:"Horizontal alignment."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"top",products:{highcharts:1,highmaps:1},description:"Vertical alignment of the button."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:-10,description:"The X offset of the button."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:10,description:"The Y offset of the button."},subtree:{}}}},relativeTo:{meta:{types:{string:1},name:"relativeTo",excludes:{},default:"plotBox",products:{highcharts:1,highmaps:1},description:"What box to align the button to. Can be either `plotBox` or\n`spacingBox`."},subtree:{}},theme:{meta:{types:{object:1},name:"theme",excludes:{},products:{highcharts:1,highmaps:1},description:"A collection of attributes for the button. The object takes SVG\nattributes like `fill`, `stroke`, `stroke-width` or `r`, the border\nradius. The theme also supports `style`, a collection of CSS\nproperties for the text. Equivalent attributes for the hover state\nare given in `theme.states.hover`."},subtree:{}}}},series:{meta:{types:{array:"Object"},name:"series",excludes:{},products:{highcharts:1,highmaps:1},description:"An array of series configurations for the drill down. Each series\nconfiguration uses the same syntax as the [series](#series) option\nset. These drilldown series are hidden by default. The drilldown\nseries is linked to the parent series' point by its `id`."},subtree:{}}}},exporting:{meta:{types:{object:1},name:"exporting",excludes:{},description:"Options for the exporting module. For an overview on the matter, see\n[the docs](https://www.highcharts.com/docs/export-module/export-module-overview)."},subtree:{allowHTML:{meta:{types:{boolean:1},name:"allowHTML",excludes:{},default:"false",description:"Experimental setting to allow HTML inside the chart (added through\nthe `useHTML` options), directly in the exported image. This allows\nyou to preserve complicated HTML structures like tables or bi-directional\ntext in exported charts.\n\nDisclaimer: The HTML is rendered in a `foreignObject` tag in the\ngenerated SVG. The official export server is based on PhantomJS,\nwhich supports this, but other SVG clients, like Batik, does not\nsupport it. This also applies to downloaded SVG that you want to\nopen in a desktop client."},subtree:{}},buttons:{meta:{types:{object:1},name:"buttons",excludes:{},description:"Options for the export related buttons, print and export. In addition\nto the default buttons listed here, custom buttons can be added.\nSee [navigation.buttonOptions](#navigation.buttonOptions) for general\noptions."},subtree:{contextButton:{meta:{types:{object:1},name:"contextButton",excludes:{},description:"Options for the export button.\n\nIn styled mode, export button styles can be applied with the\n`.highcharts-contextbutton` class.",extends:"navigation.buttonOptions"},subtree:{_titleKey:{meta:{types:{string:1},name:"_titleKey",excludes:{},default:"contextButtonTitle",description:'The key to a [lang](#lang) option setting that is used for the\nbutton\'s title tooltip. When the key is `contextButtonTitle`, it\nrefers to [lang.contextButtonTitle](#lang.contextButtonTitle)\nthat defaults to "Chart context menu".'},subtree:{}},className:{meta:{types:{string:1},name:"className",excludes:{},default:"highcharts-contextbutton",description:"The class name of the context button."},subtree:{}},menuClassName:{meta:{types:{string:1},name:"menuClassName",excludes:{},default:"highcharts-contextmenu",description:"The class name of the menu appearing from the button."},subtree:{}},menuItems:{meta:{types:{array:"String"},name:"menuItems",excludes:{},description:"A collection of strings pointing to config options for the menu\nitems. The config options are defined in the\n`menuItemDefinitions` option.\n\nBy default, there is the \"Print\" menu item plus one menu item\nfor each of the available export types.\n\nDefaults to\n
    \n[\n   'printChart',\n   'separator',\n   'downloadPNG',\n   'downloadJPEG',\n   'downloadPDF',\n   'downloadSVG'\n]\n
    "},subtree:{}},onclick:{meta:{types:{function:1},name:"onclick",excludes:{},description:"A click handler callback to use on the button directly instead of\nthe popup menu."},subtree:{}},symbol:{meta:{types:{string:1},name:"symbol",excludes:{},default:"menu",description:"The symbol for the button. Points to a definition function in\nthe `Highcharts.Renderer.symbols` collection. The default\n`exportIcon` function is part of the exporting module."},subtree:{}},symbolFill:{meta:{types:{color:1},name:"symbolFill",excludes:{},default:"#666666",description:"See [navigation.buttonOptions.symbolFill](\n#navigation.buttonOptions.symbolFill)."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"-10",description:"The horizontal position of the button relative to the `align`\noption."},subtree:{}}}}}},chartOptions:{meta:{types:{object:1},name:"chartOptions",excludes:{},default:"null",description:"Additional chart options to be merged into an exported chart. For\nexample, a common use case is to add data labels to improve readability\nof the exported chart, or to add a printer-friendly color scheme."},subtree:{}},csv:{meta:{types:{object:1},name:"csv",excludes:{},description:"Options for exporting data to CSV or ExCel, or displaying the data\nin a HTML table or a JavaScript structure. Requires the\n`export-data.js` module. This module adds data export options to the\nexport menu and provides functions like `Chart.getCSV`,\n`Chart.getTable`, `Chart.getDataRows` and `Chart.viewData`.\n\nThe XLS converter is limited and only creates a HTML string that is\npassed for download, which works but creates a warning before\nopening. The workaround for this is to use a third party XLSX\nconverter, as demonstrated in the sample below."},subtree:{columnHeaderFormatter:{meta:{types:{function:1,null:1},name:"columnHeaderFormatter",excludes:{},default:null,description:'Formatter callback for the column headers. Parameters are:\n- `item` - The series or axis object)\n- `key` - The point key, for example y or z\n- `keyLength` - The amount of value keys for this item, for\n example a range series has the keys `low` and `high` so the\n key length is 2.\n\nIf [useMultiLevelHeaders](#exporting.useMultiLevelHeaders) is\ntrue, columnHeaderFormatter by default returns an object with\ncolumnTitle and topLevelColumnTitle for each key. Columns with\nthe same topLevelColumnTitle have their titles merged into a\nsingle cell with colspan for table/Excel export.\n\nIf `useMultiLevelHeaders` is false, or for CSV export, it returns\nthe series name, followed by the key if there is more than one\nkey.\n\nFor the axis it returns the axis title or "Category" or\n"DateTime" by default.\n\nReturn `false` to use Highcharts\' proposed header.'},subtree:{}},dateFormat:{meta:{types:{string:1},name:"dateFormat",excludes:{},default:"%Y-%m-%d %H:%M:%S",description:"Which date format to use for exported dates on a datetime X axis.\nSee `Highcharts.dateFormat`."},subtree:{}},decimalPoint:{meta:{types:{string:1},name:"decimalPoint",excludes:{},default:null,description:"Which decimal point to use for exported CSV. Defaults to the same\nas the browser locale, typically `.` (English) or `,` (German,\nFrench etc)."},subtree:{}},itemDelimiter:{meta:{types:{string:1},name:"itemDelimiter",excludes:{},default:null,description:"The item delimiter in the exported data. Use `;` for direct\nexporting to Excel. Defaults to a best guess based on the browser\nlocale. If the locale _decimal point_ is `,`, the `itemDelimiter`\ndefaults to `;`, otherwise the `itemDelimiter` defaults to `,`."},subtree:{}},lineDelimiter:{meta:{types:{string:1},name:"lineDelimiter",excludes:{},default:"\n",description:"The line delimiter in the exported data, defaults to a newline."},subtree:{}}}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",description:"Whether to enable the exporting module. Disabling the module will\nhide the context button, but API methods will still be available."},subtree:{}},error:{meta:{types:{function:1},name:"error",excludes:{},default:"undefined",description:"Function to call if the offline-exporting module fails to export\na chart on the client side, and [fallbackToExportServer](\n#exporting.fallbackToExportServer) is disabled. If left undefined, an\nexception is thrown instead. Receives two parameters, the exporting\noptions, and the error from the module."},subtree:{}},fallbackToExportServer:{meta:{types:{boolean:1},name:"fallbackToExportServer",excludes:{},default:"true",description:"Whether or not to fall back to the export server if the offline-exporting\nmodule is unable to export the chart on the client side. This happens for\ncertain browsers, and certain features (e.g.\n[allowHTML](#exporting.allowHTML)), depending on the image type exporting\nto. For very complex charts, it is possible that export can fail in\nbrowsers that don't support Blob objects, due to data URL length limits.\nIt is recommended to define the [exporting.error](#exporting.error)\nhandler if disabling fallback, in order to notify users in case export\nfails."},subtree:{}},filename:{meta:{types:{string:1},name:"filename",excludes:{},default:"chart",description:"The filename, without extension, to use for the exported chart."},subtree:{}},formAttributes:{meta:{types:{object:1},name:"formAttributes",excludes:{},description:"An object containing additional attributes for the POST form that\nsends the SVG to the export server. For example, a `target` can be\nset to make sure the generated image is received in another frame,\n or a custom `enctype` or `encoding` can be set."},subtree:{}},libURL:{meta:{types:{string:1},name:"libURL",excludes:{},description:"Path where Highcharts will look for export module dependencies to\nload on demand if they don't already exist on `window`. Should currently\npoint to location of [CanVG](https://github.com/canvg/canvg) library,\n[RGBColor.js](https://github.com/canvg/canvg), [jsPDF](https://github.\ncom/yWorks/jsPDF) and [svg2pdf.js](https://github.com/yWorks/svg2pdf.\njs), required for client side export in certain browsers."},subtree:{}},menuItemDefinitions:{meta:{types:{object:1},name:"menuItemDefinitions",excludes:{},description:"An object consisting of definitions for the menu items in the context\nmenu. Each key value pair has a `key` that is referenced in the\n[menuItems](#exporting.buttons.contextButton.menuItems) setting,\nand a `value`, which is an object with the following properties:\n\n
    \n\n
    onclick
    \n\n
    The click handler for the menu item
    \n\n
    text
    \n\n
    The text for the menu item
    \n\n
    textKey
    \n\n
    If internationalization is required, the key to a language string\n
    \n\n
    "},subtree:{}},printMaxWidth:{meta:{types:{number:1},name:"printMaxWidth",excludes:{},default:"780",description:"When printing the chart from the menu item in the burger menu, if\nthe on-screen chart exceeds this width, it is resized. After printing\nor cancelled, it is restored. The default width makes the chart\nfit into typical paper format. Note that this does not affect the\nchart when printing the web page as a whole."},subtree:{}},scale:{meta:{types:{number:1},name:"scale",excludes:{},default:2,description:"Defines the scale or zoom factor for the exported image compared\nto the on-screen display. While for instance a 600px wide chart\nmay look good on a website, it will look bad in print. The default\nscale of 2 makes this chart export to a 1200px PNG or JPG."},subtree:{}},showTable:{meta:{types:{boolean:1},name:"showTable",excludes:{},default:!1,description:"Export-data module required. Show a HTML table below the chart with\nthe chart's current data."},subtree:{}},sourceHeight:{meta:{types:{number:1},name:"sourceHeight",excludes:{},description:"Analogous to [sourceWidth](#exporting.sourceWidth)."},subtree:{}},sourceWidth:{meta:{types:{number:1},name:"sourceWidth",excludes:{},description:"The width of the original chart when exported, unless an explicit\n[chart.width](#chart.width) is set. The width exported raster image\nis then multiplied by [scale](#exporting.scale)."},subtree:{}},tableCaption:{meta:{types:{boolean:1,string:1},name:"tableCaption",excludes:{},default:"undefined",description:"Export-data module required. Caption for the data table. Same as\nchart title by default. Set to `false` to disable."},subtree:{}},type:{meta:{types:{string:1},name:"type",excludes:{},default:"image/png",description:"Default MIME type for exporting if `chart.exportChart()` is called\nwithout specifying a `type` option. Possible values are `image/png`,\n `image/jpeg`, `application/pdf` and `image/svg+xml`."},subtree:{}},url:{meta:{types:{string:1},name:"url",excludes:{},default:"https://export.highcharts.com/",description:"The URL for the server module converting the SVG string to an image\nformat. By default this points to Highchart's free web service."},subtree:{}},useMultiLevelHeaders:{meta:{types:{boolean:1},name:"useMultiLevelHeaders",excludes:{},default:!0,description:"Export-data module required. Use multi level headers in data table.\nIf [csv.columnHeaderFormatter](#exporting.csv.columnHeaderFormatter)\nis defined, it has to return objects in order for multi level headers\nto work."},subtree:{}},useRowspanHeaders:{meta:{types:{boolean:1},name:"useRowspanHeaders",excludes:{},default:!0,description:"Export-data module required. If using multi level table headers, use\nrowspans for headers that have only one level."},subtree:{}},width:{meta:{types:{number:1},name:"width",excludes:{},default:"undefined",description:"The pixel width of charts exported to PNG or JPG. As of Highcharts\n3.0, the default pixel width is a function of the [chart.width](\n#chart.width) or [exporting.sourceWidth](#exporting.sourceWidth) and the\n[exporting.scale](#exporting.scale)."},subtree:{}}}},global:{meta:{types:{object:1},name:"global",excludes:{}},subtree:{Date:{meta:{types:{function:1},name:"Date",excludes:{},products:{highcharts:1,highstock:1},description:"This option is deprecated since v6.0.5. Instead, use\n[time.Date](#time.Date) that supports individual time settings\nper chart."},subtree:{}},VMLRadialGradientURL:{meta:{types:{string:1},name:"VMLRadialGradientURL",excludes:{},description:"Path to the pattern image required by VML browsers in order to\ndraw radial gradients."},subtree:{}},canvasToolsURL:{meta:{types:{string:1},name:"canvasToolsURL",excludes:{},products:{highcharts:1,highmaps:1},description:"_Canvg rendering for Android 2.x is removed as of Highcharts 5.0\\.\nUse the [libURL](#exporting.libURL) option to configure exporting._\n\nThe URL to the additional file to lazy load for Android 2.x devices.\nThese devices don't support SVG, so we download a helper file that\ncontains [canvg](http://code.google.com/p/canvg/), its dependency\nrbcolor, and our own CanVG Renderer class. To avoid hotlinking to\nour site, you can install canvas-tools.js on your own server and\nchange this option accordingly."},subtree:{}},getTimezoneOffset:{meta:{types:{function:1},name:"getTimezoneOffset",excludes:{},products:{highcharts:1,highstock:1},description:"This option is deprecated since v6.0.5. Instead, use\n[time.getTimezoneOffset](#time.getTimezoneOffset) that supports\nindividual time settings per chart."},subtree:{}},timezone:{meta:{types:{string:1},name:"timezone",excludes:{},products:{highcharts:1,highstock:1},description:"This option is deprecated since v6.0.5. Instead, use\n[time.timezone](#time.timezone) that supports individual time\nsettings per chart."},subtree:{}},timezoneOffset:{meta:{types:{number:1},name:"timezoneOffset",excludes:{},products:{highcharts:1,highstock:1},description:"This option is deprecated since v6.0.5. Instead, use\n[time.timezoneOffset](#time.timezoneOffset) that supports individual\ntime settings per chart."},subtree:{}},useUTC:{meta:{types:{boolean:1},name:"useUTC",excludes:{},description:"This option is deprecated since v6.0.5. Instead, use\n[time.useUTC](#time.useUTC) that supports individual time settings\nper chart."},subtree:{}}}},labels:{meta:{types:{"*":1},name:"labels",excludes:{},description:"HTML labels that can be positioned anywhere in the chart area."},subtree:{items:{meta:{types:{array:"*"},name:"items",excludes:{},description:"An HTML label that can be positioned anywhere in the chart area."},subtree:{html:{meta:{types:{string:1},name:"html",excludes:{},description:"Inner HTML or text for the label."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},description:"CSS styles for each label. To position the label, use left and top\nlike this:\n\n
    style: {\n    left: '100px',\n    top: '100px'\n}
    "},subtree:{}}}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},default:'{"color": "#333333"}',description:"Shared CSS styles for all labels."},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#333333"},subtree:{}},position:{meta:{types:{string:1},name:"position",excludes:{},default:"absolute"},subtree:{}}}}}},lang:{meta:{types:{"*":1},name:"lang",excludes:{},description:"Language object. The language object is global and it can't be set\non each chart initiation. Instead, use `Highcharts.setOptions` to\nset it before any chart is initialized.\n\n
    Highcharts.setOptions({\n    lang: {\n        months: [\n            'Janvier', 'Février', 'Mars', 'Avril',\n            'Mai', 'Juin', 'Juillet', 'Août',\n            'Septembre', 'Octobre', 'Novembre', 'Décembre'\n        ],\n        weekdays: [\n            'Dimanche', 'Lundi', 'Mardi', 'Mercredi',\n            'Jeudi', 'Vendredi', 'Samedi'\n        ]\n    }\n});
    "},subtree:{accessibility:{meta:{types:{object:1},name:"accessibility",excludes:{},description:"Configure the accessibility strings in the chart. Requires the\n[accessibility module](//code.highcharts.com/modules/accessibility.\njs) to be loaded. For a description of the module and information\non its features, see [Highcharts Accessibility](http://www.highcharts.\ncom/docs/chart-concepts/accessibility).\n\nFor more dynamic control over the accessibility functionality, see\n[accessibility.pointDescriptionFormatter](\naccessibility.pointDescriptionFormatter),\n[accessibility.seriesDescriptionFormatter](\naccessibility.seriesDescriptionFormatter), and\n[accessibility.screenReaderSectionFormatter](\naccessibility.screenReaderSectionFormatter)."},subtree:{axis:{meta:{types:{object:1},name:"axis",excludes:{},description:"Axis description format strings."},subtree:{xAxisDescriptionPlural:{meta:{types:{string:1},name:"xAxisDescriptionPlural",excludes:{},default:"The chart has {numAxes} X axes displaying {#each(names, -1), }and {names[-1]}"},subtree:{}},xAxisDescriptionSingular:{meta:{types:{string:1},name:"xAxisDescriptionSingular",excludes:{},default:"The chart has 1 X axis displaying {names[0]}."},subtree:{}},yAxisDescriptionPlural:{meta:{types:{string:1},name:"yAxisDescriptionPlural",excludes:{},default:"The chart has {numAxes} Y axes displaying {#each(names, -1), }and {names[-1]}"},subtree:{}},yAxisDescriptionSingular:{meta:{types:{string:1},name:"yAxisDescriptionSingular",excludes:{},default:"The chart has 1 Y axis displaying {names[0]}."},subtree:{}}}},chartContainerLabel:{meta:{types:{string:1},name:"chartContainerLabel",excludes:{},default:"Interactive chart. {title}. Use up and down arrows to navigate with most screen readers."},subtree:{}},chartHeading:{meta:{types:{string:1},name:"chartHeading",excludes:{},default:"Chart graphic."},subtree:{}},chartTypes:{meta:{types:{object:1},name:"chartTypes",excludes:{},description:"Chart type description strings. This is added to the chart\ninformation region.\n\nIf there is only a single series type used in the chart, we use\nthe format string for the series type, or default if missing.\nThere is one format string for cases where there is only a single\nseries in the chart, and one for multiple series of the same\ntype."},subtree:{barMultiple:{meta:{types:{string:1},name:"barMultiple",excludes:{},default:"Bar chart with {numSeries} data series."},subtree:{}},barSingle:{meta:{types:{string:1},name:"barSingle",excludes:{},default:"Bar chart with {numPoints} {#plural(numPoints, bars, bar)}."},subtree:{}},boxplotMultiple:{meta:{types:{string:1},name:"boxplotMultiple",excludes:{},default:"Boxplot with {numSeries} data series."},subtree:{}},boxplotSingle:{meta:{types:{string:1},name:"boxplotSingle",excludes:{},default:"Boxplot with {numPoints} {#plural(numPoints, boxes, box)}."},subtree:{}},bubbleMultiple:{meta:{types:{string:1},name:"bubbleMultiple",excludes:{},default:"Bubble chart with {numSeries} data series."},subtree:{}},bubbleSingle:{meta:{types:{string:1},name:"bubbleSingle",excludes:{},default:"Bubble chart with {numPoints} {#plural(numPoints, bubbles, bubble)}."},subtree:{}},columnMultiple:{meta:{types:{string:1},name:"columnMultiple",excludes:{},default:"Bar chart with {numSeries} data series."},subtree:{}},columnSingle:{meta:{types:{string:1},name:"columnSingle",excludes:{},default:"Bar chart with {numPoints} {#plural(numPoints, bars, bar)}."},subtree:{}},combinationChart:{meta:{types:{string:1},name:"combinationChart",excludes:{},default:"Combination chart with {numSeries} data series."},subtree:{}},defaultMultiple:{meta:{types:{string:1},name:"defaultMultiple",excludes:{},default:"Chart with {numSeries} data series."},subtree:{}},defaultSingle:{meta:{types:{string:1},name:"defaultSingle",excludes:{},default:"Chart with {numPoints} data {#plural(numPoints, points, point)}."},subtree:{}},emptyChart:{meta:{types:{string:1},name:"emptyChart",excludes:{},default:"Empty chart"},subtree:{}},lineMultiple:{meta:{types:{string:1},name:"lineMultiple",excludes:{},default:"Line chart with {numSeries} lines."},subtree:{}},lineSingle:{meta:{types:{string:1},name:"lineSingle",excludes:{},default:"Line chart with {numPoints} data {#plural(numPoints, points, point)}."},subtree:{}},mapTypeDescription:{meta:{types:{string:1},name:"mapTypeDescription",excludes:{},default:"Map of {mapTitle} with {numSeries} data series."},subtree:{}},pieMultiple:{meta:{types:{string:1},name:"pieMultiple",excludes:{},default:"Pie chart with {numSeries} pies."},subtree:{}},pieSingle:{meta:{types:{string:1},name:"pieSingle",excludes:{},default:"Pie chart with {numPoints} {#plural(numPoints, slices, slice)}."},subtree:{}},scatterMultiple:{meta:{types:{string:1},name:"scatterMultiple",excludes:{},default:"Scatter chart with {numSeries} data series."},subtree:{}},scatterSingle:{meta:{types:{string:1},name:"scatterSingle",excludes:{},default:"Scatter chart with {numPoints} {#plural(numPoints, points, point)}."},subtree:{}},splineMultiple:{meta:{types:{string:1},name:"splineMultiple",excludes:{},default:"Line chart with {numSeries} lines."},subtree:{}},splineSingle:{meta:{types:{string:1},name:"splineSingle",excludes:{},default:"Line chart with {numPoints} data {#plural(numPoints, points, point)}."},subtree:{}},unknownMap:{meta:{types:{string:1},name:"unknownMap",excludes:{},default:"Map of unspecified region with {numSeries} data series."},subtree:{}}}},defaultChartTitle:{meta:{types:{string:1},name:"defaultChartTitle",excludes:{},default:"Chart"},subtree:{}},exporting:{meta:{types:{object:1},name:"exporting",excludes:{},description:"Exporting menu format strings for accessibility module."},subtree:{chartMenuLabel:{meta:{types:{string:1},name:"chartMenuLabel",excludes:{},default:"Chart export"},subtree:{}},exportRegionLabel:{meta:{types:{string:1},name:"exportRegionLabel",excludes:{},default:"Chart export menu"},subtree:{}},menuButtonLabel:{meta:{types:{string:1},name:"menuButtonLabel",excludes:{},default:"View export menu"},subtree:{}}}},legendItem:{meta:{types:{string:1},name:"legendItem",excludes:{},default:"Toggle visibility of series {itemName}"},subtree:{}},longDescriptionHeading:{meta:{types:{string:1},name:"longDescriptionHeading",excludes:{},default:"Long description."},subtree:{}},mapZoomIn:{meta:{types:{string:1},name:"mapZoomIn",excludes:{},default:"Zoom chart"},subtree:{}},mapZoomOut:{meta:{types:{string:1},name:"mapZoomOut",excludes:{},default:"Zoom out chart"},subtree:{}},navigationHint:{meta:{types:{string:1},name:"navigationHint",excludes:{},default:"Use regions/landmarks to skip ahead to chart {#plural(numSeries, and navigate between data series,)}"},subtree:{}},noDescription:{meta:{types:{string:1},name:"noDescription",excludes:{},default:"No description available."},subtree:{}},rangeSelectorButton:{meta:{types:{string:1},name:"rangeSelectorButton",excludes:{},default:"Select range {buttonText}"},subtree:{}},rangeSelectorMaxInput:{meta:{types:{string:1},name:"rangeSelectorMaxInput",excludes:{},default:"Select end date."},subtree:{}},rangeSelectorMinInput:{meta:{types:{string:1},name:"rangeSelectorMinInput",excludes:{},default:"Select start date."},subtree:{}},screenReaderRegionLabel:{meta:{types:{string:1},name:"screenReaderRegionLabel",excludes:{},default:"Chart screen reader information."},subtree:{}},series:{meta:{types:{object:1},name:"series",excludes:{},description:"Lang configuration for different series types. For more dynamic\ncontrol over the series element descriptions, see\n[accessibility.seriesDescriptionFormatter](\naccessibility.seriesDescriptionFormatter)."},subtree:{description:{meta:{types:{string:1},name:"description",excludes:{},default:"{description}",description:"User supplied description text. This is added after the main\nsummary if present."},subtree:{}},summary:{meta:{types:{object:1},name:"summary",excludes:{},description:"Lang configuration for the series main summary. Each series\ntype has two modes:\n 1. This series type is the only series type used in the\n chart\n 2. This is a combination chart with multiple series types\n\nIf a definition does not exist for the specific series type\nand mode, the 'default' lang definitions are used."},subtree:{bar:{meta:{types:{string:1},name:"bar",excludes:{},default:"{name}, bar series {ix} of {numSeries} with {numPoints} {#plural(numPoints, bars, bar)}."},subtree:{}},barCombination:{meta:{types:{string:1},name:"barCombination",excludes:{},default:"{name}, series {ix} of {numSeries}. Bar series with {numPoints} {#plural(numPoints, bars, bar)}."},subtree:{}},boxplot:{meta:{types:{string:1},name:"boxplot",excludes:{},default:"{name}, boxplot {ix} of {numSeries} with {numPoints} {#plural(numPoints, boxes, box)}."},subtree:{}},boxplotCombination:{meta:{types:{string:1},name:"boxplotCombination",excludes:{},default:"{name}, series {ix} of {numSeries}. Boxplot with {numPoints} {#plural(numPoints, boxes, box)}."},subtree:{}},bubble:{meta:{types:{string:1},name:"bubble",excludes:{},default:"{name}, bubble series {ix} of {numSeries} with {numPoints} {#plural(numPoints, bubbles, bubble)}."},subtree:{}},bubbleCombination:{meta:{types:{string:1},name:"bubbleCombination",excludes:{},default:"{name}, series {ix} of {numSeries}. Bubble series with {numPoints} {#plural(numPoints, bubbles, bubble)}."},subtree:{}},column:{meta:{types:{string:1},name:"column",excludes:{},default:"{name}, bar series {ix} of {numSeries} with {numPoints} {#plural(numPoints, bars, bar)}."},subtree:{}},columnCombination:{meta:{types:{string:1},name:"columnCombination",excludes:{},default:"{name}, series {ix} of {numSeries}. Bar series with {numPoints} {#plural(numPoints, bars, bar)}."},subtree:{}},default:{meta:{types:{string:1},name:"default",excludes:{},default:"{name}, series {ix} of {numSeries} with {numPoints} data {#plural(numPoints, points, point)}."},subtree:{}},defaultCombination:{meta:{types:{string:1},name:"defaultCombination",excludes:{},default:"{name}, series {ix} of {numSeries} with {numPoints} data {#plural(numPoints, points, point)}."},subtree:{}},line:{meta:{types:{string:1},name:"line",excludes:{},default:"{name}, line {ix} of {numSeries} with {numPoints} data {#plural(numPoints, points, point)}."},subtree:{}},lineCombination:{meta:{types:{string:1},name:"lineCombination",excludes:{},default:"{name}, series {ix} of {numSeries}. Line with {numPoints} data {#plural(numPoints, points, point)}."},subtree:{}},map:{meta:{types:{string:1},name:"map",excludes:{},default:"{name}, map {ix} of {numSeries} with {numPoints} {#plural(numPoints, areas, area)}."},subtree:{}},mapCombination:{meta:{types:{string:1},name:"mapCombination",excludes:{},default:"{name}, series {ix} of {numSeries}. Map with {numPoints} {#plural(numPoints, areas, area)}."},subtree:{}},mapbubble:{meta:{types:{string:1},name:"mapbubble",excludes:{},default:"{name}, bubble series {ix} of {numSeries} with {numPoints} {#plural(numPoints, bubbles, bubble)}."},subtree:{}},mapbubbleCombination:{meta:{types:{string:1},name:"mapbubbleCombination",excludes:{},default:"{name}, series {ix} of {numSeries}. Bubble series with {numPoints} {#plural(numPoints, bubbles, bubble)}."},subtree:{}},mapline:{meta:{types:{string:1},name:"mapline",excludes:{},default:"{name}, line {ix} of {numSeries} with {numPoints} data {#plural(numPoints, points, point)}."},subtree:{}},maplineCombination:{meta:{types:{string:1},name:"maplineCombination",excludes:{},default:"{name}, series {ix} of {numSeries}. Line with {numPoints} data {#plural(numPoints, points, point)}."},subtree:{}},pie:{meta:{types:{string:1},name:"pie",excludes:{},default:"{name}, pie {ix} of {numSeries} with {numPoints} {#plural(numPoints, slices, slice)}."},subtree:{}},pieCombination:{meta:{types:{string:1},name:"pieCombination",excludes:{}, default:"{name}, series {ix} of {numSeries}. Pie with {numPoints} {#plural(numPoints, slices, slice)}."},subtree:{}},scatter:{meta:{types:{string:1},name:"scatter",excludes:{},default:"{name}, scatter plot {ix} of {numSeries} with {numPoints} {#plural(numPoints, points, point)}."},subtree:{}},scatterCombination:{meta:{types:{string:1},name:"scatterCombination",excludes:{},default:"{name}, series {ix} of {numSeries}, scatter plot with {numPoints} {#plural(numPoints, points, point)}."},subtree:{}},spline:{meta:{types:{string:1},name:"spline",excludes:{},default:"{name}, line {ix} of {numSeries} with {numPoints} data {#plural(numPoints, points, point)}."},subtree:{}},splineCombination:{meta:{types:{string:1},name:"splineCombination",excludes:{},default:"{name}, series {ix} of {numSeries}. Line with {numPoints} data {#plural(numPoints, points, point)}."},subtree:{}}}},xAxisDescription:{meta:{types:{string:1},name:"xAxisDescription",excludes:{},default:"X axis, {name}",description:"xAxis description for series if there are multiple xAxes in\nthe chart."},subtree:{}},yAxisDescription:{meta:{types:{string:1},name:"yAxisDescription",excludes:{},default:"Y axis, {name}",description:"yAxis description for series if there are multiple yAxes in\nthe chart."},subtree:{}}}},seriesTypeDescriptions:{meta:{types:{object:1},name:"seriesTypeDescriptions",excludes:{},description:"Descriptions of lesser known series types. The relevant\ndescription is added to the screen reader information region\nwhen these series types are used."},subtree:{arearange:{meta:{types:{string:1},name:"arearange",excludes:{},default:"Arearange charts are line charts displaying a range between a lower and higher value for each point."},subtree:{}},areasplinerange:{meta:{types:{string:1},name:"areasplinerange",excludes:{},default:"These charts are line charts displaying a range between a lower and higher value for each point."},subtree:{}},boxplot:{meta:{types:{string:1},name:"boxplot",excludes:{},default:"Box plot charts are typically used to display groups of statistical data. Each data point in the chart can have up to 5 values: minimum, lower quartile, median, upper quartile, and maximum."},subtree:{}},bubble:{meta:{types:{string:1},name:"bubble",excludes:{},default:"Bubble charts are scatter charts where each data point also has a size value."},subtree:{}},columnrange:{meta:{types:{string:1},name:"columnrange",excludes:{},default:"Columnrange charts are column charts displaying a range between a lower and higher value for each point."},subtree:{}},errorbar:{meta:{types:{string:1},name:"errorbar",excludes:{},default:"Errorbar series are used to display the variability of the data."},subtree:{}},funnel:{meta:{types:{string:1},name:"funnel",excludes:{},default:"Funnel charts are used to display reduction of data in stages."},subtree:{}},pyramid:{meta:{types:{string:1},name:"pyramid",excludes:{},default:"Pyramid charts consist of a single pyramid with item heights corresponding to each point value."},subtree:{}},waterfall:{meta:{types:{string:1},name:"waterfall",excludes:{},default:"A waterfall chart is a column chart where each column contributes towards a total end value."},subtree:{}}}},structureHeading:{meta:{types:{string:1},name:"structureHeading",excludes:{},default:"Structure."},subtree:{}},svgContainerTitle:{meta:{types:{string:1},name:"svgContainerTitle",excludes:{},default:"{chartTitle}",description:"Title element text for the chart SVG element. Leave this\nempty to disable adding the title element. Browsers will display\nthis content when hovering over elements in the chart. Assistive\ntechnology may use this element to label the chart."},subtree:{}},tableSummary:{meta:{types:{string:1},name:"tableSummary",excludes:{},default:"Table representation of chart."},subtree:{}},viewAsDataTable:{meta:{types:{string:1},name:"viewAsDataTable",excludes:{},default:"View as data table."},subtree:{}}}},contextButtonTitle:{meta:{types:{string:1},name:"contextButtonTitle",excludes:{},default:"Chart context menu",description:"Exporting module menu. The tooltip title for the context menu holding\nprint and export menu items."},subtree:{}},decimalPoint:{meta:{types:{string:1},name:"decimalPoint",excludes:{},default:".",description:"The default decimal point used in the `Highcharts.numberFormat`\nmethod unless otherwise specified in the function arguments."},subtree:{}},downloadCSV:{meta:{types:{string:1},name:"downloadCSV",excludes:{},default:"Download CSV",description:"Export-data module only. The text for the menu item."},subtree:{}},downloadJPEG:{meta:{types:{string:1},name:"downloadJPEG",excludes:{},default:"Download JPEG image",description:"Exporting module only. The text for the JPEG download menu item."},subtree:{}},downloadPDF:{meta:{types:{string:1},name:"downloadPDF",excludes:{},default:"Download PDF document",description:"Exporting module only. The text for the PDF download menu item."},subtree:{}},downloadPNG:{meta:{types:{string:1},name:"downloadPNG",excludes:{},default:"Download PNG image",description:"Exporting module only. The text for the PNG download menu item."},subtree:{}},downloadSVG:{meta:{types:{string:1},name:"downloadSVG",excludes:{},default:"Download SVG vector image",description:"Exporting module only. The text for the SVG download menu item."},subtree:{}},downloadXLS:{meta:{types:{string:1},name:"downloadXLS",excludes:{},default:"Download XLS",description:"Export-data module only. The text for the menu item."},subtree:{}},drillUpText:{meta:{types:{string:1},name:"drillUpText",excludes:{},default:"Back to {series.name}",products:{highcharts:1,highmaps:1},description:"The text for the button that appears when drilling down, linking\nback to the parent series. The parent series' name is inserted for\n`{series.name}`."},subtree:{}},invalidDate:{meta:{types:{string:1},name:"invalidDate",excludes:{},products:{highcharts:1,highstock:1},description:"What to show in a date field for invalid dates. Defaults to an empty\nstring."},subtree:{}},loading:{meta:{types:{string:1},name:"loading",excludes:{},default:"Loading...",description:"The loading text that appears when the chart is set into the loading\nstate following a call to `chart.showLoading`."},subtree:{}},months:{meta:{types:{array:"string"},name:"months",excludes:{},default:'["January", "February", "March", "April", "May", "June",\n "July", "August", "September", "October", "November",\n "December"]',description:"An array containing the months names. Corresponds to the `%B` format\nin `Highcharts.dateFormat()`."},subtree:{}},noData:{meta:{types:{string:1},name:"noData",excludes:{},default:"No data to display",products:{highcharts:1,highstock:1},description:"The text to display when the chart contains no data. Requires the\nno-data module, see [noData](#noData)."},subtree:{}},numericSymbolMagnitude:{meta:{types:{number:1},name:"numericSymbolMagnitude",excludes:{},default:"1000",description:"The magnitude of [numericSymbols](#lang.numericSymbol) replacements.\nUse 10000 for Japanese, Korean and various Chinese locales, which\nuse symbols for 10^4, 10^8 and 10^12."},subtree:{}},numericSymbols:{meta:{types:{array:"string"},name:"numericSymbols",excludes:{},default:'["k", "M", "G", "T", "P", "E"]',description:"[Metric prefixes](http://en.wikipedia.org/wiki/Metric_prefix) used\nto shorten high numbers in axis labels. Replacing any of the\npositions with `null` causes the full number to be written. Setting\n`numericSymbols` to `null` disables shortening altogether."},subtree:{}},openInCloud:{meta:{types:{string:1},name:"openInCloud",excludes:{},default:"Open in Highcharts Cloud",description:"Export-data module only. The text for the menu item."},subtree:{}},printChart:{meta:{types:{string:1},name:"printChart",excludes:{},default:"Print chart",description:"Exporting module only. The text for the menu item to print the chart."},subtree:{}},rangeSelectorFrom:{meta:{types:{string:1},name:"rangeSelectorFrom",excludes:{},default:"From",products:{highstock:1},description:'The text for the label for the "from" input box in the range\nselector.'},subtree:{}},rangeSelectorTo:{meta:{types:{string:1},name:"rangeSelectorTo",excludes:{},default:"To",products:{highstock:1},description:'The text for the label for the "to" input box in the range selector.'},subtree:{}},rangeSelectorZoom:{meta:{types:{string:1},name:"rangeSelectorZoom",excludes:{},default:"Zoom",products:{highstock:1},description:"The text for the label for the range selector buttons."},subtree:{}},resetZoom:{meta:{types:{string:1},name:"resetZoom",excludes:{},default:"Reset zoom",description:"The text for the label appearing when a chart is zoomed."},subtree:{}},resetZoomTitle:{meta:{types:{string:1},name:"resetZoomTitle",excludes:{},default:"Reset zoom level 1:1",description:"The tooltip title for the label appearing when a chart is zoomed."},subtree:{}},shortMonths:{meta:{types:{array:"string"},name:"shortMonths",excludes:{},default:'["Jan", "Feb", "Mar", "Apr", "May", "Jun",\n "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]',description:"An array containing the months names in abbreviated form. Corresponds\nto the `%b` format in `Highcharts.dateFormat()`."},subtree:{}},shortWeekdays:{meta:{types:{array:"string"},name:"shortWeekdays",excludes:{},description:"Short week days, starting Sunday. If not specified, Highcharts uses\nthe first three letters of the `lang.weekdays` option."},subtree:{}},thousandsSep:{meta:{types:{string:1},name:"thousandsSep",excludes:{},default:"\\u0020",description:"The default thousands separator used in the `Highcharts.numberFormat`\nmethod unless otherwise specified in the function arguments. Since\nHighcharts 4.1 it defaults to a single space character, which is\ncompatible with ISO and works across Anglo-American and continental\nEuropean languages.\n\nThe default is a single space."},subtree:{}},viewData:{meta:{types:{string:1},name:"viewData",excludes:{},default:"View data table",description:"Export-data module only. The text for the menu item."},subtree:{}},weekdays:{meta:{types:{array:"string"},name:"weekdays",excludes:{},default:'["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",\n "Friday", "Saturday"]',description:"An array containing the weekday names."},subtree:{}},zoomIn:{meta:{types:{string:1},name:"zoomIn",excludes:{},default:"Zoom in",products:{highmaps:1},description:'The title appearing on hovering the zoom in button. The text itself\ndefaults to "+" and can be changed in the button options.'},subtree:{}},zoomOut:{meta:{types:{string:1},name:"zoomOut",excludes:{},default:"Zoom out",products:{highmaps:1},description:'The title appearing on hovering the zoom out button. The text itself\ndefaults to "-" and can be changed in the button options.'},subtree:{}}}},legend:{meta:{types:{"*":1},name:"legend",excludes:{},description:"Options for the tooltip that appears when the user hovers over a\nseries or point."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"center",description:"The horizontal alignment of the legend box within the chart area.\nValid values are `left`, `center` and `right`.\n\nIn the case that the legend is aligned in a corner position, the\n`layout` option will determine whether to place it above/below\nor on the side of the plot area."},subtree:{}},alignColumns:{meta:{types:{boolean:1},name:"alignColumns",excludes:{},default:!0,description:"If the [layout](legend.layout) is `horizontal` and the legend items\nspan over two lines or more, whether to align the items into vertical\ncolumns. Setting this to `false` makes room for more items, but will\nlook more messy."},subtree:{}},backgroundColor:{meta:{types:{"highcharts.colorstring":1},name:"backgroundColor",excludes:{},description:"The background color of the legend."},subtree:{}},borderColor:{meta:{types:{"highcharts.colorstring":1},name:"borderColor",excludes:{},default:"#999999",description:"The color of the drawn border around the legend."},subtree:{}},borderRadius:{meta:{types:{number:1},name:"borderRadius",excludes:{},default:0,description:"The border corner radius of the legend."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:"0",description:"The width of the drawn border around the legend."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0,description:"Enable or disable the legend."},subtree:{}},floating:{meta:{types:{string:1},name:"floating",excludes:{},default:"horizontal",description:"The layout of the legend items. Can be one of `horizontal` or\n`vertical` or `proximate`. When `proximate`, the legend items will be\nplaced as close as possible to the graphs they're representing,\nexcept in inverted charts or when the legend position doesn't allow\nit."},subtree:{}},itemCheckboxStyle:{meta:{types:{"highcharts.cssobject":1},name:"itemCheckboxStyle",excludes:{},description:"Default styling for the checkbox next to a legend item when\n`showCheckbox` is true."},subtree:{height:{meta:{types:{string:1},name:"height",excludes:{},default:"13px"},subtree:{}},position:{meta:{types:{string:1},name:"position",excludes:{},default:"absolute"},subtree:{}},width:{meta:{types:{string:1},name:"width",excludes:{},default:"13px"},subtree:{}}}},itemDistance:{meta:{types:{number:1},name:"itemDistance",excludes:{},description:"In a legend with horizontal layout, the itemDistance defines the\npixel distance between each item."},subtree:{}},itemHiddenStyle:{meta:{types:{"highcharts.cssobject":1},name:"itemHiddenStyle",excludes:{},default:'{"color": "#cccccc"}',description:"CSS styles for each legend item when the corresponding series or\npoint is hidden. Only a subset of CSS is supported, notably those\noptions related to text. Properties are inherited from `style`\nunless overridden here."},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#cccccc"},subtree:{}}}},itemHoverStyle:{meta:{types:{"highcharts.cssobject":1},name:"itemHoverStyle",excludes:{},default:'{"color": "#000000"}',description:"CSS styles for each legend item in hover mode. Only a subset of\nCSS is supported, notably those options related to text. Properties\nare inherited from `style` unless overridden here."},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#000000"},subtree:{}}}},itemMarginBottom:{meta:{types:{number:1},name:"itemMarginBottom",excludes:{},default:"0",description:"The pixel bottom margin for each legend item."},subtree:{}},itemMarginTop:{meta:{types:{number:1},name:"itemMarginTop",excludes:{},default:"0",description:"The pixel top margin for each legend item."},subtree:{}},itemStyle:{meta:{types:{"highcharts.cssobject":1},name:"itemStyle",excludes:{},default:'{"color": "#333333", "cursor": "pointer", "fontSize": "12px", "fontWeight": "bold", "textOverflow": "ellipsis"}',description:"CSS styles for each legend item. Only a subset of CSS is supported,\nnotably those options related to text. The default `textOverflow`\nproperty makes long texts truncate. Set it to `undefined` to wrap\ntext instead. A `width` property can be added to control the text\nwidth."},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#333333"},subtree:{}},fontSize:{meta:{types:{string:1},name:"fontSize",excludes:{},default:"12px"},subtree:{}},fontWeight:{meta:{types:{string:1},name:"fontWeight",excludes:{},default:"bold"},subtree:{}},textOverflow:{meta:{types:{string:1},name:"textOverflow",excludes:{},default:"ellipsis"},subtree:{}}}},itemWidth:{meta:{types:{number:1},name:"itemWidth",excludes:{},description:"The width for each legend item. By default the items are laid out\nsuccessively. In a [horizontal layout](legend.layout), if the items\nare laid out across two rows or more, they will be vertically aligned\ndepending on the [legend.alignColumns](legend.alignColumns) option."},subtree:{}},keyboardNavigation:{meta:{types:{object:1},name:"keyboardNavigation",excludes:{},description:"Keyboard navigation for the legend. Requires the Accessibility module."},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",description:"Enable/disable keyboard navigation for the legend. Requires the Accessibility\nmodule."},subtree:{}}}},labelFormat:{meta:{types:{string:1},name:"labelFormat",excludes:{},default:"{name}",description:"A [format string](https://www.highcharts.com/docs/chart-concepts/\nlabels-and-string-formatting) for each legend label. Available\nvariables relates to properties on the series, or the point in case\nof pies."},subtree:{}},labelFormatter:{meta:{types:{function:1},name:"labelFormatter",excludes:{},description:"Callback function to format each of the series' labels. The `this`\nkeyword refers to the series object, or the point object in case\nof pie charts. By default the series or point name is printed."},subtree:{}},layout:{meta:{types:{string:1},name:"layout",excludes:{},default:"horizontal"},subtree:{}},lineHeight:{meta:{types:{number:1},name:"lineHeight",excludes:{},default:"16",products:{highcharts:1},description:"Line height for the legend items. Deprecated as of 2.1\\. Instead,\nthe line height for each item can be set using itemStyle.lineHeight,\nand the padding between items using `itemMarginTop` and\n`itemMarginBottom`."},subtree:{}},margin:{meta:{types:{number:1},name:"margin",excludes:{},default:"12",description:"If the plot area sized is calculated automatically and the legend\nis not floating, the legend margin is the space between the legend\nand the axis labels or plot area."},subtree:{}},maxHeight:{meta:{types:{number:1},name:"maxHeight",excludes:{},description:"Maximum pixel height for the legend. When the maximum height is\nextended, navigation will show."},subtree:{}},navigation:{meta:{types:{"*":1},name:"navigation",excludes:{},description:"Options for the paging or navigation appearing when the legend\nis overflown. Navigation works well on screen, but not in static\nexported images. One way of working around that is to\n[increase the chart height in\nexport](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/legend/navigation-enabled-false/)."},subtree:{activeColor:{meta:{types:{"highcharts.colorstring":1},name:"activeColor",excludes:{},default:"#003399",description:"The color for the active up or down arrow in the legend page\nnavigation."},subtree:{}},animation:{meta:{types:{"highcharts.animationobject":1,boolean:1},name:"animation",excludes:{},default:"true",description:"How to animate the pages when navigating up or down. A value of\n`true` applies the default navigation given in the\n`chart.animation` option. Additional options can be given as an\nobject containing values for easing and duration."},subtree:{}},arrowSize:{meta:{types:{number:1},name:"arrowSize",excludes:{},default:"12",description:"The pixel size of the up and down arrows in the legend paging\nnavigation."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",description:"Whether to enable the legend navigation. In most cases, disabling\nthe navigation results in an unwanted overflow.\n\nSee also the [adapt chart to legend](\nhttps://www.highcharts.com/products/plugin-registry/single/8/Adapt-Chart-To-Legend)\nplugin for a solution to extend the chart height to make room for\nthe legend, optionally in exported charts only."},subtree:{}},inactiveColor:{meta:{types:{"highcharts.colorstring":1},name:"inactiveColor",excludes:{},default:"#cccccc",description:"The color of the inactive up or down arrow in the legend page\nnavigation. ."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},description:"Text styles for the legend page navigation."},subtree:{}}}},padding:{meta:{types:{number:1},name:"padding",excludes:{},default:"8",description:"The inner padding of the legend box."},subtree:{}},reversed:{meta:{types:{boolean:1},name:"reversed",excludes:{},default:"false",description:"Whether to reverse the order of the legend items compared to the\norder of the series or points as defined in the configuration object."},subtree:{}},rtl:{meta:{types:{boolean:1},name:"rtl",excludes:{},default:"false",description:"Whether to show the symbol on the right side of the text rather than\nthe left side. This is common in Arabic and Hebraic."},subtree:{}},shadow:{meta:{types:{"highcharts.cssobject":1,boolean:1},name:"shadow",excludes:{},default:"false",description:"Whether to apply a drop shadow to the legend. A `backgroundColor`\nalso needs to be applied for this to take effect. The shadow can be\nan object configuration containing `color`, `offsetX`, `offsetY`,\n`opacity` and `width`."},subtree:{}},squareSymbol:{meta:{types:{boolean:1},name:"squareSymbol",excludes:{},default:"true",description:"When this is true, the legend symbol width will be the same as\nthe symbol height, which in turn defaults to the font size of the\nlegend items."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},products:{highcharts:1,highstock:1},description:"CSS styles for the legend area. In the 1.x versions the position\nof the legend area was determined by CSS. In 2.x, the position is\ndetermined by properties like `align`, `verticalAlign`, `x` and `y`,\nbut the styles are still parsed for backwards compatibility."},subtree:{}},symbolHeight:{meta:{types:{number:1},name:"symbolHeight",excludes:{},description:"The pixel height of the symbol for series types that use a rectangle\nin the legend. Defaults to the font size of legend items."},subtree:{}},symbolPadding:{meta:{types:{number:1},name:"symbolPadding",excludes:{},default:"5",description:"The pixel padding between the legend item symbol and the legend\nitem text."},subtree:{}},symbolRadius:{meta:{types:{number:1},name:"symbolRadius",excludes:{},description:"The border radius of the symbol for series types that use a rectangle\nin the legend. Defaults to half the `symbolHeight`."},subtree:{}},symbolWidth:{meta:{types:{number:1},name:"symbolWidth",excludes:{},description:"The pixel width of the legend item symbol. When the `squareSymbol`\noption is set, this defaults to the `symbolHeight`, otherwise 16."},subtree:{}},title:{meta:{types:{"*":1},name:"title",excludes:{},description:"A title to be added on top of the legend."},subtree:{style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},default:'{"fontWeight":"bold"}',description:"Generic CSS styles for the legend title."},subtree:{fontWeight:{meta:{types:{string:1},name:"fontWeight",excludes:{},default:"bold"},subtree:{}}}},text:{meta:{types:{string:1},name:"text",excludes:{},description:"A text or HTML string for the title."},subtree:{}}}},useHTML:{meta:{types:{boolean:1},name:"useHTML",excludes:{},default:"false",description:"Whether to [use HTML](https://www.highcharts.com/docs/chart-concepts/\nlabels-and-string-formatting#html) to render the legend item texts.\n\nPrior to 4.1.7, when using HTML, [legend.navigation](\n#legend.navigation) was disabled."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"bottom",description:"The vertical alignment of the legend box. Can be one of `top`,\n`middle` or `bottom`. Vertical position can be further determined\nby the `y` option.\n\nIn the case that the legend is aligned in a corner position, the\n`layout` option will determine whether to place it above/below\nor on the side of the plot area.\n\nWhen the [layout](#legend.layout) option is `proximate`, the\n`verticalAlign` option doesn't apply."},subtree:{}},width:{meta:{types:{number:1},name:"width",excludes:{},description:"The width of the legend box."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"0",description:"The x offset of the legend relative to its horizontal alignment\n`align` within chart.spacingLeft and chart.spacingRight. Negative\nx moves it to the left, positive x moves it to the right."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:"0",description:"The vertical offset of the legend relative to it's vertical alignment\n`verticalAlign` within chart.spacingTop and chart.spacingBottom.\n Negative y moves it up, positive y moves it down."},subtree:{}}}},loading:{meta:{types:{"*":1},name:"loading",excludes:{},description:'The loading options control the appearance of the loading screen\nthat covers the plot area on chart operations. This screen only\nappears after an explicit call to `chart.showLoading()`. It is a\nutility for developers to communicate to the end user that something\nis going on, for example while retrieving new data via an XHR connection.\nThe "Loading..." text itself is not part of this configuration\nobject, but part of the `lang` object.'},subtree:{hideDuration:{meta:{types:{number:1},name:"hideDuration",excludes:{},default:"100",description:"The duration in milliseconds of the fade out effect."},subtree:{}},labelStyle:{meta:{types:{"highcharts.cssobject":1},name:"labelStyle",excludes:{},default:'{"fontWeight": "bold", "position": "relative", "top": "45%"}',description:"CSS styles for the loading label `span`."},subtree:{fontWeight:{meta:{types:{string:1},name:"fontWeight",excludes:{},default:"bold"},subtree:{}},position:{meta:{types:{string:1},name:"position",excludes:{},default:"relative"},subtree:{}},top:{meta:{types:{string:1},name:"top",excludes:{},default:"45%"},subtree:{}}}},showDuration:{meta:{types:{number:1},name:"showDuration",excludes:{},default:"100",description:"The duration in milliseconds of the fade in effect."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},default:'{"position": "absolute", "backgroundColor": "#ffffff", "opacity": 0.5, "textAlign": "center"}',description:"CSS styles for the loading screen that covers the plot area.\n\nIn styled mode, the loading label is styled with the\n`.highcharts-loading` class."},subtree:{backgroundColor:{meta:{types:{string:1},name:"backgroundColor",excludes:{},default:"#ffffff"},subtree:{}},opacity:{meta:{types:{number:1},name:"opacity",excludes:{},default:.5},subtree:{}},position:{meta:{types:{string:1},name:"position",excludes:{},default:"absolute"},subtree:{}},textAlign:{meta:{types:{string:1},name:"textAlign",excludes:{},default:"center"},subtree:{}}}}}},mapNavigation:{meta:{types:{object:1},name:"mapNavigation",excludes:{},products:{highmaps:1}},subtree:{buttonOptions:{meta:{types:{"*":1},name:"buttonOptions",excludes:{},products:{highmaps:1},description:"General options for the map navigation buttons. Individual options\ncan be given from the [mapNavigation.buttons](#mapNavigation.buttons)\noption set."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"left",products:{highmaps:1},description:"The alignment of the navigation buttons."},subtree:{}},alignTo:{meta:{types:{string:1},name:"alignTo",excludes:{},default:"plotBox",products:{highmaps:1},description:"What box to align the buttons to. Possible values are `plotBox`\nand `spacingBox`."},subtree:{}},height:{meta:{types:{number:1},name:"height",excludes:{},default:"18",products:{highmaps:1},description:"The pixel height of the map navigation buttons."},subtree:{}},padding:{meta:{types:{number:1},name:"padding",excludes:{},default:"5",products:{highmaps:1},description:"Padding for the navigation buttons."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},products:{highmaps:1},description:"Text styles for the map navigation buttons. Defaults to\n\n
    {\n    fontSize: '15px',\n    fontWeight: 'bold',\n    textAlign: 'center'\n}
    "},subtree:{fontSize:{meta:{types:{string:1},name:"fontSize",excludes:{},default:"15px"},subtree:{}},fontWeight:{meta:{types:{string:1},name:"fontWeight",excludes:{},default:"bold"},subtree:{}}}},theme:{meta:{types:{"*":1},name:"theme",excludes:{},products:{highmaps:1},description:"A configuration object for the button theme. The object accepts\nSVG properties like `stroke-width`, `stroke` and `fill`. Tri-state\nbutton styles are supported by the `states.hover` and `states.select`\nobjects."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"bottom",products:{highmaps:1},description:"The vertical alignment of the buttons. Individual alignment can\nbe adjusted by each button's `y` offset."},subtree:{}},width:{meta:{types:{number:1},name:"width",excludes:{},default:"18",products:{highmaps:1},description:"The width of the map navigation buttons."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"0",products:{highmaps:1},description:"The X offset of the buttons relative to its `align` setting."},subtree:{}}}},buttons:{meta:{types:{object:1},name:"buttons",excludes:{}},subtree:{zoomIn:{meta:{types:{object:1},name:"zoomIn",excludes:{}},subtree:{onclick:{meta:{types:{function:1},name:"onclick",excludes:{},products:{highmaps:1},description:"Click handler for the button. Defaults to:\n\n
    function () {\nthis.mapZoom(0.5);\n}
    "},subtree:{}},text:{meta:{types:{string:1},name:"text",excludes:{},default:"+",products:{highmaps:1},description:"The text for the button. The tooltip (title) is a language option\ngiven by [lang.zoomIn](#lang.zoomIn)."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:"0",products:{highmaps:1},description:"The position of the zoomIn button relative to the vertical\nalignment."},subtree:{}}}},zoomOut:{meta:{types:{object:1},name:"zoomOut",excludes:{}},subtree:{onclick:{meta:{types:{function:1},name:"onclick",excludes:{},products:{highmaps:1},description:"Click handler for the button. Defaults to:\n\n
    function () {\n    this.mapZoom(2);\n}
    "},subtree:{}},text:{meta:{types:{string:1},name:"text",excludes:{},default:"-",products:{highmaps:1},description:"The text for the button. The tooltip (title) is a language option\ngiven by [lang.zoomOut](#lang.zoomIn)."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:"28",products:{highmaps:1},description:"The position of the zoomOut button relative to the vertical\nalignment."},subtree:{}}}}}},enableButtons:{meta:{types:{boolean:1},name:"enableButtons",excludes:{},products:{highmaps:1},description:"Whether to enable navigation buttons. By default it inherits the\n[enabled](#mapNavigation.enabled) setting."},subtree:{}},enableDoubleClickZoom:{meta:{types:{boolean:1},name:"enableDoubleClickZoom",excludes:{},products:{highmaps:1},description:"Enables zooming in on an area on double clicking in the map. By default\nit inherits the [enabled](#mapNavigation.enabled) setting."},subtree:{}},enableDoubleClickZoomTo:{meta:{types:{boolean:1},name:"enableDoubleClickZoomTo",excludes:{},default:"false",products:{highmaps:1},description:"Whether to zoom in on an area when that area is double clicked."},subtree:{}},enableMouseWheelZoom:{meta:{types:{boolean:1},name:"enableMouseWheelZoom",excludes:{},products:{highmaps:1},description:"Enables zooming by mouse wheel. By default it inherits the [enabled](\n#mapNavigation.enabled) setting."},subtree:{}},enableTouchZoom:{meta:{types:{boolean:1},name:"enableTouchZoom",excludes:{},products:{highmaps:1},description:"Whether to enable multitouch zooming. Note that if the chart covers the\nviewport, this prevents the user from using multitouch and touchdrag on\nthe web page, so you should make sure the user is not trapped inside the\nchart. By default it inherits the [enabled](#mapNavigation.enabled)\nsetting."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"false",products:{highmaps:1},description:"Whether to enable map navigation. The default is not to enable\nnavigation, as many choropleth maps are simple and don't need it.\nAdditionally, when touch zoom and mousewheel zoom is enabled, it breaks\nthe default behaviour of these interactions in the website, and the\nimplementer should be aware of this.\n\nIndividual interactions can be enabled separately, namely buttons,\nmultitouch zoom, double click zoom, double click zoom to element and\nmousewheel zoom." },subtree:{}},mouseWheelSensitivity:{meta:{types:{number:1},name:"mouseWheelSensitivity",excludes:{},default:"1.1",products:{highmaps:1},description:"Sensitivity of mouse wheel or trackpad scrolling. 1 is no sensitivity,\nwhile with 2, one mousewheel delta will zoom in 50%."},subtree:{}}}},navigation:{meta:{types:{object:1},name:"navigation",excludes:{},description:"A collection of options for buttons and menus appearing in the exporting\nmodule."},subtree:{buttonOptions:{meta:{types:{object:1},name:"buttonOptions",excludes:{},description:"A collection of options for buttons appearing in the exporting module.\n\n\nIn styled mode, the buttons are styled with the\n`.highcharts-contextbutton` and `.highcharts-button-symbol` classes."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"right",description:"Alignment for the buttons."},subtree:{}},buttonSpacing:{meta:{types:{number:1},name:"buttonSpacing",excludes:{},default:"3",description:"The pixel spacing between buttons."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",description:"Whether to enable buttons."},subtree:{}},height:{meta:{types:{number:1},name:"height",excludes:{},default:"22",description:"Pixel height of the buttons."},subtree:{}},symbolFill:{meta:{types:{color:1},name:"symbolFill",excludes:{},default:"#666666",description:"Fill color for the symbol within the button."},subtree:{}},symbolSize:{meta:{types:{number:1},name:"symbolSize",excludes:{},default:"14",description:"The pixel size of the symbol on the button."},subtree:{}},symbolStroke:{meta:{types:{color:1},name:"symbolStroke",excludes:{},default:"#666666",description:"The color of the symbol's stroke or line."},subtree:{}},symbolStrokeWidth:{meta:{types:{number:1},name:"symbolStrokeWidth",excludes:{},default:"1",description:"The pixel stroke width of the symbol on the button."},subtree:{}},symbolX:{meta:{types:{number:1},name:"symbolX",excludes:{},default:"12.5",description:"The x position of the center of the symbol inside the button."},subtree:{}},symbolY:{meta:{types:{number:1},name:"symbolY",excludes:{},default:"10.5",description:"The y position of the center of the symbol inside the button."},subtree:{}},text:{meta:{types:{string:1},name:"text",excludes:{},default:"null",description:"A text string to add to the individual button."},subtree:{}},theme:{meta:{types:{object:1},name:"theme",excludes:{},description:"A configuration object for the button theme. The object accepts\nSVG properties like `stroke-width`, `stroke` and `fill`. Tri-state\nbutton styles are supported by the `states.hover` and `states.select`\nobjects."},subtree:{fill:{meta:{types:{string:1},name:"fill",excludes:{},default:"#ffffff",description:"The default fill exists only to capture hover events."},subtree:{}},padding:{meta:{types:{number:1},name:"padding",excludes:{},default:"5"},subtree:{}},stroke:{meta:{types:{string:1},name:"stroke",excludes:{},default:"none"},subtree:{}}}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"top",description:'The vertical alignment of the buttons. Can be one of "top", "middle"\nor "bottom".'},subtree:{}},width:{meta:{types:{number:1},name:"width",excludes:{},default:"24",description:"The pixel width of the button."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:"0",description:"The vertical offset of the button's position relative to its\n`verticalAlign`."},subtree:{}}}},menuItemHoverStyle:{meta:{types:{cssobject:1},name:"menuItemHoverStyle",excludes:{},default:'{ "background": "#335cad", "color": "#ffffff" }',description:"CSS styles for the hover state of the individual items within the\npopup menu appearing by default when the export icon is clicked.\n The menu items are rendered in HTML."},subtree:{background:{meta:{types:{string:1},name:"background",excludes:{},default:"#335cad"},subtree:{}},color:{meta:{types:{string:1},name:"color",excludes:{},default:"#ffffff"},subtree:{}}}},menuItemStyle:{meta:{types:{cssobject:1},name:"menuItemStyle",excludes:{},default:'{ "padding": "0.5em 1em", "color": "#333333", "background": "none" }',description:"CSS styles for the individual items within the popup menu appearing\nby default when the export icon is clicked. The menu items are rendered\nin HTML."},subtree:{background:{meta:{types:{string:1},name:"background",excludes:{},default:"none"},subtree:{}},color:{meta:{types:{string:1},name:"color",excludes:{},default:"#333333"},subtree:{}},fontSize:{meta:{types:{string:1},name:"fontSize",excludes:{},description:"Defaults to `14px` on touch devices and `11px` on desktop."},subtree:{}},padding:{meta:{types:{string:1},name:"padding",excludes:{},default:"0.5em 1em"},subtree:{}},transition:{meta:{types:{string:1},name:"transition",excludes:{},default:"background 250ms, color 250ms"},subtree:{}}}},menuStyle:{meta:{types:{cssobject:1},name:"menuStyle",excludes:{},default:'{ "border": "1px solid #999999", "background": "#ffffff", "padding": "5px 0" }',description:"CSS styles for the popup menu appearing by default when the export\nicon is clicked. This menu is rendered in HTML."},subtree:{background:{meta:{types:{string:1},name:"background",excludes:{},default:"#ffffff"},subtree:{}},border:{meta:{types:{string:1},name:"border",excludes:{},default:"1px solid #999999"},subtree:{}},padding:{meta:{types:{string:1},name:"padding",excludes:{},default:"5px 0"},subtree:{}}}}}},navigator:{meta:{types:{object:1},name:"navigator",excludes:{},products:{highstock:1},description:"The navigator is a small series below the main series, displaying\na view of the entire data set. It provides tools to zoom in and\nout on parts of the data as well as panning across the dataset."},subtree:{adaptToUpdatedData:{meta:{types:{boolean:1},name:"adaptToUpdatedData",excludes:{},default:"true",products:{highstock:1},description:"Whether the navigator and scrollbar should adapt to updated data\nin the base X axis. When loading data async, as in the demo below,\nthis should be `false`. Otherwise new data will trigger navigator\nredraw, which will cause unwanted looping. In the demo below, the\ndata in the navigator is set only once. On navigating, only the main\nchart content is updated."},subtree:{}},baseSeries:{meta:{types:{"*":1},name:"baseSeries",excludes:{},default:"0",products:{highstock:1},description:"An integer identifying the index to use for the base series, or a\nstring representing the id of the series.\n\n**Note**: As of Highcharts 5.0, this is now a deprecated option.\nPrefer [series.showInNavigator](#plotOptions.series.showInNavigator)."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",products:{highstock:1},description:"Enable or disable the navigator."},subtree:{}},handles:{meta:{types:{"*":1},name:"handles",excludes:{},products:{highstock:1},description:"Options for the handles for dragging the zoomed area."},subtree:{backgroundColor:{meta:{types:{"highcharts.colorstring":1},name:"backgroundColor",excludes:{},default:"#f2f2f2",products:{highstock:1},description:"The fill for the handle."},subtree:{}},borderColor:{meta:{types:{"highcharts.colorstring":1},name:"borderColor",excludes:{},default:"#999999",products:{highstock:1},description:"The stroke for the handle border and the stripes inside."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",products:{highstock:1},description:"Allows to enable/disable handles."},subtree:{}},height:{meta:{types:{number:1},name:"height",excludes:{},default:"15",products:{highstock:1},description:"Height for handles."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:"7",products:{highstock:1},description:"The width for the handle border and the stripes inside."},subtree:{}},symbols:{meta:{types:{array:"string"},name:"symbols",excludes:{},default:"['navigator-handle', 'navigator-handle']",products:{highstock:1},description:"Array to define shapes of handles. 0-index for left, 1-index for\nright.\n\nAdditionally, the URL to a graphic can be given on this form:\n`url(graphic.png)`. Note that for the image to be applied to\nexported charts, its URL needs to be accessible by the export\nserver.\n\nCustom callbacks for symbol path generation can also be added to\n`Highcharts.SVGRenderer.prototype.symbols`. The callback is then\nused by its method name, as shown in the demo."},subtree:{}},width:{meta:{types:{number:1},name:"width",excludes:{},default:"7",products:{highstock:1},description:"Width for handles."},subtree:{}}}},height:{meta:{types:{number:1},name:"height",excludes:{},default:"40",products:{highstock:1},description:"The height of the navigator."},subtree:{}},margin:{meta:{types:{number:1},name:"margin",excludes:{},default:"25",products:{highstock:1},description:"The distance from the nearest element, the X axis or X axis labels."},subtree:{}},maskFill:{meta:{types:{"highcharts.colorstring":1},name:"maskFill",excludes:{},default:"rgba(102,133,194,0.3)",products:{highstock:1},description:"The color of the mask covering the areas of the navigator series\nthat are currently not visible in the main series. The default\ncolor is bluish with an opacity of 0.3 to see the series below."},subtree:{}},maskInside:{meta:{types:{boolean:1},name:"maskInside",excludes:{},default:"true",products:{highstock:1},description:"Whether the mask should be inside the range marking the zoomed\nrange, or outside. In Highstock 1.x it was always `false`."},subtree:{}},opposite:{meta:{types:{boolean:1},name:"opposite",excludes:{},default:"false",products:{highstock:1},description:"When the chart is inverted, whether to draw the navigator on the\nopposite side."},subtree:{}},outlineColor:{meta:{types:{"highcharts.colorstring":1},name:"outlineColor",excludes:{},default:"#cccccc",products:{highstock:1},description:"The color of the line marking the currently zoomed area in the\nnavigator."},subtree:{}},outlineWidth:{meta:{types:{number:1},name:"outlineWidth",excludes:{},default:"2",products:{highstock:1},description:"The width of the line marking the currently zoomed area in the\nnavigator."},subtree:{}},series:{meta:{types:{"*":1},name:"series",excludes:{},products:{highstock:1},description:"Options for the navigator series. Available options are the same\nas any series, documented at [plotOptions](#plotOptions.series)\nand [series](#series).\n\nUnless data is explicitly defined on navigator.series, the data\nis borrowed from the first series in the chart.\n\nDefault series options for the navigator series are:\n\n
    series: {\n    type: 'areaspline',\n    fillOpacity: 0.05,\n    dataGrouping: {\n        smoothed: true\n    },\n    lineWidth: 1,\n    marker: {\n        enabled: false\n    }\n}
    "},subtree:{className:{meta:{types:{string:1},name:"className",excludes:{},default:"highcharts-navigator-series"},subtree:{}},dataGrouping:{meta:{types:{"*":1},name:"dataGrouping",excludes:{},description:"Data grouping options for the navigator series.",extends:"plotOptions.series.dataGrouping"},subtree:{approximation:{meta:{types:{string:1},name:"approximation",excludes:{},default:"average"},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0},subtree:{}},groupPixelWidth:{meta:{types:{number:1},name:"groupPixelWidth",excludes:{},default:2},subtree:{}},smoothed:{meta:{types:{boolean:1},name:"smoothed",excludes:{},default:!0},subtree:{}},units:{meta:{types:{},name:"units",excludes:{}},subtree:{}}}},dataLabels:{meta:{types:{object:1,"*":1},name:"dataLabels",excludes:{},description:"Data label options for the navigator series. Data labels are\ndisabled by default on the navigator series.",extends:"plotOptions.series.dataLabels"},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1},subtree:{}},zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},default:2},subtree:{}}}},fillOpacity:{meta:{types:{number:1},name:"fillOpacity",excludes:{},default:"0.05",description:"The fill opacity of the navigator series."},subtree:{}},id:{meta:{types:{string:1},name:"id",excludes:{},default:"highcharts-navigator-series"},subtree:{}},lineColor:{meta:{types:{"highcharts.colorstring":1,null:1},name:"lineColor",excludes:{},default:"null",description:"Line color for the navigator series. Allows setting the color\nwhile disallowing the default candlestick setting."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:"1",description:"The pixel line width of the navigator series."},subtree:{}},marker:{meta:{types:{object:1},name:"marker",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1},subtree:{}}}},pointRange:{meta:{types:{number:1},name:"pointRange",excludes:{},default:0},subtree:{}},threshold:{meta:{types:{null:1,number:1},name:"threshold",excludes:{},default:"null",description:"The threshold option. Setting it to 0 will make the default\nnavigator area series draw its area from the 0 value and up."},subtree:{}},type:{meta:{types:{string:1},name:"type",excludes:{},default:"areaspline",description:"The type of the navigator series. Defaults to `areaspline` if\ndefined, otherwise `line`."},subtree:{}}}},xAxis:{meta:{types:{"*":1},name:"xAxis",excludes:{},products:{highstock:1},description:"Options for the navigator X axis. Default series options\nfor the navigator xAxis are:\n\n
    xAxis: {\n    tickWidth: 0,\n    lineWidth: 0,\n    gridLineWidth: 1,\n    tickPixelInterval: 200,\n    labels: {\n           align: 'left',\n        style: {\n            color: '#888'\n        },\n        x: 3,\n        y: -4\n    }\n}
    ",extends:"xAxis"},subtree:{className:{meta:{types:{string:1},name:"className",excludes:{},default:"highcharts-navigator-xaxis"},subtree:{}},crosshair:{meta:{types:{boolean:1},name:"crosshair",excludes:{},default:!1},subtree:{}},gridLineColor:{meta:{types:{string:1},name:"gridLineColor",excludes:{},default:"#e6e6e6"},subtree:{}},gridLineWidth:{meta:{types:{number:1},name:"gridLineWidth",excludes:{},default:1},subtree:{}},labels:{meta:{types:{object:1},name:"labels",excludes:{}},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"left"},subtree:{}},style:{meta:{types:{object:1},name:"style",excludes:{}},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#999999"},subtree:{}}}},x:{meta:{types:{number:1},name:"x",excludes:{},default:3},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:-4},subtree:{}}}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:0},subtree:{}},overscroll:{meta:{types:{number:1},name:"overscroll",excludes:{},default:"0",products:{highstock:1},description:"Additional range on the right side of the xAxis. Works similar to\nxAxis.maxPadding, but value is set in milliseconds.\nCan be set for both, main xAxis and navigator's xAxis."},subtree:{}},tickLength:{meta:{types:{number:1},name:"tickLength",excludes:{},default:0},subtree:{}},tickPixelInterval:{meta:{types:{number:1},name:"tickPixelInterval",excludes:{},default:200},subtree:{}}}},yAxis:{meta:{types:{"*":1},name:"yAxis",excludes:{},products:{highstock:1},description:"Options for the navigator Y axis. Default series options\nfor the navigator yAxis are:\n\n
    yAxis: {\n    gridLineWidth: 0,\n    startOnTick: false,\n    endOnTick: false,\n    minPadding: 0.1,\n    maxPadding: 0.1,\n    labels: {\n        enabled: false\n    },\n    title: {\n        text: null\n    },\n    tickWidth: 0\n}
    ",extends:"yAxis"},subtree:{className:{meta:{types:{string:1},name:"className",excludes:{},default:"highcharts-navigator-yaxis"},subtree:{}},crosshair:{meta:{types:{boolean:1},name:"crosshair",excludes:{},default:!1},subtree:{}},endOnTick:{meta:{types:{boolean:1},name:"endOnTick",excludes:{},default:!1},subtree:{}},gridLineWidth:{meta:{types:{number:1},name:"gridLineWidth",excludes:{},default:0},subtree:{}},labels:{meta:{types:{object:1},name:"labels",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1},subtree:{}}}},maxPadding:{meta:{types:{number:1},name:"maxPadding",excludes:{},default:.1},subtree:{}},minPadding:{meta:{types:{number:1},name:"minPadding",excludes:{},default:.1},subtree:{}},startOnTick:{meta:{types:{boolean:1},name:"startOnTick",excludes:{},default:!1},subtree:{}},tickLength:{meta:{types:{number:1},name:"tickLength",excludes:{},default:0},subtree:{}},tickWidth:{meta:{types:{number:1},name:"tickWidth",excludes:{},default:0},subtree:{}},title:{meta:{types:{object:1},name:"title",excludes:{}},subtree:{text:{meta:{types:{object:1},name:"text",excludes:{},default:null},subtree:{}}}}}}}},noData:{meta:{types:{object:1},name:"noData",excludes:{},description:'Options for displaying a message like "No data to display".\nThis feature requires the file no-data-to-display.js to be loaded in the\npage. The actual text to display is set in the lang.noData option.'},subtree:{attr:{meta:{types:{object:1},name:"attr",excludes:{},products:{highcharts:1,highstock:1},description:"An object of additional SVG attributes for the no-data label."},subtree:{}},position:{meta:{types:{object:1},name:"position",excludes:{},default:'{ "x": 0, "y": 0, "align": "center", "verticalAlign": "middle" }',description:"The position of the no-data label, relative to the plot area."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"center",description:"Horizontal alignment of the label."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"middle",products:{highcharts:1,highstock:1},description:"Vertical alignment of the label."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"0",products:{highcharts:1,highstock:1},description:"Horizontal offset of the label, in pixels."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:"0",products:{highcharts:1,highstock:1},description:"Vertical offset of the label, in pixels."},subtree:{}}}},style:{meta:{types:{object:1},name:"style",excludes:{},description:"CSS styles for the no-data label."},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#666666"},subtree:{}},fontSize:{meta:{types:{string:1},name:"fontSize",excludes:{},default:"12px"},subtree:{}},fontWeight:{meta:{types:{string:1},name:"fontWeight",excludes:{},default:"bold"},subtree:{}}}},useHTML:{meta:{types:{boolean:1},name:"useHTML",excludes:{},default:"false",products:{highcharts:1,highstock:1},description:"Whether to insert the label as HTML, or as pseudo-HTML rendered with\nSVG."},subtree:{}}}},pane:{meta:{types:{object:1},name:"pane",excludes:{},description:"The pane serves as a container for axes and backgrounds for circular\ngauges and polar charts."},subtree:{background:{meta:{types:{array:"Object"},name:"background",excludes:{},description:"An array of background items for the pane."},subtree:{backgroundColor:{meta:{types:{color:1},name:"backgroundColor",excludes:{},products:{highcharts:1},description:"The background color or gradient for the pane."},subtree:{linearGradient:{meta:{types:{object:1},name:"linearGradient",excludes:{},description:"Definition of the gradient, similar to SVG: object literal holds\nstart position (x1, y1) and the end position (x2, y2) relative\nto the shape, where 0 means top/left and 1 is bottom/right.\nAll positions are floats between 0 and 1."},subtree:{x1:{meta:{types:{number:1},name:"x1",excludes:{},default:0},subtree:{}},x2:{meta:{types:{number:1},name:"x2",excludes:{},default:0},subtree:{}},y1:{meta:{types:{number:1},name:"y1",excludes:{},default:0},subtree:{}},y2:{meta:{types:{number:1},name:"y2",excludes:{},default:1},subtree:{}}}},stops:{meta:{types:{array:"Array"},name:"stops",excludes:{},default:"[[0, #ffffff], [1, #e6e6e6]]",description:"The stops is an array of tuples, where the first item is a float\nbetween 0 and 1 assigning the relative position in the gradient,\nand the second item is the color."},subtree:{}}}},borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},default:"#cccccc",products:{highcharts:1},description:"The pane background border color."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:"1",products:{highcharts:1},description:"The pixel border width of the pane background."},subtree:{}},className:{meta:{types:{string:1},name:"className",excludes:{},description:"The class name for this background."},subtree:{}},innerRadius:{meta:{types:{number:1,string:1},name:"innerRadius",excludes:{},default:"0",products:{highcharts:1},description:"The inner radius of the pane background. Can be either numeric\n(pixels) or a percentage string."},subtree:{}},outerRadius:{meta:{types:{number:1,string:1},name:"outerRadius",excludes:{},default:"105%",products:{highcharts:1},description:"The outer radius of the circular pane background. Can be either\nnumeric (pixels) or a percentage string."},subtree:{}},shape:{meta:{types:{string:1},name:"shape",excludes:{},default:"solid",products:{highcharts:1},description:"The shape of the pane background. When `solid`, the background\nis circular. When `arc`, the background extends only from the min\nto the max of the value axis."},subtree:{}}}},center:{meta:{types:{array:"(String|Number)"},name:"center",excludes:{},default:'["50%", "50%"]',products:{highcharts:1},description:"The center of a polar chart or angular gauge, given as an array\nof [x, y] positions. Positions can be given as integers that\ntransform to pixels, or as percentages of the plot area size."},subtree:{}},endAngle:{meta:{types:{number:1},name:"endAngle",excludes:{},products:{highcharts:1},description:"The end angle of the polar X axis or gauge value axis, given in\ndegrees where 0 is north. Defaults to [startAngle](#pane.startAngle)\n+ 360."},subtree:{}},size:{meta:{types:{number:1,string:1},name:"size",excludes:{},default:"85%",products:{highcharts:1},description:"The size of the pane, either as a number defining pixels, or a\npercentage defining a percentage of the plot are."},subtree:{}},startAngle:{meta:{types:{number:1},name:"startAngle",excludes:{},default:0,products:{highcharts:1},description:"The start angle of the polar X axis or gauge axis, given in degrees\nwhere 0 is north. Defaults to 0."},subtree:{}}}},plotOptions:{meta:{types:{"*":1},name:"plotOptions",excludes:{},description:"The plotOptions is a wrapper object for config objects for each series\ntype. The config objects for each series can also be overridden for\neach series item as given in the series array.\n\nConfiguration options for the series are given in three levels. Options\nfor all series in a chart are given in the [plotOptions.series](\n#plotOptions.series) object. Then options for all series of a specific\ntype are given in the plotOptions of that type, for example\n`plotOptions.line`. Next, options for one single series are given in\n[the series array](#series)."},subtree:{ad:{meta:{types:{object:1},name:"ad",excludes:{},products:{highstock:1},description:"Accumulation Distribution (AD). This series requires `linkedTo` option to\nbe set.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `ad` series are defined in\n [plotOptions.ad](plotOptions.ad).\n3. Options for one single series are given in\n [the series instance array](series.ad).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        ad: {\n            // shared options for all ad series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'ad'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{volumeSeriesID:{meta:{types:{string:1},name:"volumeSeriesID",excludes:{},default:"volume",products:{highstock:1},description:"The id of volume series which is mandatory.\nFor example using OHLC data, volumeSeriesID='volume' means\nthe indicator will be calculated using OHLC and volume values."},subtree:{}}}}}},area:{meta:{types:{"*":1},name:"area",excludes:{},products:{highcharts:1,highstock:1},description:"The area series type.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `area` series are defined in\n [plotOptions.area](plotOptions.area).\n3. Options for one single series are given in\n [the series instance array](series.area).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        area: {\n            // shared options for all area series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'area'\n    }]\n});\n
    \n ",extends:"plotOptions.line"},subtree:{fillColor:{meta:{types:{"highcharts.colorstring":1},name:"fillColor",excludes:{},products:{highcharts:1,highstock:1},description:"Fill color or gradient for the area. When `null`, the series' `color`\nis used with the series' `fillOpacity`.\n\nIn styled mode, the fill color can be set with the `.highcharts-area`\nclass name."},subtree:{}},fillOpacity:{meta:{types:{number:1},name:"fillOpacity",excludes:{},products:{highcharts:1,highstock:1},description:"Fill opacity for the area. When you set an explicit `fillColor`,\nthe `fillOpacity` is not applied. Instead, you should define the\nopacity in the `fillColor` with an rgba color definition. The\n`fillOpacity` setting, also the default setting, overrides the alpha\ncomponent of the `color` setting.\n\nIn styled mode, the fill opacity can be set with the `.highcharts-area`\nclass name."},subtree:{}},lineColor:{meta:{types:{"highcharts.colorstring":1},name:"lineColor",excludes:{},products:{highcharts:1,highstock:1},description:"A separate color for the graph line. By default the line takes the\n`color` of the series, but the lineColor setting allows setting a\nseparate color for the line without altering the `fillColor`.\n\nIn styled mode, the line stroke can be set with the `.highcharts-graph`\nclass name."},subtree:{}},negativeFillColor:{meta:{types:{"highcharts.colorstring":1},name:"negativeFillColor",excludes:{},products:{highcharts:1},description:"A separate color for the negative part of the area.\n\nIn styled mode, a negative color is set with the `.highcharts-negative`\nclass name."},subtree:{}},softThreshold:{meta:{types:{boolean:1},name:"softThreshold",excludes:{},products:{highcharts:1,highstock:1},description:"When this is true, the series will not cause the Y axis to cross\nthe zero plane (or [threshold](#plotOptions.series.threshold) option)\nunless the data actually crosses the plane.\n\nFor example, if `softThreshold` is `false`, a series of 0, 1, 2,\n3 will make the Y axis show negative values according to the `minPadding`\noption. If `softThreshold` is `true`, the Y axis starts at 0."},subtree:{}},threshold:{meta:{types:{number:1},name:"threshold",excludes:{},products:{highcharts:1,highstock:1},description:"The Y axis value to serve as the base for the area, for distinguishing\nbetween values above and below a threshold. The area between the graph\nand the threshold is filled.\n\n* If a number is given, the Y axis will scale to the threshold.\n* If `null`, the scaling behaves like a line series with fill between the\n graph and the Y axis minimum.\n* If `Infinity` or `-Infinity`, the area between the graph and the\n corresponing Y axis extreme is filled (since v6.1.0)."},subtree:{}},trackByArea:{meta:{types:{boolean:1},name:"trackByArea",excludes:{},default:"false",products:{highcharts:1,highstock:1},description:"Whether the whole area or just the line should respond to mouseover\ntooltips and other mouse or touch events."},subtree:{}}}},arearange:{meta:{types:{object:1},name:"arearange",excludes:{},products:{highcharts:1,highstock:1},description:"The area range series is a carteseian series with higher and lower values\nfor each point along an X axis, where the area between the values is shaded.\nRequires `highcharts-more.js`.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `arearange` series are defined in\n [plotOptions.arearange](plotOptions.arearange).\n3. Options for one single series are given in\n [the series instance array](series.arearange).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        arearange: {\n            // shared options for all arearange series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'arearange'\n    }]\n});\n
    \n ",extends:"plotOptions.area"},subtree:{dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{},products:{highcharts:1,highstock:1},description:"Extended data labels for range series types. Range series data labels\nhave no `x` and `y` options. Instead, they have `xLow`, `xHigh`,\n`yLow` and `yHigh` options to allow the higher and lower data label\nsets individually.",extends:"plotOptions.series.dataLabels"},subtree:{align:{meta:{types:{object:1},name:"align",excludes:{},default:null},subtree:{}},verticalAlign:{meta:{types:{object:1},name:"verticalAlign",excludes:{},default:null},subtree:{}},xHigh:{meta:{types:{number:1},name:"xHigh",excludes:{},default:0,products:{highcharts:1,highstock:1},description:"X offset of the higher data labels relative to the point value."},subtree:{}},xLow:{meta:{types:{number:1},name:"xLow",excludes:{},default:0,products:{highcharts:1,highstock:1},description:"X offset of the lower data labels relative to the point value."},subtree:{}},yHigh:{meta:{types:{number:1,string:1},name:"yHigh",excludes:{},default:"-6",products:{highcharts:1,highstock:1},description:"Y offset of the higher data labels relative to the point value."},subtree:{}},yLow:{meta:{types:{number:1,string:1},name:"yLow",excludes:{},default:"16",products:{highcharts:1,highstock:1},description:"Y offset of the lower data labels relative to the point value."},subtree:{}}}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highcharts:1,highstock:1},description:"Pixel width of the arearange graph line."},subtree:{}},shadow:{meta:{types:{boolean:1,object:1},name:"shadow",excludes:{},products:{highcharts:1},description:"Whether to apply a drop shadow to the graph line. Since 2.3 the shadow\ncan be an object configuration containing `color`, `offsetX`, `offsetY`,\n`opacity` and `width`."},subtree:{}},threshold:{meta:{types:{object:1},name:"threshold",excludes:{},default:null},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:' {series.name}: {point.low} - {point.high}
    '},subtree:{}}}},trackByArea:{meta:{types:{boolean:1},name:"trackByArea",excludes:{},default:!0,products:{highcharts:1,highstock:1},description:"Whether the whole area or just the line should respond to mouseover\ntooltips and other mouse or touch events."},subtree:{}}}},areaspline:{meta:{types:{},name:"areaspline",excludes:{},products:{highcharts:1,highstock:1},description:"The area spline series is an area series where the graph between the points\nis smoothed into a spline.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `areaspline` series are defined in\n [plotOptions.areaspline](plotOptions.areaspline).\n3. Options for one single series are given in\n [the series instance array](series.areaspline).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        areaspline: {\n            // shared options for all areaspline series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'areaspline'\n    }]\n});\n
    \n ", extends:"plotOptions.area"},subtree:{}},areasplinerange:{meta:{types:{},name:"areasplinerange",excludes:{},products:{highcharts:1,highstock:1},description:"The area spline range is a cartesian series type with higher and\nlower Y values along an X axis. The area inside the range is colored, and\nthe graph outlining the area is a smoothed spline. Requires\n`highcharts-more.js`.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `areasplinerange` series are defined in\n [plotOptions.areasplinerange](plotOptions.areasplinerange).\n3. Options for one single series are given in\n [the series instance array](series.areasplinerange).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        areasplinerange: {\n            // shared options for all areasplinerange series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'areasplinerange'\n    }]\n});\n
    \n ",extends:"plotOptions.arearange"},subtree:{}},atr:{meta:{types:{object:1},name:"atr",excludes:{},products:{highstock:1},description:"Average true range indicator (ATR). This series requires `linkedTo`\noption to be set.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `atr` series are defined in\n [plotOptions.atr](plotOptions.atr).\n3. Options for one single series are given in\n [the series instance array](series.atr).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        atr: {\n            // shared options for all atr series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'atr'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{period:{meta:{types:{number:1},name:"period",excludes:{},default:14},subtree:{}}}}}},bar:{meta:{types:{object:1},name:"bar",excludes:{},products:{highcharts:1},description:"A bar series is a special type of column series where the columns are\nhorizontal.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `bar` series are defined in\n [plotOptions.bar](plotOptions.bar).\n3. Options for one single series are given in\n [the series instance array](series.bar).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        bar: {\n            // shared options for all bar series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'bar'\n    }]\n});\n
    \n ",extends:"{plotOptions.column}"},subtree:{dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{}},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"left",products:{highcharts:1},description:"Alignment of the data label relative to the data point."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"5",products:{highcharts:1},description:"The x position of the data label relative to the data point."},subtree:{}}}}}},bb:{meta:{types:{object:1},name:"bb",excludes:{},products:{highstock:1},description:"Bollinger bands (BB). This series requires the `linkedTo` option to be\nset and should be loaded after the `stock/indicators/indicators.js` file.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `bb` series are defined in\n [plotOptions.bb](plotOptions.bb).\n3. Options for one single series are given in\n [the series instance array](series.bb).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        bb: {\n            // shared options for all bb series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'bb'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{bottomLine:{meta:{types:{object:1},name:"bottomLine",excludes:{},products:{highstock:1},description:"Bottom line options."},subtree:{styles:{meta:{types:{object:1},name:"styles",excludes:{},products:{highstock:1},description:"Styles for a bottom line."},subtree:{lineColor:{meta:{types:{string:1},name:"lineColor",excludes:{},products:{highstock:1},description:"Color of the line. If not set, it's inherited from\n[plotOptions.bb.color](#plotOptions.bb.color)."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highstock:1},description:"Pixel width of the line."},subtree:{}}}}}},dataGrouping:{meta:{types:{object:1},name:"dataGrouping",excludes:{}},subtree:{approximation:{meta:{types:{string:1},name:"approximation",excludes:{},default:"averages"},subtree:{}}}},marker:{meta:{types:{object:1},name:"marker",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1},subtree:{}}}},name:{meta:{types:{string:1},name:"name",excludes:{},default:"BB (20, 2)"},subtree:{}},params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{index:{meta:{types:{number:1},name:"index",excludes:{},default:3},subtree:{}},period:{meta:{types:{number:1},name:"period",excludes:{},default:20},subtree:{}},standardDeviation:{meta:{types:{number:1},name:"standardDeviation",excludes:{},default:2,products:{highstock:1},description:"Standard deviation for top and bottom bands."},subtree:{}}}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:' {series.name}
    Top: {point.top}
    Middle: {point.middle}
    Bottom: {point.bottom}
    '},subtree:{}}}},topLine:{meta:{types:{object:1},name:"topLine",excludes:{},products:{highstock:1},description:"Top line options.",extends:"plotOptions.bb.bottomLine"},subtree:{styles:{meta:{types:{object:1},name:"styles",excludes:{}},subtree:{lineColor:{meta:{types:{},name:"lineColor",excludes:{}},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1},subtree:{}}}}}}}},bellcurve:{meta:{types:{object:1},name:"bellcurve",excludes:{},products:{highcharts:1},description:"A bell curve is an areaspline series which represents the probability density\nfunction of the normal distribution. It calculates mean and standard\ndeviation of the base series data and plots the curve according to the\ncalculated parameters.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `bellcurve` series are defined in\n [plotOptions.bellcurve](plotOptions.bellcurve).\n3. Options for one single series are given in\n [the series instance array](series.bellcurve).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        bellcurve: {\n            // shared options for all bellcurve series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'bellcurve'\n    }]\n});\n
    \n ",extends:"plotOptions.areaspline"},subtree:{intervals:{meta:{types:{number:1},name:"intervals",excludes:{},default:3,description:"This option allows to define the length of the bell curve. A unit of the\nlength of the bell curve is standard deviation."},subtree:{}},marker:{meta:{types:{object:1},name:"marker",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1},subtree:{}}}},pointsInInterval:{meta:{types:{number:1},name:"pointsInInterval",excludes:{},default:3,description:"Defines how many points should be plotted within 1 interval. See\n`plotOptions.bellcurve.intervals`."},subtree:{}}}},boxplot:{meta:{types:{object:1},name:"boxplot",excludes:{},products:{highcharts:1},description:"A box plot is a convenient way of depicting groups of data through their\nfive-number summaries: the smallest observation (sample minimum), lower\nquartile (Q1), median (Q2), upper quartile (Q3), and largest observation\n(sample maximum).\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `boxplot` series are defined in\n [plotOptions.boxplot](plotOptions.boxplot).\n3. Options for one single series are given in\n [the series instance array](series.boxplot).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        boxplot: {\n            // shared options for all boxplot series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'boxplot'\n    }]\n});\n
    \n ",extends:"{plotOptions.column}"},subtree:{fillColor:{meta:{types:{color:1},name:"fillColor",excludes:{},default:"#ffffff",products:{highcharts:1},description:"The fill color of the box.\n\nIn styled mode, the fill color can be set with the\n`.highcharts-boxplot-box` class."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highcharts:1},description:"The width of the line surrounding the box. If any of\n[stemWidth](#plotOptions.boxplot.stemWidth),\n[medianWidth](#plotOptions.boxplot.medianWidth)\nor [whiskerWidth](#plotOptions.boxplot.whiskerWidth) are `null`,\nthe lineWidth also applies to these lines."},subtree:{}},medianColor:{meta:{types:{color:1},name:"medianColor",excludes:{},default:"null",products:{highcharts:1},description:"The color of the median line. If `null`, the general series color\napplies.\n\nIn styled mode, the median stroke width can be set with the\n`.highcharts-boxplot-median` class."},subtree:{}},medianWidth:{meta:{types:{number:1},name:"medianWidth",excludes:{},default:2,products:{highcharts:1},description:"The pixel width of the median line. If `null`, the\n[lineWidth](#plotOptions.boxplot.lineWidth) is used.\n\nIn styled mode, the median stroke width can be set with the\n`.highcharts-boxplot-median` class."},subtree:{}},stemColor:{meta:{types:{color:1},name:"stemColor",excludes:{},default:"null",products:{highcharts:1},description:"The color of the stem, the vertical line extending from the box to\nthe whiskers. If `null`, the series color is used.\n\nIn styled mode, the stem stroke can be set with the\n`.highcharts-boxplot-stem` class."},subtree:{}},stemDashStyle:{meta:{types:{string:1},name:"stemDashStyle",excludes:{},default:"Solid",products:{highcharts:1},description:"The dash style of the stem, the vertical line extending from the\nbox to the whiskers."},subtree:{}},stemWidth:{meta:{types:{number:1},name:"stemWidth",excludes:{},default:"null",products:{highcharts:1},description:"The width of the stem, the vertical line extending from the box to\nthe whiskers. If `null`, the width is inherited from the\n[lineWidth](#plotOptions.boxplot.lineWidth) option.\n\nIn styled mode, the stem stroke width can be set with the\n`.highcharts-boxplot-stem` class."},subtree:{}},threshold:{meta:{types:{object:1},name:"threshold",excludes:{},default:null},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:' {series.name}
    Maximum: {point.high}
    Upper quartile: {point.q3}
    Median: {point.median}
    Lower quartile: {point.q1}
    Minimum: {point.low}
    '},subtree:{}}}},whiskerColor:{meta:{types:{color:1},name:"whiskerColor",excludes:{},default:"null",products:{highcharts:1},description:"The color of the whiskers, the horizontal lines marking low and high\nvalues. When `null`, the general series color is used.\n\nIn styled mode, the whisker stroke can be set with the\n`.highcharts-boxplot-whisker` class ."},subtree:{}},whiskerLength:{meta:{types:{number:1,string:1},name:"whiskerLength",excludes:{},default:"50%",products:{highcharts:1},description:"The length of the whiskers, the horizontal lines marking low and\nhigh values. It can be a numerical pixel value, or a percentage\nvalue of the box width. Set `0` to disable whiskers."},subtree:{}},whiskerWidth:{meta:{types:{number:1},name:"whiskerWidth",excludes:{},default:2,products:{highcharts:1},description:"The line width of the whiskers, the horizontal lines marking low and\nhigh values. When `null`, the general\n[lineWidth](#plotOptions.boxplot.lineWidth) applies.\n\nIn styled mode, the whisker stroke width can be set with the\n`.highcharts-boxplot-whisker` class."},subtree:{}}}},bubble:{meta:{types:{object:1},name:"bubble",excludes:{},products:{highcharts:1,highstock:1},description:"A bubble series is a three dimensional series type where each point renders\nan X, Y and Z value. Each points is drawn as a bubble where the position\nalong the X and Y axes mark the X and Y values, and the size of the bubble\nrelates to the Z value. Requires `highcharts-more.js`.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `bubble` series are defined in\n [plotOptions.bubble](plotOptions.bubble).\n3. Options for one single series are given in\n [the series instance array](series.bubble).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        bubble: {\n            // shared options for all bubble series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'bubble'\n    }]\n});\n
    \n ",extends:"plotOptions.scatter"},subtree:{animationLimit:{meta:{types:{number:1},name:"animationLimit",excludes:{},default:250,description:"If there are more points in the series than the `animationLimit`, the\nanimation won't run. Animation affects overall performance and doesn't\nwork well with heavy data series."},subtree:{}},dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{}},subtree:{formatter:{meta:{types:{},name:"formatter",excludes:{}},subtree:{}},inside:{meta:{types:{boolean:1},name:"inside",excludes:{},default:!0},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"middle"},subtree:{}}}},displayNegative:{meta:{types:{boolean:1},name:"displayNegative",excludes:{},default:"true",description:"Whether to display negative sized bubbles. The threshold is given\nby the [zThreshold](#plotOptions.bubble.zThreshold) option, and negative\nbubbles can be visualized by setting\n[negativeColor](#plotOptions.bubble.negativeColor)."},subtree:{}},marker:{meta:{types:{object:1},name:"marker",excludes:{},extends:"plotOptions.series.marker"},subtree:{fillOpacity:{meta:{types:{number:1},name:"fillOpacity",excludes:{},default:.5,description:"The fill opacity of the bubble markers."},subtree:{}},lineColor:{meta:{types:{object:1},name:"lineColor",excludes:{},default:null},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{}},subtree:{radiusPlus:{meta:{types:{number:1},name:"radiusPlus",excludes:{},default:0},subtree:{}}}}}},symbol:{meta:{types:{string:1},name:"symbol",excludes:{},default:"circle",description:'A predefined shape or symbol for the marker. Possible values are\n"circle", "square", "diamond", "triangle" and "triangle-down".\n\nAdditionally, the URL to a graphic can be given on the form\n`url(graphic.png)`. Note that for the image to be applied to exported\ncharts, its URL needs to be accessible by the export server.\n\nCustom callbacks for symbol path generation can also be added to\n`Highcharts.SVGRenderer.prototype.symbols`. The callback is then\nused by its method name, as shown in the demo.'},subtree:{}}}},maxSize:{meta:{types:{number:1,string:1},name:"maxSize",excludes:{},default:"20%",products:{highcharts:1,highstock:1},description:"Maximum bubble size. Bubbles will automatically size between the\n`minSize` and `maxSize` to reflect the `z` value of each bubble.\nCan be either pixels (when no unit is given), or a percentage of\nthe smallest one of the plot width and height."},subtree:{}},minSize:{meta:{types:{number:1,string:1},name:"minSize",excludes:{},default:8,products:{highcharts:1,highstock:1},description:"Minimum bubble size. Bubbles will automatically size between the\n`minSize` and `maxSize` to reflect the `z` value of each bubble.\nCan be either pixels (when no unit is given), or a percentage of\nthe smallest one of the plot width and height."},subtree:{}},negativeColor:{meta:{types:{color:1},name:"negativeColor",excludes:{},default:"null",products:{highcharts:1},description:"When a point's Z value is below the\n[zThreshold](#plotOptions.bubble.zThreshold) setting, this color is used."},subtree:{}},sizeBy:{meta:{types:{string:1},name:"sizeBy",excludes:{},default:"area",description:"Whether the bubble's value should be represented by the area or the\nwidth of the bubble. The default, `area`, corresponds best to the\nhuman perception of the size of each bubble."},subtree:{}},sizeByAbsoluteValue:{meta:{types:{boolean:1},name:"sizeByAbsoluteValue",excludes:{},default:"false",products:{highcharts:1},description:"When this is true, the absolute value of z determines the size of\nthe bubble. This means that with the default `zThreshold` of 0, a\nbubble of value -1 will have the same size as a bubble of value 1,\nwhile a bubble of value 0 will have a smaller size according to\n`minSize`."},subtree:{}},softThreshold:{meta:{types:{boolean:1},name:"softThreshold",excludes:{},default:!1,products:{highcharts:1},description:"When this is true, the series will not cause the Y axis to cross\nthe zero plane (or [threshold](#plotOptions.series.threshold) option)\nunless the data actually crosses the plane.\n\nFor example, if `softThreshold` is `false`, a series of 0, 1, 2,\n3 will make the Y axis show negative values according to the `minPadding`\noption. If `softThreshold` is `true`, the Y axis starts at 0."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{}},subtree:{halo:{meta:{types:{object:1},name:"halo",excludes:{}},subtree:{size:{meta:{types:{number:1},name:"size",excludes:{},default:5},subtree:{}}}}}}}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:"({point.x}, {point.y}), Size: {point.z}"},subtree:{}}}},turboThreshold:{meta:{types:{number:1},name:"turboThreshold",excludes:{},default:0},subtree:{}},zMax:{meta:{types:{number:1},name:"zMax",excludes:{},default:"null",products:{highcharts:1},description:"The minimum for the Z value range. Defaults to the highest Z value\nin the data."},subtree:{}},zMin:{meta:{types:{number:1},name:"zMin",excludes:{},default:"null",products:{highcharts:1},description:"The minimum for the Z value range. Defaults to the lowest Z value\nin the data."},subtree:{}},zThreshold:{meta:{types:{number:1},name:"zThreshold",excludes:{},default:"0",products:{highcharts:1},description:"When [displayNegative](#plotOptions.bubble.displayNegative) is `false`,\nbubbles with lower Z values are skipped. When `displayNegative`\nis `true` and a [negativeColor](#plotOptions.bubble.negativeColor)\nis given, points with lower Z is colored."},subtree:{}},zoneAxis:{meta:{types:{string:1},name:"zoneAxis",excludes:{},default:"z"},subtree:{}}}},bullet:{meta:{types:{object:1},name:"bullet",excludes:{},products:{highcharts:1},description:"A bullet graph is a variation of a bar graph. The bullet graph features\na single measure, compares it to a target, and displays it in the context\nof qualitative ranges of performance that could be set using\n[plotBands](#yAxis.plotBands) on [yAxis](#yAxis).\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `bullet` series are defined in\n [plotOptions.bullet](plotOptions.bullet).\n3. Options for one single series are given in\n [the series instance array](series.bullet).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        bullet: {\n            // shared options for all bullet series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'bullet'\n    }]\n});\n
    \n ",extends:"{plotOptions.column}"},subtree:{targetOptions:{meta:{types:{object:1},name:"targetOptions",excludes:{},products:{highcharts:1},description:"All options related with look and positiong of targets."},subtree:{borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},products:{highcharts:1},description:"The border color of the rectangle representing the target. When\nnot set, the point's border color is used.\n\nIn styled mode, use class `highcharts-bullet-target` instead."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:0,products:{highcharts:1},description:"The border width of the rectangle representing the target.\n\nIn styled mode, use class `highcharts-bullet-target` instead."},subtree:{}},color:{meta:{types:{color:1},name:"color",excludes:{},products:{highcharts:1},description:"The color of the rectangle representing the target. When not set,\npoint's color (if set in point's options -\n[`color`](#series.bullet.data.color)) or zone of the target value\n(if [`zones`](#plotOptions.bullet.zones) or\n[`negativeColor`](#plotOptions.bullet.negativeColor) are set)\nor the same color as the point has is used.\n\nIn styled mode, use class `highcharts-bullet-target` instead."},subtree:{}},height:{meta:{types:{number:1},name:"height",excludes:{},default:3,products:{highcharts:1},description:"The height of the rectangle representing the target."},subtree:{}},width:{meta:{types:{number:1,string:1},name:"width",excludes:{},default:"140%",products:{highcharts:1},description:"The width of the rectangle representing the target. Could be set\nas a pixel value or as a percentage of a column width."},subtree:{}}}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:' {series.name}: {point.y}. Target: {point.target}
    '},subtree:{}}}}}},candlestick:{meta:{types:{object:1},name:"candlestick",excludes:{},products:{highstock:1},description:"A candlestick chart is a style of financial chart used to describe price\nmovements over time.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `candlestick` series are defined in\n [plotOptions.candlestick](plotOptions.candlestick).\n3. Options for one single series are given in\n [the series instance array](series.candlestick).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        candlestick: {\n            // shared options for all candlestick series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'candlestick'\n    }]\n});\n
    \n ",extends:"plotOptions.ohlc"},subtree:{dataGrouping:{meta:{types:{object:1},name:"dataGrouping",excludes:{}},subtree:{approximation:{meta:{types:{string:1},name:"approximation",excludes:{},default:"ohlc"},subtree:{}}}},lineColor:{meta:{types:{color:1},name:"lineColor",excludes:{},default:"#000000",products:{highstock:1},description:"The color of the line/border of the candlestick.\n\nIn styled mode, the line stroke can be set with the\n`.highcharts-candlestick-series .highcahrts-point` rule."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:"1",products:{highstock:1},description:"The pixel width of the candlestick line/border. Defaults to `1`.\n\n\nIn styled mode, the line stroke width can be set with the\n`.highcharts-candlestick-series .highcahrts-point` rule."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{},products:{highstock:1},extends:"plotOptions.column.states.hover"},subtree:{lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:"2",products:{highstock:1},description:"The pixel width of the line/border around the candlestick."},subtree:{}}}}}},stickyTracking:{meta:{types:{boolean:1},name:"stickyTracking",excludes:{},default:!0},subtree:{}},threshold:{meta:{types:{object:1},name:"threshold",excludes:{},default:null},subtree:{}},tooltip:{meta:{types:{},name:"tooltip",excludes:{},extends:"plotOptions.ohlc.tooltip"},subtree:{}},upColor:{meta:{types:{color:1},name:"upColor",excludes:{},default:"#ffffff",products:{highstock:1},description:"The fill color of the candlestick when values are rising.\n\nIn styled mode, the up color can be set with the\n`.highcharts-candlestick-series .highcharts-point-up` rule."},subtree:{}},upLineColor:{meta:{types:{color:1},name:"upLineColor",excludes:{},default:"null",products:{highstock:1},description:"The specific line color for up candle sticks. The default is to inherit\nthe general `lineColor` setting."},subtree:{}}}},cci:{meta:{types:{object:1},name:"cci",excludes:{},products:{highstock:1},description:"Commodity Channel Index (CCI). This series requires `linkedTo` option to\nbe set.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `cci` series are defined in\n [plotOptions.cci](plotOptions.cci).\n3. Options for one single series are given in\n [the series instance array](series.cci).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        cci: {\n            // shared options for all cci series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'cci'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{period:{meta:{types:{number:1},name:"period",excludes:{},default:14},subtree:{}}}}}},cmf:{meta:{types:{object:1},name:"cmf",excludes:{},products:{highstock:1},description:"Chaikin Money Flow indicator (cmf).\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `cmf` series are defined in\n [plotOptions.cmf](plotOptions.cmf).\n3. Options for one single series are given in\n [the series instance array](series.cmf).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        cmf: {\n            // shared options for all cmf series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'cmf'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{period:{meta:{types:{number:1},name:"period",excludes:{},default:14},subtree:{}},volumeSeriesID:{meta:{types:{string:1},name:"volumeSeriesID",excludes:{},default:"volume",description:"The id of another series to use its data as volume data for the\nindiator calculation."},subtree:{}}}}}},column:{meta:{types:{object:1},name:"column",excludes:{},products:{highcharts:1,highstock:1},description:"Column series display one column per value along an X axis.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `column` series are defined in\n [plotOptions.column](plotOptions.column).\n3. Options for one single series are given in\n [the series instance array](series.column).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        column: {\n            // shared options for all column series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'column'\n    }]\n});\n
    \n ",extends:"{plotOptions.line}"},subtree:{borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},default:"#ffffff",products:{highcharts:1,highstock:1},description:"The color of the border surrounding each column or bar.\n\nIn styled mode, the border stroke can be set with the `.highcharts-point`\nrule."},subtree:{}},borderRadius:{meta:{types:{number:1},name:"borderRadius",excludes:{},default:"0",products:{highcharts:1,highstock:1},description:"The corner radius of the border surrounding each column or bar."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:"1",products:{highcharts:1,highstock:1},description:"The width of the border surrounding each column or bar.\n\nIn styled mode, the stroke width can be set with the `.highcharts-point`\nrule."},subtree:{}},colorByPoint:{meta:{types:{boolean:1},name:"colorByPoint",excludes:{},default:"false",products:{highcharts:1,highstock:1},description:"When using automatic point colors pulled from the `options.colors`\ncollection, this option determines whether the chart should receive\none color per series or one color per point."},subtree:{}},colors:{meta:{types:{array:"Color"},name:"colors",excludes:{},products:{highcharts:1,highstock:1},description:"A series specific or series type specific color set to apply instead\nof the global [colors](#colors) when [colorByPoint](\n#plotOptions.column.colorByPoint) is true."},subtree:{}},crisp:{meta:{types:{boolean:1},name:"crisp",excludes:{},default:!0,products:{highcharts:1,highstock:1},description:"When true, each column edge is rounded to its nearest pixel in order\nto render sharp on screen. In some cases, when there are a lot of\ndensely packed columns, this leads to visible difference in column\nwidths or distance between columns. In these cases, setting `crisp`\nto `false` may look better, even though each column is rendered\nblurry."},subtree:{}},cropThreshold:{meta:{types:{number:1},name:"cropThreshold",excludes:{},default:50,products:{highcharts:1,highstock:1},description:"When the series contains less points than the crop threshold, all\npoints are drawn, event if the points fall outside the visible plot\narea at the current zoom. The advantage of drawing all points (including\nmarkers and columns), is that animation is performed on updates.\nOn the other hand, when the series contains more points than the\ncrop threshold, the series data is cropped to only contain points\nthat fall within the plot area. The advantage of cropping away invisible\npoints is to increase performance on large series. ." },subtree:{}},dataGrouping:{meta:{types:{object:1},name:"dataGrouping",excludes:{}},subtree:{groupPixelWidth:{meta:{types:{number:1},name:"groupPixelWidth",excludes:{},default:"10",products:{highstock:1},description:"The approximate pixel width of each group. If for example a series\nwith 30 points is displayed over a 600 pixel wide plot area, no grouping\nis performed. If however the series contains so many points that\nthe spacing is less than the groupPixelWidth, Highcharts will try\nto group it into appropriate groups so that each is more or less\ntwo pixels wide. Defaults to `10`."},subtree:{}}}},dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{}},subtree:{align:{meta:{types:{object:1},name:"align",excludes:{},default:null},subtree:{}},verticalAlign:{meta:{types:{object:1},name:"verticalAlign",excludes:{},default:null},subtree:{}},y:{meta:{types:{object:1},name:"y",excludes:{},default:null},subtree:{}}}},depth:{meta:{types:{number:1},name:"depth",excludes:{},default:"25",products:{highcharts:1},description:"Depth of the columns in a 3D column chart. Requires `highcharts-3d.js`."},subtree:{}},edgeColor:{meta:{types:{color:1},name:"edgeColor",excludes:{},products:{highcharts:1},description:"3D columns only. The color of the edges. Similar to `borderColor`,\n except it defaults to the same color as the column."},subtree:{}},edgeWidth:{meta:{types:{number:1},name:"edgeWidth",excludes:{},default:"1",products:{highcharts:1},description:"3D columns only. The width of the colored edges."},subtree:{}},groupPadding:{meta:{types:{number:1},name:"groupPadding",excludes:{},default:.2,products:{highcharts:1,highstock:1},description:"Padding between each value groups, in x axis units."},subtree:{}},groupZPadding:{meta:{types:{number:1},name:"groupZPadding",excludes:{},default:"1",products:{highcharts:1},description:"The spacing between columns on the Z Axis in a 3D chart. Requires\n`highcharts-3d.js`."},subtree:{}},grouping:{meta:{types:{boolean:1},name:"grouping",excludes:{},default:"true",products:{highcharts:1,highstock:1},description:"Whether to group non-stacked columns or to let them render independent\nof each other. Non-grouped columns will be laid out individually\nand overlap each other."},subtree:{}},maxPointWidth:{meta:{types:{number:1},name:"maxPointWidth",excludes:{},default:"null",products:{highcharts:1,highstock:1},description:"The maximum allowed pixel width for a column, translated to the height\nof a bar in a bar chart. This prevents the columns from becoming\ntoo wide when there is a small number of points in the chart."},subtree:{}},minPointLength:{meta:{types:{number:1},name:"minPointLength",excludes:{},default:0,products:{highcharts:1,highstock:1},description:"The minimal height for a column or width for a bar. By default,\n0 values are not shown. To visualize a 0 (or close to zero) point,\nset the minimal point length to a pixel value like 3\\. In stacked\ncolumn charts, minPointLength might not be respected for tightly\npacked values."},subtree:{}},pointPadding:{meta:{types:{number:1},name:"pointPadding",excludes:{},default:.1,products:{highcharts:1,highstock:1},description:"Padding between each column or bar, in x axis units."},subtree:{}},pointRange:{meta:{types:{number:1},name:"pointRange",excludes:{},default:null,products:{highcharts:1,highstock:1},description:"The X axis range that each point is valid for. This determines the\nwidth of the column. On a categorized axis, the range will be 1\nby default (one category unit). On linear and datetime axes, the\nrange will be computed as the distance between the two closest data\npoints.\n\nThe default `null` means it is computed automatically, but this option\ncan be used to override the automatic value."},subtree:{}},pointWidth:{meta:{types:{number:1},name:"pointWidth",excludes:{},default:"null",products:{highcharts:1,highstock:1},description:"A pixel value specifying a fixed width for each column or bar. When\n`null`, the width is calculated from the `pointPadding` and\n`groupPadding`."},subtree:{}},softThreshold:{meta:{types:{boolean:1},name:"softThreshold",excludes:{},default:!1,products:{highcharts:1,highstock:1},description:"When this is true, the series will not cause the Y axis to cross\nthe zero plane (or [threshold](#plotOptions.series.threshold) option)\nunless the data actually crosses the plane.\n\nFor example, if `softThreshold` is `false`, a series of 0, 1, 2,\n3 will make the Y axis show negative values according to the `minPadding`\noption. If `softThreshold` is `true`, the Y axis starts at 0."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{},products:{highcharts:1,highstock:1},description:"Options for the hovered point. These settings override the normal\nstate options when a point is moused over or touched.",extends:"plotOptions.series.states.hover"},subtree:{borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},products:{highcharts:1},description:"A specific border color for the hovered point. Defaults to\ninherit the normal state border color."},subtree:{}},brightness:{meta:{types:{number:1},name:"brightness",excludes:{},default:.1,products:{highcharts:1,highstock:1},description:"How much to brighten the point on interaction. Requires the main\ncolor to be defined in hex or rgb(a) format.\n\nIn styled mode, the hover brightening is by default replaced\nwith a fill-opacity set in the `.highcharts-point:hover` rule."},subtree:{}},color:{meta:{types:{color:1},name:"color",excludes:{},default:"undefined",products:{highcharts:1},description:"A specific color for the hovered point."},subtree:{}}}},select:{meta:{types:{object:1},name:"select",excludes:{},products:{highcharts:1,highstock:1},description:"Options for the selected point. These settings override the normal\nstate options when a point is selected."},subtree:{borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},default:"#000000",products:{highcharts:1,highstock:1},description:"A specific border color for the selected point."},subtree:{}},color:{meta:{types:{color:1},name:"color",excludes:{},default:"#cccccc",products:{highcharts:1,highstock:1},description:"A specific color for the selected point."},subtree:{}}}}}},stickyTracking:{meta:{types:{boolean:1},name:"stickyTracking",excludes:{},default:!1},subtree:{}},threshold:{meta:{types:{number:1},name:"threshold",excludes:{},default:0,products:{highcharts:1},description:"The Y axis value to serve as the base for the columns, for distinguishing\nbetween values above and below a threshold. If `null`, the columns\nextend from the padding Y axis minimum."},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{distance:{meta:{types:{number:1},name:"distance",excludes:{},default:6},subtree:{}}}}}},columnrange:{meta:{types:{object:1},name:"columnrange",excludes:{},products:{highcharts:1,highstock:1},description:"The column range is a cartesian series type with higher and lower\nY values along an X axis. Requires `highcharts-more.js`. To display\nhorizontal bars, set [chart.inverted](#chart.inverted) to `true`.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `columnrange` series are defined in\n [plotOptions.columnrange](plotOptions.columnrange).\n3. Options for one single series are given in\n [the series instance array](series.columnrange).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        columnrange: {\n            // shared options for all columnrange series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'columnrange'\n    }]\n});\n
    \n ",extends:"plotOptions.column"},subtree:{pointRange:{meta:{types:{object:1},name:"pointRange",excludes:{},default:null},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{},name:"hover",excludes:{}},subtree:{}}}}}},ema:{meta:{types:{object:1},name:"ema",excludes:{},products:{highstock:1},description:"Exponential moving average indicator (EMA). This series requires the\n`linkedTo` option to be set.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `ema` series are defined in\n [plotOptions.ema](plotOptions.ema).\n3. Options for one single series are given in\n [the series instance array](series.ema).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        ema: {\n            // shared options for all ema series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'ema'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{index:{meta:{types:{number:1},name:"index",excludes:{},default:0},subtree:{}},period:{meta:{types:{number:1},name:"period",excludes:{},default:14},subtree:{}}}}}},errorbar:{meta:{types:{object:1},name:"errorbar",excludes:{},products:{highcharts:1,highstock:1},description:"Error bars are a graphical representation of the variability of data and are\nused on graphs to indicate the error, or uncertainty in a reported\nmeasurement.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `errorbar` series are defined in\n [plotOptions.errorbar](plotOptions.errorbar).\n3. Options for one single series are given in\n [the series instance array](series.errorbar).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        errorbar: {\n            // shared options for all errorbar series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'errorbar'\n    }]\n});\n
    \n ",extends:"{plotOptions.boxplot}"},subtree:{color:{meta:{types:{color:1},name:"color",excludes:{},default:"#000000",products:{highcharts:1},description:"The main color of the bars. This can be overridden by\n[stemColor](#plotOptions.errorbar.stemColor) and\n[whiskerColor](#plotOptions.errorbar.whiskerColor) individually."},subtree:{}},grouping:{meta:{types:{boolean:1},name:"grouping",excludes:{},default:!1},subtree:{}},linkedTo:{meta:{types:{string:1},name:"linkedTo",excludes:{},default:":previous",products:{highcharts:1},description:"The parent series of the error bar. The default value links it to\nthe previous series. Otherwise, use the id of the parent series."},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:' {series.name}: {point.low} - {point.high}
    '},subtree:{}}}},whiskerWidth:{meta:{types:{number:1},name:"whiskerWidth",excludes:{},default:null,products:{highcharts:1},description:"The line width of the whiskers, the horizontal lines marking low\nand high values. When `null`, the general\n[lineWidth](#plotOptions.errorbar.lineWidth) applies."},subtree:{}}}},flags:{meta:{types:{object:1},name:"flags",excludes:{},products:{highstock:1},description:"Flags are used to mark events in stock charts. They can be added on the\ntimeline, or attached to a specific series.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `flags` series are defined in\n [plotOptions.flags](plotOptions.flags).\n3. Options for one single series are given in\n [the series instance array](series.flags).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        flags: {\n            // shared options for all flags series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'flags'\n    }]\n});\n
    \n ",extends:"{plotOptions.column}"},subtree:{allowOverlapX:{meta:{types:{boolean:1},name:"allowOverlapX",excludes:{},default:!1,description:"Whether the flags are allowed to overlap sideways. If `false`, the flags\nare moved sideways using an algorithm that seeks to place every flag as\nclose as possible to its original position."},subtree:{}},fillColor:{meta:{types:{color:1},name:"fillColor",excludes:{},default:"#ffffff",products:{highstock:1},description:"The fill color for the flags."},subtree:{}},height:{meta:{types:{number:1},name:"height",excludes:{},default:"undefined",products:{highstock:1},description:"Fixed height of the flag's shape. By default, height is autocalculated\naccording to the flag's title."},subtree:{}},lineColor:{meta:{types:{color:1},name:"lineColor",excludes:{},default:"#000000",products:{highstock:1},description:"The color of the line/border of the flag.\n\nIn styled mode, the stroke is set in the\n`.highcharts-flag-series.highcharts-point` rule."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highstock:1},description:"The pixel width of the flag's line/border."},subtree:{}},onKey:{meta:{types:{string:1},name:"onKey",excludes:{},default:"y",products:{highstock:1},description:"In case the flag is placed on a series, on what point key to place\nit. Line and columns have one key, `y`. In range or OHLC-type series,\nhowever, the flag can optionally be placed on the `open`, `high`,\n `low` or `close` key."},subtree:{}},onSeries:{meta:{types:{string:1},name:"onSeries",excludes:{},default:"undefined",products:{highstock:1},description:"The id of the series that the flags should be drawn on. If no id\nis given, the flags are drawn on the x axis."},subtree:{}},pointRange:{meta:{types:{number:1},name:"pointRange",excludes:{},default:0},subtree:{}},shape:{meta:{types:{string:1},name:"shape",excludes:{},default:"flag",products:{highstock:1},description:'The shape of the marker. Can be one of "flag", "circlepin", "squarepin",\nor an image of the format `url(/path-to-image.jpg)`. Individual\nshapes can also be set for each point.'},subtree:{}},stackDistance:{meta:{types:{number:1},name:"stackDistance",excludes:{},default:12,products:{highstock:1},description:"When multiple flags in the same series fall on the same value, this\nnumber determines the vertical offset between them."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{},products:{highstock:1},extends:"plotOptions.column.states.hover"},subtree:{fillColor:{meta:{types:{color:1},name:"fillColor",excludes:{},default:"#ccd6eb",products:{highstock:1},description:"The fill or background color of the flag."},subtree:{}},lineColor:{meta:{types:{color:1},name:"lineColor",excludes:{},default:"#000000",products:{highstock:1},description:"The color of the line/border of the flag."},subtree:{}}}}}},style:{meta:{types:{cssobject:1},name:"style",excludes:{},default:'{ "fontSize": "11px", "fontWeight": "bold" }',products:{highstock:1},description:"The text styles of the flag.\n\nIn styled mode, the styles are set in the\n`.highcharts-flag-series .highcharts-point` rule."},subtree:{fontSize:{meta:{types:{string:1},name:"fontSize",excludes:{},default:"11px"},subtree:{}},fontWeight:{meta:{types:{string:1},name:"fontWeight",excludes:{},default:"bold"},subtree:{}}}},textAlign:{meta:{types:{string:1},name:"textAlign",excludes:{},default:"center",products:{highstock:1},description:"Text alignment for the text inside the flag."},subtree:{}},threshold:{meta:{types:{object:1},name:"threshold",excludes:{},default:null},subtree:{}},title:{meta:{types:{string:1},name:"title",excludes:{},default:"A",products:{highstock:1},description:'The text to display on each flag. This can be defined on series level,\n or individually for each point. Defaults to `"A"`.'},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{},products:{highstock:1},description:"Specific tooltip options for flag series. Flag series tooltips are\ndifferent from most other types in that a flag doesn't have a data\nvalue, so the tooltip rather displays the `text` option for each\npoint.",extends:"plotOptions.series.tooltip"},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:"{point.text}
    "},subtree:{}}}},useHTML:{meta:{types:{boolean:1},name:"useHTML",excludes:{},default:"false",products:{highstock:1},description:"Whether to use HTML to render the flag texts. Using HTML allows for\nadvanced formatting, images and reliable bi-directional text rendering.\nNote that exported images won't respect the HTML, and that HTML\nwon't respect Z-index settings."},subtree:{}},width:{meta:{types:{number:1},name:"width",excludes:{},default:"undefined",products:{highstock:1},description:"Fixed width of the flag's shape. By default, width is autocalculated\naccording to the flag's title."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:-30,products:{highstock:1},description:"The y position of the top left corner of the flag relative to either\nthe series (if onSeries is defined), or the x axis. Defaults to\n`-30`."},subtree:{}}}},funnel:{meta:{types:{object:1},name:"funnel",excludes:{},products:{highcharts:1},description:"Funnel charts are a type of chart often used to visualize stages in a sales\nproject, where the top are the initial stages with the most clients.\nIt requires that the modules/funnel.js file is loaded.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `funnel` series are defined in\n [plotOptions.funnel](plotOptions.funnel).\n3. Options for one single series are given in\n [the series instance array](series.funnel).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        funnel: {\n            // shared options for all funnel series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'funnel'\n    }]\n});\n
    \n ",extends:"{plotOptions.pie}"},subtree:{animation:{meta:{types:{boolean:1},name:"animation",excludes:{},default:!1,description:"Initial animation is by default disabled for the funnel chart."},subtree:{}},center:{meta:{types:{array:"(String|Number)"},name:"center",excludes:{},default:'["50%", "50%"]',products:{highcharts:1},description:"The center of the series. By default, it is centered in the middle\nof the plot area, so it fills the plot area height."},subtree:{}},dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{}},subtree:{connectorWidth:{meta:{types:{number:1},name:"connectorWidth",excludes:{},default:1},subtree:{}}}},height:{meta:{types:{number:1,string:1},name:"height",excludes:{},default:"100%",products:{highcharts:1},description:"The height of the funnel or pyramid. If it is a number it defines\nthe pixel height, if it is a percentage string it is the percentage\nof the plot area height."},subtree:{}},neckHeight:{meta:{types:{number:1,string:1},name:"neckHeight",excludes:{},default:"25%",products:{highcharts:1},description:"The height of the neck, the lower part of the funnel. A number defines\npixel width, a percentage string defines a percentage of the plot\narea height."},subtree:{}},neckWidth:{meta:{types:{number:1,string:1},name:"neckWidth",excludes:{},default:"30%",products:{highcharts:1},description:"The width of the neck, the lower part of the funnel. A number defines\npixel width, a percentage string defines a percentage of the plot\narea width."},subtree:{}},reversed:{meta:{types:{boolean:1},name:"reversed",excludes:{},default:!1,products:{highcharts:1},description:"A reversed funnel has the widest area down. A reversed funnel with\nno neck width and neck height is a pyramid."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{},products:{highcharts:1},description:"Options for the series states."},subtree:{hover:{meta:{types:{},name:"hover",excludes:{}},subtree:{}},select:{meta:{types:{object:1},name:"select",excludes:{},products:{highcharts:1},description:"Options for a selected funnel item."},subtree:{borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},default:"#000000",products:{highcharts:1,highstock:1},description:"A specific border color for the selected point."},subtree:{}},color:{meta:{types:{color:1},name:"color",excludes:{},default:"#cccccc",products:{highcharts:1,highstock:1},description:"A specific color for the selected point."},subtree:{}}}}}},width:{meta:{types:{number:1,string:1},name:"width",excludes:{},default:"90%",products:{highcharts:1},description:"The width of the funnel compared to the width of the plot area,\nor the pixel width if it is a number."},subtree:{}}}},gauge:{meta:{types:{object:1},name:"gauge",excludes:{},products:{highcharts:1},description:"Gauges are circular plots displaying one or more values with a dial pointing\nto values along the perimeter.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `gauge` series are defined in\n [plotOptions.gauge](plotOptions.gauge).\n3. Options for one single series are given in\n [the series instance array](series.gauge).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        gauge: {\n            // shared options for all gauge series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'gauge'\n    }]\n});\n
    \n ",extends:"{plotOptions.line}"},subtree:{dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{},products:{highcharts:1},description:"Data labels for the gauge. For gauges, the data labels are enabled\nby default and shown in a bordered box below the point.",extends:"plotOptions.series.dataLabels"},subtree:{borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},default:"#cccccc",products:{highcharts:1,highmaps:1},description:"The border color for the data label."},subtree:{}},borderRadius:{meta:{types:{number:1},name:"borderRadius",excludes:{},default:3,products:{highcharts:1,highmaps:1},description:"The border radius in pixels for the gauge's data label."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:1,products:{highcharts:1,highmaps:1},description:"The border width in pixels for the gauge data label."},subtree:{}},crop:{meta:{types:{boolean:1},name:"crop",excludes:{},default:!1},subtree:{}},defer:{meta:{types:{boolean:1},name:"defer",excludes:{},default:!1},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0,products:{highcharts:1,highmaps:1},description:"Enable or disable the data labels."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"top",products:{highcharts:1,highmaps:1},description:"The vertical alignment of the data label."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:15,products:{highcharts:1,highmaps:1},description:"The y position offset of the label relative to the center of the\ngauge."},subtree:{}},zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},default:2,products:{highcharts:1,highmaps:1},description:"The Z index of the data labels. A value of 2 display them behind\nthe dial."},subtree:{}}}},dial:{meta:{types:{object:1},name:"dial",excludes:{},products:{highcharts:1},description:"Options for the dial or arrow pointer of the gauge.\n\nIn styled mode, the dial is styled with the\n`.highcharts-gauge-series .highcharts-dial` rule."},subtree:{backgroundColor:{meta:{types:{color:1},name:"backgroundColor",excludes:{},default:"#000000",products:{highcharts:1},description:"The background or fill color of the gauge's dial."},subtree:{}},baseLength:{meta:{types:{string:1},name:"baseLength",excludes:{},default:"70%",products:{highcharts:1},description:"The length of the dial's base part, relative to the total radius\nor length of the dial."},subtree:{}},baseWidth:{meta:{types:{number:1},name:"baseWidth",excludes:{},default:"3",products:{highcharts:1},description:"The pixel width of the base of the gauge dial. The base is the part\nclosest to the pivot, defined by baseLength."},subtree:{}},borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},default:"#cccccc",products:{highcharts:1},description:"The border color or stroke of the gauge's dial. By default, the\nborderWidth is 0, so this must be set in addition to a custom border\ncolor."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:"0",products:{highcharts:1},description:"The width of the gauge dial border in pixels."},subtree:{}},radius:{meta:{types:{string:1},name:"radius",excludes:{},default:"80%",products:{highcharts:1},description:"The radius or length of the dial, in percentages relative to the\nradius of the gauge itself."},subtree:{}},rearLength:{meta:{types:{string:1},name:"rearLength",excludes:{},default:"10%",products:{highcharts:1},description:"The length of the dial's rear end, the part that extends out on the\nother side of the pivot. Relative to the dial's length."},subtree:{}},topWidth:{meta:{types:{number:1},name:"topWidth",excludes:{},default:"1",products:{highcharts:1},description:"The width of the top of the dial, closest to the perimeter. The pivot\nnarrows in from the base to the top."},subtree:{}}}},overshoot:{meta:{types:{number:1},name:"overshoot",excludes:{},default:"0",products:{highcharts:1},description:"Allow the dial to overshoot the end of the perimeter axis by this\nmany degrees. Say if the gauge axis goes from 0 to 60, a value of\n100, or 1000, will show 5 degrees beyond the end of the axis when this\noption is set to 5."},subtree:{}},pivot:{meta:{types:{object:1},name:"pivot",excludes:{},products:{highcharts:1},description:"Options for the pivot or the center point of the gauge.\n\nIn styled mode, the pivot is styled with the\n`.highcharts-gauge-series .highcharts-pivot` rule."},subtree:{backgroundColor:{meta:{types:{color:1},name:"backgroundColor",excludes:{},default:"#000000",products:{highcharts:1},description:"The background color or fill of the pivot."},subtree:{}},borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},default:"#cccccc",products:{highcharts:1},description:"The border or stroke color of the pivot. In able to change this,\nthe borderWidth must also be set to something other than the default\n0."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:"0",products:{highcharts:1},description:"The border or stroke width of the pivot."},subtree:{}},radius:{meta:{types:{number:1},name:"radius",excludes:{},default:"5",products:{highcharts:1},description:"The pixel radius of the pivot."},subtree:{}}}},showInLegend:{meta:{types:{boolean:1},name:"showInLegend",excludes:{},default:!1,products:{highcharts:1},description:"Whether to display this particular series or series type in the\nlegend. Defaults to false for gauge series."},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{headerFormat:{meta:{types:{string:1},name:"headerFormat",excludes:{},default:""},subtree:{}}}},wrap:{meta:{types:{boolean:1},name:"wrap",excludes:{},default:"true",products:{highcharts:1},description:"When this option is `true`, the dial will wrap around the axes. For\ninstance, in a full-range gauge going from 0 to 360, a value of 400\nwill point to 40\\. When `wrap` is `false`, the dial stops at 360."},subtree:{}}}},heatmap:{meta:{types:{object:1},name:"heatmap",excludes:{},products:{highcharts:1,highmaps:1},description:"A heatmap is a graphical representation of data where the individual values\ncontained in a matrix are represented as colors.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `heatmap` series are defined in\n [plotOptions.heatmap](plotOptions.heatmap).\n3. Options for one single series are given in\n [the series instance array](series.heatmap).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        heatmap: {\n            // shared options for all heatmap series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'heatmap'\n    }]\n});\n
    \n ",extends:"{plotOptions.scatter}"},subtree:{animation:{meta:{types:{boolean:1,object:1},name:"animation",excludes:{},default:!1,description:"Animation is disabled by default on the heatmap series."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:0,description:"The border width for each heat map item."},subtree:{}},color:{meta:{types:{color:1},name:"color",excludes:{},default:"null",products:{highcharts:1},description:"The main color of the series. In heat maps this color is rarely used,\nas we mostly use the color to denote the value of each point. Unless\noptions are set in the [colorAxis](#colorAxis), the default value\nis pulled from the [options.colors](#colors) array."},subtree:{}},colsize:{meta:{types:{number:1},name:"colsize",excludes:{},default:"1",products:{highcharts:1,highmaps:1},description:"The column size - how many X axis units each column in the heatmap\nshould span."},subtree:{}},dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{}},subtree:{crop:{meta:{types:{boolean:1},name:"crop",excludes:{},default:!1},subtree:{}},formatter:{meta:{types:{},name:"formatter",excludes:{}},subtree:{}},inside:{meta:{types:{boolean:1},name:"inside",excludes:{},default:!0},subtree:{}},overflow:{meta:{types:{boolean:1},name:"overflow",excludes:{},default:!1},subtree:{}},padding:{meta:{types:{number:1},name:"padding",excludes:{},default:0},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"middle"},subtree:{}}}},nullColor:{meta:{types:{color:1},name:"nullColor",excludes:{},default:"#f7f7f7",description:"The color applied to null points. In styled mode, a general CSS class is\napplied instead."},subtree:{}},pointPadding:{meta:{types:{number:1},name:"pointPadding",excludes:{},default:"0",description:"Padding between the points in the heatmap."},subtree:{}},rowsize:{meta:{types:{number:1},name:"rowsize",excludes:{},default:"1",products:{highcharts:1,highmaps:1},description:"The row size - how many Y axis units each heatmap row should span."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{}},subtree:{brightness:{meta:{types:{number:1},name:"brightness",excludes:{},default:.2,products:{highcharts:1,highmaps:1},description:"How much to brighten the point on interaction. Requires the main\ncolor to be defined in hex or rgb(a) format.\n\nIn styled mode, the hover brightening is by default replaced\nwith a fill-opacity set in the `.highcharts-point:hover` rule."},subtree:{}}}}}},tooltip:{meta:{types:{object:1},name:"tooltip", excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:"{point.x}, {point.y}: {point.value}
    "},subtree:{}}}}}},histogram:{meta:{types:{object:1},name:"histogram",excludes:{},products:{highcharts:1},description:"A histogram is a column series which represents the distribution of the data\nset in the base series. Histogram splits data into bins and shows their\nfrequencies.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `histogram` series are defined in\n [plotOptions.histogram](plotOptions.histogram).\n3. Options for one single series are given in\n [the series instance array](series.histogram).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        histogram: {\n            // shared options for all histogram series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'histogram'\n    }]\n});\n
    \n ",extends:"plotOptions.column"},subtree:{binWidth:{meta:{types:{number:1},name:"binWidth",excludes:{},description:"Width of each bin. By default the bin's width is calculated as\n`(max - min) / number of bins`. This option takes precedence over\n[binsNumber](#plotOptions.histogram.binsNumber)."},subtree:{}},binsNumber:{meta:{types:{number:1,string:1,function:1},name:"binsNumber",excludes:{},default:"square-root",description:"A preferable number of bins. It is a suggestion, so a histogram may have\na different number of bins. By default it is set to the square root\nof the base series' data length. Available options are: `square-root`,\n`sturges`, `rice`. You can also define a function which takes a\n`baseSeries` as a parameter and should return a positive integer."},subtree:{}},groupPadding:{meta:{types:{number:1},name:"groupPadding",excludes:{},default:0},subtree:{}},grouping:{meta:{types:{boolean:1},name:"grouping",excludes:{},default:!1},subtree:{}},pointPadding:{meta:{types:{number:1},name:"pointPadding",excludes:{},default:0},subtree:{}},pointPlacement:{meta:{types:{string:1},name:"pointPlacement",excludes:{},default:"between"},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{headerFormat:{meta:{types:{string:1},name:"headerFormat",excludes:{},default:""},subtree:{}},pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:'{point.x} - {point.x2}
    {series.name} {point.y}
    '},subtree:{}}}}}},ikh:{meta:{types:{object:1},name:"ikh",excludes:{},products:{highstock:1},description:"Ichimoku Kinko Hyo (IKH). This series requires `linkedTo` option to be\nset.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `ikh` series are defined in\n [plotOptions.ikh](plotOptions.ikh).\n3. Options for one single series are given in\n [the series instance array](series.ikh).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        ikh: {\n            // shared options for all ikh series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'ikh'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{chikouLine:{meta:{types:{object:1},name:"chikouLine",excludes:{},products:{highstock:1},description:"The styles for Chikou line"},subtree:{styles:{meta:{types:{object:1},name:"styles",excludes:{}},subtree:{lineColor:{meta:{types:{number:1},name:"lineColor",excludes:{},products:{highstock:1},description:"Color of the line."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highstock:1},description:"Pixel width of the line."},subtree:{}}}}}},dataGrouping:{meta:{types:{object:1},name:"dataGrouping",excludes:{}},subtree:{approximation:{meta:{types:{string:1},name:"approximation",excludes:{},default:"ichimoku-averages"},subtree:{}}}},kijunLine:{meta:{types:{object:1},name:"kijunLine",excludes:{},products:{highstock:1},description:"The styles for Kijun line"},subtree:{styles:{meta:{types:{object:1},name:"styles",excludes:{}},subtree:{lineColor:{meta:{types:{number:1},name:"lineColor",excludes:{},products:{highstock:1},description:"Color of the line."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highstock:1},description:"Pixel width of the line."},subtree:{}}}}}},marker:{meta:{types:{object:1},name:"marker",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1},subtree:{}}}},params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{period:{meta:{types:{number:1},name:"period",excludes:{},default:26},subtree:{}},periodSenkouSpanB:{meta:{types:{number:1},name:"periodSenkouSpanB",excludes:{},default:52,products:{highstock:1},description:"The base period for Senkou Span B calculations"},subtree:{}},periodTenkan:{meta:{types:{number:1},name:"periodTenkan",excludes:{},default:9,products:{highstock:1},description:"The base period for Tenkan calculations."},subtree:{}}}},senkouSpan:{meta:{types:{object:1},name:"senkouSpan",excludes:{},products:{highstock:1},description:"The styles for fill between Senkou Span A and B"},subtree:{styles:{meta:{types:{object:1},name:"styles",excludes:{}},subtree:{fill:{meta:{types:{number:1},name:"fill",excludes:{},default:"rgba(255, 0, 0, 0.5)",products:{highstock:1},description:"Color of the area between Senkou Span A and B."},subtree:{}}}}}},senkouSpanA:{meta:{types:{object:1},name:"senkouSpanA",excludes:{},products:{highstock:1},description:"The styles for Senkou Span A line"},subtree:{styles:{meta:{types:{object:1},name:"styles",excludes:{}},subtree:{lineColor:{meta:{types:{number:1},name:"lineColor",excludes:{},products:{highstock:1},description:"Color of the line."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highstock:1},description:"Pixel width of the line."},subtree:{}}}}}},senkouSpanB:{meta:{types:{object:1},name:"senkouSpanB",excludes:{},products:{highstock:1},description:"The styles for Senkou Span B line"},subtree:{styles:{meta:{types:{object:1},name:"styles",excludes:{}},subtree:{lineColor:{meta:{types:{number:1},name:"lineColor",excludes:{},products:{highstock:1},description:"Color of the line."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highstock:1},description:"Pixel width of the line."},subtree:{}}}}}},tenkanLine:{meta:{types:{object:1},name:"tenkanLine",excludes:{},products:{highstock:1},description:"The styles for Tenkan line"},subtree:{styles:{meta:{types:{object:1},name:"styles",excludes:{}},subtree:{lineColor:{meta:{types:{number:1},name:"lineColor",excludes:{},products:{highstock:1},description:"Color of the line."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highstock:1},description:"Pixel width of the line."},subtree:{}}}}}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:' {series.name}
    TENKAN SEN: {point.tenkanSen:.3f}
    KIJUN SEN: {point.kijunSen:.3f}
    CHIKOU SPAN: {point.chikouSpan:.3f}
    SENKOU SPAN A: {point.senkouSpanA:.3f}
    SENKOU SPAN B: {point.senkouSpanB:.3f}
    '},subtree:{}}}}}},line:{meta:{types:{object:1},name:"line",excludes:{},products:{highcharts:1,highstock:1},description:"A line series displays information as a series of data points connected by\nstraight line segments.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `line` series are defined in\n [plotOptions.line](plotOptions.line).\n3. Options for one single series are given in\n [the series instance array](series.line).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        line: {\n            // shared options for all line series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'line'\n    }]\n});\n
    \n ",extends:"plotOptions.series"},subtree:{linecap:{meta:{types:{string:1},name:"linecap",excludes:{},default:"round",description:"The SVG value used for the `stroke-linecap` and `stroke-linejoin`\nof a line graph. Round means that lines are rounded in the ends and\nbends."},subtree:{}}}},macd:{meta:{types:{object:1},name:"macd",excludes:{},products:{highstock:1},description:"Moving Average Convergence Divergence (MACD). This series requires\n`linkedTo` option to be set.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `macd` series are defined in\n [plotOptions.macd](plotOptions.macd).\n3. Options for one single series are given in\n [the series instance array](series.macd).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        macd: {\n            // shared options for all macd series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'macd'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{dataGrouping:{meta:{types:{object:1},name:"dataGrouping",excludes:{}},subtree:{approximation:{meta:{types:{string:1},name:"approximation",excludes:{},default:"averages"},subtree:{}}}},groupPadding:{meta:{types:{number:1},name:"groupPadding",excludes:{},default:.1},subtree:{}},macdLine:{meta:{types:{object:1},name:"macdLine",excludes:{},products:{highstock:1},description:"The styles for macd line"},subtree:{styles:{meta:{types:{object:1},name:"styles",excludes:{}},subtree:{lineColor:{meta:{types:{number:1},name:"lineColor",excludes:{},products:{highstock:1},description:"Color of the line."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highstock:1},description:"Pixel width of the line."},subtree:{}}}},zones:{meta:{types:{},name:"zones",excludes:{},extends:"plotOptions.macd.zones"},subtree:{}}}},minPointLength:{meta:{types:{number:1},name:"minPointLength",excludes:{},default:0},subtree:{}},params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{longPeriod:{meta:{types:{number:1},name:"longPeriod",excludes:{},default:26,products:{highstock:1},description:"The long period for indicator calculations."},subtree:{}},period:{meta:{types:{number:1},name:"period",excludes:{},default:26},subtree:{}},shortPeriod:{meta:{types:{number:1},name:"shortPeriod",excludes:{},default:12,products:{highstock:1},description:"The short period for indicator calculations."},subtree:{}},signalPeriod:{meta:{types:{number:1},name:"signalPeriod",excludes:{},default:9,products:{highstock:1},description:"The base period for signal calculations."},subtree:{}}}},pointPadding:{meta:{types:{number:1},name:"pointPadding",excludes:{},default:.1},subtree:{}},signalLine:{meta:{types:{object:1},name:"signalLine",excludes:{},products:{highstock:1},description:"The styles for signal line"},subtree:{styles:{meta:{types:{object:1},name:"styles",excludes:{}},subtree:{lineColor:{meta:{types:{number:1},name:"lineColor",excludes:{},products:{highstock:1},description:"Color of the line."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highstock:1},description:"Pixel width of the line."},subtree:{}}}},zones:{meta:{types:{},name:"zones",excludes:{},extends:"plotOptions.macd.zones"},subtree:{}}}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{}},subtree:{halo:{meta:{types:{object:1},name:"halo",excludes:{}},subtree:{size:{meta:{types:{number:1},name:"size",excludes:{},default:0},subtree:{}}}}}}}},threshold:{meta:{types:{number:1},name:"threshold",excludes:{},default:0},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:' {series.name}
    Value: {point.MACD}
    Signal: {point.signal}
    Histogram: {point.y}
    '},subtree:{}}}}}},map:{meta:{types:{object:1},name:"map",excludes:{},products:{highmaps:1},description:"The map series is used for basic choropleth maps, where each map area has a\ncolor based on its value.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `map` series are defined in\n [plotOptions.map](plotOptions.map).\n3. Options for one single series are given in\n [the series instance array](series.map).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        map: {\n            // shared options for all map series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'map'\n    }]\n});\n
    \n ",extends:"plotOptions.scatter"},subtree:{allAreas:{meta:{types:{boolean:1},name:"allAreas",excludes:{},default:!0},subtree:{}},animation:{meta:{types:{boolean:1},name:"animation",excludes:{},default:!1},subtree:{}},borderColor:{meta:{types:{string:1},name:"borderColor",excludes:{},default:"#cccccc"},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:1},subtree:{}},dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{}},subtree:{crop:{meta:{types:{boolean:1},name:"crop",excludes:{},default:!1},subtree:{}},formatter:{meta:{types:{},name:"formatter",excludes:{}},subtree:{}},inside:{meta:{types:{boolean:1},name:"inside",excludes:{},default:!0},subtree:{}},overflow:{meta:{types:{boolean:1},name:"overflow",excludes:{},default:!1},subtree:{}},padding:{meta:{types:{number:1},name:"padding",excludes:{},default:0},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"middle"},subtree:{}}}},joinBy:{meta:{types:{string:1},name:"joinBy",excludes:{},default:"hc-key"},subtree:{}},nullColor:{meta:{types:{color:1},name:"nullColor",excludes:{},default:"#f7f7f7",products:{highmaps:1},description:"The color to apply to null points.\n\nIn styled mode, the null point fill is set in the\n`.highcharts-null-point` class."},subtree:{}},nullInteraction:{meta:{types:{boolean:1},name:"nullInteraction",excludes:{},default:"false",products:{highmaps:1},description:"Whether to allow pointer interaction like tooltips and mouse events\non null points."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{}},subtree:{brightness:{meta:{types:{number:1},name:"brightness",excludes:{},default:.2},subtree:{}},halo:{meta:{types:{object:1},name:"halo",excludes:{},default:null},subtree:{}}}},normal:{meta:{types:{object:1},name:"normal",excludes:{}},subtree:{animation:{meta:{types:{boolean:1},name:"animation",excludes:{},default:!0},subtree:{}}}},select:{meta:{types:{object:1},name:"select",excludes:{}},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#cccccc"},subtree:{}}}}}},stickyTracking:{meta:{types:{boolean:1},name:"stickyTracking",excludes:{},default:!1},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{followPointer:{meta:{types:{boolean:1},name:"followPointer",excludes:{},default:!0},subtree:{}},pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:"{point.name}: {point.value}
    "},subtree:{}}}}}},mapbubble:{meta:{types:{object:1},name:"mapbubble",excludes:{},products:{highmaps:1},description:"A map bubble series is a bubble series laid out on top of a map series,\nwhere each bubble is tied to a specific map area.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `mapbubble` series are defined in\n [plotOptions.mapbubble](plotOptions.mapbubble).\n3. Options for one single series are given in\n [the series instance array](series.mapbubble).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        mapbubble: {\n            // shared options for all mapbubble series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'mapbubble'\n    }]\n});\n
    \n ",extends:"plotOptions.bubble"},subtree:{animationLimit:{meta:{types:{number:1},name:"animationLimit",excludes:{},default:500},subtree:{}},color:{meta:{types:{color:1},name:"color",excludes:{},products:{highmaps:1},description:"The main color of the series. This color affects both the fill and\nthe stroke of the bubble. For enhanced control, use `marker` options."},subtree:{}},displayNegative:{meta:{types:{boolean:1},name:"displayNegative",excludes:{},default:"true",products:{highmaps:1},description:"Whether to display negative sized bubbles. The threshold is given\nby the [zThreshold](#plotOptions.mapbubble.zThreshold) option, and\nnegative bubbles can be visualized by setting [negativeColor](\n#plotOptions.bubble.negativeColor)."},subtree:{}},maxSize:{meta:{types:{},name:"maxSize",excludes:{},products:{highmaps:1}},subtree:{}},minSize:{meta:{types:{},name:"minSize",excludes:{},products:{highmaps:1}},subtree:{}},negativeColor:{meta:{types:{color:1},name:"negativeColor",excludes:{},default:"null",products:{highmaps:1},description:"When a point's Z value is below the [zThreshold](\n#plotOptions.mapbubble.zThreshold) setting, this color is used."},subtree:{}},sizeBy:{meta:{types:{string:1},name:"sizeBy",excludes:{},default:"area",products:{highmaps:1},description:"Whether the bubble's value should be represented by the area or the\nwidth of the bubble. The default, `area`, corresponds best to the\nhuman perception of the size of each bubble."},subtree:{}},sizeByAbsoluteValue:{meta:{types:{boolean:1},name:"sizeByAbsoluteValue",excludes:{},default:"false",products:{highmaps:1},description:"When this is true, the absolute value of z determines the size of\nthe bubble. This means that with the default `zThreshold` of 0, a\nbubble of value -1 will have the same size as a bubble of value 1,\nwhile a bubble of value 0 will have a smaller size according to\n`minSize`."},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:"{point.name}: {point.z}"},subtree:{}}}},zMax:{meta:{types:{number:1},name:"zMax",excludes:{},default:"null",products:{highmaps:1},description:"The minimum for the Z value range. Defaults to the highest Z value\nin the data."},subtree:{}},zMin:{meta:{types:{number:1},name:"zMin",excludes:{},default:"null",products:{highmaps:1},description:"The minimum for the Z value range. Defaults to the lowest Z value\nin the data."},subtree:{}},zThreshold:{meta:{types:{number:1},name:"zThreshold",excludes:{},default:"0",products:{highmaps:1},description:"When [displayNegative](#plotOptions.mapbubble.displayNegative) is\n`false`, bubbles with lower Z values are skipped. When\n`displayNegative` is `true` and a [negativeColor](\n#plotOptions.mapbubble.negativeColor) is given, points with lower Z\nis colored."},subtree:{}}}},mapline:{meta:{types:{object:1},name:"mapline",excludes:{},products:{highmaps:1},description:"A mapline series is a special case of the map series where the value colors\nare applied to the strokes rather than the fills. It can also be used for\nfreeform drawing, like dividers, in the map.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `mapline` series are defined in\n [plotOptions.mapline](plotOptions.mapline).\n3. Options for one single series are given in\n [the series instance array](series.mapline).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        mapline: {\n            // shared options for all mapline series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'mapline'\n    }]\n});\n
    \n ",extends:"plotOptions.map"},subtree:{fillColor:{meta:{types:{color:1},name:"fillColor",excludes:{},default:"none",products:{highmaps:1},description:"Fill color for the map line shapes"},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:"1",products:{highmaps:1},description:"The width of the map line."},subtree:{}}}},mappoint:{meta:{types:{object:1},name:"mappoint",excludes:{},products:{highmaps:1},description:"A mappoint series is a special form of scatter series where the points can\nbe laid out in map coordinates on top of a map.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `mappoint` series are defined in\n [plotOptions.mappoint](plotOptions.mappoint).\n3. Options for one single series are given in\n [the series instance array](series.mappoint).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        mappoint: {\n            // shared options for all mappoint series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'mappoint'\n    }]\n});\n
    \n ",extends:"plotOptions.scatter"},subtree:{dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{}},subtree:{crop:{meta:{types:{boolean:1},name:"crop",excludes:{},default:!1},subtree:{}},defer:{meta:{types:{boolean:1},name:"defer",excludes:{},default:!1},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0},subtree:{}},format:{meta:{types:{string:1},name:"format",excludes:{},default:"{point.name}"},subtree:{}},formatter:{meta:{types:{},name:"formatter",excludes:{}},subtree:{}},overflow:{meta:{types:{boolean:1},name:"overflow",excludes:{},default:!1},subtree:{}},style:{meta:{types:{object:1},name:"style",excludes:{}},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#000000"},subtree:{}}}}}}}},mfi:{meta:{types:{object:1},name:"mfi",excludes:{},products:{highstock:1},description:"Money Flow Index. This series requires `linkedTo` option to be set and\nshould be loaded after the `stock/indicators/indicators.js` file.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `mfi` series are defined in\n [plotOptions.mfi](plotOptions.mfi).\n3. Options for one single series are given in\n [the series instance array](series.mfi).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        mfi: {\n            // shared options for all mfi series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'mfi'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{decimals:{meta:{types:{number:1},name:"decimals",excludes:{},default:4,products:{highstock:1},description:"Number of maximum decimals that are used in MFI calculations."},subtree:{}},period:{meta:{types:{number:1},name:"period",excludes:{},default:14},subtree:{}},volumeSeriesID:{meta:{types:{string:1},name:"volumeSeriesID",excludes:{},default:"volume",products:{highstock:1},description:"The id of volume series which is mandatory.\nFor example using OHLC data, volumeSeriesID='volume' means\nthe indicator will be calculated using OHLC and volume values."},subtree:{}}}}}},momentum:{meta:{types:{object:1},name:"momentum",excludes:{},products:{highstock:1},description:"Momentum. This series requires `linkedTo` option to be set.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `momentum` series are defined in\n [plotOptions.momentum](plotOptions.momentum).\n3. Options for one single series are given in\n [the series instance array](series.momentum).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        momentum: {\n            // shared options for all momentum series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'momentum'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{period:{meta:{types:{number:1},name:"period",excludes:{},default:14},subtree:{}}}}}},ohlc:{meta:{types:{object:1},name:"ohlc",excludes:{},products:{highstock:1},description:"An OHLC chart is a style of financial chart used to describe price\nmovements over time. It displays open, high, low and close values per data\npoint.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `ohlc` series are defined in\n [plotOptions.ohlc](plotOptions.ohlc).\n3. Options for one single series are given in\n [the series instance array](series.ohlc).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        ohlc: {\n            // shared options for all ohlc series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'ohlc'\n    }]\n});\n
    \n ",extends:"plotOptions.column"},subtree:{dataGrouping:{meta:{types:{object:1},name:"dataGrouping",excludes:{}},subtree:{groupPixelWidth:{meta:{types:{number:1},name:"groupPixelWidth",excludes:{},default:"5",products:{highstock:1},description:"The approximate pixel width of each group. If for example a series\nwith 30 points is displayed over a 600 pixel wide plot area, no grouping\nis performed. If however the series contains so many points that\nthe spacing is less than the groupPixelWidth, Highcharts will try\nto group it into appropriate groups so that each is more or less\ntwo pixels wide. Defaults to `5`."},subtree:{}}}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:"1",products:{highstock:1},description:"The pixel width of the line/border. Defaults to `1`."},subtree:{}},pointValKey:{meta:{types:{string:1},name:"pointValKey",excludes:{},default:"close",products:{highstock:1},description:"Determines which one of `open`, `high`, `low`, `close` values should be\nrepresented as `point.y`, which is later used to set dataLabel position."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{},products:{highstock:1},extends:"plotOptions.column.states.hover"},subtree:{lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:"3",products:{highstock:1},description:"The pixel width of the line representing the OHLC point."},subtree:{}}}}}},stickyTracking:{meta:{types:{boolean:1},name:"stickyTracking",excludes:{},default:!0},subtree:{}},threshold:{meta:{types:{object:1},name:"threshold",excludes:{},default:null},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:' {series.name}
    Open: {point.open}
    High: {point.high}
    Low: {point.low}
    Close: {point.close}
    '},subtree:{}}}},upColor:{meta:{types:{color:1},name:"upColor",excludes:{},products:{highstock:1},description:"Line color for up points."},subtree:{}}}},pareto:{meta:{types:{object:1},name:"pareto",excludes:{},products:{highcharts:1},description:"A pareto diagram is a type of chart that contains both bars and a line graph,\nwhere individual values are represented in descending order by bars,\nand the cumulative total is represented by the line.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `pareto` series are defined in\n [plotOptions.pareto](plotOptions.pareto).\n3. Options for one single series are given in\n [the series instance array](series.pareto).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        pareto: {\n            // shared options for all pareto series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'pareto'\n    }]\n});\n
    \n ",extends:"plotOptions.line"},subtree:{zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},default:3,description:"Higher zIndex than column series to draw line above shapes."},subtree:{}}}},pie:{meta:{types:{object:1},name:"pie",excludes:{},products:{highcharts:1},description:"A pie chart is a circular graphic which is divided into slices to illustrate\nnumerical proportion.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `pie` series are defined in\n [plotOptions.pie](plotOptions.pie).\n3. Options for one single series are given in\n [the series instance array](series.pie).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        pie: {\n            // shared options for all pie series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'pie'\n    }]\n});\n
    \n ",extends:"plotOptions.line"},subtree:{borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},default:"#ffffff",products:{highcharts:1},description:"The color of the border surrounding each slice. When `null`, the\nborder takes the same color as the slice fill. This can be used\ntogether with a `borderWidth` to fill drawing gaps created by\nantialiazing artefacts in borderless pies.\n\nIn styled mode, the border stroke is given in the `.highcharts-point`\nclass."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:"1",products:{highcharts:1},description:"The width of the border surrounding each slice.\n\nWhen setting the border width to 0, there may be small gaps between\nthe slices due to SVG antialiasing artefacts. To work around this,\nkeep the border width at 0.5 or 1, but set the `borderColor` to\n`null` instead.\n\nIn styled mode, the border stroke width is given in the\n`.highcharts-point` class." },subtree:{}},center:{meta:{types:{array:"(String|Number)"},name:"center",excludes:{},default:"[null, null]",products:{highcharts:1},description:'The center of the pie chart relative to the plot area. Can be percentages\nor pixel values. The default behaviour (as of 3.0) is to center\nthe pie so that all slices and data labels are within the plot area.\nAs a consequence, the pie may actually jump around in a chart with\ndynamic values, as the data labels move. In that case, the center\nshould be explicitly set, for example to `["50%", "50%"]`.'},subtree:{}},clip:{meta:{types:{boolean:1},name:"clip",excludes:{},default:!1},subtree:{}},colors:{meta:{types:{array:"Color"},name:"colors",excludes:{},products:{highcharts:1},description:"A series specific or series type specific color set to use instead\nof the global [colors](#colors)."},subtree:{}},dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{},products:{highcharts:1},extends:"plotOptions.series.dataLabels"},subtree:{allowOverlap:{meta:{types:{boolean:1},name:"allowOverlap",excludes:{},default:!0},subtree:{}},connectorColor:{meta:{types:{string:1},name:"connectorColor",excludes:{},default:"{point.color}",products:{highcharts:1},description:"The color of the line connecting the data label to the pie slice.\nThe default color is the same as the point's color.\n\nIn styled mode, the connector stroke is given in the\n`.highcharts-data-label-connector` class."},subtree:{}},connectorPadding:{meta:{types:{number:1},name:"connectorPadding",excludes:{},default:"5",products:{highcharts:1},description:"The distance from the data label to the connector."},subtree:{}},connectorWidth:{meta:{types:{number:1},name:"connectorWidth",excludes:{},default:"1",products:{highcharts:1},description:"The width of the line connecting the data label to the pie slice.\n\n\nIn styled mode, the connector stroke width is given in the\n`.highcharts-data-label-connector` class."},subtree:{}},distance:{meta:{types:{number:1},name:"distance",excludes:{},default:"30",products:{highcharts:1},description:"The distance of the data label from the pie's edge. Negative numbers\nput the data label on top of the pie slices. Connectors are only\nshown for data labels outside the pie."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0,products:{highcharts:1},description:"Enable or disable the data labels."},subtree:{}},formatter:{meta:{types:{},name:"formatter",excludes:{}},subtree:{}},softConnector:{meta:{types:{number:1},name:"softConnector",excludes:{},products:{highcharts:1},description:"Whether to render the connector as a soft arc or a line with sharp\nbreak."},subtree:{}},style:{meta:{types:{},name:"style",excludes:{}},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:0},subtree:{}}}},depth:{meta:{types:{number:1},name:"depth",excludes:{},default:"0",products:{highcharts:1},description:"The thickness of a 3D pie. Requires `highcharts-3d.js`"},subtree:{}},endAngle:{meta:{types:{number:1},name:"endAngle",excludes:{},default:"null",products:{highcharts:1},description:"The end angle of the pie in degrees where 0 is top and 90 is right.\nDefaults to `startAngle` plus 360."},subtree:{}},events:{meta:{types:{object:1},name:"events",excludes:{}},subtree:{checkboxClick:{meta:{types:{function:1},name:"checkboxClick",excludes:{},products:{highcharts:1},description:"Fires when the checkbox next to the point name in the legend is clicked.\nOne parameter, event, is passed to the function. The state of the\ncheckbox is found by event.checked. The checked item is found by\nevent.item. Return false to prevent the default action which is to\ntoggle the select state of the series."},subtree:{}},legendItemClick:{meta:{types:{function:1},name:"legendItemClick",excludes:{},products:{highcharts:1},description:"Not applicable to pies, as the legend item is per point. See point.\nevents."},subtree:{}}}},ignoreHiddenPoint:{meta:{types:{boolean:1},name:"ignoreHiddenPoint",excludes:{},default:"true",products:{highcharts:1},description:"Equivalent to [chart.ignoreHiddenSeries](#chart.ignoreHiddenSeries),\nthis option tells whether the series shall be redrawn as if the\nhidden point were `null`.\n\nThe default value changed from `false` to `true` with Highcharts\n3.0."},subtree:{}},innerSize:{meta:{types:{number:1,string:1},name:"innerSize",excludes:{},default:"0",products:{highcharts:1},description:"The size of the inner diameter for the pie. A size greater than 0\nrenders a donut chart. Can be a percentage or pixel value. Percentages\nare relative to the pie size. Pixel values are given as integers.\n\n\nNote: in Highcharts < 4.1.2, the percentage was relative to the plot\narea, not the pie size."},subtree:{}},minSize:{meta:{types:{number:1},name:"minSize",excludes:{},default:"80",products:{highcharts:1},description:"The minimum size for a pie in response to auto margins. The pie will\ntry to shrink to make room for data labels in side the plot area,\n but only to this size."},subtree:{}},point:{meta:{types:{object:1},name:"point",excludes:{}},subtree:{events:{meta:{types:{object:1},name:"events",excludes:{}},subtree:{legendItemClick:{meta:{types:{function:1},name:"legendItemClick",excludes:{},products:{highcharts:1},description:"Fires when the legend item belonging to the pie point (slice) is\nclicked. The `this` keyword refers to the point itself. One parameter,\n`event`, is passed to the function, containing common event information. The\ndefault action is to toggle the visibility of the point. This can be\nprevented by calling `event.preventDefault()`."},subtree:{}}}}}},showInLegend:{meta:{types:{boolean:1},name:"showInLegend",excludes:{},default:!1,products:{highcharts:1},description:"Whether to display this particular series or series type in the\nlegend. Since 2.1, pies are not shown in the legend by default."},subtree:{}},size:{meta:{types:{number:1,string:1},name:"size",excludes:{},default:null,products:{highcharts:1},description:'The diameter of the pie relative to the plot area. Can be a percentage\nor pixel value. Pixel values are given as integers. The default\nbehaviour (as of 3.0) is to scale to the plot area and give room\nfor data labels within the plot area.\n[slicedOffset](#plotOptions.pie.slicedOffset) is also included\nin the default size calculation. As a consequence, the size\nof the pie may vary when points are updated and data labels more\naround. In that case it is best to set a fixed value, for example\n`"75%"`.'},subtree:{}},slicedOffset:{meta:{types:{number:1},name:"slicedOffset",excludes:{},default:"10",products:{highcharts:1},description:"If a point is sliced, moved out from the center, how many pixels\nshould it be moved?."},subtree:{}},startAngle:{meta:{types:{number:1},name:"startAngle",excludes:{},default:"0",products:{highcharts:1},description:"The start angle of the pie slices in degrees where 0 is top and 90\nright."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{},products:{highcharts:1},extends:"plotOptions.series.states.hover"},subtree:{brightness:{meta:{types:{number:1},name:"brightness",excludes:{},default:.1,products:{highcharts:1},description:"How much to brighten the point on interaction. Requires the main\ncolor to be defined in hex or rgb(a) format.\n\nIn styled mode, the hover brightness is by default replaced\nby a fill-opacity given in the `.highcharts-point-hover` class."},subtree:{}}}}}},stickyTracking:{meta:{types:{boolean:1},name:"stickyTracking",excludes:{},default:!1,products:{highcharts:1},description:"Sticky tracking of mouse events. When true, the `mouseOut` event\non a series isn't triggered until the mouse moves over another series,\nor out of the plot area. When false, the `mouseOut` event on a\nseries is triggered when the mouse leaves the area around the series'\ngraph or markers. This also implies the tooltip. When `stickyTracking`\nis false and `tooltip.shared` is false, the tooltip will be hidden\nwhen moving the mouse between series."},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{followPointer:{meta:{types:{boolean:1},name:"followPointer",excludes:{},default:!0},subtree:{}}}}}},pivotpoints:{meta:{types:{object:1},name:"pivotpoints",excludes:{},products:{highstock:1},description:"Pivot points indicator. This series requires the `linkedTo` option to be\rset and should be loaded after `stock/indicators/indicators.js` file.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `pivotpoints` series are defined in\n [plotOptions.pivotpoints](plotOptions.pivotpoints).\n3. Options for one single series are given in\n [the series instance array](series.pivotpoints).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        pivotpoints: {\n            // shared options for all pivotpoints series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'pivotpoints'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{dataGrouping:{meta:{types:{object:1},name:"dataGrouping",excludes:{}},subtree:{approximation:{meta:{types:{string:1},name:"approximation",excludes:{},default:"averages"},subtree:{}}}},dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0},subtree:{}},format:{meta:{types:{string:1},name:"format",excludes:{},default:"{point.pivotLine}"},subtree:{}}}},enableMouseTracking:{meta:{types:{boolean:1},name:"enableMouseTracking",excludes:{},default:!1},subtree:{}},marker:{meta:{types:{object:1},name:"marker",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1},subtree:{}}}},params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{algorithm:{meta:{types:{string:1},name:"algorithm",excludes:{},default:"standard",products:{highstock:1},description:"Algorithm used to calculate ressistance and support lines based\ron pivot points. Implemented algorithms: `'standard'`,\r`'fibonacci'` and `'camarilla'`"},subtree:{}},period:{meta:{types:{number:1},name:"period",excludes:{},default:28},subtree:{}}}}}},polygon:{meta:{types:{object:1},name:"polygon",excludes:{},products:{highcharts:1,highstock:1},description:"A polygon series can be used to draw any freeform shape in the cartesian\ncoordinate system. A fill is applied with the `color` option, and\nstroke is applied through `lineWidth` and `lineColor` options. Requires\nthe `highcharts-more.js` file.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `polygon` series are defined in\n [plotOptions.polygon](plotOptions.polygon).\n3. Options for one single series are given in\n [the series instance array](series.polygon).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        polygon: {\n            // shared options for all polygon series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'polygon'\n    }]\n});\n
    \n ",extends:"plotOptions.scatter"},subtree:{marker:{meta:{types:{object:1},name:"marker",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1},subtree:{}}}}}}}},stickyTracking:{meta:{types:{boolean:1},name:"stickyTracking",excludes:{},default:!1},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{followPointer:{meta:{types:{boolean:1},name:"followPointer",excludes:{},default:!0},subtree:{}},pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:""},subtree:{}}}},trackByArea:{meta:{types:{boolean:1},name:"trackByArea",excludes:{},default:!0},subtree:{}}}},priceenvelopes:{meta:{types:{object:1},name:"priceenvelopes",excludes:{},products:{highstock:1},description:"Price envelopes indicator based on [SMA](#plotOptions.sma) calculations.\rThis series requires the `linkedTo` option to be set and should be loaded\rafter the `stock/indicators/indicators.js` file.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `priceenvelopes` series are defined in\n [plotOptions.priceenvelopes](plotOptions.priceenvelopes).\n3. Options for one single series are given in\n [the series instance array](series.priceenvelopes).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        priceenvelopes: {\n            // shared options for all priceenvelopes series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'priceenvelopes'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{bottomLine:{meta:{types:{object:1},name:"bottomLine",excludes:{},products:{highstock:1},description:"Bottom line options."},subtree:{styles:{meta:{types:{object:1},name:"styles",excludes:{}},subtree:{lineColor:{meta:{types:{string:1},name:"lineColor",excludes:{},products:{highstock:1},description:"Color of the line. If not set, it's inherited from\r[plotOptions.priceenvelopes.color](\r#plotOptions.priceenvelopes.color)."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highstock:1},description:"Pixel width of the line."},subtree:{}}}}}},dataGrouping:{meta:{types:{object:1},name:"dataGrouping",excludes:{}},subtree:{approximation:{meta:{types:{string:1},name:"approximation",excludes:{},default:"averages"},subtree:{}}}},marker:{meta:{types:{object:1},name:"marker",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1},subtree:{}}}},params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{bottomBand:{meta:{types:{number:1},name:"bottomBand",excludes:{},default:.1,products:{highstock:1},description:"Percentage below the moving average that should be displayed.\r0.1 means 90%. Relative to the calculated value."},subtree:{}},period:{meta:{types:{number:1},name:"period",excludes:{},default:20},subtree:{}},topBand:{meta:{types:{number:1},name:"topBand",excludes:{},default:.1,products:{highstock:1},description:"Percentage above the moving average that should be displayed.\r0.1 means 110%. Relative to the calculated value."},subtree:{}}}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:' {series.name}
    Top: {point.top}
    Middle: {point.middle}
    Bottom: {point.bottom}
    '},subtree:{}}}},topLine:{meta:{types:{object:1},name:"topLine",excludes:{},products:{highstock:1},description:"Top line options.",extends:"plotOptions.priceenvelopes.bottomLine"},subtree:{styles:{meta:{types:{object:1},name:"styles",excludes:{}},subtree:{lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1},subtree:{}}}}}}}},psar:{meta:{types:{object:1},name:"psar",excludes:{},products:{highstock:1},description:"Parabolic SAR. This series requires `linkedTo`\roption to be set and should be loaded\rafter `stock/indicators/indicators.js` file.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `psar` series are defined in\n [plotOptions.psar](plotOptions.psar).\n3. Options for one single series are given in\n [the series instance array](series.psar).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        psar: {\n            // shared options for all psar series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'psar'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:0},subtree:{}},marker:{meta:{types:{object:1},name:"marker",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0},subtree:{}}}},params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{decimals:{meta:{types:{number:1},name:"decimals",excludes:{},default:4,products:{highstock:1},description:"Number of maximum decimals that are used in PSAR calculations."},subtree:{}},increment:{meta:{types:{number:1},name:"increment",excludes:{},default:.02,products:{highstock:1},description:"Acceleration factor increases by increment each time\rthe extreme point makes a new high."},subtree:{}},index:{meta:{types:{number:1},name:"index",excludes:{},default:2,products:{highstock:1},description:"Index from which PSAR is starting calculation"},subtree:{}},initialAccelerationFactor:{meta:{types:{number:1},name:"initialAccelerationFactor",excludes:{},default:.02,products:{highstock:1},description:"The initial value for acceleration factor.\rAcceleration factor is starting with this value\rand increases by specified increment each time\rthe extreme point makes a new high.\rAF can reach a maximum of maxAccelerationFactor,\rno matter how long the uptrend extends."},subtree:{}},maxAccelerationFactor:{meta:{types:{number:1},name:"maxAccelerationFactor",excludes:{},default:.2,products:{highstock:1},description:"The Maximum value for acceleration factor.\rAF can reach a maximum of maxAccelerationFactor,\rno matter how long the uptrend extends."},subtree:{}}}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{}},subtree:{lineWidthPlus:{meta:{types:{number:1},name:"lineWidthPlus",excludes:{},default:0},subtree:{}}}}}}}},pyramid:{meta:{types:{object:1},name:"pyramid",excludes:{},products:{highcharts:1},description:"A pyramid series is a special type of funnel, without neck and reversed by\ndefault.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `pyramid` series are defined in\n [plotOptions.pyramid](plotOptions.pyramid).\n3. Options for one single series are given in\n [the series instance array](series.pyramid).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        pyramid: {\n            // shared options for all pyramid series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'pyramid'\n    }]\n});\n
    \n ",extends:"plotOptions.funnel"},subtree:{neckHeight:{meta:{types:{string:1},name:"neckHeight",excludes:{},default:"0%",products:{highcharts:1},description:"The pyramid neck width is zero by default, as opposed to the funnel,\nwhich shares the same layout logic."},subtree:{}},neckWidth:{meta:{types:{string:1},name:"neckWidth",excludes:{},default:"0%",products:{highcharts:1},description:"The pyramid neck width is zero by default, as opposed to the funnel,\nwhich shares the same layout logic."},subtree:{}},reversed:{meta:{types:{boolean:1},name:"reversed",excludes:{},default:!0,products:{highcharts:1},description:"The pyramid is reversed by default, as opposed to the funnel, which\nshares the layout engine, and is not reversed."},subtree:{}}}},roc:{meta:{types:{object:1},name:"roc",excludes:{},products:{highstock:1},description:"Rate of change indicator (ROC). The indicator value for each point\nis defined as:\n\n`(C - Cn) / Cn * 100`\n\nwhere: `C` is the close value of the point of the same x in the\nlinked series and `Cn` is the close value of the point `n` periods\nago. `n` is set through [period](#plotOptions.roc.params.period).\n\nThis series requires `linkedTo` option to be set.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `roc` series are defined in\n [plotOptions.roc](plotOptions.roc).\n3. Options for one single series are given in\n [the series instance array](series.roc).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        roc: {\n            // shared options for all roc series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'roc'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{index:{meta:{types:{number:1},name:"index",excludes:{},default:3},subtree:{}},period:{meta:{types:{number:1},name:"period",excludes:{},default:9},subtree:{}}}}}},rsi:{meta:{types:{object:1},name:"rsi",excludes:{},products:{highstock:1},description:"Relative strength index (RSI) technical indicator. This series\nrequires the `linkedTo` option to be set and should be loaded after\nthe `stock/indicators/indicators.js` file.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `rsi` series are defined in\n [plotOptions.rsi](plotOptions.rsi).\n3. Options for one single series are given in\n [the series instance array](series.rsi).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        rsi: {\n            // shared options for all rsi series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'rsi'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{decimals:{meta:{types:{number:1},name:"decimals",excludes:{},default:4,products:{highstock:1},description:"Number of maximum decimals that are used in RSI calculations."},subtree:{}},period:{meta:{types:{number:1},name:"period",excludes:{},default:14},subtree:{}}}}}},sankey:{meta:{types:{object:1},name:"sankey",excludes:{},products:{highcharts:1},description:"A sankey diagram is a type of flow diagram, in which the width of the\nlink between two nodes is shown proportionally to the flow quantity.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `sankey` series are defined in\n [plotOptions.sankey](plotOptions.sankey).\n3. Options for one single series are given in\n [the series instance array](series.sankey).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        sankey: {\n            // shared options for all sankey series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'sankey'\n    }]\n});\n
    \n ",extends:"{plotOptions.column}"},subtree:{colorByPoint:{meta:{types:{boolean:1},name:"colorByPoint",excludes:{},default:!0},subtree:{}},curveFactor:{meta:{types:{number:1},name:"curveFactor",excludes:{},default:.33,description:"Higher numbers makes the links in a sankey diagram render more curved.\nA `curveFactor` of 0 makes the lines straight."},subtree:{}},dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{},description:"Options for the data labels appearing on top of the nodes and links. For\nsankey charts, data labels are visible for the nodes by default, but\nhidden for links. This is controlled by modifying the `nodeFormat`, and\nthe `format` that applies to links and is an empty string by default."},subtree:{backgroundColor:{meta:{types:{string:1},name:"backgroundColor",excludes:{},default:"none"},subtree:{}},crop:{meta:{types:{boolean:1},name:"crop",excludes:{},default:!1},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0},subtree:{}},format:{meta:{types:{},name:"format",excludes:{},description:"The [format string](https://www.highcharts.com/docs/chart-\nconcepts/labels-and-string-formatting) specifying what to show for\n_links_ in the sankey diagram. Defaults to an empty string returned\nfrom the `formatter`, in effect disabling the labels."},subtree:{}},formatter:{meta:{types:{},name:"formatter",excludes:{},description:"Callback to format data labels for _links_ in the sankey diagram.\nThe `format` option takes precedence over the `formatter`."},subtree:{}},inside:{meta:{types:{boolean:1},name:"inside",excludes:{},default:!0},subtree:{}},nodeFormat:{meta:{types:{string:1},name:"nodeFormat",excludes:{},description:"The [format string](https://www.highcharts.com/docs/chart-\nconcepts/labels-and-string-formatting) specifying what to show\nfor _nodes_ in the sankey diagram. By default the\n`nodeFormatter` returns `{point.name}`."},subtree:{}},nodeFormatter:{meta:{types:{function:1},name:"nodeFormatter",excludes:{},description:"Callback to format data labels for _nodes_ in the sankey diagram.\nThe `nodeFormat` option takes precedence over the `nodeFormatter`."},subtree:{}}}},linkOpacity:{meta:{types:{number:1},name:"linkOpacity",excludes:{},default:.5,description:"Opacity for the links between nodes in the sankey diagram."},subtree:{}},nodePadding:{meta:{types:{number:1},name:"nodePadding",excludes:{},default:10,description:"The padding between nodes in a sankey diagram, in pixels."},subtree:{}},nodeWidth:{meta:{types:{number:1},name:"nodeWidth",excludes:{},default:20,description:"The pixel width of each node in a sankey diagram, or the height in case\nthe chart is inverted."},subtree:{}},showInLegend:{meta:{types:{boolean:1},name:"showInLegend",excludes:{},default:!1},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{}},subtree:{linkOpacity:{meta:{types:{number:1},name:"linkOpacity",excludes:{},default:1,description:"Opacity for the links between nodes in the sankey diagram in\nhover mode."},subtree:{}}}}}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{followPointer:{meta:{types:{boolean:1},name:"followPointer",excludes:{},default:!0,description:"Whether the tooltip should follow the pointer or stay fixed on the\nitem."},subtree:{}},headerFormat:{meta:{types:{string:1},name:"headerFormat",excludes:{},default:'{series.name}
    '},subtree:{}},nodeFormat:{meta:{types:{string:1},name:"nodeFormat",excludes:{},default:"{point.name}: {point.sum}
    ",description:"The [format string](https://www.highcharts.com/docs/chart-\nconcepts/labels-and-string-formatting) specifying what to\nshow for _nodes_ in tooltip\nof a sankey diagram series, as opposed to links."},subtree:{}},nodeFormatter:{meta:{types:{function:1},name:"nodeFormatter",excludes:{},description:"A callback for defining the format for _nodes_ in the sankey chart's\ntooltip, as opposed to links."},subtree:{}},pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:"{point.fromNode.name} → {point.toNode.name}: {point.weight}
    "},subtree:{}}}}}},scatter:{meta:{types:{object:1},name:"scatter",excludes:{},products:{highcharts:1,highstock:1},description:"A scatter plot uses cartesian coordinates to display values for two variables\nfor a set of data.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `scatter` series are defined in\n [plotOptions.scatter](plotOptions.scatter).\n3. Options for one single series are given in\n [the series instance array](series.scatter).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        scatter: {\n            // shared options for all scatter series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'scatter'\n    }]\n});\n
    \n ",extends:"{plotOptions.line}"},subtree:{findNearestPointBy:{meta:{types:{string:1},name:"findNearestPointBy",excludes:{},default:"xy"},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:0,products:{highcharts:1,highstock:1},description:"The width of the line connecting the data points."},subtree:{}},marker:{meta:{types:{object:1},name:"marker",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0},subtree:{}}}},stickyTracking:{meta:{types:{boolean:1},name:"stickyTracking",excludes:{},default:"false",products:{highcharts:1,highstock:1},description:"Sticky tracking of mouse events. When true, the `mouseOut` event\non a series isn't triggered until the mouse moves over another series,\nor out of the plot area. When false, the `mouseOut` event on a series\nis triggered when the mouse leaves the area around the series' graph\nor markers. This also implies the tooltip. When `stickyTracking`\nis false and `tooltip.shared` is false, the tooltip will be hidden\nwhen moving the mouse between series."},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{},products:{highcharts:1,highstock:1},description:"A configuration object for the tooltip rendering of each single\nseries. Properties are inherited from [tooltip](#tooltip).\nOverridable properties are `headerFormat`, `pointFormat`, `yDecimals`,\n`xDateFormat`, `yPrefix` and `ySuffix`. Unlike other series, in\na scatter plot the series.name by default shows in the headerFormat\nand point.x and point.y in the pointFormat."},subtree:{headerFormat:{meta:{types:{string:1},name:"headerFormat",excludes:{},default:' {series.name}
    '},subtree:{}},pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:"x: {point.x}
    y: {point.y}
    "},subtree:{}}}}}},scatter3d:{meta:{types:{object:1},name:"scatter3d",excludes:{},products:{highcharts:1},description:"A 3D scatter plot uses x, y and z coordinates to display values for three\nvariables for a set of data.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `scatter3d` series are defined in\n [plotOptions.scatter3d](plotOptions.scatter3d).\n3. Options for one single series are given in\n [the series instance array](series.scatter3d).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        scatter3d: {\n            // shared options for all scatter3d series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'scatter3d'\n    }]\n});\n
    \n ",extends:"plotOptions.scatter"},subtree:{tooltip:{meta:{types:{object:1 },name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:"x: {point.x}
    y: {point.y}
    z: {point.z}
    "},subtree:{}}}}}},series:{meta:{types:{object:1},name:"series",excludes:{},description:"General options for all series types.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `line` series are defined in\n [plotOptions.line](plotOptions.line).\n3. Options for one single series are given in\n [the series instance array](series.line).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        line: {\n            // shared options for all line series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'line'\n    }]\n});\n
    \n "},subtree:{allAreas:{meta:{types:{boolean:1},name:"allAreas",excludes:{},default:"true",products:{highmaps:1},description:"Whether all areas of the map defined in `mapData` should be rendered.\nIf `true`, areas which don't correspond to a data point, are rendered\nas `null` points. If `false`, those areas are skipped."},subtree:{}},allowPointSelect:{meta:{types:{boolean:1},name:"allowPointSelect",excludes:{},default:"false",description:"If true, a checkbox is displayed next to the legend item to allow\nselecting the series. The state of the checkbox is determined by\nthe `selected` option."},subtree:{}},animation:{meta:{types:{"highcharts.animationoptionsobject":1,boolean:1},name:"animation",excludes:{},description:"Enable or disable the initial animation when a series is displayed.\nThe animation can also be set as a configuration object. Please\nnote that this option only applies to the initial animation of the\nseries itself. For other animations, see [chart.animation](\n#chart.animation) and the animation parameter under the API methods. The\nfollowing properties are supported:\n\n
    \n\n
    duration
    \n\n
    The duration of the animation in milliseconds.
    \n\n
    easing
    \n\n
    Can be a string reference to an easing function set on the `Math`\nobject or a function. See the _Custom easing function_ demo below.
    \n\n
    \n\nDue to poor performance, animation is disabled in old IE browsers\nfor several chart types."},subtree:{duration:{meta:{types:{number:1},name:"duration",excludes:{},default:1e3},subtree:{}}}},animationLimit:{meta:{types:{number:1},name:"animationLimit",excludes:{},description:"For some series, there is a limit that shuts down initial animation\nby default when the total number of points in the chart is too high.\nFor example, for a column chart and its derivatives, animation doesn't\nrun if there is more than 250 points totally. To disable this cap, set\n`animationLimit` to `Infinity`."},subtree:{}},boostThreshold:{meta:{types:{number:1},name:"boostThreshold",excludes:{},default:"5000",description:"Set the point threshold for when a series should enter boost mode.\n\nSetting it to e.g. 2000 will cause the series to enter boost mode when there\nare 2000 or more points in the series.\n\nTo disable boosting on the series, set the `boostThreshold` to 0. Setting it\nto 1 will force boosting.\n\nRequires `modules/boost.js`."},subtree:{}},borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},default:"#cccccc",products:{highcharts:1,highmaps:1},description:"The border color of the map areas.\n\nIn styled mode, the border stroke is given in the `.highcharts-point`\nclass."},subtree:{}},borderWidth:{meta:{types:{},name:"borderWidth",excludes:{},products:{highcharts:1,highmaps:1},description:"The border width of each map area.\n\nIn styled mode, the border stroke width is given in the\n`.highcharts-point` class."},subtree:{}},className:{meta:{types:{string:1},name:"className",excludes:{},description:"An additional class name to apply to the series' graphical elements. This\noption does not replace default class names of the graphical element."},subtree:{}},clip:{meta:{types:{boolean:1},name:"clip",excludes:{},default:"true",description:"Disable this option to allow series rendering in the whole plotting\narea.\n\n**Note:** Clipping should be always enabled when\n[chart.zoomType](#chart.zoomType) is set"},subtree:{}},color:{meta:{types:{"highcharts.colorstring":1},name:"color",excludes:{},description:"The main color of the series. In line type series it applies to the\nline and the point markers unless otherwise specified. In bar type\nseries it applies to the bars unless a color is specified per point.\nThe default value is pulled from the `options.colors` array.\n\nIn styled mode, the color can be defined by the\n[colorIndex](#plotOptions.series.colorIndex) option. Also, the series\ncolor can be set with the `.highcharts-series`, `.highcharts-color-{n}`,\n`.highcharts-{type}-series` or `.highcharts-series-{n}` class, or\nindividual classes given by the `className` option."},subtree:{}},colorAxis:{meta:{types:{boolean:1},name:"colorAxis",excludes:{},default:"undefined",products:{highmaps:1},description:"Set this option to `false` to prevent a series from connecting to\nthe global color axis. This will cause the series to have its own\nlegend item."},subtree:{}},colorIndex:{meta:{types:{number:1},name:"colorIndex",excludes:{},description:"Styled mode only. A specific color index to use for the series, so its\ngraphic representations are given the class name `highcharts-color-{n}`."},subtree:{}},compare:{meta:{types:{string:1},name:"compare",excludes:{},default:"undefined",products:{highstock:1},description:'Compare the values of the series against the first non-null, non-\nzero value in the visible range. The y axis will show percentage\nor absolute change depending on whether `compare` is set to `"percent"`\nor `"value"`. When this is applied to multiple series, it allows\ncomparing the development of the series against each other. Adds\na `change` field to every point object.'},subtree:{}},compareBase:{meta:{types:{number:1},name:"compareBase",excludes:{},default:"0",products:{highstock:1},description:"When [compare](#plotOptions.series.compare) is `percent`, this option\ndictates whether to use 0 or 100 as the base of comparison."},subtree:{}},compareStart:{meta:{types:{boolean:1},name:"compareStart",excludes:{},default:"false",products:{highstock:1},description:"Defines if comparison should start from the first point within the visible\nrange or should start from the first point before the range.\nIn other words, this flag determines if first point within the visible range\nwill have 0% (`compareStart=true`) or should have been already calculated\naccording to the previous point (`compareStart=false`)."},subtree:{}},connectEnds:{meta:{types:{boolean:1},name:"connectEnds",excludes:{},products:{highcharts:1},description:"Polar charts only. Whether to connect the ends of a line series\nplot across the extremes."},subtree:{}},connectNulls:{meta:{types:{boolean:1},name:"connectNulls",excludes:{},default:"false",products:{highcharts:1,highstock:1},description:"Whether to connect a graph line across null points, or render a gap\nbetween the two points on either side of the null."},subtree:{}},cropThreshold:{meta:{types:{number:1},name:"cropThreshold",excludes:{},default:"300",products:{highcharts:1,highstock:1},description:"When the series contains less points than the crop threshold, all\npoints are drawn, even if the points fall outside the visible plot\narea at the current zoom. The advantage of drawing all points (including\nmarkers and columns), is that animation is performed on updates.\nOn the other hand, when the series contains more points than the\ncrop threshold, the series data is cropped to only contain points\nthat fall within the plot area. The advantage of cropping away invisible\npoints is to increase performance on large series."},subtree:{}},cursor:{meta:{types:{string:1},name:"cursor",excludes:{},description:'You can set the cursor to "pointer" if you have click events attached\nto the series, to signal to the user that the points and lines can\nbe clicked.\n\nPossible values are: `"default"`, `"help"`, `"none"`, `"pointer"`, and\n`"crosshair"`.\n\nIn styled mode, the series cursor can be set with the same classes\nas listed under [series.color](#plotOptions.series.color).'},subtree:{}},dashStyle:{meta:{types:{string:1},name:"dashStyle",excludes:{},default:"Solid",description:'A name for the dash style to use for the graph, or for some series types\nthe outline of each shape. The value for the `dashStyle` include:\n`"Dash"`, `"DashDot"`, `"Dot"`, `"LongDash"`, `"LongDashDot"`,\n`"LongDashDotDot"`, `"ShortDash"`, `"ShortDashDot"`, `"ShortDashDotDot"`,\n`"ShortDot"`, and `"Solid"`.\n\nIn styled mode, the [stroke dash-array](https://jsfiddle.net/gh/get/\nlibrary/pure/highcharts/highcharts/tree/master/samples/highcharts/css/\nseries-dashstyle/) can be set with the same classes as listed under\n[series.color](#plotOptions.series.color).'},subtree:{}},dataGrouping:{meta:{types:{object:1},name:"dataGrouping",excludes:{},products:{highstock:1},description:"Data grouping is the concept of sampling the data values into larger\nblocks in order to ease readability and increase performance of the\nJavaScript charts. Highstock by default applies data grouping when\nthe points become closer than a certain pixel value, determined by\nthe `groupPixelWidth` option.\n\nIf data grouping is applied, the grouping information of grouped\npoints can be read from the [Point.dataGroup](\n/class-reference/Highcharts.Point#.dataGroup)."},subtree:{approximation:{meta:{types:{string:1,function:1},name:"approximation",excludes:{},products:{highstock:1},description:'The method of approximation inside a group. When for example 30 days\nare grouped into one month, this determines what value should represent\nthe group. Possible values are "average", "averages", "open", "high",\n"low", "close" and "sum". For OHLC and candlestick series the approximation\nis "ohlc" by default, which finds the open, high, low and close values\nwithin all the grouped data. For ranges, the approximation is "range",\nwhich finds the low and high values. For multi-dimensional data,\nlike ranges and OHLC, "averages" will compute the average for each\ndimension.\n\nCustom aggregate methods can be added by assigning a callback function\nas the approximation. This function takes a numeric array as the\nargument and should return a single numeric value or `null`. Note\nthat the numeric array will never contain null values, only true\nnumbers. Instead, if null values are present in the raw data, the\nnumeric array will have an `.hasNulls` property set to `true`. For\nsingle-value data sets the data is available in the first argument\nof the callback function. For OHLC data sets, all the open values\nare in the first argument, all high values in the second etc.\n\nSince v4.2.7, grouping meta data is available in the approximation\ncallback from `this.dataGroupInfo`. It can be used to extract information\nfrom the raw data.\n\nDefaults to `average` for line-type series, `sum` for columns, `range`\nfor range series and `ohlc` for OHLC and candlestick.'},subtree:{}},dateTimeLabelFormats:{meta:{types:{object:1},name:"dateTimeLabelFormats",excludes:{},products:{highstock:1},description:"Datetime formats for the header of the tooltip in a stock chart.\nThe format can vary within a chart depending on the currently selected\ntime range and the current data grouping.\n\nThe default formats are:\n\n
    {\n    millisecond: [\n        '%A, %b %e, %H:%M:%S.%L', '%A, %b %e, %H:%M:%S.%L', '-%H:%M:%S.%L'\n    ],\n    second: ['%A, %b %e, %H:%M:%S', '%A, %b %e, %H:%M:%S', '-%H:%M:%S'],\n    minute: ['%A, %b %e, %H:%M', '%A, %b %e, %H:%M', '-%H:%M'],\n    hour: ['%A, %b %e, %H:%M', '%A, %b %e, %H:%M', '-%H:%M'],\n    day: ['%A, %b %e, %Y', '%A, %b %e', '-%A, %b %e, %Y'],\n    week: ['Week from %A, %b %e, %Y', '%A, %b %e', '-%A, %b %e, %Y'],\n    month: ['%B %Y', '%B', '-%B %Y'],\n    year: ['%Y', '%Y', '-%Y']\n}
    \n\nFor each of these array definitions, the first item is the format\nused when the active time span is one unit. For instance, if the\ncurrent data applies to one week, the first item of the week array\nis used. The second and third items are used when the active time\nspan is more than two units. For instance, if the current data applies\nto two weeks, the second and third item of the week array are used,\n and applied to the start and end date of the time span."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",products:{highstock:1},description:"Enable or disable data grouping."},subtree:{}},forced:{meta:{types:{boolean:1},name:"forced",excludes:{},default:"false",products:{highstock:1},description:"When data grouping is forced, it runs no matter how small the intervals\nare. This can be handy for example when the sum should be calculated\nfor values appearing at random times within each hour."},subtree:{}},groupAll:{meta:{types:{boolean:1},name:"groupAll",excludes:{},default:"false",products:{highstock:1},description:"By default only points within the visible range are grouped. Enabling this\noption will force data grouping to calculate all grouped points for a given\ndataset. That option prevents for example a column series from calculating\na grouped point partially. The effect is similar to\n[Series.getExtremesFromAll](#plotOptions.series.getExtremesFromAll) but does\nnot affect yAxis extremes."},subtree:{}},groupPixelWidth:{meta:{types:{number:1},name:"groupPixelWidth",excludes:{},default:"2",products:{highstock:1},description:"The approximate pixel width of each group. If for example a series\nwith 30 points is displayed over a 600 pixel wide plot area, no grouping\nis performed. If however the series contains so many points that\nthe spacing is less than the groupPixelWidth, Highcharts will try\nto group it into appropriate groups so that each is more or less\ntwo pixels wide. If multiple series with different group pixel widths\nare drawn on the same x axis, all series will take the greatest width.\nFor example, line series have 2px default group width, while column\nseries have 10px. If combined, both the line and the column will\nhave 10px by default."},subtree:{}},smoothed:{meta:{types:{boolean:1},name:"smoothed",excludes:{},default:"false",products:{highstock:1},description:"Normally, a group is indexed by the start of that group, so for example\nwhen 30 daily values are grouped into one month, that month's x value\nwill be the 1st of the month. This apparently shifts the data to\nthe left. When the smoothed option is true, this is compensated for.\nThe data is shifted to the middle of the group, and min and max\nvalues are preserved. Internally, this is used in the Navigator series."},subtree:{}},units:{meta:{types:{array:"object"},name:"units",excludes:{},products:{highstock:1},description:"An array determining what time intervals the data is allowed to be\ngrouped to. Each array item is an array where the first value is\nthe time unit and the second value another array of allowed multiples.\nDefaults to:\n\n
    units: [[\n    'millisecond', // unit name\n    [1, 2, 5, 10, 20, 25, 50, 100, 200, 500] // allowed multiples\n], [\n    'second',\n    [1, 2, 5, 10, 15, 30]\n], [\n    'minute',\n    [1, 2, 5, 10, 15, 30]\n], [\n    'hour',\n    [1, 2, 3, 4, 6, 8, 12]\n], [\n    'day',\n    [1]\n], [\n    'week',\n    [1]\n], [\n    'month',\n    [1, 3, 6]\n], [\n    'year',\n    null\n]]
    "},subtree:{}}}},dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{},description:"Options for the series data labels, appearing next to each data point.\n\nIn styled mode, the data labels can be styled with the\n`.highcharts-data-label-box` and `.highcharts-data-label` class names\n([see example](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/series-datalabels))."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"center",description:"The alignment of the data label compared to the point. If `right`,\nthe right side of the label should be touching the point. For\npoints with an extent, like columns, the alignments also dictates\nhow to align it inside the box, as given with the\n[inside](#plotOptions.column.dataLabels.inside) option. Can be one of\n`left`, `center` or `right`."},subtree:{}},allowOverlap:{meta:{types:{boolean:1},name:"allowOverlap",excludes:{},default:"false",description:"Whether to allow data labels to overlap. To make the labels less\nsensitive for overlapping, the [dataLabels.padding](\n#plotOptions.series.dataLabels.padding) can be set to 0."},subtree:{}},backgroundColor:{meta:{types:{"highcharts.colorstring":1},name:"backgroundColor",excludes:{},description:"The background color or gradient for the data label."},subtree:{}},borderColor:{meta:{types:{"highcharts.colorstring":1},name:"borderColor",excludes:{},description:"The border color for the data label. Defaults to `undefined`."},subtree:{}},borderRadius:{meta:{types:{number:1},name:"borderRadius",excludes:{},default:"0",description:"The border radius in pixels for the data label."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:"0",description:"The border width in pixels for the data label."},subtree:{}},className:{meta:{types:{string:1},name:"className",excludes:{},description:"A class name for the data label. Particularly in styled mode, this\ncan be used to give each series' or point's data label unique\nstyling. In addition to this option, a default color class name is\nadded so that we can give the labels a\n[contrast text shadow](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/data-label-contrast/)."},subtree:{}},color:{meta:{types:{"highcharts.colorstring":1},name:"color",excludes:{},description:"The text color for the data labels. Defaults to `undefined`. For\ncertain series types, like column or map, the data labels can be\ndrawn inside the points. In this case the data label will be drawn\nwith maximum contrast by default. Additionally, it will be given a\n`text-outline` style with the opposite color, to further increase the\ncontrast. This can be overridden by setting the `text-outline` style\nto `none` in the `dataLabels.style` option."},subtree:{}},crop:{meta:{types:{boolean:1},name:"crop",excludes:{},default:"true",description:"Whether to hide data labels that are outside the plot area. By\ndefault, the data label is moved inside the plot area according to\nthe [overflow](#plotOptions.series.dataLabels.overflow) option."},subtree:{}},defer:{meta:{types:{boolean:1},name:"defer",excludes:{},default:"true",products:{highcharts:1,highstock:1},description:"Whether to defer displaying the data labels until the initial series\nanimation has finished."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"false",description:"Enable or disable the data labels."},subtree:{}},filter:{meta:{types:{"*":1},name:"filter",excludes:{},description:"A declarative filter for which data labels to display. The\ndeclarative filter is designed for use when callback functions are\nnot available, like when the chart options require a pure JSON\nstructure or for use with graphical editors. For programmatic\ncontrol, use the `formatter` instead, and return `undefined` to\ndisable a single data label."},subtree:{operator:{meta:{types:{string:1},name:"operator",excludes:{},description:"The operator to compare by. Can be one of `>`, `<`, `>=`, `<=`, `==`,\nand `===`."},subtree:{}},property:{meta:{types:{string:1},name:"property",excludes:{},description:"The point property to filter by. Point options are passed directly to\nproperties, additionally there are `y` value, `percentage` and others\nlisted under [Point](https://api.highcharts.com/class-reference/Highcharts.Point)\nmembers."},subtree:{}},value:{meta:{types:{"*":1},name:"value",excludes:{},description:"The value to compare against."},subtree:{}}}},format:{meta:{types:{string:1},name:"format",excludes:{},description:"A [format string](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting)\nfor the data label. Available variables are the same as for\n`formatter`."},subtree:{}},formatter:{meta:{types:{function:1},name:"formatter",excludes:{},description:"Callback JavaScript function to format the data label. Note that if a\n`format` is defined, the format takes precedence and the formatter is\nignored. Available data are:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
    `this.percentage`Stacked series and pies only. The point's percentage of the\ntotal.
    `this.point`The point object. The point name, if defined, is available\nthrough `this.point.name`.
    `this.series`:The series object. The series name is available through\n`this.series.name`.
    `this.total`Stacked series only. The total value at this point's x value.\n
    `this.x`:The x value.
    `this.y`:The y value.
    "},subtree:{}},inside:{meta:{types:{boolean:1},name:"inside",excludes:{},description:"For points with an extent, like columns or map areas, whether to\nalign the data label inside the box or to the actual value point.\nDefaults to `false` in most cases, `true` in stacked columns."},subtree:{}},overflow:{meta:{types:{string:1},name:"overflow",excludes:{},default:"justify",description:'How to handle data labels that flow outside the plot area. The\ndefault is `justify`, which aligns them inside the plot area. For\ncolumns and bars, this means it will be moved inside the bar. To\ndisplay data labels outside the plot area, set `crop` to `false` and\n`overflow` to `"none"`.'},subtree:{}},padding:{meta:{types:{number:1},name:"padding",excludes:{},default:5,description:"When either the `borderWidth` or the `backgroundColor` is set,\nthis is the padding within the box."},subtree:{}},rotation:{meta:{types:{number:1},name:"rotation",excludes:{},default:"0",description:"Text rotation in degrees. Note that due to a more complex structure,\nbackgrounds, borders and padding will be lost on a rotated data\nlabel."},subtree:{}},shadow:{meta:{types:{"*":1,boolean:1},name:"shadow",excludes:{},default:"false",description:"The shadow of the box. Works best with `borderWidth` or\n`backgroundColor`. Since 2.3 the shadow can be an object\nconfiguration containing `color`, `offsetX`, `offsetY`, `opacity` and\n`width`."},subtree:{}},shape:{meta:{types:{string:1},name:"shape",excludes:{},default:"square",description:"The name of a symbol to use for the border around the label. Symbols\nare predefined functions on the Renderer object."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},default:'{"color": "contrast", "fontSize": "11px", "fontWeight": "bold", "textOutline": "1px contrast" }',description:'Styles for the label. The default `color` setting is `"contrast"`,\nwhich is a pseudo color that Highcharts picks up and applies the\nmaximum contrast to the underlying point item, for example the\nbar in a bar chart.\n\nThe `textOutline` is a pseudo property that\napplies an outline of the given width with the given color, which\nby default is the maximum contrast to the text. So a bright text\ncolor will result in a black text outline for maximum readability\non a mixed background. In some cases, especially with grayscale\ntext, the text outline doesn\'t work well, in which cases it can\nbe disabled by setting it to `"none"`. When `useHTML` is true, the\n`textOutline` will not be picked up. In this, case, the same effect\ncan be acheived through the `text-shadow` CSS property.'},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"contrast"},subtree:{}},fontSize:{meta:{types:{string:1},name:"fontSize",excludes:{},default:"11px"},subtree:{}},fontWeight:{meta:{types:{string:1},name:"fontWeight",excludes:{},default:"bold"},subtree:{}},textOutline:{meta:{types:{string:1},name:"textOutline",excludes:{},default:"1px contrast"},subtree:{}}}},useHTML:{meta:{types:{boolean:1},name:"useHTML",excludes:{},default:"false",description:"Whether to\n[use HTML](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting#html)\nto render the labels."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"bottom",description:"The vertical alignment of a data label. Can be one of `top`, `middle`\nor `bottom`. The default value depends on the data, for instance\nin a column chart, the label is above positive values and below\nnegative values."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"0",description:"The x position offset of the label relative to the point in pixels."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:"-6",description:"The y position offset of the label relative to the point in pixels."},subtree:{}},zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},default:"6",description:"The Z index of the data labels. The default Z index puts it above\nthe series. Use a Z index of 2 to display it behind the series."},subtree:{}}}},description:{meta:{types:{string:1},name:"description",excludes:{},description:"Requires the Accessibility module.\n\nA description of the series to add to the screen reader information\nabout the series."},subtree:{}},enableMouseTracking:{meta:{types:{boolean:1},name:"enableMouseTracking",excludes:{},default:"true",description:"Enable or disable the mouse tracking for a specific series. This\nincludes point tooltips and click events on graphs and points. For\nlarge datasets it improves performance."},subtree:{}},events:{meta:{types:{object:1},name:"events",excludes:{},description:"General event handlers for the series items. These event hooks can also\nbe attached to the series at run time using the `Highcharts.addEvent`\nfunction."},subtree:{afterAnimate:{meta:{types:{function:1},name:"afterAnimate",excludes:{},products:{highcharts:1,highstock:1},description:"Fires after the series has finished its initial animation, or in\ncase animation is disabled, immediately as the series is displayed."},subtree:{}},checkboxClick:{meta:{types:{function:1},name:"checkboxClick",excludes:{},description:"Fires when the checkbox next to the series' name in the legend is\nclicked. One parameter, `event`, is passed to the function. The state\nof the checkbox is found by `event.checked`. The checked item is\nfound by `event.item`. Return `false` to prevent the default action\nwhich is to toggle the select state of the series."},subtree:{}},click:{meta:{types:{function:1},name:"click",excludes:{},description:"Fires when the series is clicked. One parameter, `event`, is passed to\nthe function, containing common event information. Additionally,\n`event.point` holds a pointer to the nearest point on the graph."},subtree:{}},hide:{meta:{types:{function:1},name:"hide",excludes:{},description:"Fires when the series is hidden after chart generation time, either\nby clicking the legend item or by calling `.hide()`."},subtree:{}},legendItemClick:{meta:{types:{function:1},name:"legendItemClick",excludes:{},description:"Fires when the legend item belonging to the series is clicked. One\nparameter, `event`, is passed to the function. The default action\nis to toggle the visibility of the series. This can be prevented\nby returning `false` or calling `event.preventDefault()`."},subtree:{}},mouseOut:{meta:{types:{function:1},name:"mouseOut",excludes:{},description:"Fires when the mouse leaves the graph. One parameter, `event`, is\npassed to the function, containing common event information. If the\n[stickyTracking](#plotOptions.series) option is true, `mouseOut`\ndoesn't happen before the mouse enters another graph or leaves the\nplot area."},subtree:{}},mouseOver:{meta:{types:{function:1},name:"mouseOver",excludes:{},description:"Fires when the mouse enters the graph. One parameter, `event`, is\npassed to the function, containing common event information."},subtree:{}},show:{meta:{types:{function:1},name:"show",excludes:{},description:"Fires when the series is shown after chart generation time, either\nby clicking the legend item or by calling `.show()`."},subtree:{}}}},exposeElementToA11y:{meta:{types:{boolean:1},name:"exposeElementToA11y",excludes:{},description:"By default, series are exposed to screen readers as regions. By enabling\nthis option, the series element itself will be exposed in the same\nway as the data points. This is useful if the series is not used\nas a grouping entity in the chart, but you still want to attach a\ndescription to the series.\n\nRequires the Accessibility module."},subtree:{}},findNearestPointBy:{meta:{types:{string:1},name:"findNearestPointBy",excludes:{},default:"x",description:"Determines whether the series should look for the nearest point\nin both dimensions or just the x-dimension when hovering the series.\nDefaults to `'xy'` for scatter series and `'x'` for most other\nseries. If the data has duplicate x-values, it is recommended to\nset this to `'xy'` to allow hovering over all points.\n\nApplies only to series types using nearest neighbor search (not\ndirect hover) for tooltip."},subtree:{}},gapSize:{meta:{types:{number:1},name:"gapSize",excludes:{},default:"0",products:{highstock:1},description:"Defines when to display a gap in the graph, together with the\n[gapUnit](plotOptions.series.gapUnit) option.\n\nIn case when `dataGrouping` is enabled, points can be grouped into a\nlarger time span. This can make the grouped points to have a greater\ndistance than the absolute value of `gapSize` property, which will result\nin disappearing graph completely. To prevent this situation the mentioned\ndistance between grouped points is used instead of previously defined\n`gapSize`.\n\nIn practice, this option is most often used to visualize gaps in\ntime series. In a stock chart, intraday data is available for daytime\nhours, while gaps will appear in nights and weekends."},subtree:{}},gapUnit:{meta:{types:{string:1},name:"gapUnit",excludes:{},default:"relative",products:{highstock:1},description:"Together with [gapSize](plotOptions.series.gapSize), this option defines\nwhere to draw gaps in the graph.\n\nWhen the `gapUnit` is `relative` (default), a gap size of 5 means\nthat if the distance between two points is greater than five times\nthat of the two closest points, the graph will be broken.\n\nWhen the `gapUnit` is `value`, the gap is based on absolute axis values,\nwhich on a datetime axis is milliseconds. This also applies to the\nnavigator series that inherits gap options from the base series."},subtree:{}},getExtremesFromAll:{meta:{types:{boolean:1},name:"getExtremesFromAll",excludes:{},default:"false",products:{highcharts:1,highstock:1},description:"Whether to use the Y extremes of the total chart width or only the\nzoomed area when zooming in on parts of the X axis. By default, the\nY axis adjusts to the min and max of the visible data. Cartesian\nseries only."},subtree:{}},joinBy:{meta:{types:{array:"String",string:1},name:"joinBy",excludes:{},products:{highmaps:1},description:'What property to join the `mapData` to the value data. For example,\nif joinBy is "code", the mapData items with a specific code is merged\ninto the data with the same code. For maps loaded from GeoJSON, the\nkeys may be held in each point\'s `properties` object.\n\nThe joinBy option can also be an array of two values, where the first\npoints to a key in the `mapData`, and the second points to another\nkey in the `data`.\n\nWhen joinBy is `null`, the map items are joined by their position\nin the array, which performs much better in maps with many data points.\nThis is the recommended option if you are printing more than a thousand\ndata points and have a backend that can preprocess the data into\na parallel array of the mapData.' },subtree:{}},keys:{meta:{types:{array:"string"},name:"keys",excludes:{},description:"An array specifying which option maps to which key in the data point\narray. This makes it convenient to work with unstructured data arrays\nfrom different sources."},subtree:{}},label:{meta:{types:{object:1},name:"label",excludes:{},products:{highcharts:1,highstock:1},description:"Series labels are placed as close to the series as possible in a\nnatural way, seeking to avoid other series. The goal of this\nfeature is to make the chart more easily readable, like if a\nhuman designer placed the labels in the optimal position.\n\nThe series labels currently work with series types having a\n`graph` or an `area`.\n\nRequires the `series-label.js` module."},subtree:{boxesToAvoid:{meta:{types:{array:"Object"},name:"boxesToAvoid",excludes:{},description:"An array of boxes to avoid when laying out the labels. Each\nitem has a `left`, `right`, `top` and `bottom` property."},subtree:{}},connectorAllowed:{meta:{types:{boolean:1},name:"connectorAllowed",excludes:{},default:!1,description:"Allow labels to be placed distant to the graph if necessary,\nand draw a connector line to the graph. Setting this option\nto true may decrease the performance significantly, since the\nalgorithm with systematically search for open spaces in the\nwhile plot area. Visually, it may also result in a more\ncluttered chart, though more of the series will be labeled."},subtree:{}},connectorNeighbourDistance:{meta:{types:{number:1},name:"connectorNeighbourDistance",excludes:{},default:24,description:"If the label is closer than this to a neighbour graph, draw a\nconnector."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0,description:"Enable the series label per series."},subtree:{}},maxFontSize:{meta:{types:{number:1},name:"maxFontSize",excludes:{},default:null,description:"For area-like series, allow the font size to vary so that\nsmall areas get a smaller font size. The default applies this\neffect to area-like series but not line-like series."},subtree:{}},minFontSize:{meta:{types:{number:1},name:"minFontSize",excludes:{},default:null,description:"For area-like series, allow the font size to vary so that\nsmall areas get a smaller font size. The default applies this\neffect to area-like series but not line-like series."},subtree:{}},onArea:{meta:{types:{boolean:1},name:"onArea",excludes:{},default:null,description:"Draw the label on the area of an area series. By default it\nis drawn on the area. Set it to `false` to draw it next to\nthe graph instead."},subtree:{}},style:{meta:{types:{object:1},name:"style",excludes:{},description:"Styles for the series label. The color defaults to the series\ncolor, or a contrast color if `onArea`."},subtree:{fontWeight:{meta:{types:{string:1},name:"fontWeight",excludes:{},default:"bold"},subtree:{}}}}}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:"2",products:{highcharts:1,highstock:1},description:"Pixel width of the graph line."},subtree:{}},linecap:{meta:{types:{string:1},name:"linecap",excludes:{},products:{highcharts:1,highstock:1},description:"The line cap used for line ends and line joins on the graph."},subtree:{}},linkedTo:{meta:{types:{string:1},name:"linkedTo",excludes:{},products:{highcharts:1,highstock:1},description:'The [id](#series.id) of another series to link to. Additionally,\nthe value can be ":previous" to link to the previous series. When\ntwo series are linked, only the first one appears in the legend.\nToggling the visibility of this also toggles the linked series.'},subtree:{}},marker:{meta:{types:{object:1},name:"marker",excludes:{},description:"Options for the point markers of line-like series. Properties like\n`fillColor`, `lineColor` and `lineWidth` define the visual appearance\nof the markers. Other series types, like column series, don't have\nmarkers, but have visual options on the series level instead.\n\nIn styled mode, the markers can be styled with the `.highcharts-point`,\n`.highcharts-point-hover` and `.highcharts-point-select`\nclass names."},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},description:"Enable or disable the point marker. If `undefined`, the markers are\nhidden when the data is dense, and shown for more widespread data\npoints."},subtree:{}},enabledThreshold:{meta:{types:{number:1},name:"enabledThreshold",excludes:{},default:"2",description:"The threshold for how dense the point markers should be before they\nare hidden, given that `enabled` is not defined. The number indicates\nthe horizontal distance between the two closest points in the series,\nas multiples of the `marker.radius`. In other words, the default\nvalue of 2 means points are hidden if overlapping horizontally."},subtree:{}},fillColor:{meta:{types:{"highcharts.colorstring":1},name:"fillColor",excludes:{},description:"The fill color of the point marker. When `undefined`, the series' or\npoint's color is used."},subtree:{}},height:{meta:{types:{number:1},name:"height",excludes:{},description:"Image markers only. Set the image width explicitly. When using this\noption, a `width` must also be set."},subtree:{}},lineColor:{meta:{types:{"highcharts.colorstring":1},name:"lineColor",excludes:{},default:"#ffffff",description:"The color of the point marker's outline. When `undefined`, the\nseries' or point's color is used."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:"0",description:"The width of the point marker's outline."},subtree:{}},radius:{meta:{types:{number:1},name:"radius",excludes:{},default:"4",description:"The radius of the point marker."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{},description:"States for a single point marker."},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{},description:"The hover state for a single point marker."},subtree:{animation:{meta:{types:{"highcharts.animationoptionsobject":1,boolean:1},name:"animation",excludes:{},description:"Animation when hovering over the marker."},subtree:{duration:{meta:{types:{number:1},name:"duration",excludes:{},default:50},subtree:{}}}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0,description:"Enable or disable the point marker."},subtree:{}},fillColor:{meta:{types:{"highcharts.colorstring":1},name:"fillColor",excludes:{},description:"The fill color of the marker in hover state. When\n`undefined`, the series' or point's fillColor for normal\nstate is used."},subtree:{}},lineColor:{meta:{types:{"highcharts.colorstring":1},name:"lineColor",excludes:{},description:"The color of the point marker's outline. When `undefined`,\nthe series' or point's lineColor for normal state is used."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},description:"The width of the point marker's outline. When `undefined`,\nthe series' or point's lineWidth for normal state is used."},subtree:{}},lineWidthPlus:{meta:{types:{number:1},name:"lineWidthPlus",excludes:{},default:1,description:"The additional line width for a hovered point."},subtree:{}},radius:{meta:{types:{number:1},name:"radius",excludes:{},description:"The radius of the point marker. In hover state, it defaults\nto the normal state's radius + 2 as per the [radiusPlus](\n#plotOptions.series.marker.states.hover.radiusPlus)\noption."},subtree:{}},radiusPlus:{meta:{types:{number:1},name:"radiusPlus",excludes:{},default:2,description:"The number of pixels to increase the radius of the hovered\npoint."},subtree:{}}}},normal:{meta:{types:{object:1},name:"normal",excludes:{},description:"The normal state of a single point marker. Currently only used\nfor setting animation when returning to normal state from hover."},subtree:{animation:{meta:{types:{boolean:1},name:"animation",excludes:{},default:!0},subtree:{}}}},select:{meta:{types:{object:1},name:"select",excludes:{},description:"The appearance of the point marker when selected. In order to\nallow a point to be selected, set the `series.allowPointSelect`\noption to true."},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",description:"Enable or disable visible feedback for selection."},subtree:{}},fillColor:{meta:{types:{"highcharts.colorstring":1},name:"fillColor",excludes:{},default:"#cccccc",description:"The fill color of the point marker."},subtree:{}},lineColor:{meta:{types:{"highcharts.colorstring":1},name:"lineColor",excludes:{},default:"#000000",description:"The color of the point marker's outline. When `undefined`,\nthe series' or point's color is used."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:2,description:"The width of the point marker's outline."},subtree:{}},radius:{meta:{types:{number:1},name:"radius",excludes:{},description:"The radius of the point marker. In hover state, it defaults\nto the normal state's radius + 2."},subtree:{}}}}}},symbol:{meta:{types:{string:1},name:"symbol",excludes:{},description:'A predefined shape or symbol for the marker. When undefined, the\nsymbol is pulled from options.symbols. Other possible values are\n"circle", "square", "diamond", "triangle" and "triangle-down".\n\nAdditionally, the URL to a graphic can be given on this form:\n"url(graphic.png)". Note that for the image to be applied to exported\ncharts, its URL needs to be accessible by the export server.\n\nCustom callbacks for symbol path generation can also be added to\n`Highcharts.SVGRenderer.prototype.symbols`. The callback is then\nused by its method name, as shown in the demo.'},subtree:{}},width:{meta:{types:{number:1},name:"width",excludes:{},description:"Image markers only. Set the image width explicitly. When using this\noption, a `height` must also be set."},subtree:{}}}},navigatorOptions:{meta:{types:{"*":1},name:"navigatorOptions",excludes:{},products:{highstock:1},description:"Options for the corresponding navigator series if `showInNavigator`\nis `true` for this series. Available options are the same as any\nseries, documented at [plotOptions](#plotOptions.series) and\n[series](#series).\n\nThese options are merged with options in [navigator.series](\n#navigator.series), and will take precedence if the same option is\ndefined both places."},subtree:{}},negativeColor:{meta:{types:{"highcharts.colorstring":1},name:"negativeColor",excludes:{},description:"The color for the parts of the graph or points that are below the\n[threshold](#plotOptions.series.threshold)."},subtree:{}},point:{meta:{types:{object:1},name:"point",excludes:{},description:"Properties for each single point."},subtree:{events:{meta:{types:{object:1},name:"events",excludes:{},description:"Events for each single point."},subtree:{click:{meta:{types:{function:1},name:"click",excludes:{},description:"Fires when a point is clicked. One parameter, `event`, is passed\nto the function, containing common event information.\n\nIf the `series.allowPointSelect` option is true, the default\naction for the point's click event is to toggle the point's\nselect state. Returning `false` cancels this action."},subtree:{}},mouseOut:{meta:{types:{function:1},name:"mouseOut",excludes:{},description:"Fires when the mouse leaves the area close to the point. One\nparameter, `event`, is passed to the function, containing common\nevent information."},subtree:{}},mouseOver:{meta:{types:{function:1},name:"mouseOver",excludes:{},description:"Fires when the mouse enters the area close to the point. One\nparameter, `event`, is passed to the function, containing common\nevent information."},subtree:{}},remove:{meta:{types:{function:1},name:"remove",excludes:{},description:"Fires when the point is removed using the `.remove()` method. One\nparameter, `event`, is passed to the function. Returning `false`\ncancels the operation."},subtree:{}},select:{meta:{types:{function:1},name:"select",excludes:{},description:"Fires when the point is selected either programmatically or\nfollowing a click on the point. One parameter, `event`, is passed\nto the function. Returning `false` cancels the operation."},subtree:{}},unselect:{meta:{types:{function:1},name:"unselect",excludes:{},description:"Fires when the point is unselected either programmatically or\nfollowing a click on the point. One parameter, `event`, is passed\nto the function.\n Returning `false` cancels the operation."},subtree:{}},update:{meta:{types:{function:1},name:"update",excludes:{},description:"Fires when the point is updated programmatically through the\n`.update()` method. One parameter, `event`, is passed to the\nfunction. The new point options can be accessed through\n`event.options`. Returning `false` cancels the operation."},subtree:{}}}}}},pointDescriptionFormatter:{meta:{types:{function:1},name:"pointDescriptionFormatter",excludes:{},description:"Same as [accessibility.pointDescriptionFormatter](\n#accessibility.pointDescriptionFormatter), but for an individual series.\nOverrides the chart wide configuration."},subtree:{}},pointInterval:{meta:{types:{number:1},name:"pointInterval",excludes:{},default:"1",products:{highcharts:1,highstock:1},description:"If no x values are given for the points in a series, `pointInterval`\ndefines the interval of the x values. For example, if a series contains\none value every decade starting from year 0, set `pointInterval` to\n`10`. In true `datetime` axes, the `pointInterval` is set in\nmilliseconds.\n\nIt can be also be combined with `pointIntervalUnit` to draw irregular\ntime intervals.\n\nPlease note that this options applies to the _series data_, not the\ninterval of the axis ticks, which is independent."},subtree:{}},pointIntervalUnit:{meta:{types:{string:1},name:"pointIntervalUnit",excludes:{},products:{highcharts:1,highstock:1},description:"On datetime series, this allows for setting the\n[pointInterval](#plotOptions.series.pointInterval) to irregular time\nunits, `day`, `month` and `year`. A day is usually the same as 24 hours,\nbut `pointIntervalUnit` also takes the DST crossover into consideration\nwhen dealing with local time. Combine this option with `pointInterval`\nto draw weeks, quarters, 6 months, 10 years etc.\n\nPlease note that this options applies to the _series data_, not the\ninterval of the axis ticks, which is independent."},subtree:{}},pointPlacement:{meta:{types:{number:1,string:1},name:"pointPlacement",excludes:{},products:{highcharts:1,highstock:1},description:'Possible values: `"on"`, `"between"`, `number`.\n\nIn a column chart, when pointPlacement is `"on"`, the point will\nnot create any padding of the X axis. In a polar column chart this\nmeans that the first column points directly north. If the pointPlacement\nis `"between"`, the columns will be laid out between ticks. This\nis useful for example for visualising an amount between two points\nin time or in a certain sector of a polar chart.\n\nSince Highcharts 3.0.2, the point placement can also be numeric,\nwhere 0 is on the axis value, -0.5 is between this value and the\nprevious, and 0.5 is between this value and the next. Unlike the\ntextual options, numeric point placement options won\'t affect axis\npadding.\n\nNote that pointPlacement needs a [pointRange](\n#plotOptions.series.pointRange) to work. For column series this is\ncomputed, but for line-type series it needs to be set.\n\nDefaults to `undefined` in cartesian charts, `"between"` in polar charts.'},subtree:{}},pointRange:{meta:{types:{number:1},name:"pointRange",excludes:{},default:"0",products:{highstock:1},description:"The width of each point on the x axis. For example in a column chart\nwith one value each day, the pointRange would be 1 day (= 24 * 3600\n* 1000 milliseconds). This is normally computed automatically, but\nthis option can be used to override the automatic value."},subtree:{}},pointStart:{meta:{types:{number:1},name:"pointStart",excludes:{},default:"0",products:{highcharts:1,highstock:1},description:"If no x values are given for the points in a series, pointStart defines\non what value to start. For example, if a series contains one yearly\nvalue starting from 1945, set pointStart to 1945."},subtree:{}},selected:{meta:{types:{boolean:1},name:"selected",excludes:{},default:"false",description:"Whether to select the series initially. If `showCheckbox` is true,\nthe checkbox next to the series name in the legend will be checked for a\nselected series."},subtree:{}},shadow:{meta:{types:{"highcharts.seriesshadowoptions":1,boolean:1},name:"shadow",excludes:{},default:"false",description:"Whether to apply a drop shadow to the graph line. Since 2.3 the shadow\ncan be an object configuration containing `color`, `offsetX`, `offsetY`,\n`opacity` and `width`."},subtree:{}},showCheckbox:{meta:{types:{boolean:1},name:"showCheckbox",excludes:{},default:!1},subtree:{}},showInLegend:{meta:{types:{boolean:1},name:"showInLegend",excludes:{},default:"true",description:"Whether to display this particular series or series type in the legend.\nThe default value is `true` for standalone series, `false` for linked\nseries."},subtree:{}},showInNavigator:{meta:{types:{boolean:1},name:"showInNavigator",excludes:{},products:{highstock:1},description:"Whether or not to show the series in the navigator. Takes precedence\nover [navigator.baseSeries](#navigator.baseSeries) if defined."},subtree:{}},skipKeyboardNavigation:{meta:{types:{boolean:1},name:"skipKeyboardNavigation",excludes:{},description:"If set to `True`, the accessibility module will skip past the points\nin this series for keyboard navigation."},subtree:{}},softThreshold:{meta:{types:{boolean:1},name:"softThreshold",excludes:{},default:"true",products:{highcharts:1,highstock:1},description:"When this is true, the series will not cause the Y axis to cross\nthe zero plane (or [threshold](#plotOptions.series.threshold) option)\nunless the data actually crosses the plane.\n\nFor example, if `softThreshold` is `false`, a series of 0, 1, 2,\n3 will make the Y axis show negative values according to the `minPadding`\noption. If `softThreshold` is `true`, the Y axis starts at 0."},subtree:{}},stacking:{meta:{types:{string:1},name:"stacking",excludes:{},products:{highcharts:1,highstock:1},description:'Whether to stack the values of each series on top of each other. Possible\nvalues are `undefined` to disable, `"normal"` to stack by value or\n`"percent"`. When stacking is enabled, data must be sorted in ascending\nX order. A special stacking option is with the streamgraph series type,\nwhere the stacking option is set to `"stream"`.'},subtree:{}},states:{meta:{types:{"highcharts.plotseriesstatesoptions":1},name:"states",excludes:{},description:"A wrapper object for all the series options in specific states."},subtree:{hover:{meta:{types:{"highcharts.plotseriesstateshoveroptions":1},name:"hover",excludes:{},description:"Options for the hovered series. These settings override the normal\nstate options when a series is moused over or touched."},subtree:{animation:{meta:{types:{"highcharts.animationoptionsobject":1,boolean:1},name:"animation",excludes:{},default:'{ "duration": 50 }',products:{highcharts:1},description:"Animation setting for hovering the graph in line-type series."},subtree:{duration:{meta:{types:{number:1},name:"duration",excludes:{},default:50,description:"The duration of the hover animation in milliseconds. By\ndefault the hover state animates quickly in, and slowly back\nto normal."},subtree:{}}}},borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},products:{highmaps:1},description:"The border color of the point in this state."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},products:{highmaps:1},description:"The border width of the point in this state"},subtree:{}},brightness:{meta:{types:{number:1},name:"brightness",excludes:{},default:"0.2",products:{highmaps:1},description:"The relative brightness of the point when hovered, relative to\nthe normal point color."},subtree:{}},color:{meta:{types:{color:1},name:"color",excludes:{},products:{highmaps:1},description:"The color of the shape in this state"},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",description:"Enable separate styles for the hovered series to visualize that\nthe user hovers either the series itself or the legend. ."},subtree:{}},halo:{meta:{types:{"highcharts.plotseriesstateshoverhalooptions":1},name:"halo",excludes:{},products:{highcharts:1,highstock:1},description:"Options for the halo appearing around the hovered point in line-\ntype series as well as outside the hovered slice in pie charts.\nBy default the halo is filled by the current point or series\ncolor with an opacity of 0.25\\. The halo can be disabled by\nsetting the `halo` option to `false`.\n\nIn styled mode, the halo is styled with the `.highcharts-halo`\nclass, with colors inherited from `.highcharts-color-{n}`."},subtree:{attributes:{meta:{types:{"highcharts.svgattributes":1},name:"attributes",excludes:{},products:{highcharts:1,highstock:1},description:"A collection of SVG attributes to override the appearance of\nthe halo, for example `fill`, `stroke` and `stroke-width`."},subtree:{}},opacity:{meta:{types:{number:1},name:"opacity",excludes:{},default:"0.25",products:{highcharts:1,highstock:1},description:"Opacity for the halo unless a specific fill is overridden\nusing the `attributes` setting. Note that Highcharts is only\nable to apply opacity to colors of hex or rgb(a) formats."},subtree:{}},size:{meta:{types:{number:1},name:"size",excludes:{},default:"10",products:{highcharts:1,highstock:1},description:"The pixel size of the halo. For point markers this is the\nradius of the halo. For pie slices it is the width of the\nhalo outside the slice. For bubbles it defaults to 5 and is\nthe width of the halo outside the bubble."},subtree:{}}}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},products:{highcharts:1,highstock:1},description:"Pixel width of the graph line. By default this property is\nundefined, and the `lineWidthPlus` property dictates how much\nto increase the linewidth from normal state."},subtree:{}},lineWidthPlus:{meta:{types:{number:1},name:"lineWidthPlus",excludes:{},default:"1",products:{highcharts:1,highstock:1},description:"The additional line width for the graph of a hovered series."},subtree:{}},marker:{meta:{types:{},name:"marker",excludes:{},products:{highcharts:1,highstock:1},description:"In Highcharts 1.0, the appearance of all markers belonging to the\nhovered series. For settings on the hover state of the individual\npoint, see\n[marker.states.hover](#plotOptions.series.marker.states.hover).",extends:"plotOptions.series.marker"},subtree:{}}}},normal:{meta:{types:{object:1},name:"normal",excludes:{},default:"true",products:{highmaps:1},description:"Overrides for the normal state."},subtree:{animation:{meta:{types:{boolean:1,object:1},name:"animation",excludes:{},default:"true",products:{highmaps:1},description:"Animation options for the fill color when returning from hover\nstate to normal state. The animation adds some latency in order\nto reduce the effect of flickering when hovering in and out of\nfor example an uneven coastline."},subtree:{}}}},select:{meta:{types:{"highcharts.plotseriesstatesselectoptions":1},name:"select",excludes:{},products:{highmaps:1},description:"Specific options for point in selected states, after being selected\nby [allowPointSelect](#plotOptions.series.allowPointSelect) or\nprogrammatically.",extends:"plotOptions.series.states.hover"},subtree:{}}}},step:{meta:{types:{string:1},name:"step",excludes:{},products:{highcharts:1,highstock:1},description:"Whether to apply steps to the line. Possible values are `left`, `center`\nand `right`."},subtree:{}},stickyTracking:{meta:{types:{boolean:1},name:"stickyTracking",excludes:{},default:!0,description:"Sticky tracking of mouse events. When true, the `mouseOut` event\non a series isn't triggered until the mouse moves over another series,\nor out of the plot area. When false, the `mouseOut` event on a\nseries is triggered when the mouse leaves the area around the series'\ngraph or markers. This also implies the tooltip when not shared. When\n`stickyTracking` is false and `tooltip.shared` is false, the tooltip will\nbe hidden when moving the mouse between series. Defaults to true for line\nand area type series, but to false for columns, pies etc."},subtree:{}},threshold:{meta:{types:{number:1},name:"threshold",excludes:{},default:"0",products:{highcharts:1,highstock:1},description:"The threshold, also called zero level or base level. For line type\nseries this is only used in conjunction with\n[negativeColor](#plotOptions.series.negativeColor)."},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{},description:"A configuration object for the tooltip rendering of each single series.\nProperties are inherited from [tooltip](#tooltip), but only the\nfollowing properties can be defined on a series level.",extends:"tooltip"},subtree:{}},turboThreshold:{meta:{types:{number:1},name:"turboThreshold",excludes:{},default:"1000",products:{highcharts:1,highstock:1},description:"When a series contains a data array that is longer than this, only\none dimensional arrays of numbers, or two dimensional arrays with\nx and y values are allowed. Also, only the first point is tested,\nand the rest are assumed to be the same format. This saves expensive\ndata checking and indexing in long series. Set it to `0` disable."},subtree:{}},visible:{meta:{types:{boolean:1},name:"visible",excludes:{},default:"true",description:"Set the initial visibility of the series."},subtree:{}},zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},products:{highmaps:1},description:"Define the z index of the series."},subtree:{}},zoneAxis:{meta:{types:{string:1},name:"zoneAxis",excludes:{},default:"y",products:{highcharts:1,highstock:1},description:"Defines the Axis on which the zones are applied."},subtree:{}},zones:{meta:{types:{array:"object"},name:"zones",excludes:{},products:{highcharts:1,highstock:1},description:"An array defining zones within a series. Zones can be applied to\nthe X axis, Y axis or Z axis for bubbles, according to the `zoneAxis`\noption. The zone definitions have to be in ascending order regarding to\nthe value.\n\nIn styled mode, the color zones are styled with the\n`.highcharts-zone-{n}` class, or custom classed from the `className`\noption\n([view live demo](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/color-zones/))."},subtree:{className:{meta:{types:{string:1},name:"className",excludes:{},description:"Styled mode only. A custom class name for the zone."},subtree:{}},color:{meta:{types:{"highcharts.colorstring":1},name:"color",excludes:{},products:{highcharts:1,highstock:1},description:"Defines the color of the series."},subtree:{}},dashStyle:{meta:{types:{string:1},name:"dashStyle",excludes:{},products:{highcharts:1,highstock:1},description:"A name for the dash style to use for the graph."},subtree:{}},fillColor:{meta:{types:{"highcharts.colorstring":1},name:"fillColor",excludes:{},products:{highcharts:1,highstock:1},description:"Defines the fill color for the series (in area type series)"},subtree:{}},value:{meta:{types:{number:1},name:"value",excludes:{},products:{highcharts:1,highstock:1},description:"The value up to where the zone extends, if undefined the zones stretches\nto the last value in the series."},subtree:{}}}}}},sma:{meta:{types:{object:1},name:"sma",excludes:{},products:{highstock:1},description:"Simple moving average indicator (SMA). This series requires `linkedTo`\noption to be set.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `sma` series are defined in\n [plotOptions.sma](plotOptions.sma).\n3. Options for one single series are given in\n [the series instance array](series.sma).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        sma: {\n            // shared options for all sma series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'sma'\n    }]\n});\n
    \n ",extends:"plotOptions.line"},subtree:{linkedTo:{meta:{types:{string:1},name:"linkedTo",excludes:{},products:{highstock:1},description:"The main series ID that indicator will be based on. Required for this\nindicator."},subtree:{}},name:{meta:{types:{string:1},name:"name",excludes:{},products:{highstock:1},description:"The name of the series as shown in the legend, tooltip etc. If not\nset, it will be based on a technical indicator type and default\nparams."},subtree:{}},params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{index:{meta:{types:{number:1},name:"index",excludes:{},default:0,products:{highstock:1},description:"The point index which indicator calculations will base. For\nexample using OHLC data, index=2 means the indicator will be\ncalculated using Low values."},subtree:{}},period:{meta:{types:{number:1},name:"period",excludes:{},default:14,products:{highstock:1},description:"The base period for indicator calculations. This is the number of\ndata points which are taken into account for the indicator\ncalculations."},subtree:{}}}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{valueDecimals:{meta:{types:{number:1},name:"valueDecimals",excludes:{},default:4,products:{highstock:1},description:"Number of decimals in indicator series."},subtree:{}}}}}},solidgauge:{meta:{types:{object:1},name:"solidgauge",excludes:{},products:{highcharts:1},description:"A solid gauge is a circular gauge where the value is indicated by a filled\narc, and the color of the arc may variate with the value.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `solidgauge` series are defined in\n [plotOptions.solidgauge](plotOptions.solidgauge).\n3. Options for one single series are given in\n [the series instance array](series.solidgauge).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        solidgauge: {\n            // shared options for all solidgauge series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'solidgauge'\n    }]\n});\n
    \n ",extends:"plotOptions.gauge"},subtree:{colorByPoint:{meta:{types:{boolean:1},name:"colorByPoint",excludes:{},default:!0,description:"Whether to give each point an individual color."},subtree:{}},linecap:{meta:{types:{string:1},name:"linecap",excludes:{},default:"round",products:{highcharts:1},description:"Whether the strokes of the solid gauge should be `round` or `square`."},subtree:{}},overshoot:{meta:{types:{number:1},name:"overshoot",excludes:{},default:"0",products:{highcharts:1},description:"Allow the gauge to overshoot the end of the perimeter axis by this\nmany degrees. Say if the gauge axis goes from 0 to 60, a value of\n100, or 1000, will show 5 degrees beyond the end of the axis when this\noption is set to 5."},subtree:{}},rounded:{meta:{types:{boolean:1},name:"rounded",excludes:{},default:"false",products:{highcharts:1},description:"Wether to draw rounded edges on the gauge."},subtree:{}},threshold:{meta:{types:{number:1},name:"threshold",excludes:{},default:"null",products:{highcharts:1},description:"The threshold or base level for the gauge."},subtree:{}}}},spline:{meta:{types:{},name:"spline",excludes:{},products:{highcharts:1,highstock:1},description:"A spline series is a special type of line series, where the segments between\nthe data points are smoothed.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `spline` series are defined in\n [plotOptions.spline](plotOptions.spline).\n3. Options for one single series are given in\n [the series instance array](series.spline).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        spline: {\n            // shared options for all spline series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'spline'\n    }]\n});\n
    \n ", extends:"plotOptions.series"},subtree:{}},stochastic:{meta:{types:{object:1},name:"stochastic",excludes:{},products:{highstock:1},description:"Stochastic oscillator. This series requires the `linkedTo` option to be\nset and should be loaded after the `stock/indicators/indicators.js` file.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `stochastic` series are defined in\n [plotOptions.stochastic](plotOptions.stochastic).\n3. Options for one single series are given in\n [the series instance array](series.stochastic).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        stochastic: {\n            // shared options for all stochastic series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'stochastic'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{dataGrouping:{meta:{types:{object:1},name:"dataGrouping",excludes:{}},subtree:{approximation:{meta:{types:{string:1},name:"approximation",excludes:{},default:"averages"},subtree:{}}}},marker:{meta:{types:{object:1},name:"marker",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1},subtree:{}}}},name:{meta:{types:{string:1},name:"name",excludes:{},default:"Stochastic (14, 3)"},subtree:{}},params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{periods:{meta:{types:{array:"object"},name:"periods",excludes:{},default:"[14, 3]",products:{highstock:1},description:"Periods for Stochastic oscillator: [%K, %D]."},subtree:{}}}},smoothedLine:{meta:{types:{object:1},name:"smoothedLine",excludes:{},products:{highstock:1},description:"Smoothed line options."},subtree:{styles:{meta:{types:{object:1},name:"styles",excludes:{},products:{highstock:1},description:"Styles for a smoothed line."},subtree:{lineColor:{meta:{types:{string:1},name:"lineColor",excludes:{},products:{highstock:1},description:"Color of the line. If not set, it's inherited from\n[plotOptions.stochastic.color](\n#plotOptions.stochastic.color)."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highstock:1},description:"Pixel width of the line."},subtree:{}}}}}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:' {series.name}
    %K: {point.y}
    %D: {point.smoothed}
    '},subtree:{}}}}}},streamgraph:{meta:{types:{object:1},name:"streamgraph",excludes:{},products:{highcharts:1,highstock:1},description:"A streamgraph is a type of stacked area graph which is displaced around a\ncentral axis, resulting in a flowing, organic shape.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `streamgraph` series are defined in\n [plotOptions.streamgraph](plotOptions.streamgraph).\n3. Options for one single series are given in\n [the series instance array](series.streamgraph).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        streamgraph: {\n            // shared options for all streamgraph series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'streamgraph'\n    }]\n});\n
    \n ",extends:"plotOptions.areaspline"},subtree:{fillOpacity:{meta:{types:{number:1},name:"fillOpacity",excludes:{},default:1},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:0},subtree:{}},marker:{meta:{types:{object:1},name:"marker",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1},subtree:{}}}},stacking:{meta:{types:{string:1},name:"stacking",excludes:{},default:"stream"},subtree:{}}}},sunburst:{meta:{types:{object:1},name:"sunburst",excludes:{},products:{highcharts:1},description:"A Sunburst displays hierarchical data, where a level in the hierarchy is\nrepresented by a circle. The center represents the root node of the tree.\nThe visualization bears a resemblance to both treemap and pie charts.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `sunburst` series are defined in\n [plotOptions.sunburst](plotOptions.sunburst).\n3. Options for one single series are given in\n [the series instance array](series.sunburst).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        sunburst: {\n            // shared options for all sunburst series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'sunburst'\n    }]\n});\n
    \n ",extends:"plotOptions.pie"},subtree:{allowDrillToNode:{meta:{types:{boolean:1},name:"allowDrillToNode",excludes:{},default:"false",description:"When enabled the user can click on a point which is a parent and\nzoom in on its children."},subtree:{}},center:{meta:{types:{array:"(String|Number)"},name:"center",excludes:{},products:{highcharts:1},description:"The center of the sunburst chart relative to the plot area. Can be\npercentages or pixel values."},subtree:{}},colorByPoint:{meta:{types:{boolean:1},name:"colorByPoint",excludes:{},default:!1},subtree:{}},dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{},extends:"plotOptions.series.dataLabels"},subtree:{allowOverlap:{meta:{types:{boolean:1},name:"allowOverlap",excludes:{},default:!0},subtree:{}},defer:{meta:{types:{boolean:1},name:"defer",excludes:{},default:!0},subtree:{}},rotationMode:{meta:{types:{string:1},name:"rotationMode",excludes:{},default:"auto",description:"Decides how the data label will be rotated relative to the perimeter\nof the sunburst. Valid values are `auto`, `parallel` and\n`perpendicular`. When `auto`, the best fit will be computed for the\npoint.\n\nThe `series.rotation` option takes precedence over `rotationMode`."},subtree:{}},style:{meta:{types:{object:1},name:"style",excludes:{}},subtree:{textOverflow:{meta:{types:{string:1},name:"textOverflow",excludes:{},default:"ellipsis"},subtree:{}}}}}},levelIsConstant:{meta:{types:{boolean:1},name:"levelIsConstant",excludes:{},default:!0,description:"Used together with the levels and `allowDrillToNode` options. When\nset to false the first level visible when drilling is considered\nto be level one. Otherwise the level will be the same as the tree\nstructure."},subtree:{}},levelSize:{meta:{types:{object:1},name:"levelSize",excludes:{},description:"Determines the width of the ring per level."},subtree:{unit:{meta:{types:{string:1},name:"unit",excludes:{},default:"weight",description:'How to interpret `levelSize.value`.\n`percentage` gives a width relative to result of outer radius minus\ninner radius.\n`pixels` gives the ring a fixed width in pixels.\n`weight` takes the remaining width after percentage and pixels, and\ndistributes it accross all "weighted" levels. The value relative to\nthe sum of all weights determines the width.'},subtree:{}},value:{meta:{types:{number:1},name:"value",excludes:{},default:1,description:"The value used for calculating the width of the ring. Its' affect is\ndetermined by `levelSize.unit`."},subtree:{}}}},levels:{meta:{types:{array:"Object"},name:"levels",excludes:{},description:"Set options on specific levels. Takes precedence over series options,\nbut not point options."},subtree:{borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},description:"Can set a `borderColor` on all points which lies on the same level."},subtree:{}},borderDashStyle:{meta:{types:{string:1},name:"borderDashStyle",excludes:{},description:"Can set a `borderDashStyle` on all points which lies on the same level."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},description:"Can set a `borderWidth` on all points which lies on the same level."},subtree:{}},color:{meta:{types:{color:1},name:"color",excludes:{},description:"Can set a `color` on all points which lies on the same level."},subtree:{}},colorVariation:{meta:{types:{object:1},name:"colorVariation",excludes:{},description:"Can set a `colorVariation` on all points which lies on the same level."},subtree:{key:{meta:{types:{string:1},name:"key",excludes:{},description:"The key of a color variation. Currently supports `brightness` only."},subtree:{}},to:{meta:{types:{number:1},name:"to",excludes:{},description:"The ending value of a color variation. The last sibling will receive this\nvalue."},subtree:{}}}},levelSize:{meta:{types:{object:1},name:"levelSize",excludes:{},description:"Can set a `levelSize` on all points which lies on the same level."},subtree:{}},rotation:{meta:{types:{number:1},name:"rotation",excludes:{},description:"Can set a `rotation` on all points which lies on the same level."},subtree:{}},rotationMode:{meta:{types:{string:1},name:"rotationMode",excludes:{},description:"Can set a `rotationMode` on all points which lies on the same level."},subtree:{}}}},rootId:{meta:{types:{string:1,undefined:1},name:"rootId",excludes:{},default:"undefined",description:"Which point to use as a root in the visualization."},subtree:{}},slicedOffset:{meta:{types:{number:1},name:"slicedOffset",excludes:{},default:10,description:"If a point is sliced, moved out from the center, how many pixels\nshould it be moved?."},subtree:{}}}},tilemap:{meta:{types:{object:1},name:"tilemap",excludes:{},products:{highcharts:1,highmaps:1},description:"A tilemap series is a type of heatmap where the tile shapes are configurable.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `tilemap` series are defined in\n [plotOptions.tilemap](plotOptions.tilemap).\n3. Options for one single series are given in\n [the series instance array](series.tilemap).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        tilemap: {\n            // shared options for all tilemap series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'tilemap'\n    }]\n});\n
    \n ",extends:"plotOptions.heatmap"},subtree:{colsize:{meta:{types:{number:1},name:"colsize",excludes:{},default:"1",products:{highcharts:1,highmaps:1},description:"The column size - how many X axis units each column in the tilemap\nshould span. Works as in [Heatmaps](#plotOptions.heatmap.colsize)."},subtree:{}},pointPadding:{meta:{types:{number:1},name:"pointPadding",excludes:{},default:2,description:"The padding between points in the tilemap."},subtree:{}},rowsize:{meta:{types:{number:1},name:"rowsize",excludes:{},default:"1",products:{highcharts:1,highmaps:1},description:"The row size - how many Y axis units each tilemap row should span.\nAnalogous to [colsize](#plotOptions.tilemap.colsize)."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{}},subtree:{halo:{meta:{types:{object:1},name:"halo",excludes:{}},subtree:{attributes:{meta:{types:{object:1},name:"attributes",excludes:{}},subtree:{zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},default:3},subtree:{}}}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0},subtree:{}},opacity:{meta:{types:{number:1},name:"opacity",excludes:{},default:.5},subtree:{}},size:{meta:{types:{number:1},name:"size",excludes:{},default:2},subtree:{}}}}}}}},tileShape:{meta:{types:{string:1},name:"tileShape",excludes:{},default:"hexagon",description:"The shape of the tiles in the tilemap. Possible values are `hexagon`,\n`circle`, `diamond`, and `square`."},subtree:{}}}},treemap:{meta:{types:{object:1},name:"treemap",excludes:{},products:{highcharts:1},description:"A treemap displays hierarchical data using nested rectangles. The data can be\nlaid out in varying ways depending on options.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `treemap` series are defined in\n [plotOptions.treemap](plotOptions.treemap).\n3. Options for one single series are given in\n [the series instance array](series.treemap).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        treemap: {\n            // shared options for all treemap series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'treemap'\n    }]\n});\n
    \n ",extends:"plotOptions.scatter"},subtree:{allowDrillToNode:{meta:{types:{boolean:1},name:"allowDrillToNode",excludes:{},default:"false",products:{highcharts:1},description:"When enabled the user can click on a point which is a parent and\nzoom in on its children."},subtree:{}},alternateStartingDirection:{meta:{types:{boolean:1},name:"alternateStartingDirection",excludes:{},default:"false",products:{highcharts:1},description:"Enabling this option will make the treemap alternate the drawing\ndirection between vertical and horizontal. The next levels starting\ndirection will always be the opposite of the previous."},subtree:{}},borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},default:"#e6e6e6",products:{highcharts:1},description:"The color of the border surrounding each tree map item."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:1,description:"The width of the border surrounding each tree map item."},subtree:{}},colorByPoint:{meta:{types:{boolean:1},name:"colorByPoint",excludes:{},default:"false",description:"When using automatic point colors pulled from the `options.colors`\ncollection, this option determines whether the chart should receive\none color per series or one color per point."},subtree:{}},colors:{meta:{types:{array:"Color"},name:"colors",excludes:{},description:"A series specific or series type specific color set to apply instead\nof the global [colors](#colors) when [colorByPoint](\n#plotOptions.treemap.colorByPoint) is true."},subtree:{}},cropThreshold:{meta:{types:{number:1},name:"cropThreshold",excludes:{},default:"300",products:{highcharts:1},description:"When the series contains less points than the crop threshold, all\npoints are drawn, event if the points fall outside the visible plot\narea at the current zoom. The advantage of drawing all points (including\nmarkers and columns), is that animation is performed on updates.\nOn the other hand, when the series contains more points than the\ncrop threshold, the series data is cropped to only contain points\nthat fall within the plot area. The advantage of cropping away invisible\npoints is to increase performance on large series."},subtree:{}},dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{},products:{highcharts:1},extends:"plotOptions.heatmap.dataLabels"},subtree:{defer:{meta:{types:{boolean:1},name:"defer",excludes:{},default:!1},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0},subtree:{}},formatter:{meta:{types:{},name:"formatter",excludes:{}},subtree:{}},inside:{meta:{types:{boolean:1},name:"inside",excludes:{},default:!0},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"middle"},subtree:{}}}},drillUpButton:{meta:{types:{object:1},name:"drillUpButton",excludes:{},description:"Options for the button appearing when drilling down in a treemap."},subtree:{position:{meta:{types:{object:1},name:"position",excludes:{},description:"The position of the button."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"right",description:"Horizontal alignment of the button."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"top",description:"Vertical alignment of the button."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"-10",description:"Horizontal offset of the button."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:10,description:"Vertical offset of the button."},subtree:{}}}}}},ignoreHiddenPoint:{meta:{types:{boolean:1},name:"ignoreHiddenPoint",excludes:{},default:"true",products:{highcharts:1},description:"Whether to ignore hidden points when the layout algorithm runs.\nIf `false`, hidden points will leave open spaces."},subtree:{}},interactByLeaf:{meta:{types:{boolean:1},name:"interactByLeaf",excludes:{},products:{highcharts:1},description:"This option decides if the user can interact with the parent nodes\nor just the leaf nodes. When this option is undefined, it will be\ntrue by default. However when allowDrillToNode is true, then it will\nbe false by default."},subtree:{}},layoutAlgorithm:{meta:{types:{string:1},name:"layoutAlgorithm",excludes:{},default:"sliceAndDice",products:{highcharts:1},description:"This option decides which algorithm is used for setting position\nand dimensions of the points. Can be one of `sliceAndDice`, `stripes`,\n `squarified` or `strip`."},subtree:{}},layoutStartingDirection:{meta:{types:{string:1},name:"layoutStartingDirection",excludes:{},default:"vertical",products:{highcharts:1},description:'Defines which direction the layout algorithm will start drawing.\n Possible values are "vertical" and "horizontal".'},subtree:{}},levelIsConstant:{meta:{types:{boolean:1},name:"levelIsConstant",excludes:{},default:"true",products:{highcharts:1},description:"Used together with the levels and allowDrillToNode options. When\nset to false the first level visible when drilling is considered\nto be level one. Otherwise the level will be the same as the tree\nstructure."},subtree:{}},levels:{meta:{types:{array:"Object"},name:"levels",excludes:{},products:{highcharts:1},description:"Set options on specific levels. Takes precedence over series options,\nbut not point options."},subtree:{borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},products:{highcharts:1},description:"Can set a `borderColor` on all points which lies on the same level."},subtree:{}},borderDashStyle:{meta:{types:{string:1},name:"borderDashStyle",excludes:{},products:{highcharts:1},description:'Set the dash style of the border of all the point which lies on the\nlevel. See \nplotOptions.scatter.dashStyle for possible options.'},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},products:{highcharts:1},description:"Can set the borderWidth on all points which lies on the same level."},subtree:{}},color:{meta:{types:{color:1},name:"color",excludes:{},products:{highcharts:1},description:"Can set a color on all points which lies on the same level."},subtree:{}},colorVariation:{meta:{types:{object:1},name:"colorVariation",excludes:{},products:{highcharts:1},description:"A configuration object to define how the color of a child varies from the\nparent's color. The variation is distributed among the children of node.\nFor example when setting brightness, the brightness change will range\nfrom the parent's original brightness on the first child, to the amount\nset in the `to` setting on the last node. This allows a gradient-like\ncolor scheme that sets children out from each other while highlighting\nthe grouping on treemaps and sectors on sunburst charts."},subtree:{key:{meta:{types:{string:1},name:"key",excludes:{},products:{highcharts:1},description:"The key of a color variation. Currently supports `brightness` only."},subtree:{}},to:{meta:{types:{number:1},name:"to",excludes:{},products:{highcharts:1},description:"The ending value of a color variation. The last sibling will receive this\nvalue."},subtree:{}}}},layoutAlgorithm:{meta:{types:{string:1},name:"layoutAlgorithm",excludes:{},products:{highcharts:1},description:"Can set the layoutAlgorithm option on a specific level."},subtree:{}},layoutStartingDirection:{meta:{types:{string:1},name:"layoutStartingDirection",excludes:{},products:{highcharts:1},description:"Can set the layoutStartingDirection option on a specific level."},subtree:{}},level:{meta:{types:{number:1},name:"level",excludes:{},products:{highcharts:1},description:"Decides which level takes effect from the options set in the levels\nobject."},subtree:{}}}},opacity:{meta:{types:{number:1},name:"opacity",excludes:{},default:"0.15",products:{highcharts:1},description:"The opacity of a point in treemap. When a point has children, the\nvisibility of the children is determined by the opacity."},subtree:{}},showInLegend:{meta:{types:{boolean:1},name:"showInLegend",excludes:{},default:"false",products:{highcharts:1},description:"Whether to display this series type or specific series item in the\nlegend."},subtree:{}},sortIndex:{meta:{types:{number:1},name:"sortIndex",excludes:{},products:{highcharts:1},description:"The sort index of the point inside the treemap level."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{},products:{highcharts:1},description:"A wrapper object for all the series options in specific states.",extends:"plotOptions.heatmap.states"},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{},products:{highcharts:1},description:"Options for the hovered series",extends:"plotOptions.heatmap.states.hover"},subtree:{borderColor:{meta:{types:{string:1},name:"borderColor",excludes:{},default:"#999999",description:"The border color for the hovered state."},subtree:{}},brightness:{meta:{types:{number:1},name:"brightness",excludes:{},default:"null",description:"Brightness for the hovered point. Defaults to 0 if the heatmap\nseries is loaded first, otherwise 0.1."},subtree:{}},halo:{meta:{types:{boolean:1},name:"halo",excludes:{},default:!1,extends:"plotOptions.heatmap.states.hover.halo"},subtree:{}},opacity:{meta:{types:{number:1},name:"opacity",excludes:{},default:"0.75",products:{highcharts:1},description:"The opacity of a point in treemap. When a point has children,\nthe visibility of the children is determined by the opacity."},subtree:{}},shadow:{meta:{types:{boolean:1},name:"shadow",excludes:{},default:!1,description:"The shadow option for hovered state."},subtree:{}}}}}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{headerFormat:{meta:{types:{string:1},name:"headerFormat",excludes:{},default:""},subtree:{}},pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:"{point.name}: {point.value}
    "},subtree:{}}}}}},variablepie:{meta:{types:{object:1},name:"variablepie",excludes:{},products:{highcharts:1},description:"A variable pie series is a two dimensional series type, where each point\nrenders an Y and Z value. Each point is drawn as a pie slice where the\nsize (arc) of the slice relates to the Y value and the radius of pie\nslice relates to the Z value. Requires `highcharts-more.js`.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `variablepie` series are defined in\n [plotOptions.variablepie](plotOptions.variablepie).\n3. Options for one single series are given in\n [the series instance array](series.variablepie).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        variablepie: {\n            // shared options for all variablepie series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'variablepie'\n    }]\n});\n
    \n ",extends:"plotOptions.pie"},subtree:{maxPointSize:{meta:{types:{number:1,string:1},name:"maxPointSize",excludes:{},default:"100%",products:{highcharts:1},description:"The maximum size of the points' radius related to chart's `plotArea`.\nIf a number is set, it applies in pixels."},subtree:{}},minPointSize:{meta:{types:{number:1,string:1},name:"minPointSize",excludes:{},default:"10%",products:{highcharts:1},description:"The minimum size of the points' radius related to chart's `plotArea`.\nIf a number is set, it applies in pixels."},subtree:{}},sizeBy:{meta:{types:{string:1},name:"sizeBy",excludes:{},default:"area",products:{highcharts:1},description:"Whether the pie slice's value should be represented by the area\nor the radius of the slice. Can be either `area` or `radius`. The\ndefault, `area`, corresponds best to the human perception of the size\nof each pie slice."},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:' {series.name}
    Value: {point.y}
    Size: {point.z}
    '},subtree:{}}}},zMax:{meta:{types:{number:1},name:"zMax",excludes:{},products:{highcharts:1},description:"The maximum possible z value for the point's radius calculation. If\nthe point's Z value is bigger than zMax, the slice will be drawn\naccording to the zMax value"},subtree:{}},zMin:{meta:{types:{number:1},name:"zMin",excludes:{},products:{highcharts:1},description:"The minimum possible z value for the point's radius calculation.\nIf the point's Z value is smaller than zMin, the slice will be drawn\naccording to the zMin value."},subtree:{}}}},variwide:{meta:{types:{object:1},name:"variwide",excludes:{},products:{highcharts:1},description:"A variwide chart (related to marimekko chart) is a column chart with a\nvariable width expressing a third dimension.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `variwide` series are defined in\n [plotOptions.variwide](plotOptions.variwide).\n3. Options for one single series are given in\n [the series instance array](series.variwide).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        variwide: {\n            // shared options for all variwide series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'variwide'\n    }]\n});\n
    \n ",extends:"plotOptions.column"},subtree:{groupPadding:{meta:{types:{number:1},name:"groupPadding",excludes:{},default:0,description:"In a variwide chart, the group padding is 0 in order to express the\nhorizontal stacking of items."},subtree:{}},pointPadding:{meta:{types:{number:1},name:"pointPadding",excludes:{},default:0,description:"In a variwide chart, the point padding is 0 in order to express the\nhorizontal stacking of items."},subtree:{}}}},vbp:{meta:{types:{object:1},name:"vbp",excludes:{},products:{highstock:1},description:"Volume By Price indicator.\n\nThis series requires `linkedTo` option to be set.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `vbp` series are defined in\n [plotOptions.vbp](plotOptions.vbp).\n3. Options for one single series are given in\n [the series instance array](series.vbp).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        vbp: {\n            // shared options for all vbp series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'vbp'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{animationLimit:{meta:{types:{number:1},name:"animationLimit",excludes:{},default:1e3},subtree:{}},crisp:{meta:{types:{boolean:1},name:"crisp",excludes:{},default:!0},subtree:{}},dataGrouping:{meta:{types:{object:1},name:"dataGrouping",excludes:{}},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1},subtree:{}}}},dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{}},subtree:{allowOverlap:{meta:{types:{boolean:1},name:"allowOverlap",excludes:{},default:!0},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0},subtree:{}},format:{meta:{types:{string:1},name:"format",excludes:{},default:"P: {point.volumePos:.2f} | N: {point.volumeNeg:.2f}"},subtree:{}},padding:{meta:{types:{number:1},name:"padding",excludes:{},default:0},subtree:{}},style:{meta:{types:{object:1},name:"style",excludes:{}},subtree:{fontSize:{meta:{types:{string:1},name:"fontSize",excludes:{},default:"7px"},subtree:{}}}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"top"},subtree:{}}}},enableMouseTracking:{meta:{types:{boolean:1},name:"enableMouseTracking",excludes:{},default:!1},subtree:{}},params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{ranges:{meta:{types:{number:1},name:"ranges",excludes:{},default:12,products:{highstock:1},description:"The number of price zones."},subtree:{}},volumeSeriesID:{meta:{types:{string:1},name:"volumeSeriesID",excludes:{},default:"volume",products:{highstock:1},description:"The id of volume series which is mandatory. For example using\nOHLC data, volumeSeriesID='volume' means the indicator will be\ncalculated using OHLC and volume values."},subtree:{}}}},pointPadding:{meta:{types:{number:1},name:"pointPadding",excludes:{},default:0},subtree:{}},volumeDivision:{meta:{types:{object:1},name:"volumeDivision",excludes:{},products:{highstock:1},description:"The styles for bars when volume is divided into positive/negative."},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0,products:{highstock:1},description:"Option to control if volume is divided."},subtree:{}},styles:{meta:{types:{object:1},name:"styles",excludes:{}},subtree:{negativeColor:{meta:{types:{color:1},name:"negativeColor",excludes:{},default:"rgba(244, 91, 91, 0.8)",products:{highstock:1},description:"Color of negative volume bars."},subtree:{}},positiveColor:{meta:{types:{color:1},name:"positiveColor",excludes:{},default:"rgba(144, 237, 125, 0.8)",products:{highstock:1},description:"Color of positive volume bars."},subtree:{}}}}}},zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},default:-1},subtree:{}},zoneLines:{meta:{types:{object:1},name:"zoneLines",excludes:{},products:{highstock:1},description:"The styles for lines which determine price zones."},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",products:{highstock:1},description:"Enable/disable zone lines."},subtree:{}},styles:{meta:{types:{object:1},name:"styles",excludes:{}},subtree:{color:{meta:{types:{color:1},name:"color",excludes:{},default:"#0A9AC9",products:{highstock:1},description:"Color of zone lines."},subtree:{}},dashStyle:{meta:{types:{string:1},name:"dashStyle",excludes:{},default:"LongDash",products:{highstock:1},description:"The dash style of zone lines."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highstock:1},description:"Pixel width of zone lines."},subtree:{}}}}}}}},vector:{meta:{types:{object:1},name:"vector",excludes:{},products:{highcharts:1,highstock:1},description:"A vector plot is a type of cartesian chart where each point has an X and Y\nposition, a length and a direction. Vectors are drawn as arrows.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `vector` series are defined in\n [plotOptions.vector](plotOptions.vector).\n3. Options for one single series are given in\n [the series instance array](series.vector).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        vector: {\n            // shared options for all vector series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'vector'\n    }]\n});\n
    \n ", extends:"plotOptions.scatter"},subtree:{lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:2,description:"The line width for each vector arrow."},subtree:{}},rotationOrigin:{meta:{types:{string:1},name:"rotationOrigin",excludes:{},default:"center",description:"What part of the vector it should be rotated around. Can be one of\n`start`, `center` and `end`. When `start`, the vectors will start from\nthe given [x, y] position, and when `end` the vectors will end in the\n[x, y] position."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{}},subtree:{lineWidthPlus:{meta:{types:{number:1},name:"lineWidthPlus",excludes:{},default:1,description:"Additonal line width for the vector errors when they are hovered."},subtree:{}}}}}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:"[{point.x}, {point.y}]
    Length: {point.length}
    Direction: {point.direction}°
    "},subtree:{}}}},vectorLength:{meta:{types:{number:1},name:"vectorLength",excludes:{},default:20,description:"Maximum length of the arrows in the vector plot. The individual arrow\nlength is computed between 0 and this value."},subtree:{}}}},vwap:{meta:{types:{object:1},name:"vwap",excludes:{},products:{highstock:1},description:"Volume Weighted Average Price indicator.\n\nThis series requires `linkedTo` option to be set.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `vwap` series are defined in\n [plotOptions.vwap](plotOptions.vwap).\n3. Options for one single series are given in\n [the series instance array](series.vwap).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        vwap: {\n            // shared options for all vwap series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'vwap'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{period:{meta:{types:{number:1},name:"period",excludes:{},default:30},subtree:{}},volumeSeriesID:{meta:{types:{string:1},name:"volumeSeriesID",excludes:{},default:"volume",products:{highstock:1},description:"The id of volume series which is mandatory. For example using\nOHLC data, volumeSeriesID='volume' means the indicator will be\ncalculated using OHLC and volume values."},subtree:{}}}}}},waterfall:{meta:{types:{object:1},name:"waterfall",excludes:{},products:{highcharts:1},description:"A waterfall chart displays sequentially introduced positive or negative\nvalues in cumulative columns.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `waterfall` series are defined in\n [plotOptions.waterfall](plotOptions.waterfall).\n3. Options for one single series are given in\n [the series instance array](series.waterfall).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        waterfall: {\n            // shared options for all waterfall series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'waterfall'\n    }]\n});\n
    \n ",extends:"{plotOptions.column}"},subtree:{borderColor:{meta:{types:{color:1},name:"borderColor",excludes:{},default:"#333333",products:{highcharts:1},description:"The color of the border of each waterfall column.\n\nIn styled mode, the border stroke can be set with the\n`.highcharts-point` class."},subtree:{}},dashStyle:{meta:{types:{string:1},name:"dashStyle",excludes:{},default:"Dot",products:{highcharts:1},description:"A name for the dash style to use for the line connecting the columns\nof the waterfall series. Possible values:\n\n* Solid\n* ShortDash\n* ShortDot\n* ShortDashDot\n* ShortDashDotDot\n* Dot\n* Dash\n* LongDash\n* DashDot\n* LongDashDot\n* LongDashDotDot\n\nIn styled mode, the stroke dash-array can be set with the\n`.highcharts-graph` class."},subtree:{}},dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{}},subtree:{inside:{meta:{types:{boolean:1},name:"inside",excludes:{},default:!0},subtree:{}}}},lineColor:{meta:{types:{color:1},name:"lineColor",excludes:{},default:"#333333",products:{highcharts:1},description:"The color of the line that connects columns in a waterfall series.\n\nIn styled mode, the stroke can be set with the `.highcharts-graph` class."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,products:{highcharts:1},description:"The width of the line connecting waterfall columns."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{}},subtree:{lineWidthPlus:{meta:{types:{number:1},name:"lineWidthPlus",excludes:{},default:0},subtree:{}}}}}},upColor:{meta:{types:{color:1},name:"upColor",excludes:{},products:{highcharts:1},description:"The color used specifically for positive point columns. When not\nspecified, the general series color is used.\n\nIn styled mode, the waterfall colors can be set with the\n`.highcharts-point-negative`, `.highcharts-sum` and\n`.highcharts-intermediate-sum` classes."},subtree:{}}}},windbarb:{meta:{types:{object:1},name:"windbarb",excludes:{},products:{highcharts:1,highstock:1},description:"Wind barbs are a convenient way to represent wind speed and direction in one\ngraphical form. Wind direction is given by the stem direction, and wind speed\nby the number and shape of barbs.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `windbarb` series are defined in\n [plotOptions.windbarb](plotOptions.windbarb).\n3. Options for one single series are given in\n [the series instance array](series.windbarb).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        windbarb: {\n            // shared options for all windbarb series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'windbarb'\n    }]\n});\n
    \n ",extends:"plotOptions.column"},subtree:{lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:2,description:"The line width of the wind barb symbols."},subtree:{}},onSeries:{meta:{types:{string:1,null:1},name:"onSeries",excludes:{},default:null,description:"The id of another series in the chart that the wind barbs are projected\non. When `null`, the wind symbols are drawn on the X axis, but offset\nup or down by the `yOffset` setting."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{}},subtree:{hover:{meta:{types:{object:1},name:"hover",excludes:{}},subtree:{lineWidthPlus:{meta:{types:{number:1},name:"lineWidthPlus",excludes:{},default:0},subtree:{}}}}}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:' {series.name}: {point.value} ({point.beaufort})
    ',description:"The default point format for the wind barb tooltip. Note the\n`point.beaufort` property that refers to the Beaufort wind scale. The\nnames can be internationalized by modifying\n`Highcharts.seriesTypes.windbarb.prototype.beaufortNames`."},subtree:{}}}},vectorLength:{meta:{types:{number:1},name:"vectorLength",excludes:{},default:20,description:"Pixel length of the stems."},subtree:{}},xOffset:{meta:{types:{number:1},name:"xOffset",excludes:{},default:0,description:"Horizontal offset from the cartesian position, in pixels. When the chart\nis inverted, this option allows translation like\n[yOffset](#plotOptions.windbarb.yOffset) in non inverted charts."},subtree:{}},yOffset:{meta:{types:{number:1},name:"yOffset",excludes:{},default:-20,description:"Vertical offset from the cartesian position, in pixels. The default value\nmakes sure the symbols don't overlap the X axis when `onSeries` is\n`null`, and that they don't overlap the linked series when `onSeries` is\ngiven."},subtree:{}}}},wma:{meta:{types:{object:1},name:"wma",excludes:{},products:{highstock:1},description:"Weighted moving average indicator (WMA). This series requires `linkedTo`\noption to be set.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `wma` series are defined in\n [plotOptions.wma](plotOptions.wma).\n3. Options for one single series are given in\n [the series instance array](series.wma).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        wma: {\n            // shared options for all wma series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'wma'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{index:{meta:{types:{number:1},name:"index",excludes:{},default:3},subtree:{}},period:{meta:{types:{number:1},name:"period",excludes:{},default:9},subtree:{}}}}}},wordcloud:{meta:{types:{object:1},name:"wordcloud",excludes:{},products:{highcharts:1},description:"A word cloud is a visualization of a set of words, where the size and\nplacement of a word is determined by how it is weighted.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `wordcloud` series are defined in\n [plotOptions.wordcloud](plotOptions.wordcloud).\n3. Options for one single series are given in\n [the series instance array](series.wordcloud).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        wordcloud: {\n            // shared options for all wordcloud series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'wordcloud'\n    }]\n});\n
    \n ",extends:"plotOptions.column"},subtree:{allowExtendPlayingField:{meta:{types:{boolean:1},name:"allowExtendPlayingField",excludes:{},default:!0,description:"If there is no space for a word on the playing field, then this option\nwill allow the playing field to be extended to fit the word.\nIf false then the word will be dropped from the visualization.\nNB! This option is currently not decided to be published in the API, and\nis therefore marked as private."},subtree:{}},animation:{meta:{types:{object:1},name:"animation",excludes:{}},subtree:{duration:{meta:{types:{number:1},name:"duration",excludes:{},default:500},subtree:{}}}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:0},subtree:{}},clip:{meta:{types:{boolean:1},name:"clip",excludes:{},default:!1},subtree:{}},colorByPoint:{meta:{types:{boolean:1},name:"colorByPoint",excludes:{},default:!0,description:"When using automatic point colors pulled from the `options.colors`\ncollection, this option determines whether the chart should receive\none color per series or one color per point."},subtree:{}},maxFontSize:{meta:{types:{number:1},name:"maxFontSize",excludes:{},default:25,description:"The word with the largest weight will have a font size equal to this\nvalue. The font size of a word is the ratio between its weight and the\nlargest occuring weight, multiplied with the value of maxFontSize."},subtree:{}},minFontSize:{meta:{types:{number:1},name:"minFontSize",excludes:{},default:1,description:"A threshold determining the minimum font size that can be applied to a\nword."},subtree:{}},placementStrategy:{meta:{types:{string:1},name:"placementStrategy",excludes:{},default:"center",description:"This option decides which algorithm is used for placement, and rotation\nof a word. The choice of algorith is therefore a crucial part of the\nresulting layout of the wordcloud.\nIt is possible for users to add their own custom placement strategies\nfor use in word cloud. Read more about it in our\n[documentation](https://www.highcharts.com/docs/chart-and-series-types/word-cloud-series#custom-placement-strategies)"},subtree:{}},rotation:{meta:{types:{object:1},name:"rotation",excludes:{},description:"Rotation options for the words in the wordcloud."},subtree:{from:{meta:{types:{number:1},name:"from",excludes:{},default:0,description:"The smallest degree of rotation for a word."},subtree:{}},orientations:{meta:{types:{number:1},name:"orientations",excludes:{},default:2,description:"The number of possible orientations for a word, within the range of\n`rotation.from` and `rotation.to`."},subtree:{}},to:{meta:{types:{number:1},name:"to",excludes:{},default:90,description:"The largest degree of rotation for a word."},subtree:{}}}},showInLegend:{meta:{types:{boolean:1},name:"showInLegend",excludes:{},default:!1},subtree:{}},spiral:{meta:{types:{string:1},name:"spiral",excludes:{},default:"rectangular",description:"Spiral used for placing a word after the initial position experienced a\ncollision with either another word or the borders.\nIt is possible for users to add their own custom spiralling algorithms\nfor use in word cloud. Read more about it in our\n[documentation](https://www.highcharts.com/docs/chart-and-series-types/word-cloud-series#custom-spiralling-algorithm)"},subtree:{}},style:{meta:{types:{cssobject:1},name:"style",excludes:{},default:'{"fontFamily":"sans-serif", "fontWeight": "900"}',description:"CSS styles for the words."},subtree:{fontFamily:{meta:{types:{string:1},name:"fontFamily",excludes:{},default:"sans-serif"},subtree:{}},fontWeight:{meta:{types:{number:1,string:1},name:"fontWeight",excludes:{},default:"900"},subtree:{}}}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{followPointer:{meta:{types:{boolean:1},name:"followPointer",excludes:{},default:!0},subtree:{}},pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:' {series.name}: {point.weight}
    '},subtree:{}}}}}},xrange:{meta:{types:{object:1},name:"xrange",excludes:{},products:{highcharts:1,highstock:1},description:"The X-range series displays ranges on the X axis, typically time intervals\nwith a start and end date.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `xrange` series are defined in\n [plotOptions.xrange](plotOptions.xrange).\n3. Options for one single series are given in\n [the series instance array](series.xrange).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        xrange: {\n            // shared options for all xrange series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'xrange'\n    }]\n});\n
    \n ",extends:"{plotOptions.column}"},subtree:{borderRadius:{meta:{types:{number:1},name:"borderRadius",excludes:{},default:3},subtree:{}},colorByPoint:{meta:{types:{boolean:1},name:"colorByPoint",excludes:{},default:!0,description:"In an X-range series, this option makes all points of the same Y-axis\ncategory the same color."},subtree:{}},dataLabels:{meta:{types:{object:1},name:"dataLabels",excludes:{}},subtree:{formatter:{meta:{types:{},name:"formatter",excludes:{},description:"The default formatter for X-range data labels displays the percentage\nof the partial fill amount."},subtree:{}},inside:{meta:{types:{boolean:1},name:"inside",excludes:{},default:!0},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"middle"},subtree:{}}}},partialFill:{meta:{types:{object:1},name:"partialFill",excludes:{},products:{highcharts:1,highstock:1},description:"A partial fill for each point, typically used to visualize how much of\na task is performed. The partial fill object can be set either on series\nor point level."},subtree:{fill:{meta:{types:{color:1},name:"fill",excludes:{},products:{highcharts:1,highstock:1},description:"The fill color to be used for partial fills. Defaults to a darker shade\nof the point color."},subtree:{}}}},pointRange:{meta:{types:{number:1},name:"pointRange",excludes:{},default:0},subtree:{}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{headerFormat:{meta:{types:{string:1},name:"headerFormat",excludes:{},default:'{point.x} - {point.x2}
    '},subtree:{}},pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:' {series.name}: {point.yCategory}
    '},subtree:{}}}}}},zigzag:{meta:{types:{object:1},name:"zigzag",excludes:{},products:{highstock:1},description:"Zig Zag indicator.\n\nThis series requires `linkedTo` option to be set.\n\nConfiguration options for the series are given in three levels:\n1. Options for all series in a chart are defined in the\n [plotOptions.series](plotOptions.series) object.\n2. Options for all `zigzag` series are defined in\n [plotOptions.zigzag](plotOptions.zigzag).\n3. Options for one single series are given in\n [the series instance array](series.zigzag).\n\n
    \nHighcharts.chart('container', {\n    plotOptions: {\n        series: {\n            // general options for all series\n        },\n        zigzag: {\n            // shared options for all zigzag series\n        }\n    },\n    series: [{\n        // specific options for this series instance\n        type: 'zigzag'\n    }]\n});\n
    \n ",extends:"plotOptions.sma"},subtree:{params:{meta:{types:{object:1},name:"params",excludes:{}},subtree:{deviation:{meta:{types:{number:1},name:"deviation",excludes:{},default:1,products:{highstock:1},description:"The threshold for the value change.\n\nFor example deviation=1 means the indicator will ignore all price\nmovements less than 1%."},subtree:{}},highIndex:{meta:{types:{number:1},name:"highIndex",excludes:{},default:1,products:{highstock:1},description:"The point index which indicator calculations will base - high\nvalue.\n\nFor example using OHLC data, index=1 means the indicator will be\ncalculated using High values."},subtree:{}},lowIndex:{meta:{types:{number:1},name:"lowIndex",excludes:{},default:2,products:{highstock:1},description:"The point index which indicator calculations will base - low\nvalue.\n\nFor example using OHLC data, index=2 means the indicator will be\ncalculated using Low values."},subtree:{}}}}}}}},rangeSelector:{meta:{types:{object:1},name:"rangeSelector",excludes:{},products:{highstock:1},description:"The range selector is a tool for selecting ranges to display within\nthe chart. It provides buttons to select preconfigured ranges in\nthe chart, like 1 day, 1 week, 1 month etc. It also provides input\nboxes where min and max dates can be manually input."},subtree:{allButtonsEnabled:{meta:{types:{boolean:1},name:"allButtonsEnabled",excludes:{},default:"false",products:{highstock:1},description:"Whether to enable all buttons from the start. By default buttons are\nonly enabled if the corresponding time range exists on the X axis,\nbut enabling all buttons allows for dynamically loading different\ntime ranges."},subtree:{}},buttonPosition:{meta:{types:{"*":1},name:"buttonPosition",excludes:{},products:{highstock:1},description:"Positioning for the button row."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"left",description:"The alignment of the input box. Allowed properties are `left`,\n`center`, `right`."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"0",description:"X offset of the button row."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:"0",description:"Y offset of the button row."},subtree:{}}}},buttonSpacing:{meta:{types:{number:1},name:"buttonSpacing",excludes:{},default:"0",products:{highstock:1},description:"The space in pixels between the buttons in the range selector."},subtree:{}},buttonTheme:{meta:{types:{"highcharts.cssobject":1},name:"buttonTheme",excludes:{},products:{highstock:1},description:"A collection of attributes for the buttons. The object takes SVG\nattributes like `fill`, `stroke`, `stroke-width`, as well as `style`,\na collection of CSS properties for the text.\n\nThe object can also be extended with states, so you can set\npresentational options for `hover`, `select` or `disabled` button\nstates.\n\nCSS styles for the text label.\n\nIn styled mode, the buttons are styled by the\n`.highcharts-range-selector-buttons .highcharts-button` rule with its\ndifferent states."},subtree:{height:{meta:{types:{number:1},name:"height",excludes:{},default:18},subtree:{}},padding:{meta:{types:{number:1},name:"padding",excludes:{},default:2},subtree:{}},width:{meta:{types:{number:1},name:"width",excludes:{},default:28},subtree:{}},zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},default:7},subtree:{}}}},buttons:{meta:{types:{array:"*"},name:"buttons",excludes:{},products:{highstock:1},description:"An array of configuration objects for the buttons.\n\nDefaults to\n\n
    buttons: [{\n    type: 'month',\n    count: 1,\n    text: '1m'\n}, {\n    type: 'month',\n    count: 3,\n    text: '3m'\n}, {\n    type: 'month',\n    count: 6,\n    text: '6m'\n}, {\n    type: 'ytd',\n    text: 'YTD'\n}, {\n    type: 'year',\n    count: 1,\n    text: '1y'\n}, {\n    type: 'all',\n    text: 'All'\n}]
    "},subtree:{count:{meta:{types:{number:1},name:"count",excludes:{},default:"1",products:{highstock:1},description:'How many units of the defined type the button should span. If `type`\nis "month" and `count` is 3, the button spans three months.'},subtree:{}},dataGrouping:{meta:{types:{"*":1},name:"dataGrouping",excludes:{},products:{highstock:1},description:"A custom data grouping object for each button.",extends:"plotOptions.series.dataGrouping"},subtree:{}},events:{meta:{types:{object:1},name:"events",excludes:{}},subtree:{click:{meta:{types:{function:1},name:"click",excludes:{},products:{highstock:1},description:"Fires when clicking on the rangeSelector button. One parameter,\nevent, is passed to the function, containing common event\ninformation.\n\n
    \nclick: function(e) {\n  console.log(this);\n}\n
    \n\nReturn false to stop default button's click action."},subtree:{}}}},offsetMax:{meta:{types:{number:1},name:"offsetMax",excludes:{},default:"0",products:{highstock:1},description:"Additional range (in milliseconds) added to the end of the calculated\ntime span."},subtree:{}},offsetMin:{meta:{types:{number:1},name:"offsetMin",excludes:{},default:"0",products:{highstock:1},description:"Additional range (in milliseconds) added to the start of the\ncalculated time span."},subtree:{}},preserveDataGrouping:{meta:{types:{boolean:1},name:"preserveDataGrouping",excludes:{},default:"false",products:{highstock:1},description:"When buttons apply dataGrouping on a series, by deafault zooming\nin/out will deselect buttons and unset dataGrouping. Enable this\noption to keep buttons selected when extremes change."},subtree:{}},text:{meta:{types:{string:1},name:"text",excludes:{},products:{highstock:1},description:"The text for the button itself."},subtree:{}},type:{meta:{types:{string:1},name:"type",excludes:{},products:{highstock:1},description:"Defined the time span for the button. Can be one of `millisecond`,\n`second`, `minute`, `hour`, `day`, `week`, `month`, `ytd`, `all`."},subtree:{}}}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",products:{highstock:1},description:"Enable or disable the range selector."},subtree:{}},floating:{meta:{types:{boolean:1},name:"floating",excludes:{},default:"false",products:{highstock:1},description:"When the rangeselector is floating, the plot area does not reserve\nspace for it. This opens for positioning anywhere on the chart."},subtree:{}},height:{meta:{types:{number:1},name:"height",excludes:{},default:"undefined",products:{highstock:1},description:"Deprecated. The height of the range selector. Currently it is\ncalculated dynamically."},subtree:{}},inputBoxBorderColor:{meta:{types:{"highcharts.colorstring":1},name:"inputBoxBorderColor",excludes:{},default:"#cccccc",products:{highstock:1},description:"The border color of the date input boxes."},subtree:{}},inputBoxHeight:{meta:{types:{number:1},name:"inputBoxHeight",excludes:{},default:"17",products:{highstock:1},description:"The pixel height of the date input boxes."},subtree:{}},inputBoxStyle:{meta:{types:{"highcharts.cssobject":1},name:"inputBoxStyle",excludes:{},products:{highstock:1},description:"CSS for the container DIV holding the input boxes. Deprecated as\nof 1.2.5\\. Use [inputPosition](#rangeSelector.inputPosition) instead."},subtree:{}},inputBoxWidth:{meta:{types:{number:1},name:"inputBoxWidth",excludes:{},default:"90",products:{highstock:1},description:"The pixel width of the date input boxes."},subtree:{}},inputDateFormat:{meta:{types:{string:1},name:"inputDateFormat",excludes:{},default:"%b %e %Y,",products:{highstock:1},description:"The date format in the input boxes when not selected for editing.\nDefaults to `%b %e, %Y`."},subtree:{}},inputDateParser:{meta:{types:{function:1},name:"inputDateParser",excludes:{},products:{highstock:1},description:"A custom callback function to parse values entered in the input boxes\nand return a valid JavaScript time as milliseconds since 1970."},subtree:{}},inputEditDateFormat:{meta:{types:{string:1},name:"inputEditDateFormat",excludes:{},default:"%Y-%m-%d",products:{highstock:1},description:"The date format in the input boxes when they are selected for\nediting. This must be a format that is recognized by JavaScript\nDate.parse."},subtree:{}},inputEnabled:{meta:{types:{boolean:1},name:"inputEnabled",excludes:{},default:"true",products:{highstock:1},description:"Enable or disable the date input boxes. Defaults to enabled when\nthere is enough space, disabled if not (typically mobile)."},subtree:{}},inputPosition:{meta:{types:{"*":1},name:"inputPosition",excludes:{},products:{highstock:1},description:"Positioning for the input boxes. Allowed properties are `align`,\n `x` and `y`."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"right",description:"The alignment of the input box. Allowed properties are `left`,\n`center`, `right`."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"0",description:"X offset of the input row."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:"0",description:"Y offset of the input row."},subtree:{}}}},inputStyle:{meta:{types:{"highcharts.cssobject":1},name:"inputStyle",excludes:{},products:{highstock:1},description:"CSS for the HTML inputs in the range selector.\n\nIn styled mode, the inputs are styled by the\n`.highcharts-range-input text` rule in SVG mode, and\n`input.highcharts-range-selector` when active."},subtree:{}},labelStyle:{meta:{types:{"highcharts.cssobject":1},name:"labelStyle",excludes:{},products:{highstock:1},description:"CSS styles for the labels - the Zoom, From and To texts.\n\nIn styled mode, the labels are styled by the\n`.highcharts-range-label` class."},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#666666"},subtree:{}}}},selected:{meta:{types:{number:1},name:"selected",excludes:{},products:{highstock:1},description:"The index of the button to appear pre-selected."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},default:"top",description:"The vertical alignment of the rangeselector box. Allowed properties\nare `top`, `middle`, `bottom`."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"0",products:{highstock:1},description:"The x offset of the range selector relative to its horizontal\nalignment within `chart.spacingLeft` and `chart.spacingRight`."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:"0",products:{highstock:1},description:"The y offset of the range selector relative to its horizontal\nalignment within `chart.spacingLeft` and `chart.spacingRight`."},subtree:{}}}},responsive:{meta:{types:{object:1},name:"responsive",excludes:{},description:"Allows setting a set of rules to apply for different screen or chart\nsizes. Each rule specifies additional chart options."},subtree:{rules:{meta:{types:{array:"Object"},name:"rules",excludes:{},description:"A set of rules for responsive settings. The rules are executed from\nthe top down."},subtree:{chartOptions:{meta:{types:{object:1},name:"chartOptions",excludes:{},description:"A full set of chart options to apply as overrides to the general\nchart options. The chart options are applied when the given rule\nis active.\n\nA special case is configuration objects that take arrays, for example\n[xAxis](#xAxis), [yAxis](#yAxis) or [series](#series). For these\ncollections, an `id` option is used to map the new option set to\nan existing object. If an existing object of the same id is not found,\nthe item of the same indexupdated. So for example, setting `chartOptions`\nwith two series items without an `id`, will cause the existing chart's\ntwo series to be updated with respective options."},subtree:{}},condition:{meta:{types:{object:1},name:"condition",excludes:{},description:"Under which conditions the rule applies."},subtree:{callback:{meta:{types:{function:1},name:"callback",excludes:{},description:"A callback function to gain complete control on when the responsive\nrule applies. Return `true` if it applies. This opens for checking\nagainst other metrics than the chart size, or example the document\nsize or other elements."},subtree:{}},maxHeight:{meta:{types:{number:1},name:"maxHeight",excludes:{},description:"The responsive rule applies if the chart height is less than this."},subtree:{}},maxWidth:{meta:{types:{number:1},name:"maxWidth",excludes:{},description:"The responsive rule applies if the chart width is less than this."},subtree:{}},minHeight:{meta:{types:{number:1},name:"minHeight",excludes:{},default:"0",description:"The responsive rule applies if the chart height is greater than this."},subtree:{}},minWidth:{meta:{types:{number:1},name:"minWidth",excludes:{},default:"0",description:"The responsive rule applies if the chart width is greater than this."},subtree:{}}}}}}}},scrollbar:{meta:{types:{object:1},name:"scrollbar",excludes:{},products:{highstock:1},description:"The scrollbar is a means of panning over the X axis of a stock chart.\nScrollbars can also be applied to other types of axes.\n\nAnother approach to scrollable charts is the [chart.scrollablePlotArea](\nhttps://api.highcharts.com/highcharts/chart.scrollablePlotArea) option that\nis especially suitable for simpler cartesian charts on mobile.\n\nIn styled mode, all the presentational options for the\nscrollbar are replaced by the classes `.highcharts-scrollbar-thumb`,\n`.highcharts-scrollbar-arrow`, `.highcharts-scrollbar-button`,\n`.highcharts-scrollbar-rifles` and `.highcharts-scrollbar-track`."},subtree:{barBackgroundColor:{meta:{types:{"highcharts.colorstring":1},name:"barBackgroundColor", excludes:{},default:"#cccccc",products:{highstock:1},description:"The background color of the scrollbar itself."},subtree:{}},barBorderColor:{meta:{types:{"highcharts.colorstring":1},name:"barBorderColor",excludes:{},default:"#cccccc",products:{highstock:1},description:"The color of the scrollbar's border."},subtree:{}},barBorderRadius:{meta:{types:{number:1},name:"barBorderRadius",excludes:{},default:"0",products:{highstock:1},description:"The border rounding radius of the bar."},subtree:{}},barBorderWidth:{meta:{types:{number:1},name:"barBorderWidth",excludes:{},default:"1",products:{highstock:1},description:"The width of the bar's border."},subtree:{}},buttonArrowColor:{meta:{types:{"highcharts.colorstring":1},name:"buttonArrowColor",excludes:{},default:"#333333",products:{highstock:1},description:"The color of the small arrow inside the scrollbar buttons."},subtree:{}},buttonBackgroundColor:{meta:{types:{"highcharts.colorstring":1},name:"buttonBackgroundColor",excludes:{},default:"#e6e6e6",products:{highstock:1},description:"The color of scrollbar buttons."},subtree:{}},buttonBorderColor:{meta:{types:{"highcharts.colorstring":1},name:"buttonBorderColor",excludes:{},default:"#cccccc",products:{highstock:1},description:"The color of the border of the scrollbar buttons."},subtree:{}},buttonBorderRadius:{meta:{types:{number:1},name:"buttonBorderRadius",excludes:{},default:"0",products:{highstock:1},description:"The corner radius of the scrollbar buttons."},subtree:{}},buttonBorderWidth:{meta:{types:{number:1},name:"buttonBorderWidth",excludes:{},default:"1",products:{highstock:1},description:"The border width of the scrollbar buttons."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",products:{highstock:1},description:"Enable or disable the scrollbar."},subtree:{}},height:{meta:{types:{number:1},name:"height",excludes:{},default:"20/14",products:{highstock:1},description:"The height of the scrollbar. The height also applies to the width\nof the scroll arrows so that they are always squares. Defaults to\n20 for touch devices and 14 for mouse devices."},subtree:{}},liveRedraw:{meta:{types:{boolean:1},name:"liveRedraw",excludes:{},products:{highstock:1},description:"Whether to redraw the main chart as the scrollbar or the navigator\nzoomed window is moved. Defaults to `true` for modern browsers and\n`false` for legacy IE browsers as well as mobile devices."},subtree:{}},margin:{meta:{types:{number:1},name:"margin",excludes:{},default:"10",description:"The margin between the scrollbar and its axis when the scrollbar is\napplied directly to an axis."},subtree:{}},minWidth:{meta:{types:{number:1},name:"minWidth",excludes:{},default:"6",products:{highstock:1},description:"The minimum width of the scrollbar."},subtree:{}},rifleColor:{meta:{types:{"highcharts.colorstring":1},name:"rifleColor",excludes:{},default:"#333333",products:{highstock:1},description:"The color of the small rifles in the middle of the scrollbar."},subtree:{}},showFull:{meta:{types:{boolean:1},name:"showFull",excludes:{},default:"true",products:{highstock:1},description:"Whether to show or hide the scrollbar when the scrolled content is\nzoomed out to it full extent."},subtree:{}},step:{meta:{types:{number:1},name:"step",excludes:{},default:"0.2"},subtree:{}},trackBackgroundColor:{meta:{types:{"highcharts.colorstring":1},name:"trackBackgroundColor",excludes:{},default:"#f2f2f2",products:{highstock:1},description:"The color of the track background."},subtree:{}},trackBorderColor:{meta:{types:{"highcharts.colorstring":1},name:"trackBorderColor",excludes:{},default:"#f2f2f2",products:{highstock:1},description:"The color of the border of the scrollbar track."},subtree:{}},trackBorderRadius:{meta:{types:{number:1},name:"trackBorderRadius",excludes:{},default:"0",products:{highstock:1},description:"The corner radius of the border of the scrollbar track."},subtree:{}},trackBorderWidth:{meta:{types:{number:1},name:"trackBorderWidth",excludes:{},default:"1",products:{highstock:1},description:"The width of the border of the scrollbar track."},subtree:{}},zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},default:"3",description:"The z index of the scrollbar group."},subtree:{}}}},series:{meta:{types:{array:"series",object:1},name:"series",excludes:{},extends:",plotOptions.series,plotOptions.ad,plotOptions.area,plotOptions.arearange,plotOptions.areaspline,plotOptions.areasplinerange,plotOptions.atr,plotOptions.bar,plotOptions.bb,plotOptions.bellcurve,plotOptions.boxplot,plotOptions.bubble,plotOptions.bullet,plotOptions.candlestick,plotOptions.cci,plotOptions.cmf,plotOptions.column,plotOptions.columnrange,plotOptions.ema,plotOptions.errorbar,plotOptions.flags,plotOptions.funnel,plotOptions.gauge,plotOptions.heatmap,plotOptions.histogram,plotOptions.ikh,plotOptions.line,plotOptions.macd,plotOptions.map,plotOptions.mapbubble,plotOptions.mapline,plotOptions.mappoint,plotOptions.mfi,plotOptions.momentum,plotOptions.ohlc,plotOptions.pareto,plotOptions.pie,plotOptions.pivotpoints,plotOptions.polygon,plotOptions.priceenvelopes,plotOptions.psar,plotOptions.pyramid,plotOptions.roc,plotOptions.rsi,plotOptions.sankey,plotOptions.scatter,plotOptions.scatter3d,plotOptions.sma,plotOptions.solidgauge,plotOptions.spline,plotOptions.stochastic,plotOptions.streamgraph,plotOptions.sunburst,plotOptions.tilemap,plotOptions.treemap,plotOptions.variablepie,plotOptions.variwide,plotOptions.vbp,plotOptions.vector,plotOptions.vwap,plotOptions.waterfall,plotOptions.windbarb,plotOptions.wma,plotOptions.wordcloud,plotOptions.xrange,plotOptions.zigzag"},subtree:{id:{meta:{types:{string:1},name:"id",excludes:{},description:"An id for the series. This can be used after render time to get a\npointer to the series object through `chart.get()`."},subtree:{}},index:{meta:{types:{number:1},name:"index",excludes:{},description:"The index of the series in the chart, affecting the internal index\nin the `chart.series` array, the visible Z index as well as the order\nin the legend."},subtree:{}},legendIndex:{meta:{types:{number:1},name:"legendIndex",excludes:{},description:"The sequential index of the series in the legend."},subtree:{}},mapData:{meta:{types:{array:"Object"},name:"mapData",excludes:{},products:{highmaps:1},description:"An array of objects containing a `path` definition and optionally\na code or property to join in the data as per the `joinBy` option."},subtree:{}},name:{meta:{types:{string:1},name:"name",excludes:{},description:"The name of the series as shown in the legend, tooltip etc."},subtree:{}},stack:{meta:{types:{"*":1,string:1},name:"stack",excludes:{},products:{highcharts:1,highstock:1},description:"This option allows grouping series in a stacked chart. The stack option\ncan be a string or anything else, as long as the grouped series' stack\noptions match each other after conversion into a string."},subtree:{}},type:{meta:{types:{string:1},name:"type",excludes:{},description:"The type of series, for example `line` or `column`. By default, the\nseries type is inherited from [chart.type](#chart.type), so unless the\nchart is a combination of series types, there is no need to set it on the\nseries level."},subtree:{}},xAxis:{meta:{types:{number:1,string:1},name:"xAxis",excludes:{},default:"0",products:{highcharts:1,highstock:1},description:"When using dual or multiple x axes, this number defines which xAxis\nthe particular series is connected to. It refers to either the [axis\nid](#xAxis.id) or the index of the axis in the xAxis array, with\n0 being the first."},subtree:{}},yAxis:{meta:{types:{number:1,string:1},name:"yAxis",excludes:{},default:"0",products:{highcharts:1,highstock:1},description:"When using dual or multiple y axes, this number defines which yAxis\nthe particular series is connected to. It refers to either the [axis\nid](#yAxis.id) or the index of the axis in the yAxis array, with\n0 being the first."},subtree:{}},zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},products:{highcharts:1,highstock:1},description:"Define the visual z index of the series."},subtree:{}},states:{meta:{types:{object:1},name:"states",excludes:{},validFor:{bar:!0,bullet:!0,column:!0,columnrange:!0}},subtree:{hover:{meta:{types:{},name:"hover",excludes:{},products:{highcharts:1,highstock:1}},subtree:{}},select:{meta:{types:{},name:"select",excludes:{},products:{highcharts:1,highstock:1}},subtree:{}}}},baseSeries:{meta:{types:{number:1,string:1},name:"baseSeries",excludes:{},default:"undefined",validFor:{bellcurve:!0,histogram:!0,pareto:!0},description:"An integer identifying the index to use for the base series, or a string\nrepresenting the id of the series."},subtree:{}},marker:{meta:{types:{},name:"marker",excludes:{},validFor:{bubble:!0,mapbubble:!0}},subtree:{}},nodes:{meta:{types:{array:"Object"},name:"nodes",excludes:{},validFor:{sankey:!0},products:{highcharts:1},description:"A collection of options for the individual nodes. The nodes in a sankey\ndiagram are auto-generated instances of `Highcharts.Point`, but options can\nbe applied here and linked by the `id`."},subtree:{color:{meta:{types:{color:1},name:"color",excludes:{},products:{highcharts:1},description:"The color of the auto generated node."},subtree:{}},colorIndex:{meta:{types:{number:1},name:"colorIndex",excludes:{},products:{highcharts:1},description:"The color index of the auto generated node, especially for use in styled\nmode."},subtree:{}},column:{meta:{types:{number:1,undefined:1},name:"column",excludes:{},default:"undefined",products:{highcharts:1},description:"An optional column index of where to place the node. The default behaviour is\nto place it next to the preceding node."},subtree:{}},id:{meta:{types:{string:1},name:"id",excludes:{},products:{highcharts:1},description:"The id of the auto-generated node, refering to the `from` or `to` setting of\nthe link."},subtree:{}},name:{meta:{types:{string:1},name:"name",excludes:{},products:{highcharts:1},description:"The name to display for the node in data labels and tooltips. Use this when\nthe name is different from the `id`. Where the id must be unique for each\nnode, this is not necessary for the name."},subtree:{}},offset:{meta:{types:{number:1},name:"offset",excludes:{},default:"0",products:{highcharts:1},description:"The vertical offset of a node in terms of weight. Positive values shift the\nnode downwards, negative shift it upwards."},subtree:{}}}}}},subtitle:{meta:{types:{"*":1},name:"subtitle",excludes:{},description:"The chart's subtitle. This can be used both to display a subtitle below\nthe main title, and to display random text anywhere in the chart. The\nsubtitle can be updated after chart initialization through the\n`Chart.setTitle` method."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"center",description:'The horizontal alignment of the subtitle. Can be one of "left",\n "center" and "right".'},subtree:{}},floating:{meta:{types:{boolean:1},name:"floating",excludes:{},default:"false",description:"When the subtitle is floating, the plot area will not move to make\nspace for it."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},default:'{"color": "#666666"}',description:"CSS styles for the title.\n\nIn styled mode, the subtitle style is given in the\n`.highcharts-subtitle` class."},subtree:{}},text:{meta:{types:{string:1},name:"text",excludes:{},default:"",description:"The subtitle of the chart."},subtree:{}},useHTML:{meta:{types:{boolean:1},name:"useHTML",excludes:{},default:"false",description:"Whether to\n[use HTML](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting#html)\nto render the text."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},description:'The vertical alignment of the title. Can be one of "top", "middle"\nand "bottom". When a value is given, the title behaves as floating.'},subtree:{}},widthAdjust:{meta:{types:{number:1},name:"widthAdjust",excludes:{},default:"-44",description:"Adjustment made to the subtitle width, normally to reserve space\nfor the exporting burger menu."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"0",description:"The x position of the subtitle relative to the alignment within\n`chart.spacingLeft` and `chart.spacingRight`."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},description:"The y position of the subtitle relative to the alignment within\n`chart.spacingTop` and `chart.spacingBottom`. By default the subtitle\nis laid out below the title unless the title is floating."},subtree:{}}}},time:{meta:{types:{"*":1},name:"time",excludes:{},description:"Time options that can apply globally or to individual charts. These\nsettings affect how `datetime` axes are laid out, how tooltips are\nformatted, how series\n[pointIntervalUnit](#plotOptions.series.pointIntervalUnit) works and how\nthe Highstock range selector handles time.\n\nThe common use case is that all charts in the same Highcharts object\nshare the same time settings, in which case the global settings are set\nusing `setOptions`.\n\n```js\n// Apply time settings globally\nHighcharts.setOptions({\n time: {\n timezone: 'Europe/London'\n }\n});\n// Apply time settings by instance\nvar chart = Highcharts.chart('container', {\n time: {\n timezone: 'America/New_York'\n },\n series: [{\n data: [1, 4, 3, 5]\n }]\n});\n\n// Use the Time object\nconsole.log(\n 'Current time in New York',\n chart.time.dateFormat('%Y-%m-%d %H:%M:%S', Date.now())\n);\n```\n\nSince v6.0.5, the time options were moved from the `global` obect to the\n`time` object, and time options can be set on each individual chart."},subtree:{Date:{meta:{types:{object:1},name:"Date",excludes:{},products:{highcharts:1,highstock:1},description:"A custom `Date` class for advanced date handling. For example,\n[JDate](https://github.com/tahajahangir/jdate) can be hooked in to\nhandle Jalali dates."},subtree:{}},getTimezoneOffset:{meta:{types:{function:1},name:"getTimezoneOffset",excludes:{},products:{highcharts:1,highstock:1},description:"A callback to return the time zone offset for a given datetime. It\ntakes the timestamp in terms of milliseconds since January 1 1970,\nand returns the timezone offset in minutes. This provides a hook\nfor drawing time based charts in specific time zones using their\nlocal DST crossover dates, with the help of external libraries."},subtree:{}},timezone:{meta:{types:{string:1},name:"timezone",excludes:{},products:{highcharts:1,highstock:1},description:"Requires [moment.js](http://momentjs.com/). If the timezone option\nis specified, it creates a default\n[getTimezoneOffset](#time.getTimezoneOffset) function that looks\nup the specified timezone in moment.js. If moment.js is not included,\nthis throws a Highcharts error in the console, but does not crash the\nchart."},subtree:{}},timezoneOffset:{meta:{types:{number:1},name:"timezoneOffset",excludes:{},default:"0",products:{highcharts:1,highstock:1},description:"The timezone offset in minutes. Positive values are west, negative\nvalues are east of UTC, as in the ECMAScript\n[getTimezoneOffset](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset)\nmethod. Use this to display UTC based data in a predefined time zone."},subtree:{}},useUTC:{meta:{types:{boolean:1},name:"useUTC",excludes:{},default:"true",description:"Whether to use UTC time for axis scaling, tickmark placement and\ntime display in `Highcharts.dateFormat`. Advantages of using UTC\nis that the time displays equally regardless of the user agent's\ntime zone settings. Local time can be used when the data is loaded\nin real time or when correct Daylight Saving Time transitions are\nrequired."},subtree:{}}}},title:{meta:{types:{"*":1},name:"title",excludes:{},description:"The chart's main title."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"center",description:'The horizontal alignment of the title. Can be one of "left", "center"\nand "right".'},subtree:{}},floating:{meta:{types:{boolean:1},name:"floating",excludes:{},default:"false",description:"When the title is floating, the plot area will not move to make space\nfor it."},subtree:{}},margin:{meta:{types:{number:1},name:"margin",excludes:{},default:"-44",description:"Adjustment made to the title width, normally to reserve space for\nthe exporting burger menu."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},description:"CSS styles for the title. Use this for font styling, but use `align`,\n`x` and `y` for text alignment.\n\nIn styled mode, the title style is given in the `.highcharts-title`\nclass."},subtree:{}},text:{meta:{types:{string:1},name:"text",excludes:{},default:"Chart title",description:"The title of the chart. To disable the title, set the `text` to\n`undefined`."},subtree:{}},useHTML:{meta:{types:{boolean:1},name:"useHTML",excludes:{},default:"false",description:"Whether to\n[use HTML](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting#html)\nto render the text."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},description:'The vertical alignment of the title. Can be one of `"top"`,\n`"middle"` and `"bottom"`. When a value is given, the title behaves\nas if [floating](#title.floating) were `true`.'},subtree:{}},widthAdjust:{meta:{types:{number:1},name:"widthAdjust",excludes:{},default:-44},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"0",description:"The x position of the title relative to the alignment within\n`chart.spacingLeft` and `chart.spacingRight`."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},description:"The y position of the title relative to the alignment within\n[chart.spacingTop](#chart.spacingTop) and [chart.spacingBottom](\n#chart.spacingBottom). By default it depends on the font size."},subtree:{}}}},tooltip:{meta:{types:{object:1},name:"tooltip",excludes:{}},subtree:{animation:{meta:{types:{boolean:1},name:"animation",excludes:{},default:"true",description:"Enable or disable animation of the tooltip."},subtree:{}},backgroundColor:{meta:{types:{"highcharts.colorstring":1},name:"backgroundColor",excludes:{},default:"rgba(247,247,247,0.85)",description:"The background color or gradient for the tooltip.\n\nIn styled mode, the stroke width is set in the\n`.highcharts-tooltip-box` class."},subtree:{}},borderColor:{meta:{types:{"highcharts.colorstring":1},name:"borderColor",excludes:{},description:"The color of the tooltip border. When `undefined`, the border takes\nthe color of the corresponding series or point."},subtree:{}},borderRadius:{meta:{types:{number:1},name:"borderRadius",excludes:{},default:"3",description:"The radius of the rounded border corners."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:"1",description:"The pixel width of the tooltip border.\n\nIn styled mode, the stroke width is set in the\n`.highcharts-tooltip-box` class."},subtree:{}},changeDecimals:{meta:{types:{number:1},name:"changeDecimals",excludes:{},products:{highstock:1},description:"How many decimals to show for the `point.change` value when the\n`series.compare` option is set. This is overridable in each series'\ntooltip options object. The default is to preserve all decimals."},subtree:{}},crosshairs:{meta:{types:{"*":1},name:"crosshairs",excludes:{},default:"true",description:"Since 4.1, the crosshair definitions are moved to the Axis object\nin order for a better separation from the tooltip. See\n[xAxis.crosshair](#xAxis.crosshair)."},subtree:{}},dateTimeLabelFormats:{meta:{types:{"highcharts.dictionary.":1},name:"dateTimeLabelFormats",excludes:{},products:{highcharts:1,highstock:1},description:'For series on a datetime axes, the date format in the tooltip\'s\nheader will by default be guessed based on the closest data points.\nThis member gives the default string representations used for\neach unit. For an overview of the replacement codes, see\n[dateFormat](/class-reference/Highcharts#dateFormat).\n\nDefaults to:\n\n
    {\n    millisecond:"%A, %b %e, %H:%M:%S.%L",\n    second:"%A, %b %e, %H:%M:%S",\n    minute:"%A, %b %e, %H:%M",\n    hour:"%A, %b %e, %H:%M",\n    day:"%A, %b %e, %Y",\n    week:"Week from %A, %b %e, %Y",\n    month:"%B %Y",\n    year:"%Y"\n}
    '},subtree:{day:{meta:{types:{string:1},name:"day",excludes:{},default:"%A, %b %e, %Y"},subtree:{}},hour:{meta:{types:{string:1},name:"hour",excludes:{},default:"%A, %b %e, %H:%M"},subtree:{}},millisecond:{meta:{types:{string:1},name:"millisecond",excludes:{},default:"%A, %b %e, %H:%M:%S.%L"},subtree:{}},minute:{meta:{types:{string:1},name:"minute",excludes:{},default:"%A, %b %e, %H:%M"},subtree:{}},month:{meta:{types:{string:1},name:"month",excludes:{},default:"%B %Y"},subtree:{}},second:{meta:{types:{string:1},name:"second",excludes:{},default:"%A, %b %e, %H:%M:%S"},subtree:{}},week:{meta:{types:{string:1},name:"week",excludes:{},default:"Week from %A, %b %e, %Y"},subtree:{}},year:{meta:{types:{string:1},name:"year",excludes:{},default:"%Y"},subtree:{}}}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"true",description:"Enable or disable the tooltip."},subtree:{}},followPointer:{meta:{types:{boolean:1},name:"followPointer",excludes:{},description:"Whether the tooltip should follow the mouse as it moves across\ncolumns, pie slices and other point types with an extent. By default\nit behaves this way for scatter, bubble and pie series by override\nin the `plotOptions` for those series types.\n\nFor touch moves to behave the same way, [followTouchMove](\n#tooltip.followTouchMove) must be `true` also."},subtree:{}},followTouchMove:{meta:{types:{boolean:1},name:"followTouchMove",excludes:{},description:"Whether the tooltip should follow the finger as it moves on a touch\ndevice. If this is `true` and [chart.panning](#chart.panning) is\nset,`followTouchMove` will take over one-finger touches, so the user\nneeds to use two fingers for zooming and panning."},subtree:{}},footerFormat:{meta:{types:{string:1},name:"footerFormat",excludes:{},default:"",description:"A string to append to the tooltip format."},subtree:{}},formatter:{meta:{types:{function:1},name:"formatter",excludes:{},description:"Callback function to format the text of the tooltip from scratch.\nReturn `false` to disable tooltip for a specific point on series.\n\nA subset of HTML is supported. Unless `useHTML` is true, the HTML of\nthe tooltip is parsed and converted to SVG, therefore this isn't a\ncomplete HTML renderer. The following tags are supported: ``,\n``, ``, ``, `
    `, ``. Spans can be styled\nwith a `style` attribute, but only text-related CSS that is shared\nwith SVG is handled.\n\nSince version 2.1 the tooltip can be shared between multiple series\nthrough the `shared` option. The available data in the formatter\ndiffer a bit depending on whether the tooltip is shared or not. In\na shared tooltip, all properties except `x`, which is common for\nall points, are kept in an array, `this.points`.\n\nAvailable data are:\n\n
    \n\n
    this.percentage (not shared) / this.points[i].percentage (shared)\n
    \n\n
    Stacked series and pies only. The point's percentage of the\ntotal.\n
    \n\n
    this.point (not shared) / this.points[i].point (shared)
    \n\n
    The point object. The point name, if defined, is available\nthrough `this.point.name`.
    \n\n
    this.points
    \n\n
    In a shared tooltip, this is an array containing all other\nproperties for each point.
    \n\n
    this.series (not shared) / this.points[i].series (shared)
    \n\n
    The series object. The series name is available through\n`this.series.name`.
    \n\n
    this.total (not shared) / this.points[i].total (shared)
    \n\n
    Stacked series only. The total value at this point's x value.\n
    \n\n
    this.x
    \n\n
    The x value. This property is the same regardless of the tooltip\nbeing shared or not.
    \n\n
    this.y (not shared) / this.points[i].y (shared)
    \n\n
    The y value.
    \n\n
    "},subtree:{}},headerFormat:{meta:{types:{string:1},name:"headerFormat",excludes:{},default:'{point.key}
    ',description:"The HTML of the tooltip header line. Variables are enclosed by\ncurly brackets. Available variables are `point.key`, `series.name`,\n`series.color` and other members from the `point` and `series`\nobjects. The `point.key` variable contains the category name, x\nvalue or datetime string depending on the type of axis. For datetime\naxes, the `point.key` date format can be set using\n`tooltip.xDateFormat`."},subtree:{}},hideDelay:{meta:{types:{number:1},name:"hideDelay",excludes:{},default:"500",description:"The number of milliseconds to wait until the tooltip is hidden when\nmouse out from a point or chart."},subtree:{}},outside:{meta:{types:{boolean:1},name:"outside",excludes:{},default:"false",description:"Whether to allow the tooltip to render outside the chart's SVG\nelement box. By default (`false`), the tooltip is rendered within the\nchart's SVG element, which results in the tooltip being aligned\ninside the chart area. For small charts, this may result in clipping\nor overlapping. When `true`, a separate SVG element is created and\noverlaid on the page, allowing the tooltip to be aligned inside the\npage itself."},subtree:{}},padding:{meta:{types:{number:1},name:"padding",excludes:{},default:"8",description:"Padding inside the tooltip, in pixels."},subtree:{}},pointFormat:{meta:{types:{string:1},name:"pointFormat",excludes:{},default:'\\u25CF {series.name}: {point.y}
    ',description:"The HTML of the point's line in the tooltip. Variables are enclosed\nby curly brackets. Available variables are point.x, point.y, series.\nname and series.color and other properties on the same form.\nFurthermore, `point.y` can be extended by the `tooltip.valuePrefix`\nand `tooltip.valueSuffix` variables. This can also be overridden for\neach series, which makes it a good hook for displaying units.\n\nIn styled mode, the dot is colored by a class name rather\nthan the point color."},subtree:{}},pointFormatter:{meta:{types:{function:1},name:"pointFormatter",excludes:{},description:"A callback function for formatting the HTML output for a single point\nin the tooltip. Like the `pointFormat` string, but with more\nflexibility."},subtree:{}},positioner:{meta:{types:{function:1},name:"positioner",excludes:{},description:"A callback function to place the tooltip in a default position. The\ncallback receives three parameters: `labelWidth`, `labelHeight` and\n`point`, where point contains values for `plotX` and `plotY` telling\nwhere the reference point is in the plot area. Add `chart.plotLeft`\nand `chart.plotTop` to get the full coordinates.\n\nThe return should be an object containing x and y values, for example\n`{ x: 100, y: 100 }`."},subtree:{}},shadow:{meta:{types:{boolean:1},name:"shadow",excludes:{},default:"true",description:"Whether to apply a drop shadow to the tooltip."},subtree:{}},shape:{meta:{types:{string:1},name:"shape",excludes:{},default:"callout",description:'The name of a symbol to use for the border around the tooltip. Can\nbe one of: `"callout"`, `"circle"` or `"square"`.\n\nCustom callbacks for symbol path generation can also be added to\n`Highcharts.SVGRenderer.prototype.symbols` the same way as for\n[series.marker.symbol](plotOptions.line.marker.symbol).'},subtree:{}},shared:{meta:{types:{boolean:1},name:"shared",excludes:{},default:"false",products:{highcharts:1,highstock:1},description:"When the tooltip is shared, the entire plot area will capture mouse\nmovement or touch events. Tooltip texts for series types with ordered\ndata (not pie, scatter, flags etc) will be shown in a single bubble.\nThis is recommended for single series charts and for tablet/mobile\noptimized charts.\n\nSee also [tooltip.split](#tooltip.split), that is better suited for\ncharts with many series, especially line-type series. The\n`tooltip.split` option takes precedence over `tooltip.shared`."},subtree:{}},snap:{meta:{types:{number:1},name:"snap",excludes:{},default:"10/25",products:{highcharts:1,highstock:1},description:"Proximity snap for graphs or single points. It defaults to 10 for\nmouse-powered devices and 25 for touch devices.\n\nNote that in most cases the whole plot area captures the mouse\nmovement, and in these cases `tooltip.snap` doesn't make sense. This\napplies when [stickyTracking](#plotOptions.series.stickyTracking)\nis `true` (default) and when the tooltip is [shared](#tooltip.shared)\nor [split](#tooltip.split)."},subtree:{}},split:{meta:{types:{boolean:1},name:"split",excludes:{},products:{highcharts:1,highstock:1},description:"Split the tooltip into one label per series, with the header close\nto the axis. This is recommended over [shared](#tooltip.shared)\ntooltips for charts with multiple line series, generally making them\neasier to read. This option takes precedence over `tooltip.shared`."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},default:'{"color": "#333333", "cursor": "default", "fontSize": "12px", "pointerEvents": "none", "whiteSpace": "nowrap"}',description:"CSS styles for the tooltip. The tooltip can also be styled through\nthe CSS class `.highcharts-tooltip`."},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#333333"},subtree:{}},cursor:{meta:{types:{string:1},name:"cursor",excludes:{},default:"default"},subtree:{}},fontSize:{meta:{types:{string:1},name:"fontSize",excludes:{},default:"12px"},subtree:{}},pointerEvents:{meta:{types:{string:1},name:"pointerEvents",excludes:{},default:"none"},subtree:{}},whiteSpace:{meta:{types:{string:1},name:"whiteSpace",excludes:{},default:"nowrap"},subtree:{}}}},useHTML:{meta:{types:{boolean:1},name:"useHTML",excludes:{},default:"false",description:"Use HTML to render the contents of the tooltip instead of SVG. Using\nHTML allows advanced formatting like tables and images in the\ntooltip. It is also recommended for rtl languages as it works around\nrtl bugs in early Firefox."},subtree:{}},valueDecimals:{meta:{types:{number:1},name:"valueDecimals",excludes:{},description:"How many decimals to show in each series' y value. This is\noverridable in each series' tooltip options object. The default is to\npreserve all decimals."},subtree:{}},valuePrefix:{meta:{types:{string:1},name:"valuePrefix",excludes:{},description:"A string to prepend to each series' y value. Overridable in each\nseries' tooltip options object."},subtree:{}},valueSuffix:{meta:{types:{string:1},name:"valueSuffix",excludes:{},description:"A string to append to each series' y value. Overridable in each\nseries' tooltip options object."},subtree:{}},xDateFormat:{meta:{types:{string:1},name:"xDateFormat",excludes:{},products:{highcharts:1,highstock:1},description:"The format for the date in the tooltip header if the X axis is a\ndatetime axis. The default is a best guess based on the smallest\ndistance between points in the chart."},subtree:{}}}},xAxis:{meta:{types:{array:"xAxis"},name:"xAxis",excludes:{},description:"The X axis or category axis. Normally this is the horizontal axis,\nthough if the chart is inverted this is the vertical axis. In case of\nmultiple axes, the xAxis node is an array of configuration objects.\n\nSee [the Axis object](/class-reference/Highcharts.Axis) for\nprogrammatic access to the axis."},subtree:{alignTicks:{meta:{types:{boolean:1},name:"alignTicks",excludes:{},default:"true",products:{highcharts:1,highstock:1},description:"When using multiple axis, the ticks of two or more opposite axes\nwill automatically be aligned by adding ticks to the axis or axes\nwith the least ticks, as if `tickAmount` were specified.\n\nThis can be prevented by setting `alignTicks` to false. If the grid\nlines look messy, it's a good idea to hide them for the secondary\naxis by setting `gridLineWidth` to 0.\n\nIf `startOnTick` or `endOnTick` in an Axis options are set to false,\nthen the `alignTicks ` will be disabled for the Axis.\n\nDisabled for logarithmic axes." },subtree:{}},allowDecimals:{meta:{types:{boolean:1},name:"allowDecimals",excludes:{},default:"true",description:"Whether to allow decimals in this axis' ticks. When counting\nintegers, like persons or hits on a web page, decimals should\nbe avoided in the labels."},subtree:{}},alternateGridColor:{meta:{types:{"highcharts.colorstring":1},name:"alternateGridColor",excludes:{},description:"When using an alternate grid color, a band is painted across the\nplot area between every other grid line."},subtree:{}},breaks:{meta:{types:{array:"*"},name:"breaks",excludes:{},products:{highcharts:1,highstock:1},description:"An array defining breaks in the axis, the sections defined will be\nleft out and all the points shifted closer to each other."},subtree:{breakSize:{meta:{types:{number:1},name:"breakSize",excludes:{},default:"0",products:{highcharts:1,highstock:1},description:"A number indicating how much space should be left between the start\nand the end of the break. The break size is given in axis units,\nso for instance on a `datetime` axis, a break size of 3600000 would\nindicate the equivalent of an hour."},subtree:{}},from:{meta:{types:{number:1},name:"from",excludes:{},products:{highcharts:1,highstock:1},description:"The point where the break starts."},subtree:{}},repeat:{meta:{types:{number:1},name:"repeat",excludes:{},default:"0",products:{highcharts:1,highstock:1},description:"Defines an interval after which the break appears again. By default\nthe breaks do not repeat."},subtree:{}},to:{meta:{types:{number:1},name:"to",excludes:{},products:{highcharts:1,highstock:1},description:"The point where the break ends."},subtree:{}}}},categories:{meta:{types:{array:"string"},name:"categories",excludes:{},products:{highcharts:1},description:"If categories are present for the xAxis, names are used instead of\nnumbers for that axis. Since Highcharts 3.0, categories can also\nbe extracted by giving each point a [name](#series.data) and setting\naxis [type](#xAxis.type) to `category`. However, if you have multiple\nseries, best practice remains defining the `categories` array.\n\nExample:\n\n
    categories: ['Apples', 'Bananas', 'Oranges']
    "},subtree:{}},ceiling:{meta:{types:{number:1},name:"ceiling",excludes:{},products:{highcharts:1,highstock:1},description:"The highest allowed value for automatically computed axis extremes."},subtree:{}},className:{meta:{types:{string:1},name:"className",excludes:{},description:"A class name that opens for styling the axis by CSS, especially in\nHighcharts styled mode. The class name is applied to group elements\nfor the grid, axis elements and labels."},subtree:{}},crosshair:{meta:{types:{"*":1,boolean:1},name:"crosshair",excludes:{},default:"false",description:"Configure a crosshair that follows either the mouse pointer or the\nhovered point.\n\nIn styled mode, the crosshairs are styled in the\n`.highcharts-crosshair`, `.highcharts-crosshair-thin` or\n`.highcharts-xaxis-category` classes."},subtree:{className:{meta:{types:{string:1},name:"className",excludes:{},description:"A class name for the crosshair, especially as a hook for styling."},subtree:{}},color:{meta:{types:{"highcharts.colorstring":1},name:"color",excludes:{},default:"#cccccc",description:"The color of the crosshair. Defaults to `#cccccc` for numeric and\ndatetime axes, and `rgba(204,214,235,0.25)` for category axes, where\nthe crosshair by default highlights the whole category."},subtree:{}},dashStyle:{meta:{types:{string:1},name:"dashStyle",excludes:{},default:"Solid",description:"The dash style for the crosshair. See\n[series.dashStyle](#plotOptions.series.dashStyle)\nfor possible values."},subtree:{}},label:{meta:{types:{"*":1},name:"label",excludes:{},products:{highstock:1},description:"A label on the axis next to the crosshair.\n\nIn styled mode, the label is styled with the\n`.highcharts-crosshair-label` class."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},products:{highstock:1},description:"Alignment of the label compared to the axis. Defaults to `left` for\nright-side axes, `right` for left-side axes and `center` for\nhorizontal axes."},subtree:{}},backgroundColor:{meta:{types:{"highcharts.colorstring":1},name:"backgroundColor",excludes:{},products:{highstock:1},description:"The background color for the label. Defaults to the related series\ncolor, or `#666666` if that is not available."},subtree:{}},borderColor:{meta:{types:{"highcharts.colorstring":1},name:"borderColor",excludes:{},products:{highstock:1},description:"The border color for the crosshair label"},subtree:{}},borderRadius:{meta:{types:{number:1},name:"borderRadius",excludes:{},default:"3",products:{highstock:1},description:"The border corner radius of the crosshair label."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:"0",products:{highstock:1},description:"The border width for the crosshair label."},subtree:{}},format:{meta:{types:{string:1},name:"format",excludes:{},products:{highstock:1},description:"A format string for the crosshair label. Defaults to `{value}` for\nnumeric axes and `{value:%b %d, %Y}` for datetime axes."},subtree:{}},formatter:{meta:{types:{function:1},name:"formatter",excludes:{},products:{highstock:1},description:"Formatter function for the label text."},subtree:{}},padding:{meta:{types:{number:1},name:"padding",excludes:{},default:"8",products:{highstock:1},description:"Padding inside the crosshair label."},subtree:{}},shape:{meta:{types:{string:1},name:"shape",excludes:{},default:"callout",products:{highstock:1},description:"The shape to use for the label box."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},default:'{"color": "white", "fontWeight": "normal", "fontSize": "11px", "textAlign": "center"}',products:{highstock:1},description:"Text styles for the crosshair label."},subtree:{}}}},snap:{meta:{types:{boolean:1},name:"snap",excludes:{},default:"true",description:"Whether the crosshair should snap to the point or follow the pointer\nindependent of points."},subtree:{}},width:{meta:{types:{number:1},name:"width",excludes:{},default:"1",description:"The pixel width of the crosshair. Defaults to 1 for numeric or\ndatetime axes, and for one category width for category axes."},subtree:{}},zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},default:"2",description:"The Z index of the crosshair. Higher Z indices allow drawing the\ncrosshair on top of the series or behind the grid lines."},subtree:{}}}},dateTimeLabelFormats:{meta:{types:{"*":1},name:"dateTimeLabelFormats",excludes:{},products:{highcharts:1,highstock:1},description:"For a datetime axis, the scale will automatically adjust to the\nappropriate unit. This member gives the default string\nrepresentations used for each unit. For intermediate values,\ndifferent units may be used, for example the `day` unit can be used\non midnight and `hour` unit be used for intermediate values on the\nsame axis. For an overview of the replacement codes, see\n[dateFormat](/class-reference/Highcharts#dateFormat). Defaults to:\n\n
    {\n    millisecond: '%H:%M:%S.%L',\n    second: '%H:%M:%S',\n    minute: '%H:%M',\n    hour: '%H:%M',\n    day: '%e. %b',\n    week: '%e. %b',\n    month: '%b \\'%y',\n    year: '%Y'\n}
    "},subtree:{day:{meta:{types:{string:1},name:"day",excludes:{},default:"%e. %b"},subtree:{}},hour:{meta:{types:{string:1},name:"hour",excludes:{},default:"%H:%M"},subtree:{}},millisecond:{meta:{types:{string:1},name:"millisecond",excludes:{},default:"%H:%M:%S.%L"},subtree:{}},minute:{meta:{types:{string:1},name:"minute",excludes:{},default:"%H:%M"},subtree:{}},month:{meta:{types:{string:1},name:"month",excludes:{},default:"%b '%y"},subtree:{}},second:{meta:{types:{string:1},name:"second",excludes:{},default:"%H:%M:%S"},subtree:{}},week:{meta:{types:{string:1},name:"week",excludes:{},default:"%e. %b"},subtree:{}},year:{meta:{types:{string:1},name:"year",excludes:{},default:"%Y"},subtree:{}}}},description:{meta:{types:{string:1},name:"description",excludes:{},description:"_Requires Accessibility module_\n\nDescription of the axis to screen reader users."},subtree:{}},endOnTick:{meta:{types:{boolean:1},name:"endOnTick",excludes:{},default:!1,description:"Whether to force the axis to end on a tick. Use this option with\nthe `maxPadding` option to control the axis end."},subtree:{}},events:{meta:{types:{"*":1},name:"events",excludes:{},description:"Event handlers for the axis."},subtree:{afterBreaks:{meta:{types:{function:1},name:"afterBreaks",excludes:{},products:{highcharts:1},description:"An event fired after the breaks have rendered."},subtree:{}},afterSetExtremes:{meta:{types:{function:1},name:"afterSetExtremes",excludes:{},description:"As opposed to the `setExtremes` event, this event fires after the\nfinal min and max values are computed and corrected for `minRange`.\n\n\nFires when the minimum and maximum is set for the axis, either by\ncalling the `.setExtremes()` method or by selecting an area in the\nchart. One parameter, `event`, is passed to the function, containing\ncommon event information.\n\nThe new user set minimum and maximum values can be found by\n`event.min` and `event.max`. These reflect the axis minimum and\nmaximum in axis values. The actual data extremes are found in\n`event.dataMin` and `event.dataMax`."},subtree:{}},pointBreak:{meta:{types:{function:1},name:"pointBreak",excludes:{},products:{highcharts:1},description:"An event fired when a break from this axis occurs on a point."},subtree:{}},pointInBreak:{meta:{types:{function:1},name:"pointInBreak",excludes:{},products:{highcharts:1,highstock:1},description:"An event fired when a point falls inside a break from this axis."},subtree:{}},setExtremes:{meta:{types:{function:1},name:"setExtremes",excludes:{},description:'Fires when the minimum and maximum is set for the axis, either by\ncalling the `.setExtremes()` method or by selecting an area in the\nchart. One parameter, `event`, is passed to the function,\ncontaining common event information.\n\nThe new user set minimum and maximum values can be found by\n`event.min` and `event.max`. These reflect the axis minimum and\nmaximum in data values. When an axis is zoomed all the way out from\nthe "Reset zoom" button, `event.min` and `event.max` are null, and\nthe new extremes are set based on `this.dataMin` and `this.dataMax`.'},subtree:{}}}},floor:{meta:{types:{number:1},name:"floor",excludes:{},products:{highcharts:1,highstock:1},description:"The lowest allowed value for automatically computed axis extremes."},subtree:{}},gridLineColor:{meta:{types:{"highcharts.colorstring":1},name:"gridLineColor",excludes:{},default:"#e6e6e6",description:"Color of the grid lines extending the ticks across the plot area.\n\nIn styled mode, the stroke is given in the `.highcharts-grid-line`\nclass."},subtree:{}},gridLineDashStyle:{meta:{types:{string:1},name:"gridLineDashStyle",excludes:{},default:"Solid",description:"The dash or dot style of the grid lines. For possible values, see\n[this demonstration](https://jsfiddle.net/gh/get/library/pure/\nhighcharts/highcharts/tree/master/samples/highcharts/plotoptions/\nseries-dashstyle-all/)."},subtree:{}},gridLineWidth:{meta:{types:{number:1},name:"gridLineWidth",excludes:{},default:"0",description:"The width of the grid lines extending the ticks across the plot area.\n\nIn styled mode, the stroke width is given in the\n`.highcharts-grid-line` class."},subtree:{}},gridZIndex:{meta:{types:{number:1},name:"gridZIndex",excludes:{},default:"1",products:{highcharts:1,highstock:1},description:"The Z index of the grid lines."},subtree:{}},id:{meta:{types:{string:1},name:"id",excludes:{},description:"An id for the axis. This can be used after render time to get\na pointer to the axis object through `chart.get()`."},subtree:{}},labels:{meta:{types:{"*":1},name:"labels",excludes:{},description:"The axis labels show the number or category for each tick."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},description:'What part of the string the given position is anchored to.\nIf `left`, the left side of the string is at the axis position.\nCan be one of `"left"`, `"center"` or `"right"`. Defaults to\nan intelligent guess based on which side of the chart the axis\nis on and the rotation of the label.'},subtree:{}},autoRotation:{meta:{types:{array:"number"},name:"autoRotation",excludes:{},default:"[-45]",products:{highcharts:1,highstock:1},description:"For horizontal axes, the allowed degrees of label rotation\nto prevent overlapping labels. If there is enough space,\nlabels are not rotated. As the chart gets narrower, it\nwill start rotating the labels -45 degrees, then remove\nevery second label and try again with rotations 0 and -45 etc.\nSet it to `false` to disable rotation, which will\ncause the labels to word-wrap if possible."},subtree:{}},autoRotationLimit:{meta:{types:{number:1},name:"autoRotationLimit",excludes:{},default:"80",products:{highcharts:1},description:"When each category width is more than this many pixels, we don't\napply auto rotation. Instead, we lay out the axis label with word\nwrap. A lower limit makes sense when the label contains multiple\nshort words that don't extend the available horizontal space for\neach label."},subtree:{}},distance:{meta:{types:{number:1},name:"distance",excludes:{},default:"15",products:{highcharts:1},description:"Polar charts only. The label's pixel distance from the perimeter\nof the plot area."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!0,description:"Enable or disable the axis labels."},subtree:{}},format:{meta:{types:{string:1},name:"format",excludes:{},default:"{value}",description:"A [format string](https://www.highcharts.com/docs/chart-\nconcepts/labels-and-string-formatting) for the axis label."},subtree:{}},formatter:{meta:{types:{function:1},name:"formatter",excludes:{},description:"Callback JavaScript function to format the label. The value\nis given by `this.value`. Additional properties for `this` are\n`axis`, `chart`, `isFirst` and `isLast`. The value of the default\nlabel formatter can be retrieved by calling\n`this.axis.defaultLabelFormatter.call(this)` within the function.\n\nDefaults to:\n\n
    function() {\n    return this.value;\n}
    "},subtree:{}},maxStaggerLines:{meta:{types:{number:1},name:"maxStaggerLines",excludes:{},default:"5",products:{highmaps:1,highstock:1},description:"Horizontal axis only. When `staggerLines` is not set,\n`maxStaggerLines` defines how many lines the axis is allowed to\nadd to automatically avoid overlapping X labels. Set to `1` to\ndisable overlap detection."},subtree:{}},overflow:{meta:{types:{boolean:1,string:1},name:"overflow",excludes:{},description:'How to handle overflowing labels on horizontal axis. Can be\nundefined, `false` or `"justify"`. By default it aligns inside\nthe chart area. If "justify", labels will not render outside\nthe plot area. If `false`, it will not be aligned at all.\nIf there is room to move it, it will be aligned to the edge,\nelse it will be removed.'},subtree:{}},padding:{meta:{types:{number:1},name:"padding",excludes:{},default:"5",products:{highcharts:1},description:"The pixel padding for axis labels, to ensure white space between\nthem."},subtree:{}},position3d:{meta:{types:{string:1},name:"position3d",excludes:{},default:"offset",products:{highcharts:1},description:"Defines how the labels are be repositioned according to the 3D chart\norientation.\n- `'offset'`: Maintain a fixed horizontal/vertical distance from the\n tick marks, despite the chart orientation. This is the backwards\n compatible behavior, and causes skewing of X and Z axes.\n- `'chart'`: Preserve 3D position relative to the chart.\n This looks nice, but hard to read if the text isn't\n forward-facing.\n- `'flap'`: Rotated text along the axis to compensate for the chart\n orientation. This tries to maintain text as legible as possible\n on all orientations.\n- `'ortho'`: Rotated text along the axis direction so that the labels\n are orthogonal to the axis. This is very similar to `'flap'`,\n but prevents skewing the labels (X and Y scaling are still\n present)."},subtree:{}},reserveSpace:{meta:{types:{boolean:1},name:"reserveSpace",excludes:{},products:{highcharts:1},description:"Whether to reserve space for the labels. By default, space is\nreserved for the labels in these cases:\n\n* On all horizontal axes.\n* On vertical axes if `label.align` is `right` on a left-side\naxis or `left` on a right-side axis.\n* On vertical axes if `label.align` is `center`.\n\nThis can be turned off when for example the labels are rendered\ninside the plot area instead of outside."},subtree:{}},rotation:{meta:{types:{number:1},name:"rotation",excludes:{},default:"0",description:"Rotation of the labels in degrees."},subtree:{}},skew3d:{meta:{types:{boolean:1},name:"skew3d",excludes:{},default:!1,products:{highcharts:1},description:"If enabled, the axis labels will skewed to follow the perspective.\n\nThis will fix overlapping labels and titles, but texts become less\nlegible due to the distortion.\n\nThe final appearance depends heavily on `labels.position3d`."},subtree:{}},staggerLines:{meta:{types:{number:1},name:"staggerLines",excludes:{},description:"Horizontal axes only. The number of lines to spread the labels\nover to make room or tighter labels."},subtree:{}},step:{meta:{types:{number:1},name:"step",excludes:{},description:"To show only every _n_'th label on the axis, set the step to _n_.\nSetting the step to 2 shows every other label.\n\nBy default, the step is calculated automatically to avoid\noverlap. To prevent this, set it to 1\\. This usually only\nhappens on a category axis, and is often a sign that you have\nchosen the wrong axis type.\n\nRead more at\n[Axis docs](https://www.highcharts.com/docs/chart-concepts/axes)\n=> What axis should I use?"},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},description:"CSS styles for the label. Use `whiteSpace: 'nowrap'` to prevent\nwrapping of category labels. Use `textOverflow: 'none'` to\nprevent ellipsis (dots).\n\nIn styled mode, the labels are styled with the\n`.highcharts-axis-labels` class."},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#666666"},subtree:{}},cursor:{meta:{types:{string:1},name:"cursor",excludes:{},default:"default"},subtree:{}},fontSize:{meta:{types:{string:1},name:"fontSize",excludes:{},default:"11px"},subtree:{}}}},useHTML:{meta:{types:{boolean:1},name:"useHTML",excludes:{},default:"false",description:"Whether to [use HTML](https://www.highcharts.com/docs/chart-\nconcepts/labels-and-string-formatting#html) to render the labels."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"0",description:"The x position offset of the label relative to the tick position\non the axis."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},description:"The y position offset of the label relative to the tick position\non the axis. The default makes it adapt to the font size on\nbottom axis."},subtree:{}},zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},default:"7",description:"The Z index for the axis labels."},subtree:{}}}},lineColor:{meta:{types:{"highcharts.colorstring":1},name:"lineColor",excludes:{},default:"#ccd6eb",description:"The color of the line marking the axis itself.\n\nIn styled mode, the line stroke is given in the\n`.highcharts-axis-line` or `.highcharts-xaxis-line` class."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:1,description:"The width of the line marking the axis itself.\n\nIn styled mode, the stroke width is given in the\n`.highcharts-axis-line` or `.highcharts-xaxis-line` class."},subtree:{}},linkedTo:{meta:{types:{number:1},name:"linkedTo",excludes:{},products:{highcharts:1,highstock:1},description:"Index of another axis that this axis is linked to. When an axis is\nlinked to a master axis, it will take the same extremes as\nthe master, but as assigned by min or max or by setExtremes.\nIt can be used to show additional info, or to ease reading the\nchart by duplicating the scales."},subtree:{}},max:{meta:{types:{number:1},name:"max",excludes:{},description:"The maximum value of the axis. If `null`, the max value is\nautomatically calculated.\n\nIf the [endOnTick](#yAxis.endOnTick) option is true, the `max` value\nmight be rounded up.\n\nIf a [tickAmount](#yAxis.tickAmount) is set, the axis may be extended\nbeyond the set max in order to reach the given number of ticks. The\nsame may happen in a chart with multiple axes, determined by [chart.\nalignTicks](#chart), where a `tickAmount` is applied internally."},subtree:{}},maxPadding:{meta:{types:{number:1},name:"maxPadding",excludes:{},default:.01,description:"Padding of the max value relative to the length of the axis. A\npadding of 0.05 will make a 100px axis 5px longer. This is useful\nwhen you don't want the highest data value to appear on the edge\nof the plot area. When the axis' `max` option is set or a max extreme\nis set using `axis.setExtremes()`, the maxPadding will be ignored."},subtree:{}},maxRange:{meta:{types:{number:1},name:"maxRange",excludes:{},default:"undefined",products:{highstock:1},description:"Maximum range which can be set using the navigator's handles.\nOpposite of [xAxis.minRange](#xAxis.minRange)."},subtree:{}},maxZoom:{meta:{types:{number:1},name:"maxZoom",excludes:{},products:{highcharts:1,highstock:1},description:"Deprecated. Use `minRange` instead."},subtree:{}},min:{meta:{types:{number:1},name:"min",excludes:{},description:"The minimum value of the axis. If `null` the min value is\nautomatically calculated.\n\nIf the [startOnTick](#yAxis.startOnTick) option is true (default),\nthe `min` value might be rounded down.\n\nThe automatically calculated minimum value is also affected by\n[floor](#yAxis.floor), [softMin](#yAxis.softMin),\n[minPadding](#yAxis.minPadding), [minRange](#yAxis.minRange)\nas well as [series.threshold](#plotOptions.series.threshold)\nand [series.softThreshold](#plotOptions.series.softThreshold)."},subtree:{}},minPadding:{meta:{types:{number:1},name:"minPadding",excludes:{},default:.01,products:{highcharts:1,highstock:1},description:"Padding of the min value relative to the length of the axis. A\npadding of 0.05 will make a 100px axis 5px longer. This is useful\nwhen you don't want the lowest data value to appear on the edge\nof the plot area. When the axis' `min` option is set or a min extreme\nis set using `axis.setExtremes()`, the minPadding will be ignored."},subtree:{}},minRange:{meta:{types:{number:1},name:"minRange",excludes:{},description:"The minimum range to display on this axis. The entire axis will not\nbe allowed to span over a smaller interval than this. For example,\nfor a datetime axis the main unit is milliseconds. If minRange is\nset to 3600000, you can't zoom in more than to one hour.\n\nThe default minRange for the x axis is five times the smallest\ninterval between any of the data points.\n\nOn a logarithmic axis, the unit for the minimum range is the power.\nSo a minRange of 1 means that the axis can be zoomed to 10-100,\n100-1000, 1000-10000 etc.\n\nNote that the `minPadding`, `maxPadding`, `startOnTick` and\n`endOnTick` settings also affect how the extremes of the axis\nare computed."},subtree:{}},minTickInterval:{meta:{types:{number:1},name:"minTickInterval",excludes:{},description:"The minimum tick interval allowed in axis values. For example on\nzooming in on an axis with daily data, this can be used to prevent\nthe axis from showing hours. Defaults to the closest distance between\ntwo points on the axis."},subtree:{}},minorGridLineColor:{meta:{types:{"highcharts.colorstring":1},name:"minorGridLineColor",excludes:{},default:"#f2f2f2",description:"Color of the minor, secondary grid lines.\n\nIn styled mode, the stroke width is given in the\n`.highcharts-minor-grid-line` class."},subtree:{}},minorGridLineDashStyle:{meta:{types:{string:1},name:"minorGridLineDashStyle",excludes:{},default:"Solid",description:"The dash or dot style of the minor grid lines. For possible values,\nsee [this demonstration](https://jsfiddle.net/gh/get/library/pure/\nhighcharts/highcharts/tree/master/samples/highcharts/plotoptions/\nseries-dashstyle-all/)."},subtree:{}},minorGridLineWidth:{meta:{types:{number:1},name:"minorGridLineWidth",excludes:{},default:1,description:"Width of the minor, secondary grid lines.\n\nIn styled mode, the stroke width is given in the\n`.highcharts-grid-line` class."},subtree:{}},minorTickColor:{meta:{types:{"highcharts.colorstring":1},name:"minorTickColor",excludes:{},default:"#999999",description:"Color for the minor tick marks."},subtree:{}},minorTickInterval:{meta:{types:{null:1,number:1,string:1},name:"minorTickInterval",excludes:{},description:'Specific tick interval in axis units for the minor ticks. On a linear\naxis, if `"auto"`, the minor tick interval is calculated as a fifth\nof the tickInterval. If `null` or `undefined`, minor ticks are not\nshown.\n\nOn logarithmic axes, the unit is the power of the value. For example,\nsetting the minorTickInterval to 1 puts one tick on each of 0.1, 1,\n10, 100 etc. Setting the minorTickInterval to 0.1 produces 9 ticks\nbetween 1 and 10, 10 and 100 etc.\n\nIf user settings dictate minor ticks to become too dense, they don\'t\nmake sense, and will be ignored to prevent performance problems.'},subtree:{}},minorTickLength:{meta:{types:{number:1},name:"minorTickLength",excludes:{},default:2},subtree:{}},minorTickPosition:{meta:{types:{string:1},name:"minorTickPosition",excludes:{},default:"outside",description:"The position of the minor tick marks relative to the axis line.\n Can be one of `inside` and `outside`."},subtree:{}},minorTickWidth:{meta:{types:{number:1},name:"minorTickWidth",excludes:{},default:"0",description:"The pixel width of the minor tick mark."},subtree:{}},minorTicks:{meta:{types:{boolean:1},name:"minorTicks",excludes:{},default:"false",description:'Enable or disable minor ticks. Unless\n[minorTickInterval](#xAxis.minorTickInterval) is set, the tick\ninterval is calculated as a fifth of the `tickInterval`.\n\nOn a logarithmic axis, minor ticks are laid out based on a best\nguess, attempting to enter approximately 5 minor ticks between\neach major tick.\n\nPrior to v6.0.0, ticks were unabled in auto layout by setting\n`minorTickInterval` to `"auto"`.'},subtree:{}},offset:{meta:{types:{number:1},name:"offset",excludes:{},default:"0",description:"The distance in pixels from the plot area to the axis line.\nA positive offset moves the axis with it's line, labels and ticks\naway from the plot area. This is typically used when two or more\naxes are displayed on the same side of the plot. With multiple\naxes the offset is dynamically adjusted to avoid collision, this\ncan be overridden by setting offset explicitly."},subtree:{}},opposite:{meta:{types:{boolean:1},name:"opposite",excludes:{},default:"false",description:"Whether to display the axis on the opposite side of the normal. The\nnormal is on the left side for vertical axes and bottom for\nhorizontal, so the opposite sides will be right and top respectively.\nThis is typically used with dual or multiple axes."},subtree:{}},ordinal:{meta:{types:{boolean:1},name:"ordinal",excludes:{},default:"true",products:{highstock:1},description:"In an ordinal axis, the points are equally spaced in the chart\nregardless of the actual time or x distance between them. This means\nthat missing data periods (e.g. nights or weekends for a stock chart)\nwill not take up space in the chart.\nHaving `ordinal: false` will show any gaps created by the `gapSize`\nsetting proportionate to their duration.\n\nIn stock charts the X axis is ordinal by default, unless\nthe boost module is used and at least one of the series' data length\nexceeds the [boostThreshold](#series.line.boostThreshold)."},subtree:{}},overscroll:{meta:{types:{number:1},name:"overscroll",excludes:{},default:"0",products:{highstock:1},description:"Additional range on the right side of the xAxis. Works similar to\n`xAxis.maxPadding`, but value is set in milliseconds. Can be set for\nboth main `xAxis` and the navigator's `xAxis`."},subtree:{}},pane:{meta:{types:{number:1},name:"pane",excludes:{},products:{highcharts:1},description:"Refers to the index in the [panes](#panes) array. Used for circular\ngauges and polar charts. When the option is not set then first pane\nwill be used."},subtree:{}},plotBands:{meta:{types:{array:"*"},name:"plotBands",excludes:{},products:{highcharts:1,highstock:1},description:"An array of colored bands stretching across the plot area marking\nan interval on the axis.\n\nIn styled mode, the plot bands are styled by the\n`.highcharts-plot-band` class in addition to the `className` option."},subtree:{borderColor:{meta:{types:{"highcharts.colorstring":1},name:"borderColor",excludes:{},products:{highcharts:1,highstock:1},description:"Border color for the plot band. Also requires `borderWidth` to be\nset."},subtree:{}},borderWidth:{meta:{types:{number:1},name:"borderWidth",excludes:{},default:"0",products:{highcharts:1,highstock:1},description:"Border width for the plot band. Also requires `borderColor` to be\nset."},subtree:{}},className:{meta:{types:{string:1},name:"className",excludes:{},description:"A custom class name, in addition to the default\n`highcharts-plot-band`, to apply to each individual band."},subtree:{}},color:{meta:{types:{"highcharts.colorstring":1},name:"color",excludes:{},products:{highcharts:1,highstock:1},description:"The color of the plot band."},subtree:{}},events:{meta:{types:{"*":1},name:"events",excludes:{},products:{highcharts:1,highstock:1},description:"An object defining mouse events for the plot band. Supported\nproperties are `click`, `mouseover`, `mouseout`, `mousemove`."},subtree:{}},from:{meta:{types:{number:1},name:"from",excludes:{},products:{highcharts:1,highstock:1},description:"The start position of the plot band in axis units."},subtree:{}},id:{meta:{types:{string:1},name:"id",excludes:{},products:{highcharts:1,highstock:1},description:"An id used for identifying the plot band in Axis.removePlotBand."},subtree:{}},label:{meta:{types:{"*":1},name:"label",excludes:{},products:{highcharts:1,highstock:1},description:"Text labels for the plot bands"},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"center",products:{highcharts:1,highstock:1},description:'Horizontal alignment of the label. Can be one of "left", "center"\nor "right".'},subtree:{}},rotation:{meta:{types:{number:1},name:"rotation",excludes:{},default:"0",products:{highcharts:1,highstock:1},description:"Rotation of the text label in degrees ."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},products:{highcharts:1,highstock:1},description:"CSS styles for the text label.\n\nIn styled mode, the labels are styled by the\n`.highcharts-plot-band-label` class."},subtree:{}},text:{meta:{types:{string:1},name:"text",excludes:{},products:{highcharts:1},description:"The string text itself. A subset of HTML is supported."},subtree:{}},textAlign:{meta:{types:{string:1},name:"textAlign",excludes:{},products:{highcharts:1,highstock:1},description:'The text alignment for the label. While `align` determines where\nthe texts anchor point is placed within the plot band, `textAlign`\ndetermines how the text is aligned against its anchor point. Possible\nvalues are "left", "center" and "right". Defaults to the same as\nthe `align` option.'},subtree:{}},useHTML:{meta:{types:{boolean:1},name:"useHTML",excludes:{},default:"false",products:{highcharts:1,highstock:1},description:"Whether to [use HTML](https://www.highcharts.com/docs/chart-concepts/labels-\nand-string-formatting#html) to render the labels."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign", excludes:{},default:"top",products:{highcharts:1,highstock:1},description:'Vertical alignment of the label relative to the plot band. Can be\none of "top", "middle" or "bottom".'},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},products:{highcharts:1,highstock:1},description:"Horizontal position relative the alignment. Default varies by\norientation."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},products:{highcharts:1,highstock:1},description:"Vertical position of the text baseline relative to the alignment.\n Default varies by orientation."},subtree:{}}}},to:{meta:{types:{number:1},name:"to",excludes:{},products:{highcharts:1,highstock:1},description:"The end position of the plot band in axis units."},subtree:{}},zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},products:{highcharts:1,highstock:1},description:"The z index of the plot band within the chart, relative to other\nelements. Using the same z index as another element may give\nunpredictable results, as the last rendered element will be on top.\nValues from 0 to 20 make sense."},subtree:{}}}},plotLines:{meta:{types:{array:"*"},name:"plotLines",excludes:{},products:{highcharts:1,highstock:1},description:"An array of lines stretching across the plot area, marking a specific\nvalue on one of the axes.\n\nIn styled mode, the plot lines are styled by the\n`.highcharts-plot-line` class in addition to the `className` option."},subtree:{className:{meta:{types:{string:1},name:"className",excludes:{},description:"A custom class name, in addition to the default\n`highcharts-plot-line`, to apply to each individual line."},subtree:{}},color:{meta:{types:{"highcharts.colorstring":1},name:"color",excludes:{},products:{highcharts:1,highstock:1},description:"The color of the line."},subtree:{}},dashStyle:{meta:{types:{string:1},name:"dashStyle",excludes:{},default:"Solid",products:{highcharts:1,highstock:1},description:"The dashing or dot style for the plot line. For possible values see\n[this overview](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/series-\ndashstyle-all/)."},subtree:{}},events:{meta:{types:{"*":1},name:"events",excludes:{},products:{highcharts:1,highstock:1},description:"An object defining mouse events for the plot line. Supported\nproperties are `click`, `mouseover`, `mouseout`, `mousemove`."},subtree:{}},id:{meta:{types:{string:1},name:"id",excludes:{},products:{highcharts:1,highstock:1},description:"An id used for identifying the plot line in Axis.removePlotLine."},subtree:{}},label:{meta:{types:{"*":1},name:"label",excludes:{},products:{highcharts:1,highstock:1},description:"Text labels for the plot bands"},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"left",products:{highcharts:1,highstock:1},description:'Horizontal alignment of the label. Can be one of "left", "center"\nor "right".'},subtree:{}},rotation:{meta:{types:{number:1},name:"rotation",excludes:{},products:{highcharts:1,highstock:1},description:"Rotation of the text label in degrees. Defaults to 0 for horizontal\nplot lines and 90 for vertical lines."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},products:{highcharts:1,highstock:1},description:"CSS styles for the text label.\n\nIn styled mode, the labels are styled by the\n`.highcharts-plot-line-label` class."},subtree:{}},text:{meta:{types:{string:1},name:"text",excludes:{},products:{highcharts:1},description:"The text itself. A subset of HTML is supported."},subtree:{}},textAlign:{meta:{types:{string:1},name:"textAlign",excludes:{},products:{highcharts:1,highstock:1},description:'The text alignment for the label. While `align` determines where\nthe texts anchor point is placed within the plot band, `textAlign`\ndetermines how the text is aligned against its anchor point. Possible\nvalues are "left", "center" and "right". Defaults to the same as\nthe `align` option.'},subtree:{}},useHTML:{meta:{types:{boolean:1},name:"useHTML",excludes:{},default:"false",products:{highcharts:1,highstock:1},description:"Whether to [use HTML](https://www.highcharts.com/docs/chart-concepts/labels-\nand-string-formatting#html) to render the labels."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},products:{highcharts:1,highstock:1},description:'Vertical alignment of the label relative to the plot line. Can be\none of "top", "middle" or "bottom".'},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},products:{highcharts:1,highstock:1},description:"Horizontal position relative the alignment. Default varies by\norientation."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},products:{highcharts:1,highstock:1},description:"Vertical position of the text baseline relative to the alignment.\n Default varies by orientation."},subtree:{}}}},value:{meta:{types:{number:1},name:"value",excludes:{},products:{highcharts:1,highstock:1},description:"The position of the line in axis units."},subtree:{}},width:{meta:{types:{number:1},name:"width",excludes:{},products:{highcharts:1,highstock:1},description:"The width or thickness of the plot line."},subtree:{}},zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},products:{highcharts:1,highstock:1},description:"The z index of the plot line within the chart."},subtree:{}}}},range:{meta:{types:{number:1},name:"range",excludes:{},products:{highstock:1},description:"The zoomed range to display when only defining one or none of `min`\nor `max`. For example, to show the latest month, a range of one month\ncan be set."},subtree:{}},reversed:{meta:{types:{boolean:1},name:"reversed",excludes:{},default:"false",description:"Whether to reverse the axis so that the highest number is closest\nto the origin. If the chart is inverted, the x axis is reversed by\ndefault."},subtree:{}},reversedStacks:{meta:{types:{boolean:1},name:"reversedStacks",excludes:{},default:"false",products:{highcharts:1,highstock:1},description:"This option determines how stacks should be ordered within a group.\nFor example reversed xAxis also reverses stacks, so first series\ncomes last in a group. To keep order like for non-reversed xAxis\nenable this option."},subtree:{}},scrollbar:{meta:{types:{"*":1},name:"scrollbar",excludes:{},products:{highstock:1},description:"An optional scrollbar to display on the X axis in response to\nlimiting the minimum and maximum of the axis values.\n\nIn styled mode, all the presentational options for the scrollbar\nare replaced by the classes `.highcharts-scrollbar-thumb`,\n`.highcharts-scrollbar-arrow`, `.highcharts-scrollbar-button`,\n`.highcharts-scrollbar-rifles` and `.highcharts-scrollbar-track`.",extends:"scrollbar"},subtree:{}},showEmpty:{meta:{types:{boolean:1},name:"showEmpty",excludes:{},default:"true",description:"Whether to show the axis line and title when the axis has no data."},subtree:{}},showFirstLabel:{meta:{types:{boolean:1},name:"showFirstLabel",excludes:{},default:"true",description:"Whether to show the first tick label."},subtree:{}},showLastLabel:{meta:{types:{boolean:1},name:"showLastLabel",excludes:{},default:"true",products:{highcharts:1,highstock:1},description:"Whether to show the last tick label. Defaults to `true` on cartesian\ncharts, and `false` on polar charts."},subtree:{}},softMax:{meta:{types:{number:1},name:"softMax",excludes:{},products:{highcharts:1,highstock:1},description:"A soft maximum for the axis. If the series data maximum is less than\nthis, the axis will stay at this maximum, but if the series data\nmaximum is higher, the axis will flex to show all data."},subtree:{}},softMin:{meta:{types:{number:1},name:"softMin",excludes:{},products:{highcharts:1,highstock:1},description:"A soft minimum for the axis. If the series data minimum is greater\nthan this, the axis will stay at this minimum, but if the series\ndata minimum is lower, the axis will flex to show all data."},subtree:{}},startOfWeek:{meta:{types:{number:1},name:"startOfWeek",excludes:{},default:"1",products:{highcharts:1,highstock:1},description:"For datetime axes, this decides where to put the tick between weeks.\n 0 = Sunday, 1 = Monday."},subtree:{}},startOnTick:{meta:{types:{boolean:1},name:"startOnTick",excludes:{},default:!1,description:"Whether to force the axis to start on a tick. Use this option with\nthe `minPadding` option to control the axis start."},subtree:{}},tickAmount:{meta:{types:{number:1},name:"tickAmount",excludes:{},products:{highcharts:1,highstock:1},description:"The amount of ticks to draw on the axis. This opens up for aligning\nthe ticks of multiple charts or panes within a chart. This option\noverrides the `tickPixelInterval` option.\n\nThis option only has an effect on linear axes. Datetime, logarithmic\nor category axes are not affected."},subtree:{}},tickColor:{meta:{types:{"highcharts.colorstring":1},name:"tickColor",excludes:{},default:"#ccd6eb",description:"Color for the main tick marks.\n\nIn styled mode, the stroke is given in the `.highcharts-tick`\nclass."},subtree:{}},tickInterval:{meta:{types:{number:1},name:"tickInterval",excludes:{},description:"The interval of the tick marks in axis units. When `undefined`, the\ntick interval is computed to approximately follow the\n[tickPixelInterval](#xAxis.tickPixelInterval) on linear and datetime\naxes. On categorized axes, a `undefined` tickInterval will default to\n1, one category. Note that datetime axes are based on milliseconds,\nso for example an interval of one day is expressed as\n`24 * 3600 * 1000`.\n\nOn logarithmic axes, the tickInterval is based on powers, so a\ntickInterval of 1 means one tick on each of 0.1, 1, 10, 100 etc. A\ntickInterval of 2 means a tick of 0.1, 10, 1000 etc. A tickInterval\nof 0.2 puts a tick on 0.1, 0.2, 0.4, 0.6, 0.8, 1, 2, 4, 6, 8, 10, 20,\n40 etc.\n\n\nIf the tickInterval is too dense for labels to be drawn, Highcharts\nmay remove ticks.\n\nIf the chart has multiple axes, the [alignTicks](#chart.alignTicks)\noption may interfere with the `tickInterval` setting."},subtree:{}},tickLength:{meta:{types:{number:1},name:"tickLength",excludes:{},default:10,description:"The pixel length of the main tick marks."},subtree:{}},tickPixelInterval:{meta:{types:{number:1},name:"tickPixelInterval",excludes:{},default:100,description:"If tickInterval is `null` this option sets the approximate pixel\ninterval of the tick marks. Not applicable to categorized axis.\n\nThe tick interval is also influenced by the [minTickInterval](\n#xAxis.minTickInterval) option, that, by default prevents ticks from\nbeing denser than the data points."},subtree:{}},tickPosition:{meta:{types:{string:1},name:"tickPosition",excludes:{},default:"outside",description:"The position of the major tick marks relative to the axis line.\nCan be one of `inside` and `outside`."},subtree:{}},tickPositioner:{meta:{types:{function:1},name:"tickPositioner",excludes:{},description:"A callback function returning array defining where the ticks are\nlaid out on the axis. This overrides the default behaviour of\n[tickPixelInterval](#xAxis.tickPixelInterval) and [tickInterval](\n#xAxis.tickInterval). The automatic tick positions are accessible\nthrough `this.tickPositions` and can be modified by the callback."},subtree:{}},tickPositions:{meta:{types:{array:"number"},name:"tickPositions",excludes:{},description:"An array defining where the ticks are laid out on the axis. This\noverrides the default behaviour of [tickPixelInterval](\n#xAxis.tickPixelInterval) and [tickInterval](#xAxis.tickInterval)."},subtree:{}},tickWidth:{meta:{types:{number:1},name:"tickWidth",excludes:{},description:"The pixel width of the major tick marks.\n\nIn styled mode, the stroke width is given in the `.highcharts-tick`\nclass."},subtree:{}},tickmarkPlacement:{meta:{types:{string:1},name:"tickmarkPlacement",excludes:{},default:"between",products:{highcharts:1},description:"For categorized axes only. If `on` the tick mark is placed in the\ncenter of the category, if `between` the tick mark is placed between\ncategories. The default is `between` if the `tickInterval` is 1,\n else `on`."},subtree:{}},title:{meta:{types:{object:1},name:"title",excludes:{},description:"The axis title, showing next to the axis line."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},default:"middle",description:'Alignment of the title relative to the axis values. Possible\nvalues are "low", "middle" or "high".'},subtree:{}},enabled:{meta:{types:{string:1},name:"enabled",excludes:{},default:"middle",products:{highcharts:1},description:"Deprecated. Set the `text` to `null` to disable the title."},subtree:{}},margin:{meta:{types:{number:1},name:"margin",excludes:{},description:"The pixel distance between the axis labels or line and the title.\nDefaults to 0 for horizontal axes, 10 for vertical"},subtree:{}},offset:{meta:{types:{number:1},name:"offset",excludes:{},description:"The distance of the axis title from the axis line. By default,\nthis distance is computed from the offset width of the labels,\nthe labels' distance from the axis and the title's margin.\nHowever when the offset option is set, it overrides all this."},subtree:{}},position3d:{meta:{types:{string:1},name:"position3d",excludes:{},default:null,products:{highcharts:1},description:"Defines how the title is repositioned according to the 3D chart\norientation.\n- `'offset'`: Maintain a fixed horizontal/vertical distance from the\n tick marks, despite the chart orientation. This is the backwards\n compatible behavior, and causes skewing of X and Z axes.\n- `'chart'`: Preserve 3D position relative to the chart.\n This looks nice, but hard to read if the text isn't\n forward-facing.\n- `'flap'`: Rotated text along the axis to compensate for the chart\n orientation. This tries to maintain text as legible as possible on\n all orientations.\n- `'ortho'`: Rotated text along the axis direction so that the labels\n are orthogonal to the axis. This is very similar to `'flap'`, but\n prevents skewing the labels (X and Y scaling are still present).\n- `null`: Will use the config from `labels.position3d`"},subtree:{}},reserveSpace:{meta:{types:{boolean:1},name:"reserveSpace",excludes:{},default:"true",products:{highcharts:1,highstock:1},description:"Whether to reserve space for the title when laying out the axis."},subtree:{}},rotation:{meta:{types:{number:1},name:"rotation",excludes:{},default:"0",description:"The rotation of the text in degrees. 0 is horizontal, 270 is\nvertical reading from bottom to top."},subtree:{}},skew3d:{meta:{types:{boolean:1},name:"skew3d",excludes:{},default:null,products:{highcharts:1},description:"If enabled, the axis title will skewed to follow the perspective.\n\nThis will fix overlapping labels and titles, but texts become less\nlegible due to the distortion.\n\nThe final appearance depends heavily on `title.position3d`.\n\nA `null` value will use the config from `labels.skew3d`."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},default:'{"color": "#666666"}',description:"CSS styles for the title. If the title text is longer than the\naxis length, it will wrap to multiple lines by default. This can\nbe customized by setting `textOverflow: 'ellipsis'`, by\nsetting a specific `width` or by setting `whiteSpace: 'nowrap'`.\n\nIn styled mode, the stroke width is given in the\n`.highcharts-axis-title` class."},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#666666"},subtree:{}}}},text:{meta:{types:{string:1},name:"text",excludes:{},description:"The actual text of the axis title. It can contain basic HTML text\nmarkup like , and spans with style."},subtree:{}},textAlign:{meta:{types:{string:1},name:"textAlign",excludes:{},description:'Alignment of the text, can be `"left"`, `"right"` or `"center"`.\nDefault alignment depends on the\n[title.align](xAxis.title.align):\n\nHorizontal axes:\n- for `align` = `"low"`, `textAlign` is set to `left`\n- for `align` = `"middle"`, `textAlign` is set to `center`\n- for `align` = `"high"`, `textAlign` is set to `right`\n\nVertical axes:\n- for `align` = `"low"` and `opposite` = `true`, `textAlign` is\n set to `right`\n- for `align` = `"low"` and `opposite` = `false`, `textAlign` is\n set to `left`\n- for `align` = `"middle"`, `textAlign` is set to `center`\n- for `align` = `"high"` and `opposite` = `true` `textAlign` is\n set to `left`\n- for `align` = `"high"` and `opposite` = `false` `textAlign` is\n set to `right`'},subtree:{}},useHTML:{meta:{types:{boolean:1},name:"useHTML",excludes:{},default:"false",products:{highcharts:1,highstock:1},description:"Whether to [use HTML](https://www.highcharts.com/docs/\nchart-concepts/labels-and-string-formatting#html) to render the\naxis title."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"0",products:{highcharts:1,highstock:1},description:"Horizontal pixel offset of the title position."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},products:{highcharts:1,highstock:1},description:"Vertical pixel offset of the title position."},subtree:{}}}},type:{meta:{types:{string:1},name:"type",excludes:{},default:"linear",products:{highcharts:1},description:"The type of axis. Can be one of `linear`, `logarithmic`, `datetime`\nor `category`. In a datetime axis, the numbers are given in\nmilliseconds, and tick marks are placed on appropriate values like\nfull hours or days. In a category axis, the\n[point names](#series.line.data.name) of the chart's series are used\nfor categories, if not a [categories](#xAxis.categories) array is\ndefined."},subtree:{}},uniqueNames:{meta:{types:{boolean:1},name:"uniqueNames",excludes:{},default:"true",products:{highcharts:1},description:"Applies only when the axis `type` is `category`. When `uniqueNames`\nis true, points are placed on the X axis according to their names.\nIf the same point name is repeated in the same or another series,\nthe point is placed on the same X position as other points of the\nsame name. When `uniqueNames` is false, the points are laid out in\nincreasing X positions regardless of their names, and the X axis\ncategory will take the name of the last point in each position."},subtree:{}},units:{meta:{types:{array:"Array.<(string|Array.units: [[\n 'millisecond', // unit name\n [1, 2, 5, 10, 20, 25, 50, 100, 200, 500] // allowed multiples\n], [\n 'second',\n [1, 2, 5, 10, 15, 30]\n], [\n 'minute',\n [1, 2, 5, 10, 15, 30]\n], [\n 'hour',\n [1, 2, 3, 4, 6, 8, 12]\n], [\n 'day',\n [1]\n], [\n 'week',\n [1]\n], [\n 'month',\n [1, 3, 6]\n], [\n 'year',\n null\n]]"},subtree:{}},visible:{meta:{types:{boolean:1},name:"visible",excludes:{},default:"true",products:{highcharts:1,highstock:1},description:"Whether axis, including axis title, line, ticks and labels, should\nbe visible."},subtree:{}}}},yAxis:{meta:{types:{array:"yAxis"},name:"yAxis",excludes:{},description:"The Y axis or value axis. Normally this is the vertical axis,\nthough if the chart is inverted this is the horizontal axis.\nIn case of multiple axes, the yAxis node is an array of\nconfiguration objects.\n\nSee [the Axis object](/class-reference/Highcharts.Axis) for programmatic\naccess to the axis.",extends:"xAxis"},subtree:{angle:{meta:{types:{number:1},name:"angle",excludes:{},default:"0",products:{highcharts:1},description:"In a polar chart, this is the angle of the Y axis in degrees, where\n0 is up and 90 is right. The angle determines the position of the\naxis line and the labels, though the coordinate system is unaffected."},subtree:{}},endOnTick:{meta:{types:{boolean:1},name:"endOnTick",excludes:{},default:"true"},subtree:{}},gridLineInterpolation:{meta:{types:{string:1},name:"gridLineInterpolation",excludes:{},products:{highcharts:1},description:"Polar charts only. Whether the grid lines should draw as a polygon\nwith straight lines between categories, or as circles. Can be either\n`circle` or `polygon`."},subtree:{}},gridLineWidth:{meta:{types:{number:1},name:"gridLineWidth",excludes:{},default:1},subtree:{}},height:{meta:{types:{number:1,string:1},name:"height",excludes:{},products:{highstock:1},description:"The height of the Y axis. If it's a number, it is interpreted as\npixels.\n\nSince Highstock 2: If it's a percentage string, it is interpreted\nas percentages of the total plot height."},subtree:{}},labels:{meta:{types:{"*":1},name:"labels",excludes:{},extends:"xAxis.labels"},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},description:'What part of the string the given position is anchored to. Can\nbe one of `"left"`, `"center"` or `"right"`. The exact position\nalso depends on the `labels.x` setting.\n\nAngular gauges and solid gauges defaults to `center`.'},subtree:{}},distance:{meta:{types:{number:1},name:"distance",excludes:{},default:"-25",products:{highcharts:1},description:"Angular gauges and solid gauges only. The label's pixel distance\nfrom the perimeter of the plot area."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:"-8",description:"The x position offset of the label relative to the tick position\non the axis. Defaults to -15 for left axis, 15 for right axis."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},description:"The y position offset of the label relative to the tick position\non the axis."},subtree:{}}}},lineColor:{meta:{types:{"highcharts.colorstring":1},name:"lineColor",excludes:{}},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:0},subtree:{}},max:{meta:{types:{number:1},name:"max",excludes:{}},subtree:{}},maxColor:{meta:{types:{"highcharts.colorstring":1},name:"maxColor",excludes:{},default:"#003399",products:{highcharts:1},description:"Solid gauge only. Unless [stops](#yAxis.stops) are set, the color\nto represent the maximum value of the Y axis."},subtree:{}},maxLength:{meta:{types:{number:1,string:1},name:"maxLength",excludes:{},products:{highstock:1},description:"Maximal size of a resizable axis. Could be set as a percent\nof plot area or pixel size.\n\nThis feature requires the `drag-panes.js` module."},subtree:{}},maxPadding:{meta:{types:{number:1},name:"maxPadding",excludes:{},default:"0.05",products:{highcharts:1,highstock:1},description:"Padding of the max value relative to the length of the axis. A\npadding of 0.05 will make a 100px axis 5px longer. This is useful\nwhen you don't want the highest data value to appear on the edge\nof the plot area. When the axis' `max` option is set or a max extreme\nis set using `axis.setExtremes()`, the maxPadding will be ignored."},subtree:{}},min:{meta:{types:{number:1},name:"min",excludes:{}},subtree:{}},minColor:{meta:{types:{"highcharts.colorstring":1},name:"minColor",excludes:{},default:"#e6ebf5",products:{highcharts:1},description:"Solid gauge only. Unless [stops](#yAxis.stops) are set, the color\nto represent the minimum value of the Y axis."},subtree:{}},minLength:{meta:{types:{number:1,string:1},name:"minLength",excludes:{},products:{highstock:1},description:"Minimal size of a resizable axis. Could be set as a percent\nof plot area or pixel size.\n\nThis feature requires the `drag-panes.js` module."},subtree:{}},minPadding:{meta:{types:{number:1},name:"minPadding",excludes:{},default:.05},subtree:{}},opposite:{meta:{types:{boolean:1},name:"opposite",excludes:{},products:{highcharts:1,highstock:1}},subtree:{}},plotBands:{meta:{types:{array:"*"},name:"plotBands",excludes:{},products:{highcharts:1,highstock:1},description:"An array of objects defining plot bands on the Y axis.",extends:"xAxis.plotBands"},subtree:{innerRadius:{meta:{types:{number:1,string:1},name:"innerRadius",excludes:{},products:{highcharts:1},description:'In a gauge chart, this option determines the inner radius of the\nplot band that stretches along the perimeter. It can be given as\na percentage string, like `"100%"`, or as a pixel number, like `100`.\nBy default, the inner radius is controlled by the [thickness](\n#yAxis.plotBands.thickness) option.'},subtree:{}},outerRadius:{meta:{types:{number:1,string:1},name:"outerRadius",excludes:{},default:"100%",products:{highcharts:1},description:'In a gauge chart, this option determines the outer radius of the\nplot band that stretches along the perimeter. It can be given as\na percentage string, like `"100%"`, or as a pixel number, like `100`.'},subtree:{}},thickness:{meta:{types:{number:1,string:1},name:"thickness",excludes:{},default:"10",products:{highcharts:1},description:'In a gauge chart, this option sets the width of the plot band\nstretching along the perimeter. It can be given as a percentage\nstring, like `"10%"`, or as a pixel number, like `10`. The default\nvalue 10 is the same as the default [tickLength](#yAxis.tickLength),\nthus making the plot band act as a background for the tick markers.'},subtree:{}}}},plotLines:{meta:{types:{array:"*"},name:"plotLines",excludes:{},products:{highcharts:1,highstock:1},description:"An array of objects representing plot lines on the X axis",extends:"xAxis.plotLines"},subtree:{}},resize:{meta:{types:{object:1},name:"resize",excludes:{},products:{highstock:1},description:"Options for axis resizing. This feature requires the\n`drag-panes.js` -\n[classic](http://code.highcharts.com/stock/modules/drag-panes.js) or\n[styled](http://code.highcharts.com/stock/js/modules/drag-panes.js)\nmode - module."},subtree:{controlledAxis:{meta:{types:{object:1},name:"controlledAxis",excludes:{},description:"Contains two arrays of axes that are controlled by control line\nof the axis.\n\nThis feature requires the `drag-panes.js` module."},subtree:{next:{meta:{types:{array:"(String|Number)"},name:"next",excludes:{},default:"[]",description:"Array of axes that should move out of the way of resizing\nbeing done for the current axis. If not set, the next axis\nwill be used.\n\nThis feature requires the `drag-panes.js` module."},subtree:{}},prev:{meta:{types:{array:"(String|Number)"},name:"prev",excludes:{},description:"Array of axes that should move with the current axis\nwhile resizing.\n\nThis feature requires the `drag-panes.js` module."},subtree:{}}}},cursor:{meta:{types:{string:1},name:"cursor",excludes:{},default:"ns-resize",description:"Cursor style for the control line.\n\nIn styled mode use class `highcharts-axis-resizer` instead.\n\nThis feature requires the `drag-panes.js` module."},subtree:{}},enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1,description:"Enable or disable resize by drag for the axis.\n\nThis feature requires the `drag-panes.js` module."},subtree:{}},lineColor:{meta:{types:{color:1},name:"lineColor",excludes:{},default:"#cccccc",description:"Color of the control line.\n\nIn styled mode use class `highcharts-axis-resizer` instead.\n\nThis feature requires the `drag-panes.js` module."},subtree:{}},lineDashStyle:{meta:{types:{string:1},name:"lineDashStyle",excludes:{},default:"Solid",description:"Dash style of the control line.\n\nIn styled mode use class `highcharts-axis-resizer` instead.\n\nThis feature requires the `drag-panes.js` module."},subtree:{}},lineWidth:{meta:{types:{number:1},name:"lineWidth",excludes:{},default:4,description:"Width of the control line.\n\nIn styled mode use class `highcharts-axis-resizer` instead.\n\nThis feature requires the `drag-panes.js` module."},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},default:0,description:"Horizontal offset of the control line.\n\nThis feature requires the `drag-panes.js` module."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},default:0,description:"Vertical offset of the control line.\n\nThis feature requires the `drag-panes.js` module."},subtree:{}}}},reversed:{meta:{types:{boolean:1},name:"reversed",excludes:{},description:"Whether to reverse the axis so that the highest number is closest\nto the origin."},subtree:{}},reversedStacks:{meta:{types:{boolean:1},name:"reversedStacks",excludes:{},default:"true",products:{highcharts:1,highstock:1},description:"If `true`, the first series in a stack will be drawn on top in a\npositive, non-reversed Y axis. If `false`, the first series is in\nthe base of the stack."},subtree:{}},scrollbar:{meta:{types:{"*":1},name:"scrollbar",excludes:{},products:{highstock:1},description:"An optional scrollbar to display on the Y axis in response to\nlimiting the minimum an maximum of the axis values.\n\nIn styled mode, all the presentational options for the scrollbar\nare replaced by the classes `.highcharts-scrollbar-thumb`,\n`.highcharts-scrollbar-arrow`, `.highcharts-scrollbar-button`,\n`.highcharts-scrollbar-rifles` and `.highcharts-scrollbar-track`.",extends:"scrollbar"},subtree:{enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:"false",products:{highstock:1},description:"Enable the scrollbar on the Y axis."},subtree:{}},margin:{meta:{types:{number:1},name:"margin",excludes:{},default:"10",products:{highstock:1},description:"Pixel margin between the scrollbar and the axis elements."},subtree:{}},showFull:{meta:{types:{boolean:1},name:"showFull",excludes:{},default:"true",products:{highstock:1},description:"Whether to show the scrollbar when it is fully zoomed out at max\nrange. Setting it to `false` on the Y axis makes the scrollbar stay\nhidden until the user zooms in, like common in browsers."},subtree:{}},size:{meta:{types:{number:1},name:"size",excludes:{},default:"14",products:{highstock:1},description:"The width of a vertical scrollbar or height of a horizontal\nscrollbar. Defaults to 20 on touch devices."},subtree:{}},zIndex:{meta:{types:{number:1},name:"zIndex",excludes:{},default:"3",products:{highstock:1},description:"Z index of the scrollbar elements."},subtree:{}}}},showLastLabel:{meta:{types:{boolean:1},name:"showLastLabel",excludes:{},default:"true"},subtree:{}},softMax:{meta:{types:{number:1},name:"softMax",excludes:{},products:{highcharts:1,highstock:1},description:"A soft maximum for the axis. If the series data maximum is less\nthan this, the axis will stay at this maximum, but if the series\ndata maximum is higher, the axis will flex to show all data.\n\n**Note**: The [series.softThreshold](\n#plotOptions.series.softThreshold) option takes precedence over this\noption."},subtree:{}},softMin:{meta:{types:{number:1},name:"softMin",excludes:{},products:{highcharts:1,highstock:1},description:"A soft minimum for the axis. If the series data minimum is greater\nthan this, the axis will stay at this minimum, but if the series\ndata minimum is lower, the axis will flex to show all data.\n\n**Note**: The [series.softThreshold](\n#plotOptions.series.softThreshold) option takes precedence over this\noption."},subtree:{}},stackLabels:{meta:{types:{"*":1},name:"stackLabels",excludes:{},products:{highcharts:1},description:"The stack labels show the total value for each bar in a stacked\ncolumn or bar chart. The label will be placed on top of positive\ncolumns and below negative columns. In case of an inverted column\nchart or a bar chart the label is placed to the right of positive\nbars and to the left of negative bars."},subtree:{align:{meta:{types:{string:1},name:"align",excludes:{},products:{highcharts:1},description:'Defines the horizontal alignment of the stack total label. Can be one\nof `"left"`, `"center"` or `"right"`. The default value is calculated\nat runtime and depends on orientation and whether the stack is\npositive or negative.'},subtree:{}},allowOverlap:{meta:{types:{boolean:1},name:"allowOverlap",excludes:{},default:!1,products:{highcharts:1},description:"Allow the stack labels to overlap."},subtree:{} },enabled:{meta:{types:{boolean:1},name:"enabled",excludes:{},default:!1,products:{highcharts:1},description:"Enable or disable the stack total labels."},subtree:{}},format:{meta:{types:{string:1},name:"format",excludes:{},default:"{total}",products:{highcharts:1,highstock:1},description:"A [format string](http://docs.highcharts.com/#formatting) for the\ndata label. Available variables are the same as for `formatter`."},subtree:{}},formatter:{meta:{types:{function:1},name:"formatter",excludes:{},default:"function() { return H.numberFormat(this.total, -1); }",products:{highcharts:1},description:"Callback JavaScript function to format the label. The value is\ngiven by `this.total`."},subtree:{}},rotation:{meta:{types:{number:1},name:"rotation",excludes:{},default:"0",products:{highcharts:1},description:"Rotation of the labels in degrees."},subtree:{}},style:{meta:{types:{"highcharts.cssobject":1},name:"style",excludes:{},products:{highcharts:1},description:"CSS styles for the label.\n\nIn styled mode, the styles are set in the\n`.highcharts-stack-label` class."},subtree:{color:{meta:{types:{string:1},name:"color",excludes:{},default:"#000000"},subtree:{}},fontSize:{meta:{types:{string:1},name:"fontSize",excludes:{},default:"11px"},subtree:{}},fontWeight:{meta:{types:{string:1},name:"fontWeight",excludes:{},default:"bold"},subtree:{}},textOutline:{meta:{types:{string:1},name:"textOutline",excludes:{},default:"1px contrast"},subtree:{}}}},textAlign:{meta:{types:{string:1},name:"textAlign",excludes:{},products:{highcharts:1},description:'The text alignment for the label. While `align` determines where the\ntexts anchor point is placed with regards to the stack, `textAlign`\ndetermines how the text is aligned against its anchor point. Possible\nvalues are `"left"`, `"center"` and `"right"`. The default value is\ncalculated at runtime and depends on orientation and whether the\nstack is positive or negative.'},subtree:{}},useHTML:{meta:{types:{boolean:1},name:"useHTML",excludes:{},default:"false",products:{highcharts:1,highstock:1},description:"Whether to [use HTML](https://www.highcharts.com/docs/chart-concepts/\nlabels-and-string-formatting#html) to render the labels."},subtree:{}},verticalAlign:{meta:{types:{string:1},name:"verticalAlign",excludes:{},products:{highcharts:1},description:'Defines the vertical alignment of the stack total label. Can be one\nof `"top"`, `"middle"` or `"bottom"`. The default value is calculated\nat runtime and depends on orientation and whether the stack is\npositive or negative.'},subtree:{}},x:{meta:{types:{number:1},name:"x",excludes:{},products:{highcharts:1},description:"The x position offset of the label relative to the left of the\nstacked bar. The default value is calculated at runtime and depends\non orientation and whether the stack is positive or negative."},subtree:{}},y:{meta:{types:{number:1},name:"y",excludes:{},products:{highcharts:1},description:"The y position offset of the label relative to the tick position\non the axis. The default value is calculated at runtime and depends\non orientation and whether the stack is positive or negative."},subtree:{}}}},startOnTick:{meta:{types:{boolean:1},name:"startOnTick",excludes:{},default:"true",products:{highcharts:1,highstock:1},description:"Whether to force the axis to start on a tick. Use this option with\nthe `maxPadding` option to control the axis start."},subtree:{}},stops:{meta:{types:{array:"Array.<(number|Highcharts.ColorString)"},name:"stops",excludes:{},products:{highcharts:1},description:"Solid gauge series only. Color stops for the solid gauge. Use this\nin cases where a linear gradient between a `minColor` and `maxColor`\nis not sufficient. The stops is an array of tuples, where the first\nitem is a float between 0 and 1 assigning the relative position in\nthe gradient, and the second item is the color.\n\nFor solid gauges, the Y axis also inherits the concept of [data classes](http://api.\nhighcharts.com/highmaps#colorAxis.dataClasses) from the Highmaps\ncolor axis."},subtree:{}},tickPixelInterval:{meta:{types:{number:1},name:"tickPixelInterval",excludes:{},default:"72"},subtree:{}},tickWidth:{meta:{types:{number:1},name:"tickWidth",excludes:{},default:"0",products:{highcharts:1,highstock:1},description:"The pixel width of the major tick marks."},subtree:{}},title:{meta:{types:{"*":1},name:"title",excludes:{},extends:"xAxis.title"},subtree:{margin:{meta:{types:{number:1},name:"margin",excludes:{},default:"40",description:"The pixel distance between the axis labels and the title.\nPositive values are outside the axis line, negative are inside."},subtree:{}},rotation:{meta:{types:{number:1},name:"rotation",excludes:{},default:"270",description:"The rotation of the text in degrees. 0 is horizontal, 270 is\nvertical reading from bottom to top."},subtree:{}},text:{meta:{types:{string:1},name:"text",excludes:{},default:"Values",products:{highcharts:1,highstock:1},description:"The actual text of the axis title. Horizontal texts can contain\nHTML, but rotated texts are painted using vector techniques and\nmust be clean text. The Y axis title is disabled by setting the\n`text` option to `undefined`."},subtree:{}}}},tooltipValueFormat:{meta:{types:{string:1},name:"tooltipValueFormat",excludes:{},default:"undefined",description:"Parallel coordinates only. Format that will be used for point.y\nand available in [tooltip.pointFormat](#tooltip.pointFormat) as\n`{point.formattedValue}`. If not set, `{point.formattedValue}`\nwill use other options, in this order:\n\n1. [yAxis.labels.format](#yAxis.labels.format) will be used if\n set\n2. if yAxis is a category, then category name will be displayed\n3. if yAxis is a datetime, then value will use the same format as\n yAxis labels\n4. if yAxis is linear/logarithmic type, then simple value will be\n used"},subtree:{}},top:{meta:{types:{number:1,string:1},name:"top",excludes:{},products:{highstock:1},description:"The top position of the Y axis. If it's a number, it is interpreted\nas pixel position relative to the chart.\n\nSince Highstock 2: If it's a percentage string, it is interpreted\nas percentages of the plot height, offset from plot area top."},subtree:{}}}},zAxis:{meta:{types:{array:"zAxis"},name:"zAxis",excludes:{},products:{highcharts:1},description:"The Z axis or depth axis for 3D plots.\n\nSee [the Axis object](/class-reference/Highcharts.Axis) for programmatic\naccess to the axis.",extends:"xAxis"},subtree:{}}}}; //模板 //Install "zh_cn" translations highed.installLanguage({ language: "zh_cn", entries: { "confirmNewChart": "确定放弃当前图表并重新开始?", "previewChart": "预览", "newChart": "新建", "saveProject": "保存项目", "loadProject": "加载项目", "exportPNG": "导出为PNG", "exportJPEG": "导出为JPEG", "exportSVG": "导出为SVG", "exportPDF": "导出为PDF", "help": "帮助", "licenseInfo": "许可信息", "stepDone": "完成", "stepStart": "开始", "stepImport": "导入", "stepTemplates": "模板", "stepCustomize": "自定义", "stepExport": "导出", "stepData": "数据", "doneCaption": "关闭并生成图表", "dgDeleteRow": "确定删除已选行?", "dgWithSelected": "对已选择的行:", "dgImportBtn": "导入", "dgExportBtn": "导出", "dgNewBtn": "新建", "dgAddRow": "增加行", "dgDataImported": "数据已导入", "dgDataImporting": "数据导入中", "dgNewCol": "新增列", "dgSortAsc": "升序", "dgSortDec": "倒序", "dgSortAscMonth": "按月升序", "dgSortDecMonth": "按月倒序", "dgDelCol": "删除列", "dgDelColConfirm": "确定删除该列?", "dgInsColBefore": "前插列", "dgInsColAfter": "后插列", "customizeSimple": "简单", "customizeAdvanced": "高级", "option.cat.title": "标题", "option.subcat.titles": "主标题", "option.cat.general": "通用", "option.subcat.size": "图表尺寸", "option.subcat.interaction": "图表交互", "option.cat.appearance": "外观", "option.subcat.fonts": "字体", "option.subcat.titlestyle": "标题样式", "option.subcat.seriescolors": "系列颜色", "option.subcat.chartarea": "图表区域", "option.subcat.plotarea": "绘图区域", "option.cat.axes": "轴", "option.subcat.axessetup": "轴设置", "option.subcat.xaxis": "X轴", "option.subcat.yaxis": "Y轴", "option.cat.series": "数据系列", "option.cat.labels": "数据标签", "option.subcat.labels": "数据标签", "option.cat.legend": "图例", "option.subcat.general": "通用", "option.subcat.placement": "位置", "option.subcat.legendappearance": "外观", "option.cat.tooltip": "提示", "option.subcat.colorborder": "颜色和边框", "option.cat.exporting": "导出", "option.cat.localization": "本地化", "option.subcat.numberformat": "数值格式", "option.subcat.exportbutton": "导出按钮及菜单", "option.subcat.zoombutton": "缩放按钮", "option.cat.credits": "著作权", "option.text.title.text": "图表标题", "option.tooltip.title.text": "主标题", "option.text.subtitle.text": "副标题", "option.tooltip.subtitle.text": "图表的副标题,以较小的字体显示在主标题下方", "option.text.yAxis.title.text": "Y轴标题", "option.tooltip.yAxis.title.text": "Y轴标题,沿Y轴方向显示", "option.text.chart.width": "图表宽度", "option.tooltip.chart.width": "图表的确切宽度。默认(null)根据包含元素的偏移宽度计算。", "option.text.chart.height": "图表高度", "option.tooltip.chart.height": "图表的确切高度。默认(null)根据包含元素的偏移高度计算,若包含元素高度为0则采用400像素。", "option.text.chart.zoomType": "允许缩放", "option.tooltip.chart.zoomType": "用户可以通过鼠标拖拽缩放的维度。可选值为:x, y or xy.", "option.text.chart.polar": "极坐标(雷达)投影", "option.tooltip.chart.polar": "若勾选,线图、样条图、堆积图和柱状图将会按照极坐标系统进行转换。需要highcharts-more.js支持。", "option.text.chart.style": "所有字体", "option.tooltip.chart.style": "整个使用的字体", "option.text.title.style": "主标题样式", "option.tooltip.title.style": "控制主标题的样式", "option.text.subtitle.style": "副标题样式", "option.tooltip.subtitle.style": "控制副标题的样式,通常以更小的字体在主标题下方显示", "option.text.colors": "颜色", "option.tooltip.colors": "数据系列默认的颜色,或者针对饼图或柱状图单个点的颜色。色彩会被按顺序选择。如果在数据系列中对系列进行设置,则以之为准。", "option.text.chart.backgroundColor": "背景颜色", "option.tooltip.chart.backgroundColor": "整个图表区域的背景颜色", "option.text.chart.borderWidth": "边框宽度", "option.tooltip.chart.borderWidth": "图表外边框宽度(像素)。", "option.text.chart.borderRadius": "边角半径", "option.tooltip.chart.borderRadius": "图表外边框角半径。", "option.text.chart.borderColor": "边框颜色", "option.tooltip.chart.borderColor": "图表外边框颜色。", "option.text.chart.plotBackgroundColor": "背景颜色", "option.tooltip.chart.plotBackgroundColor": "绘图区域(坐标内区域)背景色", "option.text.chart.plotBackgroundImage": "背景图片链接", "option.tooltip.chart.plotBackgroundImage": "作为绘图区域背景图片的在线URL", "option.text.chart.plotBorderWidth": "边框宽度", "option.tooltip.chart.plotBorderWidth": "绘图区域边框宽度(像素)。", "option.text.chart.plotBorderColor": "边框颜色", "option.tooltip.chart.plotBorderColor": "绘图区域边框颜色。", "option.text.chart.inverted": "交换轴", "option.tooltip.chart.inverted": "

    是否交换轴以使得x轴垂直而y轴水平。When true, the x axis is reversed by default. If a bar series is present in the chart, it will be inverted automatically.

    \r\n\r\n

    Inverting the chart doesn't have an effect if there are no cartesian series in the chart, or if the chart is polar.

    ", "option.text.xAxis.title.style": "X轴标题样式", "option.tooltip.xAxis.title.style": "X轴标题的样式", "option.text.xAxis.title.text": "文本", "option.tooltip.xAxis.title.text": "该轴标题的具体文本。它可以含有基础的HTML标签,如:<b>, <i> ", "option.text.xAxis.type": "类型", "option.tooltip.xAxis.type": "轴的类型", "option.text.xAxis.opposite": "对侧显示", "option.tooltip.xAxis.opposite": "是否将坐标轴显示在图表的另一侧。一般来说,垂直的坐标在左侧,水平的坐标在下侧,所以另一侧相应地是指右侧和上侧。一般在双坐标或多坐标场景下使用。", "option.text.xAxis.reversed": "逆向显示", "option.tooltip.xAxis.reversed": "是否将坐标逆向以使得最大坐标值离原点最近。若图表逆向,默认将X轴逆向。", "option.text.xAxis.labels.format": "轴标签格式", "option.tooltip.xAxis.labels.format": "

    轴标签的格式字符串。实际数据可通过变量{value}来获得。

    例如可以使用{value} USD来增加单位。

    在变量内部也可以使用冒号来对数据进行格式化,如:USD {value:.2f}可展现两位有效数字,{value:%Y-%m-%d}可进行日期字符串格式化。", "option.text.yAxis.title.style": "Y轴标题样式", "option.tooltip.yAxis.title.style": "Y轴标题的样式", "option.text.yAxis.type": "类型", "option.tooltip.yAxis.type": "轴的类型", "option.text.yAxis.opposite": "对侧显示", "option.tooltip.yAxis.opposite": "是否将坐标轴显示在图表的另一侧。一般来说,垂直的坐标在左侧,水平的坐标在下侧,所以另一侧相应地是指右侧和上侧。一般在双坐标或多坐标场景下使用。", "option.text.yAxis.reversed": "逆向显示", "option.tooltip.yAxis.reversed": "是否将坐标逆向以使得最大坐标值离原点最近。若图表逆向,默认将Y轴逆向。", "option.text.yAxis.labels.format": "轴标签格式", "option.tooltip.yAxis.labels.format": "

    轴标签的格式字符串。实际数据可通过变量{value}来获得。

    例如可以使用{value} USD来增加单位。

    在变量内部也可以使用冒号来对数据进行格式化,如:USD {value:.2f}可展现两位有效数字,{value:%Y-%m-%d}可进行日期字符串格式化。", "option.text.series.type": "系列类型", "option.tooltip.series.type": "该系列的类型", "option.text.series.color": "颜色", "option.tooltip.series.color": "该系列的主颜色。若此处不指定,则从\"外观\"中的默认颜色中选取。", "option.text.series.negativeColor": "负色", "option.tooltip.series.negativeColor": "该系列低于阈值的负颜色。阈值默认是0,在高级设定中可以修改。", "option.text.series.colorByPoint": "单点着色", "option.tooltip.series.colorByPoint": "每一个点使用一种颜色。颜色可以在\"外观\"中修改。", "option.text.series.dashStyle": "短划线风格", "option.tooltip.series.dashStyle": "图中短划线风格。仅对具有图的系列有作用,如线图, 样条图, 面积图散点图,并且具有lineWidth短划线风格有:\r\n\t\t

      \r\n\t\t \t
    • Solid
    • \r\n\t\t \t
    • ShortDash
    • \r\n\t\t \t
    • ShortDot
    • \r\n\t\t \t
    • ShortDashDot
    • \r\n\t\t \t
    • ShortDashDotDot
    • \r\n\t\t \t
    • Dot
    • \r\n\t\t \t
    • Dash
    • \r\n\t\t \t
    • LongDash
    • \r\n\t\t \t
    • DashDot
    • \r\n\t\t \t
    • LongDashDot
    • \r\n\t\t \t
    • LongDashDotDot
    • \r\n\t\t
    ", "option.text.series.marker.enabled": "启用点标记", "option.tooltip.series.marker.enabled": "是否启用点标记。如果是null,若数据稠密则标记隐藏,否则展现。", "option.text.series.marker.symbol": "标记符号", "option.tooltip.series.marker.symbol": "

    为标记预定义的形状或符号。若空,则顺序使用options.symbols中的符号。其他可选值为:\"circle\", \"square\", \"diamond\", \"triangle\" 以及 \"triangle-down\".

    \r\n\r\n

    Additionally, the URL to a graphic can be given on this form: \"url(graphic.png)\". Note that for the image to be applied to exported charts, its URL needs to be accessible by the export server.

    \r\n\r\n

    Custom callbacks for symbol path generation can also be added to Highcharts.SVGRenderer.prototype.symbols. The callback is then used by its method name, as shown in the demo.

    ", "option.text.plotOptions.series.dataLabels.enabled": "对所有系列启用数据标签", "option.tooltip.plotOptions.series.dataLabels.enabled": "在每个数据值(点、柱、饼图切片等)旁边显示一个小标签。", "option.text.plotOptions.series.dataLabels.style": "文本样式", "option.tooltip.plotOptions.series.dataLabels.style": "标签的样式。", "option.text.legend.enabled": "启用图例", "option.tooltip.legend.enabled": "是否启用图例。", "option.text.legend.layout": "图例布局", "option.tooltip.legend.layout": "图例项的布局。可选为: \"horizontal\" , \"vertical\".", "option.text.legend.align": "水平对齐", "option.tooltip.legend.align": "

    图例在图表区域内的水平对齐。合法取值为:left, center 以及 right

    \r\n\r\n

    若图例对齐到角落位置,layout选项将决定图例展现在绘图区域的上侧或下侧。

    ", "option.text.legend.x": "水平偏移", "option.tooltip.legend.x": "图例相较于它的对齐的偏移量(像素)", "option.text.legend.verticalAlign": "垂直对齐", "option.tooltip.legend.verticalAlign": "

    图例的垂直对齐。合法取值为:top, middlebottom。垂直位置可以通过y选项进一步调整。

    \r\n\r\n

    若图例对齐到角落位置,layout选项将决定图例展现在绘图区域的上侧或下侧。

    ", "option.text.legend.y": "垂直偏移", "option.tooltip.legend.y": "图例相较于它的对齐的偏移量(像素)", "option.text.legend.floating": "在绘图区域内显示", "option.tooltip.legend.floating": "若勾选,则绘图区域不会考虑图例,且绘图可能覆盖图例。", "option.text.legend.itemStyle": "文本样式", "option.tooltip.legend.itemStyle": "每个图例项的CSS样式。仅支持CSS的一个子集,特别是和文本相关的选项。", "option.text.legend.itemHiddenStyle": "隐藏时文本样式", "option.tooltip.legend.itemHiddenStyle": "若系列或点隐藏了,其相关的图例项的CSS样式。仅支持CSS的一个子集,特别是和文本相关的选项。除非此处配置,否则属性从style继承。", "option.text.legend.backgroundColor": "背景颜色", "option.tooltip.legend.backgroundColor": "图例的背景颜色。", "option.text.legend.borderWidth": "边框宽度", "option.tooltip.legend.borderWidth": "图例边框的宽度。", "option.text.legend.borderRadius": "边框角半径", "option.tooltip.legend.borderRadius": "图例的边框角半径。", "option.text.legend.borderColor": "边框颜色", "option.tooltip.legend.borderColor": "图例边框的颜色。", "option.text.tooltip.enabled": "启用提示", "option.tooltip.tooltip.enabled": "是否启用提示。提示指的是当鼠标悬停或者触摸一个点时显示的信息框。", "option.text.tooltip.shared": "系列间共享", "option.tooltip.tooltip.shared": "若勾选,整个绘图区域将捕获鼠标移动或者触摸事件。具有有序数据的系列(非饼图、散点图等)的提示信息将在同一个信息框中展现。推荐对于单系列以及为移动设备优化的图表启用。", "option.text.tooltip.backgroundColor": "背景颜色", "option.tooltip.tooltip.backgroundColor": "提示框的背景颜色", "option.text.tooltip.borderWidth": "边框宽度", "option.tooltip.tooltip.borderWidth": "

    提示边框的宽度(像素)。

    \r\n\r\n

    In styled mode, the stroke width is set in the .highcharts-tooltip-box class.

    ", "option.text.tooltip.borderRadius": "边框角半径", "option.tooltip.tooltip.borderRadius": "提示框的边框角半径。", "option.text.tooltip.borderColor": "边框颜色", "option.tooltip.tooltip.borderColor": "提示框边框颜色。若不设置,则使用与之关联的系列的颜色。", "option.text.exporting.enabled": "启用导出", "option.tooltip.exporting.enabled": "若勾选,则启用图表右上角的上下文按钮以允许终端用户以不同格式下载图表。", "option.text.exporting.sourceWidth": "导出宽度", "option.tooltip.exporting.sourceWidth": "导出时原图的宽度。导出后的图片宽度(像素)等于该值乘以缩放因子。", "option.text.exporting.scale": "缩放因子", "option.tooltip.exporting.scale": "导出时的缩放因子. 若宽度已经设置,则该设置无效。", "option.text.lang.decimalPoint": "小数点", "option.tooltip.lang.decimalPoint": "所有数字使用的小数点", "option.text.lang.thousandsSep": "千位分隔符", "option.tooltip.lang.thousandsSep": "所有数字使用的千位分隔符", "option.text.lang.contextButtonTitle": "上下文按钮标题", "option.tooltip.lang.contextButtonTitle": "导出模块菜单。包含打印和导出菜单项的提示框标题。", "option.text.lang.printChart": "打印图表", "option.tooltip.lang.printChart": "仅用于导出模块。打印图表菜单项的文本内容。", "option.text.lang.downloadPNG": "下载PNG", "option.tooltip.lang.downloadPNG": "仅用于导出模块。PNG下载菜单项的文本内容。", "option.text.lang.downloadJPEG": "下载JPEG", "option.tooltip.lang.downloadJPEG": "仅用于导出模块。JPEG下载菜单项的文本内容。", "option.text.lang.downloadPDF": "下载PDF", "option.tooltip.lang.downloadPDF": "仅用于导出模块。PDF下载菜单项的文本内容。", "option.text.lang.downloadSVG": "下载SVG", "option.tooltip.lang.downloadSVG": "仅用于导出模块。SVG下载菜单项的文本内容。", "option.text.lang.resetZoom": "重置缩放按钮", "option.tooltip.lang.resetZoom": "图表被缩放时展现的标签文本内容。", "option.text.credits.enabled": "启用著作权信息", "option.tooltip.credits.enabled": "是否显示著作权信息", "option.text.credits.text": "著作权信息", "option.tooltip.credits.text": "著作权标签文本内容。", "option.text.credits.href": "链接", "option.tooltip.credits.href": "著作权标签的URL" } }); highed.validators.add("line", function (e) { return !0 }), highed.validators.add("line", function (e) { return !0 }), highed.validators.add("line", function (e) { return !0 }), highed.samples.add({ id: "line-series-dates", title: "Dates on X", description: "", type: "csv", dataset: ["row,val", "2013-01-01,24", "2014-01-01,76", "2015-01-01,23"] }), highed.samples.add({ id: "line-series-four-series", title: "Categorized, four series", description: "", type: "csv", dataset: ["Categories,Tokyo,New York,Berlin,London", "Jan,7,-0.2,-0.9,3.9", "Feb,6.9,0.8,0.6,4.2", "Mar,9.5,5.7,3.5,5.7", "Apr,14.5,11.3,8.4,8.5", "May,18.2,17,13.5,11.9", "Jun,21.5,22,17,15.2", "Jul,25.2,24.8,18.6,17", "Aug,26.5,24.1,17.9,16.6", "Sep,23.3,20.1,14.3,14.2", "Oct,18.3,14.1,9,10.3", "Nov,13.9,8.6,3.9,6.6", "Dec,9.6,2.5,1,4.8"] }), highed.samples.add({ id: "line-series-simple", title: "Basic Line Series", description: "", type: "csv", dataset: ["row,val", "0,24", "1,76", "2,23"] }), highed.samples.add({ id: "os-stats", title: "OS Usage Stats", description: "", type: "csv", dataset: ["Date,Windows,Android,iOS,OS X,Unknown,Linux,Nokia Unknown,Series 40,BlackBerry OS,Chrome OS,Samsung,SymbianOS,Playstation,Tizen,Xbox,LG,Sony Ericsson,MeeGo,bada,Other", "2016-02-01,48.15,27.51,11.04,5.2,3.61,1,0.97,0.98,0.39,0.3,0.29,0.29,0.09,0.03,0.03,0.03,0.03,0.02,0.02,0.02", "2016-03-01,47.32,29.34,11.02,5.08,2.95,0.95,0.94,0.93,0.38,0.29,0.29,0.28,0.08,0.03,0.02,0.03,0.03,0.02,0.02,0.02", "2016-04-01,46.44,29.9,11.12,5.09,3.12,0.99,0.96,0.89,0.4,0.3,0.28,0.26,0.08,0.03,0.03,0.03,0.02,0.02,0.01,0.02", "2016-05-01,44.29,31.6,11.38,5.05,3.35,0.91,0.99,0.89,0.41,0.3,0.3,0.26,0.1,0.04,0.03,0.03,0.03,0.02,0.01,0.02", "2016-06-01,45.55,30.15,11.83,5.29,3.39,0.96,0.79,0.72,0.35,0.22,0.29,0.2,0.1,0.04,0.03,0.03,0.03,0.02,0.01,0.02", "2016-07-01,42.56,32.48,12.25,4.81,4,0.96,0.87,0.77,0.34,0.18,0.3,0.22,0.09,0.04,0.03,0.03,0.03,0.02,0.01,0.02", "2016-08-01,42.49,32.07,12.16,4.96,4.53,0.98,0.85,0.71,0.29,0.21,0.28,0.21,0.09,0.04,0.03,0.03,0.03,0.02,0.01,0.02", "2016-09-01,41.61,32.84,11.87,5.07,4.84,0.94,0.84,0.65,0.27,0.33,0.28,0.19,0.1,0.05,0.03,0.02,0.03,0.02,0.01,0.02", "2016-10-01,40.06,34.46,12.04,5.3,4.57,0.85,0.87,0.55,0.27,0.34,0.26,0.17,0.08,0.07,0.03,0.02,0.03,0.01,0.01,0.02", "2016-11-01,39.65,36.28,12.28,5.22,3.15,0.86,0.79,0.49,0.26,0.35,0.24,0.15,0.08,0.08,0.03,0.02,0.03,0.01,0.01,0.02", "2016-12-01,38.35,37.8,12.71,4.92,2.85,0.86,0.77,0.49,0.22,0.33,0.25,0.15,0.09,0.1,0.03,0.02,0.02,0.01,0.01,0.02", "2017-01-01,38.75,37.15,13.16,5.06,2.63,0.78,0.75,0.46,0.21,0.35,0.24,0.14,0.09,0.11,0.03,0.02,0.02,0.01,0.01,0.02", "2017-02-01,38.59,37.42,12.99,5.24,2.56,0.77,0.74,0.42,0.23,0.38,0.22,0.13,0.1,0.12,0.03,0.02,0.01,0.01,0.01,0.01"] }), highed.samples.add({ id: "pie-pacman", title: "Pacman Pie", description: "", type: "csv", dataset: ["slice,val", "Not Pacman,24", "Pacman,76"] }), highed.samples.add({ id: "pie-series-simple", title: "Basic Pie Series", description: "", type: "csv", dataset: ["slice,val", "Cats,20", "Dogs,75", "Birds,5"] }) highed.templates.addCategory("Area", {}), highed.templates.addCategory("Bar", {}), highed.templates.addCategory("Line", { description: ['A line chart is a type of chart which diplays information as a series of data points called "markers" connected by straight line segments'], samples: ["os-stats", "line-series-simple", "line-series-four-series"] }), highed.templates.addCategory("Pie", { description: ["A pie chart is a circular statistical graphic which is divided into slices to illustrate numerical proportions.", "In a pie chart, the arc length of each slice is proportional to the quantity it represents."], samples: ["pie-series-simple"] }), highed.templates.addCategory("Bar", { description: ["A bar chart is a chart that presents grouped data with rectangular bars with lengths proportional to the values that they represent."], nofits: "The dataset must contain at least one column.", samples: [] }), highed.templates.addCategory("Column", { description: [], samples: [] }), highed.templates.addCategory("Stock", {}), highed.templates.addCategory("Scatter And Bubble", {}), highed.templates.addCategory("Polar", {}), highed.templates.addCategory("More", {}), highed.templates.add("Area", { title: "Basic Area", description: "", thumbnail: "ecexev.svg", dataValidator: !1, sampleSets: [], popular: !0, config: { chart: { type: "area", polar: !1 } } }), highed.templates.add("Area", { title: "Arearange", description: "", thumbnail: "udepat.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "arearange", polar: !1 } } }), highed.templates.add("Area", { title: "Area with labels", description: "", thumbnail: "atikon.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "area", polar: !1 }, plotOptions: { series: { dataLabels: { enabled: !0 } } } } }), highed.templates.add("Area", { title: "Inverted", description: "", thumbnail: "yqenid.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "area", inverted: !0, polar: !1 } } }), highed.templates.add("Area", { title: "Inverted with labels", description: "", thumbnail: "acemyq.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "area", inverted: !0, polar: !1 }, plotOptions: { series: { dataLabels: { enabled: !0 } } } } }), highed.templates.add("Area", { title: "Negative color", description: "", thumbnail: "ydypal.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "area", polar: !1 }, "series[0]": { negativeColor: "#0088FF", color: "#FF0000" } } }), highed.templates.add("Area", { title: "Stacked percentage", description: "", thumbnail: "iporos.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "area", polar: !1 }, plotOptions: { series: { stacking: "percent" } } } }), highed.templates.add("Area", { title: "Stacked", description: "", thumbnail: "inebav.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "area", polar: !1 }, plotOptions: { series: { stacking: "normal" } } } }), highed.templates.add("Area", { title: "Stacked with labels", description: "", thumbnail: "iluryh.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "area", polar: !1 }, plotOptions: { series: { stacking: "normal", dataLabels: { enabled: !0 } } } } }), highed.templates.add("Area", { title: "Step line", description: "", thumbnail: "abutix.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "area", polar: !1 }, plotOptions: { area: { step: "left" } } } }) highed.templates.add("Bar", { title: "Basic bar", description: "", thumbnail: "ovuvul.svg", dataValidator: !1, popular: !0, sampleSets: [], config: { chart: { type: "column", inverted: !0, polar: !1 } } }), highed.templates.add("Bar", { title: "Horizontal columnrange", description: "", thumbnail: "iqagel.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "columnrange", inverted: !0, polar: !1 } } }), highed.templates.add("Bar", { title: "Columnrange with labels", description: "", thumbnail: "eracar.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "columnrange", inverted: !0, polar: !1 }, plotOptions: { series: { dataLabels: { enabled: !0 } } } } }), highed.templates.add("Bar", { title: "Stacked bar", description: "", thumbnail: "epodat.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", inverted: !0, polar: !1 }, plotOptions: { series: { stacking: "normal" } } } }), highed.templates.add("Bar", { title: "Stacked with labels", description: "", thumbnail: "otupaz.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", inverted: !0, polar: !1 }, plotOptions: { series: { stacking: "normal", dataLabels: { enabled: !0 } } } } }), highed.templates.add("Bar", { title: "Stacked percent bar", description: "", thumbnail: "yhekaq.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", inverted: !0, polar: !1 }, plotOptions: { series: { stacking: "percent" } } } }), highed.templates.add("Bar", { title: "Stacked percentage with labels", description: "", thumbnail: "izoqyx.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", inverted: !0, polar: !1 }, plotOptions: { series: { stacking: "percent", dataLabels: { enabled: !0 } } } } }), highed.templates.add("Bar", { title: "Basic with labels", description: "", thumbnail: "ovuvul.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", inverted: !0, polar: !1 }, plotOptions: { series: { dataLabels: { enabled: !0 } } } } }), highed.templates.add("Bar", { title: "Error bar", description: "", thumbnail: "omikax.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", inverted: !0, polar: !1 }, "series[1]": { type: "errorbar" } } }), highed.templates.add("Bar", { title: "Logarithmic", description: "", thumbnail: "imykus.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", inverted: !0, polar: !1 }, yAxis: { type: "logarithmic", minorTickInterval: "auto" } } }), highed.templates.add("Bar", { title: "Multi color", description: "", thumbnail: "ogixak.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", inverted: !0, polar: !1 }, plotOptions: { series: { colorByPoint: !0 } } } }), highed.templates.add("Bar", { title: "Negative color", description: "", thumbnail: "efygam.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", inverted: !0, polar: !1 }, "series[0]": { negativeColor: "#0088FF", color: "#FF0000" } } }), highed.templates.add("Bar", { title: "Packed columns", description: "", thumbnail: "orixis.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", inverted: !0, polar: !1 }, plotOptions: { series: { pointPadding: 0, groupPadding: 0, borderWidth: 0, shadow: !1 } } } }), highed.templates.add("Column", { title: "Basic Column", description: "", thumbnail: "ovobiq.svg", dataValidator: !1, popular: !0, sampleSets: [], config: { chart: { type: "column", polar: !1 } } }) highed.templates.add("Column", { title: "Column 3D", description: "", thumbnail: "ahyqyx.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", margin: 75, options3d: { enabled: !0, alpha: 15, beta: 15, depth: 50, viewDistance: 15 }, polar: !1 }, plotOptions: { column: { depth: 25 } } } }), highed.templates.add("Column", { title: "Stacked 3D", description: "", thumbnail: "ahyqyx.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", margin: 75, options3d: { enabled: !0, alpha: 15, beta: 15, depth: 50, viewDistance: 15 }, polar: !1 }, plotOptions: { column: { depth: 25 }, series: { stacking: "normal" } } } }), highed.templates.add("Column", { title: "Stacked percent", description: "", thumbnail: "ojixow.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column" }, plotOptions: { series: { stacking: "percent" } } } }), highed.templates.add("Column", { title: "Stacked percent with labels", description: "", thumbnail: "iwanyg.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", polar: !1 }, plotOptions: { series: { stacking: "percent", dataLabels: { enabled: !0 } } } } }), highed.templates.add("Column", { title: "Columnrange", description: "", thumbnail: "ihilaq.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "columnrange", polar: !1 } } }), highed.templates.add("Column", { title: "Columnrange with labels", description: "", thumbnail: "ojykiw.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "columnrange", polar: !1 }, plotOptions: { series: { dataLabels: { enabled: !0 } } } } }), highed.templates.add("Column", { title: "Stacked", description: "", thumbnail: "ycehiz.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", polar: !1 }, plotOptions: { series: { stacking: "normal" } } } }), highed.templates.add("Column", { title: "Stacked with labels", description: "", thumbnail: "acijil.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", polar: !1 }, plotOptions: { series: { stacking: "normal", dataLabels: { enabled: !0 } } } } }), highed.templates.add("Column", { title: "Error bar", description: "", thumbnail: "icytes.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", polar: !1 }, "series[1]": { type: "errorbar" } } }), highed.templates.add("Column", { title: "With label", description: "", thumbnail: "ivetir.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", polar: !1 }, plotOptions: { series: { dataLabels: { enabled: !0 } } } } }), highed.templates.add("Column", { title: "Logarithmic", description: "", thumbnail: "igipeg.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", polar: !1 }, yAxis: { type: "logarithmic", minorTickInterval: "auto" } } }), highed.templates.add("Column", { title: "Multi color", description: "", thumbnail: "alyqyz.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", polar: !1 }, plotOptions: { series: { colorByPoint: !0 } } } }), highed.templates.add("Column", { title: "Negative color", description: "", thumbnail: "yxajih.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", polar: !1 }, "series[0]": { negativeColor: "#0088FF", color: "#FF0000" } } }), highed.templates.add("Column", { title: "Packed columns", description: "", thumbnail: "exypor.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "column", polar: !1 }, plotOptions: { series: { pointPadding: 0, groupPadding: 0, borderWidth: 0, shadow: !1 } } } }), highed.templates.add("Line", { title: "Line chart", description: "", thumbnail: "abywon.svg", popular: !0, dataValidator: !1, sampleSets: [], config: { chart: { type: "line" } } }) highed.templates.add("Line", { title: "Error bar", description: "", thumbnail: "ypewak.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "line", polar: !1 }, "series[0]": { type: "line" }, "series[1]": { type: "errorbar" } } }), highed.templates.add("Line", { title: "Inverted", description: "", thumbnail: "ozojul.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "line", inverted: !0, polar: !1 } } }), highed.templates.add("Line", { title: "Line", description: ["Basic line series. Good starting point for custom line series.", "Requires one column for X values or categories, subsequently one column for each series' Y values."], constructor: "Chart", thumbnail: "abywon.svg", sampleSets: [], validator: "line", config: { chart: { type: "line" } } }), highed.templates.add("Line", { title: "Logarithmic", description: "", thumbnail: "abywon.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "line", polar: !1 }, yAxis: { type: "logarithmic", minorTickInterval: "auto" } } }), highed.templates.add("Line", { title: "Negative color", description: "", thumbnail: "uxyfys.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "line", polar: !1 }, "series[0]": { negativeColor: "#0088FF", color: "#FF0000" } } }), highed.templates.add("Line", { title: "Spline", description: "", thumbnail: "upafes.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "spline", polar: !1 } } }), highed.templates.add("Line", { title: "Spline with labels", description: "", thumbnail: "odopic.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "spline", polar: !1 }, plotOptions: { series: { dataLabels: { enabled: !0 } } } } }), highed.templates.add("Line", { title: "Step line", description: "", thumbnail: "akeduw.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "line", polar: !1 }, plotOptions: { line: { step: "left" } } } }), highed.templates.add("Line", { title: "Step line with labels", description: "", thumbnail: "oxenux.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "line", polar: !1 }, plotOptions: { series: { dataLabels: { enabled: !0 } }, line: { step: "left" } } } }), highed.templates.add("Line", { title: "With data labels", description: "", thumbnail: "agonam.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "line", polar: !1 }, plotOptions: { series: { dataLabels: { enabled: !0 } } } } }), highed.templates.add("More", { title: "Boxplot", description: "", thumbnail: "idagib.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "boxplot" } } }), highed.templates.add("More", { title: "Funnel", description: "", thumbnail: "exumeq.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "funnel" }, plotOptions: { series: { datalabels: { color: "#000000" }, dataLabels: { softConnector: !0 }, neckWidth: "20%", neckHeight: "35%" } }, "series[0]": { width: "64%" } } }), highed.templates.add("More", { title: "Pyramid", description: "", thumbnail: "obulek.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "pyramid" }, plotOptions: { series: { datalabels: { color: "#000000" }, dataLabels: { softConnector: !0 } } }, "series[0]": { width: "64%" } } }), highed.templates.add("More", { title: "Solid gauge", description: "", thumbnail: "apocob.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "solidgauge" }, pane: { center: ["50%", "85%"], size: "140%", startAngle: "-90", endAngle: "90", background: { backgroundColor: "#EEE", innerRadius: "60%", outerRadius: "100%", shape: "arc" } }, tooltip: { enabled: !1 }, yAxis: { stops: [[.1, "#55BF3B"], [.5, "#DDDF0D"], [.9, "#DF5353"]], min: 0, max: 100, lineWidth: 0, minorTickInterval: null, tickPixelInterval: 400, tickWidth: 0, title: { y: -70 }, labels: { y: 16 } }, plotOptions: { solidgauge: { dataLabels: { y: 10, borderWidth: 0, useHTML: !0 } } }, "series[0]": { dataLabels: { format: '
    {y}
    ' } } } }) highed.templates.add("Pie", { title: "Pie", description: ["Good starting point for custom pie series."], constructor: "Chart", popular: !0, thumbnail: "yqoxob.svg", sampleSets: [], validator: "pie", config: { chart: { type: "pie" } } }), highed.templates.add("Pie", { title: "Pie chart with labels", description: "", thumbnail: "yqoxob.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "pie", polar: !1 }, plotOptions: { pie: { allowPointSelect: !0, cursor: !0 }, series: { dataLabels: { enabled: !0 } } } } }), highed.templates.add("Pie", { title: "Pie with legend", description: "", thumbnail: "anofof.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "pie", polar: !1 }, plotOptions: { pie: { allowPointSelect: !0, cursor: !0, showInLegend: !0, dataLabels: { enabled: !1 } } } } }), highed.templates.add("Pie", { title: "3D Pie with legend", description: "", thumbnail: "ubopaq.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "pie", options3d: { enabled: !0, alpha: 45, beta: 0 }, polar: !1 }, plotOptions: { pie: { allowPointSelect: !0, depth: 35, cursor: "pointer", showInLegend: !0, dataLabels: { enabled: !1 } } } } }), highed.templates.add("Pie", { title: "3D Pie chart", description: "", thumbnail: "erifer.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "pie", options3d: { enabled: !0, alpha: 45, beta: 0 }, polar: !1 }, plotOptions: { pie: { allowPointSelect: !0, depth: 35, cursor: "pointer" }, series: { dataLabels: { enabled: !0 } } } } }), highed.templates.add("Pie", { title: "Donut", description: "", thumbnail: "upaxab.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "pie", polar: !1 }, plotOptions: { pie: { allowPointSelect: !0, cursor: !0, innerSize: "60%", dataLabels: { enabled: !0 } } } } }), highed.templates.add("Pie", { title: "3D Donut chart", description: "", thumbnail: "ehuvoh.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "pie", options3d: { enabled: !0, alpha: 45, beta: 0 }, polar: !1 }, plotOptions: { pie: { allowPointSelect: !0, depth: 35, cursor: "pointer", innerSize: "60%" }, series: { dataLabels: { enabled: !0 } } } } }), highed.templates.add("Pie", { title: "3D Donut chart with legend", description: "", thumbnail: "oriwyb.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "pie", options3d: { enabled: !0, alpha: 45, beta: 0 }, polar: !1 }, plotOptions: { pie: { allowPointSelect: !0, depth: 35, cursor: "pointer", showInLegend: !0, innerSize: "60%" }, series: { dataLabels: { enabled: !1 } } } } }), highed.templates.add("Pie", { title: "Donut with legend", description: "", thumbnail: "arutag.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "pie", polar: !1 }, plotOptions: { pie: { allowPointSelect: !0, cursor: !0, showInLegend: !0, innerSize: "60%", dataLabels: { enabled: !1 } } } } }), highed.templates.add("Pie", { title: "Semi circle donut", description: "", thumbnail: "iwyfes.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "pie", polar: !1 }, plotOptions: { pie: { allowPointSelect: !1, dataLabels: { distance: -30, style: { fontWeight: "bold", color: "white", textShadow: "0px 1px 2px black" } }, innerSize: "50%", startAngle: -90, endAngle: 90, center: ["50%", "75%"] }, series: { dataLabels: { enabled: !0 } } } } }), highed.templates.add("Polar", { title: "Polar area", description: "", thumbnail: "oqajux.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "area", polar: !0 } } }), highed.templates.add("Polar", { title: "Polar line", description: "", thumbnail: "ajogud.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "line", polar: !0 } } }), highed.templates.add("Polar", { title: "Spider area", description: "", thumbnail: "exajib.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "area", polar: !0 }, xAxis: { tickmarkPlacement: "on", lineWidth: 0 }, yAxis: { lineWidth: 0, gridLineInterpolation: "polygon" } } }) highed.templates.add("Polar", { title: "Spider line", description: "", thumbnail: "uqonaj.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "line", polar: !0 }, xAxis: { tickmarkPlacement: "on", lineWidth: 0 }, yAxis: { lineWidth: 0, gridLineInterpolation: "polygon" } } }), highed.templates.add("Scatter And Bubble", { title: "Scatter with line", description: "", thumbnail: "ydaqok.svg", dataValidator: !1, popular: !0, sampleSets: [], config: { chart: { type: "scatter", polar: !1 }, plotOptions: { series: { lineWidth: 1 } } } }), highed.templates.add("Scatter And Bubble", { title: "Bubble chart", description: "", thumbnail: "usyfyw.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "bubble", polar: !1 } } }), highed.templates.add("Scatter And Bubble", { title: "Scatter chart", description: "", thumbnail: "ezatat.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "scatter", polar: !1 } } }), highed.templates.add("Scatter And Bubble", { title: "Scatter with line, no marker", description: "", thumbnail: "uvepiw.svg", dataValidator: !1, sampleSets: [], config: { chart: { type: "scatter", polar: !1 }, plotOptions: { series: { lineWidth: 1, marker: { enabled: !1 } } } } }); /* Highcharts Editor v0.3.0 Copyright (c) 2016-2017, Highsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ highed.templates.addCategory("Stock",{description:["Stock charts are used to display financial data."],samples:[]}),highed.templates.add("Stock",{title:"Area",description:"",constructor:"StockChart",thumbnail:"ukaqor.svg",dataValidator:!1,sampleSets:["line-series-dates"],config:{chart:{type:"area",polar:!1},rangeSelector:{enabled:!1}}}),highed.templates.add("Stock",{title:"Basic",description:"",constructor:"StockChart",thumbnail:"awuhad.svg",dataValidator:!1,sampleSets:["line-series-dates"],config:{chart:{type:"line",polar:!1},rangeSelector:{enabled:!1}}}),highed.templates.add("Stock",{title:"Candlestick",description:"",constructor:"StockChart",thumbnail:"etybef.svg",dataValidator:!1,sampleSets:["candlestick"],config:{chart:{type:"candlestick",polar:!1},rangeSelector:{enabled:!1}}}),highed.templates.add("Stock",{title:"Column",description:"",constructor:"StockChart",thumbnail:"ogywen.svg",dataValidator:!1,sampleSets:["line-series-dates"],config:{chart:{type:"column",polar:!1},rangeSelector:{enabled:!1}}}),highed.templates.add("Stock",{title:"OHLC",description:"",constructor:"StockChart",thumbnail:"opilip.svg",dataValidator:!1,sampleSets:["candlestick"],config:{chart:{type:"ohlc",polar:!1},rangeSelector:{enabled:!1}}}); tinymce.PluginManager.add('highcharts', function (editor, url) { var modal = highed.ModalEditor(false, { features: 'data templates customize', language: 'zh_cn', allowDone: true }, function (chart) { var html = chart.export.html(true); editor.insertContent('
    ' + html + '

    '); }); if (tinymce.majorVersion > 4) { editor.ui.registry.addMenuItem('highcharts', { text: 'Highcharts (Interactive)', onAction: function (e) { tinymce.activeEditor.schema.addValidElements("script[type|src],div[id|style]a[*],altGlyph[*],altGlyphDef[*],altGlyphItem[*],animate[*],animateColor[*],animateMotion[*],animateTransform[*],circle[*],clipPath[*],color-profile[*],cursor[*],defs[*],desc[*],ellipse[*],feBlend[*],feColorMatrix[*],feComponentTransfer[*],feComposite[*],feConvolveMatrix[*],feDiffuseLighting[*],feDisplacementMap[*],feDistantLight[*],feFlood[*],feFuncA[*],feFuncB[*],feFuncG[*],feFuncR[*],feGaussianBlur[*],feImage[*],feMerge[*],feMergeNode[*],feMorphology[*],feOffset[*],fePointLight[*],feSpecularLighting[*],feSpotLight[*],feTile[*],feTurbulence[*],filter[*],font[*],font-face[*],font-face-format[*],font-face-name[*],font-face-src[*],font-face-uri[*],foreignObject[*],g[*],glyph[*],glyphRef[*],hkern[*],image[*],line[*],linearGradient[*],marker[*],mask[*],metadata[*],missing-glyph[*],mpath[*],path[*],pattern[*],polygon[*],polyline[*],radialGradient[*],rect[*],script[*],set[*],stop[*],style[*],svg[*],switch[*],symbol[*],text[*],textPath[*],title[*],tref[*],tspan[*],use[*],view[*],vkern[*]"); modal.attachToSummoner(this._id); modal.show(); modal.resize(); } }); } else { editor.addMenuItem('highcharts', { text: 'Highcharts (Interactive)', context: 'insert', icon: false, onclick: function (e) { tinymce.activeEditor.schema.addValidElements("script[type|src],div[id|style]a[*],altGlyph[*],altGlyphDef[*],altGlyphItem[*],animate[*],animateColor[*],animateMotion[*],animateTransform[*],circle[*],clipPath[*],color-profile[*],cursor[*],defs[*],desc[*],ellipse[*],feBlend[*],feColorMatrix[*],feComponentTransfer[*],feComposite[*],feConvolveMatrix[*],feDiffuseLighting[*],feDisplacementMap[*],feDistantLight[*],feFlood[*],feFuncA[*],feFuncB[*],feFuncG[*],feFuncR[*],feGaussianBlur[*],feImage[*],feMerge[*],feMergeNode[*],feMorphology[*],feOffset[*],fePointLight[*],feSpecularLighting[*],feSpotLight[*],feTile[*],feTurbulence[*],filter[*],font[*],font-face[*],font-face-format[*],font-face-name[*],font-face-src[*],font-face-uri[*],foreignObject[*],g[*],glyph[*],glyphRef[*],hkern[*],image[*],line[*],linearGradient[*],marker[*],mask[*],metadata[*],missing-glyph[*],mpath[*],path[*],pattern[*],polygon[*],polyline[*],radialGradient[*],rect[*],script[*],set[*],stop[*],style[*],svg[*],switch[*],symbol[*],text[*],textPath[*],title[*],tref[*],tspan[*],use[*],view[*],vkern[*]"); modal.attachToSummoner(this._id); modal.show(); modal.resize(); } }); } });