base_ui/components/charts/Pie.vue

199 lines
6.6 KiB
Vue
Raw Permalink Normal View History

2025-02-01 09:34:55 +00:00
<template>
<div>
<v-chart
:key="treeCounter"
:option="options"
ref="chart"
@click="onChartClick"
:style="{ height: $attrs.height, width: $attrs.width }"
lazy
></v-chart>
</div>
</template>
<script>
//
import { use } from "echarts/core";
import { PieChart } from "echarts/charts";
import {
TitleComponent,
TooltipComponent,
LegendComponent,
} from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";
use([
TitleComponent,
TooltipComponent,
LegendComponent,
PieChart,
CanvasRenderer,
]);
/**
* @vue-prop {Array} [data=[]] - دادههای نمودار پای
* @vue-prop {Object} [PieOptions={}] - تنظیمات نمودار پای
* @vue-data {Number} [treeCounter=1] - شمارنده درخت
* @vue-data {Object} [options] - تنظیمات نمودار
* @vue-data {Object} [options.title] - عنوان
* @vue-data {String} [options.title.left="center"] - موقعیت افقی عنوان
* @vue-data {Object} [options.tooltip] - ابزارک
* @vue-data {String} [options.tooltip.trigger="item"] - محرک
* @vue-data {Function} [options.tooltip.formatter] - فرمتبندی کننده
* @vue-data {Object} [options.legend] - افسانه
* @vue-data {Number|String} [options.legend.right=0] - موقعیت افقی افسانه
* @vue-data {Number|String} [options.legend.top="20%"] - موقعیت عمودی افسانه
* @vue-data {String} [options.legend.orient="vertical"] - جهت
* @vue-data {String} [options.legend.left="left"] - موقعیت افقی عنوان
* @vue-data {Object} [options.legend.textStyle] - سبک متن
* @vue-data {String} [options.legend.textStyle.fontFamily="sahel"] - فونت متن
* @vue-data {Array} [options.series] - سریها
* @vue-data {Number|String} [options.series.left=400] - موقعیت افقی سری
* @vue-data {String} [options.series.name="Access From"] - نام سری
* @vue-data {String} [options.series.type="pie"] - نوع سری
* @vue-data {String} [options.series.radius="50%"] - شعاع سری
* @vue-data {Object} [options.series.label] - برچسب
* @vue-data {Boolean} [options.series.label.show=true] - نمایش برچسب
* @vue-data {Number} [options.series.label.fontSize=12] - اندازه قلم برچسب
* @vue-data {String} [options.series.label.fontFamily="sahel"] - فونت برچسب
* @vue-data {Object} [options.series.emphasis] - تاکید
* @vue-data {Object} [options.series.emphasis.label] - برچسب
* @vue-data {Boolean} [options.series.emphasis.label.show=true] - نمایش برچسب تاکید شده
* @vue-data {Number} [options.series.emphasis.label.fontSize=20] - اندازه قلم برچسب تاکید شده
* @vue-data {String} [options.series.emphasis.label.fontWeight="bold"] - وزن قلم برچسب تاکید شده
* @vue-data {Object} [options.series.emphasis.itemStyle] - سبک آیتم تاکید شده
* @vue-data {Number} [options.series.emphasis.itemStyle.shadowBlur=10] - شعاع سایه
* @vue-data {Number} [options.series.emphasis.itemStyle.shadowOffsetX=0] - آفست افقی سایه
* @vue-data {String} [options.series.emphasis.itemStyle.shadowColor="rgba(0, 0, 0, 0.5)"] - رنگ سایه
* @vue-data {Array} [options.series.data] - دادههای سری
*/
export default {
props: {
dataChart: {
default() {
return [];
},
type: Array,
},
PieOptions: {
default() {
return {};
},
type: Object,
},
},
data() {
return {
treeCounter: 1,
options: {
title: {
// text: "Referer of a Website",
// subtext: "Fake Data",
left: "center",
},
tooltip: {
trigger: "item",
formatter: (params) => {
return `${params.marker} ${params.name}: ${params.percent}<br/>`;
},
},
legend: {
show: window?.innerWidth >= 991 ? true : false,
right: 0,
top: "20%",
orient: "vertical",
left: "left",
textStyle: { fontFamily: "sahel" },
},
series: [
{
name: "Access From",
type: "pie",
radius: "50%",
left: window?.innerWidth >= 991 ? 200 : "center",
top: "center",
width: "100%",
height: "100%",
right: null,
bottom: null,
label: {
show: true,
fontSize: 12,
fontFamily: "sahel",
},
emphasis: {
label: {
show: true,
fontSize: 20,
fontWeight: "bold",
},
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: "rgba(0, 0, 0, 0.5)",
},
},
data: [
{ value: 1048, name: "Search Engine" },
{ value: 735, name: "Direct" },
{ value: 580, name: "Email" },
{ value: 484, name: "Union Ads" },
{ value: 300, name: "Video Ads" },
],
},
],
},
};
},
watch: {
dataChart(navItem) {
this.dataChartHandler(navItem);
},
},
beforeMount() {
this.dataChartHandler(this.dataChart);
},
mounted() {
if (this.PieOptions == {}) return;
let option = this.options.series[0];
this.options.series[0] = { ...option, ...this.PieOptions };
},
methods: {
/**
* هنگامی که بر روی نمودار کلیک میشود، این متد اجرا میشود.
* اطلاعات مورد نظر کاربر را از رویداد دریافت کرده و آن را به کامپوننت والد ارسال میکند.
*
* @param {object} event - رویداد کلیک بر روی نمودار
*/
onChartClick(event) {
const itemSelected = { name: event.name, y: event.value };
this.$emit("list", itemSelected);
},
/**
* پردازش دادههای نمودار.
* دادههای ورودی را تغییر شکل میدهد و آنها را برای استفاده در نمودار آماده میکند.
*
* @param {Array} value - دادههای ورودی برای نمودار
*/
dataChartHandler(value) {
const modifiedData = value.map((item) => {
return {
name: item.name,
value: item.y,
};
});
this.options.series[0].data = modifiedData;
this.treeCounter++;
},
},
};
</script>
<style lang="scss"></style>