RaphaelJS是一个用JavaScript实现的强大的矢量图形库。
(1)使用前准备,下载RaphaelJS,到官网下载。
(2)在相应的HTML页面引入RaphaelJS,如下示例代码:
import Raphael from 'raphael';
写成一个单独的组件使用
/**
* Raphael JS - 组织结构图/层次结构图/多叉树图
*/
/* eslint-disable */
/* tslint:disable */
import Raphael from 'raphael';
function orgchart(this: any, Px: any, Py: any, D: any, fontSize: any) {
if (!Array.isArray(D)) {
console.log('图谱数据格式错误,请确认!');
return;
}
const data = D;
// 参考原点坐标
const X = Px;
const Y = Py;
// 最大层数/行数
let maxRowNum = 0;
// 最大列数
// const maxColNum = 0;
// 单元格宽度
const cellW = 100;
// 单元格高度
const cellH = 50;
// 水平间距/列距
const hSpace = 10;
// 垂直间距/行距
const vSpace = 50;
// 画布对象
let paper: any;
// 画布宽度
let paperW = 0;
// 画布高度
let paperH = 500;
this.drawChart = function init(): void {
calc();
draw();
};
//
function calc() {
// 统计不重复的父节点总个数
const _rowSet = new Set();
for (let i = 0; i < data.length; i++) {
data[i].xy = {
x: X,
y: Y,
};
//
_rowSet.add(data[i].parentId);
}
//
maxRowNum = _rowSet.size;
// 节点总数-(父节点总数-1); 1--根节点没有父节点,排除
// maxColNum = data.length - (_rowSet.size - 1);
// paperW = maxColNum * (cellW + hSpace);
paperW = 1775;
paperH = maxRowNum * (cellH + vSpace);
paper = new Raphael(X, Y, paperW, paperH);
//
const rootObj = findRoot();
if (rootObj != null) {
calcXY(rootObj, 0);
calcParentXY(rootObj);
}
// console.log("paperW= " + paperW + " paperH= " + paperH + " maxRowNum=
// " + maxRowNum + " maxColNum= " + maxColNum)
}
function calcXY(obj: any, level: any) {
level++;
const childrenArr = getChildren(obj);
for (let i = 0; i < childrenArr.length; i++) {
//
if (i === 0) {
childrenArr[i].xy.x = obj.xy.x;
} else {
let offsetX = 0;
const childrenArr2 = getChildren(childrenArr[i - 1]);
if (childrenArr2.length > 0) {
offsetX = childrenArr2[childrenArr2.length - 1].xy.x;
} else {
offsetX = childrenArr[i - 1].xy.x;
}
childrenArr[i].xy.x = offsetX + (cellW + hSpace);
}
childrenArr[i].xy.y += (cellH + vSpace) * level;
obj.xy.x = childrenArr[i].xy.x;
//
calcXY(childrenArr[i], level);
}
// console.log(" | " + level + " calcXY" + obj.name + " " + obj.xy.x + "
// " + obj.xy.y)
}
function calcParentXY(obj: any) {
const childrenArr = getChildren(obj);
for (let i = 0; i < childrenArr.length; i++) {
calcParentXY(childrenArr[i]);
}
if (childrenArr.length > 0) {
if (childrenArr.length % 2 === 0) {
obj.xy.x = (childrenArr[0].xy.x + childrenArr[childrenArr.length - 1].xy.x) / 2;
} else {
obj.xy.x = childrenArr[Math.floor(childrenArr.length / 2)].xy.x;
}
}
}
function findRoot() {
for (let i = 0; i < data.length; i++) {
if (data[i].parentId === '-1') {
return data[i];
}
}
return null;
}
function getChildren(obj: any) {
const childrenArr = [];
for (let i = 0; i < data.length; i++) {
if (data[i].parentId === obj.id) {
childrenArr.push(data[i]);
}
}
return childrenArr;
}
function draw() {
for (let i = 0; i < data.length; i++) {
drawRect(data[i]);
//
const childrenArr = getChildren(data[i]);
for (let j = 0; j < childrenArr.length; j++) {
drawLine(data[i], childrenArr[j], j === 0);
}
}
}
function drawLine(parentObj: any, obj: any, isFirst: any) {
//
const pPx = parentObj.xy.x + cellW / 2;
const pPY1 = parentObj.xy.y + cellH;
const P_Y = parentObj.xy.y + cellH + vSpace / 2;
//
const pcX1 = obj.xy.x + cellW / 2;
const pcY1 = obj.xy.y;
//
let linePathStr =
' M' +
pcX1 +
' ' +
P_Y +
'L' +
pPx +
' ' +
P_Y +
' M' +
pcX1 +
' ' +
P_Y +
'L' +
pcX1 +
' ' +
pcY1;
if (isFirst) {
linePathStr = 'M' + pPx + ' ' + pPY1 + 'L' + pPx + ' ' + P_Y + linePathStr;
}
//
const line = paper.path(linePathStr);
line.attr({
stroke: '#000',
});
// let txt = paper.text(pcX1, (obj.xy.y + P_Y) / 2, obj.txt1);
// txt.attr({
// fill : "#4169E1",
// "font-size" : 10
// });
}
// 画矩形
function drawRect(obj: any) {
// 若绘圆角矩形加上圆角参数(横坐标,纵坐标,宽,高,圆角)
const rect = paper.rect(obj.xy.x, obj.xy.y, cellW, cellH, 10);
// 鼠标移入移出
// rect.mousemove(function () {
// this.attr("fill", "#ADFF2F");
// });
// rect.mouseout(function () {
// this.attr("fill", "#fff");
// });
// 设置每一栏的背景色
rect.attr({
fill: '#f2f2f2',
title: obj.name,
});
if (obj.txt1) {
paper.text(obj.xy.x + cellW / 2, obj.xy.y + cellH / 2 - 10, obj.name);
const txt = paper.text(obj.xy.x + cellW / 2, obj.xy.y + cellH / 2 + 10, obj.txt1);
txt.attr({
fill: '#333',
'font-size': fontSize,
});
} else {
paper.text(obj.xy.x + cellW / 2, obj.xy.y + cellH / 2, obj.name);
}
}
}
export default orgchart;
需要使用的地方引用
import Orgchart from './raphael-orgchart';
使用的时候 参数分别是xy的位置 数据源 和字体大小
页面创建时生成
created(): void {
const chart = new Orgchart(64, 100, this.collectionPlatesData, 12);
//使用
chart.drawChart();
}
具体参数可查看文档 RaphealJS