From 26acbbedbf2626eec1232343901a01348369a8ce Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Mon, 15 Jan 2024 23:44:12 -0800 Subject: [PATCH] Add continuous option to the graph (#6093) Co-authored-by: Samuel Sieb --- esphome/components/graph/__init__.py | 4 +++ esphome/components/graph/graph.cpp | 37 +++++++++++++++++++++++----- esphome/components/graph/graph.h | 3 +++ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/esphome/components/graph/__init__.py b/esphome/components/graph/__init__.py index 046f59ca1a..0b83b71fe4 100644 --- a/esphome/components/graph/__init__.py +++ b/esphome/components/graph/__init__.py @@ -61,6 +61,7 @@ VALUE_POSITION_TYPE = { "BELOW": ValuePositionType.VALUE_POSITION_TYPE_BELOW, } +CONF_CONTINUOUS = "continuous" GRAPH_TRACE_SCHEMA = cv.Schema( { @@ -70,6 +71,7 @@ GRAPH_TRACE_SCHEMA = cv.Schema( cv.Optional(CONF_LINE_THICKNESS): cv.positive_int, cv.Optional(CONF_LINE_TYPE): cv.enum(LINE_TYPE, upper=True), cv.Optional(CONF_COLOR): cv.use_id(color.ColorStruct), + cv.Optional(CONF_CONTINUOUS): cv.boolean, } ) @@ -186,6 +188,8 @@ async def to_code(config): if CONF_COLOR in trace: c = await cg.get_variable(trace[CONF_COLOR]) cg.add(tr.set_line_color(c)) + if CONF_CONTINUOUS in trace: + cg.add(tr.set_continuous(trace[CONF_CONTINUOUS])) cg.add(var.add_trace(tr)) # Add legend if CONF_LEGEND in config: diff --git a/esphome/components/graph/graph.cpp b/esphome/components/graph/graph.cpp index 294e16dbb1..0e437a3425 100644 --- a/esphome/components/graph/graph.cpp +++ b/esphome/components/graph/graph.cpp @@ -165,17 +165,42 @@ void Graph::draw(Display *buff, uint16_t x_offset, uint16_t y_offset, Color colo for (auto *trace : traces_) { Color c = trace->get_line_color(); uint16_t thick = trace->get_line_thickness(); + bool continuous = trace->get_continuous(); + bool has_prev = false; + bool prev_b = false; + int16_t prev_y = 0; for (uint32_t i = 0; i < this->width_; i++) { float v = (trace->get_tracedata()->get_value(i) - ymin) / yrange; if (!std::isnan(v) && (thick > 0)) { - int16_t x = this->width_ - 1 - i; - uint8_t b = (i % (thick * LineType::PATTERN_LENGTH)) / thick; - if (((uint8_t) trace->get_line_type() & (1 << b)) == (1 << b)) { - int16_t y = (int16_t) roundf((this->height_ - 1) * (1.0 - v)) - thick / 2; - for (uint16_t t = 0; t < thick; t++) { - buff->draw_pixel_at(x_offset + x, y_offset + y + t, c); + int16_t x = this->width_ - 1 - i + x_offset; + uint8_t bit = 1 << ((i % (thick * LineType::PATTERN_LENGTH)) / thick); + bool b = (trace->get_line_type() & bit) == bit; + if (b) { + int16_t y = (int16_t) roundf((this->height_ - 1) * (1.0 - v)) - thick / 2 + y_offset; + if (!continuous || !has_prev || !prev_b || (abs(y - prev_y) <= thick)) { + for (uint16_t t = 0; t < thick; t++) { + buff->draw_pixel_at(x, y + t, c); + } + } else { + int16_t mid_y = (y + prev_y + thick) / 2; + if (y > prev_y) { + for (uint16_t t = prev_y + thick; t <= mid_y; t++) + buff->draw_pixel_at(x + 1, t, c); + for (uint16_t t = mid_y + 1; t < y + thick; t++) + buff->draw_pixel_at(x, t, c); + } else { + for (uint16_t t = prev_y - 1; t >= mid_y; t--) + buff->draw_pixel_at(x + 1, t, c); + for (uint16_t t = mid_y - 1; t >= y; t--) + buff->draw_pixel_at(x, t, c); + } } + prev_y = y; } + prev_b = b; + has_prev = true; + } else { + has_prev = false; } } } diff --git a/esphome/components/graph/graph.h b/esphome/components/graph/graph.h index 339a6f6d94..34accb7d3a 100644 --- a/esphome/components/graph/graph.h +++ b/esphome/components/graph/graph.h @@ -116,6 +116,8 @@ class GraphTrace { void set_line_type(enum LineType val) { this->line_type_ = val; } Color get_line_color() { return this->line_color_; } void set_line_color(Color val) { this->line_color_ = val; } + bool get_continuous() { return this->continuous_; } + void set_continuous(bool continuous) { this->continuous_ = continuous; } std::string get_name() { return name_; } const HistoryData *get_tracedata() { return &data_; } @@ -125,6 +127,7 @@ class GraphTrace { uint8_t line_thickness_{3}; enum LineType line_type_ { LINE_TYPE_SOLID }; Color line_color_{COLOR_ON}; + bool continuous_{false}; HistoryData data_; friend Graph;