@mamrp/components 1.7.30 → 1.7.32

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 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"]}
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\";\nimport { useRef, useState } from \"react\";\nimport { Chart } from \"react-chartjs-2\";\nimport {\n Chart as ChartJS,\n CategoryScale,\n LinearScale,\n LogarithmicScale,\n BarElement,\n LineElement,\n PointElement,\n Tooltip,\n Legend,\n BarController,\n LineController,\n Chart as ChartType,\n} from \"chart.js\";\nimport { Box } from \"@mui/material\";\n\nChartJS.register(\n CategoryScale,\n LinearScale,\n LogarithmicScale,\n BarElement,\n LineElement,\n PointElement,\n Tooltip,\n Legend,\n BarController,\n LineController\n);\n\ninterface Dataset {\n label: string;\n data: (number | null)[];\n backgroundColor: string;\n borderColor?: string;\n borderWidth?: number;\n type?: \"line\";\n order?: number;\n tension?: number;\n pointRadius?: number;\n fill?: boolean;\n}\n\ninterface Props {\n labels: string[];\n datasets: Dataset[];\n height?: number;\n}\n\nexport default function BarChart({ labels, datasets, height }: Props) {\n const chartRef = useRef<ChartType | null>(null);\n const [hiddenIndices, setHiddenIndices] = useState<Set<number>>(new Set());\n\n // --- داده‌های visible ---\n const visibleDatasets = datasets.filter((_, i) => !hiddenIndices.has(i));\n const allValues = ([] as number[]).concat(\n ...visibleDatasets.map((ds) =>\n ds.data.filter((v): v is number => v !== null)\n )\n );\n\n const minValue = allValues.length ? Math.min(...allValues) : 0;\n const maxValue = allValues.length ? Math.max(...allValues) : 1;\n\n // --- تصمیم هوشمند برای scale ---\n const useLogScale = maxValue / (minValue || 1) > 50; // اگر اختلاف >50 برابر باشد log scale\n const scaleType: \"linear\" | \"logarithmic\" = useLogScale\n ? \"logarithmic\"\n : \"linear\";\n\n // --- محاسبه محور Y ---\n let yMin = minValue;\n let yMax = maxValue;\n let stepSize: number | undefined = 1;\n\n if (scaleType === \"linear\") {\n const range = yMax - yMin;\n const targetLines = 8;\n let rawStep = range / targetLines;\n\n const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));\n const normalized = rawStep / magnitude;\n if (normalized <= 1) stepSize = 1 * magnitude;\n else if (normalized <= 2) stepSize = 2 * magnitude;\n else if (normalized <= 5) stepSize = 5 * magnitude;\n else stepSize = 10 * magnitude;\n\n yMin = Math.floor(yMin / stepSize) * stepSize;\n yMax = Math.ceil(yMax / stepSize) * stepSize;\n } else {\n yMin = Math.max(minValue, 1);\n yMax = maxValue;\n stepSize = undefined;\n }\n\n // --- تنظیمات Chart.js ---\n const options = {\n responsive: true,\n maintainAspectRatio: false,\n animation: { duration: 500 },\n scales: {\n y: {\n type: scaleType,\n min: yMin,\n max: yMax,\n ticks: {\n ...(stepSize !== undefined ? { stepSize } : {}),\n callback: (value: any) => {\n // محدود کردن تعداد اعشار به حداکثر 2\n const num = Number(value);\n if (scaleType === \"logarithmic\") return num.toLocaleString();\n // اگر عدد خیلی بزرگ است، بدون اعشار\n if (num >= 1000) return num.toLocaleString();\n // اعشار برای اعداد کوچک\n if (stepSize && stepSize < 1) return num.toFixed(2);\n return num;\n },\n font: { family: \"'Vazir', sans-serif\", size: 14 },\n },\n },\n x: {\n ticks: {\n autoSkip: false,\n font: { family: \"'Vazir', sans-serif\", size: 13 },\n },\n },\n },\n plugins: {\n legend: {\n labels: {\n usePointStyle: true, // دایره‌ای\n font: { size: 16, family: \"'Vazir', sans-serif\" },\n },\n onClick: (e: any, legendItem: any, legend: any) => {\n const index = legendItem.datasetIndex as number;\n const newHidden = new Set(hiddenIndices);\n if (hiddenIndices.has(index)) newHidden.delete(index);\n else newHidden.add(index);\n setHiddenIndices(newHidden);\n },\n },\n tooltip: {\n bodyFont: { family: \"'Vazir', sans-serif\", size: 14 },\n titleFont: { family: \"'Vazir', sans-serif\", size: 16 },\n },\n datalabels: { display: false },\n },\n };\n\n // --- تنظیمات نقاط ---\n ChartJS.defaults.elements.point.radius = 5;\n ChartJS.defaults.elements.point.hoverRadius = 9;\n ChartJS.defaults.elements.point.borderWidth = 0.2;\n ChartJS.defaults.elements.point.backgroundColor = \"red\";\n ChartJS.defaults.elements.point.borderColor = \"black\";\n\n return (\n <Box height={height ?? 600}>\n <Chart\n ref={chartRef}\n type=\"bar\"\n data={{\n labels,\n datasets: datasets.map((ds, i) => ({\n ...ds,\n hidden: hiddenIndices.has(i),\n })),\n }}\n options={options}\n />\n </Box>\n );\n}\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","import_react_chartjs_2","import_chart","import_react","import_material","ChartJS","ChartDataLabels","Image"]}
@@ -2,6 +2,7 @@
2
2
  import * as React from "react";
