26
26
import java .util .ArrayList ;
27
27
import javax .swing .*;
28
28
import javax .swing .border .EmptyBorder ;
29
+
30
+ import com .jcraft .jsch .Buffer ;
31
+
29
32
import java .awt .*;
30
33
import java .awt .event .ActionListener ;
31
34
import java .awt .geom .AffineTransform ;
@@ -42,14 +45,18 @@ public class SerialPlotter extends AbstractMonitor {
42
45
private int serialRate , xCount ;
43
46
44
47
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 ;
46
52
47
53
private static class Graph {
48
54
public CircularBuffer buffer ;
55
+ public String label ;
49
56
private Color color ;
50
57
51
- public Graph (int id ) {
52
- buffer = new CircularBuffer (BUFFER_CAPACITY );
58
+ public Graph (int id , int capacity ) {
59
+ buffer = new CircularBuffer (capacity );
53
60
color = Theme .getColorCycleColor ("plotting.graphcolor" , id );
54
61
}
55
62
@@ -147,12 +154,12 @@ public void paintComponent(Graphics g1) {
147
154
}
148
155
149
156
// 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 ;
152
159
153
160
double zeroTick = ticks .getTick (0 );
154
161
double lastTick = ticks .getTick (ticks .getTickCount () - 1 );
155
- double xTickRange = BUFFER_CAPACITY / ticks .getTickCount ();
162
+ double xTickRange = buffer_capacity / ticks .getTickCount ();
156
163
157
164
for (int i = 0 ; i < ticks .getTickCount () + 1 ; i ++) {
158
165
String s ;
@@ -168,7 +175,7 @@ public void paintComponent(Graphics g1) {
168
175
s = String .valueOf ((int )(xTickRange * i )+cnt );
169
176
fBounds = fm .getStringBounds (s , g );
170
177
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 );
172
179
}
173
180
// draw graph x axis, ticks and labels
174
181
g .setColor (boundsColor );
@@ -185,13 +192,24 @@ public void paintComponent(Graphics g1) {
185
192
g .drawLine (xOffset , (int ) transformY (zeroTick ), bounds .width - xPadding , (int )transformY (zeroTick ));
186
193
187
194
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 ;
191
198
for (int i = 0 ; i < graphs .size (); ++i ) {
192
199
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
+ }
195
213
}
196
214
}
197
215
}
@@ -270,6 +288,17 @@ protected void onEnableWindow(boolean enable) {
270
288
private void onSerialRateChange (ActionListener listener ) {
271
289
serialRates .addActionListener (listener );
272
290
}
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
+ }
273
302
274
303
public void message (final String s ) {
275
304
messageBuffer .append (s );
@@ -287,19 +316,81 @@ public void message(final String s) {
287
316
if (parts .length == 0 ) {
288
317
continue ;
289
318
}
290
-
319
+
291
320
int validParts = 0 ;
321
+ int validLabels = 0 ;
292
322
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 ) {
295
378
if (validParts >= graphs .size ()) {
296
- graphs .add (new Graph (validParts ));
379
+ graphs .add (new Graph (validParts , buffer_capacity ));
297
380
}
298
381
graphs .get (validParts ).buffer .add (value );
299
382
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 ++;
302
391
}
392
+ if (validParts > validLabels ) validLabels = validParts ;
393
+ else if (validLabels > validParts ) validParts = validLabels ;
303
394
}
304
395
}
305
396
0 commit comments