highcharts
Version:
JavaScript charting framework
197 lines (191 loc) • 7.29 kB
JavaScript
/* *
*
* Author: Rafal Sebestjanski
*
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
*
* */
;
import Annotation from '../Annotation.js';
import ControlPoint from '../ControlPoint.js';
import CrookedLine from './CrookedLine.js';
import InfinityLine from './InfinityLine.js';
import MockPoint from '../MockPoint.js';
import U from '../../../Core/Utilities.js';
const { merge } = U;
/* *
*
* Functions
*
* */
/**
Method taken (and slightly changed) from the InfinityLine annotation.
It uses x coordinate to create two mock points on the same x. Then,
it uses some logic from InfinityLine to find equation of the line passing
through our two points and, using that equation, it finds and returns
the coordinates of where the line intersects the plot area edges.
This is being done for each fibonacci time zone line.
this point here is found
|
v
|---------*--------------------------------------------------------|
| |
| |
| |
| |
| * copy of the primary point |
| |
| * primary point (e.g. the one given in options) |
| |
|---------*--------------------------------------------------------|
and this point here is found (intersection with the plot area edge)
* @private
*/
function edgePoint(startIndex, endIndex, fibonacciIndex) {
return function (target) {
const chart = target.annotation.chart, plotLeftOrTop = chart.inverted ? chart.plotTop : chart.plotLeft;
let points = target.annotation.points;
const xAxis = points[0].series.xAxis,
// Distance between the two first lines in pixels
deltaX = points.length > 1 ?
points[1].plotX - points[0].plotX : 0,
// `firstLine.x + fibb * offset`
x = xAxis.toValue(points[0].plotX + plotLeftOrTop + fibonacciIndex * deltaX);
// We need 2 mock points with the same x coordinate, different y
points = [
new MockPoint(chart, points[0].target, {
x: x,
y: 0,
xAxis: points[0].options.xAxis,
yAxis: points[0].options.yAxis
}),
new MockPoint(chart, points[0].target, {
x: x,
y: 1,
xAxis: points[0].options.xAxis,
yAxis: points[0].options.yAxis
})
];
return InfinityLine.findEdgePoint(points[startIndex], points[endIndex]);
};
}
/* *
*
* Class
*
* */
class FibonacciTimeZones extends CrookedLine {
/* *
*
* Functions
*
* */
addShapes() {
const numberOfLines = 11;
let fibb = 1, nextFibb = 1;
for (let i = 0; i < numberOfLines; i++) {
// The fibb variable equals to 1 twice - correct it in the first
// iteration so the lines don't overlap
const correctedFibb = !i ? 0 : fibb, points = [
edgePoint(1, 0, correctedFibb),
edgePoint(0, 1, correctedFibb)
];
// Calculate fibonacci
nextFibb = fibb + nextFibb;
fibb = nextFibb - fibb;
// Save the second line for the control point
if (i === 1) {
this.secondLineEdgePoints = [points[0], points[1]];
}
this.initShape(merge(this.options.typeOptions.line, {
type: 'path',
points: points,
className: 'highcharts-fibonacci-timezones-lines'
}), i // Shape's index. Can be found in annotation.shapes[i].index
);
}
}
addControlPoints() {
const options = this.options, typeOptions = options.typeOptions, controlPoint = new ControlPoint(this.chart, this, merge(options.controlPointOptions, typeOptions.controlPointOptions), 0);
this.controlPoints.push(controlPoint);
typeOptions.controlPointOptions = controlPoint.options;
}
}
FibonacciTimeZones.prototype.defaultOptions = merge(CrookedLine.prototype.defaultOptions,
/**
* The Fibonacci Time Zones annotation.
*
* @sample highcharts/annotations-advanced/fibonacci-time-zones/
* Fibonacci Time Zones
*
* @extends annotations.crookedLine
* @since 9.3.0
* @product highstock
* @optionparent annotations.fibonacciTimeZones
*/
{
typeOptions: {
/**
* @exclude y
* @since 9.3.0
* @product highstock
* @apioption annotations.fibonacciTimeZones.typeOptions.points
*/
// Options for showing in popup edit
line: {
/**
* The color of the lines.
*
* @type {string}
* @since 9.3.0
* @default 'rgba(0, 0, 0, 0.75)'
* @apioption annotations.fibonacciTimeZones.typeOptions.line.stroke
*/
stroke: 'rgba(0, 0, 0, 0.75)',
/**
* The width of the lines.
*
* @type {number}
* @since 9.3.0
* @default 1
* @apioption annotations.fibonacciTimeZones.typeOptions.line.strokeWidth
*/
strokeWidth: 1,
// Don't inherit fill (don't display in popup edit)
fill: void 0
},
controlPointOptions: {
positioner: function () {
// The control point is in the middle of the second line
const target = this.target, graphic = this.graphic, edgePoints = target.secondLineEdgePoints, args = { annotation: target }, firstEdgePointY = edgePoints[0](args).y, secondEdgePointY = edgePoints[1](args).y, plotLeft = this.chart.plotLeft, plotTop = this.chart.plotTop;
let x = edgePoints[0](args).x, y = (firstEdgePointY + secondEdgePointY) / 2;
if (this.chart.inverted) {
[x, y] = [y, x];
}
return {
x: plotLeft + x - (graphic.width || 0) / 2,
y: plotTop + y - (graphic.height || 0) / 2
};
},
events: {
drag: function (e, target) {
const isInsidePlot = target.chart.isInsidePlot(e.chartX - target.chart.plotLeft, e.chartY - target.chart.plotTop, {
visiblePlotOnly: true
});
if (isInsidePlot) {
const translation = this.mouseMoveToTranslation(e);
target.translatePoint(translation.x, 0, 1);
target.redraw(false);
}
}
}
}
}
});
Annotation.types.fibonacciTimeZones = FibonacciTimeZones;
/* *
*
* Default Export
*
* */
export default FibonacciTimeZones;