UNPKG

highcharts

Version:
1,512 lines (1,450 loc) 559 kB
/** * @license Highcharts Gantt JS v12.2.0 (2025-04-07) * @module highcharts/modules/pathfinder * @requires highcharts * * Pathfinder * * (c) 2016-2025 Øystein Moseng * * License: www.highcharts.com/license */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(root["_Highcharts"], root["_Highcharts"]["Chart"], root["_Highcharts"]["Axis"], root["_Highcharts"]["Color"], root["_Highcharts"]["SeriesRegistry"], root["_Highcharts"]["RendererRegistry"], root["_Highcharts"]["SVGRenderer"], root["_Highcharts"]["SVGElement"], root["_Highcharts"]["Templating"], root["_Highcharts"]["Point"], root["_Highcharts"]["StackItem"]); else if(typeof define === 'function' && define.amd) define("highcharts/modules/gantt", ["highcharts/highcharts"], function (amd1) {return factory(amd1,amd1["Chart"],amd1["Axis"],amd1["Color"],amd1["SeriesRegistry"],amd1["RendererRegistry"],amd1["SVGRenderer"],amd1["SVGElement"],amd1["Templating"],amd1["Point"],amd1["StackItem"]);}); else if(typeof exports === 'object') exports["highcharts/modules/gantt"] = factory(root["_Highcharts"], root["_Highcharts"]["Chart"], root["_Highcharts"]["Axis"], root["_Highcharts"]["Color"], root["_Highcharts"]["SeriesRegistry"], root["_Highcharts"]["RendererRegistry"], root["_Highcharts"]["SVGRenderer"], root["_Highcharts"]["SVGElement"], root["_Highcharts"]["Templating"], root["_Highcharts"]["Point"], root["_Highcharts"]["StackItem"]); else root["Highcharts"] = factory(root["Highcharts"], root["Highcharts"]["Chart"], root["Highcharts"]["Axis"], root["Highcharts"]["Color"], root["Highcharts"]["SeriesRegistry"], root["Highcharts"]["RendererRegistry"], root["Highcharts"]["SVGRenderer"], root["Highcharts"]["SVGElement"], root["Highcharts"]["Templating"], root["Highcharts"]["Point"], root["Highcharts"]["StackItem"]); })(typeof window === 'undefined' ? this : window, (__WEBPACK_EXTERNAL_MODULE__944__, __WEBPACK_EXTERNAL_MODULE__960__, __WEBPACK_EXTERNAL_MODULE__532__, __WEBPACK_EXTERNAL_MODULE__620__, __WEBPACK_EXTERNAL_MODULE__512__, __WEBPACK_EXTERNAL_MODULE__608__, __WEBPACK_EXTERNAL_MODULE__540__, __WEBPACK_EXTERNAL_MODULE__28__, __WEBPACK_EXTERNAL_MODULE__984__, __WEBPACK_EXTERNAL_MODULE__260__, __WEBPACK_EXTERNAL_MODULE__184__) => { return /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ /***/ 28: /***/ ((module) => { module.exports = __WEBPACK_EXTERNAL_MODULE__28__; /***/ }), /***/ 184: /***/ ((module) => { module.exports = __WEBPACK_EXTERNAL_MODULE__184__; /***/ }), /***/ 260: /***/ ((module) => { module.exports = __WEBPACK_EXTERNAL_MODULE__260__; /***/ }), /***/ 512: /***/ ((module) => { module.exports = __WEBPACK_EXTERNAL_MODULE__512__; /***/ }), /***/ 532: /***/ ((module) => { module.exports = __WEBPACK_EXTERNAL_MODULE__532__; /***/ }), /***/ 540: /***/ ((module) => { module.exports = __WEBPACK_EXTERNAL_MODULE__540__; /***/ }), /***/ 608: /***/ ((module) => { module.exports = __WEBPACK_EXTERNAL_MODULE__608__; /***/ }), /***/ 620: /***/ ((module) => { module.exports = __WEBPACK_EXTERNAL_MODULE__620__; /***/ }), /***/ 944: /***/ ((module) => { module.exports = __WEBPACK_EXTERNAL_MODULE__944__; /***/ }), /***/ 960: /***/ ((module) => { module.exports = __WEBPACK_EXTERNAL_MODULE__960__; /***/ }), /***/ 984: /***/ ((module) => { module.exports = __WEBPACK_EXTERNAL_MODULE__984__; /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? /******/ () => (module['default']) : /******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // EXPORTS __webpack_require__.d(__webpack_exports__, { "default": () => (/* binding */ gantt_src) }); // EXTERNAL MODULE: external {"amd":["highcharts/highcharts"],"commonjs":["highcharts"],"commonjs2":["highcharts"],"root":["Highcharts"]} var highcharts_commonjs_highcharts_commonjs2_highcharts_root_Highcharts_ = __webpack_require__(944); var highcharts_commonjs_highcharts_commonjs2_highcharts_root_Highcharts_default = /*#__PURE__*/__webpack_require__.n(highcharts_commonjs_highcharts_commonjs2_highcharts_root_Highcharts_); ;// ./code/es-modules/Extensions/ArrowSymbols.js /* * * * (c) 2017 Highsoft AS * Authors: Lars A. V. Cabrera * * License: www.highcharts.com/license * * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!! * * */ /* * * * Functions * * */ /** * Creates an arrow symbol. Like a triangle, except not filled. * ``` * o * o * o * o * o * o * o * ``` * * @private * @function * * @param {number} x * x position of the arrow * * @param {number} y * y position of the arrow * * @param {number} w * width of the arrow * * @param {number} h * height of the arrow * * @return {Highcharts.SVGPathArray} * Path array */ function arrow(x, y, w, h) { return [ ['M', x, y + h / 2], ['L', x + w, y], ['L', x, y + h / 2], ['L', x + w, y + h] ]; } /** * Creates a half-width arrow symbol. Like a triangle, except not filled. * ``` * o * o * o * o * o * ``` * * @private * @function * * @param {number} x * x position of the arrow * * @param {number} y * y position of the arrow * * @param {number} w * width of the arrow * * @param {number} h * height of the arrow * * @return {Highcharts.SVGPathArray} * Path array */ function arrowHalf(x, y, w, h) { return arrow(x, y, w / 2, h); } /** * @private */ function compose(SVGRendererClass) { const symbols = SVGRendererClass.prototype.symbols; symbols.arrow = arrow; symbols['arrow-filled'] = triangleLeft; symbols['arrow-filled-half'] = triangleLeftHalf; symbols['arrow-half'] = arrowHalf; symbols['triangle-left'] = triangleLeft; symbols['triangle-left-half'] = triangleLeftHalf; } /** * Creates a left-oriented triangle. * ``` * o * ooooooo * ooooooooooooo * ooooooo * o * ``` * * @private * @function * * @param {number} x * x position of the triangle * * @param {number} y * y position of the triangle * * @param {number} w * width of the triangle * * @param {number} h * height of the triangle * * @return {Highcharts.SVGPathArray} * Path array */ function triangleLeft(x, y, w, h) { return [ ['M', x + w, y], ['L', x, y + h / 2], ['L', x + w, y + h], ['Z'] ]; } /** * Creates a half-width, left-oriented triangle. * ``` * o * oooo * ooooooo * oooo * o * ``` * * @private * @function * * @param {number} x * x position of the triangle * * @param {number} y * y position of the triangle * * @param {number} w * width of the triangle * * @param {number} h * height of the triangle * * @return {Highcharts.SVGPathArray} * Path array */ function triangleLeftHalf(x, y, w, h) { return triangleLeft(x, y, w / 2, h); } /* * * * Default Export * * */ const ArrowSymbols = { compose }; /* harmony default export */ const Extensions_ArrowSymbols = (ArrowSymbols); ;// ./code/es-modules/Gantt/Connection.js /* * * * (c) 2016 Highsoft AS * Authors: Øystein Moseng, Lars A. V. Cabrera * * License: www.highcharts.com/license * * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!! * * */ const { defined, error, merge, objectEach } = (highcharts_commonjs_highcharts_commonjs2_highcharts_root_Highcharts_default()); /* * * * Constants * * */ const deg2rad = (highcharts_commonjs_highcharts_commonjs2_highcharts_root_Highcharts_default()).deg2rad, max = Math.max, min = Math.min; /* * * * Class * * */ /** * The Connection class. Used internally to represent a connection between two * points. * * @private * @class * @name Highcharts.Connection * * @param {Highcharts.Point} from * Connection runs from this Point. * * @param {Highcharts.Point} to * Connection runs to this Point. * * @param {Highcharts.ConnectorsOptions} [options] * Connection options. */ class Connection { constructor(from, to, options) { this.init(from, to, options); } /** * Initialize the Connection object. Used as constructor only. * * @function Highcharts.Connection#init * * @param {Highcharts.Point} from * Connection runs from this Point. * * @param {Highcharts.Point} to * Connection runs to this Point. * * @param {Highcharts.ConnectorsOptions} [options] * Connection options. */ init(from, to, options) { this.fromPoint = from; this.toPoint = to; this.options = options; this.chart = from.series.chart; this.pathfinder = this.chart.pathfinder; } /** * Add (or update) this connection's path on chart. Stores reference to the * created element on this.graphics.path. * * @function Highcharts.Connection#renderPath * * @param {Highcharts.SVGPathArray} path * Path to render, in array format. E.g. ['M', 0, 0, 'L', 10, 10] * * @param {Highcharts.SVGAttributes} [attribs] * SVG attributes for the path. * * @param {Partial<Highcharts.AnimationOptionsObject>} [animation] * Animation options for the rendering. */ renderPath(path, attribs) { const connection = this, chart = this.chart, styledMode = chart.styledMode, pathfinder = this.pathfinder, anim = {}; let pathGraphic = connection.graphics && connection.graphics.path; // Add the SVG element of the pathfinder group if it doesn't exist if (!pathfinder.group) { pathfinder.group = chart.renderer.g() .addClass('highcharts-pathfinder-group') .attr({ zIndex: -1 }) .add(chart.seriesGroup); } // Shift the group to compensate for plot area. // Note: Do this always (even when redrawing a path) to avoid issues // when updating chart in a way that changes plot metrics. pathfinder.group.translate(chart.plotLeft, chart.plotTop); // Create path if does not exist if (!(pathGraphic && pathGraphic.renderer)) { pathGraphic = chart.renderer.path() .add(pathfinder.group); if (!styledMode) { pathGraphic.attr({ opacity: 0 }); } } // Set path attribs and animate to the new path pathGraphic.attr(attribs); anim.d = path; if (!styledMode) { anim.opacity = 1; } pathGraphic.animate(anim); // Store reference on connection this.graphics = this.graphics || {}; this.graphics.path = pathGraphic; } /** * Calculate and add marker graphics for connection to the chart. The * created/updated elements are stored on this.graphics.start and * this.graphics.end. * * @function Highcharts.Connection#addMarker * * @param {string} type * Marker type, either 'start' or 'end'. * * @param {Highcharts.ConnectorsMarkerOptions} options * All options for this marker. Not calculated or merged with other * options. * * @param {Highcharts.SVGPathArray} path * Connection path in array format. This is used to calculate the * rotation angle of the markers. */ addMarker(type, options, path) { const connection = this, chart = connection.fromPoint.series.chart, pathfinder = chart.pathfinder, renderer = chart.renderer, point = (type === 'start' ? connection.fromPoint : connection.toPoint), anchor = point.getPathfinderAnchorPoint(options); let markerVector, radians, rotation, box, width, height, pathVector, segment; if (!options.enabled) { return; } // Last vector before start/end of path, used to get angle if (type === 'start') { segment = path[1]; } else { // 'end' segment = path[path.length - 2]; } if (segment && segment[0] === 'M' || segment[0] === 'L') { pathVector = { x: segment[1], y: segment[2] }; // Get angle between pathVector and anchor point and use it to // create marker position. radians = point.getRadiansToVector(pathVector, anchor); markerVector = point.getMarkerVector(radians, options.radius, anchor); // Rotation of marker is calculated from angle between pathVector // and markerVector. // (Note: // Used to recalculate radians between markerVector and pathVector, // but this should be the same as between pathVector and anchor.) rotation = -radians / deg2rad; if (options.width && options.height) { width = options.width; height = options.height; } else { width = height = options.radius * 2; } // Add graphics object if it does not exist connection.graphics = connection.graphics || {}; box = { x: markerVector.x - (width / 2), y: markerVector.y - (height / 2), width: width, height: height, rotation: rotation, rotationOriginX: markerVector.x, rotationOriginY: markerVector.y }; if (!connection.graphics[type]) { // Create new marker element connection.graphics[type] = renderer .symbol(options.symbol) .addClass('highcharts-point-connecting-path-' + type + '-marker' + ' highcharts-color-' + this.fromPoint.colorIndex) .attr(box) .add(pathfinder.group); if (!renderer.styledMode) { connection.graphics[type].attr({ fill: options.color || connection.fromPoint.color, stroke: options.lineColor, 'stroke-width': options.lineWidth, opacity: 0 }) .animate({ opacity: 1 }, point.series.options.animation); } } else { connection.graphics[type].animate(box); } } } /** * Calculate and return connection path. * Note: Recalculates chart obstacles on demand if they aren't calculated. * * @function Highcharts.Connection#getPath * * @param {Highcharts.ConnectorsOptions} options * Connector options. Not calculated or merged with other options. * * @return {object|undefined} * Calculated SVG path data in array format. */ getPath(options) { const pathfinder = this.pathfinder, chart = this.chart, algorithm = pathfinder.algorithms[options.type]; let chartObstacles = pathfinder.chartObstacles; if (typeof algorithm !== 'function') { error('"' + options.type + '" is not a Pathfinder algorithm.'); return { path: [], obstacles: [] }; } // This function calculates obstacles on demand if they don't exist if (algorithm.requiresObstacles && !chartObstacles) { chartObstacles = pathfinder.chartObstacles = pathfinder.getChartObstacles(options); // If the algorithmMargin was computed, store the result in default // options. chart.options.connectors.algorithmMargin = options.algorithmMargin; // Cache some metrics too pathfinder.chartObstacleMetrics = pathfinder.getObstacleMetrics(chartObstacles); } // Get the SVG path return algorithm( // From this.fromPoint.getPathfinderAnchorPoint(options.startMarker), // To this.toPoint.getPathfinderAnchorPoint(options.endMarker), merge({ chartObstacles: chartObstacles, lineObstacles: pathfinder.lineObstacles || [], obstacleMetrics: pathfinder.chartObstacleMetrics, hardBounds: { xMin: 0, xMax: chart.plotWidth, yMin: 0, yMax: chart.plotHeight }, obstacleOptions: { margin: options.algorithmMargin }, startDirectionX: pathfinder.getAlgorithmStartDirection(options.startMarker) }, options)); } /** * (re)Calculate and (re)draw the connection. * * @function Highcharts.Connection#render */ render() { const connection = this, fromPoint = connection.fromPoint, series = fromPoint.series, chart = series.chart, pathfinder = chart.pathfinder, attribs = {}; let options = merge(chart.options.connectors, series.options.connectors, fromPoint.options.connectors, connection.options); // Set path attribs if (!chart.styledMode) { attribs.stroke = options.lineColor || fromPoint.color; attribs['stroke-width'] = options.lineWidth; if (options.dashStyle) { attribs.dashstyle = options.dashStyle; } } attribs['class'] = // eslint-disable-line dot-notation 'highcharts-point-connecting-path ' + 'highcharts-color-' + fromPoint.colorIndex; options = merge(attribs, options); // Set common marker options if (!defined(options.marker.radius)) { options.marker.radius = min(max(Math.ceil((options.algorithmMargin || 8) / 2) - 1, 1), 5); } // Get the path const pathResult = connection.getPath(options), path = pathResult.path; // Always update obstacle storage with obstacles from this path. // We don't know if future calls will need this for their algorithm. if (pathResult.obstacles) { pathfinder.lineObstacles = pathfinder.lineObstacles || []; pathfinder.lineObstacles = pathfinder.lineObstacles.concat(pathResult.obstacles); } // Add the calculated path to the pathfinder group connection.renderPath(path, attribs); // Render the markers connection.addMarker('start', merge(options.marker, options.startMarker), path); connection.addMarker('end', merge(options.marker, options.endMarker), path); } /** * Destroy connection by destroying the added graphics elements. * * @function Highcharts.Connection#destroy */ destroy() { if (this.graphics) { objectEach(this.graphics, function (val) { val.destroy(); }); delete this.graphics; } } } /* * * * Default Export * * */ /* harmony default export */ const Gantt_Connection = (Connection); /* * * * API Declarations * * */ /** * The default pathfinder algorithm to use for a chart. It is possible to define * your own algorithms by adding them to the * `Highcharts.Pathfinder.prototype.algorithms` * object before the chart has been created. * * The default algorithms are as follows: * * `straight`: Draws a straight line between the connecting * points. Does not avoid other points when drawing. * * `simpleConnect`: Finds a path between the points using right angles * only. Takes only starting/ending points into * account, and will not avoid other points. * * `fastAvoid`: Finds a path between the points using right angles * only. Will attempt to avoid other points, but its * focus is performance over accuracy. Works well with * less dense datasets. * * @typedef {"fastAvoid"|"simpleConnect"|"straight"|string} Highcharts.PathfinderTypeValue */ ''; // Keeps doclets above in JS file ;// ./code/es-modules/Extensions/CurrentDateIndication.js /* * * * (c) 2016-2025 Highsoft AS * * Author: Lars A. V. Cabrera * * License: www.highcharts.com/license * * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!! * * */ const { composed } = (highcharts_commonjs_highcharts_commonjs2_highcharts_root_Highcharts_default()); const { addEvent, merge: CurrentDateIndication_merge, pushUnique, wrap } = (highcharts_commonjs_highcharts_commonjs2_highcharts_root_Highcharts_default()); /* * * * Constants * * */ /** * Show an indicator on the axis for the current date and time. Can be a * boolean or a configuration object similar to * [xAxis.plotLines](#xAxis.plotLines). * * @sample gantt/current-date-indicator/demo * Current date indicator enabled * @sample gantt/current-date-indicator/object-config * Current date indicator with custom options * * @declare Highcharts.CurrentDateIndicatorOptions * @type {boolean|CurrentDateIndicatorOptions} * @default true * @extends xAxis.plotLines * @excluding value * @product gantt * @apioption xAxis.currentDateIndicator */ const defaultOptions = { color: "#ccd3ff" /* Palette.highlightColor20 */, width: 2, /** * @declare Highcharts.AxisCurrentDateIndicatorLabelOptions */ label: { /** * Format of the label. This options is passed as the first argument to * [dateFormat](/class-reference/Highcharts.Time#dateFormat) function. * * @type {string|Intl.DateTimeFormatOptions} * @product gantt * @apioption xAxis.currentDateIndicator.label.format */ format: '%[abdYHM]', formatter: function (value, format) { return this.axis.chart.time.dateFormat(format || '', value, true); }, rotation: 0, /** * @type {Highcharts.CSSObject} */ style: { /** @internal */ fontSize: '0.7em' } } }; /* * * * Functions * * */ /** * @private */ function CurrentDateIndication_compose(AxisClass, PlotLineOrBandClass) { if (pushUnique(composed, 'CurrentDateIndication')) { addEvent(AxisClass, 'afterSetOptions', onAxisAfterSetOptions); addEvent(PlotLineOrBandClass, 'render', onPlotLineOrBandRender); wrap(PlotLineOrBandClass.prototype, 'getLabelText', wrapPlotLineOrBandGetLabelText); } } /** * @private */ function onAxisAfterSetOptions() { const options = this.options, cdiOptions = options.currentDateIndicator; if (cdiOptions) { const plotLineOptions = typeof cdiOptions === 'object' ? CurrentDateIndication_merge(defaultOptions, cdiOptions) : CurrentDateIndication_merge(defaultOptions); plotLineOptions.value = Date.now(); plotLineOptions.className = 'highcharts-current-date-indicator'; if (!options.plotLines) { options.plotLines = []; } options.plotLines.push(plotLineOptions); } } /** * @private */ function onPlotLineOrBandRender() { // If the label already exists, update its text if (this.label) { this.label.attr({ text: this.getLabelText(this.options.label) }); } } /** * @private */ function wrapPlotLineOrBandGetLabelText(defaultMethod, defaultLabelOptions) { const options = this.options; if (options && options.className && options.className.indexOf('highcharts-current-date-indicator') !== -1 && options.label && typeof options.label.formatter === 'function') { options.value = Date.now(); return options.label.formatter .call(this, options.value, options.label.format); } return defaultMethod.call(this, defaultLabelOptions); } /* * * * Default Export * * */ const CurrentDateIndication = { compose: CurrentDateIndication_compose }; /* harmony default export */ const Extensions_CurrentDateIndication = (CurrentDateIndication); // EXTERNAL MODULE: external {"amd":["highcharts/highcharts","Chart"],"commonjs":["highcharts","Chart"],"commonjs2":["highcharts","Chart"],"root":["Highcharts","Chart"]} var highcharts_Chart_commonjs_highcharts_Chart_commonjs2_highcharts_Chart_root_Highcharts_Chart_ = __webpack_require__(960); var highcharts_Chart_commonjs_highcharts_Chart_commonjs2_highcharts_Chart_root_Highcharts_Chart_default = /*#__PURE__*/__webpack_require__.n(highcharts_Chart_commonjs_highcharts_Chart_commonjs2_highcharts_Chart_root_Highcharts_Chart_); ;// ./code/es-modules/Core/Chart/GanttChart.js /* * * * (c) 2016-2025 Highsoft AS * * Author: Lars A. V. Cabrera * * License: www.highcharts.com/license * * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!! * * */ const { defaultOptions: GanttChart_defaultOptions } = (highcharts_commonjs_highcharts_commonjs2_highcharts_root_Highcharts_default()); const { isArray, merge: GanttChart_merge, splat } = (highcharts_commonjs_highcharts_commonjs2_highcharts_root_Highcharts_default()); /* * * * Class * * */ /** * Gantt-optimized chart. Use {@link Highcharts.Chart|Chart} for common charts. * * @requires modules/gantt * * @class * @name Highcharts.GanttChart * @extends Highcharts.Chart */ class GanttChart extends (highcharts_Chart_commonjs_highcharts_Chart_commonjs2_highcharts_Chart_root_Highcharts_Chart_default()) { /* * * * Functions * * */ /** * Initializes the chart. The constructor's arguments are passed on * directly. * * @function Highcharts.GanttChart#init * * @param {Highcharts.Options} userOptions * Custom options. * * @param {Function} [callback] * Function to run when the chart has loaded and all external * images are loaded. * * * @emits Highcharts.GanttChart#event:init * @emits Highcharts.GanttChart#event:afterInit */ init(userOptions, callback) { const xAxisOptions = userOptions.xAxis, yAxisOptions = userOptions.yAxis; let defaultLinkedTo; // Avoid doing these twice userOptions.xAxis = userOptions.yAxis = void 0; const options = GanttChart_merge(true, { chart: { type: 'gantt' }, title: { text: '' }, legend: { enabled: false }, navigator: { series: { type: 'gantt' }, // Bars were clipped, #14060. yAxis: { type: 'category' } } }, userOptions, // User's options // forced options { isGantt: true }); userOptions.xAxis = xAxisOptions; userOptions.yAxis = yAxisOptions; // Apply X axis options to both single and multi x axes If user hasn't // defined axes as array, make it into an array and add a second axis by // default. options.xAxis = (!isArray(userOptions.xAxis) ? [userOptions.xAxis || {}, {}] : userOptions.xAxis).map((xAxisOptions, i) => { if (i === 1) { // Second xAxis defaultLinkedTo = 0; } return GanttChart_merge( // Defaults { grid: { borderColor: "#cccccc" /* Palette.neutralColor20 */, enabled: true }, opposite: GanttChart_defaultOptions.xAxis?.opposite ?? xAxisOptions.opposite ?? true, linkedTo: defaultLinkedTo }, // User options xAxisOptions, // Forced options { type: 'datetime' }); }); // Apply Y axis options to both single and multi y axes options.yAxis = (splat(userOptions.yAxis || {})).map((yAxisOptions) => GanttChart_merge( // Defaults { grid: { borderColor: "#cccccc" /* Palette.neutralColor20 */, enabled: true }, staticScale: 50, reversed: true, // Set default type treegrid, but only if 'categories' is // undefined type: yAxisOptions.categories ? yAxisOptions.type : 'treegrid' }, // User options yAxisOptions)); super.init(options, callback); } } /* * * * Class Namespace * * */ (function (GanttChart) { /* * * * Functions * * */ /* eslint-disable jsdoc/check-param-names */ /** * The factory function for creating new gantt charts. Creates a new {@link * Highcharts.GanttChart|GanttChart} object with different default options * than the basic Chart. * * @example * // Render a chart in to div#container * let chart = Highcharts.ganttChart('container', { * title: { * text: 'My chart' * }, * series: [{ * data: ... * }] * }); * * @function Highcharts.ganttChart * * @param {string|Highcharts.HTMLDOMElement} renderTo * The DOM element to render to, or its id. * * @param {Highcharts.Options} options * The chart options structure. * * @param {Highcharts.ChartCallbackFunction} [callback] * Function to run when the chart has loaded and all external * images are loaded. Defining a * [chart.events.load](https://api.highcharts.com/highcharts/chart.events.load) * handler is equivalent. * * @return {Highcharts.GanttChart} * Returns the Chart object. */ function ganttChart(a, b, c) { return new GanttChart(a, b, c); } GanttChart.ganttChart = ganttChart; /* eslint-enable jsdoc/check-param-names */ })(GanttChart || (GanttChart = {})); /* * * * Default Export * * */ /* harmony default export */ const Chart_GanttChart = (GanttChart); // EXTERNAL MODULE: external {"amd":["highcharts/highcharts","Axis"],"commonjs":["highcharts","Axis"],"commonjs2":["highcharts","Axis"],"root":["Highcharts","Axis"]} var highcharts_Axis_commonjs_highcharts_Axis_commonjs2_highcharts_Axis_root_Highcharts_Axis_ = __webpack_require__(532); var highcharts_Axis_commonjs_highcharts_Axis_commonjs2_highcharts_Axis_root_Highcharts_Axis_default = /*#__PURE__*/__webpack_require__.n(highcharts_Axis_commonjs_highcharts_Axis_commonjs2_highcharts_Axis_root_Highcharts_Axis_); ;// ./code/es-modules/Stock/Navigator/ChartNavigatorComposition.js /* * * * (c) 2010-2025 Torstein Honsi * * License: www.highcharts.com/license * * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!! * * */ const { isTouchDevice } = (highcharts_commonjs_highcharts_commonjs2_highcharts_root_Highcharts_default()); const { addEvent: ChartNavigatorComposition_addEvent, merge: ChartNavigatorComposition_merge, pick } = (highcharts_commonjs_highcharts_commonjs2_highcharts_root_Highcharts_default()); /* * * * Constants * * */ const composedMembers = []; /* * * * Variables * * */ let NavigatorConstructor; /* * * * Functions * * */ /** * @private */ function ChartNavigatorComposition_compose(ChartClass, NavigatorClass) { if (highcharts_commonjs_highcharts_commonjs2_highcharts_root_Highcharts_default().pushUnique(composedMembers, ChartClass)) { const chartProto = ChartClass.prototype; NavigatorConstructor = NavigatorClass; chartProto.callbacks.push(onChartCallback); ChartNavigatorComposition_addEvent(ChartClass, 'afterAddSeries', onChartAfterAddSeries); ChartNavigatorComposition_addEvent(ChartClass, 'afterSetChartSize', onChartAfterSetChartSize); ChartNavigatorComposition_addEvent(ChartClass, 'afterUpdate', onChartAfterUpdate); ChartNavigatorComposition_addEvent(ChartClass, 'beforeRender', onChartBeforeRender); ChartNavigatorComposition_addEvent(ChartClass, 'beforeShowResetZoom', onChartBeforeShowResetZoom); ChartNavigatorComposition_addEvent(ChartClass, 'update', onChartUpdate); } } /** * Handle adding new series. * @private */ function onChartAfterAddSeries() { if (this.navigator) { // Recompute which series should be shown in navigator, and add them this.navigator.setBaseSeries(null, false); } } /** * For stock charts, extend the Chart.setChartSize method so that we can set the * final top position of the navigator once the height of the chart, including * the legend, is determined. #367. We can't use Chart.getMargins, because * labels offsets are not calculated yet. * @private */ function onChartAfterSetChartSize() { const legend = this.legend, navigator = this.navigator; let legendOptions, xAxis, yAxis; if (navigator) { legendOptions = legend && legend.options; xAxis = navigator.xAxis; yAxis = navigator.yAxis; const { scrollbarHeight, scrollButtonSize } = navigator; // Compute the top position if (this.inverted) { navigator.left = navigator.opposite ? this.chartWidth - scrollbarHeight - navigator.height : this.spacing[3] + scrollbarHeight; navigator.top = this.plotTop + scrollButtonSize; } else { navigator.left = pick(xAxis.left, this.plotLeft + scrollButtonSize); navigator.top = navigator.navigatorOptions.top || this.chartHeight - navigator.height - scrollbarHeight - (this.scrollbar?.options.margin || 0) - this.spacing[2] - (this.rangeSelector && this.extraBottomMargin ? this.rangeSelector.getHeight() : 0) - ((legendOptions && legendOptions.verticalAlign === 'bottom' && legendOptions.layout !== 'proximate' && // #13392 legendOptions.enabled && !legendOptions.floating) ? legend.legendHeight + pick(legendOptions.margin, 10) : 0) - (this.titleOffset ? this.titleOffset[2] : 0); } if (xAxis && yAxis) { // False if navigator is disabled (#904) if (this.inverted) { xAxis.options.left = yAxis.options.left = navigator.left; } else { xAxis.options.top = yAxis.options.top = navigator.top; } xAxis.setAxisSize(); yAxis.setAxisSize(); } } } /** * Initialize navigator, if no scrolling exists yet. * @private */ function onChartAfterUpdate(event) { if (!this.navigator && !this.scroller && (this.options.navigator.enabled || this.options.scrollbar.enabled)) { this.scroller = this.navigator = new NavigatorConstructor(this); if (pick(event.redraw, true)) { this.redraw(event.animation); // #7067 } } } /** * Initialize navigator for stock charts * @private */ function onChartBeforeRender() { const options = this.options; if (options.navigator.enabled || options.scrollbar.enabled) { this.scroller = this.navigator = new NavigatorConstructor(this); } } /** * For Stock charts. For x only zooming, do not to create the zoom button * because X axis zooming is already allowed by the Navigator and Range * selector. (#9285) * @private */ function onChartBeforeShowResetZoom() { const chartOptions = this.options, navigator = chartOptions.navigator, rangeSelector = chartOptions.rangeSelector; if (((navigator && navigator.enabled) || (rangeSelector && rangeSelector.enabled)) && ((!isTouchDevice && this.zooming.type === 'x') || (isTouchDevice && this.zooming.pinchType === 'x'))) { return false; } } /** * @private */ function onChartCallback(chart) { const navigator = chart.navigator; // Initialize the navigator if (navigator && chart.xAxis[0]) { const extremes = chart.xAxis[0].getExtremes(); navigator.render(extremes.min, extremes.max); } } /** * Merge options, if no scrolling exists yet * @private */ function onChartUpdate(e) { const navigatorOptions = (e.options.navigator || {}), scrollbarOptions = (e.options.scrollbar || {}); if (!this.navigator && !this.scroller && (navigatorOptions.enabled || scrollbarOptions.enabled)) { ChartNavigatorComposition_merge(true, this.options.navigator, navigatorOptions); ChartNavigatorComposition_merge(true, this.options.scrollbar, scrollbarOptions); delete e.options.navigator; delete e.options.scrollbar; } } /* * * * Default Export * * */ const ChartNavigatorComposition = { compose: ChartNavigatorComposition_compose }; /* harmony default export */ const Navigator_ChartNavigatorComposition = (ChartNavigatorComposition); ;// ./code/es-modules/Core/Axis/NavigatorAxisComposition.js /* * * * (c) 2010-2025 Torstein Honsi * * License: www.highcharts.com/license * * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!! * * */ const { isTouchDevice: NavigatorAxisComposition_isTouchDevice } = (highcharts_commonjs_highcharts_commonjs2_highcharts_root_Highcharts_default()); const { addEvent: NavigatorAxisComposition_addEvent, correctFloat, defined: NavigatorAxisComposition_defined, isNumber, pick: NavigatorAxisComposition_pick } = (highcharts_commonjs_highcharts_commonjs2_highcharts_root_Highcharts_default()); /* * * * Functions * * */ /** * @private */ function onAxisInit() { const axis = this; if (!axis.navigatorAxis) { axis.navigatorAxis = new NavigatorAxisAdditions(axis); } } /** * For Stock charts, override selection zooming with some special features * because X axis zooming is already allowed by the Navigator and Range * selector. * @private */ function onAxisSetExtremes(e) { const axis = this, chart = axis.chart, chartOptions = chart.options, navigator = chartOptions.navigator, navigatorAxis = axis.navigatorAxis, pinchType = chart.zooming.pinchType, rangeSelector = chartOptions.rangeSelector, zoomType = chart.zooming.type; let zoomed; if (axis.isXAxis && (navigator?.enabled || rangeSelector?.enabled)) { // For y only zooming, ignore the X axis completely if (zoomType === 'y' && e.trigger === 'zoom') { zoomed = false; // For xy zooming, record the state of the zoom before zoom selection, // then when the reset button is pressed, revert to this state. This // should apply only if the chart is initialized with a range (#6612), // otherwise zoom all the way out. } else if (((e.trigger === 'zoom' && zoomType === 'xy') || (NavigatorAxisComposition_isTouchDevice && pinchType === 'xy')) && axis.options.range) { const previousZoom = navigatorAxis.previousZoom; // Minimum defined, zooming in if (NavigatorAxisComposition_defined(e.min)) { navigatorAxis.previousZoom = [axis.min, axis.max]; // Minimum undefined, resetting zoom } else if (previousZoom) { e.min = previousZoom[0]; e.max = previousZoom[1]; navigatorAxis.previousZoom = void 0; } } } if (typeof zoomed !== 'undefined') { e.preventDefault(); } } /* * * * Class * * */ /** * @private * @class */ class NavigatorAxisAdditions { /* * * * Static Functions * * */ /** * @private */ static compose(AxisClass) { if (!AxisClass.keepProps.includes('navigatorAxis')) { AxisClass.keepProps.push('navigatorAxis'); NavigatorAxisComposition_addEvent(AxisClass, 'init', onAxisInit); NavigatorAxisComposition_addEvent(AxisClass, 'setExtremes', onAxisSetExtremes); } } /* * * * Constructors * * */ constructor(axis) { this.axis = axis; } /* * * * Functions * * */ /** * @private */ destroy() { this.axis = void 0; } /** * Add logic to normalize the zoomed range in order to preserve the pressed * state of range selector buttons * * @private * @function Highcharts.Axis#toFixedRange */ toFixedRange(pxMin, pxMax, fixedMin, fixedMax) { const axis = this.axis, halfPointRange = (axis.pointRange || 0) / 2; let newMin = NavigatorAxisComposition_pick(fixedMin, axis.translate(pxMin, true, !axis.horiz)), newMax = NavigatorAxisComposition_pick(fixedMax, axis.translate(pxMax, true, !axis.horiz)); // Add/remove half point range to/from the extremes (#1172) if (!NavigatorAxisComposition_defined(fixedMin)) { newMin = correctFloat(newMin + halfPointRange); } if (!NavigatorAxisComposition_defined(fixedMax)) { newMax = correctFloat(newMax - halfPointRange); } if (!isNumber(newMin) || !isNumber(newMax)) { // #1195, #7411 newMin = newMax = void 0; } return { min: newMin, max: newMax }; } } /* * * * Default Export * * */ /* harmony default export */ const NavigatorAxisComposition = (NavigatorAxisAdditions); // EXTERNAL MODULE: external {"amd":["highcharts/highcharts","Color"],"commonjs":["highcharts","Color"],"commonjs2":["highcharts","Color"],"root":["Highcharts","Color"]} var highcharts_Color_commonjs_highcharts_Color_commonjs2_highcharts_Color_root_Highcharts_Color_ = __webpack_require__(620); var highcharts_Color_commonjs_highcharts_Color_commonjs2_highcharts_Color_root_Highcharts_Color_default = /*#__PURE__*/__webpack_require__.n(highcharts_Color_commonjs_highcharts_Color_commonjs2_highcharts_Color_root_Highcharts_Color_); // EXTERNAL MODULE: external {"amd":["highcharts/highcharts","SeriesRegistry"],"commonjs":["highcharts","SeriesRegistry"],"commonjs2":["highcharts","SeriesRegistry"],"root":["Highcharts","SeriesRegistry"]} var highcharts_SeriesRegistry_commonjs_highcharts_SeriesRegistry_commonjs2_highcharts_SeriesRegistry_root_Highcharts_SeriesRegistry_ = __webpack_require__(512); var highcharts_SeriesRegistry_commonjs_highcharts_SeriesRegistry_commonjs2_highcharts_SeriesRegistry_root_Highcharts_SeriesRegistry_default = /*#__PURE__*/__webpack_require__.n(highcharts_SeriesRegistry_commonjs_highcharts_SeriesRegistry_commonjs2_highcharts_SeriesRegistry_root_Highcharts_SeriesRegistry_); ;// ./code/es-modules/Stock/Navigator/NavigatorDefaults.js /* * * * (c) 2010-2025 Torstein Honsi * * License: www.highcharts.com/license * * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!! * * */ const { parse: color } = (highcharts_Color_commonjs_highcharts_Color_commonjs2_highcharts_Color_root_Highcharts_Color_default()); const { seriesTypes } = (highcharts_SeriesRegistry_commonjs_highcharts_SeriesRegistry_commonjs2_highcharts_SeriesRegistry_root_Highcharts_SeriesRegistry_default()); /* * * * Constants * * */ /** * The navigator is a small series below the main series, displaying * a view of the entire data set. It provides tools to zoom in and * out on parts of the data as well as panning across the dataset. * * @product highstock gantt * @optionparent navigator */ const NavigatorDefaults = { /** * Whether the navigator and scrollbar should adapt to updated data * in the base X axis. When loading data async, as in the demo below, * this should be `false`. Otherwise new data will trigger navigator * redraw, which will cause unwanted looping. In the demo below, the * data in the navigator is set only once. On navigating, only the main * chart content is updated. * * @sample {highstock} stock/demo/lazy-loading/ * Set to false with async data loading * * @type {boolean} * @default true * @apioption navigator.adaptToUpdatedData */ /** * An integer identifying the index to use for the base series, or a * string representing the id of the series. * * **Note**: As of Highcharts 5.0, this is now a deprecated option. * Prefer [series.showInNavigator](#plotOptions.series.showInNavigator). * * @see [series.showInNavigator](#plotOptions.series.showInNavigator) * * @deprecated * @type {number|string} * @default 0 * @apioption navigator.baseSeries */ /** * Enable or disable the navigator. * * @sample {highstock} stock/navigator/enabled/ * Disable the navigator * * @type {boolean} * @default true * @apioption navigator.enabled */ /** * When the chart is inverted, whether to draw the navigator on the * opposite side. * * @type {boolean} * @default false * @since 5.0.8 * @apioption navigator.opposite */ /** * The height of the navigator. * * @sample {highstock} stock/navigator/height/ * A higher navigator */ height: 40, /** * The distance from the nearest element, the X axis or X axis labels. * * @sample {highstock} stock/navigator/margin/ * A margin of 2 draws the navigator closer to the X axis labels */ margin: 22, /** * Whether the mask should be inside the range marking the zoomed * range, or outside. In Highcharts Stock 1.x it was always `false`. * * @sample {highstock} stock/demo/maskinside-false/ * False, mask outside * * @since 2.0 */ maskInside: true, /** * Options for the handles for dragging the zoomed area. * * @sample {highstock} stock/navigator/handles/ * Colored handles */ handles: { /** * Width for handles. * * @sample {highstock} stock/navigator/styled-handles/ * Styled handles * * @since 6.0.0 */ width: 7, /** * Border radius of the handles. * * @sample {highstock} stock/navigator/handles-border-radius/ * Border radius on the navigator handles. * * @since 11.4.2 */ borderRadius: 0, /** * Height for handles. * * @sample {highstock} stock/navigator/styled-handles/ * Styled handles * * @since 6.0.0 */ height: 15, /** * Array to define shapes of handles. 0-index for left, 1-index for * right. * * Additionally, the URL to a graphic can be given o