class GraphXT { PGraphics graph; HashMap traces = new HashMap(); int w; int h; int bgcolor; int gridcolor; int gridsize; long t; GraphXT(int w, int h, color bgcolor, color gridcolor, int gridsize) { // due to a bug in PGraphics.copy() the image buffer needs to be one pixel bigger graph = createGraphics(w + 1, h + 1, P2D); this.w = w; this.h = h; this.bgcolor = bgcolor; this.gridcolor = gridcolor; this.gridsize = gridsize; clear(); } void draw(int x, int y) { if(t < w) { copy(graph, 0, 0, w, h, 0, 0, w, h); } else { int s = int(t % w); copy(graph, 0, 0, s, h, x + w - s - 1, y, s, h); copy(graph, s + 1, 0, w - s - 1, h, x, y, w - s - 1, h); } } // clear canvas and draw grid void clear() { graph.beginDraw(); graph.fill(bgcolor); graph.stroke(bgcolor); graph.rect(0, 0, w, h); if(gridsize > 0) { graph.stroke(gridcolor); for(int x = 0; x < w; x += gridsize) { graph.line(x, 0, x, h - 1); } for(int y = 0; y < h; y += gridsize) { graph.line(0, y, w, y); } } graph.endDraw(); for(Iterator i = traces.values().iterator(); i.hasNext(); ) { Trace trace = (Trace) i.next(); trace.penDown = false; } t = 0; } // move pen 1 unit to the right until it reaches the end, then start moving canvas to the left void scroll() { int x = int(++t % w); graph.beginDraw(); if(t >= w) { if(gridsize > 0 && t % gridsize == 0) { graph.stroke(gridcolor); graph.line(x, 0, x, h); } else { graph.stroke(bgcolor); graph.line(x, 0, x, h); if(gridsize > 0) { graph.stroke(gridcolor); for(int y = 0; y < h; y += gridsize) { graph.line(x, y, x, y); } } } } for(Iterator i = traces.values().iterator(); i.hasNext(); ) { Trace trace = (Trace) i.next(); if(trace.penDown && trace.show) { int y = round(map(trace.value, trace.min, trace.max, h - 1, 0)); graph.stroke(trace.c); graph.line(x, trace.y, x, y); trace.y = y; } } graph.endDraw(); } void add(String name, float min, float max, color c) { traces.put(name, new Trace(min, max, c)); } void plot(String name, float value) { Trace trace = (Trace)traces.get(name); if(trace != null) { trace.value = constrain(value, trace.min, trace.max); if(!trace.penDown) { trace.y = round(map(trace.value, trace.min, trace.max, h - 1, 0)); trace.penDown = true; } } } void remove(String name) { traces.remove(name); } void show(String name, boolean show) { Trace trace = (Trace)traces.get(name); if(trace != null) { trace.show = show; trace.penDown = false; } } class Trace { float min; float max; float value; color c; boolean show; boolean penDown; int y; Trace(float min, float max, color c) { this.min = min; this.max = max; this.c = c; this.show = true; this.penDown = false; } } }