@Override public void notifyDataSetChanged() { if (mData == null) return; calcMinMax(); if (mLegend != null) mLegendRenderer.computeLegend(mData); calculateOffsets(); }
if (mChart.isRotationEnabled()) { if (mChart.isDragDecelerationEnabled()) sampleVelocity(x, y); case MotionEvent.ACTION_MOVE: if (mChart.isDragDecelerationEnabled()) sampleVelocity(x, y); mLastGesture = ChartGesture.ROTATE; mTouchMode = ROTATE; mChart.disableScroll(); } else if (mTouchMode == ROTATE) { updateGestureRotation(x, y); mChart.invalidate(); case MotionEvent.ACTION_UP: if (mChart.isDragDecelerationEnabled()) { mChart.enableScroll(); mTouchMode = NONE;
MPPointF center = getCenter(); ? getWidth() - legendWidth + 15.f : legendWidth - 15.f; float bottomY = legendHeight + 15.f; float distLegend = distanceToCenter(bottomX, bottomY); MPPointF reference = getPosition(center, getRadius(), getAngleForPoint(bottomX, bottomY)); float distReference = distanceToCenter(reference.x, reference.y); float minOffset = Utils.convertDpToPixel(5f); if (bottomY >= center.y && getHeight() - legendWidth > getWidth()) { xLegendOffset = legendWidth; } else if (distLegend < distReference) { float yOffset = getRequiredLegendOffset(); legendLeft += getRequiredBaseOffset(); legendRight += getRequiredBaseOffset(); legendTop += getRequiredBaseOffset(); legendBottom += getRequiredBaseOffset(); XAxis x = this.getXAxis(); legendTop += getExtraTopOffset(); legendRight += getExtraRightOffset(); legendBottom += getExtraBottomOffset();
/** * updates the view rotation depending on the given touch position, also * takes the starting angle into consideration * * @param x * @param y */ public void updateGestureRotation(float x, float y) { mChart.setRotationAngle(mChart.getAngleForPoint(x, y) - mStartAngle); }
/** * 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 = mChart.getAngleForPoint(x, y) - mChart.getRawRotationAngle(); }
@Override public Highlight getHighlight(float x, float y) { float touchDistanceToCenter = mChart.distanceToCenter(x, y); // check if a slice was touched if (touchDistanceToCenter > mChart.getRadius()) { // if no slice was touched, highlight nothing return null; } else { float angle = mChart.getAngleForPoint(x, y); if (mChart instanceof PieChart) { angle /= mChart.getAnimator().getPhaseY(); } int index = mChart.getIndexForAngle(angle); // check if the index could be found if (index < 0 || index >= mChart.getData().getMaxEntryCountSet().getEntryCount()) { return null; } else { return getClosestHighlight(index, x, y); } } }
/** * 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, * 90° is EAST, ... * * @param x * @param y * @return */ public float getAngleForPoint(float x, float y) { MPPointF c = getCenterOffsets(); double tx = x - c.x, ty = y - c.y; double length = Math.sqrt(tx * tx + ty * ty); double r = Math.acos(ty / length); float angle = (float) Math.toDegrees(r); if (x > c.x) angle = 360f - angle; // add 90° because chart starts EAST angle = angle + 90f; // neutralize overflow if (angle > 360f) angle = angle - 360f; MPPointF.recycleInstance(c); return angle; }
@Override protected void calcMinMax() { super.calcMinMax(); mYAxis.calculate(mData.getYMin(AxisDependency.LEFT), mData.getYMax(AxisDependency.LEFT)); mXAxis.calculate(0, mData.getMaxEntryCountSet().getEntryCount()); }
private void sampleVelocity(float touchLocationX, float touchLocationY) { long currentTime = AnimationUtils.currentAnimationTimeMillis(); _velocitySamples.add(new AngularVelocitySample(currentTime, mChart.getAngleForPoint(touchLocationX, touchLocationY))); // Remove samples older than our sample time - 1 seconds for (int i = 0, count = _velocitySamples.size(); i < count - 2; i++) { if (currentTime - _velocitySamples.get(i).time > 1000) { _velocitySamples.remove(0); i--; count--; } else { break; } } }
@Override public void calculateOffsets() { super.calculateOffsets(); // prevent nullpointer when no data set if (mData == null) return; float diameter = getDiameter(); float radius = diameter / 2f; MPPointF c = getCenterOffsets(); float shift = mData.getDataSet().getSelectionShift(); // create the circle box that will contain the pie-chart (the bounds of // the pie-chart) mCircleBox.set(c.x - radius + shift, c.y - radius + shift, c.x + radius - shift, c.y + radius - shift); MPPointF.recycleInstance(c); }
@Override public Highlight getHighlight(float x, float y) { float touchDistanceToCenter = mChart.distanceToCenter(x, y); // check if a slice was touched if (touchDistanceToCenter > mChart.getRadius()) { // if no slice was touched, highlight nothing return null; } else { float angle = mChart.getAngleForPoint(x, y); if (mChart instanceof PieChart) { angle /= mChart.getAnimator().getPhaseY(); } int index = mChart.getIndexForAngle(angle); // check if the index could be found if (index < 0 || index >= mChart.getData().getMaxEntryCountSet().getEntryCount()) { return null; } else { return getClosestHighlight(index, x, y); } } }
/** * updates the view rotation depending on the given touch position, also * takes the starting angle into consideration * * @param x * @param y */ public void updateGestureRotation(float x, float y) { mChart.setRotationAngle(mChart.getAngleForPoint(x, y) - mStartAngle); }
/** * 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 = mChart.getAngleForPoint(x, y) - mChart.getRawRotationAngle(); }
/** * Returns the distance of a certain point on the chart to the center of the * chart. * * @param x * @param y * @return */ public float distanceToCenter(float x, float y) { MPPointF c = getCenterOffsets(); float dist = 0f; float xDist = 0f; float yDist = 0f; if (x > c.x) { xDist = x - c.x; } else { xDist = c.x - x; } if (y > c.y) { yDist = y - c.y; } else { yDist = c.y - y; } // pythagoras dist = (float) Math.sqrt(Math.pow(xDist, 2.0) + Math.pow(yDist, 2.0)); MPPointF.recycleInstance(c); return dist; }
@Override protected void calcMinMax() { super.calcMinMax(); mYAxis.calculate(mData.getYMin(AxisDependency.LEFT), mData.getYMax(AxisDependency.LEFT)); mXAxis.calculate(0, mData.getMaxEntryCountSet().getEntryCount()); }
private void sampleVelocity(float touchLocationX, float touchLocationY) { long currentTime = AnimationUtils.currentAnimationTimeMillis(); _velocitySamples.add(new AngularVelocitySample(currentTime, mChart.getAngleForPoint(touchLocationX, touchLocationY))); // Remove samples older than our sample time - 1 seconds for (int i = 0, count = _velocitySamples.size(); i < count - 2; i++) { if (currentTime - _velocitySamples.get(i).time > 1000) { _velocitySamples.remove(0); i--; count--; } else { break; } } }
@Override public void calculateOffsets() { super.calculateOffsets(); // prevent nullpointer when no data set if (mData == null) return; float diameter = getDiameter(); float radius = diameter / 2f; MPPointF c = getCenterOffsets(); float shift = mData.getDataSet().getSelectionShift(); // create the circle box that will contain the pie-chart (the bounds of // the pie-chart) mCircleBox.set(c.x - radius + shift, c.y - radius + shift, c.x + radius - shift, c.y + radius - shift); MPPointF.recycleInstance(c); }
MPPointF center = getCenter(); ? getWidth() - legendWidth + 15.f : legendWidth - 15.f; float bottomY = legendHeight + 15.f; float distLegend = distanceToCenter(bottomX, bottomY); MPPointF reference = getPosition(center, getRadius(), getAngleForPoint(bottomX, bottomY)); float distReference = distanceToCenter(reference.x, reference.y); float minOffset = Utils.convertDpToPixel(5f); if (bottomY >= center.y && getHeight() - legendWidth > getWidth()) { xLegendOffset = legendWidth; } else if (distLegend < distReference) { float yOffset = getRequiredLegendOffset(); legendLeft += getRequiredBaseOffset(); legendRight += getRequiredBaseOffset(); legendTop += getRequiredBaseOffset(); legendBottom += getRequiredBaseOffset(); XAxis x = this.getXAxis(); legendTop += getExtraTopOffset(); legendRight += getExtraRightOffset(); legendBottom += getExtraBottomOffset();
@Override public Highlight getHighlight(float x, float y) { float touchDistanceToCenter = mChart.distanceToCenter(x, y); // check if a slice was touched if (touchDistanceToCenter > mChart.getRadius()) { // if no slice was touched, highlight nothing return null; } else { float angle = mChart.getAngleForPoint(x, y); if (mChart instanceof PieChart) { angle /= mChart.getAnimator().getPhaseY(); } int index = mChart.getIndexForAngle(angle); // check if the index could be found if (index < 0 || index >= mChart.getData().getMaxEntryCountSet().getEntryCount()) { return null; } else { return getClosestHighlight(index, x, y); } } }
if (mChart.isRotationEnabled()) { if (mChart.isDragDecelerationEnabled()) sampleVelocity(x, y); case MotionEvent.ACTION_MOVE: if (mChart.isDragDecelerationEnabled()) sampleVelocity(x, y); mLastGesture = ChartGesture.ROTATE; mTouchMode = ROTATE; mChart.disableScroll(); } else if (mTouchMode == ROTATE) { updateGestureRotation(x, y); mChart.invalidate(); case MotionEvent.ACTION_UP: if (mChart.isDragDecelerationEnabled()) { mChart.enableScroll(); mTouchMode = NONE;