23
23
import processing .app .helpers .Ticks ;
24
24
import processing .app .legacy .PApplet ;
25
25
26
+ import java .util .ArrayList ;
26
27
import javax .swing .*;
27
28
import javax .swing .border .EmptyBorder ;
28
29
import java .awt .*;
35
36
public class SerialPlotter extends AbstractMonitor {
36
37
37
38
private final StringBuffer messageBuffer ;
38
- private CircularBuffer buffer ;
39
39
private JComboBox <String > serialRates ;
40
40
private Serial serial ;
41
41
private int serialRate ;
42
42
43
+ private ArrayList <Graph > graphs ;
44
+ private final static int BUFFER_CAPACITY = 500 ;
45
+
46
+ private static class Graph {
47
+ public CircularBuffer buffer ;
48
+ private Color color ;
49
+
50
+ public Graph (int id ) {
51
+ buffer = new CircularBuffer (BUFFER_CAPACITY );
52
+ color = Theme .getColorCycleColor ("plotting.graphcolor" , id );
53
+ }
54
+
55
+ public void paint (Graphics2D g , float xstep , double minY ,
56
+ double maxY , double rangeY , double height ) {
57
+ g .setColor (color );
58
+ g .setStroke (new BasicStroke (1.0f ));
59
+
60
+ for (int i = 0 ; i < buffer .size () - 1 ; ++i ) {
61
+ g .drawLine (
62
+ (int ) (i * xstep ), (int ) transformY (buffer .get (i ), minY , rangeY , height ),
63
+ (int ) ((i + 1 ) * xstep ), (int ) transformY (buffer .get (i + 1 ), minY , rangeY , height )
64
+ );
65
+ }
66
+ }
67
+
68
+ private float transformY (double rawY , double minY , double rangeY , double height ) {
69
+ return (float ) (5 + (height - 10 ) * (1.0 - (rawY - minY ) / rangeY ));
70
+ }
71
+ }
72
+
43
73
private class GraphPanel extends JPanel {
44
74
private double minY , maxY , rangeY ;
45
75
private Rectangle bounds ;
46
76
private int xOffset ;
47
77
private final Font font ;
48
- private final Color graphColor ;
78
+ private final Color bgColor ;
49
79
50
80
public GraphPanel () {
51
81
font = Theme .getFont ("console.font" );
52
- graphColor = Theme .getColor ("header .bgcolor" );
82
+ bgColor = Theme .getColor ("plotting .bgcolor" );
53
83
xOffset = 20 ;
54
84
}
55
85
86
+ private Ticks computeBounds () {
87
+ minY = Double .POSITIVE_INFINITY ;
88
+ maxY = Double .NEGATIVE_INFINITY ;
89
+ for (Graph g : graphs ) {
90
+ double bMin = g .buffer .min () / 2.0 ;
91
+ double bMax = g .buffer .max () * 2.0 ;
92
+ minY = bMin < minY ? bMin : minY ;
93
+ maxY = bMax > maxY ? bMax : maxY ;
94
+ }
95
+
96
+ Ticks ticks = new Ticks (minY , maxY , 3 );
97
+ minY = Math .min (minY , ticks .getTick (0 ));
98
+ maxY = Math .max (maxY , ticks .getTick (ticks .getTickCount () - 1 ));
99
+ rangeY = maxY - minY ;
100
+ minY -= 0.05 * rangeY ;
101
+ maxY += 0.05 * rangeY ;
102
+ rangeY = maxY - minY ;
103
+ return ticks ;
104
+ }
105
+
56
106
@ Override
57
107
public void paintComponent (Graphics g1 ) {
58
108
Graphics2D g = (Graphics2D ) g1 ;
@@ -61,20 +111,12 @@ public void paintComponent(Graphics g1) {
61
111
super .paintComponent (g );
62
112
63
113
bounds = g .getClipBounds ();
64
- setBackground (Color . WHITE );
65
- if (buffer .isEmpty ()) {
114
+ setBackground (bgColor );
115
+ if (graphs .isEmpty ()) {
66
116
return ;
67
117
}
68
118
69
- minY = buffer .min () / 2 ;
70
- maxY = buffer .max () * 2 ;
71
- Ticks ticks = new Ticks (minY , maxY , 3 );
72
- minY = Math .min (minY , ticks .getTick (0 ));
73
- maxY = Math .max (maxY , ticks .getTick (ticks .getTickCount () - 1 ));
74
- rangeY = maxY - minY ;
75
- minY -= 0.05 * rangeY ;
76
- maxY += 0.05 * rangeY ;
77
- rangeY = maxY - minY ;
119
+ Ticks ticks = computeBounds ();
78
120
79
121
g .setStroke (new BasicStroke (1.0f ));
80
122
FontMetrics fm = g .getFontMetrics ();
@@ -92,19 +134,21 @@ public void paintComponent(Graphics g1) {
92
134
g .drawLine (bounds .x + xOffset , bounds .y + 5 , bounds .x + xOffset , bounds .y + bounds .height - 10 );
93
135
94
136
g .setTransform (AffineTransform .getTranslateInstance (xOffset , 0 ));
95
- float xstep = (float ) (bounds .width - xOffset ) / (float ) buffer .capacity ();
96
-
97
- g .setColor (graphColor );
98
- g .setStroke (new BasicStroke (0.75f ));
99
-
100
- for (int i = 0 ; i < buffer .size () - 1 ; ++i ) {
101
- g .drawLine (
102
- (int ) (i * xstep ), (int ) transformY (buffer .get (i )),
103
- (int ) ((i + 1 ) * xstep ), (int ) transformY (buffer .get (i + 1 ))
104
- );
137
+ float xstep = (float ) (bounds .width - xOffset ) / (float ) BUFFER_CAPACITY ;
138
+ int legendLength = graphs .size () * 10 + (graphs .size () - 1 ) * 3 ;
139
+
140
+ for (int i = 0 ; i < graphs .size (); ++i ) {
141
+ graphs .get (i ).paint (g , xstep , minY , maxY , rangeY , bounds .height );
142
+ if (graphs .size () > 1 ) {
143
+ g .fillRect (bounds .width - (xOffset + legendLength + 10 ) + i * 13 , 10 , 10 , 10 );
144
+ }
105
145
}
106
146
}
107
147
148
+ private float transformY (double rawY ) {
149
+ return (float ) (5 + (bounds .height - 10 ) * (1.0 - (rawY - minY ) / rangeY ));
150
+ }
151
+
108
152
@ Override
109
153
public Dimension getMinimumSize () {
110
154
return new Dimension (200 , 100 );
@@ -114,10 +158,6 @@ public Dimension getMinimumSize() {
114
158
public Dimension getPreferredSize () {
115
159
return new Dimension (500 , 250 );
116
160
}
117
-
118
- private float transformY (double rawY ) {
119
- return (float ) (5 + (bounds .height - 10 ) * (1.0 - (rawY - minY ) / rangeY ));
120
- }
121
161
}
122
162
123
163
public SerialPlotter (BoardPort port ) {
@@ -140,12 +180,12 @@ public SerialPlotter(BoardPort port) {
140
180
});
141
181
142
182
messageBuffer = new StringBuffer ();
183
+ graphs = new ArrayList <Graph >();
143
184
}
144
185
145
186
protected void onCreateWindow (Container mainPane ) {
146
187
mainPane .setLayout (new BorderLayout ());
147
188
148
- buffer = new CircularBuffer (500 );
149
189
GraphPanel graphPanel = new GraphPanel ();
150
190
151
191
mainPane .add (graphPanel , BorderLayout .CENTER );
@@ -182,14 +222,26 @@ public void message(final String s) {
182
222
}
183
223
184
224
String line = messageBuffer .substring (0 , linebreak );
185
- line = line .trim ();
186
225
messageBuffer .delete (0 , linebreak + 1 );
187
226
188
- try {
189
- double value = Double .valueOf (line );
190
- buffer .add (value );
191
- } catch (NumberFormatException e ) {
192
- // ignore
227
+ line = line .trim ();
228
+ String [] parts = line .split ("[, \t ]+" );
229
+ if (parts .length == 0 ) {
230
+ continue ;
231
+ }
232
+
233
+ int validParts = 0 ;
234
+ for (int i = 0 ; i < parts .length ; ++i ) {
235
+ try {
236
+ double value = Double .valueOf (parts [i ]);
237
+ if (i >= graphs .size ()) {
238
+ graphs .add (new Graph (validParts ));
239
+ }
240
+ graphs .get (validParts ).buffer .add (value );
241
+ validParts ++;
242
+ } catch (NumberFormatException e ) {
243
+ // ignore
244
+ }
193
245
}
194
246
}
195
247
0 commit comments