@mamrp/components 1.7.52 → 1.7.55
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.
- package/dist/charts/index.js +236 -121
- package/dist/charts/index.js.map +1 -1
- package/dist/charts/index.mjs +237 -122
- package/dist/charts/index.mjs.map +1 -1
- package/dist/index.d.mts +26 -2
- package/dist/index.d.ts +26 -2
- package/dist/index.js +454 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +465 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/charts/index.mjs
CHANGED
|
@@ -41,23 +41,80 @@ function BarChart({ labels, datasets, height }) {
|
|
|
41
41
|
);
|
|
42
42
|
const minValue = allValues.length ? Math.min(...allValues) : 0;
|
|
43
43
|
const maxValue = allValues.length ? Math.max(...allValues) : 1;
|
|
44
|
+
const hasNegativeData = minValue < 0;
|
|
45
|
+
const hasPositiveData = maxValue > 0;
|
|
44
46
|
const useLogScale = maxValue / (minValue || 1) > 50;
|
|
45
47
|
const scaleType = useLogScale ? "logarithmic" : "linear";
|
|
46
48
|
let yMin = minValue;
|
|
47
49
|
let yMax = maxValue;
|
|
48
50
|
let stepSize = 1;
|
|
49
51
|
if (scaleType === "linear") {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
52
|
+
if (hasNegativeData && hasPositiveData) {
|
|
53
|
+
const negativeRange = Math.abs(minValue);
|
|
54
|
+
const positiveRange = Math.abs(maxValue);
|
|
55
|
+
const maxRange = Math.max(negativeRange, positiveRange);
|
|
56
|
+
const targetLines = 5;
|
|
57
|
+
let rawStep = maxRange / targetLines;
|
|
58
|
+
if (maxRange < 0.01) {
|
|
59
|
+
stepSize = 1e-3;
|
|
60
|
+
} else if (maxRange < 0.05) {
|
|
61
|
+
stepSize = 5e-3;
|
|
62
|
+
} else if (maxRange < 0.1) {
|
|
63
|
+
stepSize = 0.01;
|
|
64
|
+
} else if (maxRange < 0.5) {
|
|
65
|
+
stepSize = 0.05;
|
|
66
|
+
} else if (maxRange < 1) {
|
|
67
|
+
stepSize = 0.1;
|
|
68
|
+
} else if (maxRange < 2) {
|
|
69
|
+
stepSize = 0.2;
|
|
70
|
+
} else if (maxRange < 5) {
|
|
71
|
+
stepSize = 0.5;
|
|
72
|
+
} else if (maxRange < 10) {
|
|
73
|
+
stepSize = 1;
|
|
74
|
+
} else {
|
|
75
|
+
const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));
|
|
76
|
+
const normalized = rawStep / magnitude;
|
|
77
|
+
if (normalized <= 1) stepSize = 1 * magnitude;
|
|
78
|
+
else if (normalized <= 2) stepSize = 2 * magnitude;
|
|
79
|
+
else if (normalized <= 5) stepSize = 5 * magnitude;
|
|
80
|
+
else stepSize = 10 * magnitude;
|
|
81
|
+
}
|
|
82
|
+
yMin = Math.floor(minValue / stepSize) * stepSize - stepSize;
|
|
83
|
+
yMax = Math.ceil(maxValue / stepSize) * stepSize + stepSize;
|
|
84
|
+
} else {
|
|
85
|
+
const range = maxValue - minValue;
|
|
86
|
+
const targetLines = 10;
|
|
87
|
+
let rawStep = range / targetLines;
|
|
88
|
+
if (range < 0.01) {
|
|
89
|
+
stepSize = 1e-3;
|
|
90
|
+
} else if (range < 0.05) {
|
|
91
|
+
stepSize = 5e-3;
|
|
92
|
+
} else if (range < 0.1) {
|
|
93
|
+
stepSize = 0.01;
|
|
94
|
+
} else if (range < 0.5) {
|
|
95
|
+
stepSize = 0.05;
|
|
96
|
+
} else if (range < 1) {
|
|
97
|
+
stepSize = 0.1;
|
|
98
|
+
} else if (range < 2) {
|
|
99
|
+
stepSize = 0.2;
|
|
100
|
+
} else if (range < 5) {
|
|
101
|
+
stepSize = 0.5;
|
|
102
|
+
} else if (range < 10) {
|
|
103
|
+
stepSize = 1;
|
|
104
|
+
} else {
|
|
105
|
+
const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));
|
|
106
|
+
const normalized = rawStep / magnitude;
|
|
107
|
+
if (normalized <= 1) stepSize = 1 * magnitude;
|
|
108
|
+
else if (normalized <= 2) stepSize = 2 * magnitude;
|
|
109
|
+
else if (normalized <= 5) stepSize = 5 * magnitude;
|
|
110
|
+
else stepSize = 10 * magnitude;
|
|
111
|
+
}
|
|
112
|
+
yMin = Math.floor(minValue / stepSize) * stepSize - stepSize;
|
|
113
|
+
yMax = Math.ceil(maxValue / stepSize) * stepSize + stepSize;
|
|
114
|
+
if (!hasNegativeData && yMin < 0) {
|
|
115
|
+
yMin = 0;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
61
118
|
} else {
|
|
62
119
|
yMin = Math.max(minValue, 1);
|
|
63
120
|
yMax = maxValue;
|
|
@@ -72,22 +129,42 @@ function BarChart({ labels, datasets, height }) {
|
|
|
72
129
|
type: scaleType,
|
|
73
130
|
min: yMin,
|
|
74
131
|
max: yMax,
|
|
132
|
+
grid: {
|
|
133
|
+
color: (context) => {
|
|
134
|
+
if (hasNegativeData && context.tick && Math.abs(context.tick.value) < 1e-4) {
|
|
135
|
+
return "rgba(0, 0, 0, 0.5)";
|
|
136
|
+
}
|
|
137
|
+
return "rgba(0, 0, 0, 0.1)";
|
|
138
|
+
},
|
|
139
|
+
lineWidth: (context) => {
|
|
140
|
+
if (hasNegativeData && context.tick && Math.abs(context.tick.value) < 1e-4) {
|
|
141
|
+
return 2;
|
|
142
|
+
}
|
|
143
|
+
return 1;
|
|
144
|
+
}
|
|
145
|
+
},
|
|
75
146
|
ticks: {
|
|
76
|
-
...stepSize !== void 0 ? { stepSize } : {},
|
|
77
147
|
callback: (value) => {
|
|
78
148
|
const num = Number(value);
|
|
79
149
|
if (scaleType === "logarithmic") return num.toLocaleString();
|
|
80
|
-
if (num >= 1e3) return num.toLocaleString();
|
|
81
|
-
if (stepSize
|
|
150
|
+
if (Math.abs(num) >= 1e3) return num.toLocaleString();
|
|
151
|
+
if (stepSize !== void 0) {
|
|
152
|
+
if (stepSize < 0.01) return num.toFixed(3);
|
|
153
|
+
if (stepSize < 0.1) return num.toFixed(2);
|
|
154
|
+
if (stepSize < 1) return num.toFixed(1);
|
|
155
|
+
}
|
|
156
|
+
if (Math.abs(num) < 1 && num !== 0) {
|
|
157
|
+
return num.toFixed(2);
|
|
158
|
+
}
|
|
82
159
|
return num;
|
|
83
160
|
},
|
|
84
|
-
font: { family: "
|
|
161
|
+
font: { family: "vazirmatn", size: 14 }
|
|
85
162
|
}
|
|
86
163
|
},
|
|
87
164
|
x: {
|
|
88
165
|
ticks: {
|
|
89
166
|
autoSkip: false,
|
|
90
|
-
font: { family: "
|
|
167
|
+
font: { family: "vazirmatn", size: 13 }
|
|
91
168
|
}
|
|
92
169
|
}
|
|
93
170
|
},
|
|
@@ -95,8 +172,7 @@ function BarChart({ labels, datasets, height }) {
|
|
|
95
172
|
legend: {
|
|
96
173
|
labels: {
|
|
97
174
|
usePointStyle: true,
|
|
98
|
-
|
|
99
|
-
font: { size: 16, family: "'Vazir', sans-serif" }
|
|
175
|
+
font: { size: 16, family: "vazirmatn" }
|
|
100
176
|
},
|
|
101
177
|
onClick: (e, legendItem, legend) => {
|
|
102
178
|
const index = legendItem.datasetIndex;
|
|
@@ -107,8 +183,16 @@ function BarChart({ labels, datasets, height }) {
|
|
|
107
183
|
}
|
|
108
184
|
},
|
|
109
185
|
tooltip: {
|
|
110
|
-
bodyFont: { family: "
|
|
111
|
-
titleFont: { family: "
|
|
186
|
+
bodyFont: { family: "vazirmatn", size: 14 },
|
|
187
|
+
titleFont: { family: "vazirmatn", size: 16 },
|
|
188
|
+
callbacks: {
|
|
189
|
+
label: (context) => {
|
|
190
|
+
const label = context.dataset.label ?? "";
|
|
191
|
+
const value = context.parsed.y;
|
|
192
|
+
const formattedValue = typeof value === "number" ? value.toLocaleString("fa-IR") : value;
|
|
193
|
+
return `${label}: ${formattedValue}`;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
112
196
|
},
|
|
113
197
|
datalabels: { display: false }
|
|
114
198
|
}
|
|
@@ -137,13 +221,14 @@ function BarChart({ labels, datasets, height }) {
|
|
|
137
221
|
|
|
138
222
|
// src/charts/pie/index.tsx
|
|
139
223
|
import { Pie } from "react-chartjs-2";
|
|
140
|
-
import { Chart as ChartJS2, ArcElement, Tooltip as Tooltip2, Legend as Legend2 } from "chart.js";
|
|
224
|
+
import { Chart as ChartJS2, ArcElement, Tooltip as Tooltip2, Legend as Legend2, Chart as Chart2 } from "chart.js";
|
|
141
225
|
import { useMemo, useRef as useRef2, useEffect, useState as useState2 } from "react";
|
|
142
226
|
import { Box as Box2, Typography } from "@mui/material";
|
|
143
227
|
import Image from "next/image";
|
|
144
228
|
import ChartDataLabels from "chartjs-plugin-datalabels";
|
|
145
229
|
ChartJS2.register(ArcElement, Tooltip2, Legend2, ChartDataLabels);
|
|
146
|
-
ChartJS2.defaults.font.family = "
|
|
230
|
+
ChartJS2.defaults.font.family = "vazirmatn";
|
|
231
|
+
Chart2.defaults.font.family = "'vazirmatn'";
|
|
147
232
|
function PieChart({
|
|
148
233
|
labels,
|
|
149
234
|
datasets,
|
|
@@ -192,7 +277,12 @@ function PieChart({
|
|
|
192
277
|
} else {
|
|
193
278
|
text = String(value);
|
|
194
279
|
}
|
|
195
|
-
newLabels.push({
|
|
280
|
+
newLabels.push({
|
|
281
|
+
left: leftRelative,
|
|
282
|
+
top: topRelative,
|
|
283
|
+
text,
|
|
284
|
+
opacity: 1
|
|
285
|
+
});
|
|
196
286
|
});
|
|
197
287
|
setDataLabels(newLabels);
|
|
198
288
|
};
|
|
@@ -242,71 +332,86 @@ function PieChart({
|
|
|
242
332
|
chart.update = originalUpdate;
|
|
243
333
|
};
|
|
244
334
|
}, [showDataLabels, showPercentage]);
|
|
245
|
-
const options = useMemo(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
plugins: {
|
|
256
|
-
tooltip: {
|
|
257
|
-
bodyFont: {
|
|
258
|
-
family: "Vazir, sans-serif",
|
|
259
|
-
size: 14
|
|
260
|
-
},
|
|
261
|
-
titleFont: {
|
|
262
|
-
family: "Vazir, sans-serif",
|
|
263
|
-
size: 16
|
|
264
|
-
}
|
|
335
|
+
const options = useMemo(
|
|
336
|
+
() => ({
|
|
337
|
+
responsive: true,
|
|
338
|
+
maintainAspectRatio: false,
|
|
339
|
+
cutout: !disableLogo ? "59%" : "0%",
|
|
340
|
+
animation: {
|
|
341
|
+
animateRotate: true,
|
|
342
|
+
animateScale: true,
|
|
343
|
+
duration: 400
|
|
344
|
+
// onComplete تنظیم میشود در useEffect بالا تا فقط رفتار محاسبه لیبل را تحت تاثیر قرار دهیم
|
|
265
345
|
},
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
346
|
+
plugins: {
|
|
347
|
+
tooltip: {
|
|
348
|
+
bodyFont: {
|
|
349
|
+
family: "vazirmatn",
|
|
350
|
+
size: 14
|
|
351
|
+
},
|
|
352
|
+
titleFont: {
|
|
353
|
+
family: "vazirmatn",
|
|
354
|
+
size: 16
|
|
275
355
|
},
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
index,
|
|
288
|
-
datasetIndex: 0,
|
|
289
|
-
textDecoration: hidden ? "line-through" : void 0
|
|
290
|
-
};
|
|
291
|
-
});
|
|
356
|
+
callbacks: {
|
|
357
|
+
label: (context) => {
|
|
358
|
+
const label = context.dataset?.label ?? "";
|
|
359
|
+
const parsed = context.parsed;
|
|
360
|
+
const yAxisID = context.dataset?.yAxisID === "y1" ? " %" : "";
|
|
361
|
+
const y = typeof parsed === "number" ? parsed : typeof parsed === "object" && parsed !== null ? parsed.y : null;
|
|
362
|
+
if (typeof y === "number") {
|
|
363
|
+
return `${label}: ${yAxisID}${y.toLocaleString("fa-IR")}`;
|
|
364
|
+
}
|
|
365
|
+
return label;
|
|
366
|
+
}
|
|
292
367
|
}
|
|
293
368
|
},
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
369
|
+
legend: {
|
|
370
|
+
labels: {
|
|
371
|
+
padding: 15,
|
|
372
|
+
usePointStyle: true,
|
|
373
|
+
color: "#666",
|
|
374
|
+
// رنگ متن legend را نرمتر میکند
|
|
375
|
+
font: {
|
|
376
|
+
size: 16,
|
|
377
|
+
family: "vazirmatn"
|
|
378
|
+
},
|
|
379
|
+
boxWidth: 40,
|
|
380
|
+
paddingBottom: 10,
|
|
381
|
+
generateLabels: (chart) => {
|
|
382
|
+
const data = chart.data;
|
|
383
|
+
const meta = chart.getDatasetMeta(0);
|
|
384
|
+
return data.labels.map((label, index) => {
|
|
385
|
+
const hidden = meta.data[index] ? meta.data[index].hidden : false;
|
|
386
|
+
return {
|
|
387
|
+
text: label,
|
|
388
|
+
fillStyle: data.datasets[0].backgroundColor[index] || "#000",
|
|
389
|
+
hidden,
|
|
390
|
+
index,
|
|
391
|
+
datasetIndex: 0,
|
|
392
|
+
textDecoration: hidden ? "line-through" : void 0
|
|
393
|
+
};
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
onClick: (e, legendItem, legend) => {
|
|
398
|
+
const ci = legend.chart;
|
|
399
|
+
const meta = ci.getDatasetMeta(legendItem.datasetIndex || 0);
|
|
400
|
+
const index = legendItem.index;
|
|
401
|
+
if (meta.data[index]) {
|
|
402
|
+
meta.data[index].hidden = !meta.data[index].hidden;
|
|
403
|
+
}
|
|
404
|
+
ci.update();
|
|
300
405
|
}
|
|
301
|
-
|
|
406
|
+
},
|
|
407
|
+
datalabels: {
|
|
408
|
+
display: false
|
|
409
|
+
// غیرفعال - لیبلها با React رندر میشوند
|
|
302
410
|
}
|
|
303
|
-
},
|
|
304
|
-
datalabels: {
|
|
305
|
-
display: false
|
|
306
|
-
// غیرفعال - لیبلها با React رندر میشوند
|
|
307
411
|
}
|
|
308
|
-
}
|
|
309
|
-
|
|
412
|
+
}),
|
|
413
|
+
[disableLogo]
|
|
414
|
+
);
|
|
310
415
|
const CenterComponent = () => {
|
|
311
416
|
return /* @__PURE__ */ React.createElement(
|
|
312
417
|
"div",
|
|
@@ -330,50 +435,60 @@ function PieChart({
|
|
|
330
435
|
)
|
|
331
436
|
);
|
|
332
437
|
};
|
|
333
|
-
return /* @__PURE__ */ React.createElement(
|
|
334
|
-
|
|
438
|
+
return /* @__PURE__ */ React.createElement(
|
|
439
|
+
Box2,
|
|
335
440
|
{
|
|
336
|
-
ref:
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
datasets
|
|
340
|
-
},
|
|
341
|
-
options
|
|
342
|
-
}
|
|
343
|
-
), showDataLabels && dataLabels.map((label, index) => /* @__PURE__ */ React.createElement(
|
|
344
|
-
Typography,
|
|
345
|
-
{
|
|
346
|
-
key: index,
|
|
347
|
-
sx: {
|
|
348
|
-
position: "absolute",
|
|
349
|
-
left: label.left,
|
|
350
|
-
top: label.top,
|
|
351
|
-
transform: "translate(-50%, -50%)",
|
|
352
|
-
color: "#fff",
|
|
353
|
-
fontWeight: "bold",
|
|
354
|
-
fontSize: 14,
|
|
355
|
-
fontFamily: "Vazir, sans-serif",
|
|
356
|
-
pointerEvents: "none",
|
|
357
|
-
textShadow: "0 1px 2px rgba(0,0,0,0.5)",
|
|
358
|
-
opacity: label.opacity,
|
|
359
|
-
transition: "opacity 0.2s ease-in-out, left 0.2s ease-in-out, top 0.2s ease-in-out"
|
|
360
|
-
}
|
|
441
|
+
ref: containerRef,
|
|
442
|
+
height: height ?? 600,
|
|
443
|
+
sx: { position: "relative" }
|
|
361
444
|
},
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
pointerEvents: "none"
|
|
372
|
-
// جلوگیری از دریافت event روی این لایه
|
|
445
|
+
/* @__PURE__ */ React.createElement(
|
|
446
|
+
Pie,
|
|
447
|
+
{
|
|
448
|
+
ref: chartRef,
|
|
449
|
+
data: {
|
|
450
|
+
labels,
|
|
451
|
+
datasets
|
|
452
|
+
},
|
|
453
|
+
options
|
|
373
454
|
}
|
|
374
|
-
|
|
375
|
-
/* @__PURE__ */ React.createElement(
|
|
376
|
-
|
|
455
|
+
),
|
|
456
|
+
showDataLabels && dataLabels.map((label, index) => /* @__PURE__ */ React.createElement(
|
|
457
|
+
Typography,
|
|
458
|
+
{
|
|
459
|
+
key: index,
|
|
460
|
+
sx: {
|
|
461
|
+
position: "absolute",
|
|
462
|
+
left: label.left,
|
|
463
|
+
top: label.top,
|
|
464
|
+
transform: "translate(-50%, -50%)",
|
|
465
|
+
color: "#fff",
|
|
466
|
+
fontWeight: "bold",
|
|
467
|
+
fontSize: 14,
|
|
468
|
+
fontFamily: "vazirmatn, sans-serif",
|
|
469
|
+
pointerEvents: "none",
|
|
470
|
+
textShadow: "0 1px 2px rgba(0,0,0,0.5)",
|
|
471
|
+
opacity: label.opacity,
|
|
472
|
+
transition: "opacity 0.2s ease-in-out, left 0.2s ease-in-out, top 0.2s ease-in-out"
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
label.text
|
|
476
|
+
)),
|
|
477
|
+
!disableLogo && /* @__PURE__ */ React.createElement(
|
|
478
|
+
"div",
|
|
479
|
+
{
|
|
480
|
+
style: {
|
|
481
|
+
position: "absolute",
|
|
482
|
+
top: "53%",
|
|
483
|
+
left: "50%",
|
|
484
|
+
transform: "translate(-50%, -50%)",
|
|
485
|
+
pointerEvents: "none"
|
|
486
|
+
// جلوگیری از دریافت event روی این لایه
|
|
487
|
+
}
|
|
488
|
+
},
|
|
489
|
+
/* @__PURE__ */ React.createElement(CenterComponent, null)
|
|
490
|
+
)
|
|
491
|
+
);
|
|
377
492
|
}
|
|
378
493
|
export {
|
|
379
494
|
BarChart,
|
|
@@ -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\";\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/**\n * 📊 BarChart — کامپوننت نمودار میلهای (Bar / Combo Bar+Line)\n *\n * @component BarChart\n *\n * @param {string[]} labels\n * آرایهای از برچسبهای محور افقی (X). طول این آرایه مبنای تمام دادههاست.\n *\n * @param {Array<{\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 * }>} datasets\n *\n * آرایهای از سریهای داده برای نمایش در نمودار.\n * هر آبجکت یک سری داده است که میتواند میلهای (Bar) یا خطی (Line) باشد:\n *\n * - ● **label**: عنوان سری (نمایش در Legend)\n * - ● **data**: مقادیر هر نقطه – مقدار `null` باعث حذف نقطه از نمودار میشود.\n * - ● **backgroundColor**: رنگ میله یا رنگ پرشدگی خط\n * - ● **borderColor**: (اختیاری) رنگ خط دور میله یا خط\n * - ● **borderWidth**: (اختیاری) ضخامت خط دور میله یا خط\n * - ● **type**: اگر `\"line\"` باشد، سری به صورت نمودار خطی نمایش داده میشود (Combo chart)\n * - ● **order**: ترتیب رسم (سری با order بزرگتر روی سایر سریها قرار میگیرد)\n * - ● **tension**: (خطی) میزان خمیدگی منحنی (۰ = خط صاف)\n * - ● **pointRadius**: (خطی) شعاع نقاط\n * - ● **fill**: (خطی) پر شدن زیر نمودار خطی\n *\n *\n * @param {number} [height=600]\n * ارتفاع نمودار بر حسب پیکسل.\n *\n *\n * @description\n * این کامپوننت یک نمودار میلهای (BarChart) با پشتیبانی از **نمودار ترکیبی Bar + Line**\n * است و برای نمایش دادهها در محیط فارسی و راستچین بهینهسازی شده است.\n *\n * ✔ پشتیبانی از فونت وزیر \n * ✔ پشتیبانی از RTL \n * ✔ امکان ترکیب چند سری میلهای یا خطی \n * ✔ مقیاسدهی خودکار محور Y \n * ✔ تشخیص خودکار بین `linear` و `logarithmic` \n * (اگر اختلاف min/max بیش از ۵۰ برابر باشد، محور Y به حالت لگاریتمی تغییر میکند)\n *\n * 🔹 تعامل Legend:\n * کلیک روی هر سری در Legend آن را مخفی/ظاهر میکند و محور Y با توجه به مقدار سریهای\n * قابلمشاهده مجدداً محاسبه میشود.\n *\n *\n * @returns {JSX.Element}\n * یک نمودار میلهای یا ترکیبی با قابلیت شخصیسازی کامل.\n *\n *\n * @example\n * ```jsx\n * <BarChart\n * labels={[\"شنبه\", \"یکشنبه\", \"دوشنبه\"]}\n * datasets={[\n * {\n * label: \"فروش\",\n * data: [10, 20, 15],\n * backgroundColor: \"rgba(75,192,192,0.7)\",\n * },\n * {\n * label: \"میانگین\",\n * data: [12, 18, 14],\n * type: \"line\",\n * borderColor: \"red\",\n * backgroundColor: \"transparent\",\n * borderWidth: 3,\n * tension: 0.4,\n * pointRadius: 4,\n * fill: false,\n * order: 0\n * }\n * ]}\n * height={400}\n * />\n * ```\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<{ left: number; top: 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 // محاسبه مجموع دادههای قابل مشاهده\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: { left: number; top: number; text: string; opacity: number }[] = [];\n\n // ابعاد و scale برای تبدیل مختصات داخلی canvas به مختصات DOM\n const canvas = chart.canvas as HTMLCanvasElement;\n const canvasRect = canvas.getBoundingClientRect();\n const containerRect = containerRef.current.getBoundingClientRect();\n\n // chart.width/chart.height => internal canvas pixel size (device pixel scaled)\n // canvasRect.width/canvasRect.height => displayed CSS size\n const scaleX = chart.width / canvasRect.width;\n const scaleY = chart.height / canvasRect.height;\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 در واحد internal canvas pixels\n const centerAngle = (arc.startAngle + arc.endAngle) / 2;\n const midRadius = arc.innerRadius + (arc.outerRadius - arc.innerRadius) * 0.65;\n\n const xInternal = arc.x - Math.cos(centerAngle) * midRadius;\n const yInternal = arc.y + Math.sin(centerAngle) * midRadius;\n\n // تبدیل به مختصات DOM (نسبت به viewport)\n const xDom = canvasRect.left + (xInternal / scaleX);\n const yDom = canvasRect.top + (yInternal / scaleY);\n\n // تبدیل به مختصات نسبی به container (برای absolute positioning داخل container)\n const leftRelative = xDom - containerRect.left;\n const topRelative = yDom - containerRect.top;\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({ left: leftRelative, top: topRelative, text, opacity: 1 });\n });\n\n setDataLabels(newLabels);\n };\n\n // محاسبه موقعیت لیبلها بعد از اتمام انیمیشن\n useEffect(() => {\n if (!showDataLabels) {\n setDataLabels([]);\n return;\n }\n\n // صبر برای اتمام انیمیشن اولیه (فقط fallback) — animation.onComplete نیز تنظیم میشود.\n const timeout = setTimeout(() => {\n calculateLabels();\n }, 500);\n\n return () => clearTimeout(timeout);\n }, [datasets, showDataLabels, showPercentage]);\n\n // ثبت callback برای onComplete انیمیشن تا دقیقاً بعد از پایان انیمیشن محاسبه انجام شود\n useEffect(() => {\n const chart = chartRef.current;\n if (!chart) return;\n\n // نگهداری مقدار قبلی تا در cleanup به حالت قبل برگردد\n const prevOnComplete = (chart.options.animation as any)?.onComplete;\n\n (chart.options.animation as any) = {\n ...(chart.options.animation as any),\n onComplete: () => {\n // اگر callback قبلی هم بود، آن را اجرا کن\n try { prevOnComplete && prevOnComplete(); } catch (e) { /* ignore */ }\n calculateLabels();\n },\n };\n\n // اعمال تغییرات در chart (بدون trigger کردن انیمیشن)\n chart.update();\n\n return () => {\n // بازیابی onComplete قبلی (در صورت وجود)\n if (chart && chart.options && chart.options.animation) {\n (chart.options.animation as any).onComplete = prevOnComplete;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [showDataLabels, showPercentage, datasets]);\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 // onComplete تنظیم میشود در useEffect بالا تا فقط رفتار محاسبه لیبل را تحت تاثیر قرار دهیم\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.left,\n top: label.top,\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"]}
|
|
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/**\n * 📊 BarChart — کامپوننت نمودار میلهای (Bar / Combo Bar+Line)\n *\n * @component BarChart\n *\n * @param {string[]} labels\n * آرایهای از برچسبهای محور افقی (X). طول این آرایه مبنای تمام دادههاست.\n *\n * @param {Array<{\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 * }>} datasets\n *\n * آرایهای از سریهای داده برای نمایش در نمودار.\n * هر آبجکت یک سری داده است که میتواند میلهای (Bar) یا خطی (Line) باشد:\n *\n * - ● **label**: عنوان سری (نمایش در Legend)\n * - ● **data**: مقادیر هر نقطه – مقدار `null` باعث حذف نقطه از نمودار میشود.\n * - ● **backgroundColor**: رنگ میله یا رنگ پرشدگی خط\n * - ● **borderColor**: (اختیاری) رنگ خط دور میله یا خط\n * - ● **borderWidth**: (اختیاری) ضخامت خط دور میله یا خط\n * - ● **type**: اگر `\"line\"` باشد، سری به صورت نمودار خطی نمایش داده میشود (Combo chart)\n * - ● **order**: ترتیب رسم (سری با order بزرگتر روی سایر سریها قرار میگیرد)\n * - ● **tension**: (خطی) میزان خمیدگی منحنی (۰ = خط صاف)\n * - ● **pointRadius**: (خطی) شعاع نقاط\n * - ● **fill**: (خطی) پر شدن زیر نمودار خطی\n *\n *\n * @param {number} [height=600]\n * ارتفاع نمودار بر حسب پیکسل.\n *\n *\n * @description\n * این کامپوننت یک نمودار میلهای (BarChart) با پشتیبانی از **نمودار ترکیبی Bar + Line**\n * است و برای نمایش دادهها در محیط فارسی و راستچین بهینهسازی شده است.\n *\n * ✔ پشتیبانی از فونت وزیر \n * ✔ پشتیبانی از RTL \n * ✔ امکان ترکیب چند سری میلهای یا خطی \n * ✔ مقیاسدهی خودکار محور Y \n * ✔ تشخیص خودکار بین `linear` و `logarithmic` \n * (اگر اختلاف min/max بیش از ۵۰ برابر باشد، محور Y به حالت لگاریتمی تغییر میکند)\n *\n * 🔹 تعامل Legend:\n * کلیک روی هر سری در Legend آن را مخفی/ظاهر میکند و محور Y با توجه به مقدار سریهای\n * قابلمشاهده مجدداً محاسبه میشود.\n *\n *\n * @returns {JSX.Element}\n * یک نمودار میلهای یا ترکیبی با قابلیت شخصیسازی کامل.\n *\n *\n * @example\n * ```jsx\n * <BarChart\n * labels={[\"شنبه\", \"یکشنبه\", \"دوشنبه\"]}\n * datasets={[\n * {\n * label: \"فروش\",\n * data: [10, 20, 15],\n * backgroundColor: \"rgba(75,192,192,0.7)\",\n * },\n * {\n * label: \"میانگین\",\n * data: [12, 18, 14],\n * type: \"line\",\n * borderColor: \"red\",\n * backgroundColor: \"transparent\",\n * borderWidth: 3,\n * tension: 0.4,\n * pointRadius: 4,\n * fill: false,\n * order: 0\n * }\n * ]}\n * height={400}\n * />\n * ```\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 const hasNegativeData = minValue < 0;\n const hasPositiveData = maxValue > 0;\n\n // --- تصمیم هوشمند برای scale ---\n const useLogScale = maxValue / (minValue || 1) > 50;\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 // const hasNegativeData = minValue < 0;\n // const hasPositiveData = maxValue > 0;\n\n if (scaleType === \"linear\") {\n // اگر هم منفی و هم مثبت داریم، باید دو طرف صفر رو جداگانه محاسبه کنیم\n if (hasNegativeData && hasPositiveData) {\n // محاسبه range برای طرف منفی و مثبت\n const negativeRange = Math.abs(minValue);\n const positiveRange = Math.abs(maxValue);\n const maxRange = Math.max(negativeRange, positiveRange);\n\n // تعداد خطوط هدف برای هر طرف\n const targetLines = 5;\n let rawStep = maxRange / targetLines;\n\n // محاسبه stepSize بر اساس بزرگترین range\n if (maxRange < 0.01) {\n stepSize = 0.001;\n } else if (maxRange < 0.05) {\n stepSize = 0.005;\n } else if (maxRange < 0.1) {\n stepSize = 0.01;\n } else if (maxRange < 0.5) {\n stepSize = 0.05;\n } else if (maxRange < 1) {\n stepSize = 0.1;\n } else if (maxRange < 2) {\n stepSize = 0.2;\n } else if (maxRange < 5) {\n stepSize = 0.5;\n } else if (maxRange < 10) {\n stepSize = 1;\n } else {\n const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));\n const normalized = rawStep / magnitude;\n\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\n // محاسبه yMin و yMax متقارن نسبت به صفر با padding\n yMin = Math.floor(minValue / stepSize) * stepSize - stepSize;\n yMax = Math.ceil(maxValue / stepSize) * stepSize + stepSize;\n } else {\n // فقط مثبت یا فقط منفی\n const range = maxValue - minValue;\n const targetLines = 10;\n let rawStep = range / targetLines;\n\n if (range < 0.01) {\n stepSize = 0.001;\n } else if (range < 0.05) {\n stepSize = 0.005;\n } else if (range < 0.1) {\n stepSize = 0.01;\n } else if (range < 0.5) {\n stepSize = 0.05;\n } else if (range < 1) {\n stepSize = 0.1;\n } else if (range < 2) {\n stepSize = 0.2;\n } else if (range < 5) {\n stepSize = 0.5;\n } else if (range < 10) {\n stepSize = 1;\n } else {\n const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));\n const normalized = rawStep / magnitude;\n\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\n // محاسبه yMin و yMax با padding\n yMin = Math.floor(minValue / stepSize) * stepSize - stepSize;\n yMax = Math.ceil(maxValue / stepSize) * stepSize + stepSize;\n\n // اگر فقط مثبت داریم و yMin منفی شده، از صفر شروع کنیم\n if (!hasNegativeData && yMin < 0) {\n yMin = 0;\n }\n }\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 grid: {\n color: (context: any) => {\n // خط صفر را فقط وقتی پررنگ میکنیم که داده منفی داشته باشیم\n if (\n hasNegativeData &&\n context.tick &&\n Math.abs(context.tick.value) < 0.0001\n ) {\n return \"rgba(0, 0, 0, 0.5)\";\n }\n return \"rgba(0, 0, 0, 0.1)\";\n },\n lineWidth: (context: any) => {\n if (\n hasNegativeData &&\n context.tick &&\n Math.abs(context.tick.value) < 0.0001\n ) {\n return 2;\n }\n return 1;\n },\n },\n ticks: {\n callback: (value: any) => {\n const num = Number(value);\n if (scaleType === \"logarithmic\") return num.toLocaleString();\n\n if (Math.abs(num) >= 1000) return num.toLocaleString();\n\n if (stepSize !== undefined) {\n if (stepSize < 0.01) return num.toFixed(3);\n if (stepSize < 0.1) return num.toFixed(2);\n if (stepSize < 1) return num.toFixed(1);\n }\n\n if (Math.abs(num) < 1 && num !== 0) {\n return num.toFixed(2);\n }\n\n return num;\n },\n font: { family: \"vazirmatn\", size: 14 },\n },\n },\n x: {\n ticks: {\n autoSkip: false,\n font: { family: \"vazirmatn\", size: 13 },\n },\n },\n },\n plugins: {\n legend: {\n labels: {\n usePointStyle: true,\n font: { size: 16, family: \"vazirmatn\" },\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: \"vazirmatn\", size: 14 },\n titleFont: { family: \"vazirmatn\", size: 16 },\n callbacks: {\n label: (context:any) => {\n const label = context.dataset.label ?? \"\";\n const value = context.parsed.y;\n\n // تبدیل عدد به رشته با locale فارسی (اختیاری)\n const formattedValue =\n typeof value === \"number\" ? value.toLocaleString(\"fa-IR\") : value;\n\n return `${label}: ${formattedValue}`;\n },\n },\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 به vazirmatn\nChartJS.defaults.font.family = \"vazirmatn\";\nChart.defaults.font.family = \"'vazirmatn'\"; //\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<\n { left: number; top: number; text: string; opacity: number }[]\n >([]);\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 // محاسبه مجموع دادههای قابل مشاهده\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: {\n left: number;\n top: number;\n text: string;\n opacity: number;\n }[] = [];\n\n // ابعاد و scale برای تبدیل مختصات داخلی canvas به مختصات DOM\n const canvas = chart.canvas as HTMLCanvasElement;\n const canvasRect = canvas.getBoundingClientRect();\n const containerRect = containerRef.current.getBoundingClientRect();\n\n // chart.width/chart.height => internal canvas pixel size (device pixel scaled)\n // canvasRect.width/canvasRect.height => displayed CSS size\n const scaleX = chart.width / canvasRect.width;\n const scaleY = chart.height / canvasRect.height;\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 در واحد internal canvas pixels\n const centerAngle = (arc.startAngle + arc.endAngle) / 2;\n const midRadius =\n arc.innerRadius + (arc.outerRadius - arc.innerRadius) * 0.65;\n\n const xInternal = arc.x - Math.cos(centerAngle) * midRadius;\n const yInternal = arc.y + Math.sin(centerAngle) * midRadius;\n\n // تبدیل به مختصات DOM (نسبت به viewport)\n const xDom = canvasRect.left + xInternal / scaleX;\n const yDom = canvasRect.top + yInternal / scaleY;\n\n // تبدیل به مختصات نسبی به container (برای absolute positioning داخل container)\n const leftRelative = xDom - containerRect.left;\n const topRelative = yDom - containerRect.top;\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({\n left: leftRelative,\n top: topRelative,\n text,\n opacity: 1,\n });\n });\n\n setDataLabels(newLabels);\n };\n\n // محاسبه موقعیت لیبلها بعد از اتمام انیمیشن\n useEffect(() => {\n if (!showDataLabels) {\n setDataLabels([]);\n return;\n }\n\n // صبر برای اتمام انیمیشن اولیه (فقط fallback) — animation.onComplete نیز تنظیم میشود.\n const timeout = setTimeout(() => {\n calculateLabels();\n }, 500);\n\n return () => clearTimeout(timeout);\n }, [datasets, showDataLabels, showPercentage]);\n\n // ثبت callback برای onComplete انیمیشن تا دقیقاً بعد از پایان انیمیشن محاسبه انجام شود\n useEffect(() => {\n const chart = chartRef.current;\n if (!chart) return;\n\n // نگهداری مقدار قبلی تا در cleanup به حالت قبل برگردد\n const prevOnComplete = (chart.options.animation as any)?.onComplete;\n\n (chart.options.animation as any) = {\n ...(chart.options.animation as any),\n onComplete: () => {\n // اگر callback قبلی هم بود، آن را اجرا کن\n try {\n prevOnComplete && prevOnComplete();\n } catch (e) {\n /* ignore */\n }\n calculateLabels();\n },\n };\n\n // اعمال تغییرات در chart (بدون trigger کردن انیمیشن)\n chart.update();\n\n return () => {\n // بازیابی onComplete قبلی (در صورت وجود)\n if (chart && chart.options && chart.options.animation) {\n (chart.options.animation as any).onComplete = prevOnComplete;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [showDataLabels, showPercentage, datasets]);\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 () => ({\n responsive: true,\n maintainAspectRatio: false,\n cutout: !disableLogo ? \"59%\" : \"0%\",\n animation: {\n animateRotate: true,\n animateScale: true,\n duration: 400,\n // onComplete تنظیم میشود در useEffect بالا تا فقط رفتار محاسبه لیبل را تحت تاثیر قرار دهیم\n },\n plugins: {\n tooltip: {\n bodyFont: {\n family: \"vazirmatn\",\n size: 14,\n },\n titleFont: {\n family: \"vazirmatn\",\n size: 16,\n },\n callbacks: {\n label: (context: any) => {\n const label = context.dataset?.label ?? \"\";\n const parsed = context.parsed;\n const yAxisID = context.dataset?.yAxisID === \"y1\" ? \" %\" : \"\";\n const y =\n typeof parsed === \"number\"\n ? parsed\n : typeof parsed === \"object\" && parsed !== null\n ? parsed.y\n : null;\n\n if (typeof y === \"number\") {\n return `${label}: ${yAxisID}${y.toLocaleString(\"fa-IR\")}`;\n }\n\n return label;\n },\n },\n },\n legend: {\n labels: {\n padding: 15,\n usePointStyle: true,\n color: \"#666\", // رنگ متن legend را نرمتر میکند\n font: {\n size: 16,\n family: \"vazirmatn\",\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]\n ? meta.data[index].hidden\n : 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 }),\n [disableLogo]\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\n ref={containerRef}\n height={height ?? 600}\n sx={{ position: \"relative\" }}\n >\n <Pie\n ref={chartRef}\n data={{\n labels: labels,\n datasets: datasets,\n }}\n options={options}\n />\n {/* لیبلهای سفارشی با فونت vazirmatn */}\n {showDataLabels &&\n dataLabels.map((label, index) => (\n <Typography\n key={index}\n sx={{\n position: \"absolute\",\n left: label.left,\n top: label.top,\n transform: \"translate(-50%, -50%)\",\n color: \"#fff\",\n fontWeight: \"bold\",\n fontSize: 14,\n fontFamily: \"vazirmatn, sans-serif\",\n pointerEvents: \"none\",\n textShadow: \"0 1px 2px rgba(0,0,0,0.5)\",\n opacity: label.opacity,\n transition:\n \"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","Chart","useRef","useState","Box"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ import { MRT_ColumnDef, MRT_PaginationState, MRT_ColumnFiltersState, MRT_Sorting
|
|
|
2
2
|
export { MRT_ColumnDef } from 'material-react-table';
|
|
3
3
|
import * as React$1 from 'react';
|
|
4
4
|
import React__default, { ReactNode, CSSProperties, Dispatch, SetStateAction } from 'react';
|
|
5
|
-
import { Control, FieldValues, Path, FieldErrors, UseFormSetValue } from 'react-hook-form';
|
|
5
|
+
import { Control, FieldValues, Path, FieldErrors, UseFormSetValue, FieldPath } from 'react-hook-form';
|
|
6
6
|
import { DialogProps, PaperProps, SxProps, Theme } from '@mui/material';
|
|
7
7
|
import { IconType } from 'react-icons';
|
|
8
8
|
import { Moment } from 'moment-jalaali';
|
|
@@ -732,4 +732,28 @@ type UploadImageProps<T extends FieldValues> = {
|
|
|
732
732
|
};
|
|
733
733
|
declare const UploadImage: <T extends FieldValues>({ placeholder, name, selectedImage, setSelectedImage, control, errors, setValue, height, allowGallery, imageFit, disableCamera, }: UploadImageProps<T>) => React__default.JSX.Element;
|
|
734
734
|
|
|
735
|
-
|
|
735
|
+
interface SubCustomerFormFields {
|
|
736
|
+
fullName: string;
|
|
737
|
+
phoneNumber: string;
|
|
738
|
+
address: string;
|
|
739
|
+
cityId: number;
|
|
740
|
+
customerType: number;
|
|
741
|
+
remittanceDiscrepancyTolerancePercent: number | null;
|
|
742
|
+
lat: number | null;
|
|
743
|
+
long: number | null;
|
|
744
|
+
}
|
|
745
|
+
interface MapPickerProps {
|
|
746
|
+
control: Control<SubCustomerFormFields>;
|
|
747
|
+
nameLat: FieldPath<SubCustomerFormFields>;
|
|
748
|
+
nameLong: FieldPath<SubCustomerFormFields>;
|
|
749
|
+
nameAddress?: FieldPath<SubCustomerFormFields>;
|
|
750
|
+
isLoading?: boolean;
|
|
751
|
+
defaultLat?: number;
|
|
752
|
+
defaultLng?: number;
|
|
753
|
+
defaultZoom?: number;
|
|
754
|
+
minZoom?: number;
|
|
755
|
+
maxZoom?: number;
|
|
756
|
+
}
|
|
757
|
+
declare function MapLocationPicker({ control, nameLat, nameLong, nameAddress, isLoading, defaultLat, defaultLng, defaultZoom, minZoom, maxZoom, }: MapPickerProps): React$1.JSX.Element;
|
|
758
|
+
|
|
759
|
+
export { Page as Accordion, AdvancedSearchButton, ConfirmationDialog$1 as ConfirmationDialog, ConnectToBasculeButton, CustomCheckbox, CustomDateTimePicker, CustomDialog, type CustomDialogProps, CustomTimePicker, DataTable, DateFilter, DateFilterRange, DateMonthPicker, JalaliDatePicker$2 as DatePicker, JalaliDatePicker$1 as DateTimePicker, JalaliDateTimeRangePicker as DateTimeRangePicker, DraggablePaper, UploadImage$1 as EnhancedUploadImage, FormInputNumber, FormInputText, HorizontalStepper, imgViewer as ImgViewer, LicensePlate, MapLocationPicker, JalaliDatePicker as MobileDateTimePicker, ConfirmationDialog as Modal, NestedSelect as NestedSelectort, NoResult, PaginationList, type PaletteColor, PatternTextField, RadioButton, SearchLicensePlate, MultipleSelectChip as Selector, SkeletonCard, SonarSpinner, SwitchButton, Table, UploadImage };
|