perf monitor 2.0 with dragging

This commit is contained in:
ChrisColeTech 2024-08-29 17:17:13 -04:00
parent 4c32ebe390
commit 5774787945
11 changed files with 1001 additions and 623 deletions

View File

@ -6,7 +6,6 @@ import zipfile
import importlib
import urllib.request
import re
import torch
re_requirement = re.compile(r"\s*([-\w]+)\s*(?:==\s*([-+.\w]+))?\s*")
@ -41,8 +40,6 @@ def check_tkinter_installed():
def check_GPUtil_installed():
if not torch.cuda.is_available():
return False
try:
import GPUtil
@ -53,8 +50,6 @@ def check_GPUtil_installed():
def check_flask_installed():
if not torch.cuda.is_available():
return False
try:
import flask
@ -137,12 +132,12 @@ def import_tkinter():
print(f"An error occurred: {e}")
except Exception as e:
print(f"An error occurred: {e}")
return None
def import_GPUtil():
run_pip(f"install GPUtil",desc="GPU Utility for NVIDIA GPUs")
run_pip(f"install GPUtil", desc="GPU Utility for NVIDIA GPUs")
try:
GPUtil = importlib.import_module(
@ -208,6 +203,6 @@ def run_pip(command, desc=None, live=default_command_live):
return None
check_tkinter_installed()
# check_tkinter_installed()
check_GPUtil_installed()
check_flask_installed()

18
api/gradio_helper.py Normal file
View File

@ -0,0 +1,18 @@
import gradio as gr
import os
from .http_server import *
def addResourceMonitor():
ceq = None
with gr.Row():
ceq = gr.HTML(load_page('templates/perf-monitor/index.html'))
return ceq
def load_page(filename):
"""Load an HTML file as a string and return it"""
file_path = os.path.join("web", filename)
with open(file_path, 'r') as file:
content = file.read()
return content

View File

@ -1,13 +1,13 @@
from .dependency_installer import *
from flask import Flask, send_from_directory, jsonify, render_template
from flask_restx import Api
import threading
import logging
from flask_cors import CORS
import args_manager
from .controllers import register_blueprints
import os
import gradio as gr
import shared
def load_page(filename):
"""Load an HTML file as a string and return it"""
@ -16,12 +16,6 @@ def load_page(filename):
content = file.read()
return content
def addResourceMonitor():
ceq = None
with gr.Row():
ceq = gr.HTML(load_page('templates/perf-monitor/index.html'))
return ceq
# Suppress the Flask development server warning
log = logging.getLogger('werkzeug')
@ -30,7 +24,8 @@ log.setLevel(logging.ERROR) # Set level to ERROR to suppress warnings
title = f"Elegant Resource Monitor"
app = Flask(title, static_folder='web/assets', template_folder='web/templates')
app.config['CORS_HEADERS'] = 'Content-Type'
api = Api(app, version='1.0', title=title, description='Elegant Resource Monitor REST API')
api = Api(app, version='1.0', title=title,
description='Elegant Resource Monitor REST API')
# Register blueprints (API endpoints)
register_blueprints(app, api)
@ -38,17 +33,11 @@ register_blueprints(app, api)
# Enable CORS for all origins
CORS(app, resources={r"/*": {"origins": "*"}})
gradio_app = shared.gradio_root
@app.route('/<path:filename>')
def serve_static(filename):
return send_from_directory('web', filename)
@app.route('/config')
def config():
return jsonify({
'base_url': f"http://{str(args_manager.args.listen)}:5000"
})
def run_app():
app.run(port=5000)

File diff suppressed because one or more lines are too long

View File

@ -1,14 +1,54 @@
#chart-button {
position: fixed !important;
transition: bottom 0.6s ease-in-out, right 0.6s ease-in-out, height 0.4s ease,
width 0.4s ease;
position: sticky;
transition: background-color 0.3s ease, width 0.8s ease, height 0.8s ease, transform 0.8s ease;
background-color: #00000096 !important;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2) !important;
color: white !important;
border-radius: 10px !important;
z-index: 9998;
bottom: 100px;
height: 0px !important;
-webkit-app-region: drag; /* Make this container draggable */
width: 100% !important;
height: 100% !important;
transform: scale(0);
-webkit-user-select: none; /* For Chrome, Safari, and Opera */
-moz-user-select: none; /* For Firefox */
-ms-user-select: none; /* For Internet Explorer and Edge */
user-select: none; /* Standard syntax */
}
#chart-button-container {
top: 0px;
left: 0px;
height: 0% !important;
width: 0% !important;
position: fixed;
z-index: 9;
will-change: transform;
text-align: center;
transition: width 0.8s ease, height 0.8s ease, transform 0.3s ease;
}
#mydivheader {
padding: 10px;
cursor: move;
z-index: 10;
background-color: #2196f3;
color: #fff;
}
body {
transition: all 0.3s ease;
}
#chart-button.small {
transform: scale(0.83);
}
#chart-button.medium {
transform: scale(0.93);
}
#chart-button.large {
transform: scale(0.96);
}
#chart-button.bottom-right {
@ -84,6 +124,10 @@
margin-bottom: -10px;
}
.chart-row.no-drag {
-webkit-app-region: no-drag; /* Make these elements non-draggable */
}
.chart-col {
flex: auto !important;
}
@ -105,61 +149,69 @@
#chart-container.bar.small {
padding: 5px !important;
height: 120px !important;
}
#chart-container.bar.medium {
padding: 5px !important;
height: 200px !important;
}
#chart-container.bar.large {
padding: 5px !important;
height: 420px !important;
}
#chart-container.line.small {
padding: 5px !important;
height: 107px !important;
}
#chart-container.line.medium {
padding: 5px !important;
height: 220px !important;
}
#chart-container.line.large {
padding: 5px !important;
height: 400px !important;
}
i {
color: #fff !important; /* Adjust color */
cursor: pointer !important; /* Change cursor to pointer on hover */
-webkit-app-region: no-drag; /* Make these elements non-draggable */
}
a,
button {
-webkit-app-region: no-drag; /* Make these elements non-draggable */
}
.toggle-resources-button:hover {
color: rgb(101, 101, 101) !important; /* Change color on hover */
}
.drag {
-webkit-app-region: drag; /* Make this container draggable */
}
.no-drag {
-webkit-app-region: no-drag; /* Make these elements non-draggable */
}
#settingsMenu {
display: grid !important; /* Show the menu */
position: absolute !important;
transform: translateX(-50%) !important; /* Center alignment */
transform: scale(0) translateX(-100%) translateY(-200%) !important; /* Center alignment */
background: #000000 !important;
border: 0px solid #ddd !important;
border-radius: 6px !important;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1) !important;
z-index: 1000 !important;
opacity: 0 !important;
transform: scale(0.8) translateY(-20px) !important; /* Initial hidden state */
transition: opacity 0.5s ease, transform 0.3s ease !important;
text-align: center;
-webkit-app-region: no-drag; /* Make these elements non-draggable */
}
#settingsMenu.show {
display: grid !important; /* Show the menu */
opacity: 1 !important;
transform: scale(1) translateY(0) !important; /* Animate to visible state */
z-index: 1000 !important;
transform: scale(0.8) translateY(-30px) translateX(-10px) !important; /* Animate to visible state */
}
.position-menu {
@ -262,3 +314,12 @@ i {
margin: 5px;
height: 14px;
}
body {
margin: 0px;
overflow: hidden;
}
/* Example CSS transition for smooth resizing */
.window {
transition: width 0.3s ease, height 0.3s ease;
}

View File

@ -1,50 +1,8 @@
window.barChart = function () {
checkForUpdates("active-chart", "bar");
updateChartSize();
};
window.lineChart = function () {
checkForUpdates("active-chart", "line");
updateChartSize();
};
window.smallChart = function () {
checkForUpdates("chart-size", "small");
updateChartSize();
};
window.mediumChart = function () {
checkForUpdates("chart-size", "medium");
updateChartSize();
};
window.largeChart = function () {
checkForUpdates("perf-monitor-position", "center");
checkForUpdates("chart-size", "large");
updateChartSize();
};
function checkForUpdates(key, value) {
var previous = localStorage.getItem(key);
var updated = previous != value;
localStorage.setItem("hasUpdates", updated);
localStorage.setItem(key, value);
}
const { hostname } = window.location; // Gets the host without port
// VARS AND CONST
const hostname = "localhost"; // Gets the host without port
const baseUrl = `http://${hostname}:5000`; // Append the port 5000
const apiUrl = `${baseUrl}/gpu_usage/`;
const chartContainer = document.getElementById("chart-container");
const chartWrapper = document.getElementById("chart-wrapper");
var styles = document.createElement("link");
styles.href =
"extensions/ComfyUI-Elegant-Resource-Monitor/assets/css/styles.css";
styles.property = "stylesheet";
styles.rel = "stylesheet";
document.head.appendChild(styles);
// Define your color palette
const colorPalette = [
"rgb(240, 193, 90, 0.2)",
"rgb(240, 142, 219, 0.2)",
@ -67,6 +25,9 @@ const borderColors = [
"rgb(159, 238, 209)",
];
let currentChart = null; // Track the current chart instance
const MAX_DATA_POINTS = 50; // Number of data points to keep
// Custom plugin to draw fixed labels in the middle of the chart area
const fixedLabelPlugin = {
id: "fixedLabelPlugin",
@ -83,11 +44,25 @@ const fixedLabelPlugin = {
labelPositions.push({
x: centerX,
y: yPos,
value: `${value.toFixed(2)}` + `${index == 5 ? "°" : "%"}`,
value: `${+value.toFixed(2)}` + `${index == 5 ? "\u00B0" : "%"}`,
});
});
const size = localStorage.getItem("chart-size") ?? "small";
let fontSize = 10; // Default font size
ctx.font = "8px Arial";
switch (size) {
case "small":
fontSize = "10px";
break;
case "medium":
fontSize = "16px";
break;
default:
fontSize = "18px";
break;
}
ctx.font = fontSize;
ctx.fillStyle = "#FFFFFF";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
@ -100,282 +75,6 @@ const fixedLabelPlugin = {
},
};
let currentChart = null; // Track the current chart instance
const MAX_DATA_POINTS = 50; // Number of data points to keep
function getSizes() {
const size = localStorage.getItem("chart-size") ?? "small";
const savedChart = localStorage.getItem("active-chart") ?? "bar";
var sizes = {};
if (savedChart == "bar") {
sizes = {
small: { height: "130", width: "180" },
medium: { height: "220", width: "340" },
large: { height: "440", width: "750" },
};
} else {
sizes = {
small: { height: "140", width: "200" },
medium: { height: "255", width: "425" },
large: { height: "450", width: "800" },
};
}
return sizes;
}
function updateButtonPosition() {
const size = localStorage.getItem("chart-size") ?? "small";
const sizes = getSizes();
const sizeStyles = sizes[size];
const buttonHeight = sizeStyles.height;
const buttonWidth = sizeStyles.width;
const viewportHeight = window.innerHeight;
const viewportWidth = window.innerWidth;
setButtonPosition(buttonHeight, buttonWidth, viewportHeight, viewportWidth);
}
function updateChartSize() {
const settingsMenu = document.getElementById("settingsMenu");
settingsMenu.classList.remove("show"); // Hide the menu if visible
const chartButton = document.getElementById("chart-button");
const size = localStorage.getItem("chart-size") ?? "small";
const savedChart = localStorage.getItem("active-chart") ?? "bar";
const chartContainer = document.getElementById("chart-container");
const sizes = getSizes();
chartContainer.classList.remove("small", "medium", "large", "bar", "line");
chartContainer.classList.add(size);
chartContainer.classList.add(savedChart);
const sizeStyles = sizes[size];
const buttonHeight = sizeStyles.height;
const buttonWidth = sizeStyles.width;
$(chartButton).each(function () {
this.style.setProperty("height", `${buttonHeight}px`, "important");
this.style.setProperty("width", `${buttonWidth}px`, "important");
if (size === "large") {
this.style.setProperty("background-color", ` #000000d6`, "important");
} else {
this.style.setProperty("background-color", ` #00000096`, "important");
}
});
updateButtonPosition();
const hasUpdates = localStorage.getItem("hasUpdates") ?? "false";
if (hasUpdates === "true") {
if (savedChart == "bar") {
initializeBarChart();
} else {
initializeLineChart();
}
}
}
function setButtonPosition(
buttonHeight,
buttonWidth,
viewportHeight,
viewportWidth
) {
const positions = {
"bottom-right": { bottom: "10px", right: "10px" },
"bottom-left": {
bottom: "10px",
right: `${viewportWidth - buttonWidth - 10}px`,
},
"bottom-center": {
bottom: "10px",
right: `${(viewportWidth - buttonWidth) / 2}px`,
},
"top-right": {
bottom: `${viewportHeight - buttonHeight - 10}px`,
right: "10px",
},
"top-left": {
bottom: `${viewportHeight - buttonHeight - 10}px`,
right: `${viewportWidth - buttonWidth - 10}px`,
},
"top-center": {
bottom: `${viewportHeight - buttonHeight - 10}px`,
right: `${(viewportWidth - buttonWidth) / 2}px`,
},
"left-center": {
bottom: `${(viewportHeight - buttonHeight) / 2}px`,
right: `${viewportWidth - buttonWidth - 10}px`,
},
"right-center": {
bottom: `${(viewportHeight - buttonHeight) / 2}px`,
right: "10px",
},
center: {
bottom: `${(viewportHeight - buttonHeight) / 2}px`,
right: `${(viewportWidth - buttonWidth) / 2}px`,
},
};
// Get the saved position
const savedPosition =
localStorage.getItem("perf-monitor-position") || "bottom-right";
const chartButton = document.getElementById("chart-button");
const existingClasses = [
"bottom-right",
"bottom-left",
"bottom-center",
"top-right",
"top-left",
"top-center",
"left-center",
"right-center",
"center",
];
existingClasses.forEach((cls) => {
chartButton.classList.remove(cls);
});
chartButton.classList.add(savedPosition);
const active = `#chart-button.${savedPosition}.active`;
const positionStyles = positions[savedPosition];
var lastClass = {
key: active,
values: [
{
bottom: positionStyles.bottom,
right: positionStyles.right,
},
],
};
var lastClassString = JSON.stringify(lastClass);
localStorage.setItem("lastClass", lastClassString);
updateCSS(active, positionStyles);
const inactive = `#chart-button.${savedPosition}`;
const inactiveStyles = {
buttonHeight: buttonHeight,
buttonWidth: buttonWidth,
viewportHeight: viewportHeight,
viewportWidth: viewportWidth,
};
updateinActiveCSS(inactive, inactiveStyles, savedPosition);
}
function updateinActiveCSS(selector, styles, key) {
var button = getCSSRule(selector);
var style = {
bottom: "auto",
right: "auto",
};
var buttonHeight = +styles.buttonHeight;
var buttonWidth = +styles.buttonWidth;
var viewportHeight = +styles.viewportHeight;
var viewportWidth = +styles.viewportWidth;
switch (key) {
case "bottom-right":
style.bottom = "10px";
style.right = `-${buttonWidth + 210}px`;
break;
case "bottom-left":
style.bottom = "10px";
style.right = `calc(100vw + ${buttonWidth + 210}px)`;
break;
case "bottom-center":
style.bottom = `-${buttonHeight + 210}px`;
style.right = `${(viewportWidth - buttonWidth) / 2}px`;
break;
case "top-right":
style.bottom = `${viewportHeight - buttonHeight - 10}px`;
style.right = `-${buttonWidth + 210}px`;
break;
case "top-left":
style.bottom = `${viewportHeight - buttonHeight - 10}px`;
style.right = `calc(100vw + ${buttonWidth + 210}px)`;
break;
case "top-center":
style.bottom = `calc(100vh + 30px + ${buttonHeight + 210}px)`;
style.right = `${(viewportWidth - buttonWidth) / 2}px`;
break;
case "left-center":
style.bottom = `${(viewportHeight - buttonHeight) / 2}px`;
style.right = `calc(100vw + ${buttonWidth + 210}px)`;
break;
case "right-center":
style.bottom = `${(viewportHeight - buttonHeight) / 2}px`;
style.right = `-${buttonWidth + 210}px`;
break;
case "center":
style.bottom = `calc(0vh - 30px - ${buttonHeight + 210}px)`;
style.right = `${(viewportWidth - buttonWidth) / 2}px`;
break;
default:
break;
}
button.style.setProperty("bottom", style.bottom, "important");
button.style.setProperty("right", style.right, "important");
var lastClass = {
key: selector,
values: [
{
bottom: style.bottom,
right: style.right,
},
],
};
var lastClassString = JSON.stringify(lastClass);
localStorage.setItem("lastInactiveClass", lastClassString);
}
function updateCSS(selector, styles) {
var button = getCSSRule(selector);
button.style.setProperty("bottom", styles.bottom, "important");
button.style.setProperty("right", styles.right, "important");
}
function getCSSRule(ruleName) {
ruleName = ruleName.toLowerCase();
var result = null;
var find = Array.prototype.find;
Array.prototype.find.call(document.styleSheets, (styleSheet) => {
try {
if (styleSheet.cssRules) {
result = find.call(styleSheet.cssRules, (cssRule) => {
return (
cssRule instanceof CSSStyleRule &&
cssRule.selectorText.toLowerCase() == ruleName
);
});
}
} catch (e) {
// Handle cross-origin or other access errors
// console.info("Cannot access cssRules for stylesheet:", e);
}
return result != null;
});
return result;
}
let intervalId; // Variable to store the interval ID
// Function to start the interval
function startInterval() {
intervalId = setInterval(updateUsage, 500);
}
// Function to stop the interval
function stopInterval() {
if (intervalId) {
clearInterval(intervalId);
intervalId = null; // Optional: Reset intervalId to indicate no active interval
}
}
// Initialize the bar chart
function initializeBarChart() {
localStorage.setItem("active-chart", "bar");
@ -385,6 +84,20 @@ function initializeBarChart() {
if (existingCanvas) {
chartContainer.removeChild(existingCanvas);
}
const size = localStorage.getItem("chart-size") ?? "small";
let fontSize = 10; // Default font size
switch (size) {
case "small":
fontSize = "10px";
break;
case "medium":
fontSize = "16px";
break;
default:
fontSize = "18px";
break;
}
// Create a new canvas element
const newCanvas = document.createElement("canvas");
@ -432,7 +145,7 @@ function initializeBarChart() {
ticks: {
color: "#ffffff",
font: {
size: 7,
size: fontSize,
weight: 600,
},
align: "center",
@ -454,15 +167,13 @@ function initializeBarChart() {
crossAlign: "far",
font: {
weight: 600,
size: fontSize,
},
// Specify the maximum number of ticks to show
maxTicksLimit: 10,
// Control the step size between ticks
stepSize: 1,
// Optional: Set font size and other style properties
font: {
size: 7,
},
},
},
},
@ -485,6 +196,12 @@ function initializeBarChart() {
legendContainer.innerHTML = "";
document.getElementById("settingsMenu").classList.remove("show"); // Hide the menu
document.querySelectorAll("canvas").forEach((row) => {
row.classList.remove("no-drag");
row.classList.add("drag");
});
window.addEventListener("resize", () => {
currentChart.resize();
});
@ -510,8 +227,6 @@ function initializeLineChart() {
const ctx = newCanvas.getContext("2d");
// ctx.width = "225px";
// ctx.height = "125px";
currentChart = new Chart(ctx, {
type: "line",
data: {
@ -762,8 +477,19 @@ function generateCustomLegend() {
? "#D9534F"
: `${borderColors[index]}`;
legendText.style.fontWeight = shouldUseRed ? "700" : `400`;
legendText.style.fontSize = "10px";
legendText.style.fontWeight = shouldUseRed ? "800" : `600`;
const size = localStorage.getItem("chart-size") ?? "small";
switch (size) {
case "small":
legendText.style.fontSize = "10px";
break;
case "medium":
legendText.style.fontSize = "16px";
break;
default:
legendText.style.fontSize = "18px";
break;
}
legendItem.appendChild(legendText);
legendContainer.appendChild(legendItem);
@ -812,119 +538,15 @@ async function updateUsage() {
}
}
// Show or hide the settings menu when the settings icon is clicked
document
.getElementById("popupTrigger")
.addEventListener("click", function (event) {
const settingsMenu = document.getElementById("settingsMenu");
settingsMenu.classList.toggle("show"); // Toggle the 'show' class for animation
setTimeout(() => {
const settingsMenuHr = document.getElementById("settings-hr");
settingsMenuHr.classList.add("show"); // Toggle the 'show' class for animation
}, 300);
event.stopPropagation();
});
// Hide the settings menu when the close button is clicked
document.getElementById("close-button").addEventListener("click", function () {
document.getElementById("settingsMenu").classList.remove("show"); // Hide the menu
showPerfMonitor();
});
// Hide the settings menu when clicking outside
window.addEventListener("click", function (e) {
const settingsMenu = document.getElementById("settingsMenu");
const trigger = document.getElementById("popupTrigger");
if (!settingsMenu.contains(e.target) && e.target !== trigger) {
settingsMenu.classList.remove("show"); // Hide the menu if clicking outside
}
});
document.querySelectorAll(".position-clickable").forEach((button) => {
button.addEventListener("click", function () {
const position = this.id;
localStorage.setItem("perf-monitor-position", position);
updateButtonPosition();
const settingsMenu = document.getElementById("settingsMenu");
settingsMenu.classList.remove("show"); // Hide the menu if visible
});
});
const perfMonitordisplayed = JSON.parse(
localStorage.getItem("shouldShowPerfMonitor")
);
if (perfMonitordisplayed == true) {
updateButtonPosition();
setTimeout(() => {
showPerfMonitor();
}, 1000);
let intervalId; // Variable to store the interval ID
// Function to start the interval
function startInterval() {
intervalId = setInterval(updateUsage, 500);
}
var shouldShowPerfMonitor = false;
window.showPerfMonitor = function () {
// Set the initial position based on localStorage
updateChartSize();
shouldShowPerfMonitor = !shouldShowPerfMonitor;
localStorage.setItem("shouldShowPerfMonitor", shouldShowPerfMonitor);
const chartButton = document.getElementById("chart-button");
const show_resource_monitor = document.getElementById(
"show_resource_monitor"
);
if (shouldShowPerfMonitor === true) {
const savedChart = localStorage.getItem("active-chart") ?? "bar";
setTimeout(() => {
if (savedChart == "bar") {
initializeBarChart();
} else {
initializeLineChart();
}
}, 100);
startInterval();
$(show_resource_monitor).fadeOut();
} else {
setTimeout(() => {
stopInterval();
}, 500);
$(chartButton).each(function () {
this.style.setProperty("height", `${0}px`, "important");
});
$(chartWrapper).hide();
$(show_resource_monitor).fadeIn();
// Function to stop the interval
function stopInterval() {
if (intervalId) {
clearInterval(intervalId);
intervalId = null; // Optional: Reset intervalId to indicate no active interval
}
$(chartButton).toggleClass("active");
};
document.getElementById("popupTrigger").addEventListener("click", function () {
const menu = document.getElementById("settingsMenu");
const menuRect = menu.getBoundingClientRect();
const buttonRect = this.getBoundingClientRect();
const viewportHeight = window.innerHeight;
if (menu.offsetTop < 0) {
menu.style.position = "absolute"; // Ensure the menu is positioned absolutely
menu.style.top = `29px`;
}
// Default position: directly below the button
let topPosition = buttonRect.bottom;
// Calculate if the menu will overflow the bottom of the viewport
if (topPosition + menuRect.height > viewportHeight) {
// Calculate how much the menu overflows the viewport
const overflowAmount = topPosition + menuRect.height - viewportHeight;
// Apply the calculated position
menu.style.position = "absolute"; // Ensure the menu is positioned absolutely
menu.style.top = `-${overflowAmount}px`;
}
});
}

View File

@ -1,106 +1,97 @@
var footer = document.querySelector("footer");
var link = document.createElement("a");
var footer = document.querySelector('footer')
var link = document.createElement('a')
// Add multiple classes correctly using the spread operator
link.classList.add("built-with", "svelte-1ax1toq");
link.id = "show_resource_monitor";
link.text = "Resource Monitor";
link.classList.add('built-with', 'svelte-1ax1toq')
link.id = 'show_resource_monitor'
link.text = 'Resource Monitor'
link.onclick = function () {
showPerfMonitor();
}; // Use function reference instead of string
showPerfMonitor()
} // Use function reference instead of string
var linkImg = document.createElement("img");
linkImg.src = "/file=web/assets/img/monitor.svg";
linkImg.classList.add("svelte-1ax1toq");
link.appendChild(linkImg);
footer.appendChild(link);
var linkImg = document.createElement('img')
linkImg.src = '/file=web/assets/img/monitor.svg'
linkImg.classList.add('svelte-1ax1toq')
link.appendChild(linkImg)
footer.appendChild(link)
var script = document.createElement("script");
script.src = "/file=web/assets/js/jquery-3.7.1.min.js";
document.body.appendChild(script);
var script = document.createElement('script')
script.src = '/file=web/assets/js/jquery-3.7.1.min.js'
document.body.appendChild(script)
var script = document.createElement("script");
script.src = "/file=web/assets/js/chart.js";
document.body.appendChild(script);
var script = document.createElement('script')
script.src = '/file=web/assets/js/chart.js'
document.body.appendChild(script)
var fa = document.createElement("link");
fa.href = "/file=web/assets/css/material-icon.css";
fa.property = "stylesheet";
fa.rel = "stylesheet";
document.body.appendChild(fa);
var fa = document.createElement('link')
fa.href = '/file=web/assets/css/material-icon.css'
fa.property = 'stylesheet'
fa.rel = 'stylesheet'
document.body.appendChild(fa)
var styles = document.createElement("link");
styles.href = "/file=web/assets/css/styles.css";
styles.property = "stylesheet";
styles.rel = "stylesheet";
document.body.appendChild(styles);
var styles = document.createElement('link')
styles.href = '/file=web/assets/css/styles.css'
styles.property = 'stylesheet'
styles.rel = 'stylesheet'
document.body.appendChild(styles)
styles.onload = async function () {
if (
localStorage.getItem("lastClass") &&
localStorage.getItem("lastInactiveClass")
) {
var lastClass = JSON.parse(localStorage.getItem("lastClass"));
var lastInactiveClass = JSON.parse(
localStorage.getItem("lastInactiveClass")
);
addCSS(lastInactiveClass.key, lastInactiveClass.values[0]);
addCSS(lastClass.key, lastClass.values[0]);
if (localStorage.getItem('lastClass') && localStorage.getItem('lastInactiveClass')) {
var lastClass = JSON.parse(localStorage.getItem('lastClass'))
var lastInactiveClass = JSON.parse(localStorage.getItem('lastInactiveClass'))
addCSS(lastInactiveClass.key, lastInactiveClass.values[0])
addCSS(lastClass.key, lastClass.values[0])
}
function getCSSRule(ruleName) {
ruleName = ruleName.toLowerCase();
var result = null;
var find = Array.prototype.find;
ruleName = ruleName.toLowerCase()
var result = null
var find = Array.prototype.find
Array.prototype.find.call(document.styleSheets, (styleSheet) => {
try {
if (styleSheet.cssRules) {
result = find.call(styleSheet.cssRules, (cssRule) => {
return (
cssRule instanceof CSSStyleRule &&
cssRule.selectorText.toLowerCase() == ruleName
);
});
return cssRule instanceof CSSStyleRule && cssRule.selectorText.toLowerCase() == ruleName
})
}
} catch (e) {
// Handle cross-origin or other access errors
// console.info("Cannot access cssRules for stylesheet:", e);
}
return result != null;
});
return result;
return result != null
})
return result
}
function addCSS(selector, styles) {
var rule = getCSSRule(selector);
var rule = getCSSRule(selector)
for (var property in styles) {
if (styles.hasOwnProperty(property)) {
rule.style.setProperty(property, styles[property], "important");
rule.style.setProperty(property, styles[property], 'important')
}
}
}
async function loadHtmlContent() {
const response = await fetch(
"/file=web/templates/perf-monitor/perf-monitor.html"
);
var resourceMonitorContent = document.getElementById(
"perf-monitor-container"
);
resourceMonitorContent.innerHTML = await response.text();
const chartButton = resourceMonitorContent.querySelector("#chart-button");
const savedPosition =
localStorage.getItem("perf-monitor-position") || "bottom-right";
const response = await fetch('/file=web/templates/perf-monitor/perf-monitor.html')
var resourceMonitorContent = document.getElementById('perf-monitor-container')
resourceMonitorContent.innerHTML = await response.text()
const chartButton = resourceMonitorContent.querySelector('#chart-button')
const savedPosition = localStorage.getItem('perf-monitor-position') || 'bottom-right'
if (chartButton) {
// Set the savedPosition class on the #chart-button element
chartButton.classList.add(savedPosition);
chartButton.classList.add(savedPosition)
}
var script = document.createElement("script");
script.src = "/file=web/assets/js/perf-monitor.js";
document.body.appendChild(script);
var script = document.createElement('script')
script.src = '/file=web/assets/js/script.js'
document.body.appendChild(script)
var chart = document.createElement('script')
chart.src = '/file=web/assets/js/chart-settings.js'
document.body.appendChild(chart)
}
await loadHtmlContent();
};
await loadHtmlContent()
}

709
web/assets/js/script.js Normal file
View File

@ -0,0 +1,709 @@
dragElement(document.getElementById('chart-button-container'))
var wasDragged = false
function dragElement(elmnt) {
var isDragging = false
var pos1 = 0,
pos2 = 0,
pos3 = 0,
pos4 = 0
// otherwise, move the DIV from anywhere inside the DIV:
elmnt.onmousedown = dragMouseDown
function dragMouseDown(e) {
e = e || window.event
e.preventDefault()
// get the mouse cursor position at startup:
pos3 = e.clientX
pos4 = e.clientY
document.onmouseup = closeDragElement
// call a function whenever the cursor moves:
document.onmousemove = elementDrag
elmnt.style.cursor = 'grabbing'
}
function elementDrag(e) {
e = e || window.event
e.preventDefault()
// calculate the new cursor position:
pos1 = pos3 - e.clientX
pos2 = pos4 - e.clientY
pos3 = e.clientX
pos4 = e.clientY
// set the element's new position:
wasDragged = true
isDragging = true
elmnt.style.top = elmnt.offsetTop - pos2 + 'px'
elmnt.style.left = elmnt.offsetLeft - pos1 + 'px'
}
function closeDragElement() {
// stop moving when mouse button is released:
document.onmouseup = null
document.onmousemove = null
elmnt.style.transition = 'transform .7s ease-in-out'
elmnt.style.cursor = 'grab'
setTimeout(() => {
if (!isDragging) {
elmnt.style.cursor = 'auto'
}
}, 1000)
isDragging = false
getNearestPosition()
}
}
function moveButtonToCenter(duration = 300) {
const widget = document.getElementById('chart-button-container')
const size = localStorage.getItem('chart-size') ?? 'small'
const sizes = getSizes()
const sizeStyles = sizes[size]
const buttonHeight = +sizeStyles.height + 25
const buttonWidth = +sizeStyles.width + 25
// Get button dimensions and viewport dimensions
const widgetWidth = buttonWidth
const widgetHeight = buttonHeight
const viewportWidth = window.innerWidth
const viewportHeight = window.innerHeight
// Calculate center of the viewport
const windowCenterX = viewportWidth / 2
const windowCenterY = viewportHeight / 2
// Calculate button center
const buttonCenterX = widgetWidth / 2
const buttonCenterY = widgetHeight / 2
// Calculate the translation offsets needed to center the button
const posx = windowCenterX - buttonCenterX
const posy = windowCenterY - buttonCenterY
goToPosition({ x: posx, y: posy })
}
// Call the function to move the button
// HELPER FUNCTIONS //
if (localStorage.getItem('lastClass') && localStorage.getItem('lastInactiveClass')) {
var lastClass = JSON.parse(localStorage.getItem('lastClass'))
var lastInactiveClass = JSON.parse(localStorage.getItem('lastInactiveClass'))
addCSS(lastInactiveClass.key, lastInactiveClass.values[0])
addCSS(lastClass.key, lastClass.values[0])
}
function getCSSRule(ruleName) {
ruleName = ruleName.toLowerCase()
var result = null
var find = Array.prototype.find
Array.prototype.find.call(document.styleSheets, (styleSheet) => {
try {
if (styleSheet.cssRules) {
result = find.call(styleSheet.cssRules, (cssRule) => {
return cssRule instanceof CSSStyleRule && cssRule.selectorText.toLowerCase() == ruleName
})
}
} catch (e) {
// Handle cross-origin or other access errors
// console.info("Cannot access cssRules for stylesheet:", e);
}
return result != null
})
return result
}
function addCSS(selector, styles) {
var rule = getCSSRule(selector)
for (var property in styles) {
if (styles.hasOwnProperty(property)) {
rule.style.setProperty(property, styles[property], 'important')
}
}
}
function updateCSS(selector, styles) {
var button = getCSSRule(selector)
button.style.setProperty('bottom', styles.bottom, 'important')
button.style.setProperty('right', styles.right, 'important')
}
window.barChart = async function () {
checkForUpdates('active-chart', 'bar')
await updateChartSize()
}
window.lineChart = async function () {
checkForUpdates('active-chart', 'line')
await updateChartSize()
}
window.smallChart = async function () {
checkForUpdates('chart-size', 'small')
await updateChartSize()
}
window.mediumChart = async function () {
checkForUpdates('chart-size', 'medium')
await updateChartSize()
}
window.largeChart = async function () {
setTimeout(async () => {
checkForUpdates('perf-monitor-position', 'center')
await updateChartSize()
}, 50)
checkForUpdates('chart-size', 'large')
}
function moveToCenter() {
if (localStorage.getItem('perf-monitor-position') === 'center') {
moveButtonToCenter(150)
}
}
function checkForUpdates(key, value) {
var previous = localStorage.getItem(key)
var updated = previous != value
localStorage.setItem('hasUpdates', updated)
localStorage.setItem(key, value)
}
function isWindowOutsideWorkingArea() {
const size = localStorage.getItem('chart-size') ?? 'small'
const sizes = getSizes()
const sizeStyles = sizes[size]
const buttonHeight = +sizeStyles.height + 25
const buttonWidth = +sizeStyles.width + 25
// Get display bounds
const { displayBounds, windowBounds } = getDisplayAndWindowBounds()
const widget = document.getElementById('chart-button-container')
const rect = widget.getBoundingClientRect()
const currentTop = rect.top + window.scrollY
const currentLeft = rect.left + window.scrollX
const windowLeft = currentLeft
const windowTop = currentTop
const windowRight = windowLeft + buttonWidth
const windowBottom = windowTop + buttonHeight
const displayLeft = 0
const displayTop = 0
const displayRight = displayLeft + displayBounds.width
const displayBottom = displayTop + displayBounds.height
let isOutside =
windowLeft < displayLeft ||
windowTop < displayTop ||
windowRight > displayRight ||
windowBottom > displayBottom
if (isOutside) {
console.log('The window is outside the working area.')
} else {
console.log('The window is within the working area.')
}
return isOutside
}
function getSizes() {
const savedChart = localStorage.getItem('active-chart') ?? 'bar'
var sizes = {}
if (savedChart == 'bar') {
sizes = {
small: { height: '120', width: '150' },
medium: { height: '300', width: '410' },
large: { height: '450', width: '700' },
}
} else {
sizes = {
small: { height: '110', width: '160' },
medium: { height: '245', width: '425' },
large: { height: '380', width: '700' },
}
}
return sizes
}
// SETTINGS MENU //
// POSITIONS BUTTONS
document.querySelectorAll('.position-clickable').forEach((button) => {
button.addEventListener('click', async function () {
const position = this.id
wasDragged = false
localStorage.setItem('perf-monitor-position', position)
//the position we should be going to
const pos = getCoordinates(false)
if (pos) {
goToPosition(pos)
} else {
console.error('Invalid position:', pos)
}
// Optionally hide the settings menu and adjust UI
const settingsMenu = document.getElementById('settingsMenu')
settingsMenu.classList.remove('show') // Hide the menu if visible
document.querySelectorAll('.chart-row').forEach((row) => {
row.classList.remove('no-drag')
row.classList.add('drag')
})
})
})
// Show or hide the settings menu when the settings icon is clicked
document.getElementById('popupTrigger').addEventListener('click', function (event) {
const settingsMenu = document.getElementById('settingsMenu')
settingsMenu.classList.toggle('show') // Toggle the 'show' class for animation
document.querySelectorAll('.chart-row').forEach((row) => {
row.classList.add('no-drag')
row.classList.remove('drag')
})
document.querySelectorAll('canvas').forEach((row) => {
row.classList.add('no-drag')
row.classList.remove('drag')
})
setTimeout(() => {
const settingsMenuHr = document.getElementById('settings-hr')
settingsMenuHr.classList.add('show') // Toggle the 'show' class for animation
}, 300)
event.stopPropagation()
})
// Hide the settings menu when clicking outside
window.addEventListener('click', function (e) {
if (e.target.className.includes('settings')) {
return
}
const settingsMenu = document.getElementById('settingsMenu')
const trigger = document.getElementById('popupTrigger')
if (!settingsMenu.contains(e.target) && e.target !== trigger) {
settingsMenu.classList.remove('show') // Hide the menu if clicking outside
}
document.querySelectorAll('canvas').forEach((row) => {
row.classList.remove('no-drag')
row.classList.add('drag')
})
document.querySelectorAll('.chart-row').forEach((row) => {
row.classList.remove('no-drag')
row.classList.add('drag')
})
})
// Calculate if the menu will overflow the bottom of the viewport
document.getElementById('popupTrigger').addEventListener('click', function () {
const menu = document.getElementById('settingsMenu')
const menuRect = menu.getBoundingClientRect()
const buttonRect = this.getBoundingClientRect()
const viewportHeight = window.innerHeight
if (menu.offsetTop < 0) {
menu.style.position = 'absolute'
menu.style.top = `29px`
}
let topPosition = buttonRect.bottom
if (topPosition + menuRect.height > viewportHeight) {
// Calculate how much the menu overflows the viewport
const overflowAmount = topPosition + menuRect.height - viewportHeight
// Apply the calculated position
menu.style.position = 'absolute' // Ensure the menu is positioned absolutely
menu.style.top = `-${overflowAmount}px`
}
})
function goToPosition(pos) {
const widget = document.getElementById('chart-button-container')
// Set transition for smooth animation
// widget.style.transition = 'transform .7s ease-in-out'
widget.style.transition = `top .4s ease, left .4s ease`
const currentTop = +widget.style.top.replace('px', '')
const currentLeft = +widget.style.left.replace('px', '')
// Target position
const targetTop = pos.y
const targetLeft = pos.x
const offsetX = pos.x - currentLeft
const offsetY = pos.y - currentTop
// Set transition duration and easing
widget.style.transition = `transform .7s ease-in-out`
// Animate to the center
widget.style.transform = `translate(${offsetX}px, ${offsetY}px)`
}
// MAIN METHODS //
function getDisplayAndWindowBounds() {
const screenWidth = window.screen.width
const screenHeight = window.screen.height
const availWidth = window.screen.availWidth
const availHeight = window.screen.availHeight
// Assume work area starts at (0, 0)
// Work area dimensions approximate available screen area minus some margins
const workArea = {
x: 0, // Typically starts at (0, 0)
y: 0, // Typically starts at (0, 0)
width: availWidth,
height: availHeight,
}
const displayBounds = {
width: window.screen.width,
height: window.screen.height,
availableWidth: window.screen.availWidth,
availableHeight: window.screen.availHeight,
workArea,
}
const windowBounds = {
width: window.innerWidth,
height: window.innerHeight,
}
return { displayBounds, windowBounds }
}
function getPositions() {
const size = localStorage.getItem('chart-size') ?? 'small'
const sizes = getSizes()
const sizeStyles = sizes[size]
const buttonHeight = +sizeStyles.height + 25
const buttonWidth = +sizeStyles.width + 25
// Get button dimensions and viewport dimensions
const widgetWidth = buttonWidth
const widgetHeight = buttonHeight
const viewportWidth = window.innerWidth
const viewportHeight = window.innerHeight
// Calculate center of the viewport
const windowCenterX = viewportWidth / 2
const windowCenterY = viewportHeight / 2
// Calculate button center
const buttonCenterX = widgetWidth / 2
const buttonCenterY = widgetHeight / 2
// Calculate the translation offsets needed to center the button
const offsetX = windowCenterX - buttonCenterX
const offsetY = windowCenterY - buttonCenterY
// Define positions based on work area
const positions = {
'bottom-right': {
x: viewportWidth - widgetWidth - 10,
y: viewportHeight - widgetHeight - 10,
},
'bottom-left': {
x: 10,
y: viewportHeight - widgetHeight - 10,
},
'bottom-center': {
x: (viewportWidth - widgetWidth) / 2,
y: viewportHeight - widgetHeight - 10,
},
'top-right': {
x: viewportWidth - widgetWidth - 10,
y: 10,
},
'top-left': { x: 10, y: 10 },
'top-center': {
x: (viewportWidth - widgetWidth) / 2,
y: 10,
},
'left-center': {
x: 10,
y: windowCenterY - buttonCenterY,
},
'right-center': {
x: viewportWidth - widgetWidth - 10,
y: windowCenterY - buttonCenterY,
},
center: {
x: (viewportWidth - widgetWidth) / 2,
y: windowCenterY - buttonCenterY,
},
}
return positions
}
function getCoordinates(isOutside) {
var position = localStorage.getItem('perf-monitor-position')
if (isOutside) {
var outsidePosition = getNearestPosition()
return outsidePosition
}
const positions = getPositions()
const pos = positions[position]
return pos
}
function getNearestPosition() {
const size = localStorage.getItem('chart-size') ?? 'small'
const sizes = getSizes()
const sizeStyles = sizes[size]
const buttonHeight = +sizeStyles.height + 25
const buttonWidth = +sizeStyles.width + 25
const widget = document.getElementById('chart-button-container')
const viewportWidth = window.innerWidth
const viewportHeight = window.innerHeight
// Get display bounds
const { displayBounds, windowBounds } = getDisplayAndWindowBounds()
// Define positions based on work area
const positions = getPositions()
// Get current window position
const currentX = $(widget).offset().left
let currentY = $(widget).offset().top
const buttonCenterX = buttonWidth / 2
const buttonCenterY = buttonHeight / 2
const windowCenter = {
x: $(widget).offset().left,
y: $(widget).offset().top,
}
const workAreaCenter = {
x: viewportWidth / 2,
y: viewportHeight / 2,
}
const distanceToCenter = {
x: Math.abs(workAreaCenter.x - windowCenter.x),
y: Math.abs(workAreaCenter.y - windowCenter.y),
}
var threshold = 100 // Define a threshold to determine proximity
switch (size) {
case 'small':
threshold = 250
break
case 'medium':
threshold = 200
default:
threshold = 150
break
}
if (distanceToCenter.x < threshold && distanceToCenter.y < threshold) {
nearestPosition = 'center'
} else {
// Function to calculate distance
function calculateDistance(x1, y1, x2, y2) {
return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
}
// Find the nearest position
let minDistance = Infinity
for (const [key, pos] of Object.entries(positions)) {
// Adjust for edge cases
const adjustedPosX = Math.max(
displayBounds.workArea.x,
Math.min(pos.x, displayBounds.width - buttonWidth),
)
const adjustedPosY = Math.max(
displayBounds.workArea.y,
Math.min(pos.y, displayBounds.height - buttonHeight),
)
const distance = calculateDistance(currentX, currentY, adjustedPosX, adjustedPosY)
if (distance < minDistance) {
minDistance = distance
nearestPosition = key
}
}
}
// Output or use the nearest position
console.log('Nearest position:', nearestPosition)
// Set the position
const pos = positions[nearestPosition]
localStorage.setItem('perf-monitor-position', nearestPosition)
return pos
}
async function updateChartSize() {
const settingsMenu = document.getElementById('settingsMenu')
settingsMenu.classList.remove('show') // Hide the menu if visible
$('#chart-wrapper').fadeOut()
document.querySelectorAll('.chart-row').forEach((row) => {
row.classList.remove('no-drag')
row.classList.add('drag')
})
document.querySelectorAll('canvas').forEach((row) => {
row.classList.remove('no-drag')
row.classList.add('drag')
})
const size = localStorage.getItem('chart-size') ?? 'small'
const chartContainer = document.getElementById('chart-container')
const savedChart = localStorage.getItem('active-chart') ?? 'bar'
chartContainer.classList.remove('small', 'medium', 'large', 'bar', 'line')
chartContainer.classList.add(size)
chartContainer.classList.add(savedChart)
const sizes = getSizes()
const sizeStyles = sizes[size]
const buttonHeight = +sizeStyles.height
const buttonWidth = +sizeStyles.width
const chartButtonContainer = document.getElementById('chart-button-container')
$(chartButtonContainer).each(function () {
this.style.setProperty('height', `${+buttonHeight + 25}px`, 'important')
this.style.setProperty('width', `${+buttonWidth + 25}px`, 'important')
})
var position = localStorage.getItem('perf-monitor-position')
if (position === 'center') {
moveToCenter()
} else {
const isOutside = isWindowOutsideWorkingArea()
const pos = getCoordinates(isOutside)
if (pos && isOutside && wasDragged) {
goToPosition(pos)
} else if (pos && !wasDragged) {
goToPosition(pos)
} else {
// do nothing
}
}
var sizeClasses = ['small', 'medium', 'large']
const chartButton = document.getElementById('chart-button')
chartButton.classList.add(size)
sizeClasses.forEach((prop) => {
if (prop != size) {
setTimeout(() => {
chartButton.classList.remove(prop)
}, 500)
}
})
var actulaButtonHeight = 0
viewportHeight = +buttonHeight + 25
viewportWidth = +buttonWidth + 25
switch (size) {
case 'small':
actulaButtonHeight = viewportHeight * 0.83
actualButtonWidth = viewportWidth * 0.83
break
case 'medium':
actulaButtonHeight = viewportHeight * 0.93
actualButtonWidth = viewportWidth * 0.93
break
default:
actulaButtonHeight = viewportHeight * 0.96
actualButtonWidth = viewportWidth * 0.96
break
}
const bottom = `12.5px`
const right = `12.5px`
$(chartButton).each(function () {
this.style.setProperty('bottom', bottom, 'important')
this.style.setProperty('right', right, 'important')
if (size === 'large') {
this.style.setProperty('background-color', ` #000000d6`, 'important')
} else {
this.style.setProperty('background-color', ` #00000096`, 'important')
}
})
const hasUpdates = localStorage.getItem('hasUpdates') ?? 'false'
if (hasUpdates === 'true') {
if (savedChart == 'bar') {
$(chartContainer).each(function () {
this.style.setProperty('height', `${actulaButtonHeight * 0.95}px`, 'important')
})
initializeBarChart()
} else {
$(chartContainer).each(function () {
this.style.setProperty('height', `${actulaButtonHeight * 0.87}px`, 'important')
})
setTimeout(() => {
initializeLineChart()
}, 500)
}
} else {
$('#chart-wrapper').fadeIn()
}
localStorage.setItem('hasUpdates', 'false')
const active = `#chart-button.top-left.active`
positionStyles = {
bottom: bottom,
right: right,
}
var lastClass = {
key: active,
values: [positionStyles],
}
var lastClassString = JSON.stringify(lastClass)
localStorage.setItem('lastClass', lastClassString)
}
const pos = getCoordinates(false)
goToPosition(pos)
setTimeout(() => {
const chartButton = document.getElementById('chart-button')
chartButton.classList.add('bottom-left')
showPerfMonitor()
}, 1000)
var shouldShowPerfMonitor = false
var appIsLoaded = false
window.showPerfMonitor = async function () {
shouldShowPerfMonitor = !shouldShowPerfMonitor
localStorage.setItem('shouldShowPerfMonitor', shouldShowPerfMonitor)
const chartButton = document.getElementById('chart-button')
const chartWrapper = document.getElementById('chart-wrapper')
if (shouldShowPerfMonitor === true) {
localStorage.setItem('hasUpdates', 'true')
startInterval()
await updateChartSize()
appIsLoaded = true
} else {
setTimeout(() => {
stopInterval()
}, 500)
chartButton.classList.remove('small', 'medium', 'large')
$(chartWrapper).fadeOut()
}
$(chartButton).toggleClass('active')
}
// when the close button is clicked
document.getElementById('close-button').addEventListener('click', function () {
document.getElementById('settingsMenu').classList.remove('show') // Hide the menu
document.querySelectorAll('.chart-row').forEach((row) => {
row.classList.remove('no-drag')
row.classList.add('drag')
})
showPerfMonitor()
setTimeout(() => {
window.electron.ipcRenderer.send('close-window')
}, 500)
})

View File

@ -1,75 +1,75 @@
<head>
<link href="/file=/css/material-icon.css" rel="stylesheet" />
</head>
<div id="chart-button">
<div class="chart-row">
<div class="left-col">
<i class="material-icons" id="popupTrigger">settings</i>
<div id="settingsMenu" class="settings-menu">
<div class="settings-row"><div class="settings-col">Settings</div></div>
<hr id="settings-hr" class="settings-hr" />
<div class="settings-row">
<div id="chart-button-container" draggable="true" ondragstart="onDragStart(event);">
<div id="chart-button" class="">
<div class="chart-row">
<div class="left-col">
<i class="material-icons" id="popupTrigger">settings</i>
<div id="settingsMenu" class="settings-menu">
<div class="settings-row">
<div class="settings-col">Layout:</div>
<div class="settings-col">
<a onclick="barChart()"> 1 </a> |
<a onclick="lineChart()"> 2 </a>
<div class="settings-col">Settings</div>
</div>
<hr id="settings-hr" class="settings-hr" />
<div class="settings-row">
<div class="settings-row">
<div class="settings-col">Layout:</div>
<div class="settings-col">
<a onclick="barChart()"> 1 </a> |
<a onclick="lineChart()"> 2 </a>
</div>
</div>
<div class="settings-row">
<div class="settings-col">Size:</div>
<div class="settings-col">
<a onclick="smallChart()"> S </a> |
<a onclick="mediumChart()"> M </a>
</div>
</div>
</div>
<div class="settings-row">
<div class="settings-col">Size:</div>
<div class="settings-col">
<a onclick="smallChart()"> S </a> |
<a onclick="mediumChart()"> M </a>
</div>
</div>
</div>
<div class="settings-row">
<div class="settings-col">Position</div>
<div id="positionMenu" class="position-menu">
<button class="position-btn position-clickable" id="top-left">
<i class="material-icons">north_west</i>
</button>
<button class="position-btn position-clickable" id="top-center">
<i class="material-icons">north</i>
</button>
<button class="position-btn position-clickable" id="top-right">
<i class="material-icons">north_east</i>
</button>
<button class="position-btn position-clickable" id="left-center">
<i class="material-icons">west</i>
</button>
<button class="position-btn" id="center" onclick="largeChart()">
<i class="material-icons">radio_button_checked</i>
</button>
<button class="position-btn position-clickable" id="right-center">
<i class="material-icons">east</i>
</button>
<button class="position-btn position-clickable" id="bottom-left">
<i class="material-icons">south_west</i>
</button>
<button class="position-btn position-clickable" id="bottom-center">
<i class="material-icons">south</i>
</button>
<button class="position-btn position-clickable" id="bottom-right">
<i class="material-icons">south_east</i>
</button>
<div class="settings-row">
<div class="settings-col">Position</div>
<div id="positionMenu" class="position-menu">
<button class="position-btn position-clickable" id="top-left">
<i class="material-icons">north_west</i>
</button>
<button class="position-btn position-clickable" id="top-center">
<i class="material-icons">north</i>
</button>
<button class="position-btn position-clickable" id="top-right">
<i class="material-icons">north_east</i>
</button>
<button class="position-btn position-clickable" id="left-center">
<i class="material-icons">west</i>
</button>
<button class="position-btn" id="center" onclick="largeChart()">
<i class="material-icons">radio_button_checked</i>
</button>
<button class="position-btn position-clickable" id="right-center">
<i class="material-icons">east</i>
</button>
<button class="position-btn position-clickable" id="bottom-left">
<i class="material-icons">south_west</i>
</button>
<button class="position-btn position-clickable" id="bottom-center">
<i class="material-icons">south</i>
</button>
<button class="position-btn position-clickable" id="bottom-right">
<i class="material-icons">south_east</i>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="chart-col">
<i class="material-icons" id="close-button">close</i>
<div class="chart-col">
<i class="material-icons" id="close-button">close</i>
</div>
</div>
</div>
<div id="chart-wrapper">
<div id="chart-container">
<canvas id="usage-chart" style="width: 100%; height: 100%"></canvas>
<div id="chart-wrapper">
<div id="chart-container">
<canvas id="usage-chart" style="width: 100%; height: 100%"></canvas>
</div>
<div id="custom-legend"></div>
</div>
<div id="custom-legend"></div>
</div>
</div>
<script src="/file=/js/perf-monitor.js"></script>

View File

@ -6,8 +6,7 @@ import time
import shared
import modules.config
import fooocus_version
from dependency_installer import *
import api.http_server
from api.gradio_helper import *
import modules.html
import modules.async_worker as worker
import modules.constants as constants
@ -1300,7 +1299,7 @@ with shared.gradio_root:
outputs=[prompt, style_selections], show_progress=True, queue=True) \
.then(fn=style_sorter.sort_styles, inputs=style_selections, outputs=style_selections, queue=False, show_progress=False) \
.then(lambda: None, _js='()=>{refresh_style_localization();}')
api.http_server.addResourceMonitor()
addResourceMonitor()
def dump_default_english_config():