v3 / static /js /charts.js
EGYADMIN's picture
Upload 115 files
82676b8 verified
/**
* ملف رسم وتهيئة المخططات البيانية
*/
// دالة التهيئة عند تحميل الصفحة
document.addEventListener('DOMContentLoaded', function() {
// تهيئة المخططات
initializeCharts();
});
/**
* تهيئة جميع المخططات في الصفحة
*/
function initializeCharts() {
// التحقق من توفر مكتبة Chart.js
if (typeof Chart === 'undefined') {
console.warn('مكتبة Chart.js غير متوفرة. لا يمكن تهيئة المخططات.');
return;
}
// تعيين الخيارات العامة للمخططات
Chart.defaults.font.family = "'Tajawal', sans-serif";
Chart.defaults.font.size = 14;
Chart.defaults.color = '#333';
Chart.defaults.plugins.tooltip.rtl = true;
Chart.defaults.plugins.tooltip.titleAlign = 'right';
Chart.defaults.plugins.tooltip.bodyAlign = 'right';
Chart.defaults.plugins.legend.rtl = true;
Chart.defaults.plugins.legend.labels.textAlign = 'right';
// إنشاء مخططات مختلفة بناءً على نوع المخطط
initializeBarCharts();
initializeLineCharts();
initializePieCharts();
initializeRadarCharts();
initializeGaugeCharts();
initializeDashboardCharts();
}
/**
* تهيئة المخططات الشريطية
*/
function initializeBarCharts() {
const barChartElements = document.querySelectorAll('.bar-chart');
barChartElements.forEach(element => {
const ctx = element.getContext('2d');
const dataUrl = element.getAttribute('data-url');
// استدعاء البيانات من الخادم إذا كان متوفرًا
if (dataUrl) {
fetch(dataUrl)
.then(response => response.json())
.then(data => {
createBarChart(ctx, element, data);
})
.catch(error => {
console.error('خطأ في تحميل بيانات المخطط:', error);
// استخدام بيانات افتراضية في حال حدوث خطأ
createBarChart(ctx, element, getDefaultBarChartData());
});
} else {
// استخدام البيانات المضمنة من سمة data-config
let chartData;
try {
chartData = JSON.parse(element.getAttribute('data-config') || '{}');
} catch (e) {
console.error('تنسيق بيانات المخطط غير صالح:', e);
chartData = getDefaultBarChartData();
}
createBarChart(ctx, element, chartData);
}
});
}
/**
* إنشاء مخطط شريطي
*/
function createBarChart(ctx, element, data) {
const isVertical = element.getAttribute('data-orientation') !== 'horizontal';
const isStacked = element.getAttribute('data-stacked') === 'true';
// تكوين الخيارات
const options = {
indexAxis: isVertical ? 'x' : 'y',
scales: {
x: {
beginAtZero: true,
grid: {
display: false
}
},
y: {
beginAtZero: true,
grid: {
display: true,
color: '#f0f0f0'
}
}
},
plugins: {
title: {
display: data.title ? true : false,
text: data.title || '',
align: 'right',
font: {
size: 16,
weight: 'bold'
}
},
legend: {
display: (data.datasets && data.datasets.length > 1) ? true : false,
position: 'top',
align: 'end'
}
},
responsive: true,
maintainAspectRatio: false
};
// إضافة خيارات للمخطط المكدس إذا لزم الأمر
if (isStacked) {
options.scales.x.stacked = true;
options.scales.y.stacked = true;
}
// إنشاء المخطط
new Chart(ctx, {
type: 'bar',
data: {
labels: data.labels || [],
datasets: data.datasets || []
},
options: options
});
}
/**
* تهيئة المخططات الخطية
*/
function initializeLineCharts() {
const lineChartElements = document.querySelectorAll('.line-chart');
lineChartElements.forEach(element => {
const ctx = element.getContext('2d');
const dataUrl = element.getAttribute('data-url');
// استدعاء البيانات من الخادم إذا كان متوفرًا
if (dataUrl) {
fetch(dataUrl)
.then(response => response.json())
.then(data => {
createLineChart(ctx, element, data);
})
.catch(error => {
console.error('خطأ في تحميل بيانات المخطط:', error);
createLineChart(ctx, element, getDefaultLineChartData());
});
} else {
// استخدام البيانات المضمنة
let chartData;
try {
chartData = JSON.parse(element.getAttribute('data-config') || '{}');
} catch (e) {
console.error('تنسيق بيانات المخطط غير صالح:', e);
chartData = getDefaultLineChartData();
}
createLineChart(ctx, element, chartData);
}
});
}
/**
* إنشاء مخطط خطي
*/
function createLineChart(ctx, element, data) {
const isCurved = element.getAttribute('data-curved') === 'true';
const showPoints = element.getAttribute('data-points') !== 'false';
// تكوين الخيارات
const options = {
scales: {
x: {
grid: {
display: false
}
},
y: {
beginAtZero: element.getAttribute('data-start-at-zero') === 'true',
grid: {
color: '#f0f0f0'
}
}
},
elements: {
line: {
tension: isCurved ? 0.4 : 0,
borderWidth: 2
},
point: {
radius: showPoints ? 4 : 0,
hoverRadius: showPoints ? 6 : 0
}
},
plugins: {
title: {
display: data.title ? true : false,
text: data.title || '',
align: 'right',
font: {
size: 16,
weight: 'bold'
}
},
legend: {
position: 'top',
align: 'end'
}
},
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false
}
};
// إنشاء المخطط
new Chart(ctx, {
type: 'line',
data: {
labels: data.labels || [],
datasets: data.datasets || []
},
options: options
});
}
/**
* تهيئة المخططات الدائرية
*/
function initializePieCharts() {
const pieChartElements = document.querySelectorAll('.pie-chart, .doughnut-chart');
pieChartElements.forEach(element => {
const ctx = element.getContext('2d');
const dataUrl = element.getAttribute('data-url');
const isDoughnut = element.classList.contains('doughnut-chart');
// استدعاء البيانات من الخادم إذا كان متوفرًا
if (dataUrl) {
fetch(dataUrl)
.then(response => response.json())
.then(data => {
createPieChart(ctx, element, data, isDoughnut);
})
.catch(error => {
console.error('خطأ في تحميل بيانات المخطط:', error);
createPieChart(ctx, element, getDefaultPieChartData(), isDoughnut);
});
} else {
// استخدام البيانات المضمنة
let chartData;
try {
chartData = JSON.parse(element.getAttribute('data-config') || '{}');
} catch (e) {
console.error('تنسيق بيانات المخطط غير صالح:', e);
chartData = getDefaultPieChartData();
}
createPieChart(ctx, element, chartData, isDoughnut);
}
});
}
/**
* إنشاء مخطط دائري
*/
function createPieChart(ctx, element, data, isDoughnut) {
// تكوين الخيارات
const options = {
plugins: {
title: {
display: data.title ? true : false,
text: data.title || '',
align: 'right',
font: {
size: 16,
weight: 'bold'
}
},
legend: {
position: 'bottom',
align: 'start',
rtl: true,
labels: {
boxWidth: 12,
padding: 15
}
}
},
responsive: true,
maintainAspectRatio: false
};
// إضافة خيارات لمخطط الدونات إذا لزم الأمر
if (isDoughnut) {
options.cutout = '60%';
options.plugins.tooltip = {
callbacks: {
title: function(tooltipItems) {
return tooltipItems[0].label;
},
label: function(context) {
const value = context.raw;
const total = context.chart.getDatasetMeta(0).total;
const percentage = Math.round((value / total) * 100);
return percentage + '% (' + value + ')';
}
}
};
}
// إنشاء المخطط
new Chart(ctx, {
type: isDoughnut ? 'doughnut' : 'pie',
data: {
labels: data.labels || [],
datasets: [{
data: data.values || [],
backgroundColor: data.colors || getDefaultColors(),
borderWidth: 1,
borderColor: '#fff'
}]
},
options: options
});
}
/**
* تهيئة مخططات الرادار
*/
function initializeRadarCharts() {
const radarChartElements = document.querySelectorAll('.radar-chart');
radarChartElements.forEach(element => {