Table of Contents
圆形布局-应用场景
在使用 echarts 关系图 graph 时,若要使用圆形或引力自动布局坐标系必须为 null;想要使关系图连线有动态效果,又需要使用动态的路线图 lines,lines 必需使用 cartesian2d 或 geo 的坐标系;因此为了实现动效,只能放弃自动圆形布局,手动计算出一个圆形布局的坐标。
圆形布局-代码示例
/** * 根据中心位置坐标、布局半径、布局数量及布局角度范围,按圆平均计算布局位置 * @param {array} centerPosition 中心位置数组 * @param {number} r 布局半径 * @param {number} number 布局数量 * @param {number} startAngle 布局起始角度,默认为0 * @param {number} endAngle 布局结束角度,默认为360 * @returns 生成的布局位置数组 */export function calcLayoutCircular( centerPosition, r, number, startAngle = 0, endAngle = 360,) { /** * 将传入的任意角度转换为0-360度的角度 * @param {number}} angle 传入角度 * @returns 转换后的角度 */ function normalizeAngle(angle) { // 任意角度相对360度取余数 const normalizedAngle = angle % 360; // 若为负角度则加上360度,转换为正角度 return normalizedAngle < 0 ? normalizedAngle + 360 : normalizedAngle; } startAngle = normalizeAngle(startAngle); endAngle = normalizeAngle(endAngle); let intervalAngle; // 计算间隔角度 // 若角度范围是完整圆周,起始角度与结束角度只占用一个布局数量,按布局数量平均分配角度即可; // 若角度范围不是完整圆周,则起始角度与结束角度会占用两个布局数量,需要以 number - 1 计算角度间隔,若number为1时不减1 if (endAngle - startAngle === 0) { intervalAngle = 360 / number; } else { intervalAngle = normalizeAngle(endAngle - startAngle) / (number - 1 || 1); } // 根据布局数量与间隔角度计算所有布局位置 const positionArr = []; for (let i = 0; i < number; i++) { let angle = normalizeAngle(startAngle + intervalAngle * i); const x = centerPosition[0] + r * Math.sin((angle * Math.PI) / 180); const y = centerPosition[1] + r * Math.cos((angle * Math.PI) / 180); positionArr.push({ angle, position: [x, y], }); } return positionArr;}标签位置-应用场景
使用圆形布局后,当元素标签不放在元素上居中显示,而要根据相对圆心的位置,显示在上、右、下、左等不同方位时,使用此方法计算。
标签位置-代码示例
/** * 根据传入的角度(当前元素相对圆心的角度)计算出标签位置,简单模式只计算左右,非简单模式计算上下左右 * @param {number} angle 传入的角度 * @param {boolean} simple 是否简单模式 * @returns 位置字符串 */export function calcLabelPositionByAngle(angle, simple = true) { if (simple) { if (angle >= 0 && angle < 180) { return "right"; } else { return "left"; } } else { if (angle > 275 || angle <= 45) { return "top"; } else if (angle > 45 && angle <= 135) { return "right"; } else if (angle > 135 && angle <= 215) { return "bottom"; } else if (angle > 215 && angle <= 275) { return "left"; } else { return "top"; } }}