@mamrp/components 1.7.28 → 1.7.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/charts/index.ts","../../react-shim.js","../../src/charts/bar/index.tsx","../../src/charts/pie/index.tsx"],"sourcesContent":["export { default as BarChart } from \"./bar\";\nexport { default as PieChart } from \"./pie\";\n","import * as React from \"react\";\nexport { React };\n","\"use client\";\r\nimport { Chart } from \"react-chartjs-2\";\r\nimport {\r\n Chart as ChartJS,\r\n CategoryScale,\r\n LinearScale,\r\n BarElement,\r\n LineElement,\r\n PointElement,\r\n Tooltip,\r\n Legend,\r\n BarController,\r\n LineController,\r\n Chart as ChartType,\r\n} from \"chart.js\";\r\nimport { Box } from \"@mui/material\";\r\n\r\nChartJS.register(\r\n CategoryScale,\r\n LinearScale,\r\n BarElement,\r\n LineElement,\r\n PointElement,\r\n Tooltip,\r\n Legend,\r\n BarController,\r\n LineController\r\n);\r\n\r\ninterface Props {\r\n labels: string[];\r\n datasets: {\r\n label: string;\r\n data: (number | null)[];\r\n backgroundColor: string;\r\n borderColor?: string;\r\n borderWidth?: number;\r\n type?: \"line\";\r\n order?: number;\r\n tension?: number;\r\n pointRadius?: number;\r\n fill?: boolean;\r\n }[];\r\n height?: number;\r\n}\r\n/**\r\n * 📊 BarChart — کامپوننت نمودار میله‌ای (Bar/Combo)\r\n *\r\n * @component BarChart\r\n *\r\n * @param {string[]} labels - آرایه‌ای از برچسب‌ها برای محور افقی (X).\r\n * @param {Array<{\r\n * label: string,\r\n * data: number[],\r\n * backgroundColor: string,\r\n * borderColor?: string,\r\n * borderWidth?: number,\r\n * type?: \"line\",\r\n * order?: number,\r\n * tension?: number,\r\n * pointRadius?: number,\r\n * fill?: boolean\r\n * }>} datasets - آرایه‌ای از آبجکت‌های داده برای هر سری نمودار.\r\n * - label: عنوان داده‌ها (نمایش در legend)\r\n * - data: آرایه‌ای از مقادیر هر سری\r\n * - backgroundColor: رنگ میله یا خط\r\n * - borderColor: (اختیاری) رنگ خط دور میله یا خط\r\n * - borderWidth: (اختیاری) ضخامت خط دور میله یا خط\r\n * - type: (اختیاری) اگر \"line\" باشد، سری به صورت خطی نمایش داده می‌شود (نمودار ترکیبی)\r\n * - order: (اختیاری) ترتیب رسم سری (سری با order بالاتر روی بقیه قرار می‌گیرد)\r\n * - tension: (اختیاری) میزان خمیدگی خط (برای سری‌های خطی)\r\n * - pointRadius: (اختیاری) شعاع نقاط روی خط (برای سری‌های خطی)\r\n * - fill: (اختیاری) پر شدن زیر خط (برای سری‌های خطی)\r\n *\r\n * @param {number} [height] - ارتفاع نمودار (پیش‌فرض: 600 پیکسل)\r\n *\r\n * @description\r\n * این کامپوننت یک نمودار میله‌ای (Bar) یا ترکیبی Bar/Line با قابلیت شخصی‌سازی کامل است.\r\n * - پشتیبانی از فونت وزیر و راست‌چین\r\n * - ریسپانسیو و مناسب صفحات فارسی\r\n * - امکان نمایش چند سری داده به صورت میله‌ای و خطی همزمان (Combo)\r\n * - شخصی‌سازی رنگ، ضخامت، ترتیب و استایل هر سری\r\n *\r\n * @returns {JSX.Element} یک نمودار میله‌ای یا ترکیبی با داده‌های ورودی\r\n *\r\n * @example\r\n * ```jsx\r\n * <BarChart\r\n * labels={[\"شنبه\", \"یکشنبه\", \"دوشنبه\"]}\r\n * datasets={[\r\n * {\r\n * label: \"فروش\",\r\n * data: [10, 20, 15],\r\n * backgroundColor: \"rgba(75,192,192,0.7)\",\r\n * },\r\n * {\r\n * label: \"میانگین\",\r\n * data: [12, 18, 14],\r\n * borderColor: \"red\",\r\n * backgroundColor: \"transparent\",\r\n * type: \"line\",\r\n * order: 0,\r\n * borderWidth: 3,\r\n * tension: 0.4,\r\n * pointRadius: 4,\r\n * fill: false,\r\n * },\r\n * ]}\r\n * height={400}\r\n * />\r\n * ```\r\n */\r\nexport default function BarChart({ labels, datasets, height }: Props) {\r\n const options = {\r\n responsive: true,\r\n maintainAspectRatio: false,\r\n scales: {\r\n y: {\r\n ticks: {\r\n font: {\r\n family: \"'Vazir', sans-serif\",\r\n size: 14,\r\n },\r\n },\r\n },\r\n x: {\r\n ticks: {\r\n autoSkip: false,\r\n font: {\r\n family: \"'Vazir', sans-serif\",\r\n size: 13,\r\n },\r\n },\r\n },\r\n },\r\n plugins: {\r\n datalabels: {\r\n display: false, // ← غیرفعال\r\n },\r\n tooltip: {\r\n bodyFont: {\r\n family: \"'Vazir', sans-serif\",\r\n size: 14,\r\n },\r\n titleFont: {\r\n family: \"'Vazir', sans-serif\",\r\n size: 16,\r\n },\r\n },\r\n legend: {\r\n labels: {\r\n generateLabels: function (chart: ChartType) {\r\n const labels =\r\n ChartJS.defaults.plugins.legend.labels.generateLabels(chart);\r\n return labels.map((label) => ({\r\n ...label,\r\n text: \" \" + label.text + \" \",\r\n boxWidth: 40,\r\n boxHeight: 20,\r\n }));\r\n },\r\n padding: 15,\r\n usePointStyle: true,\r\n font: {\r\n size: 16,\r\n family: \"'Vazir', sans-serif\",\r\n },\r\n boxWidth: 40,\r\n paddingBottom: 10,\r\n },\r\n },\r\n },\r\n };\r\n\r\n return (\r\n <Box height={height ?? 600}>\r\n <Chart type=\"bar\" data={{ labels, datasets }} options={options} />\r\n </Box>\r\n );\r\n}\r\n","'use client'\nimport { Pie } from \"react-chartjs-2\";\nimport { Chart as ChartJS, ArcElement, Tooltip, Legend, Chart } from \"chart.js\";\nimport { useMemo } from \"react\";\nimport { Box } from \"@mui/material\";\nimport Image from \"next/image\";\nimport ChartDataLabels from \"chartjs-plugin-datalabels\";\n\nChartJS.register(ArcElement, Tooltip, Legend, ChartDataLabels);\n\ninterface Props {\n labels: string[];\n datasets: {\n label: string;\n data: number[];\n backgroundColor: string | string[];\n borderWidth?: number;\n }[];\n height?: number;\n disableLogo?: boolean;\n logoSRC?: string;\n showDataLabels?: boolean;\n showPercentage?: boolean;\n}\n/**\n * 📊 PieChart — کامپوننت نمودار دایره‌ای (Pie)\n *\n * @component PieChart\n *\n * @param {string[]} labels - آرایه‌ای از برچسب‌ها برای هر بخش نمودار.\n * @param {boolean} [showDataLabels] - نمایش یا عدم نمایش برچسب‌های داده‌ها\n * @param {boolean} [showPercentage] - نمایش درصد به جای مقدار عددی در برچسب‌های داده‌ها (در صورت فعال بودن showDataLabels). درصد بر اساس داده‌های قابل مشاهده محاسبه می‌شود.\n * @param {Array<{\n * label: string,\n * data: number[],\n * backgroundColor: string[],\n * borderWidth?: number\n * }>} datasets - آرایه‌ای شامل یک آبجکت داده برای مقداردهی بخش‌های نمودار.\n * - label: عنوان داده‌ها (نمایش در legend)\n * - data: آرایه‌ای از مقادیر هر بخش\n * - backgroundColor: آرایه‌ای از رنگ‌ها برای هر بخش\n * - borderWidth: (اختیاری) ضخامت خط دور هر بخش\n * @param {number} [height] - ارتفاع نمودار (پیش‌فرض: 600 پیکسل)\n *\n * @description\n * این کامپوننت یک نمودار دایره‌ای با قابلیت شخصی‌سازی رنگ، داده و فونت (هماهنگ با وزیر) است.\n * - ریسپانسیو و مناسب صفحات فارسی\n * - امکان نمایش لوگو یا کامپوننت دلخواه در مرکز نمودار\n * - امکان نمایش درصد یا مقدار عددی در برچسب‌های داده‌ها بر اساس داده‌های قابل مشاهده\n *\n * @returns {JSX.Element} یک نمودار دایره‌ای با داده‌های ورودی\n *\n * @example\n * ```jsx\n * <PieChart\n * labels={[\"بخش اول\", \"بخش دوم\", \"بخش سوم\"]}\n * datasets={[\n * {\n * label: \"مقدار\",\n * data: [10, 20, 30],\n * backgroundColor: [\n * \"rgba(75,192,192,1)\",\n * \"rgba(255,99,132,1)\",\n * \"rgba(153,102,255,1)\",\n * ],\n * borderWidth: 2,\n * },\n * ]}\n * showDataLabels={true}\n * showPercentage={true}\n * />\n * ```\n */\nexport default function PieChart({\n labels,\n datasets,\n height,\n disableLogo,\n logoSRC,\n showDataLabels = false,\n showPercentage = false,\n}: Props) {\n const options = {\n responsive: true,\n maintainAspectRatio: false,\n cutout: !disableLogo ? \"59%\" : \"0%\",\n plugins: {\n tooltip: {\n bodyFont: {\n family: \"'Vazir', sans-serif\",\n size: 14,\n },\n titleFont: {\n family: \"'Vazir', sans-serif\",\n size: 16,\n },\n },\n legend: {\n labels: {\n padding: 15,\n usePointStyle: true,\n color: '#666', // رنگ متن legend را نرم‌تر می‌کند\n font: {\n size: 16,\n family: \"'Vazir', sans-serif\",\n },\n boxWidth: 40,\n paddingBottom: 10,\n generateLabels: (chart: any) => {\n const data = chart.data;\n const meta = chart.getDatasetMeta(0);\n return data.labels.map((label: string, index: number) => {\n const hidden = meta.data[index] ? meta.data[index].hidden : false;\n return {\n text: label,\n fillStyle: data.datasets[0].backgroundColor[index] || '#000',\n hidden: hidden,\n index: index,\n datasetIndex: 0,\n textDecoration: hidden ? 'line-through' : undefined,\n };\n });\n },\n },\n onClick: (e: any, legendItem: any, legend: any) => {\n const ci = legend.chart;\n const meta = ci.getDatasetMeta(legendItem.datasetIndex || 0);\n const index = legendItem.index;\n if (meta.data[index]) {\n meta.data[index].hidden = !meta.data[index].hidden;\n }\n ci.update();\n },\n },\n datalabels: {\n display: (context: any) => {\n return showDataLabels && !context.chart.getDatasetMeta(context.datasetIndex).data[context.dataIndex].hidden;\n },\n color: \"#fff\",\n font: {\n size: 14,\n weight: \"bold\",\n family: \"'Vazir', sans-serif\",\n } as const,\n anchor: \"center\" as const, // ← روی مرکز هر تکه\n align: \"center\" as const,\n offset: 20, // فاصله از مرکز (می‌تونی کم/زیاد کنی)\n formatter: showPercentage\n ? (value: number, context: any) => {\n if (value === 0) return \"\";\n // محاسبه مجموع داده‌های قابل مشاهده\n const total = context.chart.data.datasets[context.datasetIndex].data.reduce(\n (sum: number, val: number, index: number) => {\n const meta = context.chart.getDatasetMeta(context.datasetIndex);\n if (!meta.data[index] || meta.data[index].hidden !== true) {\n return sum + val;\n }\n return sum;\n },\n 0\n );\n const percentage = ((value / total) * 100).toFixed(1);\n return percentage + \"%\";\n }\n : (value: number) => (value === 0 ? \"\" : value),\n },\n },\n };\n\n // کامپوننتی که می‌خواهید در مرکز نمودار نمایش داده شود\n const CenterComponent = () => {\n return (\n <div\n style={{\n padding: \"10px\",\n borderRadius: \"8px\",\n textAlign: \"center\",\n width: 220,\n }}\n >\n <Image\n alt=\"\"\n width={220}\n height={220}\n src={logoSRC ?? \"/assets/images/pilogo.png\"}\n unoptimized\n />\n </div>\n );\n };\n\n return (\n <Box height={height ?? 600} sx={{ position: \"relative\" }}>\n <Pie\n data={{\n labels: labels,\n datasets: datasets,\n }}\n options={options}\n />\n {!disableLogo && (\n <div\n style={{\n position: \"absolute\",\n top: \"53%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n pointerEvents: \"none\", // جلوگیری از دریافت event روی این لایه\n }}\n >\n <CenterComponent />\n </div>\n )}\n </Box>\n );\n}\n"],"mappings":"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","names":["ChartJS","labels","import_react_chartjs_2","import_chart","import_material","ChartJS","ChartDataLabels","Image"]}
1
+ {"version":3,"sources":["../../src/charts/index.ts","../../react-shim.js","../../src/charts/bar/index.tsx","../../src/charts/pie/index.tsx"],"sourcesContent":["export { default as BarChart } from \"./bar\";\nexport { default as PieChart } from \"./pie\";\n","import * as React from \"react\";\nexport { React };\n","\"use client\";\r\nimport { Chart } from \"react-chartjs-2\";\r\nimport {\r\n Chart as ChartJS,\r\n CategoryScale,\r\n LinearScale,\r\n LogarithmicScale,\r\n BarElement,\r\n LineElement,\r\n PointElement,\r\n Tooltip,\r\n Legend,\r\n BarController,\r\n LineController,\r\n Chart as ChartType,\r\n} from \"chart.js\";\r\nimport { Box } from \"@mui/material\";\r\nimport { useRef, useEffect, useState } from \"react\";\r\n\r\nChartJS.register(\r\n CategoryScale,\r\n LinearScale,\r\n LogarithmicScale,\r\n BarElement,\r\n LineElement,\r\n PointElement,\r\n Tooltip,\r\n Legend,\r\n BarController,\r\n LineController\r\n);\r\n\r\n// تنظیم فونت پیش‌فرض Chart.js به Vazir\r\nChartJS.defaults.font.family = \"Vazir, sans-serif\";\r\n\r\ninterface Props {\r\n labels: string[];\r\n datasets: {\r\n label: string;\r\n data: (number | null)[];\r\n backgroundColor: string;\r\n borderColor?: string;\r\n borderWidth?: number;\r\n type?: \"line\";\r\n order?: number;\r\n tension?: number;\r\n pointRadius?: number;\r\n fill?: boolean;\r\n }[];\r\n height?: number;\r\n /**\r\n * حداقل مقدار محور Y (اختیاری)\r\n * اگر ست نشود، Chart.js خودش محاسبه می‌کند\r\n * ⚠️ نکته: اگر این مقدار ست شود، beginAtZero نادیده گرفته می‌شود\r\n */\r\n yAxisMin?: number;\r\n /**\r\n * حداکثر مقدار محور Y (اختیاری)\r\n * اگر ست نشود، Chart.js خودش محاسبه می‌کند\r\n */\r\n yAxisMax?: number;\r\n /**\r\n * آیا محور Y از صفر شروع شود؟\r\n * پیش‌فرض: true\r\n * ⚠️ نکته: اگر yAxisMin ست شود، این گزینه نادیده گرفته می‌شود\r\n */\r\n beginAtZero?: boolean;\r\n /**\r\n * استفاده از مقیاس لگاریتمی برای محور Y\r\n * مناسب برای داده‌هایی که اختلاف خیلی زیادی دارند\r\n * پیش‌فرض: false\r\n * ⚠️ نکته: مقادیر 0 یا منفی در مقیاس لگاریتمی نمایش داده نمی‌شوند\r\n */\r\n logarithmic?: boolean;\r\n /**\r\n * حداقل ارتفاع میله برای داده‌های خیلی کوچک (پیکسل)\r\n * مقادیر خیلی کوچک (مثل 1) در کنار مقادیر بزرگ (مثل 10000) گم نمی‌شوند\r\n * پیش‌فرض: 0 (غیرفعال)\r\n */\r\n minBarLength?: number;\r\n}\r\n/**\r\n * 📊 BarChart — کامپوننت نمودار میله‌ای (Bar/Combo)\r\n *\r\n * @component BarChart\r\n *\r\n * @param {string[]} labels - آرایه‌ای از برچسب‌ها برای محور افقی (X).\r\n * @param {Array<{\r\n * label: string,\r\n * data: number[],\r\n * backgroundColor: string,\r\n * borderColor?: string,\r\n * borderWidth?: number,\r\n * type?: \"line\",\r\n * order?: number,\r\n * tension?: number,\r\n * pointRadius?: number,\r\n * fill?: boolean\r\n * }>} datasets - آرایه‌ای از آبجکت‌های داده برای هر سری نمودار.\r\n * - label: عنوان داده‌ها (نمایش در legend)\r\n * - data: آرایه‌ای از مقادیر هر سری\r\n * - backgroundColor: رنگ میله یا خط\r\n * - borderColor: (اختیاری) رنگ خط دور میله یا خط\r\n * - borderWidth: (اختیاری) ضخامت خط دور میله یا خط\r\n * - type: (اختیاری) اگر \"line\" باشد، سری به صورت خطی نمایش داده می‌شود (نمودار ترکیبی)\r\n * - order: (اختیاری) ترتیب رسم سری (سری با order بالاتر روی بقیه قرار می‌گیرد)\r\n * - tension: (اختیاری) میزان خمیدگی خط (برای سری‌های خطی)\r\n * - pointRadius: (اختیاری) شعاع نقاط روی خط (برای سری‌های خطی)\r\n * - fill: (اختیاری) پر شدن زیر خط (برای سری‌های خطی)\r\n *\r\n * @param {number} [height] - ارتفاع نمودار (پیش‌فرض: 600 پیکسل)\r\n * @param {number} [yAxisMin] - حداقل مقدار محور Y (نادیده‌گرفتن beginAtZero)\r\n * @param {number} [yAxisMax] - حداکثر مقدار محور Y\r\n * @param {boolean} [beginAtZero=true] - آیا محور Y از صفر شروع شود؟ (اگر yAxisMin ست شود نادیده گرفته می‌شود)\r\n * @param {boolean} [logarithmic=false] - استفاده از مقیاس لگاریتمی (مقادیر 0 یا منفی نمایش داده نمی‌شوند)\r\n * @param {number} [minBarLength=0] - حداقل ارتفاع میله (پیکسل) - برای جلوگیری از گم شدن داده‌های کوچک\r\n *\r\n * @description\r\n * این کامپوننت یک نمودار میله‌ای (Bar) یا ترکیبی Bar/Line با قابلیت شخصی‌سازی کامل است.\r\n * - پشتیبانی از فونت وزیر و راست‌چین\r\n * - ریسپانسیو و مناسب صفحات فارسی\r\n * - امکان نمایش چند سری داده به صورت میله‌ای و خطی همزمان (Combo)\r\n * - شخصی‌سازی رنگ، ضخامت، ترتیب و استایل هر سری\r\n * - پشتیبانی از مقیاس لگاریتمی برای داده‌های با اختلاف زیاد\r\n * - minBarLength برای نمایش داده‌های خیلی کوچک در کنار بزرگ‌ها\r\n *\r\n * @returns {JSX.Element} یک نمودار میله‌ای یا ترکیبی با داده‌های ورودی\r\n *\r\n * @example\r\n * ```jsx\r\n * // نمودار ساده\r\n * <BarChart\r\n * labels={[\"شنبه\", \"یکشنبه\", \"دوشنبه\"]}\r\n * datasets={[\r\n * {\r\n * label: \"فروش\",\r\n * data: [10, 20, 15],\r\n * backgroundColor: \"rgba(75,192,192,0.7)\",\r\n * },\r\n * ]}\r\n * height={400}\r\n * />\r\n *\r\n * // نمودار با داده‌های اختلاف زیاد (مقیاس لگاریتمی)\r\n * <BarChart\r\n * labels={[\"A\", \"B\", \"C\", \"D\"]}\r\n * datasets={[\r\n * {\r\n * label: \"مقادیر\",\r\n * data: [5, 50, 5000, 50000],\r\n * backgroundColor: \"rgba(75,192,192,0.7)\",\r\n * },\r\n * ]}\r\n * logarithmic={true}\r\n * height={400}\r\n * />\r\n *\r\n * // نمودار با کنترل دستی بازه محور Y\r\n * <BarChart\r\n * labels={[\"A\", \"B\", \"C\"]}\r\n * datasets={[\r\n * {\r\n * label: \"مقادیر\",\r\n * data: [100, 150, 120],\r\n * backgroundColor: \"rgba(75,192,192,0.7)\",\r\n * },\r\n * ]}\r\n * yAxisMin={80}\r\n * yAxisMax={200}\r\n * beginAtZero={false}\r\n * height={400}\r\n * />\r\n * ```\r\n */\r\nexport default function BarChart({\r\n labels,\r\n datasets,\r\n height,\r\n yAxisMin,\r\n yAxisMax,\r\n beginAtZero = true,\r\n logarithmic = false,\r\n minBarLength = 0,\r\n}: Props) {\r\n const chartRef = useRef<ChartJS>(null);\r\n const [fontLoaded, setFontLoaded] = useState(false);\r\n\r\n // صبر برای لود شدن فونت Vazir و سپس آپدیت chart\r\n useEffect(() => {\r\n let isMounted = true;\r\n\r\n const loadFont = async () => {\r\n if (typeof document !== \"undefined\" && document.fonts) {\r\n try {\r\n // منتظر لود شدن فونت Vazir به صورت مستقیم\r\n await document.fonts.load(\"16px Vazir\");\r\n await document.fonts.ready;\r\n } catch (e) {\r\n // اگر فونت پیدا نشد، ادامه بده\r\n }\r\n\r\n if (isMounted) {\r\n setFontLoaded(true);\r\n // آپدیت chart بعد از لود فونت\r\n setTimeout(() => {\r\n if (chartRef.current) {\r\n chartRef.current.update();\r\n }\r\n }, 100);\r\n }\r\n } else {\r\n if (isMounted) setFontLoaded(true);\r\n }\r\n };\r\n\r\n loadFont();\r\n\r\n return () => { isMounted = false; };\r\n }, []);\r\n\r\n // محاسبه min/max فقط بر اساس داده‌های visible\r\n const getVisibleData = (): number[] => {\r\n if (!chartRef.current) return [];\r\n // فقط سری‌هایی که visible هستند و نوعشان bar است\r\n return datasets.reduce((acc: number[], ds, i) => {\r\n // اگر سری فعال است و نوعش bar است\r\n // @ts-ignore\r\n if ((ds.type === undefined || ds.type === \"bar\") && chartRef.current && typeof chartRef.current.isDatasetVisible === \"function\" && chartRef.current.isDatasetVisible(i)) {\r\n ds.data.forEach((v: number | null) => {\r\n if (typeof v === \"number\" && v > 0) acc.push(v);\r\n });\r\n }\r\n return acc;\r\n }, []);\r\n };\r\n\r\n let autoMin = yAxisMin;\r\n let autoMax = yAxisMax;\r\n if (logarithmic && yAxisMin === undefined && yAxisMax === undefined) {\r\n const visibleData = getVisibleData();\r\n if (visibleData.length) {\r\n const minVal = Math.min(...visibleData);\r\n const maxVal = Math.max(...visibleData);\r\n autoMin = minVal < 1 ? 0.5 : minVal * 0.7;\r\n autoMax = minVal === maxVal ? maxVal * 1.2 : maxVal * 1.1;\r\n }\r\n }\r\n\r\n // هر بار که legend تغییر کند، نمودار را آپدیت کن تا min/max درست شود\r\n useEffect(() => {\r\n if (!logarithmic || yAxisMin !== undefined || yAxisMax !== undefined) return;\r\n if (!chartRef.current) return;\r\n const handler = () => {\r\n // آپدیت min/max و نمودار\r\n const visibleData = getVisibleData();\r\n if (visibleData.length && chartRef.current && chartRef.current.options && chartRef.current.options.scales && chartRef.current.options.scales.y) {\r\n const minVal = Math.min(...visibleData);\r\n const maxVal = Math.max(...visibleData);\r\n chartRef.current.options.scales.y.min = minVal < 1 ? 0.5 : minVal * 0.7;\r\n chartRef.current.options.scales.y.max = minVal === maxVal ? maxVal * 1.2 : maxVal * 1.1;\r\n chartRef.current.update();\r\n }\r\n };\r\n // گوش دادن به event legend\r\n chartRef.current?.canvas?.addEventListener(\"click\", handler);\r\n return () => {\r\n chartRef.current?.canvas?.removeEventListener(\"click\", handler);\r\n };\r\n }, [logarithmic, yAxisMin, yAxisMax, datasets]);\r\n\r\n const options = {\r\n responsive: true,\r\n maintainAspectRatio: false,\r\n scales: {\r\n y: {\r\n type: logarithmic ? (\"logarithmic\" as const) : (\"linear\" as const),\r\n ...(yAxisMin === undefined && yAxisMax === undefined && !logarithmic && {\r\n beginAtZero: beginAtZero,\r\n }),\r\n ...(autoMin !== undefined && { min: autoMin }),\r\n ...(autoMax !== undefined && { max: autoMax }),\r\n ticks: {\r\n font: {\r\n family: \"Vazir, sans-serif\",\r\n size: 14,\r\n },\r\n ...(logarithmic && {\r\n callback: function (value: number | string) {\r\n const numValue = Number(value);\r\n // فقط توان‌های ۱۰ را نمایش بده\r\n if (numValue === 0) return null;\r\n const log10 = Math.log10(numValue);\r\n if (Math.abs(log10 - Math.round(log10)) < 0.0001) {\r\n if (numValue >= 1000000) return (numValue / 1000000).toFixed(1) + \"M\";\r\n if (numValue >= 1000) return (numValue / 1000).toFixed(1) + \"K\";\r\n return numValue;\r\n }\r\n return null;\r\n },\r\n }),\r\n },\r\n },\r\n x: {\r\n ticks: {\r\n autoSkip: false,\r\n font: {\r\n family: \"Vazir, sans-serif\",\r\n size: 13,\r\n },\r\n },\r\n },\r\n },\r\n plugins: {\r\n datalabels: {\r\n display: false, // ← غیرفعال\r\n },\r\n tooltip: {\r\n bodyFont: {\r\n family: \"Vazir, sans-serif\",\r\n size: 14,\r\n },\r\n titleFont: {\r\n family: \"Vazir, sans-serif\",\r\n size: 16,\r\n },\r\n },\r\n legend: {\r\n labels: {\r\n generateLabels: function (chart: ChartType) {\r\n const labels =\r\n ChartJS.defaults.plugins.legend.labels.generateLabels(chart);\r\n return labels.map((label) => ({\r\n ...label,\r\n text: \" \" + label.text + \" \",\r\n boxWidth: 40,\r\n boxHeight: 20,\r\n }));\r\n },\r\n padding: 15,\r\n usePointStyle: true,\r\n font: {\r\n size: 16,\r\n family: \"Vazir, sans-serif\",\r\n },\r\n boxWidth: 40,\r\n paddingBottom: 10,\r\n },\r\n },\r\n },\r\n };\r\n\r\n // اضافه کردن minBarLength به همه datasets\r\n const processedDatasets = datasets.map((ds) => ({\r\n ...ds,\r\n minBarLength: minBarLength,\r\n }));\r\n\r\n return (\r\n <Box height={height ?? 600}>\r\n {fontLoaded && (\r\n <Chart ref={chartRef} type=\"bar\" data={{ labels, datasets: processedDatasets }} options={options} />\r\n )}\r\n </Box>\r\n );\r\n}\r\n","'use client'\nimport { Pie } from \"react-chartjs-2\";\nimport { Chart as ChartJS, ArcElement, Tooltip, Legend, Chart } from \"chart.js\";\nimport { useMemo, useRef, useEffect, useState } from \"react\";\nimport { Box, Typography } from \"@mui/material\";\nimport Image from \"next/image\";\nimport ChartDataLabels from \"chartjs-plugin-datalabels\";\n\nChartJS.register(ArcElement, Tooltip, Legend, ChartDataLabels);\n\n// تنظیم فونت پیش‌فرض Chart.js به Vazir\nChartJS.defaults.font.family = \"Vazir, sans-serif\";\n\ninterface Props {\n labels: string[];\n datasets: {\n label: string;\n data: number[];\n backgroundColor: string | string[];\n borderWidth?: number;\n }[];\n height?: number;\n disableLogo?: boolean;\n logoSRC?: string;\n showDataLabels?: boolean;\n showPercentage?: boolean;\n}\n/**\n * 📊 PieChart — کامپوننت نمودار دایره‌ای (Pie)\n *\n * @component PieChart\n *\n * @param {string[]} labels - آرایه‌ای از برچسب‌ها برای هر بخش نمودار.\n * @param {boolean} [showDataLabels] - نمایش یا عدم نمایش برچسب‌های داده‌ها\n * @param {boolean} [showPercentage] - نمایش درصد به جای مقدار عددی در برچسب‌های داده‌ها (در صورت فعال بودن showDataLabels). درصد بر اساس داده‌های قابل مشاهده محاسبه می‌شود.\n * @param {Array<{\n * label: string,\n * data: number[],\n * backgroundColor: string[],\n * borderWidth?: number\n * }>} datasets - آرایه‌ای شامل یک آبجکت داده برای مقداردهی بخش‌های نمودار.\n * - label: عنوان داده‌ها (نمایش در legend)\n * - data: آرایه‌ای از مقادیر هر بخش\n * - backgroundColor: آرایه‌ای از رنگ‌ها برای هر بخش\n * - borderWidth: (اختیاری) ضخامت خط دور هر بخش\n * @param {number} [height] - ارتفاع نمودار (پیش‌فرض: 600 پیکسل)\n *\n * @description\n * این کامپوننت یک نمودار دایره‌ای با قابلیت شخصی‌سازی رنگ، داده و فونت (هماهنگ با وزیر) است.\n * - ریسپانسیو و مناسب صفحات فارسی\n * - امکان نمایش لوگو یا کامپوننت دلخواه در مرکز نمودار\n * - امکان نمایش درصد یا مقدار عددی در برچسب‌های داده‌ها بر اساس داده‌های قابل مشاهده\n *\n * @returns {JSX.Element} یک نمودار دایره‌ای با داده‌های ورودی\n *\n * @example\n * ```jsx\n * <PieChart\n * labels={[\"بخش اول\", \"بخش دوم\", \"بخش سوم\"]}\n * datasets={[\n * {\n * label: \"مقدار\",\n * data: [10, 20, 30],\n * backgroundColor: [\n * \"rgba(75,192,192,1)\",\n * \"rgba(255,99,132,1)\",\n * \"rgba(153,102,255,1)\",\n * ],\n * borderWidth: 2,\n * },\n * ]}\n * showDataLabels={true}\n * showPercentage={true}\n * />\n * ```\n */\nexport default function PieChart({\n labels,\n datasets,\n height,\n disableLogo,\n logoSRC,\n showDataLabels = false,\n showPercentage = false,\n}: Props) {\n const chartRef = useRef<ChartJS<\"pie\">>(null);\n const [dataLabels, setDataLabels] = useState<{ x: number; y: number; text: string; opacity: number }[]>([]);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // تابع محاسبه موقعیت لیبل‌ها\n const calculateLabels = () => {\n if (!showDataLabels || !chartRef.current || !containerRef.current) return;\n\n const chart = chartRef.current;\n const meta = chart.getDatasetMeta(0);\n const data = chart.data.datasets[0].data as number[];\n\n // گرفتن اطلاعات chart area\n const chartArea = chart.chartArea;\n\n // محاسبه مجموع داده‌های قابل مشاهده\n const visibleTotal = data.reduce((sum, val, index) => {\n if (!meta.data[index] || (meta.data[index] as any).hidden !== true) {\n return sum + val;\n }\n return sum;\n }, 0);\n\n const newLabels: { x: number; y: number; text: string; opacity: number }[] = [];\n\n meta.data.forEach((arc: any, index: number) => {\n if (arc.hidden) return;\n\n const value = data[index];\n if (value === 0) return;\n\n // محاسبه مرکز arc\n const centerAngle = (arc.startAngle + arc.endAngle) / 2;\n // نزدیک‌تر به دیواره (0.7 = بین مرکز و لبه، هرچه بیشتر به 1 نزدیک‌تر = نزدیک‌تر به لبه)\n const midRadius = arc.innerRadius + (arc.outerRadius - arc.innerRadius) * 0.65;\n\n // موقعیت در chart area - آینه کردن روی محور X\n const x = arc.x - Math.cos(centerAngle) * midRadius;\n const y = arc.y + Math.sin(centerAngle) * midRadius;\n\n let text: string;\n if (showPercentage) {\n const percentage = ((value / visibleTotal) * 100).toFixed(1);\n text = percentage + \"%\";\n } else {\n text = String(value);\n }\n\n newLabels.push({ x, y, text, opacity: 1 });\n });\n\n setDataLabels(newLabels);\n };\n\n // محاسبه موقعیت لیبل‌ها بعد از اتمام انیمیشن\n useEffect(() => {\n if (!showDataLabels) {\n setDataLabels([]);\n return;\n }\n\n // صبر برای اتمام انیمیشن اولیه (500ms)\n const timeout = setTimeout(() => {\n calculateLabels();\n }, 500);\n\n return () => clearTimeout(timeout);\n }, [datasets, showDataLabels, showPercentage]);\n\n // آپدیت لیبل‌ها بعد از هر تغییر در chart (مثل کلیک روی legend)\n useEffect(() => {\n if (!chartRef.current || !showDataLabels) return;\n\n const chart = chartRef.current;\n const originalUpdate = chart.update.bind(chart);\n\n chart.update = function (...args: any[]) {\n // مخفی کردن لیبل‌ها قبل از آپدیت\n setDataLabels(prev => prev.map(l => ({ ...l, opacity: 0 })));\n\n originalUpdate(...args);\n\n // محاسبه مجدد لیبل‌ها بعد از انیمیشن\n setTimeout(() => {\n calculateLabels();\n }, 250);\n };\n\n return () => {\n chart.update = originalUpdate;\n };\n }, [showDataLabels, showPercentage]);\n\n const options = useMemo(() => ({\n responsive: true,\n maintainAspectRatio: false,\n cutout: !disableLogo ? \"59%\" : \"0%\",\n animation: {\n animateRotate: true,\n animateScale: true,\n duration: 400,\n },\n plugins: {\n tooltip: {\n bodyFont: {\n family: \"Vazir, sans-serif\",\n size: 14,\n },\n titleFont: {\n family: \"Vazir, sans-serif\",\n size: 16,\n },\n },\n legend: {\n labels: {\n padding: 15,\n usePointStyle: true,\n color: '#666', // رنگ متن legend را نرم‌تر می‌کند\n font: {\n size: 16,\n family: \"Vazir, sans-serif\",\n },\n boxWidth: 40,\n paddingBottom: 10,\n generateLabels: (chart: any) => {\n const data = chart.data;\n const meta = chart.getDatasetMeta(0);\n return data.labels.map((label: string, index: number) => {\n const hidden = meta.data[index] ? meta.data[index].hidden : false;\n return {\n text: label,\n fillStyle: data.datasets[0].backgroundColor[index] || '#000',\n hidden: hidden,\n index: index,\n datasetIndex: 0,\n textDecoration: hidden ? 'line-through' : undefined,\n };\n });\n },\n },\n onClick: (e: any, legendItem: any, legend: any) => {\n const ci = legend.chart;\n const meta = ci.getDatasetMeta(legendItem.datasetIndex || 0);\n const index = legendItem.index;\n if (meta.data[index]) {\n meta.data[index].hidden = !meta.data[index].hidden;\n }\n ci.update();\n },\n },\n datalabels: {\n display: false, // غیرفعال - لیبل‌ها با React رندر می‌شوند\n },\n },\n }), [disableLogo]);\n\n // کامپوننتی که می‌خواهید در مرکز نمودار نمایش داده شود\n const CenterComponent = () => {\n return (\n <div\n style={{\n padding: \"10px\",\n borderRadius: \"8px\",\n textAlign: \"center\",\n width: 220,\n }}\n >\n <Image\n alt=\"\"\n width={220}\n height={220}\n src={logoSRC ?? \"/assets/images/pilogo.png\"}\n unoptimized\n />\n </div>\n );\n };\n\n return (\n <Box ref={containerRef} height={height ?? 600} sx={{ position: \"relative\" }}>\n <Pie\n ref={chartRef}\n data={{\n labels: labels,\n datasets: datasets,\n }}\n options={options}\n />\n {/* لیبل‌های سفارشی با فونت Vazir */}\n {showDataLabels && dataLabels.map((label, index) => (\n <Typography\n key={index}\n sx={{\n position: \"absolute\",\n left: label.x / (window.devicePixelRatio || 1),\n top: label.y / (window.devicePixelRatio || 1),\n transform: \"translate(-50%, -50%)\",\n color: \"#fff\",\n fontWeight: \"bold\",\n fontSize: 14,\n fontFamily: \"Vazir, sans-serif\",\n pointerEvents: \"none\",\n textShadow: \"0 1px 2px rgba(0,0,0,0.5)\",\n opacity: label.opacity,\n transition: \"opacity 0.2s ease-in-out, left 0.2s ease-in-out, top 0.2s ease-in-out\",\n }}\n >\n {label.text}\n </Typography>\n ))}\n {!disableLogo && (\n <div\n style={{\n position: \"absolute\",\n top: \"53%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n pointerEvents: \"none\", // جلوگیری از دریافت event روی این لایه\n }}\n >\n <CenterComponent />\n </div>\n )}\n </Box>\n );\n}\n"],"mappings":"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","names":["ChartJS","labels","import_react_chartjs_2","import_chart","import_react","import_material","ChartJS","ChartDataLabels","Image"]}
@@ -7,6 +7,7 @@ import {
7
7
  Chart as ChartJS,
8
8
  CategoryScale,
9
9
  LinearScale,
10
+ LogarithmicScale,
10
11
  BarElement,
11
12
  LineElement,
12
13
  PointElement,
@@ -16,9 +17,11 @@ import {
16
17
  LineController
17
18
  } from "chart.js";
18
19
  import { Box } from "@mui/material";
20
+ import { useRef, useEffect, useState } from "react";
19
21
  ChartJS.register(
20
22
  CategoryScale,
21
23
  LinearScale,
24
+ LogarithmicScale,
22
25
  BarElement,
23
26
  LineElement,
24
27
  PointElement,
@@ -27,16 +30,113 @@ ChartJS.register(
27
30
  BarController,
28
31
  LineController
29
32
  );
30
- function BarChart({ labels, datasets, height }) {
33
+ ChartJS.defaults.font.family = "Vazir, sans-serif";
34
+ function BarChart({
35
+ labels,
36
+ datasets,
37
+ height,
38
+ yAxisMin,
39
+ yAxisMax,
40
+ beginAtZero = true,
41
+ logarithmic = false,
42
+ minBarLength = 0
43
+ }) {
44
+ const chartRef = useRef(null);
45
+ const [fontLoaded, setFontLoaded] = useState(false);
46
+ useEffect(() => {
47
+ let isMounted = true;
48
+ const loadFont = async () => {
49
+ if (typeof document !== "undefined" && document.fonts) {
50
+ try {
51
+ await document.fonts.load("16px Vazir");
52
+ await document.fonts.ready;
53
+ } catch (e) {
54
+ }
55
+ if (isMounted) {
56
+ setFontLoaded(true);
57
+ setTimeout(() => {
58
+ if (chartRef.current) {
59
+ chartRef.current.update();
60
+ }
61
+ }, 100);
62
+ }
63
+ } else {
64
+ if (isMounted) setFontLoaded(true);
65
+ }
66
+ };
67
+ loadFont();
68
+ return () => {
69
+ isMounted = false;
70
+ };
71
+ }, []);
72
+ const getVisibleData = () => {
73
+ if (!chartRef.current) return [];
74
+ return datasets.reduce((acc, ds, i) => {
75
+ if ((ds.type === void 0 || ds.type === "bar") && chartRef.current && typeof chartRef.current.isDatasetVisible === "function" && chartRef.current.isDatasetVisible(i)) {
76
+ ds.data.forEach((v) => {
77
+ if (typeof v === "number" && v > 0) acc.push(v);
78
+ });
79
+ }
80
+ return acc;
81
+ }, []);
82
+ };
83
+ let autoMin = yAxisMin;
84
+ let autoMax = yAxisMax;
85
+ if (logarithmic && yAxisMin === void 0 && yAxisMax === void 0) {
86
+ const visibleData = getVisibleData();
87
+ if (visibleData.length) {
88
+ const minVal = Math.min(...visibleData);
89
+ const maxVal = Math.max(...visibleData);
90
+ autoMin = minVal < 1 ? 0.5 : minVal * 0.7;
91
+ autoMax = minVal === maxVal ? maxVal * 1.2 : maxVal * 1.1;
92
+ }
93
+ }
94
+ useEffect(() => {
95
+ if (!logarithmic || yAxisMin !== void 0 || yAxisMax !== void 0) return;
96
+ if (!chartRef.current) return;
97
+ const handler = () => {
98
+ const visibleData = getVisibleData();
99
+ if (visibleData.length && chartRef.current && chartRef.current.options && chartRef.current.options.scales && chartRef.current.options.scales.y) {
100
+ const minVal = Math.min(...visibleData);
101
+ const maxVal = Math.max(...visibleData);
102
+ chartRef.current.options.scales.y.min = minVal < 1 ? 0.5 : minVal * 0.7;
103
+ chartRef.current.options.scales.y.max = minVal === maxVal ? maxVal * 1.2 : maxVal * 1.1;
104
+ chartRef.current.update();
105
+ }
106
+ };
107
+ chartRef.current?.canvas?.addEventListener("click", handler);
108
+ return () => {
109
+ chartRef.current?.canvas?.removeEventListener("click", handler);
110
+ };
111
+ }, [logarithmic, yAxisMin, yAxisMax, datasets]);
31
112
  const options = {
32
113
  responsive: true,
33
114
  maintainAspectRatio: false,
34
115
  scales: {
35
116
  y: {
117
+ type: logarithmic ? "logarithmic" : "linear",
118
+ ...yAxisMin === void 0 && yAxisMax === void 0 && !logarithmic && {
119
+ beginAtZero
120
+ },
121
+ ...autoMin !== void 0 && { min: autoMin },
122
+ ...autoMax !== void 0 && { max: autoMax },
36
123
  ticks: {
37
124
  font: {
38
- family: "'Vazir', sans-serif",
125
+ family: "Vazir, sans-serif",
39
126
  size: 14
127
+ },
128
+ ...logarithmic && {
129
+ callback: function(value) {
130
+ const numValue = Number(value);
131
+ if (numValue === 0) return null;
132
+ const log10 = Math.log10(numValue);
133
+ if (Math.abs(log10 - Math.round(log10)) < 1e-4) {
134
+ if (numValue >= 1e6) return (numValue / 1e6).toFixed(1) + "M";
135
+ if (numValue >= 1e3) return (numValue / 1e3).toFixed(1) + "K";
136
+ return numValue;
137
+ }
138
+ return null;
139
+ }
40
140
  }
41
141
  }
42
142
  },
@@ -44,7 +144,7 @@ function BarChart({ labels, datasets, height }) {
44
144
  ticks: {
45
145
  autoSkip: false,
46
146
  font: {
47
- family: "'Vazir', sans-serif",
147
+ family: "Vazir, sans-serif",
48
148
  size: 13
49
149
  }
50
150
  }
@@ -57,11 +157,11 @@ function BarChart({ labels, datasets, height }) {
57
157
  },
58
158
  tooltip: {
59
159
  bodyFont: {
60
- family: "'Vazir', sans-serif",
160
+ family: "Vazir, sans-serif",
61
161
  size: 14
62
162
  },
63
163
  titleFont: {
64
- family: "'Vazir', sans-serif",
164
+ family: "Vazir, sans-serif",
65
165
  size: 16
66
166
  }
67
167
  },
@@ -80,7 +180,7 @@ function BarChart({ labels, datasets, height }) {
80
180
  usePointStyle: true,
81
181
  font: {
82
182
  size: 16,
83
- family: "'Vazir', sans-serif"
183
+ family: "Vazir, sans-serif"
84
184
  },
85
185
  boxWidth: 40,
86
186
  paddingBottom: 10
@@ -88,16 +188,22 @@ function BarChart({ labels, datasets, height }) {
88
188
  }
89
189
  }
90
190
  };
91
- return /* @__PURE__ */ React.createElement(Box, { height: height ?? 600 }, /* @__PURE__ */ React.createElement(Chart, { type: "bar", data: { labels, datasets }, options }));
191
+ const processedDatasets = datasets.map((ds) => ({
192
+ ...ds,
193
+ minBarLength
194
+ }));
195
+ return /* @__PURE__ */ React.createElement(Box, { height: height ?? 600 }, fontLoaded && /* @__PURE__ */ React.createElement(Chart, { ref: chartRef, type: "bar", data: { labels, datasets: processedDatasets }, options }));
92
196
  }
93
197
 
94
198
  // src/charts/pie/index.tsx
95
199
  import { Pie } from "react-chartjs-2";
96
200
  import { Chart as ChartJS2, ArcElement, Tooltip as Tooltip2, Legend as Legend2 } from "chart.js";
97
- import { Box as Box2 } from "@mui/material";
201
+ import { useMemo, useRef as useRef2, useEffect as useEffect2, useState as useState2 } from "react";
202
+ import { Box as Box2, Typography } from "@mui/material";
98
203
  import Image from "next/image";
99
204
  import ChartDataLabels from "chartjs-plugin-datalabels";
100
205
  ChartJS2.register(ArcElement, Tooltip2, Legend2, ChartDataLabels);
206
+ ChartJS2.defaults.font.family = "Vazir, sans-serif";
101
207
  function PieChart({
102
208
  labels,
103
209
  datasets,
@@ -107,18 +213,83 @@ function PieChart({
107
213
  showDataLabels = false,
108
214
  showPercentage = false
109
215
  }) {
110
- const options = {
216
+ const chartRef = useRef2(null);
217
+ const [dataLabels, setDataLabels] = useState2([]);
218
+ const containerRef = useRef2(null);
219
+ const calculateLabels = () => {
220
+ if (!showDataLabels || !chartRef.current || !containerRef.current) return;
221
+ const chart = chartRef.current;
222
+ const meta = chart.getDatasetMeta(0);
223
+ const data = chart.data.datasets[0].data;
224
+ const chartArea = chart.chartArea;
225
+ const visibleTotal = data.reduce((sum, val, index) => {
226
+ if (!meta.data[index] || meta.data[index].hidden !== true) {
227
+ return sum + val;
228
+ }
229
+ return sum;
230
+ }, 0);
231
+ const newLabels = [];
232
+ meta.data.forEach((arc, index) => {
233
+ if (arc.hidden) return;
234
+ const value = data[index];
235
+ if (value === 0) return;
236
+ const centerAngle = (arc.startAngle + arc.endAngle) / 2;
237
+ const midRadius = arc.innerRadius + (arc.outerRadius - arc.innerRadius) * 0.65;
238
+ const x = arc.x - Math.cos(centerAngle) * midRadius;
239
+ const y = arc.y + Math.sin(centerAngle) * midRadius;
240
+ let text;
241
+ if (showPercentage) {
242
+ const percentage = (value / visibleTotal * 100).toFixed(1);
243
+ text = percentage + "%";
244
+ } else {
245
+ text = String(value);
246
+ }
247
+ newLabels.push({ x, y, text, opacity: 1 });
248
+ });
249
+ setDataLabels(newLabels);
250
+ };
251
+ useEffect2(() => {
252
+ if (!showDataLabels) {
253
+ setDataLabels([]);
254
+ return;
255
+ }
256
+ const timeout = setTimeout(() => {
257
+ calculateLabels();
258
+ }, 500);
259
+ return () => clearTimeout(timeout);
260
+ }, [datasets, showDataLabels, showPercentage]);
261
+ useEffect2(() => {
262
+ if (!chartRef.current || !showDataLabels) return;
263
+ const chart = chartRef.current;
264
+ const originalUpdate = chart.update.bind(chart);
265
+ chart.update = function(...args) {
266
+ setDataLabels((prev) => prev.map((l) => ({ ...l, opacity: 0 })));
267
+ originalUpdate(...args);
268
+ setTimeout(() => {
269
+ calculateLabels();
270
+ }, 250);
271
+ };
272
+ return () => {
273
+ chart.update = originalUpdate;
274
+ };
275
+ }, [showDataLabels, showPercentage]);
276
+ const options = useMemo(() => ({
111
277
  responsive: true,
112
278
  maintainAspectRatio: false,
113
279
  cutout: !disableLogo ? "59%" : "0%",
280
+ animation: {
281
+ animateRotate: true,
282
+ animateScale: true,
283
+ duration: 400
284
+ },
114
285
  plugins: {
115
286
  tooltip: {
116
287
  bodyFont: {
117
- family: "'Vazir', sans-serif",
288
+ family: "Vazir, sans-serif",
118
289
  size: 14
119
290
  },
120
291
  titleFont: {
121
- family: "'Vazir', sans-serif",
292
+ family: "Vazir, sans-serif",
122
293
  size: 16
123
294
  }
124
295
  },
@@ -130,7 +301,7 @@ function PieChart({
130
301
  // رنگ متن legend را نرم‌تر می‌کند
131
302
  font: {
132
303
  size: 16,
133
- family: "'Vazir', sans-serif"
304
+ family: "Vazir, sans-serif"
134
305
  },
135
306
  boxWidth: 40,
136
307
  paddingBottom: 10,
@@ -161,38 +332,11 @@ function PieChart({
161
332
  }
162
333
  },
163
334
  datalabels: {
164
- display: (context) => {
165
- return showDataLabels && !context.chart.getDatasetMeta(context.datasetIndex).data[context.dataIndex].hidden;
166
- },
167
- color: "#fff",
168
- font: {
169
- size: 14,
170
- weight: "bold",
171
- family: "'Vazir', sans-serif"
172
- },
173
- anchor: "center",
174
- // ← روی مرکز هر تکه
175
- align: "center",
176
- offset: 20,
177
- // فاصله از مرکز (می‌تونی کم/زیاد کنی)
178
- formatter: showPercentage ? (value, context) => {
179
- if (value === 0) return "";
180
- const total = context.chart.data.datasets[context.datasetIndex].data.reduce(
181
- (sum, val, index) => {
182
- const meta = context.chart.getDatasetMeta(context.datasetIndex);
183
- if (!meta.data[index] || meta.data[index].hidden !== true) {
184
- return sum + val;
185
- }
186
- return sum;
187
- },
188
- 0
189
- );
190
- const percentage = (value / total * 100).toFixed(1);
191
- return percentage + "%";
192
- } : (value) => value === 0 ? "" : value
335
+ display: false
336
+ // غیرفعال - لیبل‌ها با React رندر می‌شوند
193
337
  }
194
338
  }
195
- };
339
+ }), [disableLogo]);
196
340
  const CenterComponent = () => {
197
341
  return /* @__PURE__ */ React.createElement(
198
342
  "div",
@@ -216,16 +360,37 @@ function PieChart({
216
360
  )
217
361
  );
218
362
  };
219
- return /* @__PURE__ */ React.createElement(Box2, { height: height ?? 600, sx: { position: "relative" } }, /* @__PURE__ */ React.createElement(
363
+ return /* @__PURE__ */ React.createElement(Box2, { ref: containerRef, height: height ?? 600, sx: { position: "relative" } }, /* @__PURE__ */ React.createElement(
220
364
  Pie,
221
365
  {
366
+ ref: chartRef,
222
367
  data: {
223
368
  labels,
224
369
  datasets
225
370
  },
226
371
  options
227
372
  }
228
- ), !disableLogo && /* @__PURE__ */ React.createElement(
373
+ ), showDataLabels && dataLabels.map((label, index) => /* @__PURE__ */ React.createElement(
374
+ Typography,
375
+ {
376
+ key: index,
377
+ sx: {
378
+ position: "absolute",
379
+ left: label.x / (window.devicePixelRatio || 1),
380
+ top: label.y / (window.devicePixelRatio || 1),
381
+ transform: "translate(-50%, -50%)",
382
+ color: "#fff",
383
+ fontWeight: "bold",
384
+ fontSize: 14,
385
+ fontFamily: "Vazir, sans-serif",
386
+ pointerEvents: "none",
387
+ textShadow: "0 1px 2px rgba(0,0,0,0.5)",
388
+ opacity: label.opacity,
389
+ transition: "opacity 0.2s ease-in-out, left 0.2s ease-in-out, top 0.2s ease-in-out"
390
+ }
391
+ },
392
+ label.text
393
+ )), !disableLogo && /* @__PURE__ */ React.createElement(
229
394
  "div",
230
395
  {
231
396
  style: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../react-shim.js","../../src/charts/bar/index.tsx","../../src/charts/pie/index.tsx"],"sourcesContent":["import * as React from \"react\";\nexport { React };\n","\"use client\";\r\nimport { Chart } from \"react-chartjs-2\";\r\nimport {\r\n Chart as ChartJS,\r\n CategoryScale,\r\n LinearScale,\r\n BarElement,\r\n LineElement,\r\n PointElement,\r\n Tooltip,\r\n Legend,\r\n BarController,\r\n LineController,\r\n Chart as ChartType,\r\n} from \"chart.js\";\r\nimport { Box } from \"@mui/material\";\r\n\r\nChartJS.register(\r\n CategoryScale,\r\n LinearScale,\r\n BarElement,\r\n LineElement,\r\n PointElement,\r\n Tooltip,\r\n Legend,\r\n BarController,\r\n LineController\r\n);\r\n\r\ninterface Props {\r\n labels: string[];\r\n datasets: {\r\n label: string;\r\n data: (number | null)[];\r\n backgroundColor: string;\r\n borderColor?: string;\r\n borderWidth?: number;\r\n type?: \"line\";\r\n order?: number;\r\n tension?: number;\r\n pointRadius?: number;\r\n fill?: boolean;\r\n }[];\r\n height?: number;\r\n}\r\n/**\r\n * 📊 BarChart — کامپوننت نمودار میله‌ای (Bar/Combo)\r\n *\r\n * @component BarChart\r\n *\r\n * @param {string[]} labels - آرایه‌ای از برچسب‌ها برای محور افقی (X).\r\n * @param {Array<{\r\n * label: string,\r\n * data: number[],\r\n * backgroundColor: string,\r\n * borderColor?: string,\r\n * borderWidth?: number,\r\n * type?: \"line\",\r\n * order?: number,\r\n * tension?: number,\r\n * pointRadius?: number,\r\n * fill?: boolean\r\n * }>} datasets - آرایه‌ای از آبجکت‌های داده برای هر سری نمودار.\r\n * - label: عنوان داده‌ها (نمایش در legend)\r\n * - data: آرایه‌ای از مقادیر هر سری\r\n * - backgroundColor: رنگ میله یا خط\r\n * - borderColor: (اختیاری) رنگ خط دور میله یا خط\r\n * - borderWidth: (اختیاری) ضخامت خط دور میله یا خط\r\n * - type: (اختیاری) اگر \"line\" باشد، سری به صورت خطی نمایش داده می‌شود (نمودار ترکیبی)\r\n * - order: (اختیاری) ترتیب رسم سری (سری با order بالاتر روی بقیه قرار می‌گیرد)\r\n * - tension: (اختیاری) میزان خمیدگی خط (برای سری‌های خطی)\r\n * - pointRadius: (اختیاری) شعاع نقاط روی خط (برای سری‌های خطی)\r\n * - fill: (اختیاری) پر شدن زیر خط (برای سری‌های خطی)\r\n *\r\n * @param {number} [height] - ارتفاع نمودار (پیش‌فرض: 600 پیکسل)\r\n *\r\n * @description\r\n * این کامپوننت یک نمودار میله‌ای (Bar) یا ترکیبی Bar/Line با قابلیت شخصی‌سازی کامل است.\r\n * - پشتیبانی از فونت وزیر و راست‌چین\r\n * - ریسپانسیو و مناسب صفحات فارسی\r\n * - امکان نمایش چند سری داده به صورت میله‌ای و خطی همزمان (Combo)\r\n * - شخصی‌سازی رنگ، ضخامت، ترتیب و استایل هر سری\r\n *\r\n * @returns {JSX.Element} یک نمودار میله‌ای یا ترکیبی با داده‌های ورودی\r\n *\r\n * @example\r\n * ```jsx\r\n * <BarChart\r\n * labels={[\"شنبه\", \"یکشنبه\", \"دوشنبه\"]}\r\n * datasets={[\r\n * {\r\n * label: \"فروش\",\r\n * data: [10, 20, 15],\r\n * backgroundColor: \"rgba(75,192,192,0.7)\",\r\n * },\r\n * {\r\n * label: \"میانگین\",\r\n * data: [12, 18, 14],\r\n * borderColor: \"red\",\r\n * backgroundColor: \"transparent\",\r\n * type: \"line\",\r\n * order: 0,\r\n * borderWidth: 3,\r\n * tension: 0.4,\r\n * pointRadius: 4,\r\n * fill: false,\r\n * },\r\n * ]}\r\n * height={400}\r\n * />\r\n * ```\r\n */\r\nexport default function BarChart({ labels, datasets, height }: Props) {\r\n const options = {\r\n responsive: true,\r\n maintainAspectRatio: false,\r\n scales: {\r\n y: {\r\n ticks: {\r\n font: {\r\n family: \"'Vazir', sans-serif\",\r\n size: 14,\r\n },\r\n },\r\n },\r\n x: {\r\n ticks: {\r\n autoSkip: false,\r\n font: {\r\n family: \"'Vazir', sans-serif\",\r\n size: 13,\r\n },\r\n },\r\n },\r\n },\r\n plugins: {\r\n datalabels: {\r\n display: false, // ← غیرفعال\r\n },\r\n tooltip: {\r\n bodyFont: {\r\n family: \"'Vazir', sans-serif\",\r\n size: 14,\r\n },\r\n titleFont: {\r\n family: \"'Vazir', sans-serif\",\r\n size: 16,\r\n },\r\n },\r\n legend: {\r\n labels: {\r\n generateLabels: function (chart: ChartType) {\r\n const labels =\r\n ChartJS.defaults.plugins.legend.labels.generateLabels(chart);\r\n return labels.map((label) => ({\r\n ...label,\r\n text: \" \" + label.text + \" \",\r\n boxWidth: 40,\r\n boxHeight: 20,\r\n }));\r\n },\r\n padding: 15,\r\n usePointStyle: true,\r\n font: {\r\n size: 16,\r\n family: \"'Vazir', sans-serif\",\r\n },\r\n boxWidth: 40,\r\n paddingBottom: 10,\r\n },\r\n },\r\n },\r\n };\r\n\r\n return (\r\n <Box height={height ?? 600}>\r\n <Chart type=\"bar\" data={{ labels, datasets }} options={options} />\r\n </Box>\r\n );\r\n}\r\n","'use client'\nimport { Pie } from \"react-chartjs-2\";\nimport { Chart as ChartJS, ArcElement, Tooltip, Legend, Chart } from \"chart.js\";\nimport { useMemo } from \"react\";\nimport { Box } from \"@mui/material\";\nimport Image from \"next/image\";\nimport ChartDataLabels from \"chartjs-plugin-datalabels\";\n\nChartJS.register(ArcElement, Tooltip, Legend, ChartDataLabels);\n\ninterface Props {\n labels: string[];\n datasets: {\n label: string;\n data: number[];\n backgroundColor: string | string[];\n borderWidth?: number;\n }[];\n height?: number;\n disableLogo?: boolean;\n logoSRC?: string;\n showDataLabels?: boolean;\n showPercentage?: boolean;\n}\n/**\n * 📊 PieChart — کامپوننت نمودار دایره‌ای (Pie)\n *\n * @component PieChart\n *\n * @param {string[]} labels - آرایه‌ای از برچسب‌ها برای هر بخش نمودار.\n * @param {boolean} [showDataLabels] - نمایش یا عدم نمایش برچسب‌های داده‌ها\n * @param {boolean} [showPercentage] - نمایش درصد به جای مقدار عددی در برچسب‌های داده‌ها (در صورت فعال بودن showDataLabels). درصد بر اساس داده‌های قابل مشاهده محاسبه می‌شود.\n * @param {Array<{\n * label: string,\n * data: number[],\n * backgroundColor: string[],\n * borderWidth?: number\n * }>} datasets - آرایه‌ای شامل یک آبجکت داده برای مقداردهی بخش‌های نمودار.\n * - label: عنوان داده‌ها (نمایش در legend)\n * - data: آرایه‌ای از مقادیر هر بخش\n * - backgroundColor: آرایه‌ای از رنگ‌ها برای هر بخش\n * - borderWidth: (اختیاری) ضخامت خط دور هر بخش\n * @param {number} [height] - ارتفاع نمودار (پیش‌فرض: 600 پیکسل)\n *\n * @description\n * این کامپوننت یک نمودار دایره‌ای با قابلیت شخصی‌سازی رنگ، داده و فونت (هماهنگ با وزیر) است.\n * - ریسپانسیو و مناسب صفحات فارسی\n * - امکان نمایش لوگو یا کامپوننت دلخواه در مرکز نمودار\n * - امکان نمایش درصد یا مقدار عددی در برچسب‌های داده‌ها بر اساس داده‌های قابل مشاهده\n *\n * @returns {JSX.Element} یک نمودار دایره‌ای با داده‌های ورودی\n *\n * @example\n * ```jsx\n * <PieChart\n * labels={[\"بخش اول\", \"بخش دوم\", \"بخش سوم\"]}\n * datasets={[\n * {\n * label: \"مقدار\",\n * data: [10, 20, 30],\n * backgroundColor: [\n * \"rgba(75,192,192,1)\",\n * \"rgba(255,99,132,1)\",\n * \"rgba(153,102,255,1)\",\n * ],\n * borderWidth: 2,\n * },\n * ]}\n * showDataLabels={true}\n * showPercentage={true}\n * />\n * ```\n */\nexport default function PieChart({\n labels,\n datasets,\n height,\n disableLogo,\n logoSRC,\n showDataLabels = false,\n showPercentage = false,\n}: Props) {\n const options = {\n responsive: true,\n maintainAspectRatio: false,\n cutout: !disableLogo ? \"59%\" : \"0%\",\n plugins: {\n tooltip: {\n bodyFont: {\n family: \"'Vazir', sans-serif\",\n size: 14,\n },\n titleFont: {\n family: \"'Vazir', sans-serif\",\n size: 16,\n },\n },\n legend: {\n labels: {\n padding: 15,\n usePointStyle: true,\n color: '#666', // رنگ متن legend را نرم‌تر می‌کند\n font: {\n size: 16,\n family: \"'Vazir', sans-serif\",\n },\n boxWidth: 40,\n paddingBottom: 10,\n generateLabels: (chart: any) => {\n const data = chart.data;\n const meta = chart.getDatasetMeta(0);\n return data.labels.map((label: string, index: number) => {\n const hidden = meta.data[index] ? meta.data[index].hidden : false;\n return {\n text: label,\n fillStyle: data.datasets[0].backgroundColor[index] || '#000',\n hidden: hidden,\n index: index,\n datasetIndex: 0,\n textDecoration: hidden ? 'line-through' : undefined,\n };\n });\n },\n },\n onClick: (e: any, legendItem: any, legend: any) => {\n const ci = legend.chart;\n const meta = ci.getDatasetMeta(legendItem.datasetIndex || 0);\n const index = legendItem.index;\n if (meta.data[index]) {\n meta.data[index].hidden = !meta.data[index].hidden;\n }\n ci.update();\n },\n },\n datalabels: {\n display: (context: any) => {\n return showDataLabels && !context.chart.getDatasetMeta(context.datasetIndex).data[context.dataIndex].hidden;\n },\n color: \"#fff\",\n font: {\n size: 14,\n weight: \"bold\",\n family: \"'Vazir', sans-serif\",\n } as const,\n anchor: \"center\" as const, // ← روی مرکز هر تکه\n align: \"center\" as const,\n offset: 20, // فاصله از مرکز (می‌تونی کم/زیاد کنی)\n formatter: showPercentage\n ? (value: number, context: any) => {\n if (value === 0) return \"\";\n // محاسبه مجموع داده‌های قابل مشاهده\n const total = context.chart.data.datasets[context.datasetIndex].data.reduce(\n (sum: number, val: number, index: number) => {\n const meta = context.chart.getDatasetMeta(context.datasetIndex);\n if (!meta.data[index] || meta.data[index].hidden !== true) {\n return sum + val;\n }\n return sum;\n },\n 0\n );\n const percentage = ((value / total) * 100).toFixed(1);\n return percentage + \"%\";\n }\n : (value: number) => (value === 0 ? \"\" : value),\n },\n },\n };\n\n // کامپوننتی که می‌خواهید در مرکز نمودار نمایش داده شود\n const CenterComponent = () => {\n return (\n <div\n style={{\n padding: \"10px\",\n borderRadius: \"8px\",\n textAlign: \"center\",\n width: 220,\n }}\n >\n <Image\n alt=\"\"\n width={220}\n height={220}\n src={logoSRC ?? \"/assets/images/pilogo.png\"}\n unoptimized\n />\n </div>\n );\n };\n\n return (\n <Box height={height ?? 600} sx={{ position: \"relative\" }}>\n <Pie\n data={{\n labels: labels,\n datasets: datasets,\n }}\n options={options}\n />\n {!disableLogo && (\n <div\n style={{\n position: \"absolute\",\n top: \"53%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n pointerEvents: \"none\", // جلوگیری از دریافت event روی این لایه\n }}\n >\n <CenterComponent />\n </div>\n )}\n </Box>\n );\n}\n"],"mappings":"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","names":["labels","ChartJS","Tooltip","Legend","Box"]}
1
+ {"version":3,"sources":["../../react-shim.js","../../src/charts/bar/index.tsx","../../src/charts/pie/index.tsx"],"sourcesContent":["import * as React from \"react\";\nexport { React };\n","\"use client\";\r\nimport { Chart } from \"react-chartjs-2\";\r\nimport {\r\n Chart as ChartJS,\r\n CategoryScale,\r\n LinearScale,\r\n LogarithmicScale,\r\n BarElement,\r\n LineElement,\r\n PointElement,\r\n Tooltip,\r\n Legend,\r\n BarController,\r\n LineController,\r\n Chart as ChartType,\r\n} from \"chart.js\";\r\nimport { Box } from \"@mui/material\";\r\nimport { useRef, useEffect, useState } from \"react\";\r\n\r\nChartJS.register(\r\n CategoryScale,\r\n LinearScale,\r\n LogarithmicScale,\r\n BarElement,\r\n LineElement,\r\n PointElement,\r\n Tooltip,\r\n Legend,\r\n BarController,\r\n LineController\r\n);\r\n\r\n// تنظیم فونت پیش‌فرض Chart.js به Vazir\r\nChartJS.defaults.font.family = \"Vazir, sans-serif\";\r\n\r\ninterface Props {\r\n labels: string[];\r\n datasets: {\r\n label: string;\r\n data: (number | null)[];\r\n backgroundColor: string;\r\n borderColor?: string;\r\n borderWidth?: number;\r\n type?: \"line\";\r\n order?: number;\r\n tension?: number;\r\n pointRadius?: number;\r\n fill?: boolean;\r\n }[];\r\n height?: number;\r\n /**\r\n * حداقل مقدار محور Y (اختیاری)\r\n * اگر ست نشود، Chart.js خودش محاسبه می‌کند\r\n * ⚠️ نکته: اگر این مقدار ست شود، beginAtZero نادیده گرفته می‌شود\r\n */\r\n yAxisMin?: number;\r\n /**\r\n * حداکثر مقدار محور Y (اختیاری)\r\n * اگر ست نشود، Chart.js خودش محاسبه می‌کند\r\n */\r\n yAxisMax?: number;\r\n /**\r\n * آیا محور Y از صفر شروع شود؟\r\n * پیش‌فرض: true\r\n * ⚠️ نکته: اگر yAxisMin ست شود، این گزینه نادیده گرفته می‌شود\r\n */\r\n beginAtZero?: boolean;\r\n /**\r\n * استفاده از مقیاس لگاریتمی برای محور Y\r\n * مناسب برای داده‌هایی که اختلاف خیلی زیادی دارند\r\n * پیش‌فرض: false\r\n * ⚠️ نکته: مقادیر 0 یا منفی در مقیاس لگاریتمی نمایش داده نمی‌شوند\r\n */\r\n logarithmic?: boolean;\r\n /**\r\n * حداقل ارتفاع میله برای داده‌های خیلی کوچک (پیکسل)\r\n * مقادیر خیلی کوچک (مثل 1) در کنار مقادیر بزرگ (مثل 10000) گم نمی‌شوند\r\n * پیش‌فرض: 0 (غیرفعال)\r\n */\r\n minBarLength?: number;\r\n}\r\n/**\r\n * 📊 BarChart — کامپوننت نمودار میله‌ای (Bar/Combo)\r\n *\r\n * @component BarChart\r\n *\r\n * @param {string[]} labels - آرایه‌ای از برچسب‌ها برای محور افقی (X).\r\n * @param {Array<{\r\n * label: string,\r\n * data: number[],\r\n * backgroundColor: string,\r\n * borderColor?: string,\r\n * borderWidth?: number,\r\n * type?: \"line\",\r\n * order?: number,\r\n * tension?: number,\r\n * pointRadius?: number,\r\n * fill?: boolean\r\n * }>} datasets - آرایه‌ای از آبجکت‌های داده برای هر سری نمودار.\r\n * - label: عنوان داده‌ها (نمایش در legend)\r\n * - data: آرایه‌ای از مقادیر هر سری\r\n * - backgroundColor: رنگ میله یا خط\r\n * - borderColor: (اختیاری) رنگ خط دور میله یا خط\r\n * - borderWidth: (اختیاری) ضخامت خط دور میله یا خط\r\n * - type: (اختیاری) اگر \"line\" باشد، سری به صورت خطی نمایش داده می‌شود (نمودار ترکیبی)\r\n * - order: (اختیاری) ترتیب رسم سری (سری با order بالاتر روی بقیه قرار می‌گیرد)\r\n * - tension: (اختیاری) میزان خمیدگی خط (برای سری‌های خطی)\r\n * - pointRadius: (اختیاری) شعاع نقاط روی خط (برای سری‌های خطی)\r\n * - fill: (اختیاری) پر شدن زیر خط (برای سری‌های خطی)\r\n *\r\n * @param {number} [height] - ارتفاع نمودار (پیش‌فرض: 600 پیکسل)\r\n * @param {number} [yAxisMin] - حداقل مقدار محور Y (نادیده‌گرفتن beginAtZero)\r\n * @param {number} [yAxisMax] - حداکثر مقدار محور Y\r\n * @param {boolean} [beginAtZero=true] - آیا محور Y از صفر شروع شود؟ (اگر yAxisMin ست شود نادیده گرفته می‌شود)\r\n * @param {boolean} [logarithmic=false] - استفاده از مقیاس لگاریتمی (مقادیر 0 یا منفی نمایش داده نمی‌شوند)\r\n * @param {number} [minBarLength=0] - حداقل ارتفاع میله (پیکسل) - برای جلوگیری از گم شدن داده‌های کوچک\r\n *\r\n * @description\r\n * این کامپوننت یک نمودار میله‌ای (Bar) یا ترکیبی Bar/Line با قابلیت شخصی‌سازی کامل است.\r\n * - پشتیبانی از فونت وزیر و راست‌چین\r\n * - ریسپانسیو و مناسب صفحات فارسی\r\n * - امکان نمایش چند سری داده به صورت میله‌ای و خطی همزمان (Combo)\r\n * - شخصی‌سازی رنگ، ضخامت، ترتیب و استایل هر سری\r\n * - پشتیبانی از مقیاس لگاریتمی برای داده‌های با اختلاف زیاد\r\n * - minBarLength برای نمایش داده‌های خیلی کوچک در کنار بزرگ‌ها\r\n *\r\n * @returns {JSX.Element} یک نمودار میله‌ای یا ترکیبی با داده‌های ورودی\r\n *\r\n * @example\r\n * ```jsx\r\n * // نمودار ساده\r\n * <BarChart\r\n * labels={[\"شنبه\", \"یکشنبه\", \"دوشنبه\"]}\r\n * datasets={[\r\n * {\r\n * label: \"فروش\",\r\n * data: [10, 20, 15],\r\n * backgroundColor: \"rgba(75,192,192,0.7)\",\r\n * },\r\n * ]}\r\n * height={400}\r\n * />\r\n *\r\n * // نمودار با داده‌های اختلاف زیاد (مقیاس لگاریتمی)\r\n * <BarChart\r\n * labels={[\"A\", \"B\", \"C\", \"D\"]}\r\n * datasets={[\r\n * {\r\n * label: \"مقادیر\",\r\n * data: [5, 50, 5000, 50000],\r\n * backgroundColor: \"rgba(75,192,192,0.7)\",\r\n * },\r\n * ]}\r\n * logarithmic={true}\r\n * height={400}\r\n * />\r\n *\r\n * // نمودار با کنترل دستی بازه محور Y\r\n * <BarChart\r\n * labels={[\"A\", \"B\", \"C\"]}\r\n * datasets={[\r\n * {\r\n * label: \"مقادیر\",\r\n * data: [100, 150, 120],\r\n * backgroundColor: \"rgba(75,192,192,0.7)\",\r\n * },\r\n * ]}\r\n * yAxisMin={80}\r\n * yAxisMax={200}\r\n * beginAtZero={false}\r\n * height={400}\r\n * />\r\n * ```\r\n */\r\nexport default function BarChart({\r\n labels,\r\n datasets,\r\n height,\r\n yAxisMin,\r\n yAxisMax,\r\n beginAtZero = true,\r\n logarithmic = false,\r\n minBarLength = 0,\r\n}: Props) {\r\n const chartRef = useRef<ChartJS>(null);\r\n const [fontLoaded, setFontLoaded] = useState(false);\r\n\r\n // صبر برای لود شدن فونت Vazir و سپس آپدیت chart\r\n useEffect(() => {\r\n let isMounted = true;\r\n\r\n const loadFont = async () => {\r\n if (typeof document !== \"undefined\" && document.fonts) {\r\n try {\r\n // منتظر لود شدن فونت Vazir به صورت مستقیم\r\n await document.fonts.load(\"16px Vazir\");\r\n await document.fonts.ready;\r\n } catch (e) {\r\n // اگر فونت پیدا نشد، ادامه بده\r\n }\r\n\r\n if (isMounted) {\r\n setFontLoaded(true);\r\n // آپدیت chart بعد از لود فونت\r\n setTimeout(() => {\r\n if (chartRef.current) {\r\n chartRef.current.update();\r\n }\r\n }, 100);\r\n }\r\n } else {\r\n if (isMounted) setFontLoaded(true);\r\n }\r\n };\r\n\r\n loadFont();\r\n\r\n return () => { isMounted = false; };\r\n }, []);\r\n\r\n // محاسبه min/max فقط بر اساس داده‌های visible\r\n const getVisibleData = (): number[] => {\r\n if (!chartRef.current) return [];\r\n // فقط سری‌هایی که visible هستند و نوعشان bar است\r\n return datasets.reduce((acc: number[], ds, i) => {\r\n // اگر سری فعال است و نوعش bar است\r\n // @ts-ignore\r\n if ((ds.type === undefined || ds.type === \"bar\") && chartRef.current && typeof chartRef.current.isDatasetVisible === \"function\" && chartRef.current.isDatasetVisible(i)) {\r\n ds.data.forEach((v: number | null) => {\r\n if (typeof v === \"number\" && v > 0) acc.push(v);\r\n });\r\n }\r\n return acc;\r\n }, []);\r\n };\r\n\r\n let autoMin = yAxisMin;\r\n let autoMax = yAxisMax;\r\n if (logarithmic && yAxisMin === undefined && yAxisMax === undefined) {\r\n const visibleData = getVisibleData();\r\n if (visibleData.length) {\r\n const minVal = Math.min(...visibleData);\r\n const maxVal = Math.max(...visibleData);\r\n autoMin = minVal < 1 ? 0.5 : minVal * 0.7;\r\n autoMax = minVal === maxVal ? maxVal * 1.2 : maxVal * 1.1;\r\n }\r\n }\r\n\r\n // هر بار که legend تغییر کند، نمودار را آپدیت کن تا min/max درست شود\r\n useEffect(() => {\r\n if (!logarithmic || yAxisMin !== undefined || yAxisMax !== undefined) return;\r\n if (!chartRef.current) return;\r\n const handler = () => {\r\n // آپدیت min/max و نمودار\r\n const visibleData = getVisibleData();\r\n if (visibleData.length && chartRef.current && chartRef.current.options && chartRef.current.options.scales && chartRef.current.options.scales.y) {\r\n const minVal = Math.min(...visibleData);\r\n const maxVal = Math.max(...visibleData);\r\n chartRef.current.options.scales.y.min = minVal < 1 ? 0.5 : minVal * 0.7;\r\n chartRef.current.options.scales.y.max = minVal === maxVal ? maxVal * 1.2 : maxVal * 1.1;\r\n chartRef.current.update();\r\n }\r\n };\r\n // گوش دادن به event legend\r\n chartRef.current?.canvas?.addEventListener(\"click\", handler);\r\n return () => {\r\n chartRef.current?.canvas?.removeEventListener(\"click\", handler);\r\n };\r\n }, [logarithmic, yAxisMin, yAxisMax, datasets]);\r\n\r\n const options = {\r\n responsive: true,\r\n maintainAspectRatio: false,\r\n scales: {\r\n y: {\r\n type: logarithmic ? (\"logarithmic\" as const) : (\"linear\" as const),\r\n ...(yAxisMin === undefined && yAxisMax === undefined && !logarithmic && {\r\n beginAtZero: beginAtZero,\r\n }),\r\n ...(autoMin !== undefined && { min: autoMin }),\r\n ...(autoMax !== undefined && { max: autoMax }),\r\n ticks: {\r\n font: {\r\n family: \"Vazir, sans-serif\",\r\n size: 14,\r\n },\r\n ...(logarithmic && {\r\n callback: function (value: number | string) {\r\n const numValue = Number(value);\r\n // فقط توان‌های ۱۰ را نمایش بده\r\n if (numValue === 0) return null;\r\n const log10 = Math.log10(numValue);\r\n if (Math.abs(log10 - Math.round(log10)) < 0.0001) {\r\n if (numValue >= 1000000) return (numValue / 1000000).toFixed(1) + \"M\";\r\n if (numValue >= 1000) return (numValue / 1000).toFixed(1) + \"K\";\r\n return numValue;\r\n }\r\n return null;\r\n },\r\n }),\r\n },\r\n },\r\n x: {\r\n ticks: {\r\n autoSkip: false,\r\n font: {\r\n family: \"Vazir, sans-serif\",\r\n size: 13,\r\n },\r\n },\r\n },\r\n },\r\n plugins: {\r\n datalabels: {\r\n display: false, // ← غیرفعال\r\n },\r\n tooltip: {\r\n bodyFont: {\r\n family: \"Vazir, sans-serif\",\r\n size: 14,\r\n },\r\n titleFont: {\r\n family: \"Vazir, sans-serif\",\r\n size: 16,\r\n },\r\n },\r\n legend: {\r\n labels: {\r\n generateLabels: function (chart: ChartType) {\r\n const labels =\r\n ChartJS.defaults.plugins.legend.labels.generateLabels(chart);\r\n return labels.map((label) => ({\r\n ...label,\r\n text: \" \" + label.text + \" \",\r\n boxWidth: 40,\r\n boxHeight: 20,\r\n }));\r\n },\r\n padding: 15,\r\n usePointStyle: true,\r\n font: {\r\n size: 16,\r\n family: \"Vazir, sans-serif\",\r\n },\r\n boxWidth: 40,\r\n paddingBottom: 10,\r\n },\r\n },\r\n },\r\n };\r\n\r\n // اضافه کردن minBarLength به همه datasets\r\n const processedDatasets = datasets.map((ds) => ({\r\n ...ds,\r\n minBarLength: minBarLength,\r\n }));\r\n\r\n return (\r\n <Box height={height ?? 600}>\r\n {fontLoaded && (\r\n <Chart ref={chartRef} type=\"bar\" data={{ labels, datasets: processedDatasets }} options={options} />\r\n )}\r\n </Box>\r\n );\r\n}\r\n","'use client'\nimport { Pie } from \"react-chartjs-2\";\nimport { Chart as ChartJS, ArcElement, Tooltip, Legend, Chart } from \"chart.js\";\nimport { useMemo, useRef, useEffect, useState } from \"react\";\nimport { Box, Typography } from \"@mui/material\";\nimport Image from \"next/image\";\nimport ChartDataLabels from \"chartjs-plugin-datalabels\";\n\nChartJS.register(ArcElement, Tooltip, Legend, ChartDataLabels);\n\n// تنظیم فونت پیش‌فرض Chart.js به Vazir\nChartJS.defaults.font.family = \"Vazir, sans-serif\";\n\ninterface Props {\n labels: string[];\n datasets: {\n label: string;\n data: number[];\n backgroundColor: string | string[];\n borderWidth?: number;\n }[];\n height?: number;\n disableLogo?: boolean;\n logoSRC?: string;\n showDataLabels?: boolean;\n showPercentage?: boolean;\n}\n/**\n * 📊 PieChart — کامپوننت نمودار دایره‌ای (Pie)\n *\n * @component PieChart\n *\n * @param {string[]} labels - آرایه‌ای از برچسب‌ها برای هر بخش نمودار.\n * @param {boolean} [showDataLabels] - نمایش یا عدم نمایش برچسب‌های داده‌ها\n * @param {boolean} [showPercentage] - نمایش درصد به جای مقدار عددی در برچسب‌های داده‌ها (در صورت فعال بودن showDataLabels). درصد بر اساس داده‌های قابل مشاهده محاسبه می‌شود.\n * @param {Array<{\n * label: string,\n * data: number[],\n * backgroundColor: string[],\n * borderWidth?: number\n * }>} datasets - آرایه‌ای شامل یک آبجکت داده برای مقداردهی بخش‌های نمودار.\n * - label: عنوان داده‌ها (نمایش در legend)\n * - data: آرایه‌ای از مقادیر هر بخش\n * - backgroundColor: آرایه‌ای از رنگ‌ها برای هر بخش\n * - borderWidth: (اختیاری) ضخامت خط دور هر بخش\n * @param {number} [height] - ارتفاع نمودار (پیش‌فرض: 600 پیکسل)\n *\n * @description\n * این کامپوننت یک نمودار دایره‌ای با قابلیت شخصی‌سازی رنگ، داده و فونت (هماهنگ با وزیر) است.\n * - ریسپانسیو و مناسب صفحات فارسی\n * - امکان نمایش لوگو یا کامپوننت دلخواه در مرکز نمودار\n * - امکان نمایش درصد یا مقدار عددی در برچسب‌های داده‌ها بر اساس داده‌های قابل مشاهده\n *\n * @returns {JSX.Element} یک نمودار دایره‌ای با داده‌های ورودی\n *\n * @example\n * ```jsx\n * <PieChart\n * labels={[\"بخش اول\", \"بخش دوم\", \"بخش سوم\"]}\n * datasets={[\n * {\n * label: \"مقدار\",\n * data: [10, 20, 30],\n * backgroundColor: [\n * \"rgba(75,192,192,1)\",\n * \"rgba(255,99,132,1)\",\n * \"rgba(153,102,255,1)\",\n * ],\n * borderWidth: 2,\n * },\n * ]}\n * showDataLabels={true}\n * showPercentage={true}\n * />\n * ```\n */\nexport default function PieChart({\n labels,\n datasets,\n height,\n disableLogo,\n logoSRC,\n showDataLabels = false,\n showPercentage = false,\n}: Props) {\n const chartRef = useRef<ChartJS<\"pie\">>(null);\n const [dataLabels, setDataLabels] = useState<{ x: number; y: number; text: string; opacity: number }[]>([]);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // تابع محاسبه موقعیت لیبل‌ها\n const calculateLabels = () => {\n if (!showDataLabels || !chartRef.current || !containerRef.current) return;\n\n const chart = chartRef.current;\n const meta = chart.getDatasetMeta(0);\n const data = chart.data.datasets[0].data as number[];\n\n // گرفتن اطلاعات chart area\n const chartArea = chart.chartArea;\n\n // محاسبه مجموع داده‌های قابل مشاهده\n const visibleTotal = data.reduce((sum, val, index) => {\n if (!meta.data[index] || (meta.data[index] as any).hidden !== true) {\n return sum + val;\n }\n return sum;\n }, 0);\n\n const newLabels: { x: number; y: number; text: string; opacity: number }[] = [];\n\n meta.data.forEach((arc: any, index: number) => {\n if (arc.hidden) return;\n\n const value = data[index];\n if (value === 0) return;\n\n // محاسبه مرکز arc\n const centerAngle = (arc.startAngle + arc.endAngle) / 2;\n // نزدیک‌تر به دیواره (0.7 = بین مرکز و لبه، هرچه بیشتر به 1 نزدیک‌تر = نزدیک‌تر به لبه)\n const midRadius = arc.innerRadius + (arc.outerRadius - arc.innerRadius) * 0.65;\n\n // موقعیت در chart area - آینه کردن روی محور X\n const x = arc.x - Math.cos(centerAngle) * midRadius;\n const y = arc.y + Math.sin(centerAngle) * midRadius;\n\n let text: string;\n if (showPercentage) {\n const percentage = ((value / visibleTotal) * 100).toFixed(1);\n text = percentage + \"%\";\n } else {\n text = String(value);\n }\n\n newLabels.push({ x, y, text, opacity: 1 });\n });\n\n setDataLabels(newLabels);\n };\n\n // محاسبه موقعیت لیبل‌ها بعد از اتمام انیمیشن\n useEffect(() => {\n if (!showDataLabels) {\n setDataLabels([]);\n return;\n }\n\n // صبر برای اتمام انیمیشن اولیه (500ms)\n const timeout = setTimeout(() => {\n calculateLabels();\n }, 500);\n\n return () => clearTimeout(timeout);\n }, [datasets, showDataLabels, showPercentage]);\n\n // آپدیت لیبل‌ها بعد از هر تغییر در chart (مثل کلیک روی legend)\n useEffect(() => {\n if (!chartRef.current || !showDataLabels) return;\n\n const chart = chartRef.current;\n const originalUpdate = chart.update.bind(chart);\n\n chart.update = function (...args: any[]) {\n // مخفی کردن لیبل‌ها قبل از آپدیت\n setDataLabels(prev => prev.map(l => ({ ...l, opacity: 0 })));\n\n originalUpdate(...args);\n\n // محاسبه مجدد لیبل‌ها بعد از انیمیشن\n setTimeout(() => {\n calculateLabels();\n }, 250);\n };\n\n return () => {\n chart.update = originalUpdate;\n };\n }, [showDataLabels, showPercentage]);\n\n const options = useMemo(() => ({\n responsive: true,\n maintainAspectRatio: false,\n cutout: !disableLogo ? \"59%\" : \"0%\",\n animation: {\n animateRotate: true,\n animateScale: true,\n duration: 400,\n },\n plugins: {\n tooltip: {\n bodyFont: {\n family: \"Vazir, sans-serif\",\n size: 14,\n },\n titleFont: {\n family: \"Vazir, sans-serif\",\n size: 16,\n },\n },\n legend: {\n labels: {\n padding: 15,\n usePointStyle: true,\n color: '#666', // رنگ متن legend را نرم‌تر می‌کند\n font: {\n size: 16,\n family: \"Vazir, sans-serif\",\n },\n boxWidth: 40,\n paddingBottom: 10,\n generateLabels: (chart: any) => {\n const data = chart.data;\n const meta = chart.getDatasetMeta(0);\n return data.labels.map((label: string, index: number) => {\n const hidden = meta.data[index] ? meta.data[index].hidden : false;\n return {\n text: label,\n fillStyle: data.datasets[0].backgroundColor[index] || '#000',\n hidden: hidden,\n index: index,\n datasetIndex: 0,\n textDecoration: hidden ? 'line-through' : undefined,\n };\n });\n },\n },\n onClick: (e: any, legendItem: any, legend: any) => {\n const ci = legend.chart;\n const meta = ci.getDatasetMeta(legendItem.datasetIndex || 0);\n const index = legendItem.index;\n if (meta.data[index]) {\n meta.data[index].hidden = !meta.data[index].hidden;\n }\n ci.update();\n },\n },\n datalabels: {\n display: false, // غیرفعال - لیبل‌ها با React رندر می‌شوند\n },\n },\n }), [disableLogo]);\n\n // کامپوننتی که می‌خواهید در مرکز نمودار نمایش داده شود\n const CenterComponent = () => {\n return (\n <div\n style={{\n padding: \"10px\",\n borderRadius: \"8px\",\n textAlign: \"center\",\n width: 220,\n }}\n >\n <Image\n alt=\"\"\n width={220}\n height={220}\n src={logoSRC ?? \"/assets/images/pilogo.png\"}\n unoptimized\n />\n </div>\n );\n };\n\n return (\n <Box ref={containerRef} height={height ?? 600} sx={{ position: \"relative\" }}>\n <Pie\n ref={chartRef}\n data={{\n labels: labels,\n datasets: datasets,\n }}\n options={options}\n />\n {/* لیبل‌های سفارشی با فونت Vazir */}\n {showDataLabels && dataLabels.map((label, index) => (\n <Typography\n key={index}\n sx={{\n position: \"absolute\",\n left: label.x / (window.devicePixelRatio || 1),\n top: label.y / (window.devicePixelRatio || 1),\n transform: \"translate(-50%, -50%)\",\n color: \"#fff\",\n fontWeight: \"bold\",\n fontSize: 14,\n fontFamily: \"Vazir, sans-serif\",\n pointerEvents: \"none\",\n textShadow: \"0 1px 2px rgba(0,0,0,0.5)\",\n opacity: label.opacity,\n transition: \"opacity 0.2s ease-in-out, left 0.2s ease-in-out, top 0.2s ease-in-out\",\n }}\n >\n {label.text}\n </Typography>\n ))}\n {!disableLogo && (\n <div\n style={{\n position: \"absolute\",\n top: \"53%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n pointerEvents: \"none\", // جلوگیری از دریافت event روی این لایه\n }}\n >\n <CenterComponent />\n </div>\n )}\n </Box>\n );\n}\n"],"mappings":"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","names":["labels","ChartJS","Tooltip","Legend","useRef","useEffect","useState","Box"]}
@@ -55,6 +55,7 @@ import { Moment } from 'moment-jalaali';
55
55
  * dualCalendar={false} // جدید: کنترل تقویم دوم
56
56
  * singleCalendar={false}
57
57
  * useMobilePickers={false}
58
+ * disableSmartTabs={false}
58
59
  * />
59
60
  * );
60
61
  * };
@@ -116,6 +117,16 @@ import { Moment } from 'moment-jalaali';
116
117
  * />
117
118
  * ```
118
119
  *
120
+ * 6. پنهان کردن تب‌های هوشمند (بدون تغییر عملکرد):
121
+ * ```tsx
122
+ * <DateRangePicker
123
+ * fromDate="from"
124
+ * toDate="to"
125
+ * control={control}
126
+ * disableSmartTabs={true}
127
+ * />
128
+ * ```
129
+ *
119
130
  * ویژگی‌های تب‌های هوشمند (جدید در v3.0):
120
131
  *
121
132
  * ```tsx
@@ -242,6 +253,7 @@ interface DateRangePickerProps {
242
253
  singleCalendar?: boolean;
243
254
  useMobilePickers?: boolean;
244
255
  dualCalendar?: boolean;
256
+ disableSmartTabs?: boolean;
245
257
  variant?: TextFieldVariants;
246
258
  placeholder?: string;
247
259
  disableClearIcon?: boolean;
@@ -364,6 +376,7 @@ interface DateRangePickerProps {
364
376
  * @property {boolean} [clear] - نمایش دکمه پاک کردن (پیش‌فرض: true)
365
377
  * @property {boolean} [singleCalendar] - نمایش تک تقویم به جای دوتایی (پیش‌فرض: false)
366
378
  * @property {boolean} [useMobilePickers] - استفاده از DatePicker جداگانه به جای popup (پیش‌فرض: false)
379
+ * @property {boolean} [disableSmartTabs] - پنهان کردن تب‌های هوشمند بدون تغییر عملکرد (پیش‌فرض: false)
367
380
  *
368
381
  * نکات مهم:
369
382
  * - کامپوننت خودکار mobile detection دارد (breakpoint: 700px)