update graphs and add new tier

This commit is contained in:
2020-08-11 19:52:03 +02:00
parent d1a6c638c2
commit 70a72a2836
15 changed files with 418 additions and 271 deletions

View File

@@ -39,6 +39,10 @@ account. {{if .Authenticated}}(Your e-mail address: {{.User.Email}}){{end}}
<a class="button button_highlight" href="https://www.patreon.com/join/pixeldrain/checkout?rid=5291427">
Order plan 'I'm doing my part!'
</a>
{{else if eq $plan "t5"}}
<a class="button button_highlight" href="https://www.patreon.com/join/pixeldrain/checkout?rid=5736701">
Order plan 'Resolve'
</a>
{{else if eq $plan "t2"}}
<a class="button button_highlight" href="https://www.patreon.com/join/pixeldrain/checkout?rid=5291482">
Order plan 'Persistence'

View File

@@ -1,102 +1,10 @@
// Draw usage graph
let graphViews = drawGraph(document.getElementById("views_chart"), "Views", "number");
let graphBandwidth = drawGraph(document.getElementById("bandwidth_chart"), "Bandwidth", "bytes");
Chart.defaults.global.defaultFontColor = "#b3b3b3";
Chart.defaults.global.defaultFontSize = 15;
Chart.defaults.global.defaultFontFamily = "Ubuntu";
Chart.defaults.global.maintainAspectRatio = false;
Chart.defaults.global.elements.point.radius = 0;
Chart.defaults.global.tooltips.mode = "index";
Chart.defaults.global.tooltips.axis = "x";
Chart.defaults.global.tooltips.intersect = false;
Chart.defaults.global.animation.duration = 1000;
Chart.defaults.global.animation.easing = "linear";
var graph = new Chart(
document.getElementById('bandwidth_chart'),
{
type: 'line',
data: {
datasets: [
{
label: "Bandwidth",
backgroundColor: "rgba(64, 255, 64, .01)",
borderColor: "rgba(96, 255, 96, 1)",
borderWidth: 1.5,
lineTension: 0.2,
fill: true,
yAxisID: "y_bandwidth"
}, {
label: "Views",
backgroundColor: "rgba(64, 64, 255, .01)",
borderColor: "rgba(96, 96, 255, 1)",
borderWidth: 1.5,
lineTension: 0.2,
fill: true,
yAxisID: "y_views"
}
]
},
options: {
scales: {
yAxes: [
{
type: "linear",
display: true,
position: "left",
id: "y_bandwidth",
scaleLabel: {
display: true,
labelString: "Bandwidth"
},
ticks: {
callback: function(value, index, values) {
return formatDataVolume(value, 3);
},
beginAtZero: true
},
gridLines: {
color: "rgba(100, 255, 100, .05)"
}
}, {
type: "linear",
display: true,
position: "right",
id: "y_views",
scaleLabel: {
display: true,
labelString: "Views"
},
ticks: {
callback: function(value, index, values) {
return formatNumber(value, 3);
},
beginAtZero: true
},
gridLines: {
color: "rgba(128, 128, 255, .05)"
}
}
],
xAxes: [
{
ticks: {
maxRotation: 16
},
gridLines: {
display: false
}
}
]
}
}
}
);
let graphTimeout = null;
function loadGraph(minutes, interval, live){
if (graphTimeout !== null) { clearTimeout(graphTimeout) }
if (live) {
graphTimeout = setTimeout(() => {loadGraph(minutes, interval, true)}, 2000)
graphTimeout = setTimeout(() => {updateGraphs(minutes, interval, true)}, 10000)
}
let today = new Date()
@@ -112,26 +20,41 @@ function loadGraph(minutes, interval, live){
if (!resp.ok) { return Promise.reject("Error: "+resp.status);}
return resp.json();
}).then(resp => {
if (resp.success) {
window.graph.data.labels = resp.labels;
window.graph.data.datasets[0].data = resp.downloads;
window.graph.data.datasets[1].data = resp.views;
window.graph.update();
resp.views.timestamps.forEach((val, idx) => {
let date = new Date(val);
let dateStr = ("00"+(date.getMonth()+1)).slice(-2);
dateStr += "-"+("00"+date.getDate()).slice(-2);
dateStr += " "+("00"+date.getHours()).slice(-2);
dateStr += ":"+("00"+date.getMinutes()).slice(-2);
resp.views.timestamps[idx] = " "+dateStr+" "; // Poor man's padding
});
graphViews.data.labels = resp.views.timestamps;
graphViews.data.datasets[0].data = resp.views.amounts;
graphBandwidth.data.labels = resp.views.timestamps;
graphBandwidth.data.datasets[0].data = resp.bandwidth.amounts;
graphViews.update()
graphBandwidth.update();
document.getElementById("time_start").innerText = resp.labels[0];
document.getElementById("time_end").innerText = resp.labels.slice(-1)[0];
let total = 0
resp.downloads.forEach(e => { total += e; });
document.getElementById("total_bandwidth").innerText = formatDataVolume(total, 3);
total = 0
resp.views.forEach(e => { total += e; });
document.getElementById("total_views").innerText = formatThousands(total);
}
document.getElementById("time_start").innerText = resp.views.timestamps[0];
document.getElementById("time_end").innerText = resp.views.timestamps.slice(-1)[0];
let total = 0
resp.bandwidth.amounts.forEach(e => { total += e; });
document.getElementById("total_bandwidth").innerText = formatDataVolume(total, 3);
total = 0
resp.views.amounts.forEach(e => { total += e; });
document.getElementById("total_views").innerText = formatThousands(total);
}).catch(e => {
alert("Error requesting time series: "+e);
})
}
let graphTimeout = null;
function updateGraphs(minutes, interval, live) {
loadGraph(graphViews, "views", minutes, interval);
loadGraph(graphBandwidth, "bandwidth", minutes, interval);
}
loadGraph(1440, 10, true);
// Load performance statistics

