UNPKG

highcharts

Version:
206 lines (205 loc) 6.76 kB
/* * * * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!! * * */ 'use strict'; import Annotation from '../Annotation.js'; import ControlPoint from '../ControlPoint.js'; import CrookedLine from './CrookedLine.js'; import MockPoint from '../MockPoint.js'; import U from '../../../Core/Utilities.js'; const { merge } = U; /* * * * Functions * * */ /** * @private */ function getSecondCoordinate(p1, p2, x) { return (p2.y - p1.y) / (p2.x - p1.x) * (x - p1.x) + p1.y; } /* * * * Class * * */ class Tunnel extends CrookedLine { /* * * * Functions * * */ getPointsOptions() { const pointsOptions = CrookedLine.prototype.getPointsOptions.call(this), yAxisIndex = this.options.typeOptions.yAxis || 0, yAxis = this.chart.yAxis[yAxisIndex]; pointsOptions[2] = this.heightPointOptions(pointsOptions[1]); pointsOptions[3] = this.heightPointOptions(pointsOptions[0]); // In case of log axis, translate the bottom left point again, #16769 if (yAxis && yAxis.logarithmic) { // Get the height in pixels const h = yAxis.toPixels(pointsOptions[2].y) - yAxis.toPixels(pointsOptions[1].y), // Get the pixel position of the last point y3 = yAxis.toPixels(pointsOptions[0].y) + h; // Set the new value pointsOptions[3].y = yAxis.toValue(y3); } return pointsOptions; } getControlPointsOptions() { return this.getPointsOptions().slice(0, 2); } heightPointOptions(pointOptions) { const heightPointOptions = merge(pointOptions), typeOptions = this.options.typeOptions; heightPointOptions.y += typeOptions.height; return heightPointOptions; } addControlPoints() { CrookedLine.prototype.addControlPoints.call(this); const options = this.options, typeOptions = options.typeOptions, controlPoint = new ControlPoint(this.chart, this, merge(options.controlPointOptions, typeOptions.heightControlPoint), 2); this.controlPoints.push(controlPoint); typeOptions.heightControlPoint = controlPoint.options; } addShapes() { this.addLine(); this.addBackground(); } addLine() { const line = this.initShape(merge(this.options.typeOptions.line, { type: 'path', points: [ this.points[0], this.points[1], function (target) { const pointOptions = MockPoint.pointToOptions(target.annotation.points[2]); pointOptions.command = 'M'; return pointOptions; }, this.points[3] ], className: 'highcharts-tunnel-lines' }), 0); this.options.typeOptions.line = line.options; } addBackground() { const background = this.initShape(merge(this.options.typeOptions.background, { type: 'path', points: this.points.slice(), className: 'highcharts-tunnel-background' }), 1); this.options.typeOptions.background = background.options; } /** * Translate start or end ("left" or "right") side of the tunnel. * @private * @param {number} dx * the amount of x translation * @param {number} dy * the amount of y translation * @param {boolean} [end] * whether to translate start or end side */ translateSide(dx, dy, end) { const topIndex = Number(end), bottomIndex = topIndex === 0 ? 3 : 2; this.translatePoint(dx, dy, topIndex); this.translatePoint(dx, dy, bottomIndex); } /** * Translate height of the tunnel. * @private * @param {number} dh * the amount of height translation */ translateHeight(dh) { this.translatePoint(0, dh, 2); this.translatePoint(0, dh, 3); this.options.typeOptions.height = this.points[3].y - this.points[0].y; this.userOptions.typeOptions.height = this.options.typeOptions.height; } } Tunnel.prototype.defaultOptions = merge(CrookedLine.prototype.defaultOptions, /** * A tunnel annotation. * * @extends annotations.crookedLine * @sample highcharts/annotations-advanced/tunnel/ * Tunnel * @product highstock * @optionparent annotations.tunnel */ { typeOptions: { /** * Background options. * * @type {Object} * @excluding height, point, points, r, type, width, markerEnd, * markerStart */ background: { fill: 'rgba(130, 170, 255, 0.4)', strokeWidth: 0 }, line: { strokeWidth: 1 }, /** * The height of the annotation in terms of yAxis. */ height: -2, /** * Options for the control point which controls * the annotation's height. * * @extends annotations.crookedLine.controlPointOptions * @excluding positioner, events */ heightControlPoint: { positioner: function (target) { const startXY = MockPoint.pointToPixels(target.points[2]), endXY = MockPoint.pointToPixels(target.points[3]), x = (startXY.x + endXY.x) / 2; return { x: x - (this.graphic.width || 0) / 2, y: getSecondCoordinate(startXY, endXY, x) - (this.graphic.height || 0) / 2 }; }, events: { drag: function (e, target) { if (target.chart.isInsidePlot(e.chartX - target.chart.plotLeft, e.chartY - target.chart.plotTop, { visiblePlotOnly: true })) { target.translateHeight(this.mouseMoveToTranslation(e).y); target.redraw(false); } } } } }, /** * @extends annotations.crookedLine.controlPointOptions * @excluding positioner, events */ controlPointOptions: { events: { drag: function (e, target) { if (target.chart.isInsidePlot(e.chartX - target.chart.plotLeft, e.chartY - target.chart.plotTop, { visiblePlotOnly: true })) { const translation = this.mouseMoveToTranslation(e); target.translateSide(translation.x, translation.y, !!this.index); target.redraw(false); } } } } }); Annotation.types.tunnel = Tunnel; /* * * * Default Export * * */ export default Tunnel;