請勿複製源碼 代碼僅供參考
首先 安裝d3和jquery
npm install d3 --save
npm install jquery --save-dev
在頁面中引入
import * as d3 from 'd3';
import $ from 'jquery';
<template>
<div class="warp">
<el-button type="success" class="btn-success" @click="returnLast">返回上一頁</el-button>
<div class="content">
</div>
<div class="looplist show">
<div class="rightBtn" @click="changeShowRight">
<label class="show" id="right_show">{{showRightText}}</label>
</div>
<div class="rightContent">
<strong>漏洞信息</strong>
<ul>
</ul>
</div>
</div>
<div class="systemlist" id="system_info">
<!--<label class="show" id="left_show"><</label>-->
<ul>
<li>
<label>操作系統:</label>
<span id="operate_system">未知</span>
</li>
<li>
<label>開發語言:</label>
<span id="use_language">未知</span>
</li>
<li>
<label>CDN:</label>
<span id="use_cdn">未知</span>
</li>
<li>
<label>WAF:</label>
<span id="use_waf">未知</span>
</li>
</ul>
</div>
<div class="toolbar">
<div class="btn-showOrHide">
<label class="show" id="download_show" @click="changeBottomShow">{{showBottomText}}</label>
</div>
<ul v-show="showBottom"></ul>
</div>
</div>
</template>
<style >
html,body{
width:100%;
overflow:hidden;
}
g.type-suss>rect {fill: #ddefd3;}
.node {
cursor: pointer;
}
g.node circle {
fill: #dff0e7;
stroke: #3fc96e;
stroke-width: 1px;
}
g.node rect {
padding: 5px;
fill: #dff0e7;
stroke: #3fc96e;
stroke-width: 1px;
}
g.node text {
color: #2dbb8a;
font: 14px sans-serif;
font-weight:700;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 2px;
}
ul li{
list-style: none;
}
.btn-success{
width: 220px;
position: absolute;
top:16px;
left: 20px;
background: #2dbb8a;
border-color: #2dbb8a;
}
.content{
width: 100%;
height: 100%;
}
.systemlist{
position: absolute;
left: 20px;
top: 70px;
width: 220px;
height: 160px;
background-color: #fff;
border:1px solid #d8e1e4;
border-radius: 4px;
padding: 20px;
padding-bottom: 0;
box-sizing: border-box;
font-size: 12px;
color: #687386;
}
.systemlist ul{
list-style: none;
padding-left: 0px;
margin:0;
}
.systemlist ul li{
width: 100%;
margin-bottom: 10px;
}
.systemlist ul li label{
display: inline-block;
font-weight: bold;
}
.isRed{
stroke: #f1602d;
}
.toolbar{
padding: 0px 2px;
position: absolute;
left: 0px;
bottom: 0;
right:204px;
background-color: #d8e1e4;
border-radius: 2px;
opacity:0.5;
overflow-y:scroll;
}
.toolbar ul{
height:216px;
}
.systemlist .show{
position: absolute;
width: 20px;
height: 45px;
top: 50%;
margin-top: -16px;
left: 199px;
background-color: #fff;
border:1px solid #d8e1e4;
color: #a1b0b5;
text-align: center;
line-height: 42px;
cursor: pointer;
}
.btn-showOrHide{
width:100%;
height:24px;
}
.toolbar .show{
width: 56px;
display: block;
height: 100%;
background-color: #fff;
border:1px solid #d8e1e4;
color: #a1b0b5;
margin:0 auto;
text-align: center;
cursor: pointer;
}
/*漏洞信息*/
.looplist{
position: absolute;
right: 0;
top: 0;
background-color: #fff;
height: 100%;
box-sizing: border-box;
border-left: 1px solid #d8e1e4;
}
.looplist ul{
padding-left: 0px;
}
.looplist .rightBtn{
width:21px;
height: 100%;
display: flex;
align-items: center;
float: left;
}
.looplist .rightBtn label{
width: 20px;
height: 45px;
background-color: #fff;
border:1px solid #d8e1e4;
color: #a1b0b5;
text-align: center;
line-height: 42px;
cursor: pointer;
}
.looplist .rightContent{
float:left;
width: 196px;
font-size: 14px;
color: #687386;
padding-top: 10px;
padding-bottom: 10px;
margin-left: -15px;
padding-right:5px;
}
.looplist >div li{
color: #687386;
font-size: 12px;
height: 40px;
line-height: 40px;
border-bottom: 1px solid #d8e1e4;
display:block;
overflow:hidden;
white-space:nowrap;
text-overflow:ellipsis;
}
</style>
<script>
export default({
name:'experiencetree',
data(){
return{
treeData: [],
showRight: true,
showBottom: true,
showRightText: '>',
showBottomText: '∨'
}
},
created:function(){
this.$store.state.activefirstMenu="/tree";
API.findExperienceTree().then(res => {
this.treeData =****** ;
let that = this;
let reg = new RegExp("[\\u4E00-\\u9FFF]+","g");
//定義樹圖的全局屬性(寬高)
let margin = {top:0, right: 0, bottom: 0, left: 0},
width = 1700 - margin.right - margin.left,
height = 800 - margin.top - margin.bottom;
let i = 0,
duration = 750,
root;
let tree = d3.layout.tree()//創建一個樹佈局
.size([height, width])
.nodeSize([4, 1])
.separation(function(a, b) { return (a.parent == b.parent ? 10 : 8); });
let diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
// Setup zoom and pan
let zoom = d3.behavior.zoom()
.scaleExtent([.1,1])
.on('zoom', function(){
if($("#myMenu").css("display")=="block"){
$('#myMenu').hide();
}
let tran = (Number(d3.event.translate.toString().split(',')[0])+100)+','+(Number(d3.event.translate.toString().split(',')[1])+400)
svg.attr("transform", "translate(" + tran + ") scale(" + d3.event.scale + ")");
});
let svg = d3.select(".content").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.call(zoom)
.append("g")
.attr("transform", "translate(100,400)");
generate();
function generate(){
root = that.treeData[0];
root.x0 = height / 2;
root.y0 = 0;
update(root);
d3.select(self.frameElement).style("height", "1600px");
}
function update(source) {
let nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
nodes.forEach(function(d) { d.y = d.depth * 400; });
let node = svg.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });//data():綁定一個數組到選擇集上,數組的各項值分別與選擇集的各元素綁定
let nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
.on("click", click);
//添加連接點---此處設置的是圓圈過渡時候的效果(顏色)
// nodeEnter.append("circle")
// .attr("r", 1e-6)
// .style("fill", function(d) { return d._children ? "lightsteelblue" : "#357CAE"; });//d 代表數據,也就是與某元素綁定的數據。
nodeEnter.append("rect")
.attr("x",function(d) { return 0})
.attr("y", -8)
.attr("width", function(d) {
if (reg.test(d.name)){
return d.name.length * 10 + 24;
}else{
if (d.name.length < 6){
return d.name.length * 16;
}else{
return d.name.length * 8;
}
}
})
.attr("height",25)
.attr("rx",10)
.style("fill", function(d){
if(d.isRed == true){
return "#f1602d";
}else{
return "#dff0e7"
}
});//d 代表數據,也就是與某元素綁定的數據。// 小方塊的背景顏色綠色
nodeEnter.append("text")
.attr("x", function(d) {
if (reg.test(d.name)){
return (d.name.length * 10 + 24) / 2;
}else{
if (d.name.length < 6){
return d.name.length * 16 / 2;
}else{
return d.name.length * 8 / 2;
}
}
})
.attr("dy", "10")
.attr("text-anchor", "middle")
.text(function(d) { return d.name; })
.style("fill", function(d){
if(d.isRed == true){
console.log(d);
paint_right_message(d);
return "#fff";
}else{
return "#2dbb8a";
}
})
.style("fill-opacity", 1);
let nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });//Y
let nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })//Y
.remove();
//再處理連線集合
let link = svg.selectAll("path.link")
.data(links, function(d) { return d.target.id; });
// Enter any new links at the parent's previous position.
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", function(d) {
let o = {x: source.x0, y: source.y0};//YES
return diagonal({source: o, target: o});
})
.attr('marker-end', 'url(#arrow)');
link.transition()
.duration(duration)
.attr("d", diagonal);
link.exit().transition()
.duration(duration)
.attr("d", function(d) {
let o = {x: source.x, y: source.y};//NO
return diagonal({source: o, target: o});
})
.remove();
// Stash the old positions for transition.將舊的斜線過渡效果隱藏
nodes.forEach(function(d) {
d.x0 = d.y;
d.y0 = d.x;
});
}
// Toggle children on click.切換子節點事件
function click(d) {
if($("#myMenu").css("display")=="block"){
$('#myMenu').hide();
}
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
})
},
mounted:function(){
},
methods: {
returnLast(){
this.$router.push({name: 'createtask'})
},
changeShowRight(){
if(!this.showRight){
$('.looplist').animate({'right': '0px'}, 800);
this.showRightText=">"
}else{
$('.looplist').animate({'right': '-180px'}, 800);
this.showRightText="<"
}
this.showRight = !this.showRight
},
changeBottomShow(){
if(!this.showBottom){
this.showBottomText="∨"
}else{
this.showBottomText="∧"
}
this.showBottom = !this.showBottom
}
}
})
</script>