| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- // 其他工具函数
- // 来源: u-charts.ts
- /**
- * H5 事件接口
- */
- export interface H5Event {
- offsetX: number;
- offsetY: number;
- mp: {
- changedTouches: Array<{ x: number; y: number }>;
- };
- }
- /**
- * 触摸点接口
- */
- export interface TouchPoint {
- x?: number;
- y?: number;
- clientX?: number;
- clientY?: number;
- pageX?: number;
- pageY?: number;
- }
- /**
- * 图表选项接口(用于 getTouches)
- */
- export interface ChartOptions {
- rotate?: boolean;
- height: number;
- pix: number;
- width?: number;
- }
- /**
- * DOM 事件接口
- */
- export interface DOMEvent {
- currentTarget?: {
- offsetTop?: number;
- };
- }
- /**
- * 兼容 H5 点击事件
- * 将 H5 的 offsetX/offsetY 转换为小程序格式的 changedTouches
- * @param e - H5 事件对象
- * @returns 转换后的事件对象
- */
- export function getH5Offset(e: { offsetX: number; offsetY: number }): H5Event {
- (e as H5Event).mp = {
- changedTouches: []
- };
- (e as H5Event).mp.changedTouches.push({
- x: e.offsetX,
- y: e.offsetY
- });
- return e as H5Event;
- }
- /**
- * 曲线控制点接口
- */
- export interface CurveControlPoints {
- ctrA: {
- x: number | null;
- y: number | null;
- };
- ctrB: {
- x: number | null;
- y: number | null;
- };
- }
- /**
- * 点数组接口(用于 createCurveControlPoints)
- */
- export interface PointArray extends Array<{ x: number; y: number }> {}
- /**
- * 创建曲线控制点
- * 用于绘制平滑曲线(贝塞尔曲线)
- * @param points - 点数组
- * @param i - 当前点索引
- * @returns 曲线控制点
- */
- export function createCurveControlPoints(points: PointArray, i: number): CurveControlPoints {
- function isNotMiddlePoint(pts: PointArray, idx: number): boolean {
- if (pts[idx - 1] && pts[idx + 1]) {
- return pts[idx].y >= Math.max(pts[idx - 1].y, pts[idx + 1].y) || pts[idx].y <= Math.min(pts[idx - 1].y,
- pts[idx + 1].y);
- } else {
- return false;
- }
- }
- function isNotMiddlePointX(pts: PointArray, idx: number): boolean {
- if (pts[idx - 1] && pts[idx + 1]) {
- return pts[idx].x >= Math.max(pts[idx - 1].x, pts[idx + 1].x) || pts[idx].x <= Math.min(pts[idx - 1].x,
- pts[idx + 1].x);
- } else {
- return false;
- }
- }
- let a = 0.2;
- let b = 0.2;
- let pAx: number | null = null;
- let pAy: number | null = null;
- let pBx: number | null = null;
- let pBy: number | null = null;
- if (i < 1) {
- pAx = points[0].x + (points[1].x - points[0].x) * a;
- pAy = points[0].y + (points[1].y - points[0].y) * a;
- } else {
- pAx = points[i].x + (points[i + 1].x - points[i - 1].x) * a;
- pAy = points[i].y + (points[i + 1].y - points[i - 1].y) * a;
- }
- if (i > points.length - 3) {
- let last = points.length - 1;
- pBx = points[last].x - (points[last].x - points[last - 1].x) * b;
- pBy = points[last].y - (points[last].y - points[last - 1].y) * b;
- } else {
- pBx = points[i + 1].x - (points[i + 2].x - points[i].x) * b;
- pBy = points[i + 1].y - (points[i + 2].y - points[i].y) * b;
- }
- if (isNotMiddlePoint(points, i + 1)) {
- pBy = points[i + 1].y;
- }
- if (isNotMiddlePoint(points, i)) {
- pAy = points[i].y;
- }
- if (isNotMiddlePointX(points, i + 1)) {
- pBx = points[i + 1].x;
- }
- if (isNotMiddlePointX(points, i)) {
- pAx = points[i].x;
- }
- if (pAy >= Math.max(points[i].y, points[i + 1].y) || pAy <= Math.min(points[i].y, points[i + 1].y)) {
- pAy = points[i].y;
- }
- if (pBy >= Math.max(points[i].y, points[i + 1].y) || pBy <= Math.min(points[i].y, points[i + 1].y)) {
- pBy = points[i + 1].y;
- }
- if (pAx >= Math.max(points[i].x, points[i + 1].x) || pAx <= Math.min(points[i].x, points[i + 1].x)) {
- pAx = points[i].x;
- }
- if (pBx >= Math.max(points[i].x, points[i + 1].x) || pBx <= Math.min(points[i].x, points[i + 1].x)) {
- pBx = points[i + 1].x;
- }
- return {
- ctrA: {
- x: pAx,
- y: pAy
- },
- ctrB: {
- x: pBx,
- y: pBy
- }
- };
- }
- /**
- * 获取触摸点坐标
- * 支持小程序和 H5 两种格式
- * @param touches - 触摸点数组或单个触摸点
- * @param opts - 图表选项
- * @param e - DOM 事件对象
- * @returns 触摸点坐标
- */
- export function getTouches(
- touches: TouchPoint | TouchPoint[],
- opts: ChartOptions,
- e: DOMEvent
- ): TouchPoint {
- let x: number, y: number;
- const touch = Array.isArray(touches) ? touches[0] : touches;
- if (touch.clientX) {
- if (opts.rotate) {
- y = opts.height - touch.clientX! * opts.pix;
- x = (touch.pageY! - (e.currentTarget?.offsetTop || 0) - (opts.height / opts.pix / 2) * (opts.pix - 1)) * opts.pix;
- } else {
- x = touch.clientX! * opts.pix;
- y = (touch.pageY! - (e.currentTarget?.offsetTop || 0) - (opts.height / opts.pix / 2) * (opts.pix - 1)) * opts.pix;
- }
- } else {
- if (opts.rotate) {
- y = opts.height - touch.x! * opts.pix;
- x = touch.y! * opts.pix;
- } else {
- x = touch.x! * opts.pix;
- y = touch.y! * opts.pix;
- }
- }
- return {
- x: x,
- y: y
- };
- }
|