树型图和进度条
//进度条组件
<template>
<!-- TreeTable进度条组件 -->
<div class="tree-table">
<div class="search">
<el-select
v-model="select_value"
placeholder="请选择"
style="width: 120px"
size="mini"
class="select"
>
<el-option
v-for="(item, index) in selectArr"
:key="item"
:value="item"
@click.native="sel_click(index)"
>
</el-option>
</el-select>
<el-input
v-model="input"
placeholder="Tree ID"
style="width: 120px"
size="mini"
></el-input>
<el-button
type="primary"
@click="onAdmin('search')"
class="btn_search left_btn"
icon="el-icon-my-search"
></el-button>
<el-button
class="btn_search"
icon="el-icon-my-refresh-right"
@click="onAdmin('refresh')"
></el-button>
</div>
<!-- title -->
<div class="title-box">
<span class="title">Tree</span>
<div class="list-right">
<span>Tree Size:max</span>
<div class="Gradual-change"></div>
<span>min</span>
</div>
</div>
<!-- 进度条 -->
<div class="Gradual-change-box">
<span
v-for="(item, index) in newArr"
:key="index"
:class="
glItem == index ? 'Gradual-change-item-gl' : 'Gradual-change-item'
"
@click="setGlItem(item, index)"
:style="index == 0 ? 'borderRadius:5px 0px 0px 5px' : ''"
>
<!-- : index == Arr.length - 1
? 'borderRadius:0px 5px 5px 0px;marginRight:0px' -->
<img :src="jt" alt="" v-if="glItem == index" />
</span>
</div>
</div>
</template>
<script>
import jiantou from "../../../../../assets/images/svg/common_arrow_up.svg"; //引用选中的箭头图片
export default {
props: ["TreeTableItem", "data"],
components: {},
data() {
return {
input: "", //查询的值
Arr: this.data.data, //所以的数据
newArr: [this.data.data[0], this.data.data[1], this.data.data[2]], //渲染的数据
selectArr: this.data.model, //下拉的数据
select_value: this.data.model[0],
glItem: 0, //当前选中的下表
jt: jiantou, //选中的箭头图片
};
},
methods: {
setGlItem(item, index) {
//改变高亮,给父组件选中项的方法
this.glItem = index;
this.$emit("TreeTableItem", item, index);
},
sel_click(index) {
let arr = JSON.parse(JSON.stringify(this.Arr));
if (index == 0) {
let newArr = arr.slice(index, index + 3);
this.newArr = newArr;
} else {
let newArr = arr.slice(index * 3, (index + 1) * 3);
this.newArr = newArr;
}
},
onAdmin(type) {
//查询与重置
if (type == "search") {
console.log("查询");
if (this.input == "") {
this.glItem = 0;
this.$emit("TreeTableItem", this.newArr[this.glItem], this.glItem);
} else {
if (this.input * 1 > 0 && this.input * 1 <= this.newArr.length) {
this.glItem = this.input - 1;
this.$emit("TreeTableItem", this.newArr[this.glItem], this.glItem);
} else {
this.$message.error("为查询到此选项");
}
}
} else {
console.log("重置");
this.input = "";
this.glItem = 0;
this.select_value = this.selectArr[0];
this.$emit("TreeTableItem", this.newArr[this.glItem], this.glItem);
}
},
},
created() {
console.log(this.data, "199999");
},
};
</script>
<style lang="scss" scoped>
.select {
margin-right: 10px;
}
.tree-table {
width: 100%;
height: 130px;
}
.title-box {
width: 100%;
color: #333333 100%;
font-size: 12px;
margin-bottom: 10px;
margin-top: 10px;
.list-right {
float: right;
display: flex;
.Gradual-change {
width: 120px;
height: 5px;
margin: 7px 10px 0px 10px;
background: linear-gradient(139deg, rgba(60, 121, 242, 1), #ffffff);
border-radius: 5px 5px 5px 5px;
}
}
}
.Gradual-change-box {
width: 100%;
height: 40px;
border-radius: 5px;
background-color: rgba(241, 242, 246, 1);
// overflow: hidden;
display: flex;
.Gradual-change-item {
width: 20px;
height: 40px;
opacity: 0.5;
background-color: rgba(60, 121, 242, 1);
margin-right: 2px;
cursor: pointer;
}
.Gradual-change-item-gl {
width: 20px;
height: 40px;
background-color: rgba(60, 121, 242, 1);
margin-right: 2px;
cursor: pointer;
position: relative;
img {
position: absolute;
left: 5px;
top: 45px;
}
}
}
.left_btn {
margin-left: 20px;
}
</style>
//树型结构图
<template>
<div class="header">
<!-- <div id="container"></div> -->
<TreeTable :data="this.data" @TreeTableItem="TreeTableItem"></TreeTable>
<div>Tree Id:0 Tree Size: 15</div>
<div class="main-content-box">
<svg id="svg-canvas" width="1850" height="500">
<g />
<rect />
</svg>
</div>
</div>
</template>
<script>
import TreeTable from "./tree-table.vue";
import G6 from "@antv/g6";
import dagreD3 from "dagre-d3";
// 不要去除d3
import * as d3 from "d3";
export default {
name: "nodeByDiy",
props: {
data: {
type: Object,
},
},
data() {
return {
state: [],
edg: [],
g: "",
listData: null,
page: {
currentPage1: 1,
page_size1: 20,
// 用户查询后的总共条数
allCount: 0,
},
//树型图的数据结构
trees: {
data: [
{
edg: [
{
end: 1,
start: 0,
},
{
end: 2,
start: 0,
},
{
end: 3,
start: 1,
},
],
state: [
{
label: "",
id: 0,
},
{
label: "",
id: 1,
},
{
label: "",
id: 2,
},
],
},
{
edg: [
{
end: 1,
start: 0,
},
{
end: 2,
start: 0,
},
{
end: 3,
start: 1,
},
],
state: [
{
label: "",
id: 0,
},
{
label: "",
id: 1,
},
{
label: "",
id: 2,
},
],
},
],
},
};
},
components: {
TreeTable,
},
created() {},
mounted() {
this.TreeTableItem(this.data.data[0], 0, "moren");
},
methods: {
//演示=======>TreeTable组件必传方法
TreeTableItem(item, index) {
console.log(item, "当前选中的值", index, "当前选中的下表");
this.getTree(item);
},
getTree(item) {
this.g = new dagreD3.graphlib.Graph()
.setGraph({})
.setDefaultEdgeLabel(function () {
return {};
});
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.data.data.forEach((item) => {
// this.draw(item);
// });
this.draw(item);
// this.drawNode(); //画点
// this.drawEdg(); // 画连线
render(d3.select("svg g"), this.g); //渲染节点
let 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; //initialScale元素放大倍数,随着父元素宽高发生变化时改变初始渲染大小
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)
); //元素水平垂直居中
},
draw(item) {
for (let i in item.state) {
//画点
let el = item.state[i];
this.g.setNode(i, {
rx: 5,
ry: 5,
width: 135,
height: 60,
id: i,
label: el.label,
class: el.class,
style: "fill: #3c79f2;",
});
}
for (let k in item.edg) {
// 画连线
let el = item.edg[k];
this.g.setEdge(el.start, el.end, {
style: "stroke: #0fb2cc; fill: none;",
arrowheadStyle: "fill: #0fb2cc;stroke: #0fb2cc;",
arrowhead: "vee",
});
}
},
// drawNode() {
// for (let i in this.state) {
// //画点
// let el = this.data.state[i];
// this.g.setNode(i, {
// rx: 5,
// ry: 5,
// width: 150,
// height: 60,
// id: i,
// label: el.label,
// class: el.class,
// style: "fill: #3c79f2;",
// });
// }
// },
// drawEdg(arr) {
// for (let i in this.edg) {
// // 画连线
// let el = this.data.edg[i];
// this.g.setEdge(el.start, el.end, {
// style: "stroke: #0fb2cc; fill: none;",
// arrowheadStyle: "fill: #0fb2cc;stroke: #0fb2cc;",
// arrowhead: "vee",
// });
// }
// },
// getInit() {
// var g = new dagreD3.graphlib.Graph();
// console.log(g, "ggg");
// // 注册节点。类型为开始或者结束类型
// G6.registerNode(
// "start-or-end",
// {
// drawShape: function (_cfg, group) {
// let width = cfg.size[0];
// let height = cfg.size[1];
// let stroke = cfg.style.stroke; // 样式属性,元素的描边色
// let fill = cfg.style.fill; // 样式属性,元素的填充色
// let rect = group.addShape("rect", {
// attrs: {
// x: -width / 2,
// y: -height / 2,
// width,
// height,
// radius: height / 2,
// stroke,
// fill,
// lineWidth: 1,
// },
// name: "start-or-end",
// });
// return rect;
// },
// },
// "single-node"
// );
// console.log(G6.registerNode, "G6.registerNode");
// // 注册节点。类型为子流程类型节点
// G6.registerNode(
// "sub-process",
// {
// drawShape: function (cfg, group) {
// console.log(cfg, "---", group, "gr");
// let width = cfg.size[0];
// let height = cfg.size[1];
// let stroke = cfg.style.stroke;
// let fill = cfg.style.fill;
// //大的矩形
// let subProcess = group.addShape("rect", {
// attrs: {
// x: -width / 2,
// y: -height / 2,
// height,
// width,
// fill,
// stroke,
// },
// name: "sub-process",
// });
// // 左边
// group.addShape("rect", {
// attrs: {
// x: -(width / 2 - 20),
// y: -height / 2,
// height,
// width: 1,
// fill: "#fff",
// stroke: "#fff",
// },
// });
// // 右边
// group.addShape("rect", {
// attrs: {
// x: width / 2 - 20,
// y: -height / 2,
// height,
// width: 1,
// fill: "#fff",
// stroke: "#fff",
// },
// });
// return subProcess;
// },
// },
// "rect"
// );
// // 注册节点。类型为文档类型节点
// G6.registerNode(
// "document-node",
// {
// drawShape: function (cfg, group) {
// let width = cfg.size[0];
// let height = cfg.size[1];
// let stroke = cfg.style.stroke;
// let fill = cfg.style.fill;
// let documentNodes = group.addShape("path", {
// attrs: {
// path: [
// ["M", -width / 2, 0 - height / 2], // 坐上
// ["L", width / 2, -height / 2], // 右上
// ["L", width / 2, height / 3], // 右下
// [
// "C",
// width / 4,
// -height / 8,
// -width / 4,
// (height * 6) / 8,
// -width / 2,
// height / 2,
// ], // 弧线
// ["Z"],
// ],
// fill,
// stroke,
// },
// name: "document-node",
// });
// return documentNodes;
// },
// },
// "single-node"
// );
// // 注册边。继承polyline,添加流动效果
// G6.registerEdge(
// "cus-polyline",
// {
// afterDraw(cfg, group) {
// let shape = group.get("children")[0];
// let index = 0;
// shape.animate(
// () => {
// index++;
// if (index > 9) {
// index = 0;
// }
// let animateLine = {
// lineDash: [4, 5, 1, 2],
// lineDashOffset: -index,
// };
// return animateLine;
// },
// {
// repeat: true,
// duration: 5000,
// }
// );
// },
// },
// "polyline"
// );
// const width = document.getElementById("container").scrollWidth * 0.95;
// // console.log(width, 'width-node');
// const height = document.getElementById("container").scrollHeight || 800;
// // console.log(height, 'height-node');
// const graph = new G6.Graph({
// container: "container",
// width,
// height,
// modes: {
// default: [
// "drag-canvas",
// // 'drag-node', // 拖动元素
// // 'zoom-canvas' //画面缩放
// ],
// },
// // 节点在默认状态下的样式配置(style)和其他配置
// defaultNode: {
// type: "rect",
// // type: 'circle',
// size: [80, 75], // 节点大小
// color: "#3e62ae",
// // 节点样式配置
// style: {
// fill: "#DEE9FF", // 节点填充色
// stroke: "#5B8FF9", // 节点描边色
// // lineWidth: 1, // 节点描边粗细
// },
// // 节点上的标签文本配置
// labelCfg: {
// style: {
// fill: "#ffffff", // 节点标签文字颜色
// fontSize: 16,
// },
// },
// F: [
// [0, 0.5],
// [0.5, 0],
// [1, 0.5],
// [0.5, 1],
// ],
// },
// // 边在默认状态下的样式配置(style)和其他配置
// defaultEdge: {
// type: "cus-polyline",
// // 边样式配置
// style: {
// offset: 30,
// endArrow: true,
// stroke: "blue", // 边描边颜色
// // opacity: 0.6, // 边透明度
// },
// },
// layout: {
// // type: 'force', // 设置布局算法为 force
// linkDistance: 100, // 设置边长为 100
// preventOverlap: true, // 设置防止重叠
// },
// });
// graph.data(this.gDatas);
// console.log(graph, "graph- datanode11");
// graph.render();
// graph.fitView();
// },
},
};
</script>
<style lang='scss' scoped>
.main-content-box {
border: solid 1px #000;
}
#svg-canvas {
padding-top: 20px;
margin-left: 2.5%;
// width: 100%;
// height: 100%;
}
</style>