1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.diyefi.openlogviewer.graphing;
24
25
26 import java.awt.Color;
27 import java.awt.Graphics;
28 import java.awt.Graphics2D;
29 import java.awt.event.HierarchyBoundsListener;
30 import java.awt.event.HierarchyEvent;
31 import java.beans.PropertyChangeEvent;
32 import java.beans.PropertyChangeListener;
33 import java.util.LinkedList;
34 import java.util.ListIterator;
35
36 import javax.swing.JPanel;
37 import org.diyefi.openlogviewer.OpenLogViewerApp;
38 import org.diyefi.openlogviewer.genericlog.GenericDataElement;
39
40
41
42
43
44
45
46
47
48 public class SingleGraphPanel extends JPanel implements HierarchyBoundsListener,PropertyChangeListener {
49
50
51 private GenericDataElement GDE;
52 private LinkedList<Double> leftDataPointsToDisplay;
53 private LinkedList<Double> rightDataPointsToDisplay;
54 private static final double GRAPH_TRACE_SIZE_AS_PERCENTAGE_OF_TOTAL_GRAPH_SIZE = 0.95;
55 private static final long serialVersionUID = -7808406950399781712L;
56
57 public SingleGraphPanel() {
58 this.setOpaque(false);
59 this.setLayout(null);
60 this.GDE = null;
61 leftDataPointsToDisplay = new LinkedList<Double>();
62 rightDataPointsToDisplay = new LinkedList<Double>();
63 }
64
65 @Override
66 public void ancestorMoved(HierarchyEvent e) {
67 }
68
69 @Override
70 public void ancestorResized(HierarchyEvent e) {
71 if (e.getID() == HierarchyEvent.ANCESTOR_RESIZED) {
72 sizeGraph();
73 }
74 }
75
76 @Override
77 public void propertyChange(PropertyChangeEvent evt) {
78 if(evt.getPropertyName().equalsIgnoreCase("Split")){
79 sizeGraph();
80 }
81 }
82
83
84
85 @Override
86 public void paint(Graphics g) {
87 initGraph();
88 if (hasDataPointToDisplay()) {
89 paintLeftDataPoints(g);
90 paintRightDataPoints(g);
91 }
92 }
93
94 private void paintLeftDataPoints(Graphics g){
95
96 Graphics2D g2d = (Graphics2D) g;
97 g2d.setColor(GDE.getColor());
98
99
100 boolean atGraphBeginning = false;
101 boolean firstDataPoint = true;
102 ListIterator<Double> it = (ListIterator<Double>) leftDataPointsToDisplay.iterator();
103 Double traceData = it.next();
104 Double leftOfTraceData = null;
105 Double rightOfTraceData = null;
106 if(it.hasPrevious()){
107 rightOfTraceData = it.previous();
108 it.next();
109 } else {
110 if(rightDataPointsToDisplay.size() > 1){
111 rightOfTraceData = rightDataPointsToDisplay.get(1);
112 } else {
113
114 }
115 }
116 if(it.hasNext()){
117 leftOfTraceData = it.next();
118 it.previous();
119 } else {
120 atGraphBeginning = true;
121 }
122
123
124 int zoom = OpenLogViewerApp.getInstance().getEntireGraphingPanel().getZoom();
125 double graphPosition = OpenLogViewerApp.getInstance().getEntireGraphingPanel().getGraphPosition();
126 double offset = (graphPosition % 1) * zoom;
127 int screenPositionXCoord = (this.getWidth() / 2) - (int)offset;
128 int screenPositionYCoord = getScreenPositionYCoord(traceData, GDE.getMinValue(), GDE.getMaxValue());
129 int prevScreenPositionYCoord = -1;
130
131
132 while(it.hasNext()){
133
134
135 if(zoom > 5 && (!traceData.equals(leftOfTraceData) || !traceData.equals(rightOfTraceData))){
136 g2d.fillOval(screenPositionXCoord - 2, screenPositionYCoord - 2, 4, 4);
137 }
138
139
140 if(!firstDataPoint){
141 g2d.drawLine(screenPositionXCoord, screenPositionYCoord, screenPositionXCoord + zoom, prevScreenPositionYCoord);
142 }
143
144
145 rightOfTraceData = traceData;
146 traceData = it.next();
147 if(it.hasNext()){
148 leftOfTraceData = it.next();
149 it.previous();
150 } else {
151 atGraphBeginning = true;
152 }
153
154
155 prevScreenPositionYCoord = screenPositionYCoord;
156 screenPositionYCoord = getScreenPositionYCoord(traceData, GDE.getMinValue(), GDE.getMaxValue());
157 screenPositionXCoord -= zoom;
158 firstDataPoint = false;
159 }
160
161
162 if(atGraphBeginning){
163 screenPositionYCoord = getScreenPositionYCoord(traceData, GDE.getMinValue(), GDE.getMaxValue());
164
165 if (zoom > 5) {
166 g2d.fillOval(screenPositionXCoord - 2, screenPositionYCoord - 2, 4, 4);
167 }
168
169 if(!firstDataPoint){
170 g2d.drawLine(screenPositionXCoord, screenPositionYCoord, screenPositionXCoord + zoom, prevScreenPositionYCoord);
171 }
172 }
173 }
174
175 private void paintRightDataPoints(Graphics g){
176
177 Graphics2D g2d = (Graphics2D) g;
178 g2d.setColor(GDE.getColor());
179
180
181 boolean atGraphEnd = false;
182 boolean firstDataPoint = true;
183 ListIterator<Double> it = (ListIterator<Double>) rightDataPointsToDisplay.iterator();
184 Double traceData = it.next();
185 Double leftOfTraceData = null;
186 Double rightOfTraceData = null;
187 if(it.hasPrevious()){
188 leftOfTraceData = it.previous();
189 it.next();
190 } else {
191 if(leftDataPointsToDisplay.size() > 1){
192 leftOfTraceData = leftDataPointsToDisplay.get(1);
193 } else {
194
195 }
196 }
197 if(it.hasNext()){
198 rightOfTraceData = it.next();
199 it.previous();
200 } else {
201 atGraphEnd = true;
202 }
203
204
205 int zoom = OpenLogViewerApp.getInstance().getEntireGraphingPanel().getZoom();
206 double graphPosition = OpenLogViewerApp.getInstance().getEntireGraphingPanel().getGraphPosition();
207 double offset = (graphPosition % 1) * zoom;
208 int screenPositionXCoord = (this.getWidth() / 2) - (int)offset;
209 int screenPositionYCoord = getScreenPositionYCoord(traceData, GDE.getMinValue(), GDE.getMaxValue());
210 int prevScreenPositionYCoord = -1;
211
212
213 while(it.hasNext()){
214
215
216 if(zoom > 5 && (!traceData.equals(leftOfTraceData) || !traceData.equals(rightOfTraceData))){
217 g2d.fillOval(screenPositionXCoord - 2, screenPositionYCoord - 2, 4, 4);
218 }
219
220
221 if(!firstDataPoint){
222 g2d.drawLine(screenPositionXCoord, screenPositionYCoord, screenPositionXCoord - zoom, prevScreenPositionYCoord);
223 }
224
225
226 leftOfTraceData = traceData;
227 traceData = it.next();
228 if(it.hasNext()){
229 rightOfTraceData = it.next();
230 it.previous();
231 } else {
232 atGraphEnd = true;
233 }
234
235
236 prevScreenPositionYCoord = screenPositionYCoord;
237 screenPositionYCoord = getScreenPositionYCoord(traceData, GDE.getMinValue(), GDE.getMaxValue());
238 screenPositionXCoord += zoom;
239 firstDataPoint = false;
240 }
241
242
243 if(atGraphEnd){
244 screenPositionYCoord = getScreenPositionYCoord(traceData, GDE.getMinValue(), GDE.getMaxValue());
245
246 if (zoom > 5 && !traceData.equals(leftOfTraceData)) {
247 g2d.fillOval(screenPositionXCoord - 2, screenPositionYCoord - 2, 4, 4);
248 }
249
250 if(!firstDataPoint){
251 g2d.drawLine(screenPositionXCoord, screenPositionYCoord, screenPositionXCoord - zoom, prevScreenPositionYCoord);
252 }
253 }
254 }
255
256 private int getScreenPositionYCoord(Double traceData, double minValue, double maxValue) {
257 int point = 0;
258 int height = (int)(this.getHeight() * GRAPH_TRACE_SIZE_AS_PERCENTAGE_OF_TOTAL_GRAPH_SIZE);
259 if (maxValue != minValue) {
260 point = (int) (height - (height * ((traceData - minValue) / (maxValue - minValue))));
261 }
262 return point;
263 }
264
265 private boolean hasDataPointToDisplay(){
266 boolean result = false;
267 if(leftDataPointsToDisplay != null && leftDataPointsToDisplay.size() > 0){
268 result = true;
269 }
270 return result;
271 }
272
273
274
275
276
277 public void setData(GenericDataElement GDE) {
278 this.GDE = GDE;
279 sizeGraph();
280 }
281
282 public GenericDataElement getData() {
283 return GDE;
284 }
285
286
287
288
289
290
291 public Double getMouseInfo(int cursorDistanceFromCenter) {
292 double graphPosition = OpenLogViewerApp.getInstance().getEntireGraphingPanel().getGraphPosition();
293 int zoom = OpenLogViewerApp.getInstance().getEntireGraphingPanel().getZoom();
294 double offset = (graphPosition % 1) * zoom;
295 cursorDistanceFromCenter += (int)offset;
296 double numSnapsFromCenter = ((double)cursorDistanceFromCenter / (double)zoom);
297 numSnapsFromCenter = Math.round(numSnapsFromCenter);
298 int cursorPosition = (int)graphPosition + (int)numSnapsFromCenter;
299 if (cursorPosition >= 0 && cursorPosition < GDE.size()) {
300 return GDE.get(cursorPosition);
301 } else {
302 return -1.0;
303 }
304 }
305
306
307
308
309 public Color getColor() {
310 return GDE.getColor();
311 }
312
313
314
315
316 public void setColor(Color c) {
317 GDE.setColor(c);
318 }
319
320
321
322
323 public void initGraph() {
324 if (GDE != null) {
325 leftDataPointsToDisplay = new LinkedList<Double>();
326 rightDataPointsToDisplay = new LinkedList<Double>();
327 int graphPosition = (int)OpenLogViewerApp.getInstance().getEntireGraphingPanel().getGraphPosition();
328 int zoom = OpenLogViewerApp.getInstance().getEntireGraphingPanel().getZoom();
329 int numPointsThatFitInDisplay = this.getWidth() / zoom;
330 numPointsThatFitInDisplay += 6;
331 int halfNumPoints = numPointsThatFitInDisplay / 2;
332 int leftGraphPosition = graphPosition - halfNumPoints;
333 int rightGraphPosition = graphPosition + halfNumPoints;
334 for(int i = graphPosition; i > leftGraphPosition; i--){
335 if(i >= 0 && i < GDE.size()){
336 leftDataPointsToDisplay.add(GDE.get(i));
337 }
338 }
339 for(int i = graphPosition; i < rightGraphPosition; i++){
340 if (i >= 0 && i < GDE.size()){
341 rightDataPointsToDisplay.add(GDE.get(i));
342 }
343 }
344 }
345 }
346
347
348
349 public void sizeGraph() {
350 MultiGraphLayeredPane lg = OpenLogViewerApp.getInstance().getMultiGraphLayeredPane();
351 int wherePixel = 0 ;
352 if (lg.getTotalSplits() > 1) {
353 if (GDE.getSplitNumber() <= lg.getTotalSplits()) {
354 wherePixel += lg.getHeight() / lg.getTotalSplits() * GDE.getSplitNumber() - (lg.getHeight() / lg.getTotalSplits());
355 } else {
356 wherePixel += lg.getHeight() / lg.getTotalSplits() * lg.getTotalSplits() - (lg.getHeight() / lg.getTotalSplits());
357 }
358 }
359
360 this.setBounds(0, wherePixel, lg.getWidth(), lg.getHeight() / (lg.getTotalSplits()));
361 initGraph();
362 }
363
364
365
366
367
368 public int graphSize() {
369 return GDE.size();
370 }
371
372 }