3
3
 
4
4
  // src/charts/bar/index.tsx
5
+ import { useRef, useState } from "react";
5
6
  import { Chart } from "react-chartjs-2";
6
7
  import {
7
8
  Chart as ChartJS,
@@ -17,7 +18,6 @@ import {
17
18
  LineController
18
19
  } from "chart.js";
19
20
  import { Box } from "@mui/material";
20
- import { useRef, useEffect, useState } from "react";
21
21
  ChartJS.register(
22
22
  CategoryScale,
23
23
  LinearScale,
@@ -30,175 +30,115 @@ ChartJS.register(
30
30
  BarController,
31
31
  LineController
32
32
  );
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
- }) {
33
+ function BarChart({ labels, datasets, height }) {
44
34
  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
- }
35
+ const [hiddenIndices, setHiddenIndices] = useState(/* @__PURE__ */ new Set());
36
+ const visibleDatasets = datasets.filter((_, i) => !hiddenIndices.has(i));
37
+ const allValues = [].concat(
38
+ ...visibleDatasets.map(
39
+ (ds) => ds.data.filter((v) => v !== null)
40
+ )
41
+ );
42
+ const minValue = allValues.length ? Math.min(...allValues) : 0;
43
+ const maxValue = allValues.length ? Math.max(...allValues) : 1;
44
+ const useLogScale = maxValue / (minValue || 1) > 50;
45
+ const scaleType = useLogScale ? "logarithmic" : "linear";
46
+ let yMin = minValue;
47
+ let yMax = maxValue;
48
+ let stepSize = 1;
49
+ if (scaleType === "linear") {
50
+ const range = yMax - yMin;
51
+ const targetLines = 8;
52
+ let rawStep = range / targetLines;
53
+ const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));
54
+ const normalized = rawStep / magnitude;
55
+ if (normalized <= 1) stepSize = 1 * magnitude;
56
+ else if (normalized <= 2) stepSize = 2 * magnitude;
57
+ else if (normalized <= 5) stepSize = 5 * magnitude;
58
+ else stepSize = 10 * magnitude;
59
+ yMin = Math.floor(yMin / stepSize) * stepSize;
60
+ yMax = Math.ceil(yMax / stepSize) * stepSize;
61
+ } else {
62
+ yMin = Math.max(minValue, 1);
63
+ yMax = maxValue;
64
+ stepSize = void 0;
93
65
  }
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]);
112
66
  const options = {
113
67
  responsive: true,
114
68
  maintainAspectRatio: false,
69
+ animation: { duration: 500 },
115
70
  scales: {
116
71
  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 },
72
+ type: scaleType,
73
+ min: yMin,
74
+ max: yMax,
123
75
  ticks: {
124
- font: {
125
- family: "Vazir, sans-serif",
126
- size: 14
76
+ ...stepSize !== void 0 ? { stepSize } : {},
77
+ callback: (value) => {
78
+ const num = Number(value);
79
+ if (scaleType === "logarithmic") return num.toLocaleString();
80
+ if (num >= 1e3) return num.toLocaleString();
81
+ if (stepSize && stepSize < 1) return num.toFixed(2);
82
+ return num;
127
83
  },
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
- }
140
- }
84
+ font: { family: "'Vazir', sans-serif", size: 14 }
141
85
  }
