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
24 import org.achartengine.renderer.DefaultRenderer;
\r
29 public class Zoom extends AbstractTool {
\r
30 /** A flag to be used to know if this is a zoom in or out. */
\r
31 private boolean mZoomIn;
\r
32 /** The zoom rate. */
\r
33 private float mZoomRate;
\r
34 /** The zoom listeners. */
\r
35 private List<ZoomListener> mZoomListeners = new ArrayList<ZoomListener>();
\r
36 /** Zoom limits reached on the X axis. */
\r
37 private boolean limitsReachedX = false;
\r
38 /** Zoom limits reached on the Y axis. */
\r
39 private boolean limitsReachedY = false;
\r
41 /** Zoom on X axis and Y axis */
\r
42 public static final int ZOOM_AXIS_XY = 0;
\r
43 /** Zoom on X axis independently */
\r
44 public static final int ZOOM_AXIS_X = 1;
\r
45 /** Zoom on Y axis independently */
\r
46 public static final int ZOOM_AXIS_Y = 2;
\r
50 * Builds the zoom tool.
\r
52 * @param chart the chart
\r
53 * @param in zoom in or out
\r
54 * @param rate the zoom rate
\r
56 public Zoom(AbstractChart chart, boolean in, float rate) {
\r
63 * Sets the zoom rate.
\r
67 public void setZoomRate(float rate) {
\r
74 public void apply(int zoom_axis) {
\r
75 if (mChart instanceof XYChart) {
\r
76 int scales = mRenderer.getScalesCount();
\r
77 for (int i = 0; i < scales; i++) {
\r
78 double[] range = getRange(i);
\r
79 checkRange(range, i);
\r
80 double[] limits = mRenderer.getZoomLimits();
\r
82 double centerX = (range[0] + range[1]) / 2;
\r
83 double centerY = (range[2] + range[3]) / 2;
\r
84 double newWidth = range[1] - range[0];
\r
85 double newHeight = range[3] - range[2];
\r
86 double newXMin = centerX - newWidth / 2;
\r
87 double newXMax = centerX + newWidth / 2;
\r
88 double newYMin = centerY - newHeight / 2;
\r
89 double newYMax = centerY + newHeight / 2;
\r
91 // if already reached last zoom, then it will always set to reached
\r
93 limitsReachedX = limits != null && (newXMin <= limits[0] || newXMax >= limits[1]);
\r
94 limitsReachedY = limits != null && (newYMin <= limits[2] || newYMax >= limits[3]);
\r
98 if (mRenderer.isZoomXEnabled() && // zoom in on X axis
\r
99 (zoom_axis == ZOOM_AXIS_X || zoom_axis == ZOOM_AXIS_XY)) {
\r
100 if (limitsReachedX && mZoomRate < 1) {
\r
101 // ignore pinch zoom out once reached X limit
\r
103 newWidth /= mZoomRate;
\r
107 if (mRenderer.isZoomYEnabled() && // zoom in on Y axis
\r
108 (zoom_axis == ZOOM_AXIS_Y || zoom_axis == ZOOM_AXIS_XY)) {
\r
109 if (limitsReachedY && mZoomRate < 1) {
\r
111 newHeight /= mZoomRate;
\r
115 if (mRenderer.isZoomXEnabled() && !limitsReachedX && // zoom out on X axis
\r
116 (zoom_axis == ZOOM_AXIS_X || zoom_axis == ZOOM_AXIS_XY)) {
\r
117 newWidth *= mZoomRate;
\r
120 if (mRenderer.isZoomYEnabled() && !limitsReachedY && // zoom out on Y axis
\r
121 (zoom_axis == ZOOM_AXIS_Y || zoom_axis == ZOOM_AXIS_XY)) {
\r
122 newHeight *= mZoomRate;
\r
126 if (mRenderer.isZoomXEnabled() &&
\r
127 (zoom_axis == ZOOM_AXIS_X || zoom_axis == ZOOM_AXIS_XY)) {
\r
128 newXMin = centerX - newWidth / 2;
\r
129 newXMax = centerX + newWidth / 2;
\r
130 setXRange(newXMin, newXMax, i);
\r
132 if (mRenderer.isZoomYEnabled() &&
\r
133 (zoom_axis == ZOOM_AXIS_Y || zoom_axis == ZOOM_AXIS_XY)) {
\r
134 newYMin = centerY - newHeight / 2;
\r
135 newYMax = centerY + newHeight / 2;
\r
136 setYRange(newYMin, newYMax, i);
\r
140 DefaultRenderer renderer = ((RoundChart) mChart).getRenderer();
\r
142 renderer.setScale(renderer.getScale() * mZoomRate);
\r
144 renderer.setScale(renderer.getScale() / mZoomRate);
\r
147 notifyZoomListeners(new ZoomEvent(mZoomIn, mZoomRate));
\r
152 * Notify the zoom listeners about a zoom change.
\r
154 * @param e the zoom event
\r
156 private synchronized void notifyZoomListeners(ZoomEvent e) {
\r
157 for (ZoomListener listener : mZoomListeners) {
\r
158 listener.zoomApplied(e);
\r
163 * Notify the zoom listeners about a zoom reset.
\r
165 public synchronized void notifyZoomResetListeners() {
\r
166 for (ZoomListener listener : mZoomListeners) {
\r
167 listener.zoomReset();
\r
172 * Adds a new zoom listener.
\r
174 * @param listener zoom listener
\r
176 public synchronized void addZoomListener(ZoomListener listener) {
\r
177 mZoomListeners.add(listener);
\r
181 * Removes a zoom listener.
\r
183 * @param listener zoom listener
\r
185 public synchronized void removeZoomListener(ZoomListener listener) {
\r
186 mZoomListeners.add(listener);
\r