@dickyindra/klinecharts
Version:
Lightweight k-line chart built with html5 canvas
429 lines (371 loc) • 12.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.DEVIATION = void 0;
exports.checkCoordinateInCircle = checkCoordinateInCircle;
exports.checkCoordinateInDiamond = checkCoordinateInDiamond;
exports.checkCoordinateInRect = checkCoordinateInRect;
exports.checkCoordinateInTriangle = checkCoordinateInTriangle;
exports.checkCoordinateOnArc = checkCoordinateOnArc;
exports.checkCoordinateOnCircle = checkCoordinateOnCircle;
exports.checkCoordinateOnRayLine = checkCoordinateOnRayLine;
exports.checkCoordinateOnSegment = checkCoordinateOnSegment;
exports.checkCoordinateOnStraightLine = checkCoordinateOnStraightLine;
exports.getDistance = getDistance;
exports.getLinearSlopeIntercept = getLinearSlopeIntercept;
exports.getLinearYFromCoordinates = getLinearYFromCoordinates;
exports.getLinearYFromSlopeIntercept = getLinearYFromSlopeIntercept;
exports.getParallelLines = getParallelLines;
exports.getRayLine = getRayLine;
exports.getRotateCoordinate = getRotateCoordinate;
exports.getTriangleSquare = getTriangleSquare;
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var DEVIATION = 2;
/**
* 获取两点之间的距离
* @param coordinate
* @param coordinate2
* @return {number}
*/
exports.DEVIATION = DEVIATION;
function getDistance(coordinate1, coordinate2) {
var xDif = coordinate1.x - coordinate2.x;
var yDif = coordinate1.y - coordinate2.y;
return Math.sqrt(xDif * xDif + yDif * yDif);
}
/**
* 根据三角形三个点获取三角形面积
* @param coordinate1
* @param coordinate2
* @param coordinate3
* @return {number}
*/
function getTriangleSquare(coordinate1, coordinate2, coordinate3) {
var x1 = Math.abs(coordinate2.x - coordinate1.x);
var y1 = Math.abs(coordinate2.y - coordinate1.y);
var x2 = Math.abs(coordinate3.x - coordinate1.x);
var y2 = Math.abs(coordinate3.y - coordinate1.y);
return Math.abs(x1 * y2 - x2 * y1) / 2;
}
/**
* 获取一点绕另一点旋转一定角度后新的点坐标
* @param coordinate 旋转点
* @param targetCoordinate 参照点
* @param angle 角度
* @return {{x: *, y: *}}
*/
function getRotateCoordinate(coordinate, targetCoordinate, angle) {
var x = (coordinate.x - targetCoordinate.x) * Math.cos(angle) - (coordinate.y - targetCoordinate.y) * Math.sin(angle) + targetCoordinate.x;
var y = (coordinate.x - targetCoordinate.x) * Math.sin(angle) + (coordinate.y - targetCoordinate.y) * Math.cos(angle) + targetCoordinate.y;
return {
x: x,
y: y
};
}
/**
* 获取一次函数斜率和截距,即 y = kx + b 中的k值和b值
* @param coordinate1
* @param coordinate2
*/
function getLinearSlopeIntercept(coordinate1, coordinate2) {
var difX = coordinate1.x - coordinate2.x;
if (difX !== 0) {
var k = (coordinate1.y - coordinate2.y) / difX;
var b = coordinate1.y - k * coordinate1.x;
return {
k: k,
b: b
};
}
}
/**
* 获取点在两点决定的一次函数上的y值
* @param coordinate1
* @param coordinate2
* @param targetCoordinate
*/
function getLinearYFromCoordinates(coordinate1, coordinate2, targetCoordinate) {
var kb = getLinearSlopeIntercept(coordinate1, coordinate2);
return getLinearYFromSlopeIntercept(kb, targetCoordinate);
}
/**
* 获取点在斜率和截距确定的线上的y值
* @param kb
* @param targetCoordinate
*/
function getLinearYFromSlopeIntercept(kb, targetCoordinate) {
if (kb) {
return targetCoordinate.x * kb.k + kb.b;
}
return targetCoordinate.y;
}
/**
* 点是否在线上
* @param coordinate1
* @param coordinate2
* @param targetCoordinate
*/
function checkCoordinateOnStraightLine(coordinate1, coordinate2, targetCoordinate) {
if (!targetCoordinate || !coordinate1 || !coordinate2) {
return false;
}
if (coordinate1.x === coordinate2.x) {
return Math.abs(targetCoordinate.x - coordinate1.x) < DEVIATION;
}
var kb = getLinearSlopeIntercept(coordinate1, coordinate2);
var y = getLinearYFromSlopeIntercept(kb, targetCoordinate);
var yDif = Math.abs(y - targetCoordinate.y);
return yDif * yDif / (kb.k * kb.k + 1) < DEVIATION * DEVIATION;
}
/**
* 点是否在线段上
* @param coordinate1
* @param coordinate2
* @param targetCoordinate
* @returns {boolean}
*/
function checkCoordinateOnRayLine(coordinate1, coordinate2, targetCoordinate) {
if (checkCoordinateOnStraightLine(coordinate1, coordinate2, targetCoordinate)) {
if (coordinate1.x === coordinate2.x) {
if (coordinate1.y < coordinate2.y) {
return coordinate1.y - targetCoordinate.y < DEVIATION;
} else {
return targetCoordinate.y - coordinate1.y < DEVIATION;
}
}
if (coordinate1.x < coordinate2.x) {
return coordinate1.x - targetCoordinate.x < DEVIATION;
} else {
return targetCoordinate.x - coordinate1.x < DEVIATION;
}
}
return false;
}
/**
* 判断点是否在线段上面
* @param coordinate1
* @param coordinate2
* @param targetCoordinate
*/
function checkCoordinateOnSegment(coordinate1, coordinate2, targetCoordinate) {
if (checkCoordinateOnStraightLine(coordinate1, coordinate2, targetCoordinate)) {
if (coordinate1.x === coordinate2.x) {
return Math.abs(coordinate1.y - targetCoordinate.y) + Math.abs(coordinate2.y - targetCoordinate.y) - Math.abs(coordinate1.y - coordinate2.y) < DEVIATION * 2;
}
return Math.abs(coordinate1.x - targetCoordinate.x) + Math.abs(coordinate2.x - targetCoordinate.x) - Math.abs(coordinate1.x - coordinate2.x) < DEVIATION * 2;
}
return false;
}
/**
* 点是否在圆内
* @param circleCenterCoordinate
* @param radius
* @param targetCoordinate
* @returns {boolean}
*/
function checkCoordinateInCircle(circleCenterCoordinate, radius, targetCoordinate) {
if (!targetCoordinate) {
return false;
}
var difX = targetCoordinate.x - circleCenterCoordinate.x;
var difY = targetCoordinate.y - circleCenterCoordinate.y;
return !(difX * difX + difY * difY > radius * radius);
}
/**
* 点是否在圆上
* @param circleCenterCoordinate
* @param radius
* @param targetCoordinate
* @return {boolean}
*/
function checkCoordinateOnCircle(circleCenterCoordinate, radius, targetCoordinate) {
if (!targetCoordinate) {
return false;
}
return Math.abs(getDistance(targetCoordinate, circleCenterCoordinate) - radius) < DEVIATION;
}
/**
* 检查点是否在圆弧上
* @param circleCenterCoordinate
* @param radius
* @param startAngle
* @param endAngle
* @param targetCoordinate
* @return {boolean}
*/
function checkCoordinateOnArc(circleCenterCoordinate, radius, startAngle, endAngle, targetCoordinate) {
if (checkCoordinateOnCircle(circleCenterCoordinate, radius, targetCoordinate)) {
var startCoordinateX = radius * Math.cos(startAngle) + circleCenterCoordinate.x;
var startCoordinateY = radius * Math.sin(startAngle) + circleCenterCoordinate.y;
var endCoordinateX = radius * Math.cos(endAngle) + circleCenterCoordinate.x;
var endCoordinateY = radius * Math.sin(endAngle) + circleCenterCoordinate.y;
return targetCoordinate.x <= Math.max(startCoordinateX, endCoordinateX) + DEVIATION && targetCoordinate.x >= Math.min(startCoordinateX, endCoordinateX) - DEVIATION && targetCoordinate.y <= Math.max(startCoordinateY, endCoordinateY) + DEVIATION && targetCoordinate.y >= Math.min(startCoordinateY, endCoordinateY) - DEVIATION;
}
}
/**
* 检查点是否在三角形内部
* @param triangleCoordinates
* @param targetCoordinate
* @return {boolean}
*/
function checkCoordinateInTriangle(triangleCoordinates, targetCoordinate) {
var square = getTriangleSquare(triangleCoordinates[0], triangleCoordinates[1], triangleCoordinates[2]);
var compareSquare = getTriangleSquare(triangleCoordinates[0], triangleCoordinates[1], targetCoordinate) + getTriangleSquare(triangleCoordinates[0], triangleCoordinates[2], targetCoordinate) + getTriangleSquare(triangleCoordinates[1], triangleCoordinates[2], targetCoordinate);
return Math.abs(square - compareSquare) < DEVIATION;
}
/**
* 检查点是否在三角形菱形内部
* @param centerCoordinate
* @param width
* @param height
* @param targetCoordinate
* @return {boolean}
*/
function checkCoordinateInDiamond(centerCoordinate, width, height, targetCoordinate) {
var xDis = Math.abs(centerCoordinate.x - targetCoordinate.x);
var yDis = Math.abs(centerCoordinate.y - targetCoordinate.y);
return xDis * height + yDis * width < width * height / 2 + DEVIATION;
}
/**
* 检查点是否在矩形内部
* @param coordinate1
* @param coordinate2
* @param targetCoordinate
* @return {boolean}
*/
function checkCoordinateInRect(coordinate1, coordinate2, targetCoordinate) {
return targetCoordinate.x >= coordinate1.x && targetCoordinate.x <= coordinate2.x && targetCoordinate.y >= coordinate1.y && targetCoordinate.y <= coordinate2.y;
}
/**
* 根据两点获取一条射线
* @param coordinate1
* @param coordinate2
* @param xyMax
* @return {(*|{x: *, y: *})[]|*[]}
*/
function getRayLine(coordinate1, coordinate2, xyMax) {
if (coordinate1 && coordinate2) {
var coordinate;
if (coordinate1.x === coordinate2.x && coordinate1.y !== coordinate2.y) {
if (coordinate1.y < coordinate2.y) {
coordinate = {
x: coordinate1.x,
y: xyMax.y
};
} else {
coordinate = {
x: coordinate1.x,
y: 0
};
}
} else if (coordinate1.x > coordinate2.x) {
coordinate = {
x: 0,
y: getLinearYFromCoordinates(coordinate1, coordinate2, {
x: 0,
y: coordinate1.y
})
};
} else {
coordinate = {
x: xyMax.x,
y: getLinearYFromCoordinates(coordinate1, coordinate2, {
x: xyMax.x,
y: coordinate1.y
})
};
}
return [coordinate1, coordinate];
}
return [];
}
/**
* 获取平行线
* @param coordinates
* @param xyMax
* @param extendParallelLineCount
* @returns {Array}
*/
function getParallelLines(coordinates, xyMax) {
var extendParallelLineCount = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
var lines = [];
if (coordinates.length > 1) {
if (coordinates[0].x === coordinates[1].x) {
var startY = 0;
var endY = xyMax.y;
lines.push([{
x: coordinates[0].x,
y: startY
}, {
x: coordinates[0].x,
y: endY
}]);
if (coordinates.length > 2) {
lines.push([{
x: coordinates[2].x,
y: startY
}, {
x: coordinates[2].x,
y: endY
}]);
var distance = coordinates[0].x - coordinates[2].x;
for (var i = 0; i < extendParallelLineCount; i++) {
var d = distance * (i + 1);
lines.push([{
x: coordinates[0].x + d,
y: startY
}, {
x: coordinates[0].x + d,
y: endY
}]);
}
}
} else {
var startX = 0;
var endX = xyMax.x;
var kb = getLinearSlopeIntercept(coordinates[0], coordinates[1]);
var k = kb.k;
var b = kb.b;
lines.push([{
x: startX,
y: startX * k + b
}, {
x: endX,
y: endX * k + b
}]);
if (coordinates.length > 2) {
var b1 = coordinates[2].y - k * coordinates[2].x;
lines.push([{
x: startX,
y: startX * k + b1
}, {
x: endX,
y: endX * k + b1
}]);
var _distance = b - b1;
for (var _i = 0; _i < extendParallelLineCount; _i++) {
var b2 = b + _distance * (_i + 1);
lines.push([{
x: startX,
y: startX * k + b2
}, {
x: endX,
y: endX * k + b2
}]);
}
}
}
}
return lines;
}