Merge commit '42b2e5ca519766e37ce6941ba4faecc9691cc403' into upstream
[debian/openrocket] / android-libraries / achartengine / src / org / achartengine / chart / PieMapper.java
diff --git a/android-libraries/achartengine/src/org/achartengine/chart/PieMapper.java b/android-libraries/achartengine/src/org/achartengine/chart/PieMapper.java
new file mode 100644 (file)
index 0000000..6e4b715
--- /dev/null
@@ -0,0 +1,139 @@
+/**
+ * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL
+ *  
+ * 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.
+ */
+package org.achartengine.chart;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.achartengine.model.Point;
+import org.achartengine.model.SeriesSelection;
+
+/**
+ * PieChart Segment Selection Management.
+ */
+public class PieMapper implements Serializable {
+
+  private List<PieSegment> mPieSegmentList = new ArrayList<PieSegment>();
+
+  private int mPieChartRadius;
+
+  private int mCenterX, mCenterY;
+
+  /**
+   * Set PieChart location on screen.
+   * 
+   * @param pieRadius
+   * @param centerX
+   * @param centerY
+   */
+  public void setDimensions(int pieRadius, int centerX, int centerY) {
+    mPieChartRadius = pieRadius;
+    mCenterX = centerX;
+    mCenterY = centerY;
+  }
+
+  /**
+   * If we have all PieChart Config then there is no point in reloading it
+   * 
+   * @param datasetSize
+   * @return true if cfg for each segment is present
+   */
+  public boolean areAllSegmentPresent(int datasetSize) {
+    return mPieSegmentList.size() == datasetSize;
+  }
+  
+  /**
+   * Add configuration for a PieChart Segment
+   * 
+   * @param dataIndex
+   * @param value
+   * @param startAngle
+   * @param angle
+   */
+  public void addPieSegment(int dataIndex, float value, float startAngle, float angle) {
+    mPieSegmentList.add(new PieSegment(dataIndex, value, startAngle, angle));
+  }
+  
+  /**
+   * Clears the pie segments list.
+   */
+  public void clearPieSegments() {
+    mPieSegmentList.clear();
+  }
+
+  /**
+   * Fetches angle relative to pie chart center point where 3 O'Clock is 0 and
+   * 12 O'Clock is 270degrees
+   * 
+   * @param screenPoint
+   * @return angle in degress from 0-360.
+   */
+  public double getAngle(Point screenPoint) {
+    double dx = screenPoint.getX() - mCenterX;
+    // Minus to correct for coord re-mapping
+    double dy = -(screenPoint.getY() - mCenterY);
+
+    double inRads = Math.atan2(dy, dx);
+
+    // We need to map to coord system when 0 degree is at 3 O'clock, 270 at 12
+    // O'clock
+    if (inRads < 0)
+      inRads = Math.abs(inRads);
+    else
+      inRads = 2 * Math.PI - inRads;
+
+    return Math.toDegrees(inRads);
+  }
+
+  /**
+   * Checks if Point falls within PieChart
+   * 
+   * @param screenPoint
+   * @return true if in PieChart
+   */
+  public boolean isOnPieChart(Point screenPoint) {
+    // Using a bit of Pythagoras
+    // inside circle if (x-center_x)**2 + (y-center_y)**2 <= radius**2:
+
+    double sqValue = (Math.pow(mCenterX - screenPoint.getX(), 2) + Math.pow(
+        mCenterY - screenPoint.getY(), 2));
+
+    double radiusSquared = mPieChartRadius * mPieChartRadius;
+    boolean isOnPieChart = sqValue <= radiusSquared;
+    return isOnPieChart;
+  }
+
+  /**
+   * Fetches the SeriesSelection for the PieSegment selected.
+   * 
+   * @param screenPoint - the user tap location
+   * @return null if screen point is not in PieChart or its config if it is
+   */
+  public SeriesSelection getSeriesAndPointForScreenCoordinate(Point screenPoint) {
+    if (isOnPieChart(screenPoint)) {
+      double angleFromPieCenter = getAngle(screenPoint);
+
+      for (PieSegment pieSeg : mPieSegmentList) {
+        if (pieSeg.isInSegment(angleFromPieCenter)) {
+          return new SeriesSelection(0, pieSeg.getDataIndex(), pieSeg.getValue(),
+              pieSeg.getValue());
+        }
+      }
+    }
+    return null;
+  }
+}