142
86
  },
143
87
  x: {
144
88
  ticks: {
145
89
  autoSkip: false,
146
- font: {
147
- family: "Vazir, sans-serif",
148
- size: 13
149
- }
90
+ font: { family: "'Vazir', sans-serif", size: 13 }
150
91
  }
151
92
  }
152
93
  },
153
94
  plugins: {
154
- datalabels: {
155
- display: false
156
- // ← غیرفعال
157
- },
158
- tooltip: {
159
- bodyFont: {
160
- family: "Vazir, sans-serif",
161
- size: 14
162
- },
163
- titleFont: {
164
- family: "Vazir, sans-serif",
165
- size: 16
166
- }
167
- },
168
95
  legend: {
169
96
  labels: {
170
- generateLabels: function(chart) {
171
- const labels2 = ChartJS.defaults.plugins.legend.labels.generateLabels(chart);
172
- return labels2.map((label) => ({
173
- ...label,
174
- text: " " + label.text + " ",
175
- boxWidth: 40,
176
- boxHeight: 20
177
- }));
178
- },
179
- padding: 15,
180
97
  usePointStyle: true,
181
- font: {
182
- size: 16,
183
- family: "Vazir, sans-serif"
184
- },
185
- boxWidth: 40,
186
- paddingBottom: 10
98
+ // دایره‌ای
99
+ font: { size: 16, family: "'Vazir', sans-serif" }
100
+ },
101
+ onClick: (e, legendItem, legend) => {
102
+ const index = legendItem.datasetIndex;
103
+ const newHidden = new Set(hiddenIndices);
104
+ if (hiddenIndices.has(index)) newHidden.delete(index);
105
+ else newHidden.add(index);
106
+ setHiddenIndices(newHidden);
187
107
  }
188
- }
108
+ },
109
+ tooltip: {
110
+ bodyFont: { family: "'Vazir', sans-serif", size: 14 },
111
+ titleFont: { family: "'Vazir', sans-serif", size: 16 }
112
+ },
113
+ datalabels: { display: false }
189
114
  }
190
115
  };
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 }));
116
+ ChartJS.defaults.elements.point.radius = 5;
117
+ ChartJS.defaults.elements.point.hoverRadius = 9;
118
+ ChartJS.defaults.elements.point.borderWidth = 0.2;
119
+ ChartJS.defaults.elements.point.backgroundColor = "red";
120
+ ChartJS.defaults.elements.point.borderColor = "black";
121
+ return /* @__PURE__ */ React.createElement(Box, { height: height ?? 600 }, /* @__PURE__ */ React.createElement(
122
+ Chart,
123
+ {
124
+ ref: chartRef,
125
+ type: "bar",
126
+ data: {
127
+ labels,
128
+ datasets: datasets.map((ds, i) => ({
129
+ ...ds,
130
+ hidden: hiddenIndices.has(i)
131
+ }))
132
+ },
133
+ options
134
+ }
135
+ ));
196
136
  }
197
137
 
198
138
  // src/charts/pie/index.tsx
199
139
  import { Pie } from "react-chartjs-2";
200
140
  import { Chart as ChartJS2, ArcElement, Tooltip as Tooltip2, Legend as Legend2 } from "chart.js";
201
- import { useMemo, useRef as useRef2, useEffect as useEffect2, useState as useState2 } from "react";
141
+ import { useMemo, useRef as useRef2, useEffect, useState as useState2 } from "react";
202
142
  import { Box as Box2, Typography } from "@mui/material";
203
143
  import Image from "next/image";
204
144
  import ChartDataLabels from "chartjs-plugin-datalabels";
