@Override
  public void drawData(Canvas c) {

    int width = (int) mViewPortHandler.getChartWidth();
    int height = (int) mViewPortHandler.getChartHeight();

    if (mDrawBitmap == null
        || (mDrawBitmap.getWidth() != width)
        || (mDrawBitmap.getHeight() != height)) {

      if (width > 0 && height > 0) {

        mDrawBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
        mBitmapCanvas = new Canvas(mDrawBitmap);
      } else return;
    }

    mDrawBitmap.eraseColor(Color.TRANSPARENT);

    PieData pieData = mChart.getData();

    for (PieDataSet set : pieData.getDataSets()) {

      if (set.isVisible() && set.getEntryCount() > 0) drawDataSet(c, set);
    }
  }
  @Override
  public void drawValues(Canvas c) {

    PointF center = mChart.getCenterCircleBox();

    // get whole the radius
    float r = mChart.getRadius();
    float rotationAngle = mChart.getRotationAngle();
    float[] drawAngles = mChart.getDrawAngles();
    float[] absoluteAngles = mChart.getAbsoluteAngles();

    float off = r / 10f * 3.6f;

    if (mChart.isDrawHoleEnabled()) {
      off = (r - (r / 100f * mChart.getHoleRadius())) / 2f;
    }

    r -= off; // offset to keep things inside the chart

    PieData data = mChart.getData();
    List<PieDataSet> dataSets = data.getDataSets();
    boolean drawXVals = mChart.isDrawSliceTextEnabled();

    int cnt = 0;

    for (int i = 0; i < dataSets.size(); i++) {

      PieDataSet dataSet = dataSets.get(i);

      if (!dataSet.isDrawValuesEnabled() && !drawXVals) continue;

      // apply the text-styling defined by the DataSet
      applyValueTextStyle(dataSet);

      float lineHeight = Utils.calcTextHeight(mValuePaint, "Q") + Utils.convertDpToPixel(4f);

      List<Entry> entries = dataSet.getYVals();

      for (int j = 0,
              maxEntry =
                  Math.min((int) Math.ceil(entries.size() * mAnimator.getPhaseX()), entries.size());
          j < maxEntry;
          j++) {

        Entry entry = entries.get(j);

        // offset needed to center the drawn text in the slice
        float offset = drawAngles[cnt] / 2;

        // calculate the text position
        float x =
            (float)
                (r
                        * Math.cos(
                            Math.toRadians(
                                (rotationAngle + absoluteAngles[cnt] - offset)
                                    * mAnimator.getPhaseY()))
                    + center.x);
        float y =
            (float)
                (r
                        * Math.sin(
                            Math.toRadians(
                                (rotationAngle + absoluteAngles[cnt] - offset)
                                    * mAnimator.getPhaseY()))
                    + center.y);

        float value =
            mChart.isUsePercentValuesEnabled()
                ? entry.getVal() / data.getYValueSum() * 100f
                : entry.getVal();

        ValueFormatter formatter = dataSet.getValueFormatter();

        boolean drawYVals = dataSet.isDrawValuesEnabled();

        // draw everything, depending on settings
        if (drawXVals && drawYVals) {

          drawValue(c, formatter, value, entry, 0, x, y);

          if (j < data.getXValCount())
            c.drawText(data.getXVals().get(j), x, y + lineHeight, mValuePaint);

        } else if (drawXVals && !drawYVals) {
          if (j < data.getXValCount())
            c.drawText(data.getXVals().get(j), x, y + lineHeight / 2f, mValuePaint);
        } else if (!drawXVals && drawYVals) {

          drawValue(c, formatter, value, entry, 0, x, y + lineHeight / 2f);
        }

        cnt++;
      }
    }
  }