@amcharts/amcharts4
Version:
amCharts 4
1,426 lines (1,425 loc) • 68 kB
JavaScript
/**
* Base class for all Axis
*/
import { __extends } from "tslib";
/**
* ============================================================================
* IMPORTS
* ============================================================================
* @hidden
*/
import { Component } from "../../core/Component";
import { Container } from "../../core/Container";
import { DataItem } from "../../core/DataItem";
import { AxisBreak } from "./AxisBreak";
import { Label } from "../../core/elements/Label";
import { Tooltip } from "../../core/elements/Tooltip";
import { SortedListTemplate } from "../../core/utils/SortedList";
import { List, ListTemplate, ListDisposer } from "../../core/utils/List";
import { Disposer, MultiDisposer } from "../../core/utils/Disposer";
import { registry } from "../../core/Registry";
import { InterfaceColorSet } from "../../core/utils/InterfaceColorSet";
import * as $iter from "../../core/utils/Iterator";
import * as $math from "../../core/utils/Math";
import * as $utils from "../../core/utils/Utils";
import * as $number from "../../core/utils/Number";
import * as $array from "../../core/utils/Array";
import * as $type from "../../core/utils/Type";
import { defaultRules, ResponsiveBreakpoints } from "../../core/utils/Responsive";
/**
* ============================================================================
* DATA ITEM
* ============================================================================
* @hidden
*/
/**
* Defines a [[DataItem]] for [[Axis]].
*
* @see {@link DataItem}
*/
var AxisDataItem = /** @class */ (function (_super) {
__extends(AxisDataItem, _super);
/**
* Constructor
*/
function AxisDataItem() {
var _this = _super.call(this) || this;
_this.className = "AxisDataItem";
_this.applyTheme();
return _this;
}
Object.defineProperty(AxisDataItem.prototype, "grid", {
/**
* @return Grid element
*/
get: function () {
if (!this._grid) {
var component_1 = this.component;
if (component_1) {
var template = void 0;
var grid_1;
if (this.isRange) {
template = component_1.axisRanges.template.grid;
if (template.disabled) {
return;
}
else {
grid_1 = template.clone();
}
}
else {
template = component_1.renderer.grid.template;
if (template.disabled) {
return;
}
else {
grid_1 = component_1.renderer.grid.create();
this._disposers.push(new Disposer(function () {
component_1.renderer.grid.removeValue(grid_1);
}));
}
}
this.grid = grid_1;
grid_1.shouldClone = false;
this._disposers.push(grid_1);
grid_1.axis = this.component;
}
}
return this._grid;
},
/**
* A [[Grid]] element associated with this data item.
*
* If there is no grid element associated with data item, a new one is
* created and returned.
*
* @param grid Grid element
*/
set: function (grid) {
if (this._grid && this._grid != grid) {
$array.remove(this.sprites, this._grid);
this._grid.dataItem = undefined;
}
if (grid) {
if (grid.dataItem && grid.dataItem != this) {
$array.remove(grid.dataItem.sprites, grid);
grid.dataItem.grid = undefined;
}
this.addSprite(grid);
}
this._grid = grid;
},
enumerable: true,
configurable: true
});
Object.defineProperty(AxisDataItem.prototype, "tick", {
/**
* @return Tick element
*/
get: function () {
if (!this._tick) {
var component_2 = this.component;
if (component_2) {
var template = void 0;
var tick_1;
if (this.isRange) {
template = component_2.axisRanges.template.tick;
if (template.disabled) {
return;
}
else {
tick_1 = template.clone();
}
}
else {
template = component_2.renderer.ticks.template;
if (template.disabled) {
return;
}
else {
tick_1 = component_2.renderer.ticks.create();
this._disposers.push(new Disposer(function () {
component_2.renderer.ticks.removeValue(tick_1);
}));
}
}
this.tick = tick_1;
tick_1.axis = this.component;
tick_1.shouldClone = false;
this._disposers.push(tick_1);
}
}
return this._tick;
},
/**
* An [[AxisTick]] element associated with this data item.
*
* If there is no tick element associated with data item, a new one is
* created and returned.
*
* @param tick Tick element
*/
set: function (tick) {
if (this._tick && this._tick != tick) {
$array.remove(this.sprites, this._tick);
this._tick.dataItem = undefined;
}
if (tick) {
if (tick.dataItem && tick.dataItem != this) {
$array.remove(tick.dataItem.sprites, tick);
tick.dataItem.tick = undefined;
}
this.addSprite(tick);
}
this._tick = tick;
},
enumerable: true,
configurable: true
});
Object.defineProperty(AxisDataItem.prototype, "label", {
/**
* @return Label element
*/
get: function () {
if (!this._label) {
var component_3 = this.component;
if (component_3) {
var template = void 0;
var label_1;
if (this.isRange) {
template = component_3.axisRanges.template.label;
if (template.disabled) {
return;
}
else {
label_1 = template.clone();
}
}
else {
template = component_3.renderer.labels.template;
if (template.disabled) {
return;
}
else {
label_1 = component_3.renderer.labels.create();
this._disposers.push(new Disposer(function () {
component_3.renderer.labels.removeValue(label_1);
}));
}
}
this._disposers.push(label_1);
this.label = label_1;
label_1.shouldClone = false;
label_1.axis = this.component;
label_1.virtualParent = component_3;
}
}
return this._label;
},
/**
* An [[AxisLabel]] element associated with this data item.
*
* If there is no label element associated with data item, a new one is
* created and returned.
*
* @param label Label element
*/
set: function (label) {
if (this._label && this._label != label) {
$array.remove(this.sprites, this._label);
this._label.dataItem = undefined;
}
if (label) {
if (label.dataItem && label.dataItem != this) {
$array.remove(label.dataItem.sprites, label);
label.dataItem.label = undefined;
}
this.addSprite(label);
}
this._label = label;
},
enumerable: true,
configurable: true
});
Object.defineProperty(AxisDataItem.prototype, "axisFill", {
/**
* @return Label element
*/
get: function () {
if (!this._axisFill) {
var component_4 = this.component;
if (component_4) {
var template = void 0;
var axisFill_1;
if (this.isRange) {
template = component_4.axisRanges.template.axisFill;
if (!this.isTemplate && template.disabled) {
return;
}
else {
axisFill_1 = template.clone();
}
}
else {
template = component_4.renderer.axisFills.template;
if (template.disabled) {
return;
}
else {
axisFill_1 = component_4.renderer.axisFills.create();
this._disposers.push(new Disposer(function () {
component_4.renderer.axisFills.removeValue(axisFill_1);
}));
}
}
this.axisFill = axisFill_1;
axisFill_1.shouldClone = false;
this._disposers.push(axisFill_1);
}
}
return this._axisFill;
},
/**
* An [[AxisFill]] associated element with this data item.
*
* If there is no fill element associated with data item, a new one is
* created and returned.
*
* @param label Label element
*/
set: function (axisFill) {
if (this._axisFill && this._axisFill != axisFill) {
$array.remove(this.sprites, this._axisFill);
this._axisFill.dataItem = undefined;
}
if (axisFill) {
if (axisFill.dataItem && axisFill.dataItem != this) {
$array.remove(axisFill.dataItem.sprites, axisFill);
axisFill.dataItem.axisFill = undefined;
}
axisFill.axis = this.component;
this.addSprite(axisFill);
}
this._axisFill = axisFill;
},
enumerable: true,
configurable: true
});
Object.defineProperty(AxisDataItem.prototype, "text", {
/**
* @return Text label
*/
get: function () {
return this._text;
},
/**
* Text to be used as data item's label.
*
* @param text Text label
*/
set: function (text) {
this._text = text;
if (this._label) { // do not use getter, it will create unwanted instances!
this._label.text = text;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(AxisDataItem.prototype, "mask", {
/**
* Data item's mask.
*
* @return Mask
*/
get: function () {
return this._mask;
},
enumerable: true,
configurable: true
});
Object.defineProperty(AxisDataItem.prototype, "contents", {
/**
* Returns a [[Container]] to place all visual elements, related to data item
* in.
*
* If there is no Container, a new one is created.
*
* @return Contents container
*/
get: function () {
if (!this._contents) {
var contents = new Container();
this.addSprite(contents);
contents.isMeasured = false;
this._contents = contents;
var component = this.component;
if (component) {
var mask = component.renderer.createFill(this.component);
mask.disabled = false;
mask.axis = component;
this.addSprite(mask);
this._mask = mask;
contents.mask = mask;
}
}
return this._contents;
},
enumerable: true,
configurable: true
});
Object.defineProperty(AxisDataItem.prototype, "axisBreak", {
/**
* @return Axis break
*/
get: function () {
return this._axisBreak;
},
/**
* An [[AxisBreak]] this data item falls within.
*
* @param axisBreak Axis break
*/
set: function (axisBreak) {
if (this._axisBreak) {
this._axisBreak.dataItems.removeValue(this);
}
if (axisBreak) {
axisBreak.dataItems.push(this);
}
this._axisBreak = axisBreak;
},
enumerable: true,
configurable: true
});
/**
* Re-draws the element.
*
* @ignore Exclude from docs
*/
AxisDataItem.prototype.validate = function () {
if (this.component) {
this.component.validateDataElement(this);
}
};
/**
* Appends data item's elements to the parent [[Container]].
*
* @ignore Exclude from docs
*/
AxisDataItem.prototype.appendChildren = function () {
if (this.component) {
this.component.appendDataItem(this);
}
};
/**
* Checks if data item has particular property set.
*
* @param prop Property name
* @return Property set?
*/
AxisDataItem.prototype.hasProperty = function (prop) {
return prop == "component" ? true : _super.prototype.hasProperty.call(this, prop);
};
/**
* Copies all parameters from another [[AxisDataItem]].
*
* @param source Source AxisDataItem
*/
AxisDataItem.prototype.copyFrom = function (source) {
_super.prototype.copyFrom.call(this, source);
this.text = source.text;
if (source.bullet) {
this.bullet = source.bullet.clone();
}
this.minPosition = source.minPosition;
this.maxPosition = source.maxPosition;
};
/**
* Sets visibility of the Data Item.
*
* @param value Data Item
*/
AxisDataItem.prototype.setVisibility = function (value, noChangeValues) {
_super.prototype.setVisibility.call(this, value, noChangeValues);
if (this._contents) {
this._contents.visible = value;
}
};
Object.defineProperty(AxisDataItem.prototype, "bullet", {
/**
* @return Bullet
*/
get: function () {
return this._bullet;
},
/**
* Set it to an instance of any [[Sprite]]. It will be displayed as an axis
* bullet in the middle of the cell, or specific value.
*
* If you need position bullet relatively to the cell, use [[AxisBullet]]
* instead. It has a `location` property which can be used to indicate
* precise relative location within cell/range.
*
* Also, [[AxisBullet]] is a [[Container]] so you can push any other element
* into it.
*
* NOTE: `location` is relative to the parent axis range's scope, i.e.
* between its `date` and `endDate` for [[DateAxis]], or `value`/`endValue`
* ([[ValueAxis]]), or `category`/`endCategory` ([[categoryAxis]]).
*
* ```TypeScript
* let range = dateAxis.axisRanges.create();
* range.date = new Date(2018, 0, 5);
*
* let flag = new am4plugins_bullets.FlagBullet();
* flag.label.text = "Hello";
*
* range.bullet = flag;
* ```
* ```JavaScript
* var range = dateAxis.axisRanges.create();
* range.date = new Date(2018, 0, 5);
*
* var flag = new am4plugins_bullets.FlagBullet();
* flag.label.text = "Hello";
*
* range.bullet = flag;
* ```
* ```JSON
* {
* // ...
* "xAxes": [{
* "type": "DateAxis",
* // ...
* "axisRanges": [{
* "date": new Date(2018, 0, 5),
* "bullet: {
* "type": "FlagBullet",
* "label": {
* "text": "Hello"
* }
* }
* }]
* }]
* }
* ```
*
* @since 4.5.9
* @param value Bullet
*/
set: function (value) {
if (this._bullet && this._bullet != value) {
$array.remove(this.sprites, this._bullet);
this._bullet.dataItem = undefined;
}
this._bullet = value;
if (value) {
this.addSprite(value);
}
},
enumerable: true,
configurable: true
});
return AxisDataItem;
}(DataItem));
export { AxisDataItem };
/**
* ============================================================================
* REQUISITES
* ============================================================================
* @hidden
*/
/**
* Defines named positions for data item's location within [[Axis]].
*/
export var AxisItemLocation;
(function (AxisItemLocation) {
AxisItemLocation[AxisItemLocation["Start"] = 0] = "Start";
AxisItemLocation[AxisItemLocation["Middle"] = 0.5] = "Middle";
AxisItemLocation[AxisItemLocation["End"] = 1] = "End";
})(AxisItemLocation || (AxisItemLocation = {}));
/**
* ============================================================================
* MAIN CLASS
* ============================================================================
* @hidden
*/
/**
* A base class for all Axis elements.
*
* @see {@link IAxisEvents} for a list of available Events
* @see {@link IAxisAdapters} for a list of available Adapters
*/
var Axis = /** @class */ (function (_super) {
__extends(Axis, _super);
/**
* Constructor
*/
function Axis() {
var _this =
// Init
_super.call(this) || this;
/**
* Number of Grid elements on the axis.
*/
_this._gridCount = 10;
/**
* A list of [[XYSeries]] that are using this Axis.
*/
_this._series = new List();
/**
* Specifies if axis should be automatically disposed when removing from
* chart's axis list.
*
* @default true
*/
_this.autoDispose = true;
/**
* @ignore
*/
_this._axisItemCount = 0;
if (_this.constructor === Axis) {
throw new Error("'Axis' cannot be instantiated directly. Please use a specific axis type.");
}
_this.hideTooltipWhileZooming = true;
_this.minWidth = 0.0001;
_this.minHeight = 0.0001;
_this.className = "Axis";
_this.shouldClone = false;
_this.setPropertyValue("cursorTooltipEnabled", true);
_this.toggleZoomOutButton = true;
_this.zoomable = true;
var interfaceColors = new InterfaceColorSet();
// Create title
_this.title = new Label();
_this.title.shouldClone = false;
_this._disposers.push(_this.title);
_this.setPropertyValue("startLocation", 0);
_this.setPropertyValue("endLocation", 1);
// Data item iterator
_this._dataItemsIterator = new $iter.ListIterator(_this.dataItems, function () { return _this.dataItems.create(); });
_this._dataItemsIterator.createNewItems = true;
// Create tooltip
var tooltip = new Tooltip();
_this._disposers.push(tooltip);
tooltip.label.padding(5, 10, 5, 10);
tooltip.background.pointerLength = 5;
tooltip.fitPointerToBounds = true;
tooltip.background.filters.clear();
// Set virtual parentfor the tooltip so that it can properly inheirt
// formatters from the axis.
tooltip.virtualParent = _this;
// Create background element for the tooltip
var background = tooltip.background;
background.cornerRadius = 0;
background.fill = interfaceColors.getFor("alternativeBackground");
background.stroke = background.fill;
background.strokeWidth = 1;
background.fillOpacity = 1;
tooltip.label.fill = interfaceColors.getFor("alternativeText");
_this.tooltip = tooltip;
// Accessibility
_this.readerHidden = true;
_this.events.on("rangechangestarted", function () {
_this.series.each(function (series) {
if (series.hideTooltipWhileZooming) {
series.tooltip.hide();
series.tooltip.preventShow = true;
}
});
if (_this.hideTooltipWhileZooming) {
_this.tooltip.hide();
_this.tooltip.preventShow = true;
}
}, undefined, false);
_this.events.on("rangechangeended", function () {
_this.series.each(function (series) {
if (series.hideTooltipWhileZooming) {
series.tooltip.hide();
series.tooltip.preventShow = false;
}
});
if (_this.hideTooltipWhileZooming) {
_this.tooltip.hide();
_this.tooltip.preventShow = false;
}
}, undefined, false);
_this.applyTheme();
return _this;
}
/**
* Holds reference to a function that accepts a DataItem and its index as
* parameters.
*
* It can either return a fill opacity for a fill, or manipulate data item
* directly, to create various highlighting scenarios.
*
* For example, you can set it up to highlight only weekends on a
* [[DateAxis]].
*/
Axis.prototype.fillRule = function (dataItem, index) {
if (!$type.isNumber(index)) {
index = dataItem.index;
}
if (index / 2 == Math.round(index / 2)) {
dataItem.axisFill.__disabled = true;
dataItem.axisFill.opacity = 0;
}
else {
dataItem.axisFill.opacity = 1;
dataItem.axisFill.__disabled = false;
}
};
/**
* Returns a new/empty DataItem of the type appropriate for this object.
*
* @see {@link DataItem}
* @return Data Item
*/
Axis.prototype.createDataItem = function () {
return new AxisDataItem();
};
/**
* Invalidates layout.
*
* @ignore Exclude from docs
*/
Axis.prototype.invalidateLayout = function () {
_super.prototype.invalidateLayout.call(this);
// 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%
$iter.each(this.series.iterator(), function (series) {
series.invalidateLayout();
});
};
/**
* Invalidates series of this axis.
*/
Axis.prototype.invalidateSeries = function () {
// 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%
$iter.each(this.series.iterator(), function (series) {
series.invalidate();
});
};
/**
* Override to cancel super call for data element validation.
* @ignore
*/
Axis.prototype.validateDataElements = function () {
this._axisItemCount = 0;
if (this.ghostLabel) {
this.renderer.updateLabelElement(this.ghostLabel, this.start, this.end);
this.ghostLabel.validate();
}
};
/**
* Recalculates the number of grid items on the axis.
*/
Axis.prototype.updateGridCount = function () {
if (this.renderer) {
var gridCount = this.axisLength / this.renderer.minGridDistance;
if (gridCount != this._gridCount) {
this._gridCount = gridCount;
this.clearCache();
}
}
};
/**
* Redraws the element.
*
* @ignore Exclude from docs
*/
Axis.prototype.validateLayout = function () {
this.axisFullLength = this.axisLength / (this.end - this.start);
_super.prototype.validateLayout.call(this);
this.updateGridCount();
var renderer = this.renderer;
if (renderer) {
renderer.updateAxisLine();
renderer.updateTooltip();
renderer.updateBaseGridElement();
}
if (this._prevLength != this.axisLength) {
this.dispatchImmediately("lengthchanged");
this._prevLength = this.axisLength;
}
};
/**
* Initializes Axis' renderer.
*
* @ignore Exclude from docs
*/
Axis.prototype.initRenderer = function () {
};
/**
* Adds a data item to the Axis.
*
* @param dataItem Data item
*/
Axis.prototype.appendDataItem = function (dataItem) {
var renderer = this.renderer;
var tick = dataItem.tick;
if (tick) {
if (tick.above) {
tick.parent = renderer.bulletsContainer;
}
else {
tick.parent = renderer.gridContainer;
}
}
if (dataItem.label) {
dataItem.label.parent = renderer;
}
var axisFill = dataItem.axisFill;
if (axisFill) {
if (axisFill.above) {
axisFill.parent = renderer.bulletsContainer;
}
else {
axisFill.parent = renderer.gridContainer;
}
}
var grid = dataItem.grid;
if (grid) {
if (grid.above) {
grid.parent = renderer.bulletsContainer;
}
else {
grid.parent = renderer.gridContainer;
}
}
if (dataItem.bullet) {
dataItem.bullet.parent = renderer.bulletsContainer;
}
};
/**
* Redraws Axis' related items.
*
* @ignore Exclude from docs
*/
Axis.prototype.validate = function () {
_super.prototype.validate.call(this);
this.validateLayout();
this.renderer.updateGridContainer();
};
/**
* Redars Axis ranges.
*
* @ignore Exclude from docs
*/
Axis.prototype.validateAxisRanges = function () {
var _this = this;
$iter.each(this.axisRanges.iterator(), function (axisRange) {
_this.appendDataItem(axisRange);
_this.validateDataElement(axisRange);
if (axisRange.grid) {
axisRange.grid.validate();
}
if (axisRange.tick) {
axisRange.tick.validate();
}
if (axisRange.axisFill) {
axisRange.axisFill.validate();
}
if (axisRange.label) {
axisRange.label.validate();
}
});
};
/**
* Invalidates all axis breaks, so they are redrawn.
*
* @ignore Exclude from docs
*/
Axis.prototype.validateBreaks = function () {
if (this._axisBreaks) {
$iter.each(this._axisBreaks.iterator(), function (axisBreak) {
axisBreak.invalidate();
});
}
};
/**
* Associates an Axis break with this Axis, after it is inserted into
* `axisBreaks`.
*
* @ignore Exclude from docs
* @param event Event
*/
Axis.prototype.processBreak = function (event) {
var axisBreak = event.newValue;
axisBreak.parent = this.renderer.breakContainer;
axisBreak.axis = this;
};
/**
* Registers a [[XYSeries]] element with this Axis.
*
* Returns a [[Disposer]] for all events, added to Series for watching
* changes in Axis, and vice versa.
* @ignore
* @param series Series
* @return Event disposer
*/
Axis.prototype.registerSeries = function (series) {
var _this = this;
this.series.moveValue(series);
return new MultiDisposer([
new Disposer(function () {
_this.series.removeValue(series);
}),
this.events.on("lengthchanged", series.invalidate, series, false),
this.events.on("lengthchanged", series.createMask, series, false),
this.events.on("startchanged", series.invalidate, series, false),
this.events.on("endchanged", series.invalidate, series, false),
]);
};
Object.defineProperty(Axis.prototype, "renderer", {
/**
* @return Renderer
*/
get: function () {
return this._renderer;
},
/**
* An [[AxisRenderer]] to be used to render this Axis.
*
* Please note that most of the settings, related to Axis' appearance are set
* via its renderer. Not directly on the Axis.
*
* E.g.:
*
* ```TypeScript
* axis.renderer.inside = true;
* axis.renderer.minLabelPosition = 0.1;
* axis.renderer.maxLabelPosition = 0.9;
* ```
* ```JavaScript
* axis.renderer.inside = true;
* axis.renderer.minLabelPosition = 0.1;
* axis.renderer.maxLabelPosition = 0.9;
* ```
*
* @see {@link https://www.amcharts.com/docs/v4/concepts/axes/} for more info
* @param renderer Renderer
*/
set: function (renderer) {
if (renderer != this._renderer) {
this._renderer = renderer;
renderer.chart = this.chart;
renderer.axis = this;
renderer.parent = this;
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
this.initRenderer();
this._disposers.push(renderer.gridContainer.events.on("maxsizechanged", this.invalidate, this, false));
var ghostLabel_1 = this.renderer.labels.create();
this._disposers.push(ghostLabel_1);
ghostLabel_1.dataItem = this.dataItems.template.clone(); // just for the adapters not to fail
ghostLabel_1.text = "L";
ghostLabel_1.parent = this.renderer;
ghostLabel_1.shouldClone = false;
ghostLabel_1.fillOpacity = 0;
ghostLabel_1.opacity = 0;
ghostLabel_1.strokeOpacity = 0;
ghostLabel_1.interactionsEnabled = false;
ghostLabel_1.validate();
this.ghostLabel = ghostLabel_1;
this.events.on("beforedatavalidated", function () {
ghostLabel_1.text = "L";
}, undefined, false);
}
},
enumerable: true,
configurable: true
});
/**
* Converts a relative position to angle. (for circular axes)
*
* @param position Position (0-1)
* @return Angle
*/
Axis.prototype.positionToAngle = function (position) {
return this.renderer.positionToAngle(position);
};
/**
* Converts pixel coordinates to a relative position. (0-1)
*
* @param point Coorinates (px)
* @return Position (0-1)
*/
Axis.prototype.pointToPosition = function (point) {
return this.renderer.pointToPosition(point);
};
/**
* Converts relative position to coordinate.
*
* @since 4.7.15
* @param position (0-1)
* @return coordinate (px)
*/
Axis.prototype.positionToCoordinate = function (position) {
return this.renderer.positionToCoordinate(position);
};
/**
* [getAnyRangePath description]
*
* @ignore Exclude from docs
* @todo Description
* @param start [description]
* @param end [description]
* @return [description]
*/
Axis.prototype.getAnyRangePath = function (start, end) {
return this.renderer.getPositionRangePath(start, end);
};
/**
* Converts any positional parameter to a relative position on axis.
*
* @todo Description (review)
* @param value Pisition
* @return Position (0-1)
*/
Axis.prototype.anyToPosition = function (value) {
return 0;
};
/**
* Converts any positional parameter to a relative position on axis.
*
* @todo Description (review)
* @param value Pisition
* @return Orientation point
*/
Axis.prototype.anyToPoint = function (value) {
return { x: 0, y: 0, angle: 0 };
};
/**
* [getPositionRangePath description]
*
* @ignore Exclude from docs
* @todo Description
* @param startPosition [description]
* @param endPosition [description]
* @return [description]
*/
Axis.prototype.getPositionRangePath = function (startPosition, endPosition) {
if (this.renderer) {
return this.renderer.getPositionRangePath(startPosition, endPosition);
}
return "";
};
Object.defineProperty(Axis.prototype, "axisLength", {
/**
* Actual axis length in pixels.
*
* @return Axis length (px)
*/
get: function () {
if (this.renderer) {
return this.renderer.axisLength;
}
return 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Axis.prototype, "cursorTooltipEnabled", {
/**
* @return Display tooltip?
*/
get: function () {
return this.getPropertyValue("cursorTooltipEnabled");
},
/**
* Indicates if axis should display a tooltip for chart's cursor.
*
* @param value Display tooltip?
*/
set: function (value) {
if (this.setPropertyValue("cursorTooltipEnabled", value)) {
if (value && this.renderer) {
this.renderer.updateTooltip();
}
else if (this.tooltip) {
this.tooltip.hide(0);
}
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(Axis.prototype, "toggleZoomOutButton", {
/**
* @return Toggle zoom out button?
*/
get: function () {
return this.getPropertyValue("toggleZoomOutButton");
},
/**
* Normally, when axis is zoomed in, a zoom out button is shown by a chart,
* and vice versa: when axis is zoomed out completely, zoom out button is
* hidden.
*
* Setting this to `false` will disable this behavior. Zooming in our out
* this axis will not reveal or hide zoom out button.
*
* @default true
* @since 4.6.2
* @param value Toggle zoom out button?
*/
set: function (value) {
this.setPropertyValue("toggleZoomOutButton", value);
},
enumerable: true,
configurable: true
});
/**
* Hides element's [[Tooltip]].
*
* @see {@link Tooltip}
*/
Axis.prototype.hideTooltip = function (duration) {
_super.prototype.hideTooltip.call(this, duration);
this._tooltipPosition = undefined;
};
/**
* Shows Axis tooltip at specific relative position within Axis. (0-1)
*
* @param position Position (0-1)
* @param local or global position
*/
Axis.prototype.showTooltipAtPosition = function (position, local) {
var tooltip = this._tooltip;
if (!tooltip || this.dataItems.length <= 0) {
this._tooltipPosition = undefined;
}
else {
if (!local) {
position = this.toAxisPosition(position);
}
if (!$type.isNumber(position) || position < this.start || position > this.end) {
tooltip.hide(0);
this._tooltipPosition = undefined;
return;
}
var renderer = this.renderer;
//@todo: think of how to solve this better
if (!tooltip.parent) {
tooltip.parent = this.tooltipContainer;
}
var tooltipLocation = renderer.tooltipLocation;
var startPosition = this.getCellStartPosition(position);
var endPosition = this.getCellEndPosition(position);
if (this.tooltipPosition == "fixed") {
position = startPosition + (endPosition - startPosition) * tooltipLocation;
}
position = $math.fitToRange(position, this.start, this.end);
if (this._tooltipPosition != position) {
this._tooltipPosition = position;
var tooltipLocation2 = renderer.tooltipLocation2;
var startPoint = renderer.positionToPoint(startPosition, tooltipLocation2);
var endPoint = renderer.positionToPoint(endPosition, tooltipLocation2);
// save values so cursor could use them
this.currentItemStartPoint = startPoint;
this.currentItemEndPoint = endPoint;
if (renderer.fullWidthTooltip) {
tooltip.width = endPoint.x - startPoint.x;
tooltip.height = endPoint.y - startPoint.y;
}
var point = renderer.positionToPoint(position, tooltipLocation2);
var globalPoint = $utils.spritePointToSvg(point, this.renderer.line);
tooltip.text = this.getTooltipText(position);
if (tooltip.text) {
tooltip.delayedPointTo(globalPoint);
tooltip.show();
}
}
if (!this.cursorTooltipEnabled || this.tooltip.disabled) {
tooltip.hide(0);
}
}
};
/**
* Converts relative position (0-1) to Axis position with zoom level and
* inversed taken into account.
*
* @param position Global position (0-1)
* @return Position within Axis (0-1)
*/
Axis.prototype.toAxisPosition = function (position) {
position = this.renderer.toAxisPosition(position);
if (position == undefined) {
return;
}
position = position * (this.end - this.start);
if (this.renderer.inversed) {
position = this.end - position;
}
else {
position = this.start + position;
}
return position;
};
/**
* Converts position on the axis with zoom level and
* inversed taken into account to global position.
*
* @param position Axis position (0-1)
* @return Global position (0-1)
*/
Axis.prototype.toGlobalPosition = function (position) {
if (this.renderer.inversed) {
position = this.end - position;
}
else {
position = position - this.start;
}
return position / (this.end - this.start);
};
/**
* Returns text to be used for cursor's Axis tooltip.
*
* This is a placeholder to override for extending classes.
*
* @ignore Exclude from docs
* @param position Position coordinate (px)
* @return Label text
*/
Axis.prototype.getTooltipText = function (position) {
return;
};
/**
* Updates Axis' tooltip's position and possibly size, and pointer (stem)
* place.
*
* @ignore Exclude from docs
* @param pointerOrientation Pointer (stem) orientation
* @param boundingRectangle A rectangle for tooltip to fit within
*/
Axis.prototype.updateTooltip = function (pointerOrientation, boundingRectangle) {
var tooltip = this._tooltip;
if (tooltip) {
tooltip.fixDoc = false;
tooltip.pointerOrientation = pointerOrientation;
tooltip.setBounds($utils.spriteRectToSvg(boundingRectangle, this.renderer.line));
}
};
/**
* [roundPosition description]
*
* @ignore Exclude from docs
* @todo Description
* @param position Relative position
* @param location Location on axis
* @return Rounded position
*/
Axis.prototype.roundPosition = function (position, location, axisLocation) {
return position;
};
/**
* [getCellStartPosition description]
*
* @ignore Exclude from docs
* @todo Description
* @param position [description]
* @return [description]
*/
Axis.prototype.getCellStartPosition = function (position) {
return position;
};
/**
* [getCellEndPosition description]
*
* @ignore Exclude from docs
* @todo Description
* @param position [description]
* @return [description]
*/
Axis.prototype.getCellEndPosition = function (position) {
return position;
};
Object.defineProperty(Axis.prototype, "axisRanges", {
/**
* A list of axis ranges for this Axis.
*
* @return Axis ranges
*/
get: function () {
if (!this._axisRanges) {
var dataItem = this.createDataItem();
dataItem.isRange = true;
dataItem.axisFill = this.renderer.axisFills.template.clone();
dataItem.grid = this.renderer.grid.template.clone();
dataItem.tick = this.renderer.ticks.template.clone();
dataItem.label = this.renderer.labels.template.clone();
dataItem.isTemplate = true;
dataItem.component = this;
dataItem.axisFill.disabled = false;
dataItem.tick.disabled = false;
dataItem.grid.disabled = false;
dataItem.label.disabled = false;
this._axisRanges = new ListTemplate(dataItem);
this._axisRanges.events.on("inserted", this.processAxisRange, this, false);
this._disposers.push(new ListDisposer(this._axisRanges));
this._disposers.push(this._axisRanges.template);
}
return this._axisRanges;
},
enumerable: true,
configurable: true
});
/**
* Decorates an axis range after it has been added to the axis range list.
*
* @param event Event
*/
Axis.prototype.processAxisRange = function (event) {
var axisRange = event.newValue;
axisRange.component = this;
axisRange.isRange = true;
};
Object.defineProperty(Axis.prototype, "axisBreaks", {
/**
* A list of axis breaks on this Axis.
*
* @return Axis breaks.
*/
get: function () {
if (!this._axisBreaks) {
this._axisBreaks = new SortedListTemplate(this.createAxisBreak(), function (a, b) {
return $number.order(a.adjustedStartValue, b.adjustedStartValue);
});
this._axisBreaks.events.on("inserted", this.processBreak, this, false);
this._disposers.push(new ListDisposer(this._axisBreaks));
this._disposers.push(this._axisBreaks.template);
}
return this._axisBreaks;
},
enumerable: true,
configurable: true
});
/**
* Creates a new axis break.
*
* @return Axis break
*/
Axis.prototype.createAxisBreak = function () {
return new AxisBreak();
};
Object.defineProperty(Axis.prototype, "series", {
/**
* A list of Series currently associated with this Axis.
*
* @return Series
*/
get: function () {
if (!this._series) {
this._series = new List();
}
return this._series;
},
enumerable: true,
configurable: true
});
/**
* Processes Series' data items.
*
* This is a placeholder to override for extending classes.
*
* @ignore Exclude from docs
*/
Axis.prototype.processSeriesDataItems = function () {
};
/**
* Processes Series' single data item.
*
* This is a placeholder to override for extending classes.
*
* @ignore Exclude from docs
* @param dataItem Data item
*/
Axis.prototype.processSeriesDataItem = function (dataItem, axisLetter) {
};
/**
* Post-processes Serie's data items.
*
* This is a placeholder to override for extending classes.
*
* @ignore Exclude from docs
*/
Axis.prototype.postProcessSeriesDataItems = function (series) {
};
/**
* Post-processes Serie's single data item.
*
* This is a placeholder to override for extending classes.
*
* @ignore Exclude from docs
* @param dataItem Data item
*/
Axis.prototype.postProcessSeriesDataItem = function (dataItem) {
};
//
/**
* Updates Axis based on all Series that might influence it.
*
* Called by Series after Series data is validated.
*
* This is a placeholder to override for extending classes.
*
* @ignore Exclude from docs
*/
Axis.prototype.updateAxisBySeries = function () {
};
/**
* Hides unused data items.
*
* @ignore Exclude from docs
*/
Axis.prototype.hideUnusedDataItems = function () {
var _this = this;
// hide all unused
var dataItemsIterator = this._dataItemsIterator;
dataItemsIterator.createNewItems = false;
$iter.each(dataItemsIterator.iterator(), function (dataItem) {
_this.validateDataElement(dataItem); // solves shrinking
dataItem.__disabled = true;
});
dataItemsIterator.clear();
dataItemsIterator.createNewItems = true;
};
/**
* Returns a Series' data item that corresponds to specific position on Axis.
*
* This is a placeholder to override for extending classes.
*
* @ignore Exclude from docs
* @param series Series
* @param position Position (0-1)
* @param findNearest Should axis try to find nearest tooltip if there is no data item at exact position
* @return Data item
*/
Axis.prototype.getSeriesDataItem = function (series, position, findNearest) {
return;
};
/**
* Returns an angle that corresponds to specific position on axis.
*
* This is a placeholder to override for extending classes.
*
* @ignore Exclude from docs
* @todo Description (review)
* @param dataItem Data item
* @param key ???
* @param location Location
* @param stackKey ???
* @return Angle
*/
Axis.prototype.getAngle = function (dataItem, key, location, stackKey, range) {
return;
};
/**
* [getX description]
*
* This is a placeholder to override for extending classes.
*
* @ignore Exclude from docs
* @todo Description (review)
* @param dataItem [description]