first commit
This commit is contained in:
169
ESP32_WAVESHARE_7x5/Graph.cpp
Normal file
169
ESP32_WAVESHARE_7x5/Graph.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
#include "Graph.h"
|
||||
|
||||
Graph::Graph(Ecran * _ecran, Graph_Param _gp)
|
||||
{
|
||||
ecran = _ecran;
|
||||
gp = _gp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
INITIALCODE FROM (C) D L BIRD
|
||||
This function will draw a graph on a ePaper/TFT/LCD display using data from an array containing data to be graphed.
|
||||
The variable 'max_readings' determines the maximum number of data elements for each array. Call it with the following parametric data:
|
||||
x_pos-the x axis top-left position of the graph
|
||||
y_pos-the y-axis top-left position of the graph, e.g. 100, 200 would draw the graph 100 pixels along and 200 pixels down from the top-left of the screen
|
||||
width-the width of the graph in pixels
|
||||
height-height of the graph in pixels
|
||||
Y1_Max-sets the scale of plotted data, for example 5000 would scale all data to a Y-axis of 5000 maximum
|
||||
data_array1 is parsed by value, externally they can be called anything else, e.g. within the routine it is called data_array1, but externally could be temperature_readings
|
||||
gp.auto_scale-a logical value (TRUE or FALSE) that switches the Y-axis autoscale On or Off
|
||||
barchart_on-a logical value (TRUE or FALSE) that switches the drawing mode between barhcart and line graph
|
||||
barchart_colour-a sets the gp.title and graph plotting colour
|
||||
If called with Y!_Max value of 500 and the data never goes above 500, then autoscale will retain a 0-500 Y scale, if on, the scale increases/decreases to match the data.
|
||||
gp.auto_scale_margin, e.g. if set to 1000 then autoscale increments the scale by 1000 steps.
|
||||
|
||||
Changed to be an object
|
||||
add x gp.title
|
||||
multiple gp.series
|
||||
colors for gp.series
|
||||
allow 2 scales
|
||||
use Graph_Param
|
||||
use enums
|
||||
add thickness
|
||||
add fill line mode
|
||||
*/
|
||||
// float DataArray[], int readings
|
||||
void Graph::draw(int readings, int x_pos, int y_pos, int gwidth, int gheight) {
|
||||
if (debug) Serial.println("B - graph::draw");
|
||||
|
||||
float maxYscale[2] = {-10000, -10000};
|
||||
float minYscale[2] = {10000, 10000};
|
||||
int last_x, last_y;
|
||||
float x2, y2;
|
||||
|
||||
if (gp.auto_scale == DYNAMIC_SCALE) {
|
||||
for (int s = 0; s < gp.nb_series; s++) {
|
||||
int ref = 0;
|
||||
if (gp.show_2_scales) {
|
||||
ref = s;
|
||||
}
|
||||
for (int i = 1; i < readings; i++ ) {
|
||||
if (gp.series[s].data[i] >= maxYscale[ref]) maxYscale[ref] = gp.series[s].data[i];
|
||||
if (gp.series[s].data[i] <= minYscale[ref]) minYscale[ref] = gp.series[s].data[i];
|
||||
}
|
||||
}
|
||||
for (int s = 0; s < gp.nb_series; s++) {
|
||||
maxYscale[s] = round(maxYscale[s] + gp.auto_scale_margin); // Auto scale the graph and round to the nearest value defined, default was gp.Y_Max[ref]
|
||||
gp.Y_Max[s] = round(maxYscale[s] + 0.5);
|
||||
if (minYscale[s] != s) minYscale[s] = round(minYscale[s] - gp.auto_scale_margin); // Auto scale the graph and round to the nearest value defined, default was gp.Y_Min[ref]
|
||||
gp.Y_Min[s] = round(minYscale[s]);
|
||||
}
|
||||
}
|
||||
|
||||
if (debug) Serial.println(" graph::draw "
|
||||
+ String(gp.nb_series) + " " + String(x_pos) + " " + String(y_pos) + " "
|
||||
+ String(gwidth) + " " + String(gheight) + " "
|
||||
//+ String(last_x) + " " + String(last_y) + " "
|
||||
+ String(gp.Y_Min[0]) + " " + String(gp.Y_Max[0]) + " "
|
||||
+ String(gp.Y_Min[1]) + " " + String(gp.Y_Max[1])
|
||||
);
|
||||
|
||||
|
||||
ecran->_display->drawRect(x_pos, y_pos, gwidth + 3, gheight + 2, GxEPD_BLACK);
|
||||
ecran->drawString(x_pos + gwidth / 2, y_pos - 13, gp.title, CENTER, GxEPD_BLACK);
|
||||
// Draw the data
|
||||
for (int s = 0; s < gp.nb_series; s++) {
|
||||
int ref = 0;
|
||||
if (gp.show_2_scales == TWO_SCALES) {
|
||||
ref = s;
|
||||
}
|
||||
// Draw the graph
|
||||
last_x = x_pos;
|
||||
last_y = y_pos + (gp.Y_Max[ref] - constrain(gp.series[ref].data[1], gp.Y_Min[ref], gp.Y_Max[ref])) / (gp.Y_Max[ref] - gp.Y_Min[ref]) * gheight;
|
||||
|
||||
if (debug) Serial.print("Data to draw : S" + String(s) + " ");
|
||||
|
||||
for (int gx = 0; gx < readings; gx++) {
|
||||
if (debug) Serial.print(gp.series[s].data[gx]);
|
||||
if (debug) Serial.print(" ");
|
||||
y2 = y_pos + (gp.Y_Max[ref] - constrain(gp.series[s].data[gx], gp.Y_Min[ref], gp.Y_Max[ref])) / (gp.Y_Max[ref] - gp.Y_Min[ref]) * gheight + 1;
|
||||
if (gp.series[s].chart_type == TYPE_BARCHART) {
|
||||
x2 = x_pos + gx * (gwidth / readings) + 2;
|
||||
ecran->_display->fillRect(x2, y2,
|
||||
(gwidth / readings) - 2,
|
||||
y_pos + gheight - y2 + 2,
|
||||
gp.series[s].color
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
x2 = x_pos + gx * gwidth / (readings - 1) + 1; // max_readings is the global variable that sets the maximum data that can be plotted
|
||||
if (gp.series[s].chart_type == TYPE_FILL_LINE) {
|
||||
if (last_y < y2) {
|
||||
ecran->_display->fillTriangle(last_x, last_y, last_x, y2, x2, y2, gp.series[s].color);
|
||||
}
|
||||
else {
|
||||
ecran->_display->fillTriangle(last_x, last_y, x2, last_y, x2, y2, gp.series[s].color);
|
||||
|
||||
}
|
||||
float y0 = min((float) x2, (float) last_y);
|
||||
|
||||
ecran->_display->fillRect(x2, y0,
|
||||
(gwidth / readings),
|
||||
y_pos + gheight - y0 + 2,
|
||||
gp.series[s].color);
|
||||
ecran->_display->drawLine(last_x, last_y, x2, y2, GxEPD_BLACK);
|
||||
|
||||
}
|
||||
else {
|
||||
if (gp.series[s].thickness > 1) {
|
||||
ecran->drawAngledLine(last_x, last_y, x2, y2, gp.series[s].thickness, gp.series[s].color);
|
||||
}
|
||||
else {
|
||||
ecran->_display->drawLine(last_x, last_y, x2, y2, gp.series[s].color);
|
||||
}
|
||||
}
|
||||
}
|
||||
last_x = x2;
|
||||
last_y = y2;
|
||||
}
|
||||
if (debug) Serial.println(" ");
|
||||
}
|
||||
if (debug) Serial.println(" ");
|
||||
for (int spacing = 0; spacing <= gp.y_minor_axis; spacing++) {
|
||||
for (int j = 0; j < gp.number_of_dashes; j++) { // Draw dashed graph grid lines
|
||||
if (spacing < gp.y_minor_axis)
|
||||
ecran->_display->drawFastHLine((x_pos + 3 + j * gwidth / gp.number_of_dashes), y_pos + (gheight * spacing / gp.y_minor_axis), gwidth / (2 * gp.number_of_dashes), GxEPD_BLACK);
|
||||
}
|
||||
for (int s = 0; s < (gp.show_2_scales ? 2 : 1); s++) {
|
||||
int color = (gp.show_2_scales == TWO_SCALES ? gp.series[s].color : GxEPD_BLACK);
|
||||
int xp = (s == 0 ? 0 : gwidth + 10);
|
||||
if ((gp.Y_Max[s] - (float)(gp.Y_Max[s] - gp.Y_Min[s]) / gp.y_minor_axis * spacing) < 5) {
|
||||
ecran->drawString(x_pos + xp - 1, y_pos + gheight * spacing / gp.y_minor_axis - 5,
|
||||
String((gp.Y_Max[s] - (float)(gp.Y_Max[s] - gp.Y_Min[s]) / gp.y_minor_axis * spacing + 0.01), 1),
|
||||
(s == 0 ? RIGHT : LEFT), color
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gp.Y_Min[s] < 1 && gp.Y_Max[s] < 10)
|
||||
ecran->drawString(x_pos + xp - 1, y_pos + gheight * spacing / gp.y_minor_axis - 5,
|
||||
String((gp.Y_Max[s] - (float)(gp.Y_Max[s] - gp.Y_Min[s]) / gp.y_minor_axis * spacing + 0.01), 1),
|
||||
(s == 0 ? RIGHT : LEFT), color);
|
||||
else
|
||||
ecran->drawString(x_pos + xp - 2, y_pos + gheight * spacing / gp.y_minor_axis - 5,
|
||||
String((gp.Y_Max[s] - (float)(gp.Y_Max[s] - gp.Y_Min[s]) / gp.y_minor_axis * spacing + 0.01), 0),
|
||||
(s == 0 ? RIGHT : LEFT), color);
|
||||
}
|
||||
}
|
||||
}
|
||||
// for (int i = 0; i <= 2; i++) {
|
||||
// ecran->drawString(15 + x_pos + gwidth / 3 * i, y_pos + gheight + 3, String(i), LEFT);
|
||||
// }
|
||||
ecran->drawString(x_pos + gwidth / 2, y_pos + gheight + 14, gp.x_title, RIGHT);
|
||||
|
||||
if (debug) Serial.println("E - graph::draw");
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user