mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-14 01:04:14 +00:00
663 lines
25 KiB
HTML
663 lines
25 KiB
HTML
<!DOCTYPE html>
|
|
<!--
|
|
Copyright (C) 2014 Jakob Borg and other contributors. All rights reserved.
|
|
Use of this source code is governed by an MIT-style license that can be
|
|
found in the LICENSE file.
|
|
-->
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="description" content="">
|
|
<meta name="author" content="">
|
|
<link rel="shortcut icon" href="static/assets/img/favicon.png">
|
|
|
|
<title>Syncthing Usage Reports</title>
|
|
<link href="static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
|
<script type="text/javascript" src="static/bootstrap/js/bootstrap.min.js"></script>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.css">
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/heatmapjs@2.0.2/heatmap.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/leaflet-heatmap@1.0.0/leaflet-heatmap.js"></script>
|
|
|
|
<style type="text/css">
|
|
body {
|
|
margin: 40px;
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
}
|
|
tr.main td {
|
|
font-weight: bold;
|
|
}
|
|
tr.child td.first {
|
|
padding-left: 2em;
|
|
}
|
|
.progress-bar {
|
|
overflow:hidden;
|
|
white-space:nowrap;
|
|
text-overflow: ellipsis;
|
|
}
|
|
</style>
|
|
<script type="text/javascript"
|
|
src="https://www.google.com/jsapi?autoload={
|
|
'modules':[{
|
|
'name':'visualization',
|
|
'version':'1',
|
|
'packages':['corechart']
|
|
}]
|
|
}"></script>
|
|
|
|
<script type="text/javascript">
|
|
google.setOnLoadCallback(drawVersionChart);
|
|
google.setOnLoadCallback(drawMovementChart);
|
|
google.setOnLoadCallback(drawBlockStatsChart);
|
|
google.setOnLoadCallback(drawPerformanceCharts);
|
|
|
|
function drawVersionChart() {
|
|
// Summary version chart for versions that at some point in the chart
|
|
// reaches 250 devices. This filters out versions that are old and
|
|
// uninteresting yet linger forever with like four users.
|
|
var jsonData = $.ajax({url: "summary.json?min=250", dataType:"json", async: false}).responseText;
|
|
var rows = JSON.parse(jsonData);
|
|
|
|
var data = new google.visualization.DataTable();
|
|
data.addColumn('date', 'Day');
|
|
for (var i = 1; i < rows[0].length; i++){
|
|
data.addColumn('number', rows[0][i]);
|
|
}
|
|
for (var i = 1; i < rows.length; i++){
|
|
rows[i][0] = new Date(rows[i][0]);
|
|
data.addRow(rows[i]);
|
|
};
|
|
|
|
var options = {
|
|
legend: { position: 'bottom', alignment: 'center' },
|
|
isStacked: true,
|
|
colors: ['rgb(102,194,165)','rgb(252,141,98)','rgb(141,160,203)','rgb(231,138,195)','rgb(166,216,84)','rgb(255,217,47)'],
|
|
chartArea: {left: 80, top: 20, width: '1020', height: '300'},
|
|
};
|
|
|
|
var chart = new google.visualization.AreaChart(document.getElementById('versionChart'));
|
|
chart.draw(data, options);
|
|
}
|
|
|
|
function drawMovementChart() {
|
|
var jsonData = $.ajax({url: "movement.json", dataType:"json", async: false}).responseText;
|
|
var rows = JSON.parse(jsonData);
|
|
|
|
var data = new google.visualization.DataTable();
|
|
data.addColumn('date', 'Day');
|
|
for (var i = 1; i < rows[0].length; i++){
|
|
data.addColumn('number', rows[0][i]);
|
|
}
|
|
|
|
for (var i = 1; i < rows.length; i++){
|
|
rows[i][0] = new Date(rows[i][0]);
|
|
if (rows[i][1] > 500) {
|
|
rows[i][1] = null;
|
|
}
|
|
if (rows[i][2] < -500) {
|
|
rows[i][2] = null;
|
|
}
|
|
data.addRow(rows[i]);
|
|
};
|
|
|
|
var options = {
|
|
legend: { position: 'bottom', alignment: 'center' },
|
|
colors: ['rgb(102,194,165)','rgb(252,141,98)','rgb(141,160,203)','rgb(231,138,195)','rgb(166,216,84)','rgb(255,217,47)'],
|
|
chartArea: {left: 80, top: 20, width: '1020', height: '300'},
|
|
};
|
|
|
|
var chart = new google.visualization.AreaChart(document.getElementById('movementChart'));
|
|
chart.draw(data, options);
|
|
}
|
|
|
|
function formatGibibytes(gibibytes, decimals) {
|
|
if(gibibytes == 0) return '0 GiB';
|
|
var k = 1024,
|
|
dm = decimals || 2,
|
|
sizes = ['GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'],
|
|
i = Math.floor(Math.log(gibibytes) / Math.log(k));
|
|
if (i < 0) {
|
|
sizes = 'MiB';
|
|
} else {
|
|
sizes = sizes[i];
|
|
}
|
|
return parseFloat((gibibytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes;
|
|
}
|
|
|
|
|
|
function drawBlockStatsChart() {
|
|
var jsonData = $.ajax({url: "blockstats.json", dataType:"json", async: false}).responseText;
|
|
var rows = JSON.parse(jsonData);
|
|
|
|
var data = new google.visualization.DataTable();
|
|
data.addColumn('date', 'Day');
|
|
for (var i = 1; i < rows[0].length; i++){
|
|
data.addColumn('number', rows[0][i]);
|
|
}
|
|
|
|
var totals = [0, 0, 0, 0, 0, 0];
|
|
for (var i = 1; i < rows.length; i++){
|
|
rows[i][0] = new Date(rows[i][0]);
|
|
for (var j = 2; j < rows[i].length; j++) {
|
|
totals[j-2] += rows[i][j];
|
|
}
|
|
data.addRow(rows[i]);
|
|
};
|
|
|
|
var totalTotals = totals.reduce(function(a, b) { return a + b; }, 0);
|
|
|
|
if (totalTotals > 0) {
|
|
var content = "<table class='table'>\n"
|
|
for (var j = 2; j < rows[0].length; j++) {
|
|
content += "<tr><td><b>" + rows[0][j].replace(' (GiB)', '') + "</b></td><td>" + formatGibibytes(totals[j-2].toFixed(2)) + " (" + ((100*totals[j-2])/totalTotals).toFixed(2) +"%)</td></tr>\n";
|
|
}
|
|
content += "</table>";
|
|
document.getElementById("data-to-date").innerHTML = content;
|
|
} else {
|
|
// No data, hide it.
|
|
document.getElementById("block-stats").outerHTML = "";
|
|
return;
|
|
}
|
|
|
|
var options = {
|
|
focusTarget: 'category',
|
|
vAxes: {0: {}, 1: {}},
|
|
series: {0: {type: 'line', targetAxisIndex:1}},
|
|
isStacked: true,
|
|
legend: {position: 'none'},
|
|
colors: ['rgb(102,194,165)','rgb(252,141,98)','rgb(141,160,203)','rgb(231,138,195)','rgb(166,216,84)','rgb(255,217,47)'],
|
|
chartArea: {left: 80, top: 20, width: '1020', height: '300'},
|
|
};
|
|
|
|
var chart = new google.visualization.AreaChart(document.getElementById('blockStatsChart'));
|
|
chart.draw(data, options);
|
|
}
|
|
|
|
function drawPerformanceCharts() {
|
|
var jsonData = $.ajax({url: "/performance.json", dataType:"json", async: false}).responseText;
|
|
var rows = JSON.parse(jsonData);
|
|
for (var i = 1; i < rows.length; i++){
|
|
rows[i][0] = new Date(rows[i][0]);
|
|
}
|
|
|
|
drawChart(rows, 1, 'Total Number of Files', 'totFilesChart', 1e6, 1);
|
|
drawChart(rows, 2, 'Total Folder Size (GiB)', 'totMiBChart', 1e6, 1024);
|
|
drawChart(rows, 3, 'Hash Performance (MiB/s)', 'hashPerfChart', 1000, 1);
|
|
drawChart(rows, 4, 'System RAM Size (GiB)', 'memSizeChart', 1e6, 1024);
|
|
drawChart(rows, 5, 'Memory Usage (MiB)', 'memUsageChart', 250, 1);
|
|
}
|
|
|
|
function drawChart(rows, index, title, id, cutoff, divisor) {
|
|
var data = new google.visualization.DataTable();
|
|
data.addColumn('date', 'Day');
|
|
data.addColumn('number', title);
|
|
|
|
var row;
|
|
for (var i = 1; i < rows.length; i++){
|
|
row = [rows[i][0], rows[i][index] / divisor];
|
|
if (row[1] > cutoff) {
|
|
row[1] = null;
|
|
}
|
|
data.addRow(row);
|
|
}
|
|
|
|
var options = {
|
|
legend: { position: 'bottom', alignment: 'center' },
|
|
colors: ['rgb(102,194,165)','rgb(252,141,98)','rgb(141,160,203)','rgb(231,138,195)','rgb(166,216,84)','rgb(255,217,47)'],
|
|
chartArea: {left: 80, top: 20, width: '1020', height: '300'},
|
|
vAxes: {0: {minValue: 0}},
|
|
};
|
|
|
|
var chart = new google.visualization.LineChart(document.getElementById(id));
|
|
chart.draw(data, options);
|
|
}
|
|
|
|
var locations = [];
|
|
{{range $location, $weight := .locations}}
|
|
locations.push({lat:{{- $location.Latitude -}},lng:{{- $location.Longitude -}},count:Math.min(100, {{- $weight -}})});
|
|
{{- end}}
|
|
|
|
function drawHeatMap() {
|
|
if (locations.length == 0) {
|
|
return;
|
|
}
|
|
var testData = {
|
|
data: locations
|
|
};
|
|
|
|
var baseLayer = L.tileLayer(
|
|
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
|
|
attribution: '...',
|
|
maxZoom: 18
|
|
}
|
|
);
|
|
var cfg = {
|
|
"radius": 1,
|
|
"minOpacity": .25,
|
|
"maxOpacity": .8,
|
|
"scaleRadius": true,
|
|
"useLocalExtrema": true,
|
|
latField: 'lat',
|
|
lngField: 'lng',
|
|
valueField: 'count',
|
|
gradient: {
|
|
'.1': 'cyan',
|
|
'.8': 'blue',
|
|
'.95': 'red'
|
|
}
|
|
};
|
|
var heatmapLayer = new HeatmapOverlay(cfg);
|
|
|
|
var map = new L.Map('map', {
|
|
center: new L.LatLng(25, 0),
|
|
zoom: 1,
|
|
layers: [baseLayer, heatmapLayer]
|
|
});
|
|
heatmapLayer.setData(testData);
|
|
}
|
|
</script>
|
|
</head>
|
|
|
|
<body>
|
|
<div class="container">
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<h1>Syncthing Usage Data</h1>
|
|
|
|
<h4 id="active-users">Active Users per Day and Version</h4>
|
|
<p>
|
|
This is the total number of unique users with reporting enabled, per day. Area color represents the major version.
|
|
</p>
|
|
<div class="img-thumbnail" id="versionChart" style="width: 1130px; height: 400px; padding: 10px;"></div>
|
|
|
|
<h4 id="joining-leaving">Users Joining and Leaving per Day</h4>
|
|
<p>
|
|
This is the total number of unique users joining and leaving per day. A user is counted as "joined" on first the day their unique ID is seen, and as "left" on the last day the unique ID was seen before a two weeks or longer absence. "Bounced" refers to users who joined and left on the same day.
|
|
</p>
|
|
<div class="img-thumbnail" id="movementChart" style="width: 1130px; height: 400px; padding: 10px;"></div>
|
|
<p class="text-muted">
|
|
Reappearance of users cause the "left" data to shrink retroactively.
|
|
</p>
|
|
<div id="block-stats">
|
|
<h4>Data Transfers per Day</h4>
|
|
<p>
|
|
This is total data transferred per day. Also shows how much data was saved (not transferred) by each of the methods syncthing uses.
|
|
</p>
|
|
<div class="img-thumbnail" id="blockStatsChart" style="width: 1130px; height: 400px; padding: 10px;"></div>
|
|
<h4 id="totals-to-date">Totals to date</h4>
|
|
<p id="data-to-date">
|
|
No data
|
|
</p>
|
|
</div>
|
|
|
|
<h4 id="metrics">Usage Metrics</h4>
|
|
<p>
|
|
This is the aggregated usage report data for the last 24 hours. Data based on <b>{{.nodes}}</b> devices that have reported in.
|
|
</p>
|
|
|
|
{{if .locations}}
|
|
<div class="img-thumbnail" id="map" style="width: 1130px; height: 400px; padding: 10px;"></div>
|
|
<p class="text-muted">
|
|
Heatmap max intensity is capped at 100 reports within a location.
|
|
</p>
|
|
<div class="panel panel-default">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">
|
|
<a data-toggle="collapse" href="#collapseTwo">Break down per country</a>
|
|
</h4>
|
|
</div>
|
|
<div id="collapseTwo" class="panel-collapse collapse">
|
|
<div class="panel-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<table class="table table-striped">
|
|
<tbody>
|
|
{{range .contries | slice 2 1}}
|
|
<tr>
|
|
<td style="width: 45%">{{.Key}}</td>
|
|
<td style="width: 5%" class="text-right">{{if ge .Pct 10.0}}{{.Pct | printf "%.0f"}}{{else if ge .Pct 1.0}}{{.Pct | printf "%.01f"}}{{else}}{{.Pct | printf "%.02f"}}{{end}}%</td>
|
|
<td style="width: 5%" class="text-right">{{.Count}}</td>
|
|
<td>
|
|
<div class="progress-bar" role="progressbar" aria-valuenow="{{.Pct | printf "%.02f"}}" aria-valuemin="0" aria-valuemax="100" style="width: {{.Pct | printf "%.02f"}}%; height:20px"></div>
|
|
</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<table class="table table-striped">
|
|
<tbody>
|
|
{{range .contries | slice 2 2}}
|
|
<tr>
|
|
<td style="width: 45%">{{.Key}}</td>
|
|
<td style="width: 5%" class="text-right">{{if ge .Pct 10.0}}{{.Pct | printf "%.0f"}}{{else if ge .Pct 1.0}}{{.Pct | printf "%.01f"}}{{else}}{{.Pct | printf "%.02f"}}{{end}}%</td>
|
|
<td style="width: 5%" class="text-right">{{.Count}}</td>
|
|
<td>
|
|
<div class="progress-bar" role="progressbar" aria-valuenow="{{.Pct | printf "%.02f"}}" aria-valuemin="0" aria-valuemax="100" style="width: {{.Pct | printf "%.02f"}}%; height:20px"></div>
|
|
</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th></th>
|
|
<th colspan="4" class="text-center">
|
|
<a href="https://en.wikipedia.org/wiki/Percentile">Percentile</a>
|
|
</th>
|
|
</tr>
|
|
<tr>
|
|
<th></th>
|
|
<th class="text-right">5%</th>
|
|
<th class="text-right">50%</th>
|
|
<th class="text-right">95%</th>
|
|
<th class="text-right">100%</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .categories}}
|
|
<tr>
|
|
<td>{{.Descr}}</td>
|
|
<td class="text-right">{{index .Values 0 | number .Type | commatize " "}}{{.Unit}}</td>
|
|
<td class="text-right">{{index .Values 1 | number .Type | commatize " "}}{{.Unit}}</td>
|
|
<td class="text-right">{{index .Values 2 | number .Type | commatize " "}}{{.Unit}}</td>
|
|
<td class="text-right">{{index .Values 3 | number .Type | commatize " "}}{{.Unit}}</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>Version</th><th class="text-right">Devices</th><th class="text-right">Share</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .versions}}
|
|
{{if gt .Percentage 0.1}}
|
|
<tr class="main">
|
|
<td>{{.Key}}</td>
|
|
<td class="text-right">{{.Count}}</td>
|
|
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
|
|
</tr>
|
|
{{range .Items}}
|
|
{{if gt .Percentage 0.1}}
|
|
<tr class="child">
|
|
<td class="first">{{.Key}}</td>
|
|
<td class="text-right">{{.Count}}</td>
|
|
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
|
|
</tr>
|
|
{{end}}
|
|
{{end}}
|
|
{{end}}
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>Penetration Level</th>
|
|
<th>Version</th>
|
|
<th class="text-right">Actual</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .versionPenetrations}}
|
|
<tr>
|
|
<td>{{.Count}}%</td>
|
|
<td>≥ {{.Key}}</td>
|
|
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>Platform</th>
|
|
<th class="text-right">Devices</th>
|
|
<th class="text-right">Share</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .platforms}}
|
|
<tr class="main">
|
|
<td>{{.Key}}</td>
|
|
<td class="text-right">{{.Count}}</td>
|
|
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
|
|
</tr>
|
|
{{range .Items}}
|
|
<tr class="child">
|
|
<td class="first">{{.Key}}</td>
|
|
<td class="text-right">{{.Count}}</td>
|
|
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
|
|
</tr>
|
|
{{end}}
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
</div>
|
|
<div class="row">
|
|
|
|
<div class="col-md-6">
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>Compiler</th>
|
|
<th class="text-right">Devices</th>
|
|
<th class="text-right">Share</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .compilers}}
|
|
<tr class="main">
|
|
<td>{{.Key}}</td>
|
|
<td class="text-right">{{.Count}}</td>
|
|
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
|
|
</tr>
|
|
{{range .Items}}
|
|
{{if or (gt .Percentage 0.1) (eq .Key "Others")}}
|
|
<tr class="child">
|
|
<td class="first">{{.Key}}</td>
|
|
<td class="text-right">{{.Count}}</td>
|
|
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
|
|
</tr>
|
|
{{end}}
|
|
{{end}}
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>Builder</th>
|
|
<th class="text-right">Devices</th>
|
|
<th class="text-right">Share</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .builders}}
|
|
<tr>
|
|
<td>{{.Key}}</td>
|
|
<td class="text-right">{{.Count}}</td>
|
|
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>Distribution Channel</th>
|
|
<th class="text-right">Devices</th>
|
|
<th class="text-right">Share</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .distributions}}
|
|
<tr>
|
|
<td>{{.Key}}</td>
|
|
<td class="text-right">{{.Count}}</td>
|
|
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<h4 id="features">Feature Usage</h4>
|
|
<p>
|
|
The following lists feature usage. Some features are reported per report, some are per sum of units within report (eg. devices with static addresses among all known devices per report).
|
|
Currently there are <b>{{.versionNodes.v2}}</b> devices reporting for version 2 and <b>{{.versionNodes.v3}}</b> for version 3.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="row">
|
|
{{$i := counter}}
|
|
{{range $featureName := .featureOrder}}
|
|
{{$featureValues := index $.features $featureName }}
|
|
{{if $i.DrawTwoDivider}}
|
|
</div>
|
|
<div class="row">
|
|
{{end}}
|
|
{{ $i.Increment }}
|
|
<div class="col-md-6">
|
|
<table class="table table-striped">
|
|
<thead><tr>
|
|
<th>{{$featureName}} Features</th><th colspan="2" class="text-center">Usage</th>
|
|
</tr></thead>
|
|
<tbody>
|
|
{{range $featureValues}}
|
|
<tr>
|
|
<td style="width: 50%">{{.Key}} ({{.Version}})</td>
|
|
<td style="width: 10%" class="text-right">{{if ge .Pct 10.0}}{{.Pct | printf "%.0f"}}{{else if ge .Pct 1.0}}{{.Pct | printf "%.01f"}}{{else}}{{.Pct | printf "%.02f"}}{{end}}%</td>
|
|
<td style="width: 40%" {{if lt .Pct 5.0}}data-toggle="tooltip" title='{{.Count}}'{{end}}>
|
|
<div class="progress-bar" role="progressbar" aria-valuenow="{{.Pct | printf "%.02f"}}" aria-valuemin="0" aria-valuemax="100" style="width: {{.Pct | printf "%.02f"}}%; height:20px" {{if ge .Pct 5.0}}data-toggle="tooltip" title='{{.Count}}'{{end}}></div>
|
|
</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<h4 id="features">Feature Group Usage</h4>
|
|
<p>
|
|
The following lists feature usage groups, which might include multiple occourances of a feature use per report.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
{{$i := counter}}
|
|
{{range $featureName := .featureOrder}}
|
|
{{$featureValues := index $.featureGroups $featureName }}
|
|
{{if $i.DrawTwoDivider}}
|
|
</div>
|
|
<div class="row">
|
|
{{end}}
|
|
{{ $i.Increment }}
|
|
<div class="col-md-6">
|
|
<table class="table table-striped">
|
|
<thead><tr>
|
|
<th>{{$featureName}} Group Features</th><th colspan="2" class="text-center">Usage</th>
|
|
</tr></thead>
|
|
<tbody>
|
|
{{range $featureValues}}
|
|
{{$counts := .Counts}}
|
|
<tr>
|
|
<td style="width: 50%">
|
|
<div data-toggle="tooltip" title='{{range $key, $value := .Counts}}{{$key}} ({{$value | proportion $counts | printf "%.02f"}}% - {{$value}})</br>{{end}}'>
|
|
{{.Key}} ({{.Version}})
|
|
</div>
|
|
</td>
|
|
<td style="width: 50%">
|
|
<div class="progress" role="progressbar" style="width: 100%">
|
|
{{$j := counter}}
|
|
{{range $key, $value := .Counts}}
|
|
{{with $valuePct := $value | proportion $counts}}
|
|
<div class="progress-bar {{ $j.Current | progressBarClassByIndex }}" style='width: {{$valuePct | printf "%.02f"}}%' data-toggle="tooltip" title='{{$key}} ({{$valuePct | printf "%.02f"}}% - {{$value}})'>
|
|
{{if ge $valuePct 30.0}}{{$key}}{{end}}
|
|
</div>
|
|
{{end}}
|
|
{{ $j.Increment }}
|
|
{{end}}
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<h1 id="performance-charts">Historical Performance Data</h1>
|
|
<p>These charts are all the average of the corresponding metric, for the entire population of a given day.</p>
|
|
|
|
<h4 id="hash-performance">Hash Performance (MiB/s)</h4>
|
|
<div class="img-thumbnail" id="hashPerfChart" style="width: 1130px; height: 400px; padding: 10px;"></div>
|
|
|
|
<h4 id="memory-usage">Memory Usage (MiB)</h4>
|
|
<div class="img-thumbnail" id="memUsageChart" style="width: 1130px; height: 400px; padding: 10px;"></div>
|
|
|
|
<h4 id="total-files">Total Number of Files</h4>
|
|
<div class="img-thumbnail" id="totFilesChart" style="width: 1130px; height: 400px; padding: 10px;"></div>
|
|
|
|
<h4 id="total-size">Total Folder Size (GiB)</h4>
|
|
<div class="img-thumbnail" id="totMiBChart" style="width: 1130px; height: 400px; padding: 10px;"></div>
|
|
|
|
<h4 id="system-ram">System RAM Size (GiB)</h4>
|
|
<div class="img-thumbnail" id="memSizeChart" style="width: 1130px; height: 400px; padding: 10px;"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<hr>
|
|
<p>
|
|
This product includes GeoLite2 data created by MaxMind, available from
|
|
<a href="http://www.maxmind.com">http://www.maxmind.com</a>.
|
|
</p>
|
|
<script type="text/javascript">
|
|
$('[data-toggle="tooltip"]').tooltip({html:true});
|
|
drawHeatMap();
|
|
</script>
|
|
</body>
|
|
</html>
|