#ifndef TEMPERATURE_CHART_H #define TEMPERATURE_CHART_H #include #include #include #include #include #include struct DataPoint { double temperature; int64_t timestamp; }; struct SeriesData { std::vector points; GdkRGBA color; std::string name; }; class TemperatureChart { public: TemperatureChart(GtkWidget *parent = nullptr); ~TemperatureChart(); GtkWidget* getWidget() const { return drawingArea; } void addTemperatureData(const std::string &device, const std::string &sensor, double temperature, int64_t timestamp); void clear(); void draw(); // Get list of devices with their colors std::vector> getDeviceColors() const; void drawChart(GtkDrawingArea *area, cairo_t *cr, int width, int height); private: void setupColors(); GdkRGBA getColorForDevice(const std::string &device); void redraw(); void updateThemeColors(); static gboolean onTick(gpointer userData); static void onLeave(GtkEventControllerMotion *motion, gpointer userData); struct NearestPoint { bool found; double temperature; int64_t timestamp; std::string seriesName; double distance; }; NearestPoint findNearestDataPoint(double mouseX, double mouseY, int width, int height); void showTooltip(double x, double y, const NearestPoint &point); void hideTooltip(); GtkWidget *drawingArea; GtkWidget *tooltipWindow; GtkWidget *tooltipLabel; std::map seriesMap; std::map colorMap; int maxDataPoints; guint tickHandler; double lastMouseX, lastMouseY; // Cairo drawing state double minTemp, maxTemp; int64_t minTime, maxTime; static constexpr int MAX_TIME_MS = 600000; // 10 minutes in milliseconds static constexpr double MIN_TEMP = 10.0; static constexpr double MAX_TEMP = 110.0; // Theme colors GdkRGBA bgColor, textColor, gridColor, axisColor; }; #endif // TEMPERATURE_CHART_H