|
@@ -0,0 +1,372 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <div id="chart" style="width: 1000px; height: 700px"></div>
|
|
|
+ <button v-show="selectedNode" @click="addLeftNode">添加左节点</button>
|
|
|
+ <button v-show="selectedNode" @click="addRightNode">添加右节点</button>
|
|
|
+ <button v-show="selectedNode" @click="deleteNode">删除该节点</button>
|
|
|
+ <button v-show="selectedNode" @click="updateNode">修改该节点</button>
|
|
|
+
|
|
|
+ <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
|
|
+ <el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
|
|
+ <el-form-item label="检查点" prop="startId">
|
|
|
+ <el-select
|
|
|
+ v-model="form.id"
|
|
|
+ placeholder="请选择检查点"
|
|
|
+ filterable
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in pointList"
|
|
|
+ :key="item.code"
|
|
|
+ :label="item.check_piont"
|
|
|
+ :value="item.code"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button type="primary" @click="submitForm">确 定</el-button>
|
|
|
+ <el-button @click="cancel">取 消</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+<script>
|
|
|
+import echarts from "echarts";
|
|
|
+import { getPointOption } from "@/api/suport/piont";
|
|
|
+
|
|
|
+export default {
|
|
|
+ props: {
|
|
|
+ codes: {
|
|
|
+ type: String,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ chartInstance: null,
|
|
|
+ selectedNode: null,
|
|
|
+ treeData: [
|
|
|
+ // 初始节点
|
|
|
+ {
|
|
|
+ name: "Root",
|
|
|
+ value: null,
|
|
|
+ children: [],
|
|
|
+ itemStyle: { borderColor: "#ccc" },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ title: "",
|
|
|
+ open: false,
|
|
|
+ form: {},
|
|
|
+ rules: {},
|
|
|
+ pointList: [],
|
|
|
+ idMap: new Map(),
|
|
|
+ codeMap: new Map(),
|
|
|
+ };
|
|
|
+ },
|
|
|
+
|
|
|
+ created() {},
|
|
|
+
|
|
|
+ mounted() {
|
|
|
+ this.chartInstance = echarts.init(document.getElementById("chart"));
|
|
|
+ this.chartInstance.on("click", this.selectNode); // 监听点击事件
|
|
|
+ this.getPointOption();
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ this.chartInstance.off("click", this.selectNode); // 移除监听事件
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ renderChart() {
|
|
|
+ const option = {
|
|
|
+ // ECharts配置项
|
|
|
+ tooltip: {
|
|
|
+ trigger: "item",
|
|
|
+ triggerOn: "mousemove",
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: "tree",
|
|
|
+ data: this.treeData,
|
|
|
+ left: "2%",
|
|
|
+ right: "2%",
|
|
|
+ top: "8%",
|
|
|
+ bottom: "20%",
|
|
|
+ symbol: "emptyCircle",
|
|
|
+ orient: "vertical",
|
|
|
+ symbolSize: 30,
|
|
|
+ itemStyle: {
|
|
|
+ color: null,
|
|
|
+ },
|
|
|
+ expandAndCollapse: false,
|
|
|
+ label: {
|
|
|
+ position: "bottom",
|
|
|
+ rotate: 0,
|
|
|
+ verticalAlign: "middle",
|
|
|
+ align: "center",
|
|
|
+ fontSize: 15,
|
|
|
+ distance: 15,
|
|
|
+ color: "#ccc",
|
|
|
+ },
|
|
|
+ animationDurationUpdate: 750,
|
|
|
+ initialTreeDepth: 10,
|
|
|
+ lineStyle: {
|
|
|
+ color: "rgba(16, 228, 232, 1)",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+
|
|
|
+ this.chartInstance.setOption(option);
|
|
|
+ },
|
|
|
+
|
|
|
+ reset() {
|
|
|
+ this.form = {
|
|
|
+ id: null,
|
|
|
+ code: null,
|
|
|
+ checkPiont: null,
|
|
|
+ createBy: null,
|
|
|
+ createTime: null,
|
|
|
+ updateBy: null,
|
|
|
+ updateTime: null,
|
|
|
+ };
|
|
|
+ this.resetForm("form");
|
|
|
+ },
|
|
|
+
|
|
|
+ selectNode(params) {
|
|
|
+ if (params.data && params.data.name) {
|
|
|
+ this.selectedNode = params.data;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ addLeftNode() {
|
|
|
+ const newNode = {
|
|
|
+ name: "Left Node",
|
|
|
+ value: null,
|
|
|
+ children: [],
|
|
|
+ itemStyle: { borderColor: "#FF0000" },
|
|
|
+ };
|
|
|
+ let n = this.selectedNode.children.length;
|
|
|
+ if (n === 2) {
|
|
|
+ this.$message({
|
|
|
+ message: "左节点已存在",
|
|
|
+ type: "warning",
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ n === 1 &&
|
|
|
+ this.selectedNode.children[0].itemStyle.borderColor == "#FF0000"
|
|
|
+ ) {
|
|
|
+ this.$message({
|
|
|
+ message: "左节点已存在",
|
|
|
+ type: "warning",
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.selectedNode.children.unshift(newNode);
|
|
|
+ this.treeData = this.chartInstance.getOption().series[0].data;
|
|
|
+ this.chartInstance.clear();
|
|
|
+ this.renderChart();
|
|
|
+ this.levelOrder();
|
|
|
+ },
|
|
|
+ addRightNode() {
|
|
|
+ const newNode = {
|
|
|
+ name: "Right Node",
|
|
|
+ value: null,
|
|
|
+ children: [],
|
|
|
+ itemStyle: { borderColor: "#0000FF" },
|
|
|
+ };
|
|
|
+ let n = this.selectedNode.children.length;
|
|
|
+ if (n === 2) {
|
|
|
+ this.$message({
|
|
|
+ message: "右节点已存在",
|
|
|
+ type: "warning",
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ n === 1 &&
|
|
|
+ this.selectedNode.children[0].itemStyle.borderColor == "#0000FF"
|
|
|
+ ) {
|
|
|
+ this.$message({
|
|
|
+ message: "右节点已存在",
|
|
|
+ type: "warning",
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.selectedNode.children.push(newNode);
|
|
|
+ this.treeData = this.chartInstance.getOption().series[0].data;
|
|
|
+ this.chartInstance.clear();
|
|
|
+ debugger
|
|
|
+ this.renderChart();
|
|
|
+ this.levelOrder();
|
|
|
+ },
|
|
|
+ deleteNode() {
|
|
|
+ this.treeData = this.chartInstance.getOption().series[0].data;
|
|
|
+ const parentNode = this.findParentNode(this.treeData, this.selectedNode);
|
|
|
+ if (parentNode) {
|
|
|
+ const index = parentNode.children.indexOf(this.selectedNode);
|
|
|
+ parentNode.children.splice(index, 1);
|
|
|
+ this.chartInstance.clear();
|
|
|
+ this.renderChart();
|
|
|
+ this.levelOrder();
|
|
|
+ this.selectedNode = null;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ findParentNode(tree, targetNode) {
|
|
|
+ for (const node of tree) {
|
|
|
+ for (const child of node.children) {
|
|
|
+ if (child.name === targetNode.name) {
|
|
|
+ return node;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (node.children.length > 0) {
|
|
|
+ const parentNode = this.findParentNode(node.children, targetNode);
|
|
|
+ if (parentNode) {
|
|
|
+ return parentNode;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ },
|
|
|
+
|
|
|
+ updateNode() {
|
|
|
+ this.reset();
|
|
|
+ this.form.id = this.selectedNode.value;
|
|
|
+ this.open = true;
|
|
|
+ this.title = "修改检查点";
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 提交按钮 */
|
|
|
+ submitForm() {
|
|
|
+ this.selectedNode.value = this.form.id;
|
|
|
+ for (const point of this.pointList) {
|
|
|
+ if (point.id === this.form.id) {
|
|
|
+ this.selectedNode.name = point.check_piont;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.open = false;
|
|
|
+ this.treeData = this.chartInstance.getOption().series[0].data;
|
|
|
+ this.chartInstance.clear();
|
|
|
+ this.renderChart();
|
|
|
+ this.levelOrder();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 取消按钮
|
|
|
+ cancel() {
|
|
|
+ this.open = false;
|
|
|
+ this.reset();
|
|
|
+ },
|
|
|
+
|
|
|
+ getPointOption() {
|
|
|
+ getPointOption().then((resp) => {
|
|
|
+ this.pointList = resp.data;
|
|
|
+ console.info(resp);
|
|
|
+ this.creatIdMap();
|
|
|
+ this.createCodeMap();
|
|
|
+ this.createTree();
|
|
|
+ this.renderChart();
|
|
|
+ console.info(this);
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ //根据treeData生成flowEncode并返回父组件
|
|
|
+ levelOrder() {
|
|
|
+ const ret = [];
|
|
|
+ if (!this.treeData) {
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ const q = [];
|
|
|
+ q.push(this.treeData[0]);
|
|
|
+ while (q.length !== 0) {
|
|
|
+ const currentLevelSize = q.length;
|
|
|
+ const nullNode = { name: "", value: 0, children: [] };
|
|
|
+ for (let i = 1; i <= currentLevelSize; ++i) {
|
|
|
+ const node = q.shift();
|
|
|
+ ret.push(node.value);
|
|
|
+ let n = node.children.length;
|
|
|
+ if (n == 0 && node.value != 0) {
|
|
|
+ q.push(nullNode);
|
|
|
+ q.push(nullNode);
|
|
|
+ } else if (n == 1) {
|
|
|
+ if (node.children[0].itemStyle.borderColor == "#FF0000") {
|
|
|
+ q.push(node.children[0]);
|
|
|
+ q.push(nullNode);
|
|
|
+ } else {
|
|
|
+ q.push(nullNode);
|
|
|
+ q.push(node.children[0]);
|
|
|
+ }
|
|
|
+ } else if (n == 2) {
|
|
|
+ q.push(node.children[0]);
|
|
|
+ q.push(node.children[1]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ let n = ret.length;
|
|
|
+ while (ret[n - 1] === 0) {
|
|
|
+ ret.pop();
|
|
|
+ n--;
|
|
|
+ }
|
|
|
+ this.$emit("handleEncode", ret.join(","));
|
|
|
+ },
|
|
|
+
|
|
|
+ //根据父页面传来的codes给treeData赋值
|
|
|
+ createTree() {
|
|
|
+ let v = this.codes.split(",");
|
|
|
+ let n = v.length;
|
|
|
+ if (n === 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const q = [];
|
|
|
+ let j = 0;
|
|
|
+ this.treeData[0].name = this.codeMap.get(v[j]);
|
|
|
+ this.treeData[0].value = v[j];
|
|
|
+ q.push(this.treeData[0]);
|
|
|
+ j++;
|
|
|
+ while (q.length !== 0 && j < n) {
|
|
|
+ const node = q.shift();
|
|
|
+ if (v[j] !== "0") {
|
|
|
+ const l = {
|
|
|
+ name: this.codeMap.get(v[j]),
|
|
|
+ value: v[j],
|
|
|
+ children: [],
|
|
|
+ itemStyle: { borderColor: "#FF0000" },
|
|
|
+ };
|
|
|
+ node.children.unshift(l);
|
|
|
+ q.push(l);
|
|
|
+ }
|
|
|
+ j++;
|
|
|
+ if (j === n) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (v[j] !== "0") {
|
|
|
+ const r = {
|
|
|
+ name: this.codeMap.get(v[j]),
|
|
|
+ value: v[j],
|
|
|
+ children: [],
|
|
|
+ itemStyle: { borderColor: "#0000FF" },
|
|
|
+ };
|
|
|
+ node.children.push(r);
|
|
|
+ q.push(r);
|
|
|
+ }
|
|
|
+ j++;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ creatIdMap() {
|
|
|
+ for (const point of this.pointList) {
|
|
|
+ this.idMap.set(point.id, point.check_piont);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ createCodeMap() {
|
|
|
+ for (const point of this.pointList) {
|
|
|
+ this.codeMap.set(point.code, point.check_piont);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|