Skip to content

Commit

Permalink
Merge pull request PhilJay#616 from danielgindi/master
Browse files Browse the repository at this point in the history
Improvements for radial chart deceleration
  • Loading branch information
PhilJay committed May 2, 2015
2 parents 478c37e + fb70ef7 commit c7b6e07
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 127 deletions.
6 changes: 3 additions & 3 deletions MPChartLib/src/com/github/mikephil/charting/charts/Chart.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ public abstract class Chart<T extends ChartData<? extends DataSet<? extends Entr
private boolean mDragDecelerationEnabled = true;

/**
* Decelaration friction coefficient in [0 ; 1] interval, higher values
* Deceleration friction coefficient in [0 ; 1] interval, higher values
* indicate that speed will decrease slowly, for example if it set to 0, it
* will stop immediately, if set to 1, it will scroll with constant speed,
* until the last point
* will stop immediately. 1 is an invalid value, and will be converted to 0.999f
* automatically.
*/
private float mDragDecelerationFrictionCoef = 0.9f;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ private float calcAngle(float value) {
public int getIndexForAngle(float angle) {

// take the current angle of the chart into consideration
float a = (angle - mRotationAngle + 360) % 360f;
float a = Utils.getNormalizedAngle(angle - getRotationAngle());

for (int i = 0; i < mAbsoluteAngles.length; i++) {
if (mAbsoluteAngles[i] > a)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@
public abstract class PieRadarChartBase<T extends ChartData<? extends DataSet<? extends Entry>>>
extends Chart<T> {

/** holds the current rotation angle of the chart */
protected float mRotationAngle = 270f;
/** the angle where the dragging started */
private float mStartAngle = 0f;
/** holds the normalized version of the current rotation angle of the chart */
private float mRotationAngle = 270f;

/** holds the raw version of the current rotation angle of the chart */
private float mRawRotationAngle = 270f;

/** flag that indicates if rotation is enabled or not */
protected boolean mRotateEnabled = true;
Expand Down Expand Up @@ -203,39 +203,6 @@ protected void calculateOffsets() {
+ ", offsetRight: " + offsetRight + ", offsetBottom: " + offsetBottom);
}

/**
* sets the starting angle of the rotation, this is only used by the touch
* listener, x and y is the touch position
*
* @param x
* @param y
*/
public void setGestureStartAngle(float x, float y) {

mStartAngle = getAngleForPoint(x, y);

// take the current angle into consideration when starting a new drag
mStartAngle -= mRotationAngle;
}

/**
* updates the view rotation depending on the given touch position, also
* takes the starting angle into consideration
*
* @param x
* @param y
*/
public void updateRotation(float x, float y) {

mRotationAngle = getAngleForPoint(x, y);

// take the offset into consideration
mRotationAngle -= mStartAngle;

// keep the angle >= 0 and <= 360
mRotationAngle = (mRotationAngle + 360f) % 360f;
}

/**
* returns the angle relative to the chart center for the given point on the
* chart in degrees. The angle is always between 0 and 360°, 0° is NORTH,
Expand Down Expand Up @@ -336,16 +303,25 @@ public float distanceToCenter(float x, float y) {
* @param angle
*/
public void setRotationAngle(float angle) {
mRawRotationAngle = angle;
mRotationAngle = Utils.getNormalizedAngle(mRawRotationAngle);
}

while (angle < 0.f)
angle += 360.f;

mRotationAngle = angle % 360;
/**
* gets the raw version of the current rotation angle of the pie chart
* the returned value could be any value, negative or positive, outside of the 360 degrees.
* this is used when working with rotation direction, mainly by gestures and animations.
*
* @return
*/
public float getRawRotationAngle() {
return mRawRotationAngle;
}

/**
* gets the current rotation angle of the pie chart
*
* gets a normalized version of the current rotation angle of the pie chart,
* which will always be between 0.0 < 360.0
*
* @return
*/
public float getRotationAngle() {
Expand Down Expand Up @@ -480,7 +456,7 @@ public void spin(int durationmillis, float fromangle, float toangle, Easing.Easi
if (android.os.Build.VERSION.SDK_INT < 11)
return;

mRotationAngle = fromangle;
setRotationAngle(fromangle);

ObjectAnimator spinAnimator = ObjectAnimator.ofFloat(this, "rotationAngle", fromangle, toangle);
spinAnimator.setDuration(durationmillis);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ public float getSliceAngle() {
public int getIndexForAngle(float angle) {

// take the current angle of the chart into consideration
float a = (angle - mRotationAngle + 360) % 360f;
float a = Utils.getNormalizedAngle(angle - getRotationAngle());

float sliceangle = getSliceAngle();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import android.view.animation.AnimationUtils;

import com.github.mikephil.charting.charts.BarLineChartBase;
import com.github.mikephil.charting.charts.Chart;
import com.github.mikephil.charting.charts.HorizontalBarChart;
import com.github.mikephil.charting.data.BarLineScatterCandleData;
import com.github.mikephil.charting.data.BarLineScatterCandleDataSet;
Expand Down Expand Up @@ -77,9 +76,9 @@ public class BarLineChartTouchListener<T extends BarLineChartBase<? extends BarL
/** used for tracking velocity of dragging */
private VelocityTracker mVelocityTracker;

private long mDecelarationLastTime = 0;
private PointF mDecelarationCurrentPoint = new PointF();
private PointF mDecelarationVelocity = new PointF();
private long mDecelerationLastTime = 0;
private PointF mDecelerationCurrentPoint = new PointF();
private PointF mDecelerationVelocity = new PointF();

public BarLineChartTouchListener(T chart, Matrix touchMatrix) {
this.mChart = chart;
Expand Down Expand Up @@ -202,9 +201,9 @@ public boolean onTouch(View v, MotionEvent event) {

stopDeceleration();

mDecelarationLastTime = AnimationUtils.currentAnimationTimeMillis();
mDecelarationCurrentPoint = new PointF(event.getX(), event.getY());
mDecelarationVelocity = new PointF(velocityX, velocityY);
mDecelerationLastTime = AnimationUtils.currentAnimationTimeMillis();
mDecelerationCurrentPoint = new PointF(event.getX(), event.getY());
mDecelerationVelocity = new PointF(velocityX, velocityY);

Utils.postInvalidateOnAnimation(mChart); // This causes computeScroll to fire, recommended for this by Google
}
Expand Down Expand Up @@ -577,35 +576,35 @@ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float ve
}

public void stopDeceleration() {
mDecelarationVelocity = new PointF(0.f, 0.f);
mDecelerationVelocity = new PointF(0.f, 0.f);
}

public void computeScroll() {

if (mDecelarationVelocity.x == 0.f && mDecelarationVelocity.y == 0.f)
if (mDecelerationVelocity.x == 0.f && mDecelerationVelocity.y == 0.f)
return; // There's no deceleration in progress

final long currentTime = AnimationUtils.currentAnimationTimeMillis();

mDecelarationVelocity.x *= mChart.getDragDecelerationFrictionCoef();
mDecelarationVelocity.y *= mChart.getDragDecelerationFrictionCoef();
mDecelerationVelocity.x *= mChart.getDragDecelerationFrictionCoef();
mDecelerationVelocity.y *= mChart.getDragDecelerationFrictionCoef();

final float timeInterval = (float)(currentTime - mDecelarationLastTime) / 1000.f;
final float timeInterval = (float)(currentTime - mDecelerationLastTime) / 1000.f;

float distanceX = mDecelarationVelocity.x * timeInterval;
float distanceY = mDecelarationVelocity.y * timeInterval;
float distanceX = mDecelerationVelocity.x * timeInterval;
float distanceY = mDecelerationVelocity.y * timeInterval;

mDecelarationCurrentPoint.x += distanceX;
mDecelarationCurrentPoint.y += distanceY;
mDecelerationCurrentPoint.x += distanceX;
mDecelerationCurrentPoint.y += distanceY;

MotionEvent event = MotionEvent.obtain(currentTime, currentTime, MotionEvent.ACTION_MOVE, mDecelarationCurrentPoint.x, mDecelarationCurrentPoint.y, 0);
MotionEvent event = MotionEvent.obtain(currentTime, currentTime, MotionEvent.ACTION_MOVE, mDecelerationCurrentPoint.x, mDecelerationCurrentPoint.y, 0);
performDrag(event);
event.recycle();
mMatrix = mChart.getViewPortHandler().refresh(mMatrix, mChart, false);

mDecelarationLastTime = currentTime;
mDecelerationLastTime = currentTime;

if (Math.abs(mDecelarationVelocity.x) >= 0.001 || Math.abs(mDecelarationVelocity.y) >= 0.001)
if (Math.abs(mDecelerationVelocity.x) >= 0.001 || Math.abs(mDecelerationVelocity.y) >= 0.001)
Utils.postInvalidateOnAnimation(mChart); // This causes computeScroll to fire, recommended for this by Google
else
stopDeceleration();
Expand Down
Loading

0 comments on commit c7b6e07

Please sign in to comment.