• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 AndroidPlot.com
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 
17 package com.androidplot.demos;
18 
19 import android.app.Activity;
20 import android.graphics.Color;
21 import android.graphics.DashPathEffect;
22 import android.graphics.Paint;
23 import android.os.Bundle;
24 import android.widget.CheckBox;
25 import android.widget.CompoundButton;
26 import com.androidplot.util.PixelUtils;
27 import com.androidplot.xy.XYSeries;
28 import com.androidplot.ui.*;
29 import com.androidplot.xy.*;
30 
31 import java.text.DecimalFormat;
32 import java.text.FieldPosition;
33 import java.text.NumberFormat;
34 import java.text.ParsePosition;
35 import java.util.Arrays;
36 
37 /**
38  * Demonstration of the usage of Marker and RectRegion.
39  */
40 public class XYRegionExampleActivity extends Activity {
41 
42     private static final float HOME_RUN_DIST = 325;
43     private static final int LINE_THICKNESS_DP = 2;
44     private static final int POINT_SIZE_DP = 6;
45     private XYPlot plot;
46     private final Number[] timHits = {105, 252, 220, 350, 12, 250, 353};
47     private final Number[] nickHits = {110, 191, 61, 371, 289, 101, 10};
48     private final Number[] joeHits = {25, 375, 364, 128, 178, 289, 346};
49     private final Number[] jamesHits = {250, 285, 295, 211, 311, 365, 241};
50     private LineAndPointFormatter timFormatter;
51     private LineAndPointFormatter nickFormatter;
52     private LineAndPointFormatter joeFormatter;
53     private LineAndPointFormatter jamesFormatter;
54 
55     private XYSeries timSeries;
56     private XYSeries nickSeries;
57     private XYSeries joeSeries;
58     private XYSeries jamesSeries;
59 
60     private RectRegion shortRegion;
61     private RectRegion warmupRegion;
62     private RectRegion homeRunRegion;
63 
64     //private XYRegionFormatter rf1;
65     private XYRegionFormatter shortRegionFormatter;
66     private XYRegionFormatter warmupRegionFormatter;
67     private XYRegionFormatter homeRunRegionFormatter;
68     //private XYRegionFormatter rf5;
69 
70     private CheckBox timCB;
71     private CheckBox nickCB;
72     private CheckBox joeCB;
73     private CheckBox jamesCB;
74 
75     private CheckBox r2CheckBox;
76     private CheckBox r3CheckBox;
77     private CheckBox r4CheckBox;
78 
onCreate(Bundle savedInstanceState)79     public void onCreate(Bundle savedInstanceState) {
80         super.onCreate(savedInstanceState);
81         setContentView(R.layout.xyregion_example);
82         plot = (XYPlot) findViewById(R.id.xyRegionExamplePlot);
83         timCB = (CheckBox) findViewById(R.id.s1CheckBox);
84         timCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
85             @Override
86             public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
87                 onS1CheckBoxClicked();
88             }
89         });
90 
91         nickCB = (CheckBox) findViewById(R.id.s2CheckBox);
92         nickCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
93             @Override
94             public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
95                 onS2CheckBoxClicked();
96             }
97         });
98 
99         joeCB = (CheckBox) findViewById(R.id.s3CheckBox);
100         joeCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
101             @Override
102             public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
103                 onS3CheckBoxClicked();
104             }
105         });
106 
107         jamesCB = (CheckBox) findViewById(R.id.s4CheckBox);
108         jamesCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
109             @Override
110             public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
111                 onS4CheckBoxClicked();
112             }
113         });
114 
115 
116 
117         r2CheckBox = (CheckBox) findViewById(R.id.r2CheckBox);
118         r2CheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
119             @Override
120             public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
121                 onCheckBoxClicked(r2CheckBox, timFormatter, shortRegionFormatter, shortRegion);
122             }
123         });
124 
125         r3CheckBox = (CheckBox) findViewById(R.id.r3CheckBox);
126         r3CheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
127             @Override
128             public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
129                 onCheckBoxClicked(r3CheckBox, nickFormatter, warmupRegionFormatter, warmupRegion);
130             }
131         });
132 
133         r4CheckBox = (CheckBox) findViewById(R.id.r4CheckBox);
134         r4CheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
135             @Override
136             public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
137                 onCheckBoxClicked(r4CheckBox, nickFormatter, homeRunRegionFormatter, homeRunRegion);
138             }
139         });
140 
141         seriesSetup();
142         markerSetup();
143         axisLabelSetup();
144         regionSetup();
145         makePlotPretty();
146     }
147 
onS1CheckBoxClicked()148     private void onS1CheckBoxClicked() {
149         if(timCB.isChecked()) {
150             plot.addSeries(timSeries, timFormatter);
151             r2CheckBox.setEnabled(true);
152         } else {
153             plot.removeSeries(timSeries);
154             r2CheckBox.setEnabled(false);
155         }
156         plot.redraw();
157     }
158 
onS2CheckBoxClicked()159     private void onS2CheckBoxClicked() {
160         if(nickCB.isChecked()) {
161             plot.addSeries(nickSeries, nickFormatter);
162             r3CheckBox.setEnabled(true);
163             r4CheckBox.setEnabled(true);
164         } else {
165             plot.removeSeries(nickSeries);
166             r3CheckBox.setEnabled(false);
167             r4CheckBox.setEnabled(false);
168         }
169         plot.redraw();
170     }
171 
onS3CheckBoxClicked()172     private void onS3CheckBoxClicked() {
173         if(joeCB.isChecked()) {
174             plot.addSeries(joeSeries, joeFormatter);
175         } else {
176             plot.removeSeries(joeSeries);
177         }
178         plot.redraw();
179     }
180 
onS4CheckBoxClicked()181     private void onS4CheckBoxClicked() {
182         if(jamesCB.isChecked()) {
183             plot.addSeries(jamesSeries, jamesFormatter);
184         } else {
185             plot.removeSeries(jamesSeries);
186         }
187         plot.redraw();
188     }
189 
190     /**
191      * Processes a check box event
192      * @param cb The checkbox event origin
193      * @param lpf LineAndPointFormatter with which rr and rf are to be added/removed
194      * @param rf The XYRegionFormatter with which rr should be rendered
195      * @param rr The RectRegion to add/remove
196      */
onCheckBoxClicked(CheckBox cb, LineAndPointFormatter lpf, XYRegionFormatter rf, RectRegion rr)197     private void onCheckBoxClicked(CheckBox cb, LineAndPointFormatter lpf,
198                                    XYRegionFormatter rf, RectRegion rr) {
199         if(cb.isChecked()) {
200             lpf.removeRegion(rr);
201         } else {
202             lpf.addRegion(rr, rf);
203         }
204     }
205 
206     /**
207      * Cleans up the plot's general layout and color scheme
208      */
makePlotPretty()209     private void makePlotPretty() {
210         // use a 2x5 grid with room for 10 items:
211         plot.getLegendWidget().setTableModel(new DynamicTableModel(4, 2));
212 
213         // add a semi-transparent black background to the legend
214         // so it's easier to see overlaid on top of our plot:
215         Paint bgPaint = new Paint();
216         bgPaint.setColor(Color.BLACK);
217         bgPaint.setStyle(Paint.Style.FILL);
218         bgPaint.setAlpha(40);
219 
220         plot.getLegendWidget().setBackgroundPaint(bgPaint);
221 
222         // adjust the padding of the legend widget to look a little nicer:
223         plot.getLegendWidget().setPadding(5, 5, 5, 5);
224 
225         plot.setRangeValueFormat(new NumberFormat() {
226             @Override
227             public StringBuffer format(double value, StringBuffer buffer, FieldPosition field) {
228                 return new StringBuffer(value + "'");
229             }
230 
231             @Override
232             public StringBuffer format(long value, StringBuffer buffer, FieldPosition field) {
233                 throw new UnsupportedOperationException("Not yet implemented.");
234             }
235 
236             @Override
237             public Number parse(String string, ParsePosition position) {
238                 throw new UnsupportedOperationException("Not yet implemented.");
239             }
240         });
241 
242         plot.setDomainValueFormat(new DecimalFormat("#"));
243 
244         plot.getLegendWidget().setWidth(PixelUtils.dpToPix(100), SizeLayoutType.FILL);
245 
246 
247         // adjust the legend size so there is enough room
248         // to draw the new legend grid:
249         //plot.getLegendWidget().getHeightMetric().setLayoutType(SizeLayoutType.ABSOLUTE);
250         //plot.getLegendWidget().getWidthMetric().setLayoutType(SizeLayoutType.ABSOLUTE);
251         //plot.getLegendWidget().setSize(
252         //    new SizeMetrics(70, SizeLayoutType.ABSOLUTE, 80, SizeLayoutType.ABSOLUTE));
253 
254         // reposition the grid so that it rests above the bottom-left
255         // edge of the graph widget:
256 
257         plot.getLegendWidget().position(
258                 125,
259                 XLayoutStyle.ABSOLUTE_FROM_LEFT,
260                 65,
261                 YLayoutStyle.ABSOLUTE_FROM_TOP,
262                 AnchorPosition.LEFT_TOP);
263 
264         plot.getGraphWidget().setRangeLabelHorizontalOffset(-1);
265 
266         // add enough space to ensure range value labels arent cut off on the left/right:
267         plot.getGraphWidget().setRangeLabelWidth(25);
268 
269         // add enough space to make sure domain value labels arent cut off on the bottom:
270         plot.getGraphWidget().setDomainLabelWidth(15);
271 
272         plot.getGraphWidget().setDomainLabelVerticalOffset(-6);
273 
274         plot.setRangeBoundaries(0, BoundaryMode.FIXED, 500, BoundaryMode.FIXED);
275     }
276 
277     /**
278      * Create 4 XYSeries from the values defined above add add them to the plot.
279      * Also add some arbitrary regions.
280      */
seriesSetup()281     private void seriesSetup() {
282 
283 
284         // TIM
285         timFormatter = new LineAndPointFormatter(
286                 Color.rgb(100, 25, 20),
287                 Color.rgb(100, 25, 20),
288                 null, null);
289         timFormatter.getLinePaint().setStrokeWidth(PixelUtils.dpToPix(LINE_THICKNESS_DP));
290         timFormatter.getVertexPaint().setStrokeWidth(PixelUtils.dpToPix(POINT_SIZE_DP));
291 
292         timSeries = new SimpleXYSeries(Arrays.asList(timHits),
293             SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Tim");
294 
295         plot.addSeries(timSeries, timFormatter);
296 
297         // SERIES #2:
298         nickFormatter = new LineAndPointFormatter(
299                 Color.rgb(100, 25, 200),
300                 Color.rgb(100, 25, 200),
301                 null, null);
302         nickFormatter.getLinePaint().setStrokeWidth(PixelUtils.dpToPix(LINE_THICKNESS_DP));
303         nickFormatter.getVertexPaint().setStrokeWidth(PixelUtils.dpToPix(POINT_SIZE_DP));
304 
305 
306 
307         nickSeries = new SimpleXYSeries(Arrays.asList(nickHits),
308             SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Nick");
309 
310         plot.addSeries(nickSeries, nickFormatter);
311 
312         // SERIES #3:
313         joeFormatter = new LineAndPointFormatter(
314                 Color.rgb(200, 25, 200),
315                 Color.rgb(200, 25, 200),
316                 null, null);
317         joeFormatter.getLinePaint().setStrokeWidth(PixelUtils.dpToPix(LINE_THICKNESS_DP));
318         joeFormatter.getVertexPaint().setStrokeWidth(PixelUtils.dpToPix(POINT_SIZE_DP));
319 
320         joeSeries = new SimpleXYSeries(Arrays.asList(joeHits),
321             SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Joe");
322 
323         plot.addSeries(joeSeries, joeFormatter);
324 
325         // SERIES #4:
326         jamesFormatter = new LineAndPointFormatter(
327                 Color.rgb(220, 25, 20),
328                 Color.rgb(220, 25, 20),
329                 null, null);
330 
331         jamesFormatter.getLinePaint().setStrokeWidth(PixelUtils.dpToPix(LINE_THICKNESS_DP));
332         jamesFormatter.getVertexPaint().setStrokeWidth(PixelUtils.dpToPix(POINT_SIZE_DP));
333 
334         jamesSeries = new SimpleXYSeries(Arrays.asList(jamesHits),
335             SimpleXYSeries.ArrayFormat.Y_VALS_ONLY,"James");
336         plot.addSeries(jamesSeries, jamesFormatter);
337 
338         plot.setRangeStep(XYStepMode.INCREMENT_BY_VAL, 100);
339         //plot.setTicksPerRangeLabel(1);
340         plot.setDomainStep(XYStepMode.INCREMENT_BY_VAL, 1);
341     }
342 
343     /**
344      * Add some color coded regions to our axis labels.
345      */
axisLabelSetup()346     private void axisLabelSetup() {
347         // DOMAIN
348         plot.getGraphWidget().addDomainAxisValueLabelRegion(
349                 Double.NEGATIVE_INFINITY, 2, new AxisValueLabelFormatter(Color.GRAY));
350         plot.getGraphWidget().addDomainAxisValueLabelRegion(
351                 2, Double.POSITIVE_INFINITY, new AxisValueLabelFormatter(Color.WHITE));
352         // RANGE
353         plot.getGraphWidget().addRangeAxisValueLabelRegion(
354                 Double.NEGATIVE_INFINITY, HOME_RUN_DIST, new AxisValueLabelFormatter(Color.RED));
355         plot.getGraphWidget().addRangeAxisValueLabelRegion(
356                 HOME_RUN_DIST, Double.POSITIVE_INFINITY, new AxisValueLabelFormatter(Color.GREEN));
357     }
358 
359     /**
360      * Add some markers to our plot.
361      */
markerSetup()362     private void markerSetup() {
363 
364         YValueMarker fenwayLfMarker = new YValueMarker(
365                 380,                                        // y-val to mark
366                 "Fenway Park LF Wall",                      // marker label
367                 new XPositionMetric(                        // object instance to set text positioning on the marker
368                         PixelUtils.dpToPix(5),              // 5dp offset
369                         XLayoutStyle.ABSOLUTE_FROM_RIGHT),  // offset origin
370                 Color.BLUE,                                 // line paint color
371                 Color.BLUE);                                // text paint color
372 
373         YValueMarker attRfMarker = new YValueMarker(
374                         309,                                        // y-val to mark
375                         "ATT Park RF Wall",                         // marker label
376                         new XPositionMetric(                        // object instance to set text positioning on the marker
377                                 PixelUtils.dpToPix(5),              // 5dp offset
378                                 XLayoutStyle.ABSOLUTE_FROM_RIGHT),  // offset origin
379                         Color.CYAN,                                 // line paint color
380                         Color.CYAN);                                // text paint color
381 
382 
383         fenwayLfMarker.getTextPaint().setTextSize(PixelUtils.dpToPix(14));
384         attRfMarker.getTextPaint().setTextSize(PixelUtils.dpToPix(14));
385 
386         DashPathEffect dpe = new DashPathEffect(
387                         new float[]{PixelUtils.dpToPix(2), PixelUtils.dpToPix(2)}, 0);
388 
389         fenwayLfMarker.getLinePaint().setPathEffect(dpe);
390         attRfMarker.getLinePaint().setPathEffect(dpe);
391 
392         plot.addMarker(fenwayLfMarker);
393         plot.addMarker(attRfMarker);
394     }
395 
396     /**
397      * Add some fill regions to our series data
398      */
regionSetup()399     private void regionSetup() {
400 
401 
402         // and another region:
403         shortRegionFormatter = new XYRegionFormatter(Color.RED);
404         shortRegionFormatter.getPaint().setAlpha(75);
405         shortRegion = new RectRegion(2, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, HOME_RUN_DIST, "Short");
406         timFormatter.addRegion(shortRegion, shortRegionFormatter);
407         nickFormatter.addRegion(shortRegion, shortRegionFormatter);
408         joeFormatter.addRegion(shortRegion, shortRegionFormatter);
409         jamesFormatter.addRegion(shortRegion, shortRegionFormatter);
410 
411         // the next three regions are horizontal regions with minY/maxY
412         // set to negative and positive infinity respectively.
413         warmupRegionFormatter = new XYRegionFormatter(Color.WHITE);
414         warmupRegionFormatter.getPaint().setAlpha(75);
415 
416         warmupRegion = new RectRegion(0, 2, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, "Warmup");
417         timFormatter.addRegion(warmupRegion, warmupRegionFormatter);
418         nickFormatter.addRegion(warmupRegion, warmupRegionFormatter);
419         joeFormatter.addRegion(warmupRegion, warmupRegionFormatter);
420         jamesFormatter.addRegion(warmupRegion, warmupRegionFormatter);
421 
422         homeRunRegionFormatter = new XYRegionFormatter(Color.GREEN);
423         homeRunRegionFormatter.getPaint().setAlpha(75);
424 
425         homeRunRegion = new RectRegion(2, Double.POSITIVE_INFINITY, HOME_RUN_DIST, Double.POSITIVE_INFINITY, "H. Run");
426         timFormatter.addRegion(homeRunRegion, homeRunRegionFormatter);
427         nickFormatter.addRegion(homeRunRegion, homeRunRegionFormatter);
428         joeFormatter.addRegion(homeRunRegion, homeRunRegionFormatter);
429         jamesFormatter.addRegion(homeRunRegion, homeRunRegionFormatter);
430 
431         nickFormatter.setFillDirection(FillDirection.RANGE_ORIGIN);
432     }
433 }