Нет данных
';
+ return;
+ }
+ const max = Math.max(...data.map(d => d[1]));
+ container.innerHTML = data.map(d => {
+ const height = (d[1] / max) * 180;
+ const date = d[0].slice(5) + '.' + d[0].slice(0, 4);
+ return '';
+ }).join("");
+}
+
+function renderChannelChart(data) {
+ const container = document.getElementById("channel-chart");
+ if (data.length === 0) {
+ container.innerHTML = 'Нет данных
';
+ return;
+ }
+ const max = Math.max(...data.map(d => d[1]));
+ container.innerHTML = data.map(d => {
+ const height = (d[1] / max) * 180;
+ return '';
+ }).join("");
+}
+
+function renderOperatorChart(data) {
+ const container = document.getElementById("operator-chart");
+ if (data.length === 0) {
+ container.innerHTML = 'Нет данных
';
+ return;
+ }
+ const max = Math.max(...data.map(d => d[1]));
+ container.innerHTML = data.map(d => {
+ const height = (d[1] / max) * 180;
+ return '';
+ }).join("");
+}
+
+function renderStatusPie(statuses) {
+ const total = statuses['в работе'] + statuses['выполнен'] + statuses['ОТКАЗ'];
+ if (total === 0) return;
+
+ const activeDeg = (statuses['в работе'] / total) * 360;
+ const completedDeg = (statuses['выполнен'] / total) * 360;
+ const rejectedDeg = (statuses['ОТКАЗ'] / total) * 360;
+
+ const pie = document.getElementById("status-pie");
+ pie.style.background = 'conic-gradient(#F59E0B 0deg ' + activeDeg + 'deg, #10B981 ' + activeDeg + 'deg ' + (activeDeg + completedDeg) + 'deg, #EF4444 ' + (activeDeg + completedDeg) + 'deg 360deg)';
+
+ const legend = document.getElementById("status-legend");
+ legend.innerHTML = [
+ {label: 'В работе', count: statuses['в работе'], color: '#F59E0B'},
+ {label: 'Выполнен', count: statuses['выполнен'], color: '#10B981'},
+ {label: 'ОТКАЗ', count: statuses['ОТКАЗ'], color: '#EF4444'}
+ ].map(item => '' + item.label + ': ' + item.count + '
').join("");
+}
+
async function load() {
const res = await fetch("/api/data");
const data = await res.json();
allOrders = data.orders || [];
renderTable(allOrders);
updateStats(allOrders);
+ updateCharts(allOrders);
}
function updateStats(orders) {
- document.getElementById("stat-total").textContent = orders.length;
- document.getElementById("stat-active").textContent = orders.filter(o => o.status === "в работе").length;
- document.getElementById("stat-completed").textContent = orders.filter(o => o.status === "выполнен").length;
- document.getElementById("stat-rejected").textContent = orders.filter(o => o.status === "ОТКАЗ").length;
+ const total = orders.length;
+ const active = orders.filter(o => o.status === "в работе").length;
+ const completed = orders.filter(o => o.status === "выполнен").length;
+ const rejected = orders.filter(o => o.status === "ОТКАЗ").length;
+ const conversion = total > 0 ? Math.round((completed / total) * 100) : 0;
+
+ document.getElementById("stat-total").textContent = total;
+ document.getElementById("stat-active").textContent = active;
+ document.getElementById("stat-completed").textContent = completed;
+ document.getElementById("stat-rejected").textContent = rejected;
+ document.getElementById("stat-conversion").textContent = conversion + '%';
+}
+
+function updateCharts(orders) {
+ renderDailyChart(groupByDate(orders));
+ renderChannelChart(groupByChannel(orders));
+ renderOperatorChart(groupByOperator(orders));
+ renderStatusPie(groupByStatus(orders));
}
function renderTable(orders) {