mirror of
https://github.com/4cuck/nitter-status.git
synced 2026-10-27 00:57:39 +00:00
248 lines
8.5 KiB
JavaScript
248 lines
8.5 KiB
JavaScript
// SPDX-License-Identifier: AGPL-3.0-only
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
const startDateInput = document.getElementById('startDate');
|
|
const endDateInput = document.getElementById('endDate');
|
|
const submitTime = document.getElementById('submitDateRange');
|
|
|
|
// Set initial values in UTC
|
|
const initialEndDate = moment.utc();
|
|
const initialStartDate = moment().subtract(30, 'days').utc();
|
|
startDateInput.value = initialStartDate.format('YYYY-MM-DD');
|
|
endDateInput.value = initialEndDate.format('YYYY-MM-DD');;
|
|
|
|
submitTime.addEventListener('click', function() {
|
|
const startDate = moment(startDateInput.value, 'YYYY-MM-DD');
|
|
const endDate = moment(endDateInput.value, 'YYYY-MM-DD');
|
|
|
|
if (!startDate.isValid() || !endDate.isValid()) {
|
|
alert('Invalid date format. Please use the YYYY-MM-DD format.');
|
|
} else if (startDate.isAfter(endDate)) {
|
|
alert('Invalid date range. Start date must be before the end date.');
|
|
} else {
|
|
fetchDataAndCreateChart(startDate,endDate);
|
|
}
|
|
});
|
|
fetchDataAndCreateChart(initialStartDate,initialEndDate);
|
|
});
|
|
|
|
let chart = undefined;
|
|
async function fetchDataAndCreateChart(startDate,endDate) {
|
|
let data;
|
|
try {
|
|
const response = await fetch('/admin/api/history', {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({"start": startDate.utc(), "end": endDate.add(1, 'days').utc()})
|
|
});
|
|
data = await response.json();
|
|
} catch (error) {
|
|
console.error('Failed to fetch data:', error);
|
|
}
|
|
// Create arrays for y-values for both datasets
|
|
const healthyData = data.global.map(entry => {
|
|
return {x: moment.unix(entry.time), y: entry.alive};
|
|
});
|
|
|
|
const unhealthyData = data.global.map(entry => {
|
|
return {x: moment.unix(entry.time), y: entry.dead};
|
|
});
|
|
|
|
let statsData = [];
|
|
let statsKeys = [];
|
|
if (data.stats.length > 0) {
|
|
|
|
statsKeys = Object.keys(data.stats[0]).filter(key => key !== 'time');
|
|
statsData = statsKeys.map(key => ({"key": key, data: data.stats.map(entry => ({x: moment.unix(entry.time), y: entry[key]}))}));
|
|
}
|
|
|
|
|
|
const userUnhealthyData = data.user.filter(entry => entry.dead > 0).map(entry => ({"x": entry.time * 1000, "y": entry.dead}));
|
|
const paramData = {"healthyData": healthyData, "unhealthyData": unhealthyData, "user": userUnhealthyData, "stats": statsData, "statsKeys": statsKeys};
|
|
|
|
createChartOverview(paramData);
|
|
}
|
|
|
|
function mapKey(key) {
|
|
const keyMappings = {
|
|
"limited_accs_max": "Max Lim. Accs",
|
|
"limited_accs_avg": "Avg Lim. Accs",
|
|
"total_accs_max": "Max Accs",
|
|
"total_accs_avg": "Avg Accs",
|
|
"total_requests_max": "Max Requests Req.",
|
|
"total_requests_avg": "Avg Requests Req.",
|
|
"req_photo_rail_max": "Max PhotoRail Req.",
|
|
"req_photo_rail_avg": "Avg PhotoRail Req.",
|
|
"req_user_screen_name_max": "Max UserScreenName Req.",
|
|
"req_user_screen_name_avg": "Avg UserScreenName Req.",
|
|
"req_search_max": "Max Search Req.",
|
|
"req_search_avg": "Avg Search Req.",
|
|
"req_list_tweets_max": "Max ListTweets Req.",
|
|
"req_list_tweets_avg": "Avg ListTweets Req.",
|
|
"req_user_media_max": "Max UserMedia Req.",
|
|
"req_user_media_avg": "Avg UserMedia Req.",
|
|
"req_tweet_detail_max": "Max TweetDetail Req.",
|
|
"req_tweet_detail_avg": "Avg TweetDetail Req.",
|
|
"req_list_max": "Max List Req.",
|
|
"req_list_avg": "Avg List Req.",
|
|
"req_user_tweets_max": "Max UserTweets Req.",
|
|
"req_user_tweets_avg": "Avg UserTweets Req.",
|
|
"req_user_tweets_and_replies_max": "Max UserTweetsAndReplies Req.",
|
|
"req_user_tweets_and_replies_avg": "Avg UserTweetsAndReplies Req.",
|
|
}
|
|
return keyMappings[key];
|
|
}
|
|
|
|
function nameToColor(name) {
|
|
const colors = ["#fafa6e"
|
|
,"#eafb71"
|
|
,"#dafb75"
|
|
,"#cafb7b"
|
|
,"#b9fa81"
|
|
,"#a8f989"
|
|
,"#97f890"
|
|
,"#85f799"
|
|
,"#71f5a1"
|
|
,"#5cf3aa"
|
|
,"#42f1b3"
|
|
,"#15efbc"
|
|
,"#00ecc4"
|
|
,"#00e9cd"
|
|
,"#00e6d5"
|
|
,"#00e3dd"
|
|
,"#00e0e4"
|
|
,"#00dcea"
|
|
,"#00d8f0"
|
|
,"#00d5f5"
|
|
,"#00d0f9"
|
|
,"#00ccfd"
|
|
,"#00c8ff"
|
|
,"#00c3ff"
|
|
,"#00beff"
|
|
,"#00b9ff"
|
|
,"#00b4ff"];
|
|
var hash = hashStr(name);
|
|
var index = hash % colors.length;
|
|
return colors[index];
|
|
}
|
|
|
|
function hashStr(str) {
|
|
var hash = 0;
|
|
for (var i = 0; i < str.length; i++) {
|
|
var charCode = str.charCodeAt(i);
|
|
hash += charCode;
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
function createChartOverview(data) {
|
|
const ctx = document.getElementById('graph-health').getContext('2d');
|
|
let high_data = data.stats.length > 1000;
|
|
if (chart) {
|
|
chart.destroy();
|
|
}
|
|
let datasets = [{
|
|
label: 'Healthy',
|
|
data: data.healthyData,
|
|
borderColor: 'green',
|
|
backgroundColor: 'rgba(0, 255, 0, 0.2)',
|
|
fill: true
|
|
},
|
|
{
|
|
label: 'Unhealthy',
|
|
data: data.unhealthyData,
|
|
borderColor: 'orange',
|
|
backgroundColor: 'rgba(241, 90, 34, 0.2)',
|
|
fill: true
|
|
},
|
|
{
|
|
label: 'Own Instances Unhealthy',
|
|
data: data.user,
|
|
pointRadius: 5,
|
|
pointBackgroundColor: 'rgba(255, 0, 0, 1)',
|
|
fill: false,
|
|
datasetIndex: "x",
|
|
}];
|
|
datasets = datasets.concat(data.stats.map(entry => ({
|
|
yAxisID: 'yStats',
|
|
label: mapKey(entry.key),
|
|
data: entry.data,
|
|
borderColor: nameToColor(entry.key),
|
|
fill: false,
|
|
hidden: (entry.key !== 'total_requests_avg' && entry.key !== 'limited_accs_avg'),
|
|
})));
|
|
console.log(datasets);
|
|
chart = new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
datasets: datasets,
|
|
},
|
|
options: {
|
|
//responsive: false,
|
|
//maintainAspectRatio: false,
|
|
plugins: {
|
|
colors: {
|
|
enabled: true
|
|
},
|
|
decimation: {
|
|
enabled: high_data,
|
|
algorithm: 'min-max',
|
|
},
|
|
tooltip: {
|
|
// callbacks: {
|
|
// label: function(context) {
|
|
// console.log(context);
|
|
// if (context.dataset) {
|
|
// if (context.dataset.yAxisID == 'yStats') {
|
|
// let dataset = context.dataset.data[context.dataIndex];
|
|
// if (!dataset) {
|
|
// console.warn(context.dataset);
|
|
// console.warn(context.dataset.data[context.dataIndex]);
|
|
// }
|
|
// let mainValue = dataset.y;
|
|
// let detailValue = dataset.additional.total_requests_max;
|
|
// return [`${context.dataset.label}: ${mainValue}`,`Max Total Requests: ${detailValue}`];
|
|
// } else {
|
|
// return `${context.dataset.label}: ${context.formattedValue}`;
|
|
// }
|
|
// } else {
|
|
// console.log(context);
|
|
// return null;
|
|
// }
|
|
// // let label = context.dataset.label || '';
|
|
|
|
// // if (label) {
|
|
// // label += ': ';
|
|
// // }
|
|
// // if (context.parsed.y !== null) {
|
|
// // label += new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(context.parsed.y);
|
|
// // }
|
|
// return 'asdf';
|
|
// }
|
|
// }
|
|
}
|
|
},
|
|
animation: !high_data,
|
|
scales: {
|
|
x: {
|
|
type: 'time',
|
|
time: {
|
|
unit: 'day'
|
|
},
|
|
autoSkip: true,
|
|
},
|
|
y: {
|
|
beginAtZero: true
|
|
},
|
|
yStats: {
|
|
beginAtZero: false
|
|
}
|
|
},
|
|
interaction: {
|
|
mode: 'index',
|
|
intersect: false
|
|
},
|
|
}
|
|
});
|
|
} |