Introduce zoomToAnimated(...) method - first version

This commit is contained in:
Philipp Jahoda 2016-02-24 11:39:34 +01:00
parent 1a0e90aacf
commit 2dd9d5aa34
9 changed files with 172 additions and 44 deletions

View file

@ -27,8 +27,6 @@ import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.data.filter.Approximator;
import com.github.mikephil.charting.data.filter.Approximator.ApproximatorType;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.listener.ChartTouchListener;
@ -357,7 +355,7 @@ public class LineChartActivity1 extends DemoBase implements OnSeekBarChangeListe
@Override
public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
Log.i("Gesture", "START");
Log.i("Gesture", "START, x: " + me.getX() + ", y: " + me.getY());
}
@Override

View file

@ -329,6 +329,7 @@ public class LineChartActivity2 extends DemoBase implements OnSeekBarChangeListe
//mChart.centerViewToAnimated(e.getXIndex(), e.getVal(), mChart.getData().getDataSetByIndex(dataSetIndex).getAxisDependency(), 1000);
//mChart.zoomAndCenterAnimated(2.5f, 2.5f, e.getXIndex(), e.getVal(), mChart.getData().getDataSetByIndex(dataSetIndex).getAxisDependency(), 1000);
mChart.zoomAndCenterAnimated(1.8f, 1.8f, e.getXIndex(), e.getVal(), mChart.getData().getDataSetByIndex(dataSetIndex).getAxisDependency(), 1000);
}
@Override

View file

@ -29,6 +29,7 @@ import com.github.mikephil.charting.interfaces.datasets.IBarLineScatterCandleBub
import com.github.mikephil.charting.jobs.AnimatedMoveViewJob;
import com.github.mikephil.charting.jobs.AnimatedZoomJob;
import com.github.mikephil.charting.jobs.MoveViewJob;
import com.github.mikephil.charting.jobs.ZoomJob;
import com.github.mikephil.charting.listener.BarLineChartTouchListener;
import com.github.mikephil.charting.listener.OnDrawListener;
import com.github.mikephil.charting.renderer.XAxisRenderer;
@ -701,9 +702,24 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
postInvalidate();
}
/**
* Zooms in or out by the given scale factor.
* x and y are the values to or which to zoom from (the values of the zoom center).
*
* @param scaleX
* @param scaleY
* @param xValue
* @param yValue
* @param axis the axis relative to which the zoom should take place
*/
public void zoom(float scaleX, float scaleY, float xValue, float yValue, AxisDependency axis) {
Runnable job = new ZoomJob(mViewPortHandler, scaleX, scaleY, xValue, yValue, getTransformer(axis), axis, this);
postJob(job);
}
/**
* Zooms by the specified scale factor to the specified values on the specified axis.
* STILL WORK IN PROGRESS
*
* @param scaleX
* @param scaleY
@ -712,14 +728,11 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
* @param axis
* @param duration
*/
private void zoomAndCenterAnimated(float scaleX, float scaleY, float xValue, float yValue, AxisDependency axis, long duration) {
public void zoomAndCenterAnimated(float scaleX, float scaleY, float xValue, float yValue, AxisDependency axis, long duration) {
PointD bounds = getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentTop(), axis);
PointD origin = getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentTop(), axis);
float valsInView = getDeltaY(axis) / mViewPortHandler.getScaleY();
float xsInView = getXAxis().getValues().size() / mViewPortHandler.getScaleX();
Runnable job = new AnimatedZoomJob(mViewPortHandler, this, getTransformer(axis), scaleX, scaleY, mViewPortHandler.getScaleX(), mViewPortHandler.getScaleY(), xValue - xsInView / 2f, yValue + valsInView / 2f, (float) bounds.x, (float) bounds.y, duration);
Runnable job = new AnimatedZoomJob(mViewPortHandler, this, getTransformer(axis), getAxis(axis), mXAxis.getValues().size(), scaleX, scaleY, mViewPortHandler.getScaleX(), mViewPortHandler.getScaleY(), xValue, yValue, (float) origin.x, (float) origin.y, duration);
postJob(job);
}

View file

