Skip to content

Commit c76a8f9

Browse files
committed
Added label support to SerialPlotter
Supports csv style header and colon separated <label>:<value> Two command where added. All command start with # CLEAN -> will clean the scope SIZE:<value> -> set the xaxis size. Right now it is limited to 10-5000.
1 parent 219cc6c commit c76a8f9

File tree

2 files changed

+117
-20
lines changed

2 files changed

+117
-20
lines changed

app/src/processing/app/SerialPlotter.java

Lines changed: 109 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
import java.util.ArrayList;
2727
import javax.swing.*;
2828
import javax.swing.border.EmptyBorder;
29+
30+
import com.jcraft.jsch.Buffer;
31+
2932
import java.awt.*;
3033
import java.awt.event.ActionListener;
3134
import java.awt.geom.AffineTransform;
@@ -42,14 +45,18 @@ public class SerialPlotter extends AbstractMonitor {
4245
private int serialRate, xCount;
4346

4447
private ArrayList<Graph> graphs;
45-
private final static int BUFFER_CAPACITY = 500;
48+
private int buffer_capacity = 500;
49+
private final static int BUFFER_CAPACITY_DEFAULT = 500;
50+
private final static int BUFFER_CAPACITY_MAX = 5000;
51+
private final static int BUFFER_CAPACITY_MIN = 10;
4652

4753
private static class Graph {
4854
public CircularBuffer buffer;
55+
public String label;
4956
private Color color;
5057

51-
public Graph(int id) {
52-
buffer = new CircularBuffer(BUFFER_CAPACITY);
58+
public Graph(int id, int capacity) {
59+
buffer = new CircularBuffer(capacity);
5360
color = Theme.getColorCycleColor("plotting.graphcolor", id);
5461
}
5562

@@ -147,12 +154,12 @@ public void paintComponent(Graphics g1) {
147154
}
148155

149156
// handle data count
150-
int cnt = xCount - BUFFER_CAPACITY;
151-
if (xCount < BUFFER_CAPACITY) cnt = 0;
157+
int cnt = xCount - buffer_capacity;
158+
if (xCount < buffer_capacity) cnt = 0;
152159

153160
double zeroTick = ticks.getTick(0);
154161
double lastTick = ticks.getTick(ticks.getTickCount() - 1);
155-
double xTickRange = BUFFER_CAPACITY / ticks.getTickCount();
162+
double xTickRange = buffer_capacity / ticks.getTickCount();
156163

157164
for (int i = 0; i < ticks.getTickCount() + 1; i++) {
158165
String s;
@@ -168,7 +175,7 @@ public void paintComponent(Graphics g1) {
168175
s = String.valueOf((int)(xTickRange * i)+cnt);
169176
fBounds = fm.getStringBounds(s, g);
170177
sWidth = (int)fBounds.getWidth()/2;
171-
xValue = (int)((bounds.width - xOffset - xPadding) * ((xTickRange * i) / BUFFER_CAPACITY) + xOffset);
178+
xValue = (int)((bounds.width - xOffset - xPadding) * ((xTickRange * i) / buffer_capacity) + xOffset);
172179
}
173180
// draw graph x axis, ticks and labels
174181
g.setColor(boundsColor);
@@ -185,13 +192,24 @@ public void paintComponent(Graphics g1) {
185192
g.drawLine(xOffset, (int) transformY(zeroTick), bounds.width - xPadding, (int)transformY(zeroTick));
186193

187194
g.setTransform(AffineTransform.getTranslateInstance(xOffset, 0));
188-
float xstep = (float) (bounds.width - xOffset - xPadding) / (float) BUFFER_CAPACITY;
189-
int legendLength = graphs.size() * 10 + (graphs.size() - 1) * 3;
190-
195+
float xstep = (float) (bounds.width - xOffset - xPadding) / (float) buffer_capacity;
196+
// draw legend
197+
int legendXOffset = 0;
191198
for(int i = 0; i < graphs.size(); ++i) {
192199
graphs.get(i).paint(g, xstep, minY, maxY, rangeY, bounds.height);
193-
if(graphs.size() > 1) {
194-
g.fillRect(bounds.width - (xOffset + legendLength + 10) + i * 13, 10, 10, 10);
200+
if(graphs.size() > 1) {
201+
//draw legend rectangle
202+
g.fillRect(10 + legendXOffset, 10, 10, 10);
203+
legendXOffset += 13;
204+
//draw label
205+
g.setColor(boundsColor);
206+
String s = graphs.get(i).label;
207+
if(s != null && s.length() > 0) {
208+
Rectangle2D fBounds = fm.getStringBounds(s, g);
209+
int sWidth = (int)fBounds.getWidth();
210+
g.drawString(s, 10 + legendXOffset, 10 + (int)fBounds.getHeight() /2);
211+
legendXOffset += sWidth + 3;
212+
}
195213
}
196214
}
197215
}
@@ -270,6 +288,17 @@ protected void onEnableWindow(boolean enable) {
270288
private void onSerialRateChange(ActionListener listener) {
271289
serialRates.addActionListener(listener);
272290
}
291+
292+
private void setNewBufferCapacity(int capacity){
293+
if(buffer_capacity != capacity) {
294+
if(capacity > BUFFER_CAPACITY_MAX) capacity = BUFFER_CAPACITY_MAX;
295+
else if(capacity < BUFFER_CAPACITY_MIN) capacity = BUFFER_CAPACITY_MIN;
296+
buffer_capacity = capacity;
297+
for(int i = 0; i < graphs.size(); i++) {
298+
graphs.get(i).buffer.newCapacity(capacity);
299+
}
300+
}
301+
}
273302

274303
public void message(final String s) {
275304
messageBuffer.append(s);
@@ -287,19 +316,81 @@ public void message(final String s) {
287316
if(parts.length == 0) {
288317
continue;
289318
}
290-
319+
291320
int validParts = 0;
321+
int validLabels = 0;
292322
for(int i = 0; i < parts.length; ++i) {
293-
try {
294-
double value = Double.valueOf(parts[i]);
323+
Double value = null;
324+
String label = null;
325+
326+
// all commands start with #
327+
if(parts[i].startsWith("#") && parts[i].length() > 1) {
328+
String command = parts[i].substring(1, parts[i].length()).trim();
329+
if(command.equals("CLEAR")) {
330+
graphs.clear();
331+
}
332+
else if(command.startsWith("SIZE:")) {
333+
String[] subString = parts[i].split("[:]+");
334+
int newSize = BUFFER_CAPACITY_DEFAULT;
335+
if(subString.length > 1) {
336+
try {
337+
newSize = Integer.parseInt(subString[1]);
338+
} catch (NumberFormatException e) {
339+
// Ignore
340+
}
341+
}
342+
setNewBufferCapacity(newSize);
343+
}
344+
} else {
345+
if(parts[i].contains(":")) {
346+
// get label
347+
String[] subString = parts[i].split("[:]+");
348+
349+
if(subString.length > 0) {
350+
int labelLength = subString[0].length();
351+
352+
if(labelLength > 32) {
353+
labelLength = 32;
354+
}
355+
label = subString[0].substring(0, labelLength);
356+
} else {
357+
label = "";
358+
}
359+
360+
if(subString.length > 1) {
361+
parts[i] = subString[1];
362+
} else {
363+
parts[i] = "";
364+
}
365+
}
366+
try {
367+
value = Double.valueOf(parts[i]);
368+
} catch (NumberFormatException e) {
369+
// ignored
370+
}
371+
//CSV header
372+
if(label == null && value == null) {
373+
label = parts[i];
374+
}
375+
}
376+
377+
if(value != null) {
295378
if(validParts >= graphs.size()) {
296-
graphs.add(new Graph(validParts));
379+
graphs.add(new Graph(validParts, buffer_capacity));
297380
}
298381
graphs.get(validParts).buffer.add(value);
299382
validParts++;
300-
} catch (NumberFormatException e) {
301-
// ignore
383+
384+
}
385+
if(label != null) {
386+
if(validLabels >= graphs.size()) {
387+
graphs.add(new Graph(validLabels, buffer_capacity));
388+
}
389+
graphs.get(validLabels).label = label;
390+
validLabels++;
302391
}
392+
if(validParts > validLabels) validLabels = validParts;
393+
else if(validLabels > validParts) validParts = validLabels;
303394
}
304395
}
305396

app/src/processing/app/helpers/CircularBuffer.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
public class CircularBuffer {
66

7-
private final double[] elements;
7+
private double[] elements;
88
private int start = -1;
99
private int end = -1;
10-
private final int capacity;
10+
private int capacity;
1111

1212
public void add(double num) {
1313
end = (end + 1) % capacity;
@@ -36,6 +36,12 @@ public CircularBuffer(int capacity) {
3636
this.capacity = capacity;
3737
elements = new double[capacity];
3838
}
39+
40+
public void newCapacity(int capacity) {
41+
elements = new double[capacity];
42+
this.capacity = capacity;
43+
start = end = 0;
44+
}
3945

4046
public double min() {
4147
if (size() == 0) {

0 commit comments

Comments
 (0)