package com.github.mikephil.charting.listener;
import android.annotation.SuppressLint;
import android.graphics.PointF;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import com.github.mikephil.charting.charts.PieChart;
import com.github.mikephil.charting.charts.PieRadarChartBase;
import com.github.mikephil.charting.charts.RadarChart;
import com.github.mikephil.charting.utils.Highlight;
import com.github.mikephil.charting.utils.SelInfo;
import com.github.mikephil.charting.utils.Utils;
import java.util.List;
/**
* Touchlistener for the PieChart.
*
* @author Philipp Jahoda
*/
public class PieRadarChartTouchListener extends SimpleOnGestureListener implements OnTouchListener {
private static final int NONE = 0;
private static final int ROTATE = 1;
private PointF mTouchStartPoint = new PointF();
private PieRadarChartBase<?> mChart;
private int mTouchMode = NONE;
private GestureDetector mGestureDetector;
public PieRadarChartTouchListener(PieRadarChartBase<?> ctx) {
this.mChart = ctx;
mGestureDetector = new GestureDetector(ctx.getContext(), this);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent e) {
if (mGestureDetector.onTouchEvent(e))
return true;
// if rotation by touch is enabled
if (mChart.isRotationEnabled()) {
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
mChart.setStartAngle(x, y);
mTouchStartPoint.x = x;
mTouchStartPoint.y = y;
break;
case MotionEvent.ACTION_MOVE:
if (mTouchMode == NONE
&& distance(x, mTouchStartPoint.x, y, mTouchStartPoint.y)
> Utils.convertDpToPixel(8f)) {
mTouchMode = ROTATE;
mChart.disableScroll();
} else if (mTouchMode == ROTATE) {
mChart.updateRotation(x, y);
mChart.invalidate();
}
break;
case MotionEvent.ACTION_UP:
mChart.enableScroll();
mTouchMode = NONE;
break;
}
}
return true;
}
@Override
public void onLongPress(MotionEvent me) {
OnChartGestureListener l = mChart.getOnChartGestureListener();
if (l != null) {
l.onChartLongPressed(me);
}
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return true;
}
/** reference to the last highlighted object */
private Highlight mLastHighlight = null;
@Override
public boolean onSingleTapUp(MotionEvent e) {
OnChartGestureListener l = mChart.getOnChartGestureListener();
if (l != null) {
l.onChartSingleTapped(e);
}
float distance = mChart.distanceToCenter(e.getX(), e.getY());
// check if a slice was touched
if (distance > mChart.getRadius()) {
// if no slice was touched, highlight nothing
mChart.highlightValues(null);
mLastHighlight = null;
} else {
float angle = mChart.getAngleForPoint(e.getX(), e.getY());
if (mChart instanceof PieChart) {
angle /= mChart.getAnimator().getPhaseY();
}
int index = mChart.getIndexForAngle(angle);
// check if the index could be found
if (index < 0) {
mChart.highlightValues(null);
mLastHighlight = null;
} else {
List<SelInfo> valsAtIndex = mChart.getYValsAtIndex(index);
int dataSetIndex = 0;
// get the dataset that is closest to the selection (PieChart
// only
// has one DataSet)
if (mChart instanceof RadarChart) {
dataSetIndex = Utils.getClosestDataSetIndex(valsAtIndex, distance
/ ((RadarChart) mChart).getFactor(), null);
}
Highlight h = new Highlight(index, dataSetIndex);
if (h.equalTo(mLastHighlight)) {
mChart.highlightTouch(null);
mLastHighlight = null;
} else {
mChart.highlightTouch(h);
mLastHighlight = h;
}
}
}
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
OnChartGestureListener l = mChart.getOnChartGestureListener();
if (l != null) {
l.onChartDoubleTapped(e);
}
return super.onDoubleTap(e);
}
/**
* returns the distance between two points
*
* @param eventX
* @param startX
* @param eventY
* @param startY
* @return
*/
private static float distance(float eventX, float startX, float eventY, float startY) {
float dx = eventX - startX;
float dy = eventY - startY;
return (float) Math.sqrt(dx * dx + dy * dy);
}
}