Vote Distribution
×
", 1], ["", 0], ["", 0]];
// Boş veri kontrolü
if (chartData && chartData.length > 0) {
// Desktop chart
if (document.getElementById('chart')) {
c3.generate({
bindto: '#chart',
size: { width: 240, height: 240 },
data: {
columns: chartData,
type: 'pie'
},
pie: {
label: {
format: function(value, ratio, id) {
if (ratio < 0.05) return '';
return id && id.length > 10 ? id.substring(0, 8) + '..' : id;
},
threshold: 0.05
}
},
legend: { show: false },
tooltip: {
format: {
value: function(value, ratio, id) {
return value + ' (' + (ratio * 100).toFixed(1) + '%)';
}
}
}
});
// Custom legend for desktop
createCustomLegend(chartData, '#chart-legend');
}
// Mobile chart
if (document.getElementById('chart-mobile')) {
c3.generate({
bindto: '#chart-mobile',
size: { width: 280, height: 280 },
data: {
columns: chartData,
type: 'pie'
},
pie: {
label: {
format: function(value, ratio, id) {
if (ratio < 0.05) return '';
return id && id.length > 10 ? id.substring(0, 8) + '..' : id;
},
threshold: 0.05
}
},
legend: { show: false },
tooltip: {
format: {
value: function(value, ratio, id) {
return value + ' (' + (ratio * 100).toFixed(1) + '%)';
}
}
}
});
// Custom legend for mobile
createCustomLegend(chartData, '#chart-mobile-legend');
}
}
} catch(e) { console.log('Chart error:', e); }
// Custom scrollable legend
function createCustomLegend(data, targetSelector) {
var container = document.querySelector(targetSelector);
if (!container) return;
var colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf'];
var total = data.reduce(function(sum, item) { return sum + item[1]; }, 0);
var html = '';
data.forEach(function(item, i) {
var name = item[0];
var value = item[1];
var percent = total > 0 ? ((value / total) * 100).toFixed(1) : 0;
var color = colors[i % colors.length];
var shortName = name.length > 25 ? name.substring(0, 22) + '...' : name;
html += '' +
'' +
'' + shortName + '' +
'' + percent + '%' +
'
';
});
container.innerHTML = html;
}
// Live updates polling
document.addEventListener('DOMContentLoaded', function() {
const totalVoteEl = document.querySelector("#totalvote");
const pollSlug = 'scriptalert1script';
const apiUrl = '/poll/api/live/' + pollSlug + '/';
let pollTimeout = null;
let currentEtag = null;
let consecutiveNoChange = 0;
let errorCount = 0;
const POLL_INTERVALS = { fast: 3000, normal: 5000, slow: 10000, verySlow: 30000 };
function getPollingInterval() {
if (errorCount > 0) return Math.min(60000, 5000 * Math.pow(2, errorCount - 1));
if (consecutiveNoChange > 20) return POLL_INTERVALS.verySlow;
if (consecutiveNoChange > 10) return POLL_INTERVALS.slow;
if (consecutiveNoChange > 3) return POLL_INTERVALS.normal;
return POLL_INTERVALS.fast;
}
function scheduleNextPoll() {
if (pollTimeout) clearTimeout(pollTimeout);
if (!document.hidden) pollTimeout = setTimeout(fetchPollData, getPollingInterval());
}
function fetchPollData() {
const headers = { 'X-Requested-With': 'XMLHttpRequest' };
if (currentEtag) headers['If-None-Match'] = currentEtag;
fetch(apiUrl, { method: 'GET', credentials: 'same-origin', headers: headers })
.then(response => {
const newEtag = response.headers.get('ETag');
if (newEtag) currentEtag = newEtag;
if (response.status === 304) { consecutiveNoChange++; errorCount = 0; scheduleNextPoll(); return null; }
if (!response.ok) throw new Error('API error');
return response.json();
})
.then(data => {
if (!data) return;
errorCount = 0;
if (!data.success || data.hidden) { scheduleNextPoll(); return; }
consecutiveNoChange = 0;
if (totalVoteEl) totalVoteEl.innerHTML = data.total_votes.toLocaleString();
data.choices.forEach((choice, i) => {
const choiceEl = document.querySelector('#choice_' + (i + 1));
const rateEl = document.querySelector('#rates_' + (i + 1));
if (choiceEl) choiceEl.innerHTML = choice.votes.toLocaleString();
if (rateEl) rateEl.style.width = choice.percentage + '%';
});
scheduleNextPoll();
})
.catch(error => { errorCount++; scheduleNextPoll(); });
}
document.addEventListener('visibilitychange', function() {
if (document.hidden) { if (pollTimeout) clearTimeout(pollTimeout); }
else { consecutiveNoChange = 0; fetchPollData(); }
});
fetchPollData();
});
Commentaires
Pas encore de commentaires. Sois le premier !