2 * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
16 package org.achartengine.tools;
\r
18 import java.util.ArrayList;
\r
19 import java.util.List;
\r
21 import org.achartengine.chart.AbstractChart;
\r
22 import org.achartengine.chart.RoundChart;
\r
23 import org.achartengine.chart.XYChart;
\r
28 public class Pan extends AbstractTool {
\r
29 /** The pan listeners. */
\r
30 private List<PanListener> mPanListeners = new ArrayList<PanListener>();
\r
31 /** Pan limits reached on the X axis. */
\r
32 private boolean limitsReachedX = false;
\r
33 /** Pan limits reached on the X axis. */
\r
34 private boolean limitsReachedY = false;
\r
37 * Builds and instance of the pan tool.
\r
39 * @param chart the XY chart
\r
41 public Pan(AbstractChart chart) {
\r
48 * @param oldX the previous location on X axis
\r
49 * @param oldY the previous location on Y axis
\r
50 * @param newX the current location on X axis
\r
51 * @param newY the current location on the Y axis
\r
53 public void apply(float oldX, float oldY, float newX, float newY) {
\r
54 boolean notLimitedUp = true;
\r
55 boolean notLimitedBottom = true;
\r
56 boolean notLimitedLeft = true;
\r
57 boolean notLimitedRight = true;
\r
58 if (mChart instanceof XYChart) {
\r
59 int scales = mRenderer.getScalesCount();
\r
60 double[] limits = mRenderer.getPanLimits();
\r
61 boolean limited = limits != null && limits.length == 4;
\r
62 XYChart chart = (XYChart) mChart;
\r
63 for (int i = 0; i < scales; i++) {
\r
64 double[] range = getRange(i);
\r
65 double[] calcRange = chart.getCalcRange(i);
\r
68 && (range[0] == range[1] && calcRange[0] == calcRange[1] || range[2] == range[3]
\r
69 && calcRange[2] == calcRange[3])) {
\r
72 checkRange(range, i);
\r
74 double[] realPoint = chart.toRealPoint(oldX, oldY, i);
\r
75 double[] realPoint2 = chart.toRealPoint(newX, newY, i);
\r
76 double deltaX = realPoint[0] - realPoint2[0];
\r
77 double deltaY = realPoint[1] - realPoint2[1];
\r
78 double ratio = getAxisRatio(range);
\r
79 if (chart.isVertical(mRenderer)) {
\r
80 double newDeltaX = -deltaY * ratio;
\r
81 double newDeltaY = deltaX / ratio;
\r
85 if (mRenderer.isPanXEnabled()) {
\r
86 if (limits != null) {
\r
87 if (notLimitedLeft) {
\r
88 notLimitedLeft = limits[0] <= range[0] + deltaX;
\r
90 if (notLimitedRight) {
\r
91 notLimitedRight = limits[1] >= range[1] + deltaX;
\r
94 if (!limited || (notLimitedLeft && notLimitedRight)) {
\r
95 setXRange(range[0] + deltaX, range[1] + deltaX, i);
\r
96 limitsReachedX = false;
\r
98 limitsReachedX = true;
\r
101 if (mRenderer.isPanYEnabled()) {
\r
102 if (limits != null) {
\r
103 if (notLimitedBottom) {
\r
104 notLimitedBottom = limits[2] <= range[2] + deltaY;
\r
106 if (notLimitedUp) {
\r
107 notLimitedUp = limits[3] >= range[3] + deltaY;
\r
110 if (!limited || (notLimitedBottom && notLimitedUp)) {
\r
111 setYRange(range[2] + deltaY, range[3] + deltaY, i);
\r
112 limitsReachedY = false;
\r
114 limitsReachedY = true;
\r
119 RoundChart chart = (RoundChart) mChart;
\r
120 chart.setCenterX(chart.getCenterX() + (int) (newX - oldX));
\r
121 chart.setCenterY(chart.getCenterY() + (int) (newY - oldY));
\r
123 notifyPanListeners();
\r
127 * Return the X / Y axis range ratio.
\r
129 * @param range the axis range
\r
130 * @return the ratio
\r
132 private double getAxisRatio(double[] range) {
\r
133 return Math.abs(range[1] - range[0]) / Math.abs(range[3] - range[2]);
\r
137 * Notify the pan listeners about a pan.
\r
139 private synchronized void notifyPanListeners() {
\r
140 for (PanListener listener : mPanListeners) {
\r
141 listener.panApplied();
\r
146 * Adds a new pan listener.
\r
148 * @param listener pan listener
\r
150 public synchronized void addPanListener(PanListener listener) {
\r
151 mPanListeners.add(listener);
\r
155 * Removes a pan listener.
\r
157 * @param listener pan listener
\r
159 public synchronized void removePanListener(PanListener listener) {
\r
160 mPanListeners.add(listener);
\r