UNPKG

68 kBJavaScriptView Raw
1/**
2 * Base class for all Axis
3 */
4import { __extends } from "tslib";
5/**
6 * ============================================================================
7 * IMPORTS
8 * ============================================================================
9 * @hidden
10 */
11import { Component } from "../../core/Component";
12import { Container } from "../../core/Container";
13import { DataItem } from "../../core/DataItem";
14import { AxisBreak } from "./AxisBreak";
15import { Label } from "../../core/elements/Label";
16import { Tooltip } from "../../core/elements/Tooltip";
17import { SortedListTemplate } from "../../core/utils/SortedList";
18import { List, ListTemplate, ListDisposer } from "../../core/utils/List";
19import { Disposer, MultiDisposer } from "../../core/utils/Disposer";
20import { registry } from "../../core/Registry";
21import { InterfaceColorSet } from "../../core/utils/InterfaceColorSet";
22import * as $iter from "../../core/utils/Iterator";
23import * as $math from "../../core/utils/Math";
24import * as $utils from "../../core/utils/Utils";
25import * as $number from "../../core/utils/Number";
26import * as $array from "../../core/utils/Array";
27import * as $type from "../../core/utils/Type";
28import { defaultRules, ResponsiveBreakpoints } from "../../core/utils/Responsive";
29/**
30 * ============================================================================
31 * DATA ITEM
32 * ============================================================================
33 * @hidden
34 */
35/**
36 * Defines a [[DataItem]] for [[Axis]].
37 *
38 * @see {@link DataItem}
39 */
40var AxisDataItem = /** @class */ (function (_super) {
41 __extends(AxisDataItem, _super);
42 /**
43 * Constructor
44 */
45 function AxisDataItem() {
46 var _this = _super.call(this) || this;
47 _this.className = "AxisDataItem";
48 _this.applyTheme();
49 return _this;
50 }
51 Object.defineProperty(AxisDataItem.prototype, "grid", {
52 /**
53 * @return Grid element
54 */
55 get: function () {
56 if (!this._grid) {
57 var component_1 = this.component;
58 if (component_1) {
59 var template = void 0;
60 var grid_1;
61 if (this.isRange) {
62 template = component_1.axisRanges.template.grid;
63 if (template.disabled) {
64 return;
65 }
66 else {
67 grid_1 = template.clone();
68 }
69 }
70 else {
71 template = component_1.renderer.grid.template;
72 if (template.disabled) {
73 return;
74 }
75 else {
76 grid_1 = component_1.renderer.grid.create();
77 this._disposers.push(new Disposer(function () {
78 component_1.renderer.grid.removeValue(grid_1);
79 }));
80 }
81 }
82 this.grid = grid_1;
83 grid_1.shouldClone = false;
84 this._disposers.push(grid_1);
85 grid_1.axis = this.component;
86 }
87 }
88 return this._grid;
89 },
90 /**
91 * A [[Grid]] element associated with this data item.
92 *
93 * If there is no grid element associated with data item, a new one is
94 * created and returned.
95 *
96 * @param grid Grid element
97 */
98 set: function (grid) {
99 if (this._grid && this._grid != grid) {
100 $array.remove(this.sprites, this._grid);
101 this._grid.dataItem = undefined;
102 }
103 if (grid) {
104 if (grid.dataItem && grid.dataItem != this) {
105 $array.remove(grid.dataItem.sprites, grid);
106 grid.dataItem.grid = undefined;
107 }
108 this.addSprite(grid);
109 }
110 this._grid = grid;
111 },
112 enumerable: true,
113 configurable: true
114 });
115 Object.defineProperty(AxisDataItem.prototype, "tick", {
116 /**
117 * @return Tick element
118 */
119 get: function () {
120 if (!this._tick) {
121 var component_2 = this.component;
122 if (component_2) {
123 var template = void 0;
124 var tick_1;
125 if (this.isRange) {
126 template = component_2.axisRanges.template.tick;
127 if (template.disabled) {
128 return;
129 }
130 else {
131 tick_1 = template.clone();
132 }
133 }
134 else {
135 template = component_2.renderer.ticks.template;
136 if (template.disabled) {
137 return;
138 }
139 else {
140 tick_1 = component_2.renderer.ticks.create();
141 this._disposers.push(new Disposer(function () {
142 component_2.renderer.ticks.removeValue(tick_1);
143 }));
144 }
145 }
146 this.tick = tick_1;
147 tick_1.axis = this.component;
148 tick_1.shouldClone = false;
149 this._disposers.push(tick_1);
150 }
151 }
152 return this._tick;
153 },
154 /**
155 * An [[AxisTick]] element associated with this data item.
156 *
157 * If there is no tick element associated with data item, a new one is
158 * created and returned.
159 *
160 * @param tick Tick element
161 */
162 set: function (tick) {
163 if (this._tick && this._tick != tick) {
164 $array.remove(this.sprites, this._tick);
165 this._tick.dataItem = undefined;
166 }
167 if (tick) {
168 if (tick.dataItem && tick.dataItem != this) {
169 $array.remove(tick.dataItem.sprites, tick);
170 tick.dataItem.tick = undefined;
171 }
172 this.addSprite(tick);
173 }
174 this._tick = tick;
175 },
176 enumerable: true,
177 configurable: true
178 });
179 Object.defineProperty(AxisDataItem.prototype, "label", {
180 /**
181 * @return Label element
182 */
183 get: function () {
184 if (!this._label) {
185 var component_3 = this.component;
186 if (component_3) {
187 var template = void 0;
188 var label_1;
189 if (this.isRange) {
190 template = component_3.axisRanges.template.label;
191 if (template.disabled) {
192 return;
193 }
194 else {
195 label_1 = template.clone();
196 }
197 }
198 else {
199 template = component_3.renderer.labels.template;
200 if (template.disabled) {
201 return;
202 }
203 else {
204 label_1 = component_3.renderer.labels.create();
205 this._disposers.push(new Disposer(function () {
206 component_3.renderer.labels.removeValue(label_1);
207 }));
208 }
209 }
210 this._disposers.push(label_1);
211 this.label = label_1;
212 label_1.shouldClone = false;
213 label_1.axis = this.component;
214 label_1.virtualParent = component_3;
215 }
216 }
217 return this._label;
218 },
219 /**
220 * An [[AxisLabel]] element associated with this data item.
221 *
222 * If there is no label element associated with data item, a new one is
223 * created and returned.
224 *
225 * @param label Label element
226 */
227 set: function (label) {
228 if (this._label && this._label != label) {
229 $array.remove(this.sprites, this._label);
230 this._label.dataItem = undefined;
231 }
232 if (label) {
233 if (label.dataItem && label.dataItem != this) {
234 $array.remove(label.dataItem.sprites, label);
235 label.dataItem.label = undefined;
236 }
237 this.addSprite(label);
238 }
239 this._label = label;
240 },
241 enumerable: true,
242 configurable: true
243 });
244 Object.defineProperty(AxisDataItem.prototype, "axisFill", {
245 /**
246 * @return Label element
247 */
248 get: function () {
249 if (!this._axisFill) {
250 var component_4 = this.component;
251 if (component_4) {
252 var template = void 0;
253 var axisFill_1;
254 if (this.isRange) {
255 template = component_4.axisRanges.template.axisFill;
256 if (!this.isTemplate && template.disabled) {
257 return;
258 }
259 else {
260 axisFill_1 = template.clone();
261 }
262 }
263 else {
264 template = component_4.renderer.axisFills.template;
265 if (template.disabled) {
266 return;
267 }
268 else {
269 axisFill_1 = component_4.renderer.axisFills.create();
270 this._disposers.push(new Disposer(function () {
271 component_4.renderer.axisFills.removeValue(axisFill_1);
272 }));
273 }
274 }
275 this.axisFill = axisFill_1;
276 axisFill_1.shouldClone = false;
277 this._disposers.push(axisFill_1);
278 }
279 }
280 return this._axisFill;
281 },
282 /**
283 * An [[AxisFill]] associated element with this data item.
284 *
285 * If there is no fill element associated with data item, a new one is
286 * created and returned.
287 *
288 * @param label Label element
289 */
290 set: function (axisFill) {
291 if (this._axisFill && this._axisFill != axisFill) {
292 $array.remove(this.sprites, this._axisFill);
293 this._axisFill.dataItem = undefined;
294 }
295 if (axisFill) {
296 if (axisFill.dataItem && axisFill.dataItem != this) {
297 $array.remove(axisFill.dataItem.sprites, axisFill);
298 axisFill.dataItem.axisFill = undefined;
299 }
300 axisFill.axis = this.component;
301 this.addSprite(axisFill);
302 }
303 this._axisFill = axisFill;
304 },
305 enumerable: true,
306 configurable: true
307 });
308 Object.defineProperty(AxisDataItem.prototype, "text", {
309 /**
310 * @return Text label
311 */
312 get: function () {
313 return this._text;
314 },
315 /**
316 * Text to be used as data item's label.
317 *
318 * @param text Text label
319 */
320 set: function (text) {
321 this._text = text;
322 if (this._label) { // do not use getter, it will create unwanted instances!
323 this._label.text = text;
324 }
325 },
326 enumerable: true,
327 configurable: true
328 });
329 Object.defineProperty(AxisDataItem.prototype, "mask", {
330 /**
331 * Data item's mask.
332 *
333 * @return Mask
334 */
335 get: function () {
336 return this._mask;
337 },
338 enumerable: true,
339 configurable: true
340 });
341 Object.defineProperty(AxisDataItem.prototype, "contents", {
342 /**
343 * Returns a [[Container]] to place all visual elements, related to data item
344 * in.
345 *
346 * If there is no Container, a new one is created.
347 *
348 * @return Contents container
349 */
350 get: function () {
351 if (!this._contents) {
352 var contents = new Container();
353 this.addSprite(contents);
354 contents.isMeasured = false;
355 this._contents = contents;
356 var component = this.component;
357 if (component) {
358 var mask = component.renderer.createFill(this.component);
359 mask.disabled = false;
360 mask.axis = component;
361 this.addSprite(mask);
362 this._mask = mask;
363 contents.mask = mask;
364 }
365 }
366 return this._contents;
367 },
368 enumerable: true,
369 configurable: true
370 });
371 Object.defineProperty(AxisDataItem.prototype, "axisBreak", {
372 /**
373 * @return Axis break
374 */
375 get: function () {
376 return this._axisBreak;
377 },
378 /**
379 * An [[AxisBreak]] this data item falls within.
380 *
381 * @param axisBreak Axis break
382 */
383 set: function (axisBreak) {
384 if (this._axisBreak) {
385 this._axisBreak.dataItems.removeValue(this);
386 }
387 if (axisBreak) {
388 axisBreak.dataItems.push(this);
389 }
390 this._axisBreak = axisBreak;
391 },
392 enumerable: true,
393 configurable: true
394 });
395 /**
396 * Re-draws the element.
397 *
398 * @ignore Exclude from docs
399 */
400 AxisDataItem.prototype.validate = function () {
401 if (this.component) {
402 this.component.validateDataElement(this);
403 }
404 };
405 /**
406 * Appends data item's elements to the parent [[Container]].
407 *
408 * @ignore Exclude from docs
409 */
410 AxisDataItem.prototype.appendChildren = function () {
411 if (this.component) {
412 this.component.appendDataItem(this);
413 }
414 };
415 /**
416 * Checks if data item has particular property set.
417 *
418 * @param prop Property name
419 * @return Property set?
420 */
421 AxisDataItem.prototype.hasProperty = function (prop) {
422 return prop == "component" ? true : _super.prototype.hasProperty.call(this, prop);
423 };
424 /**
425 * Copies all parameters from another [[AxisDataItem]].
426 *
427 * @param source Source AxisDataItem
428 */
429 AxisDataItem.prototype.copyFrom = function (source) {
430 _super.prototype.copyFrom.call(this, source);
431 this.text = source.text;
432 if (source.bullet) {
433 this.bullet = source.bullet.clone();
434 }
435 this.minPosition = source.minPosition;
436 this.maxPosition = source.maxPosition;
437 };
438 /**
439 * Sets visibility of the Data Item.
440 *
441 * @param value Data Item
442 */
443 AxisDataItem.prototype.setVisibility = function (value, noChangeValues) {
444 _super.prototype.setVisibility.call(this, value, noChangeValues);
445 if (this._contents) {
446 this._contents.visible = value;
447 }
448 };
449 Object.defineProperty(AxisDataItem.prototype, "bullet", {
450 /**
451 * @return Bullet
452 */
453 get: function () {
454 return this._bullet;
455 },
456 /**
457 * Set it to an instance of any [[Sprite]]. It will be displayed as an axis
458 * bullet in the middle of the cell, or specific value.
459 *
460 * If you need position bullet relatively to the cell, use [[AxisBullet]]
461 * instead. It has a `location` property which can be used to indicate
462 * precise relative location within cell/range.
463 *
464 * Also, [[AxisBullet]] is a [[Container]] so you can push any other element
465 * into it.
466 *
467 * NOTE: `location` is relative to the parent axis range's scope, i.e.
468 * between its `date` and `endDate` for [[DateAxis]], or `value`/`endValue`
469 * ([[ValueAxis]]), or `category`/`endCategory` ([[categoryAxis]]).
470 *
471 * ```TypeScript
472 * let range = dateAxis.axisRanges.create();
473 * range.date = new Date(2018, 0, 5);
474 *
475 * let flag = new am4plugins_bullets.FlagBullet();
476 * flag.label.text = "Hello";
477 *
478 * range.bullet = flag;
479 * ```
480 * ```JavaScript
481 * var range = dateAxis.axisRanges.create();
482 * range.date = new Date(2018, 0, 5);
483 *
484 * var flag = new am4plugins_bullets.FlagBullet();
485 * flag.label.text = "Hello";
486 *
487 * range.bullet = flag;
488 * ```
489 * ```JSON
490 * {
491 * // ...
492 * "xAxes": [{
493 * "type": "DateAxis",
494 * // ...
495 * "axisRanges": [{
496 * "date": new Date(2018, 0, 5),
497 * "bullet: {
498 * "type": "FlagBullet",
499 * "label": {
500 * "text": "Hello"
501 * }
502 * }
503 * }]
504 * }]
505 * }
506 * ```
507 *
508 * @since 4.5.9
509 * @param value Bullet
510 */
511 set: function (value) {
512 if (this._bullet && this._bullet != value) {
513 $array.remove(this.sprites, this._bullet);
514 this._bullet.dataItem = undefined;
515 }
516 this._bullet = value;
517 if (value) {
518 this.addSprite(value);
519 }
520 },
521 enumerable: true,
522 configurable: true
523 });
524 return AxisDataItem;
525}(DataItem));
526export { AxisDataItem };
527/**
528 * ============================================================================
529 * REQUISITES
530 * ============================================================================
531 * @hidden
532 */
533/**
534 * Defines named positions for data item's location within [[Axis]].
535 */
536export var AxisItemLocation;
537(function (AxisItemLocation) {
538 AxisItemLocation[AxisItemLocation["Start"] = 0] = "Start";
539 AxisItemLocation[AxisItemLocation["Middle"] = 0.5] = "Middle";
540 AxisItemLocation[AxisItemLocation["End"] = 1] = "End";
541})(AxisItemLocation || (AxisItemLocation = {}));
542/**
543 * ============================================================================
544 * MAIN CLASS
545 * ============================================================================
546 * @hidden
547 */
548/**
549 * A base class for all Axis elements.
550 *
551 * @see {@link IAxisEvents} for a list of available Events
552 * @see {@link IAxisAdapters} for a list of available Adapters
553 */
554var Axis = /** @class */ (function (_super) {
555 __extends(Axis, _super);
556 /**
557 * Constructor
558 */
559 function Axis() {
560 var _this =
561 // Init
562 _super.call(this) || this;
563 /**
564 * Number of Grid elements on the axis.
565 */
566 _this._gridCount = 10;
567 /**
568 * A list of [[XYSeries]] that are using this Axis.
569 */
570 _this._series = new List();
571 /**
572 * Specifies if axis should be automatically disposed when removing from
573 * chart's axis list.
574 *
575 * @default true
576 */
577 _this.autoDispose = true;
578 /**
579 * @ignore
580 */
581 _this._axisItemCount = 0;
582 if (_this.constructor === Axis) {
583 throw new Error("'Axis' cannot be instantiated directly. Please use a specific axis type.");
584 }
585 _this.hideTooltipWhileZooming = true;
586 _this.minWidth = 0.0001;
587 _this.minHeight = 0.0001;
588 _this.className = "Axis";
589 _this.shouldClone = false;
590 _this.setPropertyValue("cursorTooltipEnabled", true);
591 _this.toggleZoomOutButton = true;
592 _this.zoomable = true;
593 var interfaceColors = new InterfaceColorSet();
594 // Create title
595 _this.title = new Label();
596 _this.title.shouldClone = false;
597 _this._disposers.push(_this.title);
598 _this.setPropertyValue("startLocation", 0);
599 _this.setPropertyValue("endLocation", 1);
600 // Data item iterator
601 _this._dataItemsIterator = new $iter.ListIterator(_this.dataItems, function () { return _this.dataItems.create(); });
602 _this._dataItemsIterator.createNewItems = true;
603 // Create tooltip
604 var tooltip = new Tooltip();
605 _this._disposers.push(tooltip);
606 tooltip.label.padding(5, 10, 5, 10);
607 tooltip.background.pointerLength = 5;
608 tooltip.fitPointerToBounds = true;
609 tooltip.background.filters.clear();
610 // Set virtual parentfor the tooltip so that it can properly inheirt
611 // formatters from the axis.
612 tooltip.virtualParent = _this;
613 // Create background element for the tooltip
614 var background = tooltip.background;
615 background.cornerRadius = 0;
616 background.fill = interfaceColors.getFor("alternativeBackground");
617 background.stroke = background.fill;
618 background.strokeWidth = 1;
619 background.fillOpacity = 1;
620 tooltip.label.fill = interfaceColors.getFor("alternativeText");
621 _this.tooltip = tooltip;
622 // Accessibility
623 _this.readerHidden = true;
624 _this.events.on("rangechangestarted", function () {
625 _this.series.each(function (series) {
626 if (series.hideTooltipWhileZooming) {
627 series.tooltip.hide();
628 series.tooltip.preventShow = true;
629 }
630 });
631 if (_this.hideTooltipWhileZooming) {
632 _this.tooltip.hide();
633 _this.tooltip.preventShow = true;
634 }
635 }, undefined, false);
636 _this.events.on("rangechangeended", function () {
637 _this.series.each(function (series) {
638 if (series.hideTooltipWhileZooming) {
639 series.tooltip.hide();
640 series.tooltip.preventShow = false;
641 }
642 });
643 if (_this.hideTooltipWhileZooming) {
644 _this.tooltip.hide();
645 _this.tooltip.preventShow = false;
646 }
647 }, undefined, false);
648 _this.applyTheme();
649 return _this;
650 }
651 /**
652 * Holds reference to a function that accepts a DataItem and its index as
653 * parameters.
654 *
655 * It can either return a fill opacity for a fill, or manipulate data item
656 * directly, to create various highlighting scenarios.
657 *
658 * For example, you can set it up to highlight only weekends on a
659 * [[DateAxis]].
660 */
661 Axis.prototype.fillRule = function (dataItem, index) {
662 if (!$type.isNumber(index)) {
663 index = dataItem.index;
664 }
665 if (index / 2 == Math.round(index / 2)) {
666 dataItem.axisFill.__disabled = true;
667 dataItem.axisFill.opacity = 0;
668 }
669 else {
670 dataItem.axisFill.opacity = 1;
671 dataItem.axisFill.__disabled = false;
672 }
673 };
674 /**
675 * Returns a new/empty DataItem of the type appropriate for this object.
676 *
677 * @see {@link DataItem}
678 * @return Data Item
679 */
680 Axis.prototype.createDataItem = function () {
681 return new AxisDataItem();
682 };
683 /**
684 * Invalidates layout.
685 *
686 * @ignore Exclude from docs
687 */
688 Axis.prototype.invalidateLayout = function () {
689 _super.prototype.invalidateLayout.call(this);
690 // this puts series after axis in invalidation order also makes series update it's data items in case widht/height of a series is not 100%
691 $iter.each(this.series.iterator(), function (series) {
692 series.invalidateLayout();
693 });
694 };
695 /**
696 * Invalidates series of this axis.
697 */
698 Axis.prototype.invalidateSeries = function () {
699 // this puts series after axis in invalidation order also makes series update it's data items in case widht/height of a series is not 100%
700 $iter.each(this.series.iterator(), function (series) {
701 series.invalidate();
702 });
703 };
704 /**
705 * Override to cancel super call for data element validation.
706 * @ignore
707 */
708 Axis.prototype.validateDataElements = function () {
709 this._axisItemCount = 0;
710 if (this.ghostLabel) {
711 this.renderer.updateLabelElement(this.ghostLabel, this.start, this.end);
712 this.ghostLabel.validate();
713 }
714 };
715 /**
716 * Recalculates the number of grid items on the axis.
717 */
718 Axis.prototype.updateGridCount = function () {
719 if (this.renderer) {
720 var gridCount = this.axisLength / this.renderer.minGridDistance;
721 if (gridCount != this._gridCount) {
722 this._gridCount = gridCount;
723 this.clearCache();
724 }
725 }
726 };
727 /**
728 * Redraws the element.
729 *
730 * @ignore Exclude from docs
731 */
732 Axis.prototype.validateLayout = function () {
733 this.axisFullLength = this.axisLength / (this.end - this.start);
734 _super.prototype.validateLayout.call(this);
735 this.updateGridCount();
736 var renderer = this.renderer;
737 if (renderer) {
738 renderer.updateAxisLine();
739 renderer.updateTooltip();
740 renderer.updateBaseGridElement();
741 }
742 if (this._prevLength != this.axisLength) {
743 this.dispatchImmediately("lengthchanged");
744 this._prevLength = this.axisLength;
745 }
746 };
747 /**
748 * Initializes Axis' renderer.
749 *
750 * @ignore Exclude from docs
751 */
752 Axis.prototype.initRenderer = function () {
753 };
754 /**
755 * Adds a data item to the Axis.
756 *
757 * @param dataItem Data item
758 */
759 Axis.prototype.appendDataItem = function (dataItem) {
760 var renderer = this.renderer;
761 var tick = dataItem.tick;
762 if (tick) {
763 if (tick.above) {
764 tick.parent = renderer.bulletsContainer;
765 }
766 else {
767 tick.parent = renderer.gridContainer;
768 }
769 }
770 if (dataItem.label) {
771 dataItem.label.parent = renderer;
772 }
773 var axisFill = dataItem.axisFill;
774 if (axisFill) {
775 if (axisFill.above) {
776 axisFill.parent = renderer.bulletsContainer;
777 }
778 else {
779 axisFill.parent = renderer.gridContainer;
780 }
781 }
782 var grid = dataItem.grid;
783 if (grid) {
784 if (grid.above) {
785 grid.parent = renderer.bulletsContainer;
786 }
787 else {
788 grid.parent = renderer.gridContainer;
789 }
790 }
791 if (dataItem.bullet) {
792 dataItem.bullet.parent = renderer.bulletsContainer;
793 }
794 };
795 /**
796 * Redraws Axis' related items.
797 *
798 * @ignore Exclude from docs
799 */
800 Axis.prototype.validate = function () {
801 _super.prototype.validate.call(this);
802 this.validateLayout();
803 this.renderer.updateGridContainer();
804 };
805 /**
806 * Redars Axis ranges.
807 *
808 * @ignore Exclude from docs
809 */
810 Axis.prototype.validateAxisRanges = function () {
811 var _this = this;
812 $iter.each(this.axisRanges.iterator(), function (axisRange) {
813 _this.appendDataItem(axisRange);
814 _this.validateDataElement(axisRange);
815 if (axisRange.grid) {
816 axisRange.grid.validate();
817 }
818 if (axisRange.tick) {
819 axisRange.tick.validate();
820 }
821 if (axisRange.axisFill) {
822 axisRange.axisFill.validate();
823 }
824 if (axisRange.label) {
825 axisRange.label.validate();
826 }
827 });
828 };
829 /**
830 * Invalidates all axis breaks, so they are redrawn.
831 *
832 * @ignore Exclude from docs
833 */
834 Axis.prototype.validateBreaks = function () {
835 if (this._axisBreaks) {
836 $iter.each(this._axisBreaks.iterator(), function (axisBreak) {
837 axisBreak.invalidate();
838 });
839 }
840 };
841 /**
842 * Associates an Axis break with this Axis, after it is inserted into
843 * `axisBreaks`.
844 *
845 * @ignore Exclude from docs
846 * @param event Event
847 */
848 Axis.prototype.processBreak = function (event) {
849 var axisBreak = event.newValue;
850 axisBreak.parent = this.renderer.breakContainer;
851 axisBreak.axis = this;
852 };
853 /**
854 * Registers a [[XYSeries]] element with this Axis.
855 *
856 * Returns a [[Disposer]] for all events, added to Series for watching
857 * changes in Axis, and vice versa.
858 * @ignore
859 * @param series Series
860 * @return Event disposer
861 */
862 Axis.prototype.registerSeries = function (series) {
863 var _this = this;
864 this.series.moveValue(series);
865 return new MultiDisposer([
866 new Disposer(function () {
867 _this.series.removeValue(series);
868 }),
869 this.events.on("lengthchanged", series.invalidate, series, false),
870 this.events.on("lengthchanged", series.createMask, series, false),
871 this.events.on("startchanged", series.invalidate, series, false),
872 this.events.on("endchanged", series.invalidate, series, false),
873 ]);
874 };
875 Object.defineProperty(Axis.prototype, "renderer", {
876 /**
877 * @return Renderer
878 */
879 get: function () {
880 return this._renderer;
881 },
882 /**
883 * An [[AxisRenderer]] to be used to render this Axis.
884 *
885 * Please note that most of the settings, related to Axis' appearance are set
886 * via its renderer. Not directly on the Axis.
887 *
888 * E.g.:
889 *
890 * ```TypeScript
891 * axis.renderer.inside = true;
892 * axis.renderer.minLabelPosition = 0.1;
893 * axis.renderer.maxLabelPosition = 0.9;
894 * ```
895 * ```JavaScript
896 * axis.renderer.inside = true;
897 * axis.renderer.minLabelPosition = 0.1;
898 * axis.renderer.maxLabelPosition = 0.9;
899 * ```
900 *
901 * @see {@link https://www.amcharts.com/docs/v4/concepts/axes/} for more info
902 * @param renderer Renderer
903 */
904 set: function (renderer) {
905 if (renderer != this._renderer) {
906 this._renderer = renderer;
907 renderer.chart = this.chart;
908 renderer.axis = this;
909 renderer.parent = this;
910 this.title.parent = this; // we add title to axis and set layout in renderer to avoid one extra container, as otherwise axis container would be used for holding renderer only
911 this.initRenderer();
912 this._disposers.push(renderer.gridContainer.events.on("maxsizechanged", this.invalidate, this, false));
913 var ghostLabel_1 = this.renderer.labels.create();
914 this._disposers.push(ghostLabel_1);
915 ghostLabel_1.dataItem = this.dataItems.template.clone(); // just for the adapters not to fail
916 ghostLabel_1.text = "L";
917 ghostLabel_1.parent = this.renderer;
918 ghostLabel_1.shouldClone = false;
919 ghostLabel_1.fillOpacity = 0;
920 ghostLabel_1.opacity = 0;
921 ghostLabel_1.strokeOpacity = 0;
922 ghostLabel_1.interactionsEnabled = false;
923 ghostLabel_1.validate();
924 this.ghostLabel = ghostLabel_1;
925 this.events.on("beforedatavalidated", function () {
926 ghostLabel_1.text = "L";
927 }, undefined, false);
928 }
929 },
930 enumerable: true,
931 configurable: true
932 });
933 /**
934 * Converts a relative position to angle. (for circular axes)
935 *
936 * @param position Position (0-1)
937 * @return Angle
938 */
939 Axis.prototype.positionToAngle = function (position) {
940 return this.renderer.positionToAngle(position);
941 };
942 /**
943 * Converts pixel coordinates to a relative position. (0-1)
944 *
945 * @param point Coorinates (px)
946 * @return Position (0-1)
947 */
948 Axis.prototype.pointToPosition = function (point) {
949 return this.renderer.pointToPosition(point);
950 };
951 /**
952 * Converts relative position to coordinate.
953 *
954 * @since 4.7.15
955 * @param position (0-1)
956 * @return coordinate (px)
957 */
958 Axis.prototype.positionToCoordinate = function (position) {
959 return this.renderer.positionToCoordinate(position);
960 };
961 /**
962 * [getAnyRangePath description]
963 *
964 * @ignore Exclude from docs
965 * @todo Description
966 * @param start [description]
967 * @param end [description]
968 * @return [description]
969 */
970 Axis.prototype.getAnyRangePath = function (start, end) {
971 return this.renderer.getPositionRangePath(start, end);
972 };
973 /**
974 * Converts any positional parameter to a relative position on axis.
975 *
976 * @todo Description (review)
977 * @param value Pisition
978 * @return Position (0-1)
979 */
980 Axis.prototype.anyToPosition = function (value) {
981 return 0;
982 };
983 /**
984 * Converts any positional parameter to a relative position on axis.
985 *
986 * @todo Description (review)
987 * @param value Pisition
988 * @return Orientation point
989 */
990 Axis.prototype.anyToPoint = function (value) {
991 return { x: 0, y: 0, angle: 0 };
992 };
993 /**
994 * [getPositionRangePath description]
995 *
996 * @ignore Exclude from docs
997 * @todo Description
998 * @param startPosition [description]
999 * @param endPosition [description]
1000 * @return [description]
1001 */
1002 Axis.prototype.getPositionRangePath = function (startPosition, endPosition) {
1003 if (this.renderer) {
1004 return this.renderer.getPositionRangePath(startPosition, endPosition);
1005 }
1006 return "";
1007 };
1008 Object.defineProperty(Axis.prototype, "axisLength", {
1009 /**
1010 * Actual axis length in pixels.
1011 *
1012 * @return Axis length (px)
1013 */
1014 get: function () {
1015 if (this.renderer) {
1016 return this.renderer.axisLength;
1017 }
1018 return 0;
1019 },
1020 enumerable: true,
1021 configurable: true
1022 });
1023 Object.defineProperty(Axis.prototype, "cursorTooltipEnabled", {
1024 /**
1025 * @return Display tooltip?
1026 */
1027 get: function () {
1028 return this.getPropertyValue("cursorTooltipEnabled");
1029 },
1030 /**
1031 * Indicates if axis should display a tooltip for chart's cursor.
1032 *
1033 * @param value Display tooltip?
1034 */
1035 set: function (value) {
1036 if (this.setPropertyValue("cursorTooltipEnabled", value)) {
1037 if (value && this.renderer) {
1038 this.renderer.updateTooltip();
1039 }
1040 else if (this.tooltip) {
1041 this.tooltip.hide(0);
1042 }
1043 }
1044 },
1045 enumerable: true,
1046 configurable: true
1047 });
1048 Object.defineProperty(Axis.prototype, "toggleZoomOutButton", {
1049 /**
1050 * @return Toggle zoom out button?
1051 */
1052 get: function () {
1053 return this.getPropertyValue("toggleZoomOutButton");
1054 },
1055 /**
1056 * Normally, when axis is zoomed in, a zoom out button is shown by a chart,
1057 * and vice versa: when axis is zoomed out completely, zoom out button is
1058 * hidden.
1059 *
1060 * Setting this to `false` will disable this behavior. Zooming in our out
1061 * this axis will not reveal or hide zoom out button.
1062 *
1063 * @default true
1064 * @since 4.6.2
1065 * @param value Toggle zoom out button?
1066 */
1067 set: function (value) {
1068 this.setPropertyValue("toggleZoomOutButton", value);
1069 },
1070 enumerable: true,
1071 configurable: true
1072 });
1073 /**
1074 * Hides element's [[Tooltip]].
1075 *
1076 * @see {@link Tooltip}
1077 */
1078 Axis.prototype.hideTooltip = function (duration) {
1079 _super.prototype.hideTooltip.call(this, duration);
1080 this._tooltipPosition = undefined;
1081 };
1082 /**
1083 * Shows Axis tooltip at specific relative position within Axis. (0-1)
1084 *
1085 * @param position Position (0-1)
1086 * @param local or global position
1087 */
1088 Axis.prototype.showTooltipAtPosition = function (position, local) {
1089 var tooltip = this._tooltip;
1090 if (!tooltip || this.dataItems.length <= 0) {
1091 this._tooltipPosition = undefined;
1092 }
1093 else {
1094 if (!local) {
1095 position = this.toAxisPosition(position);
1096 }
1097 if (!$type.isNumber(position) || position < this.start || position > this.end) {
1098 tooltip.hide(0);
1099 this._tooltipPosition = undefined;
1100 return;
1101 }
1102 var renderer = this.renderer;
1103 //@todo: think of how to solve this better
1104 if (!tooltip.parent) {
1105 tooltip.parent = this.tooltipContainer;
1106 }
1107 var tooltipLocation = renderer.tooltipLocation;
1108 var startPosition = this.getCellStartPosition(position);
1109 var endPosition = this.getCellEndPosition(position);
1110 if (this.tooltipPosition == "fixed") {
1111 position = startPosition + (endPosition - startPosition) * tooltipLocation;
1112 }
1113 position = $math.fitToRange(position, this.start, this.end);
1114 if (this._tooltipPosition != position) {
1115 this._tooltipPosition = position;
1116 var tooltipLocation2 = renderer.tooltipLocation2;
1117 var startPoint = renderer.positionToPoint(startPosition, tooltipLocation2);
1118 var endPoint = renderer.positionToPoint(endPosition, tooltipLocation2);
1119 // save values so cursor could use them
1120 this.currentItemStartPoint = startPoint;
1121 this.currentItemEndPoint = endPoint;
1122 if (renderer.fullWidthTooltip) {
1123 tooltip.width = endPoint.x - startPoint.x;
1124 tooltip.height = endPoint.y - startPoint.y;
1125 }
1126 var point = renderer.positionToPoint(position, tooltipLocation2);
1127 var globalPoint = $utils.spritePointToSvg(point, this.renderer.line);
1128 tooltip.text = this.getTooltipText(position);
1129 if (tooltip.text) {
1130 tooltip.delayedPointTo(globalPoint);
1131 tooltip.show();
1132 }
1133 }
1134 if (!this.cursorTooltipEnabled || this.tooltip.disabled) {
1135 tooltip.hide(0);
1136 }
1137 }
1138 };
1139 /**
1140 * Converts relative position (0-1) to Axis position with zoom level and
1141 * inversed taken into account.
1142 *
1143 * @param position Global position (0-1)
1144 * @return Position within Axis (0-1)
1145 */
1146 Axis.prototype.toAxisPosition = function (position) {
1147 position = this.renderer.toAxisPosition(position);
1148 if (position == undefined) {
1149 return;
1150 }
1151 position = position * (this.end - this.start);
1152 if (this.renderer.inversed) {
1153 position = this.end - position;
1154 }
1155 else {
1156 position = this.start + position;
1157 }
1158 return position;
1159 };
1160 /**
1161 * Converts position on the axis with zoom level and
1162 * inversed taken into account to global position.
1163 *
1164 * @param position Axis position (0-1)
1165 * @return Global position (0-1)
1166 */
1167 Axis.prototype.toGlobalPosition = function (position) {
1168 if (this.renderer.inversed) {
1169 position = this.end - position;
1170 }
1171 else {
1172 position = position - this.start;
1173 }
1174 return position / (this.end - this.start);
1175 };
1176 /**
1177 * Returns text to be used for cursor's Axis tooltip.
1178 *
1179 * This is a placeholder to override for extending classes.
1180 *
1181 * @ignore Exclude from docs
1182 * @param position Position coordinate (px)
1183 * @return Label text
1184 */
1185 Axis.prototype.getTooltipText = function (position) {
1186 return;
1187 };
1188 /**
1189 * Updates Axis' tooltip's position and possibly size, and pointer (stem)
1190 * place.
1191 *
1192 * @ignore Exclude from docs
1193 * @param pointerOrientation Pointer (stem) orientation
1194 * @param boundingRectangle A rectangle for tooltip to fit within
1195 */
1196 Axis.prototype.updateTooltip = function (pointerOrientation, boundingRectangle) {
1197 var tooltip = this._tooltip;
1198 if (tooltip) {
1199 tooltip.fixDoc = false;
1200 tooltip.pointerOrientation = pointerOrientation;
1201 tooltip.setBounds($utils.spriteRectToSvg(boundingRectangle, this.renderer.line));
1202 }
1203 };
1204 /**
1205 * [roundPosition description]
1206 *
1207 * @ignore Exclude from docs
1208 * @todo Description
1209 * @param position Relative position
1210 * @param location Location on axis
1211 * @return Rounded position
1212 */
1213 Axis.prototype.roundPosition = function (position, location, axisLocation) {
1214 return position;
1215 };
1216 /**
1217 * [getCellStartPosition description]
1218 *
1219 * @ignore Exclude from docs
1220 * @todo Description
1221 * @param position [description]
1222 * @return [description]
1223 */
1224 Axis.prototype.getCellStartPosition = function (position) {
1225 return position;
1226 };
1227 /**
1228 * [getCellEndPosition description]
1229 *
1230 * @ignore Exclude from docs
1231 * @todo Description
1232 * @param position [description]
1233 * @return [description]
1234 */
1235 Axis.prototype.getCellEndPosition = function (position) {
1236 return position;
1237 };
1238 Object.defineProperty(Axis.prototype, "axisRanges", {
1239 /**
1240 * A list of axis ranges for this Axis.
1241 *
1242 * @return Axis ranges
1243 */
1244 get: function () {
1245 if (!this._axisRanges) {
1246 var dataItem = this.createDataItem();
1247 dataItem.isRange = true;
1248 dataItem.axisFill = this.renderer.axisFills.template.clone();
1249 dataItem.grid = this.renderer.grid.template.clone();
1250 dataItem.tick = this.renderer.ticks.template.clone();
1251 dataItem.label = this.renderer.labels.template.clone();
1252 dataItem.isTemplate = true;
1253 dataItem.component = this;
1254 dataItem.axisFill.disabled = false;
1255 dataItem.tick.disabled = false;
1256 dataItem.grid.disabled = false;
1257 dataItem.label.disabled = false;
1258 this._axisRanges = new ListTemplate(dataItem);
1259 this._axisRanges.events.on("inserted", this.processAxisRange, this, false);
1260 this._disposers.push(new ListDisposer(this._axisRanges));
1261 this._disposers.push(this._axisRanges.template);
1262 }
1263 return this._axisRanges;
1264 },
1265 enumerable: true,
1266 configurable: true
1267 });
1268 /**
1269 * Decorates an axis range after it has been added to the axis range list.
1270 *
1271 * @param event Event
1272 */
1273 Axis.prototype.processAxisRange = function (event) {
1274 var axisRange = event.newValue;
1275 axisRange.component = this;
1276 axisRange.isRange = true;
1277 };
1278 Object.defineProperty(Axis.prototype, "axisBreaks", {
1279 /**
1280 * A list of axis breaks on this Axis.
1281 *
1282 * @return Axis breaks.
1283 */
1284 get: function () {
1285 if (!this._axisBreaks) {
1286 this._axisBreaks = new SortedListTemplate(this.createAxisBreak(), function (a, b) {
1287 return $number.order(a.adjustedStartValue, b.adjustedStartValue);
1288 });
1289 this._axisBreaks.events.on("inserted", this.processBreak, this, false);
1290 this._disposers.push(new ListDisposer(this._axisBreaks));
1291 this._disposers.push(this._axisBreaks.template);
1292 }
1293 return this._axisBreaks;
1294 },
1295 enumerable: true,
1296 configurable: true
1297 });
1298 /**
1299 * Creates a new axis break.
1300 *
1301 * @return Axis break
1302 */
1303 Axis.prototype.createAxisBreak = function () {
1304 return new AxisBreak();
1305 };
1306 Object.defineProperty(Axis.prototype, "series", {
1307 /**
1308 * A list of Series currently associated with this Axis.
1309 *
1310 * @return Series
1311 */
1312 get: function () {
1313 if (!this._series) {
1314 this._series = new List();
1315 }
1316 return this._series;
1317 },
1318 enumerable: true,
1319 configurable: true
1320 });
1321 /**
1322 * Processes Series' data items.
1323 *
1324 * This is a placeholder to override for extending classes.
1325 *
1326 * @ignore Exclude from docs
1327 */
1328 Axis.prototype.processSeriesDataItems = function () {
1329 };
1330 /**
1331 * Processes Series' single data item.
1332 *
1333 * This is a placeholder to override for extending classes.
1334 *
1335 * @ignore Exclude from docs
1336 * @param dataItem Data item
1337 */
1338 Axis.prototype.processSeriesDataItem = function (dataItem, axisLetter) {
1339 };
1340 /**
1341 * Post-processes Serie's data items.
1342 *
1343 * This is a placeholder to override for extending classes.
1344 *
1345 * @ignore Exclude from docs
1346 */
1347 Axis.prototype.postProcessSeriesDataItems = function (series) {
1348 };
1349 /**
1350 * Post-processes Serie's single data item.
1351 *
1352 * This is a placeholder to override for extending classes.
1353 *
1354 * @ignore Exclude from docs
1355 * @param dataItem Data item
1356 */
1357 Axis.prototype.postProcessSeriesDataItem = function (dataItem) {
1358 };
1359 //
1360 /**
1361 * Updates Axis based on all Series that might influence it.
1362 *
1363 * Called by Series after Series data is validated.
1364 *
1365 * This is a placeholder to override for extending classes.
1366 *
1367 * @ignore Exclude from docs
1368 */
1369 Axis.prototype.updateAxisBySeries = function () {
1370 };
1371 /**
1372 * Hides unused data items.
1373 *
1374 * @ignore Exclude from docs
1375 */
1376 Axis.prototype.hideUnusedDataItems = function () {
1377 var _this = this;
1378 // hide all unused
1379 var dataItemsIterator = this._dataItemsIterator;
1380 dataItemsIterator.createNewItems = false;
1381 $iter.each(dataItemsIterator.iterator(), function (dataItem) {
1382 _this.validateDataElement(dataItem); // solves shrinking
1383 dataItem.__disabled = true;
1384 });
1385 dataItemsIterator.clear();
1386 dataItemsIterator.createNewItems = true;
1387 };
1388 /**
1389 * Returns a Series' data item that corresponds to specific position on Axis.
1390 *
1391 * This is a placeholder to override for extending classes.
1392 *
1393 * @ignore Exclude from docs
1394 * @param series Series
1395 * @param position Position (0-1)
1396 * @param findNearest Should axis try to find nearest tooltip if there is no data item at exact position
1397 * @return Data item
1398 */
1399 Axis.prototype.getSeriesDataItem = function (series, position, findNearest) {
1400 return;
1401 };
1402 /**
1403 * Returns an angle that corresponds to specific position on axis.
1404 *
1405 * This is a placeholder to override for extending classes.
1406 *
1407 * @ignore Exclude from docs
1408 * @todo Description (review)
1409 * @param dataItem Data item
1410 * @param key ???
1411 * @param location Location
1412 * @param stackKey ???
1413 * @return Angle
1414 */
1415 Axis.prototype.getAngle = function (dataItem, key, location, stackKey, range) {
1416 return;
1417 };
1418 /**
1419 * [getX description]
1420 *
1421 * This is a placeholder to override for extending classes.
1422 *
1423 * @ignore Exclude from docs
1424 * @todo Description (review)
1425 * @param dataItem [description]
1426 * @param key [description]
1427 * @param location [description]
1428 * @param stackKey [description]
1429 * @return [description]
1430 */
1431 Axis.prototype.getX = function (dataItem, key, location, stackKey, range) {
1432 return;
1433 };
1434 /**
1435 * [getX description]
1436 *
1437 * This is a placeholder to override for extending classes.
1438 *
1439 * @ignore Exclude from docs
1440 * @todo Description (review)
1441 * @param dataItem [description]
1442 * @param key [description]
1443 * @param location [description]
1444 * @param stackKey [description]
1445 * @return [description]
1446 */
1447 Axis.prototype.getPositionX = function (dataItem, key, location, stackKey, range) {
1448 return;
1449 };
1450 /**
1451 * [getY description]
1452 *
1453 * This is a placeholder to override for extending classes.
1454 *
1455 * @ignore Exclude from docs
1456 * @todo Description (review)
1457 * @param dataItem [description]
1458 * @param key [description]
1459 * @param location [description]
1460 * @param stackKey [description]
1461 * @return [description]
1462 */
1463 Axis.prototype.getY = function (dataItem, key, location, stackKey, range) {
1464 return;
1465 };
1466 /**
1467 * [getY description]
1468 *
1469 * This is a placeholder to override for extending classes.
1470 *
1471 * @ignore Exclude from docs
1472 * @todo Description (review)
1473 * @param dataItem [description]
1474 * @param key [description]
1475 * @param location [description]
1476 * @param stackKey [description]
1477 * @return [description]
1478 */
1479 Axis.prototype.getPositionY = function (dataItem, key, location, stackKey, range) {
1480 return;
1481 };
1482 Object.defineProperty(Axis.prototype, "basePoint", {
1483 /**
1484 * Coordinates of the actual axis start.
1485 *
1486 * @ignore Exclude from docs
1487 * @return Base point coordinates
1488 */
1489 get: function () {
1490 return { x: 0, y: 0 };
1491 },
1492 enumerable: true,
1493 configurable: true
1494 });
1495 /**
1496 * [dataChangeUpdate description]
1497 *
1498 * This is a placeholder to override for extending classes.
1499 *
1500 * @ignore Exclude from docs
1501 * @todo Description
1502 */
1503 Axis.prototype.dataChangeUpdate = function () {
1504 };
1505 /**
1506 * [dataChangeUpdate description]
1507 *
1508 *
1509 * @ignore Exclude from docs
1510 * @todo Description
1511 */
1512 Axis.prototype.seriesDataChangeUpdate = function (series) {
1513 };
1514 /**
1515 * Removes axis breaks that fall between `min` and `max` (???)
1516 *
1517 * @ignore Exclude from docs
1518 * @todo Description (review)
1519 * @param min Start value
1520 * @param max End value
1521 * @return Spread o
1522 */
1523 Axis.prototype.adjustDifference = function (min, max) {
1524 var difference = max - min;
1525 if ($type.isNumber(difference)) {
1526 if (this._axisBreaks) {
1527 $iter.eachContinue(this._axisBreaks.iterator(), function (axisBreak) {
1528 var startValue = axisBreak.adjustedStartValue;
1529 var endValue = axisBreak.adjustedEndValue;
1530 if ($type.isNumber(startValue) && $type.isNumber(endValue)) {
1531 // breaks are sorted, we don't need go further anymore
1532 if (startValue > max) {
1533 return false;
1534 }
1535 if (endValue >= min) {
1536 if ($type.isNumber(startValue) && $type.isNumber(endValue)) {
1537 var breakSize = axisBreak.breakSize;
1538 var intersection = $math.intersection({ start: startValue, end: endValue }, { start: min, end: max });
1539 if (intersection) {
1540 difference -= (intersection.end - intersection.start) * (1 - breakSize);
1541 }
1542 }
1543 }
1544 return true;
1545 }
1546 });
1547 }
1548 return difference;
1549 }
1550 };
1551 /**
1552 * Checks if specific value falls within a break.
1553 *
1554 * Returns [[AxisBreak]] the value falls into.
1555 *
1556 * @param value Value to check
1557 * @return Axis break
1558 */
1559 Axis.prototype.isInBreak = function (value) {
1560 if (this._axisBreaks) {
1561 return $iter.find(this._axisBreaks.iterator(), function (axisBreak) {
1562 return value >= axisBreak.adjustedStartValue &&
1563 value <= axisBreak.adjustedEndValue;
1564 });
1565 }
1566 };
1567 /**
1568 * [fixAxisBreaks description]
1569 *
1570 * @ignore Exclude from docs
1571 * @todo Description
1572 */
1573 Axis.prototype.fixAxisBreaks = function () {
1574 var _this = this;
1575 if (this._axisBreaks) {
1576 var axisBreaks = this._axisBreaks;
1577 if (axisBreaks.length > 0) {
1578 // first make sure that startValue is <= end value
1579 // This needs to make a copy of axisBreaks because it mutates the list while traversing
1580 // TODO very inefficient
1581 $array.each($iter.toArray(axisBreaks.iterator()), function (axisBreak) {
1582 var startValue = $math.min(axisBreak.startValue, axisBreak.endValue);
1583 var endValue = $math.max(axisBreak.startValue, axisBreak.endValue);
1584 axisBreak.adjustedStartValue = startValue;
1585 axisBreak.adjustedEndValue = endValue;
1586 _this._axisBreaks.update(axisBreak);
1587 });
1588 var firstAxisBreak = axisBreaks.first;
1589 var previousEndValue_1 = Math.min(firstAxisBreak.startValue, firstAxisBreak.endValue);
1590 // process breaks
1591 // TODO does this need to call axisBreaks.update ?
1592 $iter.each(axisBreaks.iterator(), function (axisBreak) {
1593 var startValue = axisBreak.adjustedStartValue;
1594 var endValue = axisBreak.adjustedEndValue;
1595 // breaks can't overlap
1596 // if break starts before previous break ends
1597 if (startValue < previousEndValue_1) {
1598 startValue = previousEndValue_1;
1599 if (endValue < previousEndValue_1) {
1600 endValue = previousEndValue_1;
1601 }
1602 }
1603 axisBreak.adjustedStartValue = startValue;
1604 axisBreak.adjustedEndValue = endValue;
1605 });
1606 }
1607 }
1608 };
1609 Object.defineProperty(Axis.prototype, "startIndex", {
1610 /**
1611 * @ignore Exclude from docs
1612 * @return [description]
1613 */
1614 get: function () {
1615 return 0;
1616 },
1617 /**
1618 * We need start/end indexes of axes to be 0 - `dataItems.length`.
1619 *
1620 * Yes, also for category axis, this helps to avoid jumping of categories
1621 * while scrolling and does not do a lot of extra work as we use
1622 * protected `_startIndex` and `_endIndex` when working with items.
1623 *
1624 * @hidden
1625 */
1626 /**
1627 * [startIndex description]
1628 *
1629 * @ignore Exclude from docs
1630 * @todo Description
1631 * @param value [description]
1632 */
1633 set: function (value) {
1634 },
1635 enumerable: true,
1636 configurable: true
1637 });
1638 Object.defineProperty(Axis.prototype, "endIndex", {
1639 /**
1640 * @ignore Exclude from docs
1641 * @return [description]
1642 */
1643 get: function () {
1644 return this.dataItems.length;
1645 },
1646 /**
1647 * [endIndex description]
1648 *
1649 * @ignore Exclude from docs
1650 * @todo Description
1651 * @param value [description]
1652 */
1653 set: function (value) {
1654 },
1655 enumerable: true,
1656 configurable: true
1657 });
1658 /**
1659 * Returns a formatted label based on position.
1660 *
1661 * Individual axis types should override this method to generate a label
1662 * that is relevant to axis type.
1663 *
1664 * Please note that `position` represents position within axis which may be
1665 * zoomed and not correspond to Cursor's `position`.
1666 *
1667 * To convert Cursor's `position` to Axis' `position` use `toAxisPosition()` method.
1668 *
1669 * @see {@link https://www.amcharts.com/docs/v4/tutorials/tracking-cursors-position-via-api/#Tracking_Cursor_s_position} For more information about cursor tracking.
1670 * @param position Relative position on axis (0-1)
1671 * @return Position label
1672 */
1673 Axis.prototype.getPositionLabel = function (position) {
1674 return Math.round(position * 100) + "%x";
1675 };
1676 Object.defineProperty(Axis.prototype, "chart", {
1677 /**
1678 * @return Chart
1679 */
1680 get: function () {
1681 return this._chart;
1682 },
1683 /**
1684 * A Chart this Axis belongs to.
1685 *
1686 * @param value Chart
1687 */
1688 set: function (value) {
1689 this._chart = value;
1690 },
1691 enumerable: true,
1692 configurable: true
1693 });
1694 /**
1695 * Creates a data item for a Series range.
1696 *
1697 * @param series Target Series
1698 * @return Range data item
1699 */
1700 Axis.prototype.createSeriesRange = function (series) {
1701 var range = this.axisRanges.create();
1702 range.component = this;
1703 range.axisFill = this.renderer.axisFills.template.clone();
1704 range.axisFill.disabled = false;
1705 range.axisFill.fillOpacity = 0;
1706 range.grid = this.renderer.grid.template.clone();
1707 range.grid.disabled = true;
1708 range.tick = this.renderer.ticks.template.clone();
1709 range.tick.disabled = true;
1710 range.label = this.renderer.labels.template.clone();
1711 range.label.disabled = true;
1712 range.addDisposer(new Disposer(function () {
1713 series.axisRanges.removeValue(range);
1714 }));
1715 series.axisRanges.push(range);
1716 return range;
1717 };
1718 /**
1719 * Copies all properties and related data from a different instance of Axis.
1720 *
1721 * @param source Source Axis
1722 */
1723 Axis.prototype.copyFrom = function (source) {
1724 _super.prototype.copyFrom.call(this, source);
1725 if (this.renderer) {
1726 this.renderer.copyFrom(source.renderer);
1727 }
1728 else {
1729 if (source.renderer) {
1730 this.renderer = source.renderer.clone();
1731 this._disposers.push(this.renderer);
1732 }
1733 }
1734 if (source.title) {
1735 if (!this.title) {
1736 this.title = source.title.clone();
1737 this.title.parent = this;
1738 }
1739 else {
1740 this.title.copyFrom(source.title);
1741 }
1742 this._disposers.push(this.title);
1743 }
1744 };
1745 /**
1746 * Resets internal iterator.
1747 */
1748 Axis.prototype.resetIterators = function () {
1749 this._dataItemsIterator.reset();
1750 };
1751 /**
1752 * Processes JSON-based config before it is applied to the object.
1753 *
1754 * @ignore Exclude from docs
1755 * @param config Config
1756 */
1757 Axis.prototype.processConfig = function (config) {
1758 if (config) {
1759 // Set up axis ranges
1760 if ($type.hasValue(config.axisRanges) && $type.isArray(config.axisRanges)) {
1761 for (var i = 0, len = config.axisRanges.length; i < len; i++) {
1762 var range = config.axisRanges[i];
1763 // If `series` is set, we know it's a series range
1764 if ($type.hasValue(range["series"])) {
1765 if ($type.isString(range["series"])) {
1766 if (this.map.hasKey(range["series"])) {
1767 //range["series"] = this.map.getKey(range["series"]);
1768 config.axisRanges[i] = this.createSeriesRange(this.map.getKey(range["series"]));
1769 delete (range["series"]);
1770 config.axisRanges[i].config = range;
1771 }
1772 }
1773 }
1774 }
1775 }
1776 }
1777 _super.prototype.processConfig.call(this, config);
1778 };
1779 /**
1780 * Ordering function used in JSON setup.
1781 *
1782 * @param a Item A
1783 * @param b Item B
1784 * @return Order
1785 */
1786 Axis.prototype.configOrder = function (a, b) {
1787 if (a == b) {
1788 return 0;
1789 }
1790 // last
1791 else if (a == "title") {
1792 return 1;
1793 }
1794 else if (b == "title") {
1795 return -1;
1796 }
1797 // first
1798 else if (a == "component") {
1799 return -1;
1800 }
1801 else if (b == "component") {
1802 return 1;
1803 }
1804 else {
1805 return _super.prototype.configOrder.call(this, a, b);
1806 }
1807 };
1808 Object.defineProperty(Axis.prototype, "startLocation", {
1809 /**
1810 * @return Location (0-1)
1811 */
1812 get: function () {
1813 return this.getPropertyValue("startLocation");
1814 },
1815 /**
1816 * Axis start location. Works on Date/Category axis, doesn't work on Value axis.
1817 *
1818 * * 0 - Full first cell is shown.
1819 * * 0.5 - Half of first cell is shown.
1820 * * 1 - None of the first cell is visible. (you probably don't want that)
1821 *
1822 * @param value Location (0-1)
1823 */
1824 set: function (value) {
1825 this.setPropertyValue("startLocation", value, true);
1826 },
1827 enumerable: true,
1828 configurable: true
1829 });
1830 Object.defineProperty(Axis.prototype, "endLocation", {
1831 /**
1832 * @return Location (0-1)
1833 */
1834 get: function () {
1835 return this.getPropertyValue("endLocation");
1836 },
1837 /**
1838 * Axis end location. Works on Date/Category axis, doesn't work on Value axis.
1839 *
1840 * * 0 - None of the last cell is shown. (don't do that)
1841 * * 0.5 - Half of the last cell is shown.
1842 * * 1 - Full last cell is shown.
1843 *
1844 * @param value Location (0-1)
1845 */
1846 set: function (value) {
1847 this.setPropertyValue("endLocation", value, true);
1848 },
1849 enumerable: true,
1850 configurable: true
1851 });
1852 Axis.prototype.setDisabled = function (value) {
1853 var changed = _super.prototype.setDisabled.call(this, value);
1854 if (this.renderer) {
1855 this.renderer.gridContainer.disabled = value;
1856 }
1857 return changed;
1858 };
1859 Object.defineProperty(Axis.prototype, "title", {
1860 /**
1861 * @return Title label
1862 */
1863 get: function () {
1864 return this._title;
1865 },
1866 /**
1867 * A reference to a [[Label]] element which serves as a title to the axis.
1868 *
1869 * When axis is created it aleready has an element, so you can just modify
1870 * it.
1871 *
1872 * Or you can replace it with your own instance of `Label`.
1873 *
1874 * @param value Title label
1875 */
1876 set: function (value) {
1877 if (this._title && this._title != value) {
1878 this._title.dispose();
1879 }
1880 if (value) {
1881 this._title = value;
1882 value.parent = this;
1883 value.shouldClone = false;
1884 }
1885 },
1886 enumerable: true,
1887 configurable: true
1888 });
1889 Object.defineProperty(Axis.prototype, "hideTooltipWhileZooming", {
1890 /**
1891 * @return Hide tooltip while zooming?
1892 */
1893 get: function () {
1894 return this.getPropertyValue("hideTooltipWhileZooming");
1895 },
1896 /**
1897 * Indicates if axis' tooltip should be hidden while axis range is animating
1898 * (zooming)
1899 *
1900 * @default true
1901 * @since 4.7.16
1902 * @param value Hide tooltip while zooming?
1903 */
1904 set: function (value) {
1905 this.setPropertyValue("hideTooltipWhileZooming", value);
1906 },
1907 enumerable: true,
1908 configurable: true
1909 });
1910 Object.defineProperty(Axis.prototype, "zoomable", {
1911 /**
1912 * @return Zoomable?
1913 */
1914 get: function () {
1915 return this.getPropertyValue("zoomable");
1916 },
1917 /**
1918 * Should the axis be zoomed with scrollbar/cursor?
1919 *
1920 * @default true
1921 * @since 4.9.28
1922 * @param value Zoomable?
1923 */
1924 set: function (value) {
1925 this.setPropertyValue("zoomable", value);
1926 },
1927 enumerable: true,
1928 configurable: true
1929 });
1930 return Axis;
1931}(Component));
1932export { Axis };
1933/**
1934 * Register class in system, so that it can be instantiated using its name from
1935 * anywhere.
1936 *
1937 * @ignore
1938 */
1939registry.registeredClasses["Axis"] = Axis;
1940registry.registeredClasses["AxisDataItem"] = AxisDataItem;
1941/**
1942 * Add default responsive rules
1943 */
1944/**
1945 * Disable axis tooltips.
1946 */
1947defaultRules.push({
1948 relevant: ResponsiveBreakpoints.maybeXS,
1949 state: function (target, stateId) {
1950 if (target instanceof Axis && target.tooltip) {
1951 var state = target.states.create(stateId);
1952 state.properties.cursorTooltipEnabled = false;
1953 return state;
1954 }
1955 return null;
1956 }
1957});
1958//# sourceMappingURL=Axis.js.map
\No newline at end of file