Closed vieyahn2017 closed 5 years ago
代码如下 demo2.html
<!doctype html>
<meta charset="utf-8">
<title>Dagre D3 Demo: Sentence Tokenization</title>
<link rel="stylesheet" href="demo.css">
<script src="d3.min.js" charset="utf-8"></script>
<script src="dagre-d3.js"></script>
<script src="diag.js"></script>
<style id="css">
/* This sets the color for "TK" nodes to a light blue green. */
g.type-suss>rect {
fill: #ddefd3;
}
.node text {
font-weight: 300;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
font-size: 12px;
pointer-events: none;
text-anchor: middle;
fill: white;
}
.label g text tspan:last-child {
font-size: 10px;
margin-top: 5px;
dy: 1.5em;
}
.label g {
transform: translate(0, -13px);
}
.node rect {
fill: white;
stroke-width: 0px;
color: white;
}
.edgePath path {
stroke: rgb(78, 78, 78);
stroke-width: 1px;
}
g.type-init>rect {
fill: rgba(0, 91, 252, 0.4);
}
g.type-ready>rect {
fill: rgba(0, 91, 252, 0.6);
}
g.type-queue>rect {
fill: rgba(0, 91, 252, 0.8);
}
g.type-run>rect {
fill: rgba(0, 91, 252, 1);
}
g.type-suss>rect {
fill: #3EBB44;
}
g.type-fail>rect {
fill: #E93A3A;
}
g.type-freeze>rect {
fill: #f2f3f7;
}
.type-freeze text {
fill: #999999;
}
#myMenu{
position: absolute;
display: none;
width: 100px;
height: 100px;
background: #999999;
}
</style>
<svg id="svgCanvas" width=960 height=900></svg>
<ul id="myMenu">
<li>xx</li>
<li>xx</li>
</ul>
<script id="js">
var state = [
{ id: 1, label: 'V1\n数据同步', class: 'type-suss' },
{ id: 2, label: 'V2\nhive-sql', class: 'type-suss' },
{ id: 3, label: 'V3\nspark-sql', class: 'type-init' },
{ id: 4, label: 'V4\nshell', class: 'type-ready' },
{ id: 5, label: 'V5\npython', class: 'type-fail' },
{ id: 6, label: 'V6\n虚节点', class: 'type-suss' },
{ id: 7, label: 'V7\nspark-sql', class: 'type-suss' },
{ id: 8, label: 'V8\nshell', class: 'type-freeze' },
{ id: 9, label: 'V9\n数据同步', class: 'type-suss' },
{ id: 10, label: 'V10\nshell', class: 'type-queue' },
{ id: 11, label: 'V11\nspark-sql', class: 'type-run' },
{ id: 12, label: 'V12\nspark-sql', class: 'type-suss' },
{ id: 13, label: 'V13\n虚节点', class: 'type-init' },
{ id: 14, label: 'V14\n数据同步', class: 'type-fail' },
{ id: 0, label: 'V15\nhive-sql', class: 'type-freeze' },
]
var edg = [
{ start: 1, end: 4, option: {} },
{ start: 1, end: 3, option: {} },
{ start: 1, end: 2, option: {} },
{ start: 6, end: 7, option: {} },
{ start: 5, end: 6, option: {} },
{ start: 9, end: 10, option: {} },
{ start: 8, end: 9, option: {} },
{ start: 11, end: 12, option: {} },
{ start: 8, end: 11, option: {} },
{ start: 5, end: 8, option: {} },
{ start: 1, end: 5, option: {} },
{ start: 13, end: 14, option: {} },
{ start: 1, end: 13, option: {} },
{ start: 0, end: 1, option: {} }
]
var statePoint = 1; // 当前选中的点
diagGraph.init(statePoint, state, edg); //创建关系图
var svgCanvas = document.getElementById('svgCanvas'); //绑定事件鼠标点击
svgCanvas.addEventListener('click', function (e) {
e.preventDefault();
if (e.target.tagName === 'rect') {
diagGraph.changePoint(e.target.parentNode.id);
}
})
var myMenu = document.getElementById("myMenu"); //鼠标右键
svgCanvas.addEventListener("contextmenu", (event) => { //鼠标右击事件
event.preventDefault();
if (event.target.tagName === 'rect') {
myMenu.style.top = event.clientY + "px";
myMenu.style.left = event.clientX + "px";
myMenu.style.display = 'block'
// this.myMenuShow = true
}
});
document.addEventListener("click", (event) => {
myMenu.style.display = 'none'
});
</script>
diag.js
var diagGraph = { //diag图数据操作
state: [],
edg: [],
statePoint: '',
g: '',
init: function (statePoint ,state, edg) {
this.statePoint = statePoint
this.state = state
this.edg = edg
this.createG();
this.renderG();
},
createG: function () {
this.g = new dagreD3.graphlib.Graph()
.setGraph({})
.setDefaultEdgeLabel(function () { return {}; });
},
drawNode: function () {
for (let i in this.state) { //画点
let el = this.state[i]
let style = ''
if (el.id === this.statePoint) {
if (el.class === 'type-suss') {
style = "stroke: #35b34a; stroke-width: 1px;"
} else if (el.class === 'type-fail') {
style = "stroke:#f15533; stroke-width: 1px;"
} else if (el.class === 'type-normal') {
style = "stroke:#a5e0ee; stroke-width: 1px;"
} else if (el.class === 'type-init') {
style = "stroke:#a5e0ee; stroke-width: 1px;"
} else if (el.class === 'type-ready') {
style = "stroke:#a5e0ee; stroke-width: 1px;"
} else if (el.class === 'type-queue') {
style = "stroke:#a5e0ee; stroke-width: 1px;"
} else if (el.class === 'type-run') {
style = "stroke:#a5e0ee; stroke-width: 1px;"
} else if (el.class === 'type-freeze') {
style = "stroke:grey; stroke-width: 1px;"
}
}
this.g.setNode(el.id, {
id: el.id,
label: el.label,
class: el.class,
style: style,
});
}
this.g.nodes().forEach((v) => { //画圆角
var node = this.g.node(v);
// Round the corners of the nodes
node.rx = node.ry = 5;
});
},
drawEdg: function () {
for (let i in this.edg) { // 画连线
let el = this.edg[i]
if (el.start === this.statePoint || el.end === this.statePoint) {
this.g.setEdge(el.start, el.end, {
style: "stroke: #0fb2cc; fill: none;",
arrowheadStyle: "fill: #0fb2cc;stroke: #0fb2cc;",
arrowhead: 'vee'
});
} else {
this.g.setEdge(el.start, el.end, {
arrowhead: 'vee'
});
}
}
},
renderG: function () {
var render = new dagreD3.render();
var svg = d3.select("#svgCanvas");
svg.select("g").remove(); //删除以前的节点
var svgGroup = svg.append("g");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function () { //放大
inner.attr("transform", d3.event.transform);
});
svg.call(zoom);
this.drawNode();
this.drawEdg();
render(d3.select("svg g"), this.g); //渲染节点
var max = svg._groups[0][0].clientWidth > svg._groups[0][0].clientHeight ? svg._groups[0][0].clientWidth : svg._groups[0][0].clientHeight;
var initialScale = max / 779;
var tWidth = (svg._groups[0][0].clientWidth - this.g.graph().width * initialScale) / 2;
var tHeight = (svg._groups[0][0].clientHeight - this.g.graph().height * initialScale) / 2;
svg.call(zoom.transform, d3.zoomIdentity.translate(tWidth, tHeight).scale(initialScale)); //元素居中
},
changePoint: function (point) {
this.statePoint = point * 1.0
this.renderG()
},
}
demo.class
body {
width: 960px;
margin: 0 auto;
/* color: #333; */
font-weight: 300;
color: white;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
}
h1 {
font-size: 3em;
font-weight: 300;
}
h2 {
font-size: 1.5em;
font-weight: 300;
}
section {
margin-bottom: 3em;
}
section p {
text-align: justify;
}
svg {
border: 1px solid #ccc;
overflow: hidden;
margin: 0 auto;
}
pre {
border: 1px solid #ccc;
}
我把html里面的js事件绑定修改如下,进行测试:
var statePoint = 1; // 当前选中的点
diagGraph.init(statePoint, state, edg); //创建关系图
var svgCanvas = document.getElementById('svgCanvas'); //绑定事件鼠标点击
// svgCanvas.addEventListener('click', function (e) {
// e.preventDefault();
// if (e.target.tagName === 'rect') {
// diagGraph.changePoint(e.target.parentNode.id);
// }
// })
var myMenu = document.getElementById("myMenu"); //鼠标右键
svgCanvas.addEventListener("click", (event) => { //鼠标右击事件
event.preventDefault();
if (event.target.tagName === 'rect') {
myMenu.style.top = event.clientY + "px";
myMenu.style.left = event.clientX + "px";
myMenu.style.display = 'block';
// this.myMenuShow = true
}
});
// document.addEventListener("click", (event) => {
// myMenu.style.display = 'none'
// });
改成了左键,还需要优化
https://github.com/xuhuihui/svg