最初のケースの下に2つのノード間で描画されたデータ・パスを取得した後、現在のサービス要件、入力ノード2は、図1のビューを使用する前に、メッシュはメッシュが、無効、必要性はのフローチャートにモードを変換します:
それでは、どのよう、データを変更することなく、同様の効果を達成ニジェール?
echartsは、グラフの種類の下で見て、あなたが似て達成することができ、次は公式の例であり、
例から分かるように、難易度はノードx、yおよび曲線の表示位置を設定することです。サービスデータ:
1、変数ノードの数は、可変数の関係
図2に示すように、データは、単一のノード情報との関係情報を戻します
アイデアの実現:
ライン(XINDEX情報ノード)の位置を得るために1、データ解析、取得前後のノードとの間の関係、
開始ノードと1に設定されたノードアレイXINDEXに見出される、その後の第二の層のノードを探し始めます
// 获取节点的x轴顺序
setNodeOrder () {
this.entityList.forEach(item => {
if (item.id === this.startNode) {
item.xIndex = 1;
}
// 设置一个对象,记录节点信息,用于后面查询信息,比数组查询来的快
this.nodesObj[item.id] = item;
});
this.findNodeOrder(2, this.startNode);
}
// 广度遍历--按顺序找到第index层的数据,并设置对应的参数,再层层递进
findNodeOrder (xIndex, sId){
}
ノードは、第二の層である場合、送信元または宛先ノードがそうでstartNodeがstartNodeであり、そして、その後の関係がなければならない、考える、プログレッシブ層、
幅ではなく、深さトラバーサルを横断するために使用される必要がある、二つの配列を設定し、次のように現在層、記録層afterQueueノードcurrentQueueにafterQueue後層currentQueueを横断するとき、トラバーサルは、コアコードの終わりまで続く記録currentQueueノードです。
......
let nextIds = [];
this.relationList.forEach(item => {
// 源
if (item.source === sId) {
if (!this.nodesObj[item.target].xIndex) {
this.nodesObj[item.target].xIndex = xIndex;
nextIds.push(item.target);
}
}
// 目的
if (item.target === sId) {
if (!this.nodesObj[item.source].xIndex) {
this.nodesObj[item.source].xIndex = xIndex;
nextIds.push(item.source);
}
}
});
let nextIdsLen = nextIds.length;
// 1、没有当前的队列,没有后续的队列,有nextIds
if (
!this.currentQueue.length &&
!this.afterQueue.length &&
nextIdsLen
) {
this.currentQueue = nextIds;
this.currentXindex = this.currentXindex + 1;
this.setNextOrder();
} else if (this.currentQueue.length && nextIdsLen) {
// 2、有当前的队列在遍历,排队
this.afterQueue = this.afterQueue.concat(nextIds);
} else if (!this.currentQueue.length && this.afterQueue.length) {
// 3、没有当前的队列了,有排队的队列,则排队的进去
if (nextIdsLen) {
this.afterQueue = this.afterQueue.concat(nextIds);
}
this.currentQueue = JSON.parse(JSON.stringify(this.afterQueue));
this.afterQueue = [];
this.currentXindex = this.currentXindex + 1;
}
setNextOrder機能:
js// 设置下个 setNextOrder () { while (this.currentQueue.length) { let id = this.currentQueue.shift(); this.findNodeOrder(this.currentXindex, id); } }
列の数を行数を設定位置情報に基づいて2、(YINDEX層ノード情報)
第一及び第二層の第一ソート順、第一の層上のノードとの間の関係、第一層と第2層とが同じで、順序は問題ではないので、それは直接的に遭遇重ね合わせることができます
// 排完了x,再排列y
// 先排第一和二行的元素的y,按顺序排
let maxXindex = 1;
let secondYIndexObj = {};
for (let i in this.nodesObj) {
let item = this.nodesObj[i];
if (!item.yIndex) {
maxXindex = item.xIndex > maxXindex ? item.xIndex : maxXindex;
if (item.xIndex === 1) {
item.yIndex = 1;
this.yIndexObj[item.id] = {
xIndex: 1,
yIndex: 1
};
}
if (item.xIndex === 2) {
if (!secondYIndexObj[item.xIndex]) {
item.yIndex = 1;
// 记录当前的y轴上的节点个数
secondYIndexObj[item.xIndex] = 1;
this.yIndexObj[item.id] = {
xIndex: 2,
yIndex: 1
};
} else {
item.yIndex = secondYIndexObj[item.xIndex] + 1;
secondYIndexObj[item.xIndex] = item.yIndex;
this.yIndexObj[item.id] = {
xIndex: 2,
yIndex: item.yIndex
};
}
}
}
}
しかし、第3層は、方法を制御するために、第2層の順に、注意を払うようにすることはできません開始します。第二及び第三の層は、関係の数と、ランダムワイヤ混乱が生じる可能性があることを配置した場合には、必ずしもではないので、最良の方法は、第2の層の順序、取得のための第三の層です。N番目のノードは、第N層上に配置された第二の層は約についてです。この数が第2の層の数と第三の層に等しい場合、それは完全に直線アップします。数字は、そう混乱することがない場合は - が、ノードの第二層と第三層と複数のノードがある場合の関係を有し、今回は〜のランダムに選択されたレベルを選択しました
// 从第三层开始
if (maxXindex > 2) {
// 后面列的排序根据前一列为准(尽量保证在一条直线上)
for (let j = 3; j <= maxXindex; j++) {
for (let i in this.nodesObj) {
let item = this.nodesObj[i];
while (item.xIndex === j && !item.yIndex) {
// 先看跟它一层的节点有多少个
if (!this.nodeOrders[j]) {
let totals = this.findYtotal(j);
this.nodeOrders[j] = [];
for (let i = 1; i <= totals; i++) {
this.nodeOrders[j].push(i);
}
}
// 找第二层中的对应的层级
let findX = j - 1;
// 找到所有的层级
let findYs = this.findLinkNode(item.id, findX);
// 找到还有的层级
let sameArr = findYs.filter(x =>
this.nodeOrders[j].includes(x)
);
let findY;
// 找不到按顺序抽取了
if (!sameArr.length) {
// 只能随机选择一个了
let ran = Math.floor(
Math.random() * this.nodeOrders[j].length
);
findY = this.nodeOrders[j][ran];
this.nodeOrders[j].splice(ran, 1);
} else {
findY = sameArr[0];
// 去除该顺序
let order;
this.nodeOrders[j].find((num, k) => {
if (num === findY) {
order = k;
return true;
}
});
this.nodeOrders[j].splice(order, 1);
}
this.yIndexObj[item.id] = {
xIndex: j,
yIndex: findY
};
item.yIndex = findY;
}
}
}
}
図3に示すように、特定の場所を設定します
上記相互に応じて、チャートの中心位置、途中の開始と終了のy位置を、取得しYINDEXはXINDEXも間隔(gapX、gapY)とノード(サイズ)を設けた場合の大きさから算出取得CenterY XとYのノード情報
// 设置节点的位置x,y
setNodesPositon () {
for (let i in this.nodesObj) {
let item = this.nodesObj[i];
if (item.id === this.startNode) {
item.y = this.centerY;
item.x = 1;
}
if (!item.x) {
item.x = this.gapX * (item.xIndex - 1) + this.size / 2;
}
if (!item.y && !item.total) {
item.total = this.findYtotal(item.xIndex);
if (item.total === 1) {
item.y = this.centerY;
} else {
let middleNum = item.total / 2;
let ceilNum = Math.ceil(middleNum);
let topGap;
let bottomGap;
let ty = (ceilNum - item.yIndex) * (this.gapY + this.size);
let by = (item.yIndex - ceilNum) * (this.gapY + this.size);
if (item.total % 2 === 1) {
topGap = this.centerY - ty;
bottomGap = this.centerY + by;
} else {
topGap = this.centerY - (ty + this.gapY + 0.5 * this.size);
bottomGap = this.centerY + (by - 0.5 * this.size);
}
if (item.yIndex <= middleNum) {
item.y = topGap;
} else {
item.y = bottomGap;
}
// 奇数
if (item.total % 2 === 1) {
if (item.yIndex === ceilNum) {
item.y = this.centerY;
}
}
}
}
}
}