httpd: add country pie chart to dashboard
This commit is contained in:
61
httpd.py
61
httpd.py
@@ -598,9 +598,30 @@ function update(d) {
|
|||||||
$('failLegend').innerHTML = fhtml;
|
$('failLegend').innerHTML = fhtml;
|
||||||
|
|
||||||
// Leaderboards (session data)
|
// Leaderboards (session data)
|
||||||
renderLeaderboard('topCountries', d.top_countries_session, 'code', 'count');
|
|
||||||
renderLeaderboard('topAsns', d.top_asns_session, 'asn', 'count');
|
renderLeaderboard('topAsns', d.top_asns_session, 'asn', 'count');
|
||||||
|
|
||||||
|
// Country pie chart (database data)
|
||||||
|
var countryColors = ['#58a6ff','#3fb950','#d29922','#f85149','#a371f7','#39c5cf','#db61a2','#db6d28','#7ee787','#7d8590'];
|
||||||
|
if (d.db && d.db.top_countries && d.db.top_countries.length > 0) {
|
||||||
|
var countries = d.db.top_countries.slice(0, 8);
|
||||||
|
var countryTotal = countries.reduce(function(s, c) { return s + (c.count || c[1] || 0); }, 0);
|
||||||
|
var segs = [], chtml = '';
|
||||||
|
countries.forEach(function(c, i) {
|
||||||
|
var code = c.code || c[0], cnt = c.count || c[1] || 0;
|
||||||
|
var col = countryColors[i % countryColors.length];
|
||||||
|
var pctVal = countryTotal > 0 ? ((cnt / countryTotal) * 100).toFixed(1) : '0';
|
||||||
|
segs.push({c: col, d: (cnt / countryTotal) * 360});
|
||||||
|
chtml += '<div class="legend-item"><div class="legend-dot" style="background:' + col + '"></div>';
|
||||||
|
chtml += '<span class="legend-name">' + code + '</span><span class="legend-val">' + fmt(cnt) + '</span>';
|
||||||
|
chtml += '<span class="sub" style="margin-left:4px">' + pctVal + '%</span></div>';
|
||||||
|
});
|
||||||
|
$('countryPie').style.background = conicGrad(segs);
|
||||||
|
$('countryLegend').innerHTML = chtml;
|
||||||
|
} else {
|
||||||
|
$('countryPie').style.background = 'var(--border)';
|
||||||
|
$('countryLegend').innerHTML = '<div style="color:var(--dim);font-size:11px">No data</div>';
|
||||||
|
}
|
||||||
|
|
||||||
// Tor pool
|
// Tor pool
|
||||||
var thtml = '';
|
var thtml = '';
|
||||||
if (d.tor_pool && d.tor_pool.hosts) {
|
if (d.tor_pool && d.tor_pool.hosts) {
|
||||||
@@ -639,15 +660,6 @@ function update(d) {
|
|||||||
return '<div class="stat-row"><span class="stat-lbl">' + p.toUpperCase() + '</span><span class="stat-val">' + fmt(c) + '</span></div>';
|
return '<div class="stat-row"><span class="stat-lbl">' + p.toUpperCase() + '</span><span class="stat-val">' + fmt(c) + '</span></div>';
|
||||||
}).join('');
|
}).join('');
|
||||||
|
|
||||||
var chtml = '';
|
|
||||||
if (dbs.top_countries) {
|
|
||||||
dbs.top_countries.slice(0, 5).forEach(function(c, i) {
|
|
||||||
var name = c.code || c[0], cnt = c.count || c[1];
|
|
||||||
chtml += '<div class="lb-item"><div class="lb-rank' + (i === 0 ? ' top' : '') + '">' + (i + 1) + '</div>';
|
|
||||||
chtml += '<span class="lb-name">' + name + '</span><span class="lb-val blu">' + fmt(cnt) + '</span></div>';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
$('dbCountries').innerHTML = chtml || '<div style="color:var(--dim)">No data</div>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scraper/Engine stats
|
// Scraper/Engine stats
|
||||||
@@ -705,6 +717,11 @@ function update(d) {
|
|||||||
$('dbTestedHour').textContent = fmt(dbh.tested_last_hour);
|
$('dbTestedHour').textContent = fmt(dbh.tested_last_hour);
|
||||||
$('dbAddedDay').textContent = fmt(dbh.added_last_day);
|
$('dbAddedDay').textContent = fmt(dbh.added_last_day);
|
||||||
$('dbDead').textContent = fmt(dbh.dead_count);
|
$('dbDead').textContent = fmt(dbh.dead_count);
|
||||||
|
$('dbFailing').textContent = fmt(dbh.failing_count);
|
||||||
|
$('dbFreelist').textContent = fmt(dbh.freelist_count);
|
||||||
|
$('dbAvgLat').textContent = fmtMs(dbh.db_avg_latency);
|
||||||
|
$('dbMinLat').textContent = fmtMs(dbh.db_min_latency);
|
||||||
|
$('dbMaxLat').textContent = fmtMs(dbh.db_max_latency);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tor pool enhanced stats
|
// Tor pool enhanced stats
|
||||||
@@ -933,14 +950,17 @@ DASHBOARD_HTML = '''<!DOCTYPE html>
|
|||||||
|
|
||||||
<!-- Geographic Distribution -->
|
<!-- Geographic Distribution -->
|
||||||
<div class="sec">
|
<div class="sec">
|
||||||
<div class="sec-hdr">Geographic Distribution (Session)</div>
|
<div class="sec-hdr">Geographic Distribution <a href="/map" style="font-size:10px;font-weight:normal;margin-left:8px">View Map →</a></div>
|
||||||
<div class="g g2">
|
<div class="g g2">
|
||||||
<div class="c">
|
<div class="c">
|
||||||
<div class="lbl">Top Countries</div>
|
<div class="lbl">Proxies by Country (Database)</div>
|
||||||
<div class="lb" id="topCountries"></div>
|
<div class="pie-wrap">
|
||||||
|
<div class="pie" id="countryPie"></div>
|
||||||
|
<div class="legend" id="countryLegend"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="c">
|
<div class="c">
|
||||||
<div class="lbl">Top ASNs</div>
|
<div class="lbl">Top ASNs (Session)</div>
|
||||||
<div class="lb" id="topAsns"></div>
|
<div class="lb" id="topAsns"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1023,14 +1043,21 @@ DASHBOARD_HTML = '''<!DOCTYPE html>
|
|||||||
<div class="val-sm red" id="dbDead">-</div>
|
<div class="val-sm red" id="dbDead">-</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="g g2">
|
<div class="g g3">
|
||||||
<div class="c">
|
<div class="c">
|
||||||
<div class="lbl">Working by Protocol</div>
|
<div class="lbl">Working by Protocol</div>
|
||||||
<div id="dbByProto"></div>
|
<div id="dbByProto"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="c">
|
<div class="c">
|
||||||
<div class="lbl">Top Countries (All Time)</div>
|
<div class="lbl">Latency Stats</div>
|
||||||
<div class="lb" id="dbCountries"></div>
|
<div class="stat-row"><span class="stat-lbl">Average</span><span class="stat-val cyn" id="dbAvgLat">-</span></div>
|
||||||
|
<div class="stat-row"><span class="stat-lbl">Min</span><span class="stat-val grn" id="dbMinLat">-</span></div>
|
||||||
|
<div class="stat-row"><span class="stat-lbl">Max</span><span class="stat-val red" id="dbMaxLat">-</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="c">
|
||||||
|
<div class="lbl">Activity</div>
|
||||||
|
<div class="stat-row"><span class="stat-lbl">Failing</span><span class="stat-val yel" id="dbFailing">-</span></div>
|
||||||
|
<div class="stat-row"><span class="stat-lbl">Freelist</span><span class="stat-val" id="dbFreelist">-</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user