326 lines
9.0 KiB
Vue
326 lines
9.0 KiB
Vue
<template>
|
|
<div>
|
|
<v-chart
|
|
:option="option"
|
|
style="height: 85dvh; width: 100%"
|
|
ref="chart"
|
|
@click="handleNodeClick"
|
|
@dblclick="showModalTree"
|
|
lazy
|
|
></v-chart>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
// import { random } from "lodash";
|
|
// import HttpService from "@services/httpService";
|
|
//
|
|
import { use } from "echarts/core";
|
|
import { TreeChart } from "echarts/charts";
|
|
import { TooltipComponent, ToolboxComponent } from "echarts/components";
|
|
import { CanvasRenderer } from "echarts/renderers";
|
|
import searchApis from "~/apis/searchApi";
|
|
|
|
use([TooltipComponent, TreeChart, CanvasRenderer, ToolboxComponent]);
|
|
|
|
export default {
|
|
props: {
|
|
dataChart: {
|
|
default() {
|
|
return [];
|
|
},
|
|
type: Array,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
treeCounter: 1,
|
|
showButtons: false,
|
|
showDiv: false,
|
|
buttonAction: "",
|
|
addText: "",
|
|
editText: "",
|
|
// httpService: undefined,
|
|
|
|
mainList: [],
|
|
itemData: {},
|
|
tooltipText: "",
|
|
position: { top: "0px", left: "0px" },
|
|
option: {
|
|
tooltip: {
|
|
trigger: "item",
|
|
triggerOn: "mousemove",
|
|
},
|
|
toolbox: {
|
|
show: true,
|
|
itemSize: 15,
|
|
},
|
|
series: [
|
|
{
|
|
type: "tree",
|
|
id: 0,
|
|
name: "tree1",
|
|
data: [],
|
|
top: "0%",
|
|
left: "40%",
|
|
bottom: "30%",
|
|
right: "8%",
|
|
while: "100%",
|
|
height: "100%",
|
|
zoom: 1,
|
|
symbolSize: 10,
|
|
edgeForkPosition: "30%",
|
|
initialTreeDepth: 1,
|
|
edgeShape: "curve",
|
|
orient: "RL",
|
|
label: {
|
|
color: "#fff",
|
|
fontFamily: "sahel",
|
|
fontSize: 15,
|
|
align: "center",
|
|
position: "left",
|
|
verticalAlign: "middle",
|
|
borderRadius: 3,
|
|
padding: 6,
|
|
borderWidth: 2,
|
|
// shadowColor: "rgba(51, 41, 41, 1)",
|
|
// shadowBlur: 2.5,
|
|
// shadowOffsetX: 2,
|
|
// shadowOffsetY: 2,
|
|
width: 140,
|
|
height: 12,
|
|
backgroundColor: "#fff",
|
|
distance: 80,
|
|
formatter: function (params) {
|
|
const maxLength = 15;
|
|
const text =
|
|
params.name.length > maxLength
|
|
? params.name.substring(0, maxLength) + "..."
|
|
: params.name;
|
|
return text;
|
|
},
|
|
},
|
|
leaves: {
|
|
label: {
|
|
distance: 80,
|
|
color: "#fff",
|
|
fontFamily: "sahel",
|
|
fontSize: 15,
|
|
align: "center",
|
|
position: "left",
|
|
verticalAlign: "middle",
|
|
borderRadius: 3,
|
|
padding: 6,
|
|
borderWidth: 2,
|
|
// shadowColor: "rgba(51, 41, 41, 1)",
|
|
// shadowBlur: 2.5,
|
|
// shadowOffsetX: 2,
|
|
// shadowOffsetY: 2,
|
|
width: 140,
|
|
height: 12,
|
|
backgroundColor: "#fff",
|
|
formatter: function (params) {
|
|
const maxLength = 15;
|
|
const text =
|
|
params.name.length > maxLength
|
|
? params.name.substring(0, maxLength) + "..."
|
|
: params.name;
|
|
return text;
|
|
},
|
|
},
|
|
},
|
|
lineStyle: {
|
|
curveness: 0.6,
|
|
},
|
|
emphasis: {
|
|
focus: "relative",
|
|
blurScope: "coordinateSystem",
|
|
},
|
|
expandAndCollapse: true,
|
|
animationDuration: 550,
|
|
animationDurationUpdate: 750,
|
|
symbolOffset: [30, 0],
|
|
},
|
|
],
|
|
},
|
|
colors: [
|
|
"#5470C6",
|
|
"#91CC75",
|
|
"#FAC858",
|
|
"#EE6666",
|
|
"#37a2da",
|
|
"#3BA272",
|
|
"#FC8452",
|
|
"#9A60B4",
|
|
"#EA7CCC",
|
|
"#F59F00",
|
|
],
|
|
currentIndex: 0,
|
|
};
|
|
},
|
|
watch: {
|
|
dataChart(newValue) {
|
|
this.option.series[0].data = newValue;
|
|
},
|
|
},
|
|
// beforeMount() {
|
|
// this.httpService = new HttpService();
|
|
// },
|
|
mounted() {
|
|
this.option.series[0].data = this.dataChart;
|
|
},
|
|
|
|
methods: {
|
|
/**
|
|
* این تابع مسئول دریافت و نمایش آیتمهای موجود زیر یک آیتم پدر است.
|
|
*/
|
|
handleNodeClick(params) {
|
|
const dataNode = params.data;
|
|
// if (dataNode.children && dataNode.children.length > 0) {
|
|
// this.handleNodeWithChildren(dataNode);
|
|
// }
|
|
// this.collapseAllExceptSelected(params);
|
|
if (dataNode.children.length > 1) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
this.getChildrenNode(dataNode.id).then((list) => {
|
|
list.forEach((element, index) => {
|
|
const dataColor = dataNode.label.backgroundColor;
|
|
var node = {
|
|
item: element,
|
|
text: element.title,
|
|
name: element.title,
|
|
id: element.id,
|
|
pid: dataNode.id,
|
|
collapsed: null,
|
|
children: [],
|
|
//children: element.children > 0 ? [1] : [],
|
|
label: {
|
|
backgroundColor: dataColor,
|
|
},
|
|
itemStyle: {
|
|
color: dataColor,
|
|
},
|
|
};
|
|
// // وقتی دادههای جدید اضافه میشود، 1 را حذف میکنیم
|
|
// if (dataNode.children.length === 1 && dataNode.children[0] === 1) {
|
|
// dataNode.children.splice(0, 1); // حذف 1
|
|
// }
|
|
dataNode.children.push(node);
|
|
if (dataNode.id === 0) {
|
|
this.option.series[0].data[0].children.push(node);
|
|
} else {
|
|
this.addChildToParent(
|
|
this.option.series[0].data[0],
|
|
dataNode.id,
|
|
node
|
|
);
|
|
}
|
|
});
|
|
});
|
|
} catch (error) {
|
|
console.error("Error fetching children nodes:", error);
|
|
}
|
|
},
|
|
// collapseAllExceptSelected(params) {
|
|
// console.log(params.data.id)
|
|
// const collapseNode = (node) => {
|
|
// if (typeof node === "object" && node !== null) {
|
|
// if (node.id !== params.data.id) {
|
|
// node.collapsed = true;
|
|
// } else {
|
|
// node.collapsed = false;
|
|
// }
|
|
// if (Array.isArray(node.children)) {
|
|
// node.children.forEach(collapseNode);
|
|
// }
|
|
// }
|
|
// };
|
|
// this.option.series[0].data.forEach(collapseNode);
|
|
// this.$refs.chart.setOption(this.option);
|
|
// },
|
|
/**
|
|
* این تابع مسئول دریافت لیست آیتمهای زیر یک آیتم پدر از سرور است.
|
|
* @param {string} parentId - شناسه آیتم پدر
|
|
* @returns {Promise} - لیست آیتمهای زیر آیتم پدر
|
|
*/
|
|
async getChildrenNode(parentId = 0) {
|
|
const payload = {
|
|
projectid: this.dataChart[0].projectId,
|
|
parent: parentId,
|
|
sortby: "id",
|
|
offset: 0,
|
|
limit: 100,
|
|
listtype: 0,
|
|
};
|
|
let url = searchApis.chart.tree;
|
|
// ارسال درخواست به سرور و بازگشت پاسخ به صورت Promise
|
|
|
|
try {
|
|
const { $api } = useNuxtApp();
|
|
return await $api(url, {
|
|
method: "post",
|
|
baseURL: baseUrl(),
|
|
body: payload,
|
|
});
|
|
} catch (err) {}
|
|
|
|
// return await this.httpService
|
|
// .formDataRequest(url, payload)
|
|
// .then((res) => {
|
|
// return res.data;
|
|
// });
|
|
},
|
|
/**
|
|
* این تابع مسئول اضافه کردن یک آیتم فرزند به آیتم پدر میباشد.
|
|
* @param {Object} node - آیتم پدر
|
|
* @param {string} parentId - شناسه آیتم پدر
|
|
* @param {Object} newChild - آیتم فرزند جدید
|
|
* @returns {boolean} - مقدار منطقی True در صورت موفقیت آمیز بودن اضافه کردن، در غیر این صورت False
|
|
*/
|
|
addChildToParent(node, parentId, newChild) {
|
|
if (node.id === parentId) {
|
|
node.children.push(newChild);
|
|
return true;
|
|
}
|
|
if (node.children) {
|
|
for (let child of node.children) {
|
|
if (this.addChildToParent(child, parentId, newChild)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
showModalTree(event) {
|
|
const itemSelected = { name: event.name, y: event.value };
|
|
this.$emit("list", itemSelected);
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
<style lang="scss">
|
|
.tooltip-button {
|
|
button {
|
|
color: #dee2e6 !important;
|
|
&:hover {
|
|
color: black !important;
|
|
}
|
|
}
|
|
}
|
|
.reject-button {
|
|
color: #dee2e6 !important;
|
|
&:hover {
|
|
color: rgb(231, 10, 10) !important;
|
|
}
|
|
}
|
|
.accept-button {
|
|
color: #dee2e6 !important;
|
|
&:hover {
|
|
color: rgb(37, 223, 12) !important;
|
|
}
|
|
}
|
|
</style>
|