@amcharts/amcharts4
Version:
amCharts 4
547 lines • 21.7 kB
JavaScript
/**
* Module, defining Axis Renderer for curved axes.
*/
import { __extends } from "tslib";
/**
* ============================================================================
* IMPORTS
* ============================================================================
* @hidden
*/
import { AxisRendererX } from "../../charts/axes/AxisRendererX";
import { Sprite } from "../../core/Sprite";
import { registry } from "../../core/Registry";
import { Polyspline } from "../../core/elements/Polyspline";
import * as $math from "../../core/utils/Math";
import * as $path from "../../core/rendering/Path";
import * as $type from "../../core/utils/Type";
import * as $array from "../../core/utils/Array";
import { AxisBullet } from "../../charts/axes/AxisBullet";
import { wavedLine } from "../../core/rendering/Smoothing";
/**
* ============================================================================
* MAIN CLASS
* ============================================================================
* @hidden
*/
/**
* A renderer for "horizontal" curve axis.
*/
var AxisRendererCurveX = /** @class */ (function (_super) {
__extends(AxisRendererCurveX, _super);
/**
* Constructor.
*/
function AxisRendererCurveX() {
var _this =
// Init
_super.call(this) || this;
/**
* @ignore
*/
_this.pixelRadiusReal = 0;
/**
* @readonly
* @ignore
*/
_this.autoScaleScale = 1;
// axis.layout = "none"; // does not trigger redraw when size changes
// axis.layout = "none"; // does not trigger redraw when size changes
_this.layout = "none";
_this.autoScale = true;
_this.autoCenter = true;
_this.isMeasured = false;
_this.className = "AxisRendererCurveX";
_this.line.strokeOpacity = 1;
_this.precisionStep = 10;
_this.line.isMeasured = false;
_this.points = [{ x: -300, y: 0 }, { x: 300, y: 0 }];
_this._tempSprite = _this.createChild(Sprite);
_this._tempSprite.visible = false;
_this.applyTheme();
return _this;
}
Object.defineProperty(AxisRendererCurveX.prototype, "axisLength", {
/**
* Returns actual length of the Axis, in pixels.
*
* @return Length (px)
*/
get: function () {
return this.polyspline.distance;
},
enumerable: true,
configurable: true
});
/**
* Updates and positions the axis line element.
*
* @ignore Exclude from docs
*/
AxisRendererCurveX.prototype.updateAxisLine = function () {
this.line.path = this.polyspline.path;
};
Object.defineProperty(AxisRendererCurveX.prototype, "polyspline", {
/**
* @return Polyspline
*/
get: function () {
var polyspline = this.getPropertyValue("polyspline");
if (!polyspline) {
polyspline = this.createChild(Polyspline);
polyspline.tensionX = 1;
polyspline.tensionY = 1;
this.polyspline = polyspline;
}
return polyspline;
},
/**
* A [[Polyspline]] elment that represents axis shape / curve.
*
* @param value Polyspline
*/
set: function (value) {
this.setPropertyValue("polyspline", value, true);
value.parent = this;
},
enumerable: true,
configurable: true
});
Object.defineProperty(AxisRendererCurveX.prototype, "autoScale", {
/**
* @return Auto-scale?
*/
get: function () {
return this.getPropertyValue("autoScale");
},
/**
* Should the chart be scaled automatically, to fit into container?
*
* @default true
* @param value Auto-scale?
*/
set: function (value) {
this.setPropertyValue("autoScale", value, true);
},
enumerable: true,
configurable: true
});
Object.defineProperty(AxisRendererCurveX.prototype, "autoCenter", {
/**
* @return {boolean} Auto-center?
*/
get: function () {
return this.getPropertyValue("autoCenter");
},
/**
* Should chart be centered within chart area?
*
* @default true
* @param value Auto-center?
*/
set: function (value) {
this.setPropertyValue("autoCenter", value, true);
},
enumerable: true,
configurable: true
});
Object.defineProperty(AxisRendererCurveX.prototype, "precisionStep", {
/**
* @return Precision step
*/
get: function () {
return this.getPropertyValue("precisionStep");
},
/**
* Precision setting to use when drawing chart objects. Basically, it's
* number of pixels that a control point should be added at.
*
* The smaller the number, the finer line. However, small number will impact
* the performace.
*
* Depending on actual chart configuration, you might need to find the best
* possible value to balance between detail and good performance.
*
* @default 10
* @param value Precision step
*/
set: function (value) {
this.setPropertyValue("precisionStep", value, true);
},
enumerable: true,
configurable: true
});
Object.defineProperty(AxisRendererCurveX.prototype, "points", {
/**
* @return Control points
*/
get: function () {
return this.getPropertyValue("points");
},
/**
* An array of control points that define axis curve.
*
* @see {@link https://www.amcharts.com/docs/v4/chart-types/timeline/#Control_points} for more info
* @param value Control points
*/
set: function (value) {
if (this.setPropertyValue("points", value, true)) {
this._pointsChanged = true;
this.polyspline.segments = [value];
}
},
enumerable: true,
configurable: true
});
/**
* @ignore
*/
AxisRendererCurveX.prototype.setAxis = function (axis) {
var _this = this;
_super.prototype.setAxis.call(this, axis);
if (axis && axis.chart) {
var chart = axis.chart;
this._disposers.push(chart.curveContainer.events.on("positionchanged", function () {
_this.handleSizeChange();
}));
this._disposers.push(chart.events.on("maxsizechanged", function () {
_this.handleSizeChange();
}));
}
};
/**
* A handler for when axis size changes.
*/
AxisRendererCurveX.prototype.handleSizeChange = function () {
if (this._pointsChanged) {
var pp = this.axis.getPositionRangePath(0, 1);
this._tempSprite.path = pp;
this._pointsChanged = false;
}
if (this.points) {
var chart = this.axis.chart;
var curveContainer = chart.curveContainer;
var mw = chart.plotContainer.maxWidth - curveContainer.pixelPaddingLeft - curveContainer.pixelPaddingRight;
var mh = chart.plotContainer.maxHeight - curveContainer.pixelPaddingTop - curveContainer.pixelPaddingBottom;
var bbox = this._tempSprite.element.getBBox();
var centerPoint_1 = { x: 0, y: 0 };
if (this.autoCenter) {
centerPoint_1 = { x: bbox.x + bbox.width / 2, y: bbox.y + bbox.height / 2 };
}
var scale_1 = 1;
if (this.autoScale) {
scale_1 = $math.min(mw / bbox.width, mh / bbox.height);
}
var modifiedPoints_1 = [];
$array.each(this.points, function (point) {
modifiedPoints_1.push({ x: (point.x - centerPoint_1.x) * scale_1, y: (point.y - centerPoint_1.y) * scale_1 });
});
this.polyspline.segments = [modifiedPoints_1];
}
};
/**
* Converts relative position on axis to point coordinates.
*
* @param position Position (0-1)
* @param position2 Position (0-1) Position on the second axis
* @return Point
*/
AxisRendererCurveX.prototype.positionToPoint = function (position, position2) {
var axis = this.axis;
position = (position - axis.start) / (axis.end - axis.start);
var point = this.polyspline.positionToPoint(position, true);
point.angle += 90;
var axisRendererY = this.axisRendererY;
if ($type.isNumber(position2) && axisRendererY) {
var radius = axisRendererY.positionToPoint(position2).y;
point.x += radius * $math.cos(point.angle);
point.y += radius * $math.sin(point.angle);
}
return point;
};
/**
* Converts relative position (0-1) on axis to angle in degrees (0-360).
*
* @param position Position (0-1)
* @return Angle (0-360)
*/
AxisRendererCurveX.prototype.positionToAngle = function (position) {
var axis = this.axis;
position = $math.max(0, (position - axis.start) / (axis.end - axis.start));
return this.polyspline.positionToPoint(position, true).angle + 90;
};
/**
* Updates and positions a grid element.
*
* @ignore Exclude from docs
* @param grid Grid element
* @param position Starting position
* @param endPosition End position
*/
AxisRendererCurveX.prototype.updateGridElement = function (grid, position, endPosition) {
if (grid.element) {
position = position + (endPosition - position) * grid.location;
grid.zIndex = 0;
grid.path = this.getGridPath(position);
this.toggleVisibility(grid, position, 0, 1);
}
};
/**
* [getGridPath description]
*
* @ignore
* @todo description
* @param position Position
* @return SVG path
*/
AxisRendererCurveX.prototype.getGridPath = function (position) {
var point = this.positionToPoint(position);
var angle = point.angle;
var axisRendererY = this.axisRendererY;
if (axisRendererY) {
var radius = -axisRendererY.radius;
var innerRadius = -axisRendererY.innerRadius;
return $path.moveTo({ x: point.x + innerRadius * $math.cos(angle), y: point.y + innerRadius * $math.sin(angle) }) + $path.lineTo({ x: point.x + radius * $math.cos(angle), y: point.y + radius * $math.sin(angle) });
}
return "";
};
/**
* Updates and positions a tick element.
*
* @ignore Exclude from docs
* @param tick Tick element
* @param position Position
*/
AxisRendererCurveX.prototype.updateTickElement = function (tick, position) {
if (tick.element) {
var point = this.positionToPoint(position);
var angle = point.angle;
var tickLength = tick.length;
if (tick.inside) {
tickLength *= -1;
}
tick.path = $path.moveTo({ x: point.x, y: point.y }) + $path.lineTo({ x: point.x + tickLength * $math.cos(angle), y: point.y + tickLength * $math.sin(angle) });
this.toggleVisibility(tick, position, 0, 1);
}
};
/**
* Updates and positions a label element.
*
* @ignore Exclude from docs
* @param label Label element
* @param position Starting position
* @param endPosition Ending position
*/
AxisRendererCurveX.prototype.updateLabelElement = function (label, position, endPosition, location) {
if (!$type.hasValue(location)) {
location = label.location;
}
position = position + (endPosition - position) * location;
var point = this.positionToPoint(position);
label.x = point.x;
label.y = point.y;
label.zIndex = 2;
this.toggleVisibility(label, position, this.minLabelPosition, this.maxLabelPosition);
};
/**
* [getPositionRangePath description]
*
* @ignore Exclude from docs
* @todo Description
* @param startPosition Starting position
* @param endPosition End position
* @return SVG path
*/
AxisRendererCurveX.prototype.getPositionRangePath = function (startPosition, endPosition) {
var path = "";
var axisRendererY = this.axisRendererY;
if (axisRendererY) {
if (startPosition > endPosition) {
var temp = startPosition;
startPosition = endPosition;
endPosition = temp;
}
var startY = axisRendererY.axis.start;
var endY = axisRendererY.axis.end;
var startX = this.axis.start;
var endX = this.axis.end;
if ((startPosition <= startX && endPosition <= startX) || (startPosition >= endX && endPosition >= endX)) {
return path;
}
startPosition = $math.fitToRange(startPosition, startX, endX);
endPosition = $math.fitToRange(endPosition, startX, endX);
if (endPosition == startX || startPosition == endX) {
return path;
}
if (endPosition == startPosition) {
return path;
}
var startRadius = $math.round(axisRendererY.positionToPoint(startY).y, 1) | 0;
var endRadius = $math.round(axisRendererY.positionToPoint(endY).y, 1) | 0;
var point = this.positionToPoint(startPosition);
var angle = point.angle;
path = $path.moveTo(point);
var count = Math.ceil(this.axisLength / this.precisionStep * (endPosition - startPosition) / (endX - startX));
for (var i = 0; i <= count; i++) {
var pos = startPosition + i / count * (endPosition - startPosition);
point = this.positionToPoint(pos);
angle = point.angle;
var x = point.x + startRadius * $math.cos(angle);
var y = point.y + startRadius * $math.sin(angle);
path += $path.lineTo({ x: x, y: y });
}
for (var i = count; i >= 0; i--) {
var pos = startPosition + i / count * (endPosition - startPosition);
point = this.positionToPoint(pos);
angle = point.angle;
var x = point.x + endRadius * $math.cos(angle);
var y = point.y + endRadius * $math.sin(angle);
path += $path.lineTo({ x: x, y: y });
}
path += $path.closePath();
}
return path;
};
/**
* Updates and positions the base grid element.
*
* @ignore Exclude from docs
*/
AxisRendererCurveX.prototype.updateBaseGridElement = function () {
};
/**
* Updates and positions axis bullet.
*
* @ignore Exclude from docs
* @param bullet AxisBullet element
* @param position Starting position
* @param endPosition End position
*/
AxisRendererCurveX.prototype.updateBullet = function (bullet, position, endPosition) {
var location = 0.5;
if (bullet instanceof AxisBullet) {
location = bullet.location;
}
position = position + (endPosition - position) * location;
var point = this.positionToPoint(position);
//let angle = point.angle;
bullet.moveTo({ x: point.x, y: point.y });
//bullet.rotation = angle - 90;
this.toggleVisibility(bullet, position, 0, 1);
};
/**
* Updates and positions an axis break element.
*
* @ignore Exclude from docs
* @param axisBreak Break element
*/
AxisRendererCurveX.prototype.updateBreakElement = function (axisBreak) {
var axisRendererY = this.axisRendererY;
if (axisRendererY) {
var startPosition = axisBreak.startPosition;
var endPosition = axisBreak.endPosition;
var startAngle = this.positionToAngle(startPosition);
var startPoint = this.positionToPoint(startPosition);
var endAngle = this.positionToAngle(endPosition);
var endPoint = this.positionToPoint(endPosition);
var startLine = axisBreak.startLine;
var endLine = axisBreak.endLine;
var fillShape = axisBreak.fillShape;
var radius = -axisRendererY.radius + axisBreak.pixelMarginTop;
var innerRadius = -axisRendererY.innerRadius - axisBreak.pixelMarginBottom;
var x1 = startPoint.x + innerRadius * $math.cos(startAngle);
var y1 = startPoint.y + innerRadius * $math.sin(startAngle);
var x2 = startPoint.x + radius * $math.cos(startAngle);
var y2 = startPoint.y + radius * $math.sin(startAngle);
var x3 = endPoint.x + innerRadius * $math.cos(endAngle);
var y3 = endPoint.y + innerRadius * $math.sin(endAngle);
var x4 = endPoint.x + radius * $math.cos(endAngle);
var y4 = endPoint.y + radius * $math.sin(endAngle);
var p1 = { x: x1, y: y1 };
var p2 = { x: x2, y: y2 };
var p3 = { x: x3, y: y3 };
var p4 = { x: x4, y: y4 };
startLine.path = $path.moveTo(p1) + wavedLine(p1, p2, startLine.waveLength, startLine.waveHeight, startLine.tension, true);
endLine.path = $path.moveTo(p4) + wavedLine(p4, p3, endLine.waveLength, endLine.waveHeight, endLine.tension, true);
var path = $path.moveTo(p1);
path += wavedLine(p1, p2, fillShape.waveLength, fillShape.waveHeight, fillShape.tension, true);
var startX = this.axis.start;
var endX = this.axis.end;
var count = Math.ceil(this.axisLength / this.precisionStep * (endPosition - startPosition) / (endX - startX));
for (var i = 0; i <= count; i++) {
var pos = startPosition + i / count * (endPosition - startPosition);
var point = this.positionToPoint(pos);
var angle = point.angle;
var x = point.x + radius * $math.cos(angle);
var y = point.y + radius * $math.sin(angle);
path += $path.lineTo({ x: x, y: y });
}
path += wavedLine(p4, p3, fillShape.waveLength, fillShape.waveHeight, fillShape.tension, true);
for (var i = count; i >= 0; i--) {
var pos = startPosition + i / count * (endPosition - startPosition);
var point = this.positionToPoint(pos);
var angle = point.angle;
var x = point.x + innerRadius * $math.cos(angle);
var y = point.y + innerRadius * $math.sin(angle);
path += $path.lineTo({ x: x, y: y });
}
fillShape.path = path;
this.toggleVisibility(axisBreak.startLine, axisBreak.startPosition, 0, 1);
this.toggleVisibility(axisBreak.endLine, axisBreak.endPosition, 0, 1);
}
};
/**
* @ignore
*/
AxisRendererCurveX.prototype.toAxisPosition = function (value) {
return value;
};
/**
* Converts a coordinate in pixels to a relative position. (0-1)
*
* @param coordinate Coordinate (px)
* @param coordinate2 Coordinate (px) Some more complicated axes need two coordinates
* @return Position (0-1)
*/
AxisRendererCurveX.prototype.coordinateToPosition = function (coordinate, coordinate2) {
var points = this.polyspline.allPoints;
var closestPoint = this.polyspline.getClosestPointIndex({ x: coordinate, y: coordinate2 });
return _super.prototype.coordinateToPosition.call(this, closestPoint / (points.length - 1) * this.axisLength);
};
/**
* Updates some of the Axis tooltip's visual properties, related to
* rendering of the Axis.
*
* @todo Description (review)
* @ignore Exclude from docs
*/
AxisRendererCurveX.prototype.updateTooltip = function () {
};
Object.defineProperty(AxisRendererCurveX.prototype, "inversed", {
/**
* @return Flip axis?
*/
get: function () {
return false;
},
/**
* [[CurveChart]] does not support inversed X axes. This setting will be
* ignored.
* @param value Flip axis?
*/
set: function (value) {
},
enumerable: true,
configurable: true
});
return AxisRendererCurveX;
}(AxisRendererX));
export { AxisRendererCurveX };
/**
* Register class in system, so that it can be instantiated using its name from
* anywhere.
*
* @ignore
*/
registry.registeredClasses["AxisRendererCurveX"] = AxisRendererCurveX;
//# sourceMappingURL=AxisRendererCurveX.js.map