2 * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.achartengine.chart;
18 import java.io.Serializable;
19 import java.util.ArrayList;
20 import java.util.List;
22 import org.achartengine.model.Point;
23 import org.achartengine.model.SeriesSelection;
26 * PieChart Segment Selection Management.
28 public class PieMapper implements Serializable {
30 private List<PieSegment> mPieSegmentList = new ArrayList<PieSegment>();
32 private int mPieChartRadius;
34 private int mCenterX, mCenterY;
37 * Set PieChart location on screen.
43 public void setDimensions(int pieRadius, int centerX, int centerY) {
44 mPieChartRadius = pieRadius;
50 * If we have all PieChart Config then there is no point in reloading it
53 * @return true if cfg for each segment is present
55 public boolean areAllSegmentPresent(int datasetSize) {
56 return mPieSegmentList.size() == datasetSize;
60 * Add configuration for a PieChart Segment
67 public void addPieSegment(int dataIndex, float value, float startAngle, float angle) {
68 mPieSegmentList.add(new PieSegment(dataIndex, value, startAngle, angle));
72 * Clears the pie segments list.
74 public void clearPieSegments() {
75 mPieSegmentList.clear();
79 * Fetches angle relative to pie chart center point where 3 O'Clock is 0 and
80 * 12 O'Clock is 270degrees
83 * @return angle in degress from 0-360.
85 public double getAngle(Point screenPoint) {
86 double dx = screenPoint.getX() - mCenterX;
87 // Minus to correct for coord re-mapping
88 double dy = -(screenPoint.getY() - mCenterY);
90 double inRads = Math.atan2(dy, dx);
92 // We need to map to coord system when 0 degree is at 3 O'clock, 270 at 12
95 inRads = Math.abs(inRads);
97 inRads = 2 * Math.PI - inRads;
99 return Math.toDegrees(inRads);
103 * Checks if Point falls within PieChart
106 * @return true if in PieChart
108 public boolean isOnPieChart(Point screenPoint) {
109 // Using a bit of Pythagoras
110 // inside circle if (x-center_x)**2 + (y-center_y)**2 <= radius**2:
112 double sqValue = (Math.pow(mCenterX - screenPoint.getX(), 2) + Math.pow(
113 mCenterY - screenPoint.getY(), 2));
115 double radiusSquared = mPieChartRadius * mPieChartRadius;
116 boolean isOnPieChart = sqValue <= radiusSquared;
121 * Fetches the SeriesSelection for the PieSegment selected.
123 * @param screenPoint - the user tap location
124 * @return null if screen point is not in PieChart or its config if it is
126 public SeriesSelection getSeriesAndPointForScreenCoordinate(Point screenPoint) {
127 if (isOnPieChart(screenPoint)) {
128 double angleFromPieCenter = getAngle(screenPoint);
130 for (PieSegment pieSeg : mPieSegmentList) {
131 if (pieSeg.isInSegment(angleFromPieCenter)) {
132 return new SeriesSelection(0, pieSeg.getDataIndex(), pieSeg.getValue(),