Trying to make a "Scrolling" SVG graph.

Hi all,

I want to graph some sensor data using SVG on either an Arduino with WiFi module, or a NodeMCU, thinking the method would be essentially the same, I just have not quite worked out HOW to make it appear to scroll as each new datapoint is added.

So the idea is I will be running the MCU as an access point with a small web page that displays the SVG image and refreshes every 30 seconds or a minute, something practical when a client is connected. The device will be taking measurements such as temperature, humidity and time and recording these every 10 seconds to a CSV file. I want to also put the sensor readings over time on an SVG line graph. I've already sorted out how to "Draw" the graph in the HTML portion of my code, I'm just trying to wrap my head around updating it. So as a new set of readings with a timestamp is recorded, I want to be able to add it to the right-hand side of the graph and drop the oldest value off of the left hand side of my graph so when the page refreshes, the graph appears to scroll from right to left.

I'm visualizing putting the data into a multi-dimensional array so I can select a column (same cell in each dimension of the array) to put data into and after the array is filled, I would need to shift everything left a cell and add the new data into the last cell in each row. This way I'm pointing to the same cells in the array every time the SVG graph is re-drawn, but the data in each cell is changing.

If anybody has recommendations on methods to accomplish this I would love to hear them. Code isn't necessary unless you feel it is the best way to express the explanation. I think I have this all somewhat worked out in my head but I'm not sure if I'm over thinking some simpler solution.

Thanks.

Websockets are good way to send data in real-time between the browser and the server. AJAX is an older way to do the same. The following is an example of using websockets on an ESP8266.

https://www.hackster.io/rayburne/nodemcu-esp8266-remote-temperature-using-websockets-5956c4

gdsports:
Websockets are good way to send data in real-time between the browser and the server. AJAX is an older way to do the same. The following is an example of using websockets on an ESP8266.

Thanks for the tip, and I have read about a few ways to do this. I have played around with websockets a bit and that does work good for a lot of things, but for this project, I want to try and avoid the need for, and use of an internet connection or even a server. The generic NodeMCU board I have been playing around with, I think will have enough speed and local storage that I should be able to make everything work. The first experiment I conducted last week involved using an arduino with some basic code to see if I could get it to generate all of the data needed to generate the SVG graphic on the fly and it seems to have worked. This is not yet a wireless project as all of the applicable output has to be copied and pasted out of the serial monitor. Once it is copied out and pasted into a new SVG file though, that SVG file is viewable and looks how I would expect it to. I realize it isn’t the most elegant approach and I’m probably even doing a few things I don’t have to, but I’m hoping as I continue to develop this project that I can slim down and simplify some of my code. Obviously this is just a small part of it. I just wanted to see if I could generate output quickly.

There are a few sections commented out that are used for visualizing array contents and I have not added any notes, I thought it straightforward enough, but let me know what you think.

int arr[4][24];
int pos = 0;

void setup() {
  Serial.begin(115200);
  int x = 0;
  int G = 20;
  for (int i = 0; i <= 23; i++)
  {
    arr[1][i] = x;
    arr[3][i] = G;
    G+=20;
    x++;
  }
/*
  for (int i = 0; i <= 7; i++)
  {
    Serial.print("[");Serial.print(arr[1][i]);Serial.print("]");
  }
  Serial.println("PtrBuf");
  delay(5000);
*/
}

void loop() {
  int RND = random(10, 90);
  
  arr[2][pos] = RND;
  pos++;

 for (int i = 0; i <= 23; i++)
 {
  arr[1][i]++;
  if (arr[1][i] == 24) arr[1][i] = 0;
//  Serial.print("[");Serial.print(arr[1][i]);Serial.print("]");
  int Z = arr[1][i];
  arr[0][i] = arr[2][Z];
 }
// Serial.println("PtrBuf");delay(5000);
/*
  for (int i = 1; i <= 7; i++)
  {
    Serial.print("[");Serial.print(arr[0][i]);Serial.print("]");
  }
  Serial.println("Graph");
*/
  delay(1000);
  if (pos == 24) pos = 0;
/* ------Generating a raw-text SVG graph for testing purposes ---*/
Serial.println("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"510\" height=\"210\">");  
Serial.println("<rect x=\"5\" y=\"5\" rx=\"20\" ry=\"20\" width=\"500\" height=\"200\" style=\"fill:#A0FFA0;stroke:black;stroke-width:2;opacity:0.8\" />");
Serial.println("<text x=\"190\" y=\"25\" fill=\"black\">Plotting random numbers</text>");
Serial.println("<line x1=\"5\" y1=\"105\" x2=\"505\" y2=\"105\" style=\"stroke:green;stroke-width:1;opacity:0.3\"/>");
Serial.println("<line x1=\"5\" y1=\"52\" x2=\"505\" y2=\"52\" style=\"stroke:green;stroke-width:1;opacity:0.3\"/>");
Serial.println("<line x1=\"5\" y1=\"157\" x2=\"505\" y2=\"157\" style=\"stroke:green;stroke-width:1;opacity:0.3\"/>");

for (int i = 0; i <= 23; i++)
{
  int X1 = arr[3][i];
  int Y1 = (200 - (arr[0][i]));
  int X2 = X1;
  int Y2 = 195;
  Serial.print("<line x1=\"");Serial.print(X1);Serial.print("\" y1=\"");Serial.print(Y1);Serial.print("\" x2=\"");Serial.print(X2);Serial.print("\" y2=\"");Serial.print(Y2);Serial.println("\" style=\"stroke:blue;stroke-width=20;opacity:1\"/>");
}

Serial.println("</svg>");
Serial.println("");
/* -------------End of raw-text SVG graph generator ---------------*/
}