Greasy Fork is available in English.

GrreasyFork User Script Data Visualization

Fetch and visualize user script data with Chart.js and display totals below the chart

Fra 05.07.2024. Se den seneste versjonen.

  1. // ==UserScript==
  2. // @name GrreasyFork User Script Data Visualization
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description Fetch and visualize user script data with Chart.js and display totals below the chart
  6. // @author aspen138
  7. // @match https://greatest.deepsurf.us/*/users/*
  8. // @grant none
  9. // @license MIT
  10. // @icon https://greatest.deepsurf.us//vite/assets/blacklogo16-37ZGLlXh.png
  11. // ==/UserScript==
  12.  
  13.  
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. // Function to inject Chart.js from a CDN if the target element exists
  19. const injectChartJs = () => {
  20. const userHeader = document.querySelector('#about-user h2');
  21. if (!userHeader) return;
  22.  
  23. const script = document.createElement('script');
  24. script.src = 'https://cdn.jsdelivr.net/npm/chart.js';
  25. script.onload = () => fetchDataAndPlot(); // Fetch data and plot chart once Chart.js is loaded
  26. document.head.appendChild(script);
  27. };
  28.  
  29. // Function to fetch user data
  30. const getUserData = (userID) => {
  31. return fetch(`https://${window.location.hostname}/users/${userID}.json`)
  32. .then((response) => {
  33. console.log(`${response.status}: ${response.url}`);
  34. return response.json();
  35. });
  36. };
  37.  
  38. // Function to plot the chart
  39. const plotDistribution = (labels, totalInstalls, dailyInstalls) => {
  40. const canvasHtml = '<canvas id="installDistributionCanvas" width="100" height="50"></canvas>';
  41. const userHeader = document.querySelector('#about-user h2');
  42. if (userHeader) {
  43. userHeader.insertAdjacentHTML('afterend', canvasHtml);
  44. const ctx = document.getElementById('installDistributionCanvas').getContext('2d');
  45.  
  46. // Plot chart
  47. new Chart(ctx, {
  48. type: 'bar', // Change this to 'line', 'bar', etc. as needed
  49. data: {
  50. labels: labels, // X-axis labels
  51. datasets: [{
  52. label: 'Total Installs',
  53. data: totalInstalls, // Y-axis data for Total Installs
  54. backgroundColor: 'rgba(54, 162, 235, 0.2)',
  55. borderColor: 'rgba(54, 162, 235, 1)',
  56. borderWidth: 1,
  57. yAxisID: 'y-axis-1', // Associate this dataset with the first y-axis
  58. },
  59. {
  60. label: 'Daily Installs',
  61. data: dailyInstalls, // Y-axis data for Daily Installs
  62. backgroundColor: 'rgba(255, 99, 132, 0.2)',
  63. borderColor: 'rgba(255, 99, 132, 1)',
  64. borderWidth: 1,
  65. yAxisID: 'y-axis-2', // Associate this dataset with the second y-axis
  66. }
  67. ]
  68. },
  69. options: {
  70. scales: {
  71. yAxes: [{
  72. id: 'y-axis-1',
  73. type: 'linear',
  74. position: 'left', // This places the first y-axis on the left
  75. beginAtZero: true,
  76. },
  77. {
  78. id: 'y-axis-2',
  79. type: 'linear',
  80. position: 'right', // This places the second y-axis on the right
  81. beginAtZero: true,
  82. grid: {
  83. drawOnChartArea: false, // Ensures grid lines from this axis do not overlap with the first axis
  84. },
  85. }
  86. ]
  87. }
  88. }
  89. });
  90. }
  91. };
  92.  
  93. // Function to display totals
  94. const displayTotals = (daily, total, publishedScriptsNumber) => {
  95. const userHeader = document.querySelector('#about-user h2');
  96. const language = document.documentElement.lang; // Get the current language of the document
  97.  
  98. let dailyInstallsText = '';
  99. let totalInstallsText = '';
  100.  
  101. // Determine the text based on the current language
  102. switch (language) {
  103. case 'zh-CN':
  104. publishedScriptsNumber = `已发布脚本总数:${publishedScriptsNumber}`;
  105. dailyInstallsText = `该用户所有脚本的今日总安装次数:${daily}`;
  106. totalInstallsText = `该用户所有脚本的迄今总安装次数:${total}`;
  107. break;
  108. case 'zh-TW':
  109. publishedScriptsNumber = `已發布腳本總數:${publishedScriptsNumber}`;
  110. dailyInstallsText = `該用戶所有腳本的今日總安裝次數:${daily}`;
  111. totalInstallsText = `該用戶所有腳本的迄今總安裝次數:${total}`;
  112. break;
  113. case 'ja':
  114. publishedScriptsNumber = `公開されたスクリプトの合計:${publishedScriptsNumber}`;
  115. dailyInstallsText = `本日の全スクリプトの合計インストール回数:${daily}`;
  116. totalInstallsText = `全スクリプトの累計インストール回数:${total}`;
  117. break;
  118. case 'ko':
  119. publishedScriptsNumber = `게시된 스크립트 수: ${publishedScriptsNumber}`;
  120. dailyInstallsText = `해당 사용자의 모든 스크립트에 대한 오늘의 설치 횟수: ${daily}`;
  121. totalInstallsText = `해당 사용자의 모든 스크립트에 대한 설치 횟수: ${total}`;
  122. break;
  123. default:
  124. publishedScriptsNumber = `Number of published scripts: ${publishedScriptsNumber}`;
  125. dailyInstallsText = `Total daily installations for all scripts: ${daily}`;
  126. totalInstallsText = `Total installations to date for all scripts: ${total}`;
  127. }
  128.  
  129. if (userHeader) {
  130. userHeader.insertAdjacentHTML('afterend', `
  131. <div>${publishedScriptsNumber}</div>
  132. <div>${dailyInstallsText}</div>
  133. <div>${totalInstallsText}</div>
  134. `);
  135. }
  136. };
  137.  
  138. // Function to fetch data and plot the chart
  139. const fetchDataAndPlot = () => {
  140. const userID = '1177387'; // Replace this with the desired user ID
  141. getUserData(userID)
  142. .then((data) => {
  143. const filteredScripts = data.scripts.filter(script => !script.deleted);
  144. const labels = filteredScripts.map(script => script.name);
  145. const totalInstalls = filteredScripts.map(script => script.total_installs);
  146. const dailyInstalls = filteredScripts.map(script => script.daily_installs);
  147. const totalDailyInstalls = dailyInstalls.reduce((sum, value) => sum + value, 0);
  148. const totalTotalInstalls = totalInstalls.reduce((sum, value) => sum + value, 0);
  149. const publishedScriptsNumber = filteredScripts.length;
  150.  
  151. plotDistribution(labels, totalInstalls, dailyInstalls);
  152. displayTotals(totalDailyInstalls, totalTotalInstalls, publishedScriptsNumber);
  153. })
  154. .catch((error) => console.error('Error fetching user data:', error));
  155. };
  156.  
  157. // Inject Chart.js and initiate data fetching and plotting
  158. injectChartJs();
  159. })();