@ -12,7 +12,7 @@ import com.github.mikephil.charting.utils.ViewPortHandler;
* Created by Philipp Jahoda on 19/02/16.
*/
@SuppressLint("NewApi")
public abstract class AnimatedJob extends Job implements ValueAnimator.AnimatorUpdateListener {
public abstract class AnimatedJob extends ViewPortJob implements ValueAnimator.AnimatorUpdateListener {
protected ObjectAnimator animator;
@ -43,4 +43,12 @@ public abstract class AnimatedJob extends Job implements ValueAnimator.AnimatorU
public void setPhase(float phase) {
this.phase = phase;
}
public float getXOrigin() {
return xOrigin;
}
public float getYOrigin() {
return yOrigin;
}
}

View file

@ -3,9 +3,11 @@ package com.github.mikephil.charting.jobs;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.graphics.Matrix;
import android.view.View;
import com.github.mikephil.charting.charts.BarLineChartBase;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.utils.Transformer;
import com.github.mikephil.charting.utils.ViewPortHandler;
@ -21,8 +23,12 @@ public class AnimatedZoomJob extends AnimatedJob implements Animator.AnimatorLis
protected float zoomCenterX;
protected float zoomCenterY;
protected YAxis yAxis;
protected float xValCount;
@SuppressLint("NewApi")
public AnimatedZoomJob(ViewPortHandler viewPortHandler, View v, Transformer trans, float scaleX, float scaleY, float xOrigin, float yOrigin, float zoomCenterX, float zoomCenterY, float zoomOriginX, float zoomOriginY, long duration) {
public AnimatedZoomJob(ViewPortHandler viewPortHandler, View v, Transformer trans, YAxis axis, float xValCount, float scaleX, float scaleY, float xOrigin, float yOrigin, float zoomCenterX, float zoomCenterY, float zoomOriginX, float zoomOriginY, long duration) {
super(viewPortHandler, scaleX, scaleY, trans, v, xOrigin, yOrigin, duration);
this.zoomCenterX = zoomCenterX;
@ -30,6 +36,8 @@ public class AnimatedZoomJob extends AnimatedJob implements Animator.AnimatorLis
this.zoomOriginX = zoomOriginX;
this.zoomOriginY = zoomOriginY;
this.animator.addListener(this);
this.yAxis = axis;
this.xValCount = xValCount;
}
@Override
@ -38,14 +46,19 @@ public class AnimatedZoomJob extends AnimatedJob implements Animator.AnimatorLis
float scaleX = xOrigin + (xValue - xOrigin) * phase;
float scaleY = yOrigin + (yValue - yOrigin) * phase;
pts[0] = zoomOriginX + (zoomCenterX - zoomOriginX) * phase;
pts[1] = zoomOriginY + (zoomCenterY - zoomOriginY) * phase;
Matrix save = mViewPortHandler.setZoom(scaleX, scaleY);
mViewPortHandler.refresh(save, view, false);
float valsInView = yAxis.mAxisRange / mViewPortHandler.getScaleY();
float xsInView = xValCount / mViewPortHandler.getScaleX();
pts[0] = zoomOriginX + ((zoomCenterX - xsInView / 2f) - zoomOriginX) * phase;
pts[1] = zoomOriginY + ((zoomCenterY + valsInView / 2f) - zoomOriginY) * phase;
mTrans.pointValuesToPixel(pts);
//Matrix save = mViewPortHandler.zoomAndCenter(xValue * phase, yValue * phase, zoomCenterX * phase, zoomCenterY * phase);
mViewPortHandler.zoomAndCenter(scaleX, scaleY, pts, view);//zoomOriginX + (zoomCenterX - zoomOriginX) * phase, zoomOriginY + (zoomCenterY - zoomOriginY) * phase);
save = mViewPortHandler.translate(pts);
mViewPortHandler.refresh(save, view, true);
}
@Override

View file

@ -9,10 +9,10 @@ import com.github.mikephil.charting.utils.ViewPortHandler;
/**
* Created by Philipp Jahoda on 19/02/16.
*/
public class MoveViewJob extends Job {
public class MoveViewJob extends ViewPortJob {
public MoveViewJob(ViewPortHandler viewPortHandler, float xIndex, float yValue, Transformer trans, View v) {
super(viewPortHandler, xIndex, yValue, trans, v);
public MoveViewJob(ViewPortHandler viewPortHandler, float xValue, float yValue, Transformer trans, View v) {
super(viewPortHandler, xValue, yValue, trans, v);
}
@Override

View file

@ -9,11 +9,13 @@ import com.github.mikephil.charting.utils.ViewPortHandler;
/**
* Runnable that is used for viewport modifications since they cannot be
* executed at any time. This can be used to delay the execution of viewport
* modifications until the onSizeChanged(...) method of the chartview is called.
* modifications until the onSizeChanged(...) method of the chart-view is called.
* This is especially important if viewport modifying methods are called on the chart
* directly after initialization.
*
* @author Philipp Jahoda
*/
public abstract class Job implements Runnable {
public abstract class ViewPortJob implements Runnable {
protected float[] pts = new float[2];
@ -23,8 +25,8 @@ public abstract class Job implements Runnable {
protected Transformer mTrans;
protected View view;
public Job(ViewPortHandler viewPortHandler, float xValue, float yValue,
Transformer trans, View v) {
public ViewPortJob(ViewPortHandler viewPortHandler, float xValue, float yValue,
Transformer trans, View v) {
this.mViewPortHandler = viewPortHandler;
this.xValue = xValue;
@ -32,4 +34,12 @@ public abstract class Job implements Runnable {
this.mTrans = trans;
this.view = v;
}
public float getXValue() {
return xValue;
}
public float getYValue() {
return yValue;
}
}

View file

@ -0,0 +1,50 @@
package com.github.mikephil.charting.jobs;
import android.graphics.Matrix;
import android.view.View;
import com.github.mikephil.charting.charts.BarLineChartBase;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.utils.Transformer;
import com.github.mikephil.charting.utils.ViewPortHandler;
/**
* Created by Philipp Jahoda on 19/02/16.
*/
public class ZoomJob extends ViewPortJob {
protected float scaleX;
protected float scaleY;
protected YAxis.AxisDependency axisDependency;
public ZoomJob(ViewPortHandler viewPortHandler, float scaleX, float scaleY, float xValue, float yValue, Transformer trans, YAxis.AxisDependency axis, View v) {
super(viewPortHandler, xValue, yValue, trans, v);
this.scaleX = scaleX;
this.scaleY = scaleY;
this.axisDependency = axis;
}
@Override
public void run() {
Matrix save = mViewPortHandler.zoom(scaleX, scaleY);
mViewPortHandler.refresh(save, view, false);
float valsInView = ((BarLineChartBase) view).getDeltaY(axisDependency) / mViewPortHandler.getScaleY();
float xsInView = ((BarLineChartBase) view).getXAxis().getValues().size() / mViewPortHandler.getScaleX();
pts[0] = xValue - xsInView / 2f;
pts[1] = yValue + valsInView / 2f;
mTrans.pointValuesToPixel(pts);
save = mViewPortHandler.translate(pts);
mViewPortHandler.refresh(save, view, false);
((BarLineChartBase) view).calculateOffsets();
view.postInvalidate();
}
}

View file

@ -210,13 +210,30 @@ public class ViewPortHandler {
}
/**
* Zooms in or out by the given scale factor. x and y are the coordinates
* (in pixels) of the zoom center.
* Post-scales by the specified scale factors.
*
* @param scaleX if < 1f --> zoom out, if > 1f --> zoom in
* @param scaleY if < 1f --> zoom out, if > 1f --> zoom in
* @param scaleX
* @param scaleY
* @return
*/
public Matrix zoom(float scaleX, float scaleY) {
Matrix save = new Matrix();
save.set(mMatrixTouch);
save.postScale(scaleX, scaleY);
return save;
}
/**
* Post-scales by the specified scale factors. x and y is pivot.
*
* @param scaleX
* @param scaleY
* @param x
* @param y
* @return
*/
public Matrix zoom(float scaleX, float scaleY, float x, float y) {
@ -228,7 +245,14 @@ public class ViewPortHandler {
return save;
}
public Matrix zoom(float scaleX, float scaleY) {
/**
* Sets the scale factor to the specified values.
*
* @param scaleX
* @param scaleY
* @return
*/
public Matrix setZoom(float scaleX, float scaleY) {
Matrix save = new Matrix();
save.set(mMatrixTouch);
@ -239,28 +263,22 @@ public class ViewPortHandler {
}
/**
* Zooms by the specified scale factors and moves the viewport to the specified values.
* Sets the scale factor to the specified values. x and y is pivot.
*
* @param scaleX
* @param scaleY
* @param pts
* @param view
* @param x
* @param y
* @return
*/
public synchronized Matrix zoomAndCenter(float scaleX, float scaleY, float[] pts, final View view) {
public Matrix setZoom(float scaleX, float scaleY, float x, float y) {
Matrix save = new Matrix();
save.set(mMatrixTouch);
final float x = pts[0] - offsetLeft();
final float y = pts[1] - offsetTop();
save.setScale(scaleX, scaleY, x, y);
PointF center = getContentCenter();
save.setScale(scaleX, scaleY, center.x, center.y);
save.postTranslate(-x, -y);
return refresh(save, view, true);
return save;
}
/**
@ -290,6 +308,25 @@ public class ViewPortHandler {
return save;
}
/**
* Post-translates to the specified points.
*
* @param transformedPts
* @return
*/
public Matrix translate(final float[] transformedPts) {
Matrix save = new Matrix();
save.set(mMatrixTouch);
final float x = transformedPts[0] - offsetLeft();
final float y = transformedPts[1] - offsetTop();
save.postTranslate(-x, -y);
return save;
}
/**
* Centers the viewport around the specified position (x-index and y-value)
* in the chart. Centering the viewport outside the bounds of the chart is
@ -300,7 +337,7 @@ public class ViewPortHandler {
* @param view
* @return save
*/
public synchronized void centerViewPort(final float[] transformedPts, final View view) {
public void centerViewPort(final float[] transformedPts, final View view) {
Matrix save = new Matrix();
save.set(mMatrixTouch);
@ -308,8 +345,6 @@ public class ViewPortHandler {
final float x = transformedPts[0] - offsetLeft();
final float y = transformedPts[1] - offsetTop();
//Log.i("", "Moving view to x: " + x + ", y: " + y);
save.postTranslate(-x, -y);
refresh(save, view, true);