perf monitor 2.0 with dragging
This commit is contained in:
parent
4c32ebe390
commit
5774787945
|
|
@ -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()
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
5
webui.py
5
webui.py
|
|
@ -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():
|
||||
|
|
|
|||
Loading…
Reference in New Issue