Spaces:
Sleeping
Sleeping
/** | |
* ملف رسم وتهيئة المخططات البيانية | |
*/ | |
// دالة التهيئة عند تحميل الصفحة | |
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 => { |