From 7893160306fcba7baacd8db46745ede00b35bc0a Mon Sep 17 00:00:00 2001 From: hannesa2 Date: Sun, 22 Apr 2018 18:24:06 +0200 Subject: [PATCH 01/38] update to Android Studio 3.1.1 (#77) --- build.gradle | 6 +++--- demoapp-wearable/build.gradle | 5 +++-- demoapp/build.gradle | 8 ++++---- gradle/wrapper/gradle-wrapper.properties | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/build.gradle b/build.gradle index d9bdfbfc..a7aa9c13 100644 --- a/build.gradle +++ b/build.gradle @@ -38,9 +38,9 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' - classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' + classpath 'com.android.tools.build:gradle:3.1.1' + classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0' classpath 'com.vanniktech:gradle-android-junit-jacoco-plugin:0.6.0' classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.6.3' } diff --git a/demoapp-wearable/build.gradle b/demoapp-wearable/build.gradle index b4afad27..22e5186d 100644 --- a/demoapp-wearable/build.gradle +++ b/demoapp-wearable/build.gradle @@ -17,9 +17,10 @@ buildscript { repositories { jcenter() + google() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' + classpath 'com.android.tools.build:gradle:3.1.1' } } apply plugin: 'com.android.application' @@ -54,6 +55,6 @@ android { dependencies { compile project(':androidplot-core') - compile 'com.google.android.support:wearable:1.3.0' + compile 'com.google.android.support:wearable:2.3.0' compile 'com.google.android.gms:play-services-wearable:8.3.0' } diff --git a/demoapp/build.gradle b/demoapp/build.gradle index c501ed33..36a7c800 100644 --- a/demoapp/build.gradle +++ b/demoapp/build.gradle @@ -21,9 +21,9 @@ dependencies { compile project(':androidplot-core') compile 'com.crittercism:crittercism-android-agent:5.4.0' - debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1' - releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1' - testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1' + debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.4' + releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4' + testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4' } buildscript { @@ -32,7 +32,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.github.triplet.gradle:play-publisher:1.1.5' + classpath 'com.github.triplet.gradle:play-publisher:1.2.0' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6bd840a3..42a64d0b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip From c53ac24397e25032c444304951c50152ff5a39ad Mon Sep 17 00:00:00 2001 From: Nick Fellows Date: Fri, 4 May 2018 13:47:45 -0500 Subject: [PATCH 02/38] include full apache 2.0 license in LICENSE.md --- LICENSE.md | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 198 insertions(+), 10 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index 3fbf0a78..f49a4e16 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,13 +1,201 @@ - Copyright 2018 Androidplot.com + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - http://www.apache.org/licenses/LICENSE-2.0 + 1. Definitions. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file From f58cd6b43859886a7141d8294c16069d85baf768 Mon Sep 17 00:00:00 2001 From: Nick Fellows Date: Wed, 23 May 2018 11:18:38 -0500 Subject: [PATCH 03/38] 1.5.5 changes (#79) * remove unused button from simple xy plot * #78 Fixes issue where setting XYGraphWidget insets has no effect. * XYGraphWidget.drawMarkerText is now protected instead of private. * 1.5.5 documentation updates --- .../com/androidplot/xy/XYGraphWidget.java | 54 +++++----- .../com/androidplot/xy/XYGraphWidgetTest.java | 98 ++++++++++--------- .../demos/SimpleXYPlotActivity.java | 17 +++- .../res/layout/simple_xy_plot_example.xml | 6 -- docs/quickstart.md | 2 +- docs/release_notes.md | 6 ++ 6 files changed, 107 insertions(+), 76 deletions(-) diff --git a/androidplot-core/src/main/java/com/androidplot/xy/XYGraphWidget.java b/androidplot-core/src/main/java/com/androidplot/xy/XYGraphWidget.java index 23506f64..1ca3de77 100644 --- a/androidplot-core/src/main/java/com/androidplot/xy/XYGraphWidget.java +++ b/androidplot-core/src/main/java/com/androidplot/xy/XYGraphWidget.java @@ -530,8 +530,15 @@ protected float seriesToScreenY(Number y) { @Override protected void onResize(@Nullable RectF oldRect, @NonNull RectF newRect) { - gridRect = RectFUtils.applyInsets(newRect, gridInsets); - labelRect = RectFUtils.applyInsets(newRect, lineLabelInsets); + recalculateSizes(newRect); + } + + protected void recalculateSizes(@Nullable RectF rect) { + if(rect == null) { + rect = getWidgetDimensions().paddedRect; + } + gridRect = RectFUtils.applyInsets(rect, gridInsets); + labelRect = RectFUtils.applyInsets(rect, lineLabelInsets); } @Override @@ -694,27 +701,29 @@ protected void drawGrid(Canvas canvas) { * @param x * @param y */ - private void drawMarkerText(Canvas canvas, String text, ValueMarker marker, + protected void drawMarkerText(Canvas canvas, String text, ValueMarker marker, float x, float y) { - x += MARKER_LABEL_SPACING; - y -= MARKER_LABEL_SPACING; - RectF textRect = new RectF(FontUtils.getStringDimensions( - text, - marker.getTextPaint() - )); - textRect.offsetTo(x, y - textRect.height()); + if (marker.getText() != null) { + x += MARKER_LABEL_SPACING; + y -= MARKER_LABEL_SPACING; + RectF textRect = new RectF(FontUtils.getStringDimensions( + text, + marker.getTextPaint() + )); + textRect.offsetTo(x, y - textRect.height()); + + if (textRect.right > gridRect.right) { + textRect.offset(-(textRect.right - gridRect.right), ZERO); + } - if (textRect.right > gridRect.right) { - textRect.offset(-(textRect.right - gridRect.right), ZERO); - } + if (textRect.top < gridRect.top) { + textRect.offset(0, gridRect.top - textRect.top); + } - if (textRect.top < gridRect.top) { - textRect.offset(0, gridRect.top - textRect.top); + canvas.drawText(text, textRect.left, textRect.bottom, + marker.getTextPaint() + ); } - - canvas.drawText(text, textRect.left, textRect.bottom, - marker.getTextPaint() - ); } protected void drawMarkers(Canvas canvas) { @@ -731,10 +740,7 @@ protected void drawMarkers(Canvas canvas) { float xPix = marker.getTextPosition().getPixelValue( gridRect.width()); xPix += gridRect.left; - - if (marker.getText() != null) { - drawMarkerText(canvas, marker.getText(), marker, xPix, yPix); - } + drawMarkerText(canvas, marker.getText(), marker, xPix, yPix); } } } @@ -1149,6 +1155,7 @@ public Insets getGridInsets() { public void setGridInsets(Insets gridInsets) { this.gridInsets = gridInsets; + recalculateSizes(null); } /** @@ -1160,6 +1167,7 @@ public Insets getLineLabelInsets() { public void setLineLabelInsets(Insets lineLabelInsets) { this.lineLabelInsets = lineLabelInsets; + recalculateSizes(null); } public RectF getGridRect() { diff --git a/androidplot-core/src/test/java/com/androidplot/xy/XYGraphWidgetTest.java b/androidplot-core/src/test/java/com/androidplot/xy/XYGraphWidgetTest.java index 9f92afa8..65d3898a 100644 --- a/androidplot-core/src/test/java/com/androidplot/xy/XYGraphWidgetTest.java +++ b/androidplot-core/src/test/java/com/androidplot/xy/XYGraphWidgetTest.java @@ -21,6 +21,7 @@ import com.androidplot.test.*; import com.androidplot.ui.*; +import com.androidplot.util.DisplayDimensions; import org.junit.*; import org.mockito.*; @@ -67,7 +68,7 @@ public class XYGraphWidgetTest extends AndroidplotTest { @Before - public void setUp() throws Exception { + public void setUp() { size = spy(new Size(100, SizeMode.ABSOLUTE, 100, SizeMode.ABSOLUTE)); xyPlot = spy(new XYPlot(getContext(), "XYPlot")); when(xyPlot.getRegistry()).thenReturn(seriesRegistry); @@ -83,13 +84,8 @@ public void setUp() throws Exception { graphWidget.setLabelRect(new RectF(0, 0, 100, 100)); } - @After - public void tearDown() throws Exception { - - } - @Test - public void testProcessAttrs() throws Exception { + public void processAttrs_withDefaults_disablesGridClipping() { XYGraphWidget graphWidget = spy(new XYGraphWidget(layoutManager, xyPlot, size)); graphWidget.processAttrs(typedArray); @@ -97,7 +93,7 @@ public void testProcessAttrs() throws Exception { } @Test - public void testDoOnDraw_drawGridOnTopFalse() throws Exception { + public void doOnDraw_drawGridOnTopFalse_drawsGridAfterData() throws Exception { XYGraphWidget graphWidget = spy(new XYGraphWidget(layoutManager, xyPlot, size)); graphWidget.setDrawGridOnTop(false); doNothing().when(graphWidget).drawGrid(canvas); @@ -113,7 +109,7 @@ public void testDoOnDraw_drawGridOnTopFalse() throws Exception { } @Test - public void testDoOnDraw_drawGridOnTopTrue() throws Exception { + public void doOnDraw_drawGridOnTopTrue_drawsGridBeforeData() throws Exception { XYGraphWidget graphWidget = spy(new XYGraphWidget(layoutManager, xyPlot, size)); graphWidget.setDrawGridOnTop(true); doNothing().when(graphWidget).drawGrid(canvas); @@ -129,7 +125,7 @@ public void testDoOnDraw_drawGridOnTopTrue() throws Exception { } @Test - public void testDrawMarkers() throws Exception { + public void drawMarkers_drawsLineForEachMarker() { xyPlot.addMarker(new XValueMarker(1, "x")); xyPlot.addMarker(new YValueMarker(-1, "y")); @@ -140,42 +136,22 @@ public void testDrawMarkers() throws Exception { .drawLine(anyFloat(), anyFloat(), anyFloat(), anyFloat(), any(Paint.class)); } - protected void runDrawGridTest() { - doNothing().when(graphWidget). - drawDomainLine(any(Canvas.class), anyFloat(), any(Number.class), any(Paint.class), anyBoolean()); - - doNothing().when(graphWidget). - drawRangeLine(any(Canvas.class), anyFloat(), any(Number.class), any(Paint.class), anyBoolean()); - - xyPlot.setRangeBoundaries(0, 100, BoundaryMode.FIXED); - xyPlot.setDomainBoundaries(0, 100, BoundaryMode.FIXED); - - graphWidget.drawGrid(canvas); - - // expecting a 100x100 grid to be drawn: - verify(graphWidget, times(100)) - .drawDomainLine(eq(canvas), anyFloat(), anyFloat(), any(Paint.class), eq(false)); - - verify(graphWidget, times(100)) - .drawRangeLine(eq(canvas), anyFloat(), anyFloat(), any(Paint.class), eq(false)); - } - @Test - public void testDrawGrid_nullOrigin() throws Exception { + public void drawGrid_nullOrigin_drawsGrid() { when(xyPlot.getDomainOrigin()).thenReturn(null); when(xyPlot.getRangeOrigin()).thenReturn(null); runDrawGridTest(); } @Test - public void testDrawGrid_zeroOrigin() throws Exception { + public void drawGrid_zeroOrigin_drawsGrid() { when(xyPlot.getDomainOrigin()).thenReturn(0); when(xyPlot.getRangeOrigin()).thenReturn(0); runDrawGridTest(); } @Test - public void testDrawGrid_centeredOrigin() throws Exception { + public void drawGrid_centeredOrigin_drawsGrid() { // set origin to midpoint so we exercise // code to draw lines on both sides of the origin: @@ -185,7 +161,7 @@ public void testDrawGrid_centeredOrigin() throws Exception { } @Test - public void testDrawCursors_ifCursorPaintAndPositionAreSet() throws Exception { + public void drawCursors_withCursorPaintAndPosition_drawsCursorLines() { final Paint domainCursorPaint = new Paint(); graphWidget.setDomainCursorPaint(domainCursorPaint); @@ -201,7 +177,7 @@ public void testDrawCursors_ifCursorPaintAndPositionAreSet() throws Exception { } @Test - public void testDrawCursors_ifCursorPaintAndPositionAreNotSet() throws Exception { + public void testDrawCursors_noCursorPaintOrPosition_drawsNoCursorLines() { graphWidget.setDomainCursorPaint(null); graphWidget.setRangeCursorPaint(null); @@ -212,7 +188,7 @@ public void testDrawCursors_ifCursorPaintAndPositionAreNotSet() throws Exception } @Test - public void testDrawCursorLabel() throws Exception { + public void drawCursorLabel_drawsText() { graphWidget.setDomainCursorPosition(0f); graphWidget.setRangeCursorPosition(0f); XYGraphWidget.CursorLabelFormatter clf = mock(XYGraphWidget.CursorLabelFormatter.class); @@ -224,7 +200,7 @@ public void testDrawCursorLabel() throws Exception { } @Test - public void testSetLineLabelEdges() throws Exception { + public void setLineLabelEdges_setsEdges() { graphWidget.setLineLabelEdges(XYGraphWidget.Edge.LEFT, XYGraphWidget.Edge.BOTTOM); assertTrue(graphWidget.isLineLabelEnabled(XYGraphWidget.Edge.LEFT)); @@ -238,7 +214,7 @@ public void testSetLineLabelEdges() throws Exception { } @Test - public void testSetLineLabelEdges_bitfield() throws Exception { + public void setLineLabelEdges_bitfield_setsEdges() { graphWidget.setLineLabelEdges( XYGraphWidget.Edge.TOP.getValue() | XYGraphWidget.Edge.RIGHT.getValue()); @@ -250,7 +226,7 @@ public void testSetLineLabelEdges_bitfield() throws Exception { } @Test - public void testScreenToSeries() throws Exception { + public void screenToSeries_returnsSeriesCoords() { when(xyPlot.getBounds()).thenReturn(new RectRegion(-100, 100, -100, 100)); XYCoords coords = graphWidget.screenToSeries(new PointF(0, 0)); @@ -267,7 +243,7 @@ public void testScreenToSeries() throws Exception { } @Test - public void testSeriesToScreen() throws Exception { + public void seriesToScreen_returnsScreenPoint() { when(xyPlot.getBounds()).thenReturn(new RectRegion(-100, 100, -100, 100)); PointF point = graphWidget.seriesToScreen(new XYCoords(-100, 100)); @@ -284,7 +260,7 @@ public void testSeriesToScreen() throws Exception { } @Test - public void testScreenToSeriesX() throws Exception { + public void screenToSeriesX_returnsSeriesValue() { when(xyPlot.getBounds()).thenReturn(new RectRegion(-100, 100, -100, 100)); assertEquals(-100, graphWidget.screenToSeriesX(new PointF(0, 0)).intValue()); @@ -293,7 +269,7 @@ public void testScreenToSeriesX() throws Exception { } @Test - public void testScreenToSeriesY() throws Exception { + public void screenToSeriesY_returnsSeriesValue() { when(xyPlot.getBounds()).thenReturn(new RectRegion(-100, 100, -100, 100)); assertEquals(100, graphWidget.screenToSeriesY(new PointF(0, 0)).intValue()); @@ -302,7 +278,7 @@ public void testScreenToSeriesY() throws Exception { } @Test - public void testSeriesToScreenX() throws Exception { + public void seriesToScreenX_returnsScreenValue() { when(xyPlot.getBounds()).thenReturn(new RectRegion(-100, 100, -100, 100)); assertEquals(0f, graphWidget.seriesToScreenX(-100)); @@ -311,11 +287,45 @@ public void testSeriesToScreenX() throws Exception { } @Test - public void testSeriesToScreenY() throws Exception { + public void seriesToScreenY_returnsScreenValue() { when(xyPlot.getBounds()).thenReturn(new RectRegion(-100, 100, -100, 100)); assertEquals(100f, graphWidget.seriesToScreenY(100)); assertEquals(0f, graphWidget.seriesToScreenY(-100)); assertEquals(50f, graphWidget.seriesToScreenY(0)); } + + @Test + public void setGridInsets_updatesGridRect() { + graphWidget.setGridInsets(new Insets(0, 0, 0, 0)); + final RectF oldRect = graphWidget.getGridRect(); + + graphWidget.setGridInsets(new Insets(2, 2, 2, 2)); + final RectF newRect = graphWidget.getGridRect(); + + assertEquals(oldRect.left + 2, newRect.left); + assertEquals(oldRect.top + 2, newRect.top); + assertEquals(oldRect.right - 2, newRect.right); + assertEquals(oldRect.bottom -2, newRect.bottom); + } + + private void runDrawGridTest() { + doNothing().when(graphWidget). + drawDomainLine(any(Canvas.class), anyFloat(), any(Number.class), any(Paint.class), anyBoolean()); + + doNothing().when(graphWidget). + drawRangeLine(any(Canvas.class), anyFloat(), any(Number.class), any(Paint.class), anyBoolean()); + + xyPlot.setRangeBoundaries(0, 100, BoundaryMode.FIXED); + xyPlot.setDomainBoundaries(0, 100, BoundaryMode.FIXED); + + graphWidget.drawGrid(canvas); + + // expecting a 100x100 grid to be drawn: + verify(graphWidget, times(100)) + .drawDomainLine(eq(canvas), anyFloat(), anyFloat(), any(Paint.class), eq(false)); + + verify(graphWidget, times(100)) + .drawRangeLine(eq(canvas), anyFloat(), anyFloat(), any(Paint.class), eq(false)); + } } diff --git a/demoapp/src/main/java/com/androidplot/demos/SimpleXYPlotActivity.java b/demoapp/src/main/java/com/androidplot/demos/SimpleXYPlotActivity.java index b673f512..6238e4df 100644 --- a/demoapp/src/main/java/com/androidplot/demos/SimpleXYPlotActivity.java +++ b/demoapp/src/main/java/com/androidplot/demos/SimpleXYPlotActivity.java @@ -21,8 +21,7 @@ import android.os.Bundle; import android.support.annotation.NonNull; -import com.androidplot.ui.Size; -import com.androidplot.ui.SizeMode; +import com.androidplot.ui.Insets; import com.androidplot.util.PixelUtils; import com.androidplot.xy.CatmullRomInterpolator; import com.androidplot.xy.LineAndPointFormatter; @@ -102,5 +101,19 @@ public Object parseObject(String source, @NonNull ParsePosition pos) { return null; } }); + + new Thread(new Runnable() { + + @Override + public void run() { + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + plot.getGraph().setGridInsets(new Insets(120, 120, 120, 120)); + plot.redraw(); + } + }).start(); } } diff --git a/demoapp/src/main/res/layout/simple_xy_plot_example.xml b/demoapp/src/main/res/layout/simple_xy_plot_example.xml index 48aeb5cb..08a2c5af 100644 --- a/demoapp/src/main/res/layout/simple_xy_plot_example.xml +++ b/demoapp/src/main/res/layout/simple_xy_plot_example.xml @@ -33,10 +33,4 @@ ap:lineLabelRotationBottom="-45" android:layout_weight="1"/> -