開發環境
- angular v6
- Node v8.12.0
安裝依賴
npm install dagre-d3 --save
npm install d3 --save
在 angular 中引用
import * as d3 from "d3";
import dagreD3 from "dagre-d3";
chart.html
<svg width="80vw" height="30vw">
<g />
</svg>
創建graph對象
let svg = d3.select("svg"),
inner = svg.select("g");
// Left-to-right layout
let g = new dagreD3.graphlib.Graph().setGraph({
nodesep: 70, // 節點之間間距
ranksep: 100, // 層與層之間的間距
rankdir: "LR",
});
生成節點與連線
let labelType = "html";
for (let i = 0; i < flows.length; i++) {
if (!flows[i]) {
return;
}
let { id, parentId } = flows[i];
let label = this.container.createEmbeddedView(this.flowChip, {
flow: flows[i],
}).rootNodes[0];
g.setNode(id, { labelType, label });
if (parentId) {
g.setEdge(parentId, id, {
arrowhead: "vee",
label: "",
});
}
let children = flows[i].children || [];
if (children.length > 0) {
this.generateFlowChart(children, g);
}
}
生成svg圖像
var render = new dagreD3.render();
render(inner, g);
添加擴展功能
// 縮放
var zoom = d3
.zoom() // 縮放支持
.scaleExtent([0.5, 2]) // 縮放範圍
.on("zoom", function () {
let pos = d3.event.transform;
// 這裏偶爾會出錯,賦默認值
if (isNaN(pos.x)) pos.x = 0;
inner.attr("transform", pos);
});
let { clientWidth, clientHeight } = svg._groups[0][0];
let { width, height } = g.graph();
let initScale = 0.75;
svg.call(zoom); // 縮放生效
// 居中,默認縮放比例
svg
.transition()
.duration(1000) // 1s完成過渡
.call(
zoom.transform,
d3.zoomIdentity // 居中顯示
.translate(
(clientWidth - width * initScale) / 2,
(clientHeight - height * initScale) / 2
)
.scale(initScale) // 默認縮放比例
);
input data
[
{
"id": 65,
"parentNo": null,
"relationType": null,
"children": [
{
"parentNo": null,
"relationType": null,
"children": []
}
]
},
{
"id": 65,
"parentNo": null,
"relationType": null,
"children": [
{
"parentNo": null,
"relationType": null,
"children": []
}
]
}
]