@@ -248,7 +188,7 @@ function PieChart({
248
188
  });
249
189
  setDataLabels(newLabels);
250
190
  };
251
- useEffect2(() => {
191
+ useEffect(() => {
252
192
  if (!showDataLabels) {
253
193
  setDataLabels([]);
254
194
  return;
@@ -258,7 +198,7 @@ function PieChart({
258
198
  }, 500);
259
199
  return () => clearTimeout(timeout);
260
200
  }, [datasets, showDataLabels, showPercentage]);
261
- useEffect2(() => {
201
+ useEffect(() => {
262
202
  if (!chartRef.current || !showDataLabels) return;
263
203
  const chart = chartRef.current;
264
204
  const originalUpdate = chart.update.bind(chart);
@@ -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 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"]}
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\";\nimport { useRef, useState } from \"react\";\nimport { Chart } from \"react-chartjs-2\";\nimport {\n Chart as ChartJS,\n CategoryScale,\n LinearScale,\n LogarithmicScale,\n BarElement,\n LineElement,\n PointElement,\n Tooltip,\n Legend,\n BarController,\n LineController,\n Chart as ChartType,\n} from \"chart.js\";\nimport { Box } from \"@mui/material\";\n\nChartJS.register(\n CategoryScale,\n LinearScale,\n LogarithmicScale,\n BarElement,\n LineElement,\n PointElement,\n Tooltip,\n Legend,\n BarController,\n LineController\n);\n\ninterface Dataset {\n label: string;\n data: (number | null)[];\n backgroundColor: string;\n borderColor?: string;\n borderWidth?: number;\n type?: \"line\";\n order?: number;\n tension?: number;\n pointRadius?: number;\n fill?: boolean;\n}\n\ninterface Props {\n labels: string[];\n datasets: Dataset[];\n height?: number;\n}\n\nexport default function BarChart({ labels, datasets, height }: Props) {\n const chartRef = useRef<ChartType | null>(null);\n const [hiddenIndices, setHiddenIndices] = useState<Set<number>>(new Set());\n\n // --- داده‌های visible ---\n const visibleDatasets = datasets.filter((_, i) => !hiddenIndices.has(i));\n const allValues = ([] as number[]).concat(\n ...visibleDatasets.map((ds) =>\n ds.data.filter((v): v is number => v !== null)\n )\n );\n\n const minValue = allValues.length ? Math.min(...allValues) : 0;\n const maxValue = allValues.length ? Math.max(...allValues) : 1;\n\n // --- تصمیم هوشمند برای scale ---\n const useLogScale = maxValue / (minValue || 1) > 50; // اگر اختلاف >50 برابر باشد log scale\n const scaleType: \"linear\" | \"logarithmic\" = useLogScale\n ? \"logarithmic\"\n : \"linear\";\n\n // --- محاسبه محور Y ---\n let yMin = minValue;\n let yMax = maxValue;\n let stepSize: number | undefined = 1;\n\n if (scaleType === \"linear\") {\n const range = yMax - yMin;\n const targetLines = 8;\n let rawStep = range / targetLines;\n\n const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));\n const normalized = rawStep / magnitude;\n if (normalized <= 1) stepSize = 1 * magnitude;\n else if (normalized <= 2) stepSize = 2 * magnitude;\n else if (normalized <= 5) stepSize = 5 * magnitude;\n else stepSize = 10 * magnitude;\n\n yMin = Math.floor(yMin / stepSize) * stepSize;\n yMax = Math.ceil(yMax / stepSize) * stepSize;\n } else {\n yMin = Math.max(minValue, 1);\n yMax = maxValue;\n stepSize = undefined;\n }\n\n // --- تنظیمات Chart.js ---\n const options = {\n responsive: true,\n maintainAspectRatio: false,\n animation: { duration: 500 },\n scales: {\n y: {\n type: scaleType,\n min: yMin,\n max: yMax,\n ticks: {\n ...(stepSize !== undefined ? { stepSize } : {}),\n callback: (value: any) => {\n // محدود کردن تعداد اعشار به حداکثر 2\n const num = Number(value);\n if (scaleType === \"logarithmic\") return num.toLocaleString();\n // اگر عدد خیلی بزرگ است، بدون اعشار\n if (num >= 1000) return num.toLocaleString();\n // اعشار برای اعداد کوچک\n if (stepSize && stepSize < 1) return num.toFixed(2);\n return num;\n },\n font: { family: \"'Vazir', sans-serif\", size: 14 },\n },\n },\n x: {\n ticks: {\n autoSkip: false,\n font: { family: \"'Vazir', sans-serif\", size: 13 },\n },\n },\n },\n plugins: {\n legend: {\n labels: {\n usePointStyle: true, // دایره‌ای\n font: { size: 16, family: \"'Vazir', sans-serif\" },\n },\n onClick: (e: any, legendItem: any, legend: any) => {\n const index = legendItem.datasetIndex as number;\n const newHidden = new Set(hiddenIndices);\n if (hiddenIndices.has(index)) newHidden.delete(index);\n else newHidden.add(index);\n setHiddenIndices(newHidden);\n },\n },\n tooltip: {\n bodyFont: { family: \"'Vazir', sans-serif\", size: 14 },\n titleFont: { family: \"'Vazir', sans-serif\", size: 16 },\n },\n datalabels: { display: false },\n },\n };\n\n // --- تنظیمات نقاط ---\n ChartJS.defaults.elements.point.radius = 5;\n ChartJS.defaults.elements.point.hoverRadius = 9;\n ChartJS.defaults.elements.point.borderWidth = 0.2;\n ChartJS.defaults.elements.point.backgroundColor = \"red\";\n ChartJS.defaults.elements.point.borderColor = \"black\";\n\n return (\n <Box height={height ?? 600}>\n <Chart\n ref={chartRef}\n type=\"bar\"\n data={{\n labels,\n datasets: datasets.map((ds, i) => ({\n ...ds,\n hidden: hiddenIndices.has(i),\n })),\n }}\n options={options}\n />\n </Box>\n );\n}\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","Tooltip","Legend","useRef","useState","Box"]}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/dist/index.d.mts CHANGED
File without changes
package/dist/index.d.ts CHANGED
File without changes
package/dist/index.js CHANGED
@@ -898,7 +898,6 @@ var import_DialogContent3 = __toESM(require("@mui/material/DialogContent"));
898
898
  var import_DialogTitle3 = __toESM(require("@mui/material/DialogTitle"));
899
899
  var import_react6 = require("react");
900
900
  var import_md2 = require("react-icons/md");
901
- var import_Tooltip = __toESM(require("@mui/material/Tooltip"));
902
901
  var import_react_hook_form3 = require("react-hook-form");
903
902
  var import_common = require("@mamrp/icons/common");
904
903
  function CustomTimePicker({
@@ -1038,7 +1037,7 @@ var TimePickerComponent = ({
1038
1037
  },
1039
1038
  InputProps: {
1040
1039
  ...!disabled && {
1041
- endAdornment: /* @__PURE__ */ React.createElement(import_material8.InputAdornment, { position: "end" }, /* @__PURE__ */ React.createElement(import_Tooltip.default, { title: "\u0627\u0646\u062A\u062E\u0627\u0628 \u0632\u0645\u0627\u0646" }, /* @__PURE__ */ React.createElement(import_material8.IconButton, { onClick: () => setIsModalOpen(true) }, /* @__PURE__ */ React.createElement(import_common.Clock, { size: 22, color: theme3.palette.text.primary }))))
1040
+ endAdornment: /* @__PURE__ */ React.createElement(import_material8.InputAdornment, { position: "end" }, /* @__PURE__ */ React.createElement(import_material8.Tooltip, { title: "\u0627\u0646\u062A\u062E\u0627\u0628 \u0632\u0645\u0627\u0646" }, /* @__PURE__ */ React.createElement(import_material8.IconButton, { onClick: () => setIsModalOpen(true) }, /* @__PURE__ */ React.createElement(import_common.Clock, { size: 22, color: theme3.palette.text.primary }))))
1042
1041
  }
1043
1042
  },
1044
1043
  sx: { width: fullwidth ? "100%" : "8rem" },