创建四分位模型
所谓四分位模型,每一个标记点都有上下左右四个放文字的位子,如果左边放不下,那就放右边试试,还不行就放到下面试试,以此类推,原理就这么简单,哈哈。
创建右侧虚拟矩形坐标描述:
右侧虚拟矩形坐标的描述把圆点也包含在内了,是为了防止文字和圆点重叠。
在计算虚拟矩形的高度时有些坑,圆点大小不是固定的,是根据用户动态配置的,圆点的直径可能大于文字的高度,我们就设定虚拟矩形的高度永远都是最大的那个,需要做一些特殊处理。
代码如下:
_getLeftAnchor() { let x = this.center.x - this.radius - this.textReact.width, y = this.center.y - this.textReact.height / 2, diam = this.radius * 2, maxH = diam > this.textReact.height ? diam : this.textReact.height; //矩形的高度 return { x, y, minX: x, maxX: this.center.x + this.radius, minY: this.center.y - maxH / 2, maxY: this.center.y + maxH / 2 }; }
以此类推,描述下面、左面、上面的虚拟矩形坐标。
判断碰撞
判断两个矩形是否覆盖相交,根据矩形的 minX,maxX,minY,maxY 判断相交,原理比较简单,代码如下:
/** * 判断分位是否相交 * @param {*} target */ isAnchorMeet(target) { let react = this.getCurrentRect(), targetReact = target.getCurrentRect(); if ((react.minX < targetReact.maxX) && (targetReact.minX < react.maxX) && (react.minY < targetReact.maxY) && (targetReact.minY < react.maxY)) { return true; } return false; }
创建虚拟文字集合对象
let labels = pixels.map((val) => { let radius = val.pixel.radius + this.style.normal.borderWidth; //圆点半径 return new Label(val.pixel.x, val.pixel.y, radius, fontSize, byteWidth, val.name); });
递归遍历虚拟文字集合、判断是否与其他相交,如果有相交就移动当前文字位子,直到不相交为止。当找不到合适位置时,就选择隐藏当前文字。
代码如下:
do { var meet = false; //本轮是否有相交 for (let i = 0; i < labels.length; i++) { let temp = labels[i]; for (let j = 0; j < labels.length; j++) { if (i != j && temp.show && temp.isAnchorMeet(labels[j])) { temp.next(); meet = true; break; } } } } while (meet);
内容版权声明:除非注明,否则皆为本站原创文章。