View File

@@ -55,6 +55,10 @@ Modal.prototype.setBody = function(element) {
this.body.append(element)
}
Modal.prototype.cloneTemplate = function(templateID) {
this.setBody(document.getElementById(templateID).content.cloneNode(true))
}
Modal.prototype.open = function() {
if (this.visible) { return }
this.visible = true

View File

@@ -0,0 +1,65 @@
Chart.defaults.global.defaultFontColor = "#b3b3b3";
Chart.defaults.global.defaultFontSize = 15;
Chart.defaults.global.defaultFontFamily = "system-ui, sans-serif";
Chart.defaults.global.maintainAspectRatio = false;
Chart.defaults.global.elements.point.radius = 0;
Chart.defaults.global.tooltips.mode = "index";
Chart.defaults.global.tooltips.axis = "x";
Chart.defaults.global.tooltips.intersect = false;
Chart.defaults.global.animation.duration = 500;
Chart.defaults.global.animation.easing = "linear";
function drawGraph(element, label, dataType) {
return new Chart(
element,
{
type: 'line',
data: {
datasets: [
{
label: label,
backgroundColor: highlightColor,
borderWidth: 0,
lineTension: 0,
fill: true,
yAxisID: "ax_1"
}
]
},
options: {
legend: { display: false },
scales: {
yAxes: [
{
type: "linear",
display: true,
position: "left",
id: "ax_1",
ticks: {
callback: function(value, index, values) {
if (dataType == "bytes") {
return formatDataVolume(value, 3);
}
return formatNumber(value, 3);
},
beginAtZero: true
},
gridLines: { display: false },
}
],
xAxes: [
{
ticks: {
sampleSize: 1,
padding: 4,
minRotation: 0,
maxRotation: 0
},
gridLines: { display: false }
}
]
}
}
}
);
}

View File

@@ -2,7 +2,9 @@ function DetailsWindow(viewer) {
this.viewer = viewer
this.visible = false
this.file = null
this.graph = 0
this.graphsInitialized = false
this.graphViews = 0
this.graphDownloads = 0
this.modal = new Modal(
document.getElementById("file_viewer"),
() => { this.toggle() },
@@ -27,8 +29,9 @@ DetailsWindow.prototype.toggle = function() {
this.btnDetails.classList.add("button_highlight")
this.visible = true
if (this.graph === 0) {
this.renderGraph()
if (!this.graphsInitialized) {
this.renderGraphs()
this.graphsInitialized = true
}
this.updateGraph(this.file)
}
@@ -54,12 +57,22 @@ DetailsWindow.prototype.setFile = function(file) {
}
}
DetailsWindow.prototype.renderGraphs = function() {
console.log("rendering graphs")
this.graphDownloads = drawGraph(
document.getElementById("downloads_chart"), "Downloads", "number",
);
this.graphViews = drawGraph(
document.getElementById("views_chart"), "Views", "number",
);
}
DetailsWindow.prototype.updateGraph = function(file) {
console.log("updating graph")
let today = new Date()
let start = new Date()
start.setDate(start.getDate()-30)
start.setDate(start.getDate()-90)
fetch(
file.timeseries_href+
@@ -70,101 +83,21 @@ DetailsWindow.prototype.updateGraph = function(file) {
if (!resp.ok) {return null}
return resp.json()
}).then(resp => {
this.graph.data.labels = resp.labels
this.graph.data.datasets[0].data = resp.downloads
this.graph.data.datasets[1].data = resp.views
this.graph.update()
resp.views.timestamps.forEach((val, idx) => {
let date = new Date(val);
let dateStr = ("00"+(date.getMonth()+1)).slice(-2);
dateStr += "-"+("00"+date.getDate()).slice(-2);
dateStr += " "+("00"+date.getHours()).slice(-2)+"h";
resp.views.timestamps[idx] = " "+dateStr+" "; // Poor man's padding
});
resp.bandwidth.amounts.forEach((val, idx) => {
resp.bandwidth.amounts[idx] = Math.round(val/file.size);
});
this.graphDownloads.data.labels = resp.views.timestamps
this.graphViews.data.labels = resp.views.timestamps
this.graphDownloads.data.datasets[0].data = resp.bandwidth.amounts
this.graphViews.data.datasets[0].data = resp.views.amounts
this.graphDownloads.update()
this.graphViews.update()
})
}
DetailsWindow.prototype.renderGraph = function() {
console.log("rendering graph")
Chart.defaults.global.defaultFontColor = "#b3b3b3"
Chart.defaults.global.defaultFontSize = 15
Chart.defaults.global.defaultFontFamily = "Ubuntu"
Chart.defaults.global.maintainAspectRatio = false;
Chart.defaults.global.elements.point.radius = 0
Chart.defaults.global.tooltips.mode = "index"
Chart.defaults.global.tooltips.axis = "x"
Chart.defaults.global.tooltips.intersect = false
this.graph = new Chart(
document.getElementById('bandwidth_chart'),
{
type: 'line',
data: {
datasets: [
{
label: "Downloads",
backgroundColor: "rgba(64, 255, 64, .01)",
borderColor: "rgba(96, 255, 96, 1)",
borderWidth: 1.5,
lineTension: 0.2,
fill: true,
yAxisID: "y_bandwidth"
}, {
label: "Views",
backgroundColor: "rgba(64, 64, 255, .01)",
borderColor: "rgba(96, 96, 255, 1)",
borderWidth: 1.5,
lineTension: 0.2,
fill: true,
yAxisID: "y_views"
}
]
},
options: {
scales: {
yAxes: [
{
type: "linear",
display: true,
position: "left",
id: "y_bandwidth",
scaleLabel: {
display: true,
labelString: "Downloads"
},
ticks: {
callback: function(value, index, values) {
return formatNumber(value, 3);
},
beginAtZero: true
},
gridLines: {
color: "rgba(100, 255, 100, .05)"
}
}, {
type: "linear",
display: true,
position: "right",
id: "y_views",
scaleLabel: {
display: true,
labelString: "Views"
},
ticks: {
callback: function(value, index, values) {
return formatNumber(value, 3);
},
beginAtZero: true
},
gridLines: {
color: "rgba(128, 128, 255, .05)"
}
}
],
xAxes: [
{
ticks: {
maxRotation: 16
},
gridLines: {
display: false
}
}
]
}
}
}
)
}

View File

@@ -0,0 +1,61 @@
function loadGraph(graph, stat, minutes, interval){
let today = new Date()
let start = new Date()
start.setMinutes(start.getMinutes()-minutes)
fetch(
apiEndpoint+"/user/time_series/" + stat +
"?start="+start.toISOString() +
"&end="+today.toISOString() +
"&interval="+interval
).then(resp => {
if (!resp.ok) { return Promise.reject("Error: "+resp.status);}
return resp.json();
}).then(resp => {
resp.timestamps.forEach((val, idx) => {
let date = new Date(val);
let dateStr = ("00"+(date.getMonth()+1)).slice(-2);
dateStr += "-"+("00"+date.getDate()).slice(-2);
dateStr += " "+("00"+date.getHours()).slice(-2);
dateStr += ":"+("00"+date.getMinutes()).slice(-2);
resp.timestamps[idx] = " "+dateStr+" "; // Poor man's padding
});
graph.data.labels = resp.timestamps;
graph.data.datasets[0].data = resp.amounts;
graph.update();
document.getElementById("time_start").innerText = resp.timestamps[0];
document.getElementById("time_end").innerText = resp.timestamps.slice(-1)[0];
let total = 0
resp.amounts.forEach(e => { total += e; });
if (stat == "views") {
document.getElementById("total_views").innerText = formatThousands(total);
} else if (stat == "downloads") {
document.getElementById("total_downloads").innerText = formatThousands(total);
} else if (stat == "bandwidth") {
document.getElementById("total_bandwidth").innerText = formatDataVolume(total, 3);
}
}).catch(e => {
console.error("Error requesting time series: "+e);
})
}
let graphViews = drawGraph(document.getElementById("views_chart"), "Views", "number");
let graphDownloads = drawGraph(document.getElementById("downloads_chart"), "Downloads", "number");
let graphBandwidth = drawGraph(document.getElementById("bandwidth_chart"), "Bandwidth", "bytes");
let graphTimeout = null;
function updateGraphs(minutes, interval, live) {
if (graphTimeout !== null) { clearTimeout(graphTimeout) }
if (live) {
graphTimeout = setTimeout(() => {updateGraphs(minutes, interval, true)}, 10000)
}
loadGraph(graphViews, "views", minutes, interval);
loadGraph(graphDownloads, "downloads", minutes, interval);
loadGraph(graphBandwidth, "bandwidth", minutes, interval);
}
// Default
updateGraphs(10080, 60, false);

View File

@@ -104,6 +104,7 @@ is collapsed */
margin: 0;
box-sizing: border-box;
color: var(--text_color);
text-decoration: none;
}
.node:hover:not(.node_selected) {
background-color: var(--input_color_dark);

View File

@@ -96,7 +96,7 @@ body{
.page_navigation {
position: fixed;
backface-visibility: hidden;
z-index: 100;
z-index: 99;
width: 250px;
height: 100%;
left: 0;
@@ -125,7 +125,7 @@ body{
overflow-x: hidden;
z-index: 50;
transition: left 0.5s;
padding: 50px 0 50px 0;
padding: 70px 0 100px 0;
}
@media (max-width: 800px) {
.page_navigation {
@@ -183,6 +183,7 @@ body{
text-overflow: ellipsis;
transition: background-color 0.5s;
border-radius: 5px;
text-decoration: none;
}
.page_navigation a:hover {
background-color: #3f3f3f;
@@ -285,10 +286,11 @@ hr{
a {
color: #74ad38;
color: var(--highlight_color);
text-decoration: none;
color: var(--highlight_color_dark);
}
a:hover {
color: var(--highlight_color);
}
a:hover {text-decoration: underline;}
.form{
margin-left: auto;

View File

@@ -1,5 +1,5 @@
.modal_background {
position: absolute;
position: fixed;
top: 0;
right: 0;
bottom: 0;