added cpu, renaming
This commit is contained in:
parent
1519a1bee4
commit
c8668e5f00
@ -2,6 +2,7 @@
|
||||
#define CONFIG_MANAGER_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
class ConfigManager {
|
||||
public:
|
||||
@ -22,12 +23,21 @@ public:
|
||||
void setWindowHeight(int h) { windowHeight = h; }
|
||||
void setPollingTime(int t) { pollingTime = t; }
|
||||
|
||||
std::map<std::string, std::string> getSensorColors() const { return sensorColors; }
|
||||
std::map<std::string, std::string> getSensorNames() const { return sensorNames; }
|
||||
|
||||
void setSensorColor(const std::string &id, const std::string &color) { sensorColors[id] = color; }
|
||||
void setSensorName(const std::string &id, const std::string &name) { sensorNames[id] = name; }
|
||||
|
||||
private:
|
||||
std::string getConfigFilePath() const;
|
||||
|
||||
int windowWidth;
|
||||
int windowHeight;
|
||||
int pollingTime;
|
||||
|
||||
std::map<std::string, std::string> sensorColors;
|
||||
std::map<std::string, std::string> sensorNames;
|
||||
};
|
||||
|
||||
#endif // CONFIG_MANAGER_H
|
||||
|
||||
@ -25,6 +25,7 @@ private:
|
||||
static void onClearButtonClicked(GtkButton *button, gpointer userData);
|
||||
static void onQuitButtonClicked(GtkButton *button, gpointer userData);
|
||||
static void onColorSet(GObject *object, GParamSpec *pspec, gpointer userData);
|
||||
static void onNameChanged(GtkEditable *editable, gpointer userData);
|
||||
|
||||
GtkWidget *window;
|
||||
GtkWidget *statusLabel;
|
||||
@ -35,6 +36,7 @@ private:
|
||||
guint timerID;
|
||||
int refreshRateSec;
|
||||
GtkWidget *legendBox;
|
||||
std::map<std::string, GtkWidget*> tempLabels;
|
||||
};
|
||||
|
||||
// Global main loop reference for proper shutdown
|
||||
|
||||
@ -26,6 +26,15 @@ public:
|
||||
std::map<std::string, std::map<std::string, double>> getAllTemperatures();
|
||||
|
||||
private:
|
||||
struct SensorInfo {
|
||||
std::string deviceName;
|
||||
std::string sensorName;
|
||||
std::string path;
|
||||
};
|
||||
|
||||
std::vector<SensorInfo> discoveredSensors;
|
||||
|
||||
void discoverSensors();
|
||||
double readTemperatureFromFile(const std::string &filePath);
|
||||
};
|
||||
|
||||
|
||||
@ -16,7 +16,8 @@ struct DataPoint {
|
||||
struct SeriesData {
|
||||
std::vector<DataPoint> points;
|
||||
GdkRGBA color;
|
||||
std::string name;
|
||||
std::string id; // Unique internal ID (device + sensor)
|
||||
std::string name; // User-friendly display name
|
||||
};
|
||||
|
||||
class TemperatureChart {
|
||||
@ -34,6 +35,11 @@ public:
|
||||
// Get list of series with their colors
|
||||
std::vector<std::pair<std::string, GdkRGBA>> getSeriesColors() const;
|
||||
void setSeriesColor(const std::string &seriesName, const GdkRGBA &color);
|
||||
|
||||
// Name management
|
||||
std::string getSeriesName(const std::string &seriesId) const;
|
||||
void setSeriesName(const std::string &seriesId, const std::string &name);
|
||||
|
||||
void drawChart(GtkDrawingArea *area, cairo_t *cr, int width, int height);
|
||||
|
||||
private:
|
||||
|
||||
@ -2,3 +2,30 @@
|
||||
window {
|
||||
/* Icon can be set via CSS if needed */
|
||||
}
|
||||
|
||||
.small-entry {
|
||||
font-size: 9px;
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
padding: 0px 1px;
|
||||
margin: 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.small-entry:focus {
|
||||
background: rgba(255,255,255,0.1);
|
||||
}
|
||||
|
||||
.temp-label-small {
|
||||
font-size: 9px;
|
||||
font-weight: bold;
|
||||
margin-left: 1px;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
/* Compact box items */
|
||||
.legend-item {
|
||||
margin: 0 4px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
ConfigManager::ConfigManager()
|
||||
: windowWidth(1200), windowHeight(700), pollingTime(3)
|
||||
: windowWidth(1200), windowHeight(700), pollingTime(1)
|
||||
{
|
||||
}
|
||||
|
||||
@ -67,6 +67,10 @@ void ConfigManager::load()
|
||||
windowHeight = std::stoi(value);
|
||||
} else if (key == "polling_time") {
|
||||
pollingTime = std::stoi(value);
|
||||
} else if (key.find("color_") == 0) {
|
||||
sensorColors[key.substr(6)] = value;
|
||||
} else if (key.find("name_") == 0) {
|
||||
sensorNames[key.substr(5)] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,5 +94,13 @@ void ConfigManager::save()
|
||||
file << "window_height = " << windowHeight << "\n";
|
||||
file << "polling_time = " << pollingTime << "\n";
|
||||
|
||||
for (auto const& [id, color] : sensorColors) {
|
||||
file << "color_" << id << " = " << color << "\n";
|
||||
}
|
||||
|
||||
for (auto const& [id, name] : sensorNames) {
|
||||
file << "name_" << id << " = " << name << "\n";
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <iostream>
|
||||
#include "mainwindow.h"
|
||||
|
||||
// Declaration from resources.c
|
||||
@ -15,6 +16,7 @@ GMainLoop *gMainLoop = nullptr;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/*
|
||||
// Daemonize the process
|
||||
pid_t pid = fork();
|
||||
|
||||
@ -45,16 +47,23 @@ int main(int argc, char *argv[])
|
||||
dup2(fd, STDERR_FILENO);
|
||||
close(fd);
|
||||
}
|
||||
*/
|
||||
|
||||
gtk_init();
|
||||
|
||||
std::cerr << "GTK Initialized" << std::endl;
|
||||
|
||||
// Register resources containing the application icon
|
||||
GResource *resource = resources_get_resource();
|
||||
g_resources_register(resource);
|
||||
|
||||
std::cerr << "Resources registered" << std::endl;
|
||||
|
||||
gMainLoop = g_main_loop_new(nullptr, FALSE);
|
||||
|
||||
std::cerr << "Creating MainWindow" << std::endl;
|
||||
MainWindow *window = new MainWindow();
|
||||
std::cerr << "MainWindow created" << std::endl;
|
||||
window->show();
|
||||
|
||||
// Run the main event loop
|
||||
|
||||
@ -9,7 +9,8 @@
|
||||
|
||||
MainWindow::MainWindow()
|
||||
: window(nullptr), statusLabel(nullptr), refreshRateSpinBox(nullptr),
|
||||
chart(nullptr), monitor(nullptr), config(nullptr), timerID(0), refreshRateSec(3)
|
||||
chart(nullptr), monitor(nullptr), config(nullptr), timerID(0),
|
||||
refreshRateSec(3)
|
||||
{
|
||||
monitor = new TempMonitor();
|
||||
config = new ConfigManager();
|
||||
@ -48,6 +49,14 @@ MainWindow::~MainWindow()
|
||||
|
||||
void MainWindow::setupUI()
|
||||
{
|
||||
// Load CSS
|
||||
GtkCssProvider *provider = gtk_css_provider_new();
|
||||
gtk_css_provider_load_from_resource(provider, "/org/kamma/nvme-monitor/style.css");
|
||||
gtk_style_context_add_provider_for_display(gdk_display_get_default(),
|
||||
GTK_STYLE_PROVIDER(provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
g_object_unref(provider);
|
||||
|
||||
window = gtk_window_new();
|
||||
gtk_window_set_title(GTK_WINDOW(window), "NVMe Temperature Monitor");
|
||||
|
||||
@ -113,10 +122,15 @@ void MainWindow::setupUI()
|
||||
gtk_box_append(GTK_BOX(mainBox), chart->getWidget());
|
||||
gtk_widget_set_vexpand(chart->getWidget(), TRUE);
|
||||
|
||||
// Legend box
|
||||
legendBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_widget_set_margin_top(legendBox, 10);
|
||||
gtk_box_append(GTK_BOX(mainBox), legendBox);
|
||||
// Legend box with horizontal scrolling only
|
||||
legendBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
|
||||
GtkWidget *legendScroll = gtk_scrolled_window_new();
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(legendScroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
|
||||
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(legendScroll), legendBox);
|
||||
gtk_widget_set_margin_top(legendScroll, 2);
|
||||
|
||||
gtk_box_append(GTK_BOX(mainBox), legendScroll);
|
||||
}
|
||||
|
||||
gboolean MainWindow::onDeleteWindow(GtkWidget *widget, gpointer userData)
|
||||
@ -185,6 +199,7 @@ void MainWindow::saveWindowState()
|
||||
|
||||
void MainWindow::updateTemperatures()
|
||||
{
|
||||
std::cerr << "updateTemperatures starting" << std::endl;
|
||||
auto allTemps = monitor->getAllTemperatures();
|
||||
|
||||
// Get current real time in milliseconds since epoch
|
||||
@ -198,13 +213,41 @@ void MainWindow::updateTemperatures()
|
||||
const std::string &device = deviceEntry.first;
|
||||
const auto &temps = deviceEntry.second;
|
||||
|
||||
std::cerr << "Processing device: " << device << " with " << temps.size() << " sensors" << std::endl;
|
||||
|
||||
for (const auto &tempEntry : temps) {
|
||||
const std::string &sensorName = tempEntry.first;
|
||||
double temperature = tempEntry.second;
|
||||
|
||||
std::cerr << " Sensor: " << sensorName << " Temp: " << temperature << std::endl;
|
||||
|
||||
if (chart->addTemperatureData(device, sensorName, temperature, currentTime)) {
|
||||
needsLegendUpdate = true;
|
||||
|
||||
// Apply saved settings for new series
|
||||
std::string seriesId = device + " - " + sensorName;
|
||||
auto savedNames = config->getSensorNames();
|
||||
if (savedNames.count(seriesId)) {
|
||||
chart->setSeriesName(seriesId, savedNames[seriesId]);
|
||||
}
|
||||
|
||||
auto savedColors = config->getSensorColors();
|
||||
if (savedColors.count(seriesId)) {
|
||||
GdkRGBA color;
|
||||
if (gdk_rgba_parse(&color, savedColors[seriesId].c_str())) {
|
||||
chart->setSeriesColor(seriesId, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update individual temperature label in legend
|
||||
std::string seriesId = device + " - " + sensorName;
|
||||
if (tempLabels.count(seriesId)) {
|
||||
char buf[16];
|
||||
snprintf(buf, sizeof(buf), "%.1f°C", temperature);
|
||||
gtk_label_set_text(GTK_LABEL(tempLabels[seriesId]), buf);
|
||||
}
|
||||
|
||||
totalReadings++;
|
||||
}
|
||||
}
|
||||
@ -235,33 +278,48 @@ void MainWindow::updateLegend()
|
||||
child = next;
|
||||
}
|
||||
|
||||
tempLabels.clear();
|
||||
|
||||
// Get series colors from chart
|
||||
auto seriesColors = chart->getSeriesColors();
|
||||
|
||||
// Add legend items
|
||||
for (const auto &pair : seriesColors) {
|
||||
const std::string &seriesName = pair.first;
|
||||
const std::string &seriesId = pair.first;
|
||||
const GdkRGBA &color = pair.second;
|
||||
std::string displayName = chart->getSeriesName(seriesId);
|
||||
|
||||
// Create container for legend item
|
||||
GtkWidget *itemBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
GtkWidget *itemBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
|
||||
gtk_widget_add_css_class(itemBox, "legend-item");
|
||||
|
||||
// Create color dialog and button (modern GTK4 way)
|
||||
// Create color dialog and button
|
||||
GtkColorDialog *dialog = gtk_color_dialog_new();
|
||||
GtkWidget *colorButton = gtk_color_dialog_button_new(dialog);
|
||||
gtk_color_dialog_button_set_rgba(GTK_COLOR_DIALOG_BUTTON(colorButton), &color);
|
||||
gtk_widget_set_size_request(colorButton, 24, 24);
|
||||
|
||||
// Store series name in user data to know which series to update
|
||||
g_object_set_data_full(G_OBJECT(colorButton), "series-name", g_strdup(seriesName.c_str()), g_free);
|
||||
gtk_widget_set_size_request(colorButton, 12, 12);
|
||||
|
||||
// Store series id in user data
|
||||
g_object_set_data_full(G_OBJECT(colorButton), "series-name", g_strdup(seriesId.c_str()), g_free);
|
||||
g_signal_connect(colorButton, "notify::rgba", G_CALLBACK(onColorSet), this);
|
||||
|
||||
gtk_box_append(GTK_BOX(itemBox), colorButton);
|
||||
|
||||
// Create label with series name
|
||||
GtkWidget *label = gtk_label_new(seriesName.c_str());
|
||||
gtk_box_append(GTK_BOX(itemBox), label);
|
||||
// Create editable label for series name
|
||||
GtkWidget *entry = gtk_entry_new();
|
||||
gtk_editable_set_text(GTK_EDITABLE(entry), displayName.c_str());
|
||||
gtk_widget_set_size_request(entry, 60, -1);
|
||||
gtk_widget_add_css_class(entry, "small-entry");
|
||||
|
||||
// Store series id in user data
|
||||
g_object_set_data_full(G_OBJECT(entry), "series-name", g_strdup(seriesId.c_str()), g_free);
|
||||
g_signal_connect(entry, "changed", G_CALLBACK(onNameChanged), this);
|
||||
gtk_box_append(GTK_BOX(itemBox), entry);
|
||||
|
||||
// Temperature label
|
||||
GtkWidget *tempLabel = gtk_label_new("---°C");
|
||||
gtk_widget_add_css_class(tempLabel, "temp-label-small");
|
||||
gtk_box_append(GTK_BOX(itemBox), tempLabel);
|
||||
tempLabels[seriesId] = tempLabel;
|
||||
|
||||
gtk_box_append(GTK_BOX(legendBox), itemBox);
|
||||
}
|
||||
@ -283,6 +341,27 @@ void MainWindow::onColorSet(GObject *object, GParamSpec *pspec, gpointer userDat
|
||||
const GdkRGBA *color = gtk_color_dialog_button_get_rgba(GTK_COLOR_DIALOG_BUTTON(object));
|
||||
if (color) {
|
||||
self->chart->setSeriesColor(seriesName, *color);
|
||||
|
||||
// Save to config
|
||||
char *colorStr = gdk_rgba_to_string(color);
|
||||
self->config->setSensorColor(seriesName, colorStr);
|
||||
g_free(colorStr);
|
||||
self->config->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onNameChanged(GtkEditable *editable, gpointer userData)
|
||||
{
|
||||
MainWindow *self = static_cast<MainWindow*>(userData);
|
||||
const char *seriesId = static_cast<const char*>(g_object_get_data(G_OBJECT(editable), "series-name"));
|
||||
|
||||
if (seriesId) {
|
||||
const char *newName = gtk_editable_get_text(editable);
|
||||
if (newName) {
|
||||
self->chart->setSeriesName(seriesId, newName);
|
||||
self->config->setSensorName(seriesId, newName);
|
||||
self->config->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,72 @@
|
||||
|
||||
TempMonitor::TempMonitor()
|
||||
{
|
||||
discoverSensors();
|
||||
}
|
||||
|
||||
void TempMonitor::discoverSensors()
|
||||
{
|
||||
discoveredSensors.clear();
|
||||
DIR* hwmonDir = opendir("/sys/class/hwmon");
|
||||
if (!hwmonDir) return;
|
||||
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(hwmonDir)) != nullptr) {
|
||||
std::string hwmonName = entry->d_name;
|
||||
if (hwmonName.find("hwmon") != 0) continue;
|
||||
|
||||
std::string path = "/sys/class/hwmon/" + hwmonName;
|
||||
|
||||
// Read "name" from sysfs
|
||||
std::string nameFromSysfs = "Unknown";
|
||||
std::ifstream nameFile(path + "/name");
|
||||
if (nameFile.is_open()) {
|
||||
std::getline(nameFile, nameFromSysfs);
|
||||
nameFromSysfs.erase(nameFromSysfs.find_last_not_of(" \n\r\t") + 1);
|
||||
nameFile.close();
|
||||
}
|
||||
|
||||
// Filter: Only interested in nvme and coretemp (CPU)
|
||||
if (nameFromSysfs != "nvme" && nameFromSysfs != "coretemp") continue;
|
||||
|
||||
DIR* dDir = opendir(path.c_str());
|
||||
if (dDir) {
|
||||
struct dirent* sEntry;
|
||||
while ((sEntry = readdir(dDir)) != nullptr) {
|
||||
std::string fname = sEntry->d_name;
|
||||
// Only temperature sensors (temp*_input)
|
||||
if (fname.find("temp") == 0 && fname.find("_input") != std::string::npos) {
|
||||
std::string id = fname.substr(4, fname.find("_input") - 4);
|
||||
|
||||
// Use "label" from sysfs for sensor name if available
|
||||
std::string labelFromSysfs = "";
|
||||
std::ifstream labelFile(path + "/temp" + id + "_label");
|
||||
if (labelFile.is_open()) {
|
||||
std::getline(labelFile, labelFromSysfs);
|
||||
labelFromSysfs.erase(labelFromSysfs.find_last_not_of(" \n\r\t") + 1);
|
||||
labelFile.close();
|
||||
}
|
||||
|
||||
// For CPU (coretemp), filter only Package id 0
|
||||
if (nameFromSysfs == "coretemp") {
|
||||
if (labelFromSysfs != "Package id 0") continue;
|
||||
}
|
||||
|
||||
// For NVMe, filter out Composite sensor
|
||||
if (nameFromSysfs == "nvme") {
|
||||
if (labelFromSysfs == "Composite") continue;
|
||||
}
|
||||
|
||||
std::string finalSensorName = labelFromSysfs.empty() ? "temp" + id : labelFromSysfs;
|
||||
std::string deviceDisplayName = nameFromSysfs + " (" + hwmonName + ")";
|
||||
|
||||
discoveredSensors.push_back({deviceDisplayName, finalSensorName, path + "/" + fname});
|
||||
}
|
||||
}
|
||||
closedir(dDir);
|
||||
}
|
||||
}
|
||||
closedir(hwmonDir);
|
||||
}
|
||||
|
||||
std::vector<std::string> TempMonitor::getAvailableDevices()
|
||||
@ -52,73 +118,12 @@ std::map<std::string, std::map<std::string, double>> TempMonitor::getAllTemperat
|
||||
{
|
||||
std::map<std::string, std::map<std::string, double>> allTemperatures;
|
||||
|
||||
DIR* hwmonDir = opendir("/sys/class/hwmon");
|
||||
if (!hwmonDir) return allTemperatures;
|
||||
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(hwmonDir)) != nullptr) {
|
||||
std::string hwmonName = entry->d_name;
|
||||
if (hwmonName.find("hwmon") != 0) continue;
|
||||
|
||||
std::string path = "/sys/class/hwmon/" + hwmonName;
|
||||
|
||||
// Read "name" from sysfs as requested
|
||||
std::string nameFromSysfs = "Unknown";
|
||||
std::ifstream nameFile(path + "/name");
|
||||
if (nameFile.is_open()) {
|
||||
std::getline(nameFile, nameFromSysfs);
|
||||
nameFromSysfs.erase(nameFromSysfs.find_last_not_of(" \n\r\t") + 1);
|
||||
nameFile.close();
|
||||
}
|
||||
|
||||
// Filter: Only interested in nvme and coretemp (CPU)
|
||||
if (nameFromSysfs != "nvme" && nameFromSysfs != "coretemp") continue;
|
||||
|
||||
std::map<std::string, double> sensors;
|
||||
DIR* dDir = opendir(path.c_str());
|
||||
if (dDir) {
|
||||
struct dirent* sEntry;
|
||||
while ((sEntry = readdir(dDir)) != nullptr) {
|
||||
std::string fname = sEntry->d_name;
|
||||
// Only temperature sensors (temp*_input)
|
||||
if (fname.find("temp") == 0 && fname.find("_input") != std::string::npos) {
|
||||
std::string id = fname.substr(4, fname.find("_input") - 4);
|
||||
|
||||
double temp = readTemperatureFromFile(path + "/" + fname);
|
||||
for (const auto& sensor : discoveredSensors) {
|
||||
double temp = readTemperatureFromFile(sensor.path);
|
||||
if (temp > -200.0) {
|
||||
// Use "label" from sysfs for sensor name if available
|
||||
std::string labelFromSysfs = "";
|
||||
std::ifstream labelFile(path + "/temp" + id + "_label");
|
||||
if (labelFile.is_open()) {
|
||||
std::getline(labelFile, labelFromSysfs);
|
||||
labelFromSysfs.erase(labelFromSysfs.find_last_not_of(" \n\r\t") + 1);
|
||||
labelFile.close();
|
||||
}
|
||||
|
||||
// For CPU (coretemp), filter only Package id 0
|
||||
if (nameFromSysfs == "coretemp") {
|
||||
if (labelFromSysfs != "Package id 0") continue;
|
||||
}
|
||||
|
||||
// For NVMe, filter out Composite sensor
|
||||
if (nameFromSysfs == "nvme") {
|
||||
if (labelFromSysfs == "Composite") continue;
|
||||
}
|
||||
|
||||
std::string finalSensorName = labelFromSysfs.empty() ? "temp" + id : labelFromSysfs;
|
||||
sensors[finalSensorName] = temp;
|
||||
allTemperatures[sensor.deviceName][sensor.sensorName] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dDir);
|
||||
}
|
||||
|
||||
if (!sensors.empty()) {
|
||||
// Label device with its sysfs name and instance ID
|
||||
allTemperatures[nameFromSysfs + " (" + hwmonName + ")"] = sensors;
|
||||
}
|
||||
}
|
||||
closedir(hwmonDir);
|
||||
|
||||
return allTemperatures;
|
||||
}
|
||||
|
||||
@ -180,6 +180,7 @@ bool TemperatureChart::addTemperatureData(const std::string &device, const std::
|
||||
if (seriesMap.find(seriesKey) == seriesMap.end()) {
|
||||
SeriesData series;
|
||||
series.color = getColorForSeries(seriesKey);
|
||||
series.id = seriesKey;
|
||||
series.name = seriesKey;
|
||||
seriesMap[seriesKey] = series;
|
||||
isNew = true;
|
||||
@ -230,8 +231,8 @@ void TemperatureChart::clear()
|
||||
std::vector<std::pair<std::string, GdkRGBA>> TemperatureChart::getSeriesColors() const
|
||||
{
|
||||
std::vector<std::pair<std::string, GdkRGBA>> result;
|
||||
for (const auto &entry : colorMap) {
|
||||
result.push_back({entry.first, entry.second});
|
||||
for (const auto &pair : seriesMap) {
|
||||
result.push_back({pair.first, pair.second.color});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -249,6 +250,22 @@ void TemperatureChart::setSeriesColor(const std::string &seriesName, const GdkRG
|
||||
gtk_widget_queue_draw(drawingArea);
|
||||
}
|
||||
|
||||
std::string TemperatureChart::getSeriesName(const std::string &seriesId) const
|
||||
{
|
||||
auto it = seriesMap.find(seriesId);
|
||||
if (it != seriesMap.end()) {
|
||||
return it->second.name;
|
||||
}
|
||||
return seriesId;
|
||||
}
|
||||
|
||||
void TemperatureChart::setSeriesName(const std::string &seriesId, const std::string &name)
|
||||
{
|
||||
if (seriesMap.find(seriesId) != seriesMap.end()) {
|
||||
seriesMap[seriesId].name = name;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean TemperatureChart::onTick(gpointer userData)
|
||||
{
|
||||
TemperatureChart *self = static_cast<TemperatureChart*>(userData);
|
||||
@ -414,7 +431,7 @@ TemperatureChart::NearestPoint TemperatureChart::findNearestDataPoint(double mou
|
||||
result.found = true;
|
||||
result.temperature = point.temperature;
|
||||
result.timestamp = point.timestamp;
|
||||
result.seriesName = seriesEntry.first;
|
||||
result.seriesName = series.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user