// ==UserScript==
// @name GreasyFork用户主页显示该用户发布脚本数目、所有脚本的今日总安装次数和迄今总安装次数
// @name:zh-TW GreasyFork用戶主頁顯示該用戶發佈腳本數目、
// @name:en Displays the number of scripts published by the user, the total number of installations
// @namespace http://tampermonkey.net/
// @version 0.2.9.7
// @description 在GreasyFork用户主页显示该用户发布脚本数目、所有脚本的今日总安装次数和迄今总安装次数。
// @description:en The GreasyFork user homepage displays the number of scripts published by the user, the total number of installations for all scripts today, and the total number of installations to date.
// @description:zh-tw GreasyFork用戶主頁顯示該用戶發佈腳本數目、所有腳本的今日總安裝次數和迄今總安裝次數。
// @author aspen138
// @match https://greasyfork.org/*/users/*
// @grant none
// @license MIT
// @locale en The GreasyFork user homepage displays the number of scripts published by the user, the total number of installations for all scripts today, and the total number of installations to date
// @locale zh-CN GreasyFork用户主页显示该用户发布脚本数目、所有脚本的今日总安装次数和迄今总安装次数
// @locale zh-TW GreasyFork用戶主頁顯示該用戶發佈腳本數目、所有腳本的今日總安裝次數和迄今總安裝次數
// @locale ja GreasyForkユーザーのホームページには、ユーザーが発行したスクリプトの数、すべてのスクリプトの今日の総インストール数、合計インストール数が表示されます。
// @locale ko GreasyFork 사용자 홈 페이지에는 해당 사용자가 게시한 스크립트 수, 모든 스크립트의 오늘 총 설치 횟수 및 현재 총 설치 횟수가 표시됩니다.
// @icon https://greasyfork.org//vite/assets/blacklogo16-37ZGLlXh.png
// ==/UserScript==
// Function to inject Chart.js from a CDN
const injectChartJs = () => {
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/chart.js';
document.head.appendChild(script);
};
const plotDistribution = (data1, data2) => {
// Ensure Chart.js has loaded
if (typeof Chart === 'undefined') {
setTimeout(() => plotDistribution(data1, data2), 500); // Retry after 500ms
return;
}
// Create canvas for the chart
const canvasHtml = '<canvas id="installDistributionCanvas" width="100" height="50"></canvas>';
const userHeader = document.querySelector('#about-user h2');
if (userHeader) {
userHeader.insertAdjacentHTML('afterend', canvasHtml);
const ctx = document.getElementById('installDistributionCanvas').getContext('2d');
// Plot chart
new Chart(ctx, {
type: 'bar', // Change this to 'line', 'bar', etc. as needed
data: {
labels: data1.labels, // X-axis labels
datasets: [{
label: 'Total Installs',
data: data1.values, // Y-axis data for Total Installs
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1,
yAxisID: 'y-axis-1', // Associate this dataset with the first y-axis
},
{
label: 'Daily Installs',
data: data2.values, // Y-axis data for Daily Installs
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: 'rgba(255, 99, 132, 1)',
borderWidth: 1,
yAxisID: 'y-axis-2', // Associate this dataset with the second y-axis
}
]
},
options: {
scales: {
yAxes: [{
id: 'y-axis-1',
type: 'linear',
position: 'left', // This places the first y-axis on the left
beginAtZero: true,
// Additional customization for this axis
},
{
id: 'y-axis-2',
type: 'linear',
position: 'right', // This places the second y-axis on the right
beginAtZero: true,
grid: {
drawOnChartArea: false, // Ensures grid lines from this axis do not overlap with the first axis
},
// Additional customization for this axis
}
]
}
}
});
}
};
const collectAndPlotData = () => {
// Assuming you have a way to collect individual install counts
const totalInstallData = {
labels: [], // Populate with script names or identifiers
values: [] // Populate with corresponding install counts
};
const dailyInstallData = {
labels: [], // Populate with script names or identifiers
values: [] // Populate with corresponding install counts
};
var totalInstalls_selector = '#user-script-list-section dd.script-list-total-installs > span';
var array_totalInstall = Array.from(document.querySelectorAll(totalInstalls_selector)).map(el => (parseInt(el.textContent.replace(/,/g, ''), 10) || 0));
var dailyInstalls_selector = '#user-script-list-section dd.script-list-daily-installs > span';
var array_dailyInstalls = Array.from(document.querySelectorAll(dailyInstalls_selector)).map(el => (parseInt(el.textContent.replace(/,/g, ''), 10) || 0))
var scriptTitle_selector = '#user-script-list-section article > h2 > a.script-link';
var array_scriptTitle = Array.from(document.querySelectorAll(scriptTitle_selector)).map(el => el.text)
for (let i = 0; i < array_totalInstall.length; i++) {
// totalInstallData.labels.push(`Script ${i+1}`);
// dailyInstallData.labels.push(`Script ${i+1}`);
totalInstallData.labels.push(array_scriptTitle[i]);
dailyInstallData.labels.push(array_scriptTitle[i]);
totalInstallData.values = array_totalInstall;
dailyInstallData.values = array_dailyInstalls;
}
plotDistribution(totalInstallData, dailyInstallData);
};
var publishedScriptsNumber = 0;
(function() {
'use strict';
const sumInstalls = (selector) => Array.from(document.querySelectorAll(selector))
.reduce((sum, el) => sum + (parseInt(el.textContent.replace(/,/g, ''), 10) || 0), 0);
const displayTotals = (daily, total) => {
const userHeader = document.querySelector('#about-user h2');
const language = document.documentElement.lang; // Get the current language of the document
let dailyInstallsText = '';
let totalInstallsText = '';
// Determine the text based on the current language
switch (language) {
case 'en':
publishedScriptsNumber = `Number of published scripts: ${publishedScriptsNumber}`;
dailyInstallsText = `Total daily installations for all scripts: ${daily}`;
totalInstallsText = `Total installations to date for all scripts: ${total}`;
break;
case 'zh-CN':
publishedScriptsNumber = `已发布脚本总数:${publishedScriptsNumber}`;
dailyInstallsText = `该用户所有脚本的今日总安装次数:${daily}`;
totalInstallsText = `该用户所有脚本的迄今总安装次数:${total}`;
break;
case 'zh-TW':
publishedScriptsNumber = `已發布腳本總數:${publishedScriptsNumber}`;
dailyInstallsText = `該用戶所有腳本的今日總安裝次數:${daily}`;
totalInstallsText = `該用戶所有腳本的迄今總安裝次數:${total}`;
break;
case 'ja':
publishedScriptsNumber = `公開されたスクリプトの合計:${publishedScriptsNumber}`;
dailyInstallsText = `本日の全スクリプトの合計インストール回数:${daily}`;
totalInstallsText = `全スクリプトの累計インストール回数:${total}`;
break;
case 'ko':
publishedScriptsNumber = `게시된 스크립트 총 수: ${publishedScriptsNumber}`;
dailyInstallsText = `해당 사용자의 모든 스크립트에 대한 오늘의 총 설치 횟수: ${daily}`;
totalInstallsText = `해당 사용자의 모든 스크립트에 대한 총 설치 횟수: ${total}`;
break;
// ... add other languages if needed
default:
publishedScriptsNumber = `Number of published scripts: ${publishedScriptsNumber}`;
dailyInstallsText = `Total daily installations for all scripts: ${daily}`;
totalInstallsText = `Total installations to date for all scripts: ${total}`;
}
if (userHeader) {
userHeader.insertAdjacentHTML('afterend', `
<dib>${publishedScriptsNumber}</div>
<div>${dailyInstallsText}</div>
<div>${totalInstallsText}</div>
`);
}
};
// const dailyInstallsSum = sumInstalls('dd.script-list-daily-installs > span');
// const totalInstallsSum = sumInstalls('dd.script-list-total-installs > span');
const dailyInstallsSum = sumInstalls('#user-script-list-section dd.script-list-daily-installs > span');
const totalInstallsSum = sumInstalls('#user-script-list-section dd.script-list-total-installs > span');
(function() {
var list = document.querySelector('ol#user-script-list.script-list.showing-all-languages');
if (list) {
var items = list.querySelectorAll('li');
publishedScriptsNumber = items.length;
} else {
console.log('没有找到指定的OL元素');
}
})();
displayTotals(dailyInstallsSum, totalInstallsSum);
// Call this function at the appropriate place in your script, after the DOM is ready
injectChartJs();
collectAndPlotData();
})();