您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a line chart to show price changes over time on Jellyneo's Price History page
// ==UserScript== // @name Insert Chart Above Price History (Beta) // @description Adds a line chart to show price changes over time on Jellyneo's Price History page // @version 0.1 // @license GNU GPLv3 // @match https://items.jellyneo.net/item/*/price-history/ // @author Posterboy // @icon https://images.neopets.com/new_shopkeepers/t_1900.gif // @namespace https://youtube.com/@Neo_Posterboy // @grant none // ==/UserScript== (function() { 'use strict'; // ============================== // Load External Resources // ============================== // Load Chart.js from CDN const script = document.createElement('script'); script.src = 'https://cdn.jsdelivr.net/npm/chart.js'; script.onload = () => initChart(); document.head.appendChild(script); // Initialize Chart and UI function initChart() { const container = document.querySelector('.pricing-row-container'); if (!container) return; const priceRows = container.querySelectorAll('.price-row'); const dataPoints = []; priceRows.forEach(row => { const priceText = row.childNodes[0].textContent.trim(); const dateText = row.querySelector('.price-date')?.textContent.trim(); const price = parseInt(priceText.replace(/,/g, '').replace('NP', '').trim()); const date = dateText?.replace('on ', '').trim(); if (!isNaN(price) && date) { dataPoints.push({ date, price }); } }); if (dataPoints.length === 0) return; dataPoints.sort((a, b) => new Date(a.date) - new Date(b.date)); const allLabels = dataPoints.map(dp => dp.date); const allPrices = dataPoints.map(dp => dp.price); // ============================== // UI Elements: Chart and Buttons // ============================== // Create a wrapper container for the UI const chartDivWrapper = document.createElement('div'); chartDivWrapper.style.border = '1px solid #ccc'; chartDivWrapper.style.borderRadius = '8px'; chartDivWrapper.style.marginBottom = '20px'; chartDivWrapper.style.padding = '15px'; chartDivWrapper.style.textAlign = 'center'; // Create the UI buttons const chartDiv = document.createElement('div'); const button3M = createButton('3 Months'); const button6M = createButton('6 Months'); const button1Y = createButton('1 Year'); const buttonMax = createButton('Max'); chartDiv.appendChild(button3M); chartDiv.appendChild(button6M); chartDiv.appendChild(button1Y); chartDiv.appendChild(buttonMax); // Create the chart canvas const canvas = document.createElement('canvas'); canvas.id = 'priceChart'; canvas.style.maxWidth = '100%'; canvas.style.margin = '20px auto'; canvas.style.display = 'block'; // Insert the UI elements into the wrapper container chartDivWrapper.appendChild(chartDiv); chartDivWrapper.appendChild(canvas); container.parentNode.insertBefore(chartDivWrapper, container); // Chart Configuration const chart = new Chart(canvas, { type: 'line', data: { labels: allLabels, datasets: [{ label: 'NP Price', data: allPrices, borderColor: 'rgb(75, 192, 192)', backgroundColor: 'rgba(75, 192, 192, 0.2)', tension: 0.2, fill: true, }] }, options: { scales: { y: { beginAtZero: false } }, plugins: { legend: { display: false } } } }); // Button Event Listeners button3M.addEventListener('click', () => updateChart(0.25)); button6M.addEventListener('click', () => updateChart(0.5)); button1Y.addEventListener('click', () => updateChart(1)); buttonMax.addEventListener('click', () => updateChart('max')); // Update Chart Data function updateChart(range) { let cutoff = new Date(); let filtered; if (range === 'max') { filtered = dataPoints; } else if (range === 0.25) { cutoff.setMonth(cutoff.getMonth() - 3); filtered = dataPoints.filter(dp => new Date(dp.date) >= cutoff); } else if (range === 0.5) { cutoff.setMonth(cutoff.getMonth() - 6); filtered = dataPoints.filter(dp => new Date(dp.date) >= cutoff); } else { cutoff.setFullYear(cutoff.getFullYear() - range); filtered = dataPoints.filter(dp => new Date(dp.date) >= cutoff); } chart.data.labels = filtered.map(dp => dp.date); chart.data.datasets[0].data = filtered.map(dp => dp.price); chart.update(); } // ============================== // Helper Functions // ============================== function createButton(label) { const btn = document.createElement('button'); btn.textContent = label; btn.style.margin = '0 5px'; btn.style.padding = '5px 10px'; btn.style.cursor = 'pointer'; btn.style.border = 'none'; btn.style.borderRadius = '4px'; btn.style.background = 'rgb(75, 192, 192)'; btn.style.color = 'white'; btn.style.fontSize = '12px'; btn.addEventListener('mouseenter', () => btn.style.background = 'rgb(60, 160, 160)'); btn.addEventListener('mouseleave', () => btn.style.background = 'rgb(75, 192, 192)'); return btn; } } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址