| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670 |
- /**
- * @license Highcharts Gantt JS v8.1.2 (2020-06-16)
- *
- * Tree Grid
- *
- * (c) 2016-2019 Jon Arild Nygard
- *
- * License: www.highcharts.com/license
- */
- 'use strict';
- (function (factory) {
- if (typeof module === 'object' && module.exports) {
- factory['default'] = factory;
- module.exports = factory;
- } else if (typeof define === 'function' && define.amd) {
- define('highcharts/modules/treegrid', ['highcharts'], function (Highcharts) {
- factory(Highcharts);
- factory.Highcharts = Highcharts;
- return factory;
- });
- } else {
- factory(typeof Highcharts !== 'undefined' ? Highcharts : undefined);
- }
- }(function (Highcharts) {
- var _modules = Highcharts ? Highcharts._modules : {};
- function _registerModule(obj, path, args, fn) {
- if (!obj.hasOwnProperty(path)) {
- obj[path] = fn.apply(null, args);
- }
- }
- _registerModule(_modules, 'parts-gantt/Tree.js', [_modules['parts/Utilities.js']], function (U) {
- /* *
- *
- * (c) 2016-2020 Highsoft AS
- *
- * Authors: Jon Arild Nygard
- *
- * License: www.highcharts.com/license
- *
- * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
- *
- * */
- /* eslint no-console: 0 */
- var extend = U.extend, isNumber = U.isNumber, pick = U.pick;
- /**
- * Creates an object map from parent id to childrens index.
- *
- * @private
- * @function Highcharts.Tree#getListOfParents
- *
- * @param {Array<*>} data
- * List of points set in options. `Array.parent` is parent id of point.
- *
- * @param {Array<string>} ids
- * List of all point ids.
- *
- * @return {Highcharts.Dictionary<Array<*>>}
- * Map from parent id to children index in data
- */
- var getListOfParents = function (data, ids) {
- var listOfParents = data.reduce(function (prev, curr) {
- var parent = pick(curr.parent, '');
- if (typeof prev[parent] === 'undefined') {
- prev[parent] = [];
- }
- prev[parent].push(curr);
- return prev;
- }, {}), parents = Object.keys(listOfParents);
- // If parent does not exist, hoist parent to root of tree.
- parents.forEach(function (parent, list) {
- var children = listOfParents[parent];
- if ((parent !== '') && (ids.indexOf(parent) === -1)) {
- children.forEach(function (child) {
- list[''].push(child);
- });
- delete list[parent];
- }
- });
- return listOfParents;
- };
- var getNode = function (id, parent, level, data, mapOfIdToChildren, options) {
- var descendants = 0, height = 0, after = options && options.after, before = options && options.before, node = {
- data: data,
- depth: level - 1,
- id: id,
- level: level,
- parent: parent
- }, start, end, children;
- // Allow custom logic before the children has been created.
- if (typeof before === 'function') {
- before(node, options);
- }
- // Call getNode recursively on the children. Calulate the height of the
- // node, and the number of descendants.
- children = ((mapOfIdToChildren[id] || [])).map(function (child) {
- var node = getNode(child.id, id, (level + 1), child, mapOfIdToChildren, options), childStart = child.start, childEnd = (child.milestone === true ?
- childStart :
- child.end);
- // Start should be the lowest child.start.
- start = ((!isNumber(start) || childStart < start) ?
- childStart :
- start);
- // End should be the largest child.end.
- // If child is milestone, then use start as end.
- end = ((!isNumber(end) || childEnd > end) ?
- childEnd :
- end);
- descendants = descendants + 1 + node.descendants;
- height = Math.max(node.height + 1, height);
- return node;
- });
- // Calculate start and end for point if it is not already explicitly set.
- if (data) {
- data.start = pick(data.start, start);
- data.end = pick(data.end, end);
- }
- extend(node, {
- children: children,
- descendants: descendants,
- height: height
- });
- // Allow custom logic after the children has been created.
- if (typeof after === 'function') {
- after(node, options);
- }
- return node;
- };
- var getTree = function (data, options) {
- var ids = data.map(function (d) {
- return d.id;
- }), mapOfIdToChildren = getListOfParents(data, ids);
- return getNode('', null, 1, null, mapOfIdToChildren, options);
- };
- var Tree = {
- getListOfParents: getListOfParents,
- getNode: getNode,
- getTree: getTree
- };
- return Tree;
- });
- _registerModule(_modules, 'parts-gantt/TreeGridTick.js', [_modules['parts/Utilities.js']], function (U) {
- /* *
- *
- * (c) 2016 Highsoft AS
- * Authors: Jon Arild Nygard
- *
- * License: www.highcharts.com/license
- *
- * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
- *
- * */
- var addEvent = U.addEvent, defined = U.defined, isObject = U.isObject, isNumber = U.isNumber, pick = U.pick, wrap = U.wrap;
- /**
- * @private
- */
- var TreeGridTick;
- (function (TreeGridTick) {
- /* *
- *
- * Interfaces
- *
- * */
- /* *
- *
- * Variables
- *
- * */
- var applied = false;
- /* *
- *
- * Functions
- *
- * */
- /**
- * @private
- */
- function compose(TickClass) {
- if (!applied) {
- addEvent(TickClass, 'init', onInit);
- wrap(TickClass.prototype, 'getLabelPosition', wrapGetLabelPosition);
- wrap(TickClass.prototype, 'renderLabel', wrapRenderLabel);
- // backwards compatibility
- TickClass.prototype.collapse = function (redraw) {
- this.treeGrid.collapse(redraw);
- };
- TickClass.prototype.expand = function (redraw) {
- this.treeGrid.expand(redraw);
- };
- TickClass.prototype.toggleCollapse = function (redraw) {
- this.treeGrid.toggleCollapse(redraw);
- };
- applied = true;
- }
- }
- TreeGridTick.compose = compose;
- /**
- * @private
- */
- function onInit() {
- var tick = this;
- if (!tick.treeGrid) {
- tick.treeGrid = new Additions(tick);
- }
- }
- /**
- * @private
- */
- function onTickHover(label) {
- label.addClass('highcharts-treegrid-node-active');
- if (!label.renderer.styledMode) {
- label.css({
- textDecoration: 'underline'
- });
- }
- }
- /**
- * @private
- */
- function onTickHoverExit(label, options) {
- var css = defined(options.style) ? options.style : {};
- label.removeClass('highcharts-treegrid-node-active');
- if (!label.renderer.styledMode) {
- label.css({ textDecoration: css.textDecoration });
- }
- }
- /**
- * @private
- */
- function renderLabelIcon(tick, params) {
- var treeGrid = tick.treeGrid, isNew = !treeGrid.labelIcon, renderer = params.renderer, labelBox = params.xy, options = params.options, width = options.width, height = options.height, iconCenter = {
- x: labelBox.x - (width / 2) - options.padding,
- y: labelBox.y - (height / 2)
- }, rotation = params.collapsed ? 90 : 180, shouldRender = params.show && isNumber(iconCenter.y);
- var icon = treeGrid.labelIcon;
- if (!icon) {
- treeGrid.labelIcon = icon = renderer
- .path(renderer.symbols[options.type](options.x, options.y, width, height))
- .addClass('highcharts-label-icon')
- .add(params.group);
- }
- // Set the new position, and show or hide
- if (!shouldRender) {
- icon.attr({ y: -9999 }); // #1338
- }
- // Presentational attributes
- if (!renderer.styledMode) {
- icon
- .attr({
- 'stroke-width': 1,
- 'fill': pick(params.color, '#666666')
- })
- .css({
- cursor: 'pointer',
- stroke: options.lineColor,
- strokeWidth: options.lineWidth
- });
- }
- // Update the icon positions
- icon[isNew ? 'attr' : 'animate']({
- translateX: iconCenter.x,
- translateY: iconCenter.y,
- rotation: rotation
- });
- }
- /**
- * @private
- */
- function wrapGetLabelPosition(proceed, x, y, label, horiz, labelOptions, tickmarkOffset, index, step) {
- var tick = this, lbOptions = pick(tick.options && tick.options.labels, labelOptions), pos = tick.pos, axis = tick.axis, options = axis.options, isTreeGrid = options.type === 'treegrid', result = proceed.apply(tick, [x, y, label, horiz, lbOptions, tickmarkOffset, index, step]);
- var symbolOptions, indentation, mapOfPosToGridNode, node, level;
- if (isTreeGrid) {
- symbolOptions = (lbOptions && isObject(lbOptions.symbol, true) ?
- lbOptions.symbol :
- {});
- indentation = (lbOptions && isNumber(lbOptions.indentation) ?
- lbOptions.indentation :
- 0);
- mapOfPosToGridNode = axis.treeGrid.mapOfPosToGridNode;
- node = mapOfPosToGridNode && mapOfPosToGridNode[pos];
- level = (node && node.depth) || 1;
- result.x += (
- // Add space for symbols
- ((symbolOptions.width) + (symbolOptions.padding * 2)) +
- // Apply indentation
- ((level - 1) * indentation));
- }
- return result;
- }
- /**
- * @private
- */
- function wrapRenderLabel(proceed) {
- var tick = this, pos = tick.pos, axis = tick.axis, label = tick.label, mapOfPosToGridNode = axis.treeGrid.mapOfPosToGridNode, options = axis.options, labelOptions = pick(tick.options && tick.options.labels, options && options.labels), symbolOptions = (labelOptions && isObject(labelOptions.symbol, true) ?
- labelOptions.symbol :
- {}), node = mapOfPosToGridNode && mapOfPosToGridNode[pos], level = node && node.depth, isTreeGrid = options.type === 'treegrid', shouldRender = axis.tickPositions.indexOf(pos) > -1, prefixClassName = 'highcharts-treegrid-node-', styledMode = axis.chart.styledMode;
- var collapsed, addClassName, removeClassName;
- if (isTreeGrid && node) {
- // Add class name for hierarchical styling.
- if (label &&
- label.element) {
- label.addClass(prefixClassName + 'level-' + level);
- }
- }
- proceed.apply(tick, Array.prototype.slice.call(arguments, 1));
- if (isTreeGrid &&
- label &&
- label.element &&
- node &&
- node.descendants &&
- node.descendants > 0) {
- collapsed = axis.treeGrid.isCollapsed(node);
- renderLabelIcon(tick, {
- color: !styledMode && label.styles && label.styles.color || '',
- collapsed: collapsed,
- group: label.parentGroup,
- options: symbolOptions,
- renderer: label.renderer,
- show: shouldRender,
- xy: label.xy
- });
- // Add class name for the node.
- addClassName = prefixClassName +
- (collapsed ? 'collapsed' : 'expanded');
- removeClassName = prefixClassName +
- (collapsed ? 'expanded' : 'collapsed');
- label
- .addClass(addClassName)
- .removeClass(removeClassName);
- if (!styledMode) {
- label.css({
- cursor: 'pointer'
- });
- }
- // Add events to both label text and icon
- [label, tick.treeGrid.labelIcon].forEach(function (object) {
- if (object && !object.attachedTreeGridEvents) {
- // On hover
- addEvent(object.element, 'mouseover', function () {
- onTickHover(label);
- });
- // On hover out
- addEvent(object.element, 'mouseout', function () {
- onTickHoverExit(label, labelOptions);
- });
- addEvent(object.element, 'click', function () {
- tick.treeGrid.toggleCollapse();
- });
- object.attachedTreeGridEvents = true;
- }
- });
- }
- }
- /* *
- *
- * Classes
- *
- * */
- /**
- * @private
- * @class
- */
- var Additions = /** @class */ (function () {
- /* *
- *
- * Constructors
- *
- * */
- /**
- * @private
- */
- function Additions(tick) {
- this.tick = tick;
- }
- /* *
- *
- * Functions
- *
- * */
- /**
- * Collapse the grid cell. Used when axis is of type treegrid.
- *
- * @see gantt/treegrid-axis/collapsed-dynamically/demo.js
- *
- * @private
- * @function Highcharts.Tick#collapse
- *
- * @param {boolean} [redraw=true]
- * Whether to redraw the chart or wait for an explicit call to
- * {@link Highcharts.Chart#redraw}
- */
- Additions.prototype.collapse = function (redraw) {
- var tick = this.tick, axis = tick.axis, brokenAxis = axis.brokenAxis;
- if (brokenAxis &&
- axis.treeGrid.mapOfPosToGridNode) {
- var pos = tick.pos, node = axis.treeGrid.mapOfPosToGridNode[pos], breaks = axis.treeGrid.collapse(node);
- brokenAxis.setBreaks(breaks, pick(redraw, true));
- }
- };
- /**
- * Expand the grid cell. Used when axis is of type treegrid.
- *
- * @see gantt/treegrid-axis/collapsed-dynamically/demo.js
- *
- * @private
- * @function Highcharts.Tick#expand
- *
- * @param {boolean} [redraw=true]
- * Whether to redraw the chart or wait for an explicit call to
- * {@link Highcharts.Chart#redraw}
- */
- Additions.prototype.expand = function (redraw) {
- var tick = this.tick, axis = tick.axis, brokenAxis = axis.brokenAxis;
- if (brokenAxis &&
- axis.treeGrid.mapOfPosToGridNode) {
- var pos = tick.pos, node = axis.treeGrid.mapOfPosToGridNode[pos], breaks = axis.treeGrid.expand(node);
- brokenAxis.setBreaks(breaks, pick(redraw, true));
- }
- };
- /**
- * Toggle the collapse/expand state of the grid cell. Used when axis is
- * of type treegrid.
- *
- * @see gantt/treegrid-axis/collapsed-dynamically/demo.js
- *
- * @private
- * @function Highcharts.Tick#toggleCollapse
- *
- * @param {boolean} [redraw=true]
- * Whether to redraw the chart or wait for an explicit call to
- * {@link Highcharts.Chart#redraw}
- */
- Additions.prototype.toggleCollapse = function (redraw) {
- var tick = this.tick, axis = tick.axis, brokenAxis = axis.brokenAxis;
- if (brokenAxis &&
- axis.treeGrid.mapOfPosToGridNode) {
- var pos = tick.pos, node = axis.treeGrid.mapOfPosToGridNode[pos], breaks = axis.treeGrid.toggleCollapse(node);
- brokenAxis.setBreaks(breaks, pick(redraw, true));
- }
- };
- return Additions;
- }());
- TreeGridTick.Additions = Additions;
- })(TreeGridTick || (TreeGridTick = {}));
- return TreeGridTick;
- });
- _registerModule(_modules, 'mixins/tree-series.js', [_modules['parts/Color.js'], _modules['parts/Utilities.js']], function (Color, U) {
- /* *
- *
- * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
- *
- * */
- var extend = U.extend, isArray = U.isArray, isNumber = U.isNumber, isObject = U.isObject, merge = U.merge, pick = U.pick;
- var isBoolean = function (x) {
- return typeof x === 'boolean';
- }, isFn = function (x) {
- return typeof x === 'function';
- };
- /* eslint-disable valid-jsdoc */
- /**
- * @todo Combine buildTree and buildNode with setTreeValues
- * @todo Remove logic from Treemap and make it utilize this mixin.
- * @private
- */
- var setTreeValues = function setTreeValues(tree, options) {
- var before = options.before, idRoot = options.idRoot, mapIdToNode = options.mapIdToNode, nodeRoot = mapIdToNode[idRoot], levelIsConstant = (isBoolean(options.levelIsConstant) ?
- options.levelIsConstant :
- true), points = options.points, point = points[tree.i], optionsPoint = point && point.options || {}, childrenTotal = 0, children = [], value;
- extend(tree, {
- levelDynamic: tree.level - (levelIsConstant ? 0 : nodeRoot.level),
- name: pick(point && point.name, ''),
- visible: (idRoot === tree.id ||
- (isBoolean(options.visible) ? options.visible : false))
- });
- if (isFn(before)) {
- tree = before(tree, options);
- }
- // First give the children some values
- tree.children.forEach(function (child, i) {
- var newOptions = extend({}, options);
- extend(newOptions, {
- index: i,
- siblings: tree.children.length,
- visible: tree.visible
- });
- child = setTreeValues(child, newOptions);
- children.push(child);
- if (child.visible) {
- childrenTotal += child.val;
- }
- });
- tree.visible = childrenTotal > 0 || tree.visible;
- // Set the values
- value = pick(optionsPoint.value, childrenTotal);
- extend(tree, {
- children: children,
- childrenTotal: childrenTotal,
- isLeaf: tree.visible && !childrenTotal,
- val: value
- });
- return tree;
- };
- /**
- * @private
- */
- var getColor = function getColor(node, options) {
- var index = options.index, mapOptionsToLevel = options.mapOptionsToLevel, parentColor = options.parentColor, parentColorIndex = options.parentColorIndex, series = options.series, colors = options.colors, siblings = options.siblings, points = series.points, getColorByPoint, chartOptionsChart = series.chart.options.chart, point, level, colorByPoint, colorIndexByPoint, color, colorIndex;
- /**
- * @private
- */
- function variation(color) {
- var colorVariation = level && level.colorVariation;
- if (colorVariation) {
- if (colorVariation.key === 'brightness') {
- return Color.parse(color).brighten(colorVariation.to * (index / siblings)).get();
- }
- }
- return color;
- }
- if (node) {
- point = points[node.i];
- level = mapOptionsToLevel[node.level] || {};
- getColorByPoint = point && level.colorByPoint;
- if (getColorByPoint) {
- colorIndexByPoint = point.index % (colors ?
- colors.length :
- chartOptionsChart.colorCount);
- colorByPoint = colors && colors[colorIndexByPoint];
- }
- // Select either point color, level color or inherited color.
- if (!series.chart.styledMode) {
- color = pick(point && point.options.color, level && level.color, colorByPoint, parentColor && variation(parentColor), series.color);
- }
- colorIndex = pick(point && point.options.colorIndex, level && level.colorIndex, colorIndexByPoint, parentColorIndex, options.colorIndex);
- }
- return {
- color: color,
- colorIndex: colorIndex
- };
- };
- /**
- * Creates a map from level number to its given options.
- *
- * @private
- * @function getLevelOptions
- * @param {object} params
- * Object containing parameters.
- * - `defaults` Object containing default options. The default options
- * are merged with the userOptions to get the final options for a
- * specific level.
- * - `from` The lowest level number.
- * - `levels` User options from series.levels.
- * - `to` The highest level number.
- * @return {Highcharts.Dictionary<object>|null}
- * Returns a map from level number to its given options.
- */
- var getLevelOptions = function getLevelOptions(params) {
- var result = null, defaults, converted, i, from, to, levels;
- if (isObject(params)) {
- result = {};
- from = isNumber(params.from) ? params.from : 1;
- levels = params.levels;
- converted = {};
- defaults = isObject(params.defaults) ? params.defaults : {};
- if (isArray(levels)) {
- converted = levels.reduce(function (obj, item) {
- var level, levelIsConstant, options;
- if (isObject(item) && isNumber(item.level)) {
- options = merge({}, item);
- levelIsConstant = (isBoolean(options.levelIsConstant) ?
- options.levelIsConstant :
- defaults.levelIsConstant);
- // Delete redundant properties.
- delete options.levelIsConstant;
- delete options.level;
- // Calculate which level these options apply to.
- level = item.level + (levelIsConstant ? 0 : from - 1);
- if (isObject(obj[level])) {
- extend(obj[level], options);
- }
- else {
- obj[level] = options;
- }
- }
- return obj;
- }, {});
- }
- to = isNumber(params.to) ? params.to : 1;
- for (i = 0; i <= to; i++) {
- result[i] = merge({}, defaults, isObject(converted[i]) ? converted[i] : {});
- }
- }
- return result;
- };
- /**
- * Update the rootId property on the series. Also makes sure that it is
- * accessible to exporting.
- *
- * @private
- * @function updateRootId
- *
- * @param {object} series
- * The series to operate on.
- *
- * @return {string}
- * Returns the resulting rootId after update.
- */
- var updateRootId = function (series) {
- var rootId, options;
- if (isObject(series)) {
- // Get the series options.
- options = isObject(series.options) ? series.options : {};
- // Calculate the rootId.
- rootId = pick(series.rootNode, options.rootId, '');
- // Set rootId on series.userOptions to pick it up in exporting.
- if (isObject(series.userOptions)) {
- series.userOptions.rootId = rootId;
- }
- // Set rootId on series to pick it up on next update.
- series.rootNode = rootId;
- }
- return rootId;
- };
- var result = {
- getColor: getColor,
- getLevelOptions: getLevelOptions,
- setTreeValues: setTreeValues,
- updateRootId: updateRootId
- };
- return result;
- });
- _registerModule(_modules, 'parts-gantt/GridAxis.js', [_modules['parts/Axis.js'], _modules['parts/Globals.js'], _modules['parts/Options.js'], _modules['parts/Tick.js'], _modules['parts/Utilities.js']], function (Axis, H, O, Tick, U) {
- /* *
- *
- * (c) 2016 Highsoft AS
- * Authors: Lars A. V. Cabrera
- *
- * License: www.highcharts.com/license
- *
- * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
- *
- * */
- var dateFormat = O.dateFormat;
- var addEvent = U.addEvent, defined = U.defined, erase = U.erase, find = U.find, isArray = U.isArray, isNumber = U.isNumber, merge = U.merge, pick = U.pick, timeUnits = U.timeUnits, wrap = U.wrap;
- var argsToArray = function (args) {
- return Array.prototype.slice.call(args, 1);
- }, isObject = function (x) {
- // Always use strict mode
- return U.isObject(x, true);
- }, Chart = H.Chart;
- var applyGridOptions = function applyGridOptions(axis) {
- var options = axis.options;
- // Center-align by default
- if (!options.labels) {
- options.labels = {};
- }
- options.labels.align = pick(options.labels.align, 'center');
- // @todo: Check against tickLabelPlacement between/on etc
- /* Prevents adding the last tick label if the axis is not a category
- axis.
- Since numeric labels are normally placed at starts and ends of a
- range of value, and this module makes the label point at the value,
- an "extra" label would appear. */
- if (!axis.categories) {
- options.showLastLabel = false;
- }
- // Prevents rotation of labels when squished, as rotating them would not
- // help.
- axis.labelRotation = 0;
- options.labels.rotation = 0;
- };
- /**
- * Set grid options for the axis labels. Requires Highcharts Gantt.
- *
- * @since 6.2.0
- * @product gantt
- * @apioption xAxis.grid
- */
- /**
- * Enable grid on the axis labels. Defaults to true for Gantt charts.
- *
- * @type {boolean}
- * @default true
- * @since 6.2.0
- * @product gantt
- * @apioption xAxis.grid.enabled
- */
- /**
- * Set specific options for each column (or row for horizontal axes) in the
- * grid. Each extra column/row is its own axis, and the axis options can be set
- * here.
- *
- * @sample gantt/demo/left-axis-table
- * Left axis as a table
- *
- * @type {Array<Highcharts.XAxisOptions>}
- * @apioption xAxis.grid.columns
- */
- /**
- * Set border color for the label grid lines.
- *
- * @type {Highcharts.ColorString}
- * @apioption xAxis.grid.borderColor
- */
- /**
- * Set border width of the label grid lines.
- *
- * @type {number}
- * @default 1
- * @apioption xAxis.grid.borderWidth
- */
- /**
- * Set cell height for grid axis labels. By default this is calculated from font
- * size. This option only applies to horizontal axes.
- *
- * @sample gantt/grid-axis/cellheight
- * Gant chart with custom cell height
- * @type {number}
- * @apioption xAxis.grid.cellHeight
- */
- ''; // detach doclets above
- /**
- * Get the largest label width and height.
- *
- * @private
- * @function Highcharts.Axis#getMaxLabelDimensions
- *
- * @param {Highcharts.Dictionary<Highcharts.Tick>} ticks
- * All the ticks on one axis.
- *
- * @param {Array<number|string>} tickPositions
- * All the tick positions on one axis.
- *
- * @return {Highcharts.SizeObject}
- * Object containing the properties height and width.
- *
- * @todo Move this to the generic axis implementation, as it is used there.
- */
- Axis.prototype.getMaxLabelDimensions = function (ticks, tickPositions) {
- var dimensions = {
- width: 0,
- height: 0
- };
- tickPositions.forEach(function (pos) {
- var tick = ticks[pos], tickHeight = 0, tickWidth = 0, label;
- if (isObject(tick)) {
- label = isObject(tick.label) ? tick.label : {};
- // Find width and height of tick
- tickHeight = label.getBBox ? label.getBBox().height : 0;
- if (label.textStr && !isNumber(label.textPxLength)) {
- label.textPxLength = label.getBBox().width;
- }
- tickWidth = isNumber(label.textPxLength) ?
- // Math.round ensures crisp lines
- Math.round(label.textPxLength) :
- 0;
- // Update the result if width and/or height are larger
- dimensions.height = Math.max(tickHeight, dimensions.height);
- dimensions.width = Math.max(tickWidth, dimensions.width);
- }
- });
- return dimensions;
- };
- // Adds week date format
- H.dateFormats.W = function (timestamp) {
- var d = new this.Date(timestamp);
- var firstDay = (this.get('Day', d) + 6) % 7;
- var thursday = new this.Date(d.valueOf());
- this.set('Date', thursday, this.get('Date', d) - firstDay + 3);
- var firstThursday = new this.Date(this.get('FullYear', thursday), 0, 1);
- if (this.get('Day', firstThursday) !== 4) {
- this.set('Month', d, 0);
- this.set('Date', d, 1 + (11 - this.get('Day', firstThursday)) % 7);
- }
- return (1 +
- Math.floor((thursday.valueOf() - firstThursday.valueOf()) / 604800000)).toString();
- };
- // First letter of the day of the week, e.g. 'M' for 'Monday'.
- H.dateFormats.E = function (timestamp) {
- return dateFormat('%a', timestamp, true).charAt(0);
- };
- /* eslint-disable no-invalid-this */
- addEvent(Chart, 'afterSetChartSize', function () {
- this.axes.forEach(function (axis) {
- (axis.grid && axis.grid.columns || []).forEach(function (column) {
- column.setAxisSize();
- column.setAxisTranslation();
- });
- });
- });
- // Center tick labels in cells.
- addEvent(Tick, 'afterGetLabelPosition', function (e) {
- var tick = this, label = tick.label, axis = tick.axis, reversed = axis.reversed, chart = axis.chart, options = axis.options, gridOptions = options.grid || {}, labelOpts = axis.options.labels, align = labelOpts.align,
- // verticalAlign is currently not supported for axis.labels.
- verticalAlign = 'middle', // labelOpts.verticalAlign,
- side = GridAxis.Side[axis.side], tickmarkOffset = e.tickmarkOffset, tickPositions = axis.tickPositions, tickPos = tick.pos - tickmarkOffset, nextTickPos = (isNumber(tickPositions[e.index + 1]) ?
- tickPositions[e.index + 1] - tickmarkOffset :
- axis.max + tickmarkOffset), tickSize = axis.tickSize('tick'), tickWidth = tickSize ? tickSize[0] : 0, crispCorr = tickSize ? tickSize[1] / 2 : 0, labelHeight, lblMetrics, lines, bottom, top, left, right;
- // Only center tick labels in grid axes
- if (gridOptions.enabled === true) {
- // Calculate top and bottom positions of the cell.
- if (side === 'top') {
- bottom = axis.top + axis.offset;
- top = bottom - tickWidth;
- }
- else if (side === 'bottom') {
- top = chart.chartHeight - axis.bottom + axis.offset;
- bottom = top + tickWidth;
- }
- else {
- bottom = axis.top + axis.len - axis.translate(reversed ? nextTickPos : tickPos);
- top = axis.top + axis.len - axis.translate(reversed ? tickPos : nextTickPos);
- }
- // Calculate left and right positions of the cell.
- if (side === 'right') {
- left = chart.chartWidth - axis.right + axis.offset;
- right = left + tickWidth;
- }
- else if (side === 'left') {
- right = axis.left + axis.offset;
- left = right - tickWidth;
- }
- else {
- left = Math.round(axis.left + axis.translate(reversed ? nextTickPos : tickPos)) - crispCorr;
- right = Math.round(axis.left + axis.translate(reversed ? tickPos : nextTickPos)) - crispCorr;
- }
- tick.slotWidth = right - left;
- // Calculate the positioning of the label based on
- // alignment.
- e.pos.x = (align === 'left' ?
- left :
- align === 'right' ?
- right :
- left + ((right - left) / 2) // default to center
- );
- e.pos.y = (verticalAlign === 'top' ?
- top :
- verticalAlign === 'bottom' ?
- bottom :
- top + ((bottom - top) / 2) // default to middle
- );
- lblMetrics = chart.renderer.fontMetrics(labelOpts.style.fontSize, label.element);
- labelHeight = label.getBBox().height;
- // Adjustment to y position to align the label correctly.
- // Would be better to have a setter or similar for this.
- if (!labelOpts.useHTML) {
- lines = Math.round(labelHeight / lblMetrics.h);
- e.pos.y += (
- // Center the label
- // TODO: why does this actually center the label?
- ((lblMetrics.b - (lblMetrics.h - lblMetrics.f)) / 2) +
- // Adjust for height of additional lines.
- -(((lines - 1) * lblMetrics.h) / 2));
- }
- else {
- e.pos.y += (
- // Readjust yCorr in htmlUpdateTransform
- lblMetrics.b +
- // Adjust for height of html label
- -(labelHeight / 2));
- }
- e.pos.x += (axis.horiz && labelOpts.x || 0);
- }
- });
- /* eslint-enable no-invalid-this */
- /**
- * Additions for grid axes.
- * @private
- * @class
- */
- var GridAxisAdditions = /** @class */ (function () {
- /* *
- *
- * Constructors
- *
- * */
- function GridAxisAdditions(axis) {
- this.axis = axis;
- }
- /* *
- *
- * Functions
- *
- * */
- /**
- * Checks if an axis is the outer axis in its dimension. Since
- * axes are placed outwards in order, the axis with the highest
- * index is the outermost axis.
- *
- * Example: If there are multiple x-axes at the top of the chart,
- * this function returns true if the axis supplied is the last
- * of the x-axes.
- *
- * @private
- *
- * @return {boolean}
- * True if the axis is the outermost axis in its dimension; false if
- * not.
- */
- GridAxisAdditions.prototype.isOuterAxis = function () {
- var axis = this.axis;
- var chart = axis.chart;
- var columnIndex = axis.grid.columnIndex;
- var columns = (axis.linkedParent && axis.linkedParent.grid.columns ||
- axis.grid.columns);
- var parentAxis = columnIndex ? axis.linkedParent : axis;
- var thisIndex = -1, lastIndex = 0;
- chart[axis.coll].forEach(function (otherAxis, index) {
- if (otherAxis.side === axis.side && !otherAxis.options.isInternal) {
- lastIndex = index;
- if (otherAxis === parentAxis) {
- // Get the index of the axis in question
- thisIndex = index;
- }
- }
- });
- return (lastIndex === thisIndex &&
- (isNumber(columnIndex) ? columns.length === columnIndex : true));
- };
- return GridAxisAdditions;
- }());
- /**
- * Axis with grid support.
- * @private
- * @class
- */
- var GridAxis = /** @class */ (function () {
- function GridAxis() {
- }
- /* *
- *
- * Static Functions
- *
- * */
- /* eslint-disable valid-jsdoc */
- /**
- * Extends axis class with grid support.
- * @private
- */
- GridAxis.compose = function (AxisClass) {
- Axis.keepProps.push('grid');
- wrap(AxisClass.prototype, 'unsquish', GridAxis.wrapUnsquish);
- // Add event handlers
- addEvent(AxisClass, 'init', GridAxis.onInit);
- addEvent(AxisClass, 'afterGetOffset', GridAxis.onAfterGetOffset);
- addEvent(AxisClass, 'afterGetTitlePosition', GridAxis.onAfterGetTitlePosition);
- addEvent(AxisClass, 'afterInit', GridAxis.onAfterInit);
- addEvent(AxisClass, 'afterRender', GridAxis.onAfterRender);
- addEvent(AxisClass, 'afterSetAxisTranslation', GridAxis.onAfterSetAxisTranslation);
- addEvent(AxisClass, 'afterSetOptions', GridAxis.onAfterSetOptions);
- addEvent(AxisClass, 'afterSetOptions', GridAxis.onAfterSetOptions2);
- addEvent(AxisClass, 'afterSetScale', GridAxis.onAfterSetScale);
- addEvent(AxisClass, 'afterTickSize', GridAxis.onAfterTickSize);
- addEvent(AxisClass, 'trimTicks', GridAxis.onTrimTicks);
- addEvent(AxisClass, 'destroy', GridAxis.onDestroy);
- };
- /**
- * Handle columns and getOffset.
- * @private
- */
- GridAxis.onAfterGetOffset = function () {
- var grid = this.grid;
- (grid && grid.columns || []).forEach(function (column) {
- column.getOffset();
- });
- };
- /**
- * @private
- */
- GridAxis.onAfterGetTitlePosition = function (e) {
- var axis = this;
- var options = axis.options;
- var gridOptions = options.grid || {};
- if (gridOptions.enabled === true) {
- // compute anchor points for each of the title align options
- var title = axis.axisTitle, axisHeight = axis.height, horiz = axis.horiz, axisLeft = axis.left, offset = axis.offset, opposite = axis.opposite, _a = axis.options.title, axisTitleOptions = _a === void 0 ? {} : _a, axisTop = axis.top, axisWidth = axis.width;
- var tickSize = axis.tickSize();
- var titleWidth = title && title.getBBox().width;
- var xOption = axisTitleOptions.x || 0;
- var yOption = axisTitleOptions.y || 0;
- var titleMargin = pick(axisTitleOptions.margin, horiz ? 5 : 10);
- var titleFontSize = axis.chart.renderer.fontMetrics(axisTitleOptions.style &&
- axisTitleOptions.style.fontSize, title).f;
- var crispCorr = tickSize ? tickSize[0] / 2 : 0;
- // TODO account for alignment
- // the position in the perpendicular direction of the axis
- var offAxis = ((horiz ? axisTop + axisHeight : axisLeft) +
- (horiz ? 1 : -1) * // horizontal axis reverses the margin
- (opposite ? -1 : 1) * // so does opposite axes
- crispCorr +
- (axis.side === GridAxis.Side.bottom ? titleFontSize : 0));
- e.titlePosition.x = horiz ?
- axisLeft - titleWidth / 2 - titleMargin + xOption :
- offAxis + (opposite ? axisWidth : 0) + offset + xOption;
- e.titlePosition.y = horiz ?
- (offAxis -
- (opposite ? axisHeight : 0) +
- (opposite ? titleFontSize : -titleFontSize) / 2 +
- offset +
- yOption) :
- axisTop - titleMargin + yOption;
- }
- };
- /**
- * @private
- */
- GridAxis.onAfterInit = function () {
- var axis = this;
- var chart = axis.chart, _a = axis.options.grid, gridOptions = _a === void 0 ? {} : _a, userOptions = axis.userOptions;
- if (gridOptions.enabled) {
- applyGridOptions(axis);
- /* eslint-disable no-invalid-this */
- // TODO: wrap the axis instead
- wrap(axis, 'labelFormatter', function (proceed) {
- var _a = this, axis = _a.axis, value = _a.value;
- var tickPos = axis.tickPositions;
- var series = (axis.isLinked ?
- axis.linkedParent :
- axis).series[0];
- var isFirst = value === tickPos[0];
- var isLast = value === tickPos[tickPos.length - 1];
- var point = series && find(series.options.data, function (p) {
- return p[axis.isXAxis ? 'x' : 'y'] === value;
- });
- // Make additional properties available for the
- // formatter
- this.isFirst = isFirst;
- this.isLast = isLast;
- this.point = point;
- // Call original labelFormatter
- return proceed.call(this);
- });
- /* eslint-enable no-invalid-this */
- }
- if (gridOptions.columns) {
- var columns = axis.grid.columns = [], columnIndex = axis.grid.columnIndex = 0;
- // Handle columns, each column is a grid axis
- while (++columnIndex < gridOptions.columns.length) {
- var columnOptions = merge(userOptions, gridOptions.columns[gridOptions.columns.length - columnIndex - 1], {
- linkedTo: 0,
- // Force to behave like category axis
- type: 'category'
- });
- delete columnOptions.grid.columns; // Prevent recursion
- var column = new Axis(axis.chart, columnOptions);
- column.grid.isColumn = true;
- column.grid.columnIndex = columnIndex;
- // Remove column axis from chart axes array, and place it
- // in the columns array.
- erase(chart.axes, column);
- erase(chart[axis.coll], column);
- columns.push(column);
- }
- }
- };
- /**
- * Draw an extra line on the far side of the outermost axis,
- * creating floor/roof/wall of a grid. And some padding.
- * ```
- * Make this:
- * (axis.min) __________________________ (axis.max)
- * | | | | |
- * Into this:
- * (axis.min) __________________________ (axis.max)
- * ___|____|____|____|____|__
- * ```
- * @private
- */
- GridAxis.onAfterRender = function () {
- var axis = this;
- var grid = axis.grid;
- var options = axis.options;
- var renderer = axis.chart.renderer;
- var gridOptions = options.grid || {};
- var yStartIndex, yEndIndex, xStartIndex, xEndIndex;
- if (gridOptions.enabled === true) {
- // @todo acutual label padding (top, bottom, left, right)
- axis.maxLabelDimensions = axis.getMaxLabelDimensions(axis.ticks, axis.tickPositions);
- // Remove right wall before rendering if updating
- if (axis.rightWall) {
- axis.rightWall.destroy();
- }
- /*
- Draw an extra axis line on outer axes
- >
- Make this: |______|______|______|___
- > _________________________
- Into this: |______|______|______|__|
- */
- if (axis.grid && axis.grid.isOuterAxis() && axis.axisLine) {
- var lineWidth = options.lineWidth;
- if (lineWidth) {
- var linePath = axis.getLinePath(lineWidth);
- var startPoint = linePath[0];
- var endPoint = linePath[1];
- // Negate distance if top or left axis
- // Subtract 1px to draw the line at the end of the tick
- var tickLength = (axis.tickSize('tick') || [1])[0];
- var distance = (tickLength - 1) * ((axis.side === GridAxis.Side.top ||
- axis.side === GridAxis.Side.left) ? -1 : 1);
- // If axis is horizontal, reposition line path vertically
- if (startPoint[0] === 'M' && endPoint[0] === 'L') {
- if (axis.horiz) {
- startPoint[2] += distance;
- endPoint[2] += distance;
- }
- else {
- // If axis is vertical, reposition line path
- // horizontally
- startPoint[1] += distance;
- endPoint[1] += distance;
- }
- }
- if (!axis.grid.axisLineExtra) {
- axis.grid.axisLineExtra = renderer
- .path(linePath)
- .attr({
- zIndex: 7
- })
- .addClass('highcharts-axis-line')
- .add(axis.axisGroup);
- if (!renderer.styledMode) {
- axis.grid.axisLineExtra.attr({
- stroke: options.lineColor,
- 'stroke-width': lineWidth
- });
- }
- }
- else {
- axis.grid.axisLineExtra.animate({
- d: linePath
- });
- }
- // show or hide the line depending on
- // options.showEmpty
- axis.axisLine[axis.showAxis ? 'show' : 'hide'](true);
- }
- }
- (grid && grid.columns || []).forEach(function (column) {
- column.render();
- });
- }
- };
- /**
- * @private
- */
- GridAxis.onAfterSetAxisTranslation = function () {
- var axis = this;
- var tickInfo = axis.tickPositions && axis.tickPositions.info;
- var options = axis.options;
- var gridOptions = options.grid || {};
- var userLabels = axis.userOptions.labels || {};
- if (axis.horiz) {
- if (gridOptions.enabled === true) {
- axis.series.forEach(function (series) {
- series.options.pointRange = 0;
- });
- }
- // Lower level time ticks, like hours or minutes, represent
- // points in time and not ranges. These should be aligned
- // left in the grid cell by default. The same applies to
- // years of higher order.
- if (tickInfo &&
- options.dateTimeLabelFormats &&
- options.labels &&
- !defined(userLabels.align) &&
- (options.dateTimeLabelFormats[tickInfo.unitName].range === false ||
- tickInfo.count > 1 // years
- )) {
- options.labels.align = 'left';
- if (!defined(userLabels.x)) {
- options.labels.x = 3;
- }
- }
- }
- };
- /**
- * Creates a left and right wall on horizontal axes:
- * - Places leftmost tick at the start of the axis, to create a left
- * wall
- * - Ensures that the rightmost tick is at the end of the axis, to
- * create a right wall.
- * @private
- */
- GridAxis.onAfterSetOptions = function (e) {
- var options = this.options, userOptions = e.userOptions, gridAxisOptions, gridOptions = ((options && isObject(options.grid)) ? options.grid : {});
- if (gridOptions.enabled === true) {
- // Merge the user options into default grid axis options so
- // that when a user option is set, it takes presedence.
- gridAxisOptions = merge(true, {
- className: ('highcharts-grid-axis ' + (userOptions.className || '')),
- dateTimeLabelFormats: {
- hour: {
- list: ['%H:%M', '%H']
- },
- day: {
- list: ['%A, %e. %B', '%a, %e. %b', '%E']
- },
- week: {
- list: ['Week %W', 'W%W']
- },
- month: {
- list: ['%B', '%b', '%o']
- }
- },
- grid: {
- borderWidth: 1
- },
- labels: {
- padding: 2,
- style: {
- fontSize: '13px'
- }
- },
- margin: 0,
- title: {
- text: null,
- reserveSpace: false,
- rotation: 0
- },
- // In a grid axis, only allow one unit of certain types,
- // for example we shouln't have one grid cell spanning
- // two days.
- units: [[
- 'millisecond',
- [1, 10, 100]
- ], [
- 'second',
- [1, 10]
- ], [
- 'minute',
- [1, 5, 15]
- ], [
- 'hour',
- [1, 6]
- ], [
- 'day',
- [1]
- ], [
- 'week',
- [1]
- ], [
- 'month',
- [1]
- ], [
- 'year',
- null
- ]]
- }, userOptions);
- // X-axis specific options
- if (this.coll === 'xAxis') {
- // For linked axes, tickPixelInterval is used only if
- // the tickPositioner below doesn't run or returns
- // undefined (like multiple years)
- if (defined(userOptions.linkedTo) &&
- !defined(userOptions.tickPixelInterval)) {
- gridAxisOptions.tickPixelInterval = 350;
- }
- // For the secondary grid axis, use the primary axis'
- // tick intervals and return ticks one level higher.
- if (
- // Check for tick pixel interval in options
- !defined(userOptions.tickPixelInterval) &&
- // Only for linked axes
- defined(userOptions.linkedTo) &&
- !defined(userOptions.tickPositioner) &&
- !defined(userOptions.tickInterval)) {
- gridAxisOptions.tickPositioner = function (min, max) {
- var parentInfo = (this.linkedParent &&
- this.linkedParent.tickPositions &&
- this.linkedParent.tickPositions.info);
- if (parentInfo) {
- var unitIdx, count, unitName, i, units = gridAxisOptions.units, unitRange;
- for (i = 0; i < units.length; i++) {
- if (units[i][0] ===
- parentInfo.unitName) {
- unitIdx = i;
- break;
- }
- }
- // Get the first allowed count on the next
- // unit.
- if (units[unitIdx + 1]) {
- unitName = units[unitIdx + 1][0];
- count =
- (units[unitIdx + 1][1] || [1])[0];
- // In case the base X axis shows years, make
- // the secondary axis show ten times the
- // years (#11427)
- }
- else if (parentInfo.unitName === 'year') {
- unitName = 'year';
- count = parentInfo.count * 10;
- }
- unitRange = timeUnits[unitName];
- this.tickInterval = unitRange * count;
- return this.getTimeTicks({
- unitRange: unitRange,
- count: count,
- unitName: unitName
- }, min, max, this.options.startOfWeek);
- }
- };
- }
- }
- // Now merge the combined options into the axis options
- merge(true, this.options, gridAxisOptions);
- if (this.horiz) {
- /* _________________________
- Make this: ___|_____|_____|_____|__|
- ^ ^
- _________________________
- Into this: |_____|_____|_____|_____|
- ^ ^ */
- options.minPadding = pick(userOptions.minPadding, 0);
- options.maxPadding = pick(userOptions.maxPadding, 0);
- }
- // If borderWidth is set, then use its value for tick and
- // line width.
- if (isNumber(options.grid.borderWidth)) {
- options.tickWidth = options.lineWidth = gridOptions.borderWidth;
- }
- }
- };
- /**
- * @private
- */
- GridAxis.onAfterSetOptions2 = function (e) {
- var axis = this;
- var userOptions = e.userOptions;
- var gridOptions = userOptions && userOptions.grid || {};
- var columns = gridOptions.columns;
- // Add column options to the parent axis. Children has their column
- // options set on init in onGridAxisAfterInit.
- if (gridOptions.enabled && columns) {
- merge(true, axis.options, columns[columns.length - 1]);
- }
- };
- /**
- * Handle columns and setScale.
- * @private
- */
- GridAxis.onAfterSetScale = function () {
- var axis = this;
- (axis.grid.columns || []).forEach(function (column) {
- column.setScale();
- });
- };
- /**
- * Draw vertical axis ticks extra long to create cell floors and roofs.
- * Overrides the tickLength for vertical axes.
- * @private
- */
- GridAxis.onAfterTickSize = function (e) {
- var defaultLeftAxisOptions = Axis.defaultLeftAxisOptions;
- var _a = this, horiz = _a.horiz, maxLabelDimensions = _a.maxLabelDimensions, _b = _a.options.grid, gridOptions = _b === void 0 ? {} : _b;
- if (gridOptions.enabled && maxLabelDimensions) {
- var labelPadding = (Math.abs(defaultLeftAxisOptions.labels.x) * 2);
- var distance = horiz ?
- gridOptions.cellHeight || labelPadding + maxLabelDimensions.height :
- labelPadding + maxLabelDimensions.width;
- if (isArray(e.tickSize)) {
- e.tickSize[0] = distance;
- }
- else {
- e.tickSize = [distance, 0];
- }
- }
- };
- /**
- * @private
- */
- GridAxis.onDestroy = function (e) {
- var grid = this.grid;
- (grid.columns || []).forEach(function (column) {
- column.destroy(e.keepEvents);
- });
- grid.columns = void 0;
- };
- /**
- * Wraps axis init to draw cell walls on vertical axes.
- * @private
- */
- GridAxis.onInit = function (e) {
- var axis = this;
- var userOptions = e.userOptions || {};
- var gridOptions = userOptions.grid || {};
- if (gridOptions.enabled && defined(gridOptions.borderColor)) {
- userOptions.tickColor = userOptions.lineColor = gridOptions.borderColor;
- }
- if (!axis.grid) {
- axis.grid = new GridAxisAdditions(axis);
- }
- };
- /**
- * Makes tick labels which are usually ignored in a linked axis
- * displayed if they are within range of linkedParent.min.
- * ```
- * _____________________________
- * | | | | |
- * Make this: | | 2 | 3 | 4 |
- * |___|_______|_______|_______|
- * ^
- * _____________________________
- * | | | | |
- * Into this: | 1 | 2 | 3 | 4 |
- * |___|_______|_______|_______|
- * ^
- * ```
- * @private
- * @todo Does this function do what the drawing says? Seems to affect
- * ticks and not the labels directly?
- */
- GridAxis.onTrimTicks = function () {
- var axis = this;
- var options = axis.options;
- var gridOptions = options.grid || {};
- var categoryAxis = axis.categories;
- var tickPositions = axis.tickPositions;
- var firstPos = tickPositions[0];
- var lastPos = tickPositions[tickPositions.length - 1];
- var linkedMin = axis.linkedParent && axis.linkedParent.min;
- var linkedMax = axis.linkedParent && axis.linkedParent.max;
- var min = linkedMin || axis.min;
- var max = linkedMax || axis.max;
- var tickInterval = axis.tickInterval;
- var endMoreThanMin = (firstPos < min &&
- firstPos + tickInterval > min);
- var startLessThanMax = (lastPos > max &&
- lastPos - tickInterval < max);
- if (gridOptions.enabled === true &&
- !categoryAxis &&
- (axis.horiz || axis.isLinked)) {
- if (endMoreThanMin && !options.startOnTick) {
- tickPositions[0] = min;
- }
- if (startLessThanMax && !options.endOnTick) {
- tickPositions[tickPositions.length - 1] = max;
- }
- }
- };
- /**
- * Avoid altering tickInterval when reserving space.
- * @private
- */
- GridAxis.wrapUnsquish = function (proceed) {
- var axis = this;
- var _a = axis.options.grid, gridOptions = _a === void 0 ? {} : _a;
- if (gridOptions.enabled === true && axis.categories) {
- return axis.tickInterval;
- }
- return proceed.apply(axis, argsToArray(arguments));
- };
- return GridAxis;
- }());
- (function (GridAxis) {
- /**
- * Enum for which side the axis is on. Maps to axis.side.
- * @private
- */
- var Side;
- (function (Side) {
- Side[Side["top"] = 0] = "top";
- Side[Side["right"] = 1] = "right";
- Side[Side["bottom"] = 2] = "bottom";
- Side[Side["left"] = 3] = "left";
- })(Side = GridAxis.Side || (GridAxis.Side = {}));
- })(GridAxis || (GridAxis = {}));
- GridAxis.compose(Axis);
- return GridAxis;
- });
- _registerModule(_modules, 'modules/broken-axis.src.js', [_modules['parts/Axis.js'], _modules['parts/Globals.js'], _modules['parts/Utilities.js'], _modules['parts/Stacking.js']], function (Axis, H, U, StackItem) {
- /* *
- *
- * (c) 2009-2020 Torstein Honsi
- *
- * License: www.highcharts.com/license
- *
- * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
- *
- * */
- var addEvent = U.addEvent, find = U.find, fireEvent = U.fireEvent, isArray = U.isArray, isNumber = U.isNumber, pick = U.pick;
- var Series = H.Series;
- /* eslint-disable valid-jsdoc */
- /**
- * Provides support for broken axes.
- * @private
- * @class
- */
- var BrokenAxisAdditions = /** @class */ (function () {
- /* *
- *
- * Constructors
- *
- * */
- function BrokenAxisAdditions(axis) {
- this.hasBreaks = false;
- this.axis = axis;
- }
- /* *
- *
- * Static Functions
- *
- * */
- /**
- * @private
- */
- BrokenAxisAdditions.isInBreak = function (brk, val) {
- var ret, repeat = brk.repeat || Infinity, from = brk.from, length = brk.to - brk.from, test = (val >= from ?
- (val - from) % repeat :
- repeat - ((from - val) % repeat));
- if (!brk.inclusive) {
- ret = test < length && test !== 0;
- }
- else {
- ret = test <= length;
- }
- return ret;
- };
- /**
- * @private
- */
- BrokenAxisAdditions.lin2Val = function (val) {
- var axis = this;
- var brokenAxis = axis.brokenAxis;
- var breakArray = brokenAxis && brokenAxis.breakArray;
- if (!breakArray) {
- return val;
- }
- var nval = val, brk, i;
- for (i = 0; i < breakArray.length; i++) {
- brk = breakArray[i];
- if (brk.from >= nval) {
- break;
- }
- else if (brk.to < nval) {
- nval += brk.len;
- }
- else if (BrokenAxisAdditions.isInBreak(brk, nval)) {
- nval += brk.len;
- }
- }
- return nval;
- };
- /**
- * @private
- */
- BrokenAxisAdditions.val2Lin = function (val) {
- var axis = this;
- var brokenAxis = axis.brokenAxis;
- var breakArray = brokenAxis && brokenAxis.breakArray;
- if (!breakArray) {
- return val;
- }
- var nval = val, brk, i;
- for (i = 0; i < breakArray.length; i++) {
- brk = breakArray[i];
- if (brk.to <= val) {
- nval -= brk.len;
- }
- else if (brk.from >= val) {
- break;
- }
- else if (BrokenAxisAdditions.isInBreak(brk, val)) {
- nval -= (val - brk.from);
- break;
- }
- }
- return nval;
- };
- /* *
- *
- * Functions
- *
- * */
- /**
- * Returns the first break found where the x is larger then break.from and
- * smaller then break.to.
- *
- * @param {number} x
- * The number which should be within a break.
- *
- * @param {Array<Highcharts.XAxisBreaksOptions>} breaks
- * The array of breaks to search within.
- *
- * @return {Highcharts.XAxisBreaksOptions|undefined}
- * Returns the first break found that matches, returns false if no break is
- * found.
- */
- BrokenAxisAdditions.prototype.findBreakAt = function (x, breaks) {
- return find(breaks, function (b) {
- return b.from < x && x < b.to;
- });
- };
- /**
- * @private
- */
- BrokenAxisAdditions.prototype.isInAnyBreak = function (val, testKeep) {
- var brokenAxis = this;
- var axis = brokenAxis.axis;
- var breaks = axis.options.breaks, i = breaks && breaks.length, inbrk, keep, ret;
- if (i) {
- while (i--) {
- if (BrokenAxisAdditions.isInBreak(breaks[i], val)) {
- inbrk = true;
- if (!keep) {
- keep = pick(breaks[i].showPoints, !axis.isXAxis);
- }
- }
- }
- if (inbrk && testKeep) {
- ret = inbrk && !keep;
- }
- else {
- ret = inbrk;
- }
- }
- return ret;
- };
- /**
- * Dynamically set or unset breaks in an axis. This function in lighter than
- * usin Axis.update, and it also preserves animation.
- *
- * @private
- * @function Highcharts.Axis#setBreaks
- *
- * @param {Array<Highcharts.XAxisBreaksOptions>} [breaks]
- * The breaks to add. When `undefined` it removes existing breaks.
- *
- * @param {boolean} [redraw=true]
- * Whether to redraw the chart immediately.
- *
- * @return {void}
- */
- BrokenAxisAdditions.prototype.setBreaks = function (breaks, redraw) {
- var brokenAxis = this;
- var axis = brokenAxis.axis;
- var hasBreaks = (isArray(breaks) && !!breaks.length);
- axis.isDirty = brokenAxis.hasBreaks !== hasBreaks;
- brokenAxis.hasBreaks = hasBreaks;
- axis.options.breaks = axis.userOptions.breaks = breaks;
- axis.forceRedraw = true; // Force recalculation in setScale
- // Recalculate series related to the axis.
- axis.series.forEach(function (series) {
- series.isDirty = true;
- });
- if (!hasBreaks && axis.val2lin === BrokenAxisAdditions.val2Lin) {
- // Revert to prototype functions
- delete axis.val2lin;
- delete axis.lin2val;
- }
- if (hasBreaks) {
- axis.userOptions.ordinal = false;
- axis.lin2val = BrokenAxisAdditions.lin2Val;
- axis.val2lin = BrokenAxisAdditions.val2Lin;
- axis.setExtremes = function (newMin, newMax, redraw, animation, eventArguments) {
- // If trying to set extremes inside a break, extend min to
- // after, and max to before the break ( #3857 )
- if (brokenAxis.hasBreaks) {
- var axisBreak, breaks = this.options.breaks;
- while ((axisBreak = brokenAxis.findBreakAt(newMin, breaks))) {
- newMin = axisBreak.to;
- }
- while ((axisBreak = brokenAxis.findBreakAt(newMax, breaks))) {
- newMax = axisBreak.from;
- }
- // If both min and max is within the same break.
- if (newMax < newMin) {
- newMax = newMin;
- }
- }
- Axis.prototype.setExtremes.call(this, newMin, newMax, redraw, animation, eventArguments);
- };
- axis.setAxisTranslation = function (saveOld) {
- Axis.prototype.setAxisTranslation.call(this, saveOld);
- brokenAxis.unitLength = null;
- if (brokenAxis.hasBreaks) {
- var breaks = axis.options.breaks || [],
- // Temporary one:
- breakArrayT = [], breakArray = [], length = 0, inBrk, repeat, min = axis.userMin || axis.min, max = axis.userMax || axis.max, pointRangePadding = pick(axis.pointRangePadding, 0), start, i;
- // Min & max check (#4247)
- breaks.forEach(function (brk) {
- repeat = brk.repeat || Infinity;
- if (BrokenAxisAdditions.isInBreak(brk, min)) {
- min +=
- (brk.to % repeat) -
- (min % repeat);
- }
- if (BrokenAxisAdditions.isInBreak(brk, max)) {
- max -=
- (max % repeat) -
- (brk.from % repeat);
- }
- });
- // Construct an array holding all breaks in the axis
- breaks.forEach(function (brk) {
- start = brk.from;
- repeat = brk.repeat || Infinity;
- while (start - repeat > min) {
- start -= repeat;
- }
- while (start < min) {
- start += repeat;
- }
- for (i = start; i < max; i += repeat) {
- breakArrayT.push({
- value: i,
- move: 'in'
- });
- breakArrayT.push({
- value: i + (brk.to - brk.from),
- move: 'out',
- size: brk.breakSize
- });
- }
- });
- breakArrayT.sort(function (a, b) {
- return ((a.value === b.value) ?
- ((a.move === 'in' ? 0 : 1) -
- (b.move === 'in' ? 0 : 1)) :
- a.value - b.value);
- });
- // Simplify the breaks
- inBrk = 0;
- start = min;
- breakArrayT.forEach(function (brk) {
- inBrk += (brk.move === 'in' ? 1 : -1);
- if (inBrk === 1 && brk.move === 'in') {
- start = brk.value;
- }
- if (inBrk === 0) {
- breakArray.push({
- from: start,
- to: brk.value,
- len: brk.value - start - (brk.size || 0)
- });
- length += brk.value - start - (brk.size || 0);
- }
- });
- /**
- * HC <= 8 backwards compatibility, used by demo samples.
- * @deprecated
- * @private
- * @requires modules/broken-axis
- */
- axis.breakArray = brokenAxis.breakArray = breakArray;
- // Used with staticScale, and below the actual axis length,
- // when breaks are substracted.
- brokenAxis.unitLength = max - min - length + pointRangePadding;
- fireEvent(axis, 'afterBreaks');
- if (axis.staticScale) {
- axis.transA = axis.staticScale;
- }
- else if (brokenAxis.unitLength) {
- axis.transA *=
- (max - axis.min + pointRangePadding) /
- brokenAxis.unitLength;
- }
- if (pointRangePadding) {
- axis.minPixelPadding =
- axis.transA * axis.minPointOffset;
- }
- axis.min = min;
- axis.max = max;
- }
- };
- }
- if (pick(redraw, true)) {
- axis.chart.redraw();
- }
- };
- return BrokenAxisAdditions;
- }());
- /**
- * Axis with support of broken data rows.
- * @private
- * @class
- */
- var BrokenAxis = /** @class */ (function () {
- function BrokenAxis() {
- }
- /**
- * Adds support for broken axes.
- * @private
- */
- BrokenAxis.compose = function (AxisClass, SeriesClass) {
- AxisClass.keepProps.push('brokenAxis');
- var seriesProto = Series.prototype;
- /**
- * @private
- */
- seriesProto.drawBreaks = function (axis, keys) {
- var series = this, points = series.points, breaks, threshold, eventName, y;
- if (axis && // #5950
- axis.brokenAxis &&
- axis.brokenAxis.hasBreaks) {
- var brokenAxis_1 = axis.brokenAxis;
- keys.forEach(function (key) {
- breaks = brokenAxis_1 && brokenAxis_1.breakArray || [];
- threshold = axis.isXAxis ?
- axis.min :
- pick(series.options.threshold, axis.min);
- points.forEach(function (point) {
- y = pick(point['stack' + key.toUpperCase()], point[key]);
- breaks.forEach(function (brk) {
- if (isNumber(threshold) && isNumber(y)) {
- eventName = false;
- if ((threshold < brk.from && y > brk.to) ||
- (threshold > brk.from && y < brk.from)) {
- eventName = 'pointBreak';
- }
- else if ((threshold < brk.from && y > brk.from && y < brk.to) ||
- (threshold > brk.from && y > brk.to && y < brk.from)) {
- eventName = 'pointInBreak';
- }
- if (eventName) {
- fireEvent(axis, eventName, { point: point, brk: brk });
- }
- }
- });
- });
- });
- }
- };
- /**
- * Extend getGraphPath by identifying gaps in the data so that we can
- * draw a gap in the line or area. This was moved from ordinal axis
- * module to broken axis module as of #5045.
- *
- * @private
- * @function Highcharts.Series#gappedPath
- *
- * @return {Highcharts.SVGPathArray}
- * Gapped path
- */
- seriesProto.gappedPath = function () {
- var currentDataGrouping = this.currentDataGrouping, groupingSize = currentDataGrouping && currentDataGrouping.gapSize, gapSize = this.options.gapSize, points = this.points.slice(), i = points.length - 1, yAxis = this.yAxis, stack;
- /**
- * Defines when to display a gap in the graph, together with the
- * [gapUnit](plotOptions.series.gapUnit) option.
- *
- * In case when `dataGrouping` is enabled, points can be grouped
- * into a larger time span. This can make the grouped points to have
- * a greater distance than the absolute value of `gapSize` property,
- * which will result in disappearing graph completely. To prevent
- * this situation the mentioned distance between grouped points is
- * used instead of previously defined `gapSize`.
- *
- * In practice, this option is most often used to visualize gaps in
- * time series. In a stock chart, intraday data is available for
- * daytime hours, while gaps will appear in nights and weekends.
- *
- * @see [gapUnit](plotOptions.series.gapUnit)
- * @see [xAxis.breaks](#xAxis.breaks)
- *
- * @sample {highstock} stock/plotoptions/series-gapsize/
- * Setting the gap size to 2 introduces gaps for weekends
- * in daily datasets.
- *
- * @type {number}
- * @default 0
- * @product highstock
- * @requires modules/broken-axis
- * @apioption plotOptions.series.gapSize
- */
- /**
- * Together with [gapSize](plotOptions.series.gapSize), this option
- * defines where to draw gaps in the graph.
- *
- * When the `gapUnit` is `"relative"` (default), a gap size of 5
- * means that if the distance between two points is greater than
- * 5 times that of the two closest points, the graph will be broken.
- *
- * When the `gapUnit` is `"value"`, the gap is based on absolute
- * axis values, which on a datetime axis is milliseconds. This also
- * applies to the navigator series that inherits gap options from
- * the base series.
- *
- * @see [gapSize](plotOptions.series.gapSize)
- *
- * @type {string}
- * @default relative
- * @since 5.0.13
- * @product highstock
- * @validvalue ["relative", "value"]
- * @requires modules/broken-axis
- * @apioption plotOptions.series.gapUnit
- */
- if (gapSize && i > 0) { // #5008
- // Gap unit is relative
- if (this.options.gapUnit !== 'value') {
- gapSize *= this.basePointRange;
- }
- // Setting a new gapSize in case dataGrouping is enabled (#7686)
- if (groupingSize &&
- groupingSize > gapSize &&
- // Except when DG is forced (e.g. from other series)
- // and has lower granularity than actual points (#11351)
- groupingSize >= this.basePointRange) {
- gapSize = groupingSize;
- }
- // extension for ordinal breaks
- var current = void 0, next = void 0;
- while (i--) {
- // Reassign next if it is not visible
- if (!(next && next.visible !== false)) {
- next = points[i + 1];
- }
- current = points[i];
- // Skip iteration if one of the points is not visible
- if (next.visible === false || current.visible === false) {
- continue;
- }
- if (next.x - current.x > gapSize) {
- var xRange = (current.x + next.x) / 2;
- points.splice(// insert after this one
- i + 1, 0, {
- isNull: true,
- x: xRange
- });
- // For stacked chart generate empty stack items, #6546
- if (yAxis.stacking && this.options.stacking) {
- stack = yAxis.stacking.stacks[this.stackKey][xRange] =
- new StackItem(yAxis, yAxis.options
- .stackLabels, false, xRange, this.stack);
- stack.total = 0;
- }
- }
- // Assign current to next for the upcoming iteration
- next = current;
- }
- }
- // Call base method
- return this.getGraphPath(points);
- };
- /* eslint-disable no-invalid-this */
- addEvent(AxisClass, 'init', function () {
- var axis = this;
- if (!axis.brokenAxis) {
- axis.brokenAxis = new BrokenAxisAdditions(axis);
- }
- });
- addEvent(AxisClass, 'afterInit', function () {
- if (typeof this.brokenAxis !== 'undefined') {
- this.brokenAxis.setBreaks(this.options.breaks, false);
- }
- });
- addEvent(AxisClass, 'afterSetTickPositions', function () {
- var axis = this;
- var brokenAxis = axis.brokenAxis;
- if (brokenAxis &&
- brokenAxis.hasBreaks) {
- var tickPositions = this.tickPositions, info = this.tickPositions.info, newPositions = [], i;
- for (i = 0; i < tickPositions.length; i++) {
- if (!brokenAxis.isInAnyBreak(tickPositions[i])) {
- newPositions.push(tickPositions[i]);
- }
- }
- this.tickPositions = newPositions;
- this.tickPositions.info = info;
- }
- });
- // Force Axis to be not-ordinal when breaks are defined
- addEvent(AxisClass, 'afterSetOptions', function () {
- if (this.brokenAxis && this.brokenAxis.hasBreaks) {
- this.options.ordinal = false;
- }
- });
- addEvent(SeriesClass, 'afterGeneratePoints', function () {
- var _a = this, isDirty = _a.isDirty, connectNulls = _a.options.connectNulls, points = _a.points, xAxis = _a.xAxis, yAxis = _a.yAxis;
- // Set, or reset visibility of the points. Axis.setBreaks marks the
- // series as isDirty
- if (isDirty) {
- var i = points.length;
- while (i--) {
- var point = points[i];
- // Respect nulls inside the break (#4275)
- var nullGap = point.y === null && connectNulls === false;
- var isPointInBreak = (!nullGap && ((xAxis &&
- xAxis.brokenAxis &&
- xAxis.brokenAxis.isInAnyBreak(point.x, true)) || (yAxis &&
- yAxis.brokenAxis &&
- yAxis.brokenAxis.isInAnyBreak(point.y, true))));
- // Set point.visible if in any break.
- // If not in break, reset visible to original value.
- point.visible = isPointInBreak ?
- false :
- point.options.visible !== false;
- }
- }
- });
- addEvent(SeriesClass, 'afterRender', function drawPointsWrapped() {
- this.drawBreaks(this.xAxis, ['x']);
- this.drawBreaks(this.yAxis, pick(this.pointArrayMap, ['y']));
- });
- };
- return BrokenAxis;
- }());
- BrokenAxis.compose(Axis, Series); // @todo remove automatism
- return BrokenAxis;
- });
- _registerModule(_modules, 'parts-gantt/TreeGridAxis.js', [_modules['parts/Axis.js'], _modules['parts/Tick.js'], _modules['parts-gantt/Tree.js'], _modules['parts-gantt/TreeGridTick.js'], _modules['mixins/tree-series.js'], _modules['parts/Utilities.js']], function (Axis, Tick, Tree, TreeGridTick, TreeSeriesMixin, U) {
- /* *
- *
- * (c) 2016 Highsoft AS
- * Authors: Jon Arild Nygard
- *
- * License: www.highcharts.com/license
- *
- * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
- *
- * */
- var addEvent = U.addEvent, find = U.find, fireEvent = U.fireEvent, isNumber = U.isNumber, isObject = U.isObject, isString = U.isString, merge = U.merge, pick = U.pick, wrap = U.wrap;
- /**
- * @private
- */
- var TreeGridAxis;
- (function (TreeGridAxis) {
- /* *
- *
- * Interfaces
- *
- * */
- /* *
- *
- * Variables
- *
- * */
- var applied = false;
- /* *
- *
- * Functions
- *
- * */
- /**
- * @private
- */
- function compose(AxisClass) {
- if (!applied) {
- wrap(AxisClass.prototype, 'generateTick', wrapGenerateTick);
- wrap(AxisClass.prototype, 'getMaxLabelDimensions', wrapGetMaxLabelDimensions);
- wrap(AxisClass.prototype, 'init', wrapInit);
- wrap(AxisClass.prototype, 'setTickInterval', wrapSetTickInterval);
- TreeGridTick.compose(Tick);
- applied = true;
- }
- }
- TreeGridAxis.compose = compose;
- /**
- * @private
- */
- function getBreakFromNode(node, max) {
- var from = node.collapseStart || 0, to = node.collapseEnd || 0;
- // In broken-axis, the axis.max is minimized until it is not within a
- // break. Therefore, if break.to is larger than axis.max, the axis.to
- // should not add the 0.5 axis.tickMarkOffset, to avoid adding a break
- // larger than axis.max.
- // TODO consider simplifying broken-axis and this might solve itself
- if (to >= max) {
- from -= 0.5;
- }
- return {
- from: from,
- to: to,
- showPoints: false
- };
- }
- /**
- * Creates a tree structure of the data, and the treegrid. Calculates
- * categories, and y-values of points based on the tree.
- *
- * @private
- * @function getTreeGridFromData
- *
- * @param {Array<Highcharts.GanttPointOptions>} data
- * All the data points to display in the axis.
- *
- * @param {boolean} uniqueNames
- * Wether or not the data node with the same name should share grid cell. If
- * true they do share cell. False by default.
- *
- * @param {number} numberOfSeries
- *
- * @return {object}
- * Returns an object containing categories, mapOfIdToNode,
- * mapOfPosToGridNode, and tree.
- *
- * @todo There should be only one point per line.
- * @todo It should be optional to have one category per point, or merge
- * cells
- * @todo Add unit-tests.
- */
- function getTreeGridFromData(data, uniqueNames, numberOfSeries) {
- var categories = [], collapsedNodes = [], mapOfIdToNode = {}, mapOfPosToGridNode = {}, posIterator = -1, uniqueNamesEnabled = typeof uniqueNames === 'boolean' ? uniqueNames : false, tree;
- // Build the tree from the series data.
- var treeParams = {
- // After the children has been created.
- after: function (node) {
- var gridNode = mapOfPosToGridNode[node.pos], height = 0, descendants = 0;
- gridNode.children.forEach(function (child) {
- descendants += (child.descendants || 0) + 1;
- height = Math.max((child.height || 0) + 1, height);
- });
- gridNode.descendants = descendants;
- gridNode.height = height;
- if (gridNode.collapsed) {
- collapsedNodes.push(gridNode);
- }
- },
- // Before the children has been created.
- before: function (node) {
- var data = isObject(node.data, true) ? node.data : {}, name = isString(data.name) ? data.name : '', parentNode = mapOfIdToNode[node.parent], parentGridNode = (isObject(parentNode, true) ?
- mapOfPosToGridNode[parentNode.pos] :
- null), hasSameName = function (x) {
- return x.name === name;
- }, gridNode, pos;
- // If not unique names, look for sibling node with the same name
- if (uniqueNamesEnabled &&
- isObject(parentGridNode, true) &&
- !!(gridNode = find(parentGridNode.children, hasSameName))) {
- // If there is a gridNode with the same name, reuse position
- pos = gridNode.pos;
- // Add data node to list of nodes in the grid node.
- gridNode.nodes.push(node);
- }
- else {
- // If it is a new grid node, increment position.
- pos = posIterator++;
- }
- // Add new grid node to map.
- if (!mapOfPosToGridNode[pos]) {
- mapOfPosToGridNode[pos] = gridNode = {
- depth: parentGridNode ? parentGridNode.depth + 1 : 0,
- name: name,
- nodes: [node],
- children: [],
- pos: pos
- };
- // If not root, then add name to categories.
- if (pos !== -1) {
- categories.push(name);
- }
- // Add name to list of children.
- if (isObject(parentGridNode, true)) {
- parentGridNode.children.push(gridNode);
- }
- }
- // Add data node to map
- if (isString(node.id)) {
- mapOfIdToNode[node.id] = node;
- }
- // If one of the points are collapsed, then start the grid node
- // in collapsed state.
- if (gridNode &&
- data.collapsed === true) {
- gridNode.collapsed = true;
- }
- // Assign pos to data node
- node.pos = pos;
- }
- };
- var updateYValuesAndTickPos = function (map, numberOfSeries) {
- var setValues = function (gridNode, start, result) {
- var nodes = gridNode.nodes, end = start + (start === -1 ? 0 : numberOfSeries - 1), diff = (end - start) / 2, padding = 0.5, pos = start + diff;
- nodes.forEach(function (node) {
- var data = node.data;
- if (isObject(data, true)) {
- // Update point
- data.y = start + (data.seriesIndex || 0);
- // Remove the property once used
- delete data.seriesIndex;
- }
- node.pos = pos;
- });
- result[pos] = gridNode;
- gridNode.pos = pos;
- gridNode.tickmarkOffset = diff + padding;
- gridNode.collapseStart = end + padding;
- gridNode.children.forEach(function (child) {
- setValues(child, end + 1, result);
- end = (child.collapseEnd || 0) - padding;
- });
- // Set collapseEnd to the end of the last child node.
- gridNode.collapseEnd = end + padding;
- return result;
- };
- return setValues(map['-1'], -1, {});
- };
- // Create tree from data
- tree = Tree.getTree(data, treeParams);
- // Update y values of data, and set calculate tick positions.
- mapOfPosToGridNode = updateYValuesAndTickPos(mapOfPosToGridNode, numberOfSeries);
- // Return the resulting data.
- return {
- categories: categories,
- mapOfIdToNode: mapOfIdToNode,
- mapOfPosToGridNode: mapOfPosToGridNode,
- collapsedNodes: collapsedNodes,
- tree: tree
- };
- }
- /**
- * Builds the tree of categories and calculates its positions.
- * @private
- * @param {object} e Event object
- * @param {object} e.target The chart instance which the event was fired on.
- * @param {object[]} e.target.axes The axes of the chart.
- */
- function onBeforeRender(e) {
- var chart = e.target, axes = chart.axes;
- axes.filter(function (axis) {
- return axis.options.type === 'treegrid';
- }).forEach(function (axis) {
- var options = axis.options || {}, labelOptions = options.labels, uniqueNames = options.uniqueNames, numberOfSeries = 0, isDirty, data, treeGrid;
- // Check whether any of series is rendering for the first time,
- // visibility has changed, or its data is dirty,
- // and only then update. #10570, #10580
- // Also check if mapOfPosToGridNode exists. #10887
- isDirty = (!axis.treeGrid.mapOfPosToGridNode ||
- axis.series.some(function (series) {
- return !series.hasRendered ||
- series.isDirtyData ||
- series.isDirty;
- }));
- if (isDirty) {
- // Concatenate data from all series assigned to this axis.
- data = axis.series.reduce(function (arr, s) {
- if (s.visible) {
- // Push all data to array
- (s.options.data || []).forEach(function (data) {
- if (isObject(data, true)) {
- // Set series index on data. Removed again
- // after use.
- data.seriesIndex = numberOfSeries;
- arr.push(data);
- }
- });
- // Increment series index
- if (uniqueNames === true) {
- numberOfSeries++;
- }
- }
- return arr;
- }, []);
- // setScale is fired after all the series is initialized,
- // which is an ideal time to update the axis.categories.
- treeGrid = getTreeGridFromData(data, uniqueNames || false, (uniqueNames === true) ? numberOfSeries : 1);
- // Assign values to the axis.
- axis.categories = treeGrid.categories;
- axis.treeGrid.mapOfPosToGridNode = treeGrid.mapOfPosToGridNode;
- axis.hasNames = true;
- axis.treeGrid.tree = treeGrid.tree;
- // Update yData now that we have calculated the y values
- axis.series.forEach(function (series) {
- var data = (series.options.data || []).map(function (d) {
- return isObject(d, true) ? merge(d) : d;
- });
- // Avoid destroying points when series is not visible
- if (series.visible) {
- series.setData(data, false);
- }
- });
- // Calculate the label options for each level in the tree.
- axis.treeGrid.mapOptionsToLevel =
- TreeSeriesMixin.getLevelOptions({
- defaults: labelOptions,
- from: 1,
- levels: labelOptions && labelOptions.levels,
- to: axis.treeGrid.tree && axis.treeGrid.tree.height
- });
- // Setting initial collapsed nodes
- if (e.type === 'beforeRender') {
- axis.treeGrid.collapsedNodes = treeGrid.collapsedNodes;
- }
- }
- });
- }
- /**
- * Generates a tick for initial positioning.
- *
- * @private
- * @function Highcharts.GridAxis#generateTick
- *
- * @param {Function} proceed
- * The original generateTick function.
- *
- * @param {number} pos
- * The tick position in axis values.
- */
- function wrapGenerateTick(proceed, pos) {
- var axis = this, mapOptionsToLevel = axis.treeGrid.mapOptionsToLevel || {}, isTreeGrid = axis.options.type === 'treegrid', ticks = axis.ticks;
- var tick = ticks[pos], levelOptions, options, gridNode;
- if (isTreeGrid &&
- axis.treeGrid.mapOfPosToGridNode) {
- gridNode = axis.treeGrid.mapOfPosToGridNode[pos];
- levelOptions = mapOptionsToLevel[gridNode.depth];
- if (levelOptions) {
- options = {
- labels: levelOptions
- };
- }
- if (!tick) {
- ticks[pos] = tick =
- new Tick(axis, pos, void 0, void 0, {
- category: gridNode.name,
- tickmarkOffset: gridNode.tickmarkOffset,
- options: options
- });
- }
- else {
- // update labels depending on tick interval
- tick.parameters.category = gridNode.name;
- tick.options = options;
- tick.addLabel();
- }
- }
- else {
- proceed.apply(axis, Array.prototype.slice.call(arguments, 1));
- }
- }
- /**
- * Override to add indentation to axis.maxLabelDimensions.
- *
- * @private
- * @function Highcharts.GridAxis#getMaxLabelDimensions
- *
- * @param {Function} proceed
- * The original function
- */
- function wrapGetMaxLabelDimensions(proceed) {
- var axis = this, options = axis.options, labelOptions = options && options.labels, indentation = (labelOptions && isNumber(labelOptions.indentation) ?
- labelOptions.indentation :
- 0), retVal = proceed.apply(axis, Array.prototype.slice.call(arguments, 1)), isTreeGrid = axis.options.type === 'treegrid';
- var treeDepth;
- if (isTreeGrid && axis.treeGrid.mapOfPosToGridNode) {
- treeDepth = axis.treeGrid.mapOfPosToGridNode[-1].height || 0;
- retVal.width += indentation * (treeDepth - 1);
- }
- return retVal;
- }
- /**
- * @private
- */
- function wrapInit(proceed, chart, userOptions) {
- var axis = this, isTreeGrid = userOptions.type === 'treegrid';
- if (!axis.treeGrid) {
- axis.treeGrid = new Additions(axis);
- }
- // Set default and forced options for TreeGrid
- if (isTreeGrid) {
- // Add event for updating the categories of a treegrid.
- // NOTE Preferably these events should be set on the axis.
- addEvent(chart, 'beforeRender', onBeforeRender);
- addEvent(chart, 'beforeRedraw', onBeforeRender);
- // Add new collapsed nodes on addseries
- addEvent(chart, 'addSeries', function (e) {
- if (e.options.data) {
- var treeGrid = getTreeGridFromData(e.options.data, userOptions.uniqueNames || false, 1);
- axis.treeGrid.collapsedNodes = (axis.treeGrid.collapsedNodes || []).concat(treeGrid.collapsedNodes);
- }
- });
- // Collapse all nodes in axis.treegrid.collapsednodes
- // where collapsed equals true.
- addEvent(axis, 'foundExtremes', function () {
- if (axis.treeGrid.collapsedNodes) {
- axis.treeGrid.collapsedNodes.forEach(function (node) {
- var breaks = axis.treeGrid.collapse(node);
- if (axis.brokenAxis) {
- axis.brokenAxis.setBreaks(breaks, false);
- // remove the node from the axis collapsedNodes
- if (axis.treeGrid.collapsedNodes) {
- axis.treeGrid.collapsedNodes = axis.treeGrid.collapsedNodes.filter(function (n) {
- return node.collapseStart !== n.collapseStart ||
- node.collapseEnd !== n.collapseEnd;
- });
- }
- }
- });
- }
- });
- // If staticScale is not defined on the yAxis
- // and chart height is set, set axis.isDirty
- // to ensure collapsing works (#12012)
- addEvent(axis, 'afterBreaks', function () {
- var _a;
- if (axis.coll === 'yAxis' && !axis.staticScale && ((_a = axis.chart.options.chart) === null || _a === void 0 ? void 0 : _a.height)) {
- axis.isDirty = true;
- }
- });
- userOptions = merge({
- // Default options
- grid: {
- enabled: true
- },
- // TODO: add support for align in treegrid.
- labels: {
- align: 'left',
- /**
- * Set options on specific levels in a tree grid axis. Takes
- * precedence over labels options.
- *
- * @sample {gantt} gantt/treegrid-axis/labels-levels
- * Levels on TreeGrid Labels
- *
- * @type {Array<*>}
- * @product gantt
- * @apioption yAxis.labels.levels
- *
- * @private
- */
- levels: [{
- /**
- * Specify the level which the options within this object
- * applies to.
- *
- * @type {number}
- * @product gantt
- * @apioption yAxis.labels.levels.level
- *
- * @private
- */
- level: void 0
- }, {
- level: 1,
- /**
- * @type {Highcharts.CSSObject}
- * @product gantt
- * @apioption yAxis.labels.levels.style
- *
- * @private
- */
- style: {
- /** @ignore-option */
- fontWeight: 'bold'
- }
- }],
- /**
- * The symbol for the collapse and expand icon in a
- * treegrid.
- *
- * @product gantt
- * @optionparent yAxis.labels.symbol
- *
- * @private
- */
- symbol: {
- /**
- * The symbol type. Points to a definition function in
- * the `Highcharts.Renderer.symbols` collection.
- *
- * @type {Highcharts.SymbolKeyValue}
- *
- * @private
- */
- type: 'triangle',
- x: -5,
- y: -5,
- height: 10,
- width: 10,
- padding: 5
- }
- },
- uniqueNames: false
- }, userOptions, {
- // Forced options
- reversed: true,
- // grid.columns is not supported in treegrid
- grid: {
- columns: void 0
- }
- });
- }
- // Now apply the original function with the original arguments,
- // which are sliced off this function's arguments
- proceed.apply(axis, [chart, userOptions]);
- if (isTreeGrid) {
- axis.hasNames = true;
- axis.options.showLastLabel = true;
- }
- }
- /**
- * Set the tick positions, tickInterval, axis min and max.
- *
- * @private
- * @function Highcharts.GridAxis#setTickInterval
- *
- * @param {Function} proceed
- * The original setTickInterval function.
- */
- function wrapSetTickInterval(proceed) {
- var axis = this, options = axis.options, isTreeGrid = options.type === 'treegrid';
- if (isTreeGrid) {
- axis.min = pick(axis.userMin, options.min, axis.dataMin);
- axis.max = pick(axis.userMax, options.max, axis.dataMax);
- fireEvent(axis, 'foundExtremes');
- // setAxisTranslation modifies the min and max according to
- // axis breaks.
- axis.setAxisTranslation(true);
- axis.tickmarkOffset = 0.5;
- axis.tickInterval = 1;
- axis.tickPositions = axis.treeGrid.mapOfPosToGridNode ?
- axis.treeGrid.getTickPositions() :
- [];
- }
- else {
- proceed.apply(axis, Array.prototype.slice.call(arguments, 1));
- }
- }
- /* *
- *
- * Classes
- *
- * */
- /**
- * @private
- * @class
- */
- var Additions = /** @class */ (function () {
- /* *
- *
- * Constructors
- *
- * */
- /**
- * @private
- */
- function Additions(axis) {
- this.axis = axis;
- }
- /* *
- *
- * Functions
- *
- * */
- /**
- * Calculates the new axis breaks to collapse a node.
- *
- * @private
- *
- * @param {Highcharts.Axis} axis
- * The axis to check against.
- *
- * @param {Highcharts.GridNode} node
- * The node to collapse.
- *
- * @param {number} pos
- * The tick position to collapse.
- *
- * @return {Array<object>}
- * Returns an array of the new breaks for the axis.
- */
- Additions.prototype.collapse = function (node) {
- var axis = this.axis, breaks = (axis.options.breaks || []), obj = getBreakFromNode(node, axis.max);
- breaks.push(obj);
- return breaks;
- };
- /**
- * Calculates the new axis breaks to expand a node.
- *
- * @private
- *
- * @param {Highcharts.Axis} axis
- * The axis to check against.
- *
- * @param {Highcharts.GridNode} node
- * The node to expand.
- *
- * @param {number} pos
- * The tick position to expand.
- *
- * @return {Array<object>}
- * Returns an array of the new breaks for the axis.
- */
- Additions.prototype.expand = function (node) {
- var axis = this.axis, breaks = (axis.options.breaks || []), obj = getBreakFromNode(node, axis.max);
- // Remove the break from the axis breaks array.
- return breaks.reduce(function (arr, b) {
- if (b.to !== obj.to || b.from !== obj.from) {
- arr.push(b);
- }
- return arr;
- }, []);
- };
- /**
- * Creates a list of positions for the ticks on the axis. Filters out
- * positions that are outside min and max, or is inside an axis break.
- *
- * @private
- *
- * @return {Array<number>}
- * List of positions.
- */
- Additions.prototype.getTickPositions = function () {
- var axis = this.axis;
- return Object.keys(axis.treeGrid.mapOfPosToGridNode || {}).reduce(function (arr, key) {
- var pos = +key;
- if (axis.min <= pos &&
- axis.max >= pos &&
- !(axis.brokenAxis && axis.brokenAxis.isInAnyBreak(pos))) {
- arr.push(pos);
- }
- return arr;
- }, []);
- };
- /**
- * Check if a node is collapsed.
- *
- * @private
- *
- * @param {Highcharts.Axis} axis
- * The axis to check against.
- *
- * @param {object} node
- * The node to check if is collapsed.
- *
- * @param {number} pos
- * The tick position to collapse.
- *
- * @return {boolean}
- * Returns true if collapsed, false if expanded.
- */
- Additions.prototype.isCollapsed = function (node) {
- var axis = this.axis, breaks = (axis.options.breaks || []), obj = getBreakFromNode(node, axis.max);
- return breaks.some(function (b) {
- return b.from === obj.from && b.to === obj.to;
- });
- };
- /**
- * Calculates the new axis breaks after toggling the collapse/expand
- * state of a node. If it is collapsed it will be expanded, and if it is
- * exapended it will be collapsed.
- *
- * @private
- *
- * @param {Highcharts.Axis} axis
- * The axis to check against.
- *
- * @param {Highcharts.GridNode} node
- * The node to toggle.
- *
- * @return {Array<object>}
- * Returns an array of the new breaks for the axis.
- */
- Additions.prototype.toggleCollapse = function (node) {
- return (this.isCollapsed(node) ?
- this.expand(node) :
- this.collapse(node));
- };
- return Additions;
- }());
- TreeGridAxis.Additions = Additions;
- })(TreeGridAxis || (TreeGridAxis = {}));
- // Make utility functions available for testing.
- Axis.prototype.utils = {
- getNode: Tree.getNode
- };
- TreeGridAxis.compose(Axis);
- return TreeGridAxis;
- });
- _registerModule(_modules, 'masters/modules/treegrid.src.js', [], function () {
- });
- }));
|