base_ui/components/charts/TreeSimple.vue

326 lines
9.0 KiB
Vue
Raw Permalink Normal View History

2025-02-01 09:34:55 +00:00
<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>