Пример #1
0
  /**
   * 计算同标签多柱形时的X分隔
   *
   * @param XSteps X轴步长
   * @param barNumber 柱形个数
   * @return 返回单个柱形的宽度及间距
   */
  protected List<Float> calcBarWidthAndMargin(float XSteps, int barNumber) {

    /*
    int labelBarTotalWidth = (int) Math.round(XSteps * 0.9);
    int barTotalInnerMargin = (int) Math.round(labelBarTotalWidth * mBarInnerMargin);

    int barTotalWidth = labelBarTotalWidth - barTotalInnerMargin;

    int barInnerMargin = barTotalInnerMargin / barNumber;
    int barWidth = barTotalWidth / barNumber;

    */

    float labelBarTotalWidth = MathHelper.getInstance().mul(XSteps, 0.9f);
    float barTotalInnerMargin =
        MathHelper.getInstance().mul(labelBarTotalWidth, (float) mBarInnerMargin);

    float barTotalWidth = MathHelper.getInstance().sub(labelBarTotalWidth, barTotalInnerMargin);

    float barInnerMargin = MathHelper.getInstance().div(barTotalInnerMargin, barNumber);
    float barWidth = MathHelper.getInstance().div(barTotalWidth, barNumber);

    List<Float> ret = new LinkedList<Float>();
    ret.add(barWidth);
    ret.add(barInnerMargin);
    return ret;
  }
Пример #2
0
  /** 绘制key */
  protected void renderKey(Canvas canvas) {
    if (!getKeyVisible()) return;

    DrawHelper dw = new DrawHelper();
    float textHeight = dw.getPaintFontHeight(getKeyPaint());
    float rectWidth = 2 * textHeight;
    float currentX = 0.0f;
    float currentY = 0.0f;

    if (!isVerticalScreen()) // 横屏
    {
      getKeyPaint().setTextAlign(Align.RIGHT);
      currentX = plotArea.getRight();
      currentY = this.plotArea.getTop() + textHeight;
    } else {
      getKeyPaint().setTextAlign(Align.LEFT);
      currentX = plotArea.getLeft();
      currentY = this.plotArea.getBottom();
    }

    int totalTextWidth = 0;
    for (RadarData cData : mDataSet) {
      getKeyPaint().setColor(cData.getLineColor());
      if (!isVerticalScreen()) // 横屏
      {
        canvas.drawRect(
            currentX, currentY, currentX - rectWidth, currentY - textHeight, getKeyPaint());

        canvas.drawText(cData.getLineKey(), currentX - rectWidth, currentY, getKeyPaint());

        currentY = MathHelper.getInstance().add(currentY, textHeight);

      } else { // 竖屏
        int keyTextWidth = dw.getTextWidth(getKeyPaint(), cData.getLineKey());
        totalTextWidth += keyTextWidth;

        if (totalTextWidth > plotArea.getWidth()) {
          currentY += textHeight;
          currentX = plotArea.getLeft();
          totalTextWidth = 0;
        }
        canvas.drawRect(
            currentX, currentY, currentX + rectWidth, currentY - textHeight, getKeyPaint());
        canvas.drawText(cData.getLineKey(), currentX + rectWidth, currentY, getKeyPaint());

        currentX = MathHelper.getInstance().add(currentX, rectWidth + keyTextWidth + 5);
      }
    }
  }
Пример #3
0
  /**
   * 绘制数据区网络
   *
   * @param canvas 画布
   */
  private void renderDataArea(Canvas canvas) {
    float cirX = plotArea.getCenterX();
    float cirY = plotArea.getCenterY();

    for (RadarData lineData : mDataSet) {
      // 画各自的网
      List<Double> dataset = lineData.getLinePoint();

      int dataSize = dataset.size();
      if (dataSize < 3) {
        Log.e(TAG, "这几个数据可不够,最少三个起步.");
        continue;
      }

      Float[] arrayDataX = new Float[dataSize];
      Float[] arrayDataY = new Float[dataSize];

      int i = 0;
      for (Double data : dataset) {
        Double per = (data - dataAxis.getAxisMin()) / dataAxis.getAxisRange();
        float curRadius = (float) (getRadius() * per);

        // 计算位置
        MathHelper.getInstance().calcArcEndPointXY(cirX, cirY, curRadius, mArrayLabelAgent[i]);

        // 依Path还是Line来决定画线风格
        arrayDataX[i] = MathHelper.getInstance().getPosX();
        arrayDataY[i] = MathHelper.getInstance().getPosY();

        i++; // 标签
      }

      // 画线或填充
      switch (lineData.getAreaStyle()) {
        case FILL:
          drawDataPath(canvas, lineData, arrayDataX, arrayDataY);
          break;
        case STROKE:
          renderDataLine(canvas, lineData, arrayDataX, arrayDataY);
          break;
        default:
          Log.e(TAG, "这类型不认识.");
      }
    }
  }
Пример #4
0
  /**
   * 计算同标签多柱形时的Y分隔
   *
   * @param YSteps Y轴步长
   * @param barNumber 柱形个数
   * @return 返回单个柱形的高度及间距
   */
  protected List<Float> calcBarHeightAndMargin(float YSteps, int barNumber) {
    /*
    int labelBarTotalHeight = (int) Math.round(YSteps * 0.9);
    int barTotalInnerMargin = (int) Math.round(labelBarTotalHeight * mBarInnerMargin);
    int barInnerMargin = barTotalInnerMargin / barNumber;
    int barHeight = (labelBarTotalHeight - barTotalInnerMargin) / barNumber;
    */

    float labelBarTotalHeight = MathHelper.getInstance().mul(YSteps, 0.9f);
    float barTotalInnerMargin =
        MathHelper.getInstance().mul(labelBarTotalHeight, (float) mBarInnerMargin);
    float barInnerMargin = MathHelper.getInstance().div(barTotalInnerMargin, barNumber);
    float barHeight =
        MathHelper.getInstance()
            .div(MathHelper.getInstance().sub(labelBarTotalHeight, barTotalInnerMargin), barNumber);

    List<Float> ret = new LinkedList<Float>();
    ret.add(barHeight);
    ret.add(barInnerMargin);
    return ret;
  }
Пример #5
0
  /**
   * 将百分比转换为饼图显示角度
   *
   * @return 圆心角度
   */
  public float getSliceAgent() {
    float agent = 0.0f;
    try {
      float currentValue = (float) this.getPercentage();
      if (currentValue >= 101f || currentValue < 0.0f) {
        Log.e(TAG, "输入的百分比不合规范.须在0~100之间.");
      } else {
        // agent = (float) Math.rint( 360f *  (currentValue / 100f) );
        agent = MathHelper.getInstance().round(360f * (currentValue / 100f), 2);
      }
    } catch (Exception ex) {
      agent = -1f;
    } finally {

    }
    return agent;
  }
  public PointF renderLabelLine(
      String text,
      float itemAngle,
      float cirX,
      float cirY,
      float radius,
      float calcAngle,
      Canvas canvas,
      Paint paintLabel,
      boolean showLabel,
      PlotLabelRender plotLabel) {
    float pointRadius = 0.0f;
    if (getLinePointStyle() == XEnum.LabelLinePoint.END
        || getLinePointStyle() == XEnum.LabelLinePoint.ALL) pointRadius = getRadius();

    // 显示在扇形的外部
    // 1/4处为起始点
    float calcRadius = MathHelper.getInstance().sub(radius, radius / mBrokenStartPoint);
    MathHelper.getInstance().calcArcEndPointXY(cirX, cirY, calcRadius, calcAngle);

    float startX = MathHelper.getInstance().getPosX();
    float startY = MathHelper.getInstance().getPosY();

    // 延长原来半径的一半在外面
    calcRadius = radius / 2f;
    MathHelper.getInstance().calcArcEndPointXY(startX, startY, calcRadius, calcAngle);
    float stopX = MathHelper.getInstance().getPosX();
    float stopY = MathHelper.getInstance().getPosY();

    float borkenline = getBrokenLine(); // 折线长度

    float endX = 0.0f, endLabelX = 0.0f;
    if (Float.compare(stopX, cirX) == 0) { // 位于中间竖线上				    		
      if (Float.compare(stopY, cirY) == 1) // 中点上方,左折线
      {
        paintLabel.setTextAlign(Align.LEFT);
        endX = stopX + borkenline; // + pointRadius;
        endLabelX = endX + pointRadius;
      } else { // 中点下方,右折线
        paintLabel.setTextAlign(Align.RIGHT);
        endX = stopX - borkenline;
        endLabelX = endX - pointRadius;
      }
    } else if (Float.compare(stopY, cirY) == 0) { // 中线横向两端
      endX = stopX;
      if (Float.compare(stopX, cirX) == 0 || Float.compare(stopX, cirX) == -1) // 左边
      {
        paintLabel.setTextAlign(Align.RIGHT);
        endLabelX = endX - pointRadius;
      } else {
        paintLabel.setTextAlign(Align.LEFT);
        endLabelX = endX + pointRadius;
      }

    } else if (Float.compare(stopX + borkenline, cirX) == 1) // 右边
    {
      paintLabel.setTextAlign(Align.LEFT);
      endX = stopX + borkenline;
      endLabelX = endX + pointRadius;
    } else if (Float.compare(stopX - borkenline, cirX) == -1) // 左边
    {
      paintLabel.setTextAlign(Align.RIGHT);
      endX = stopX - borkenline;
      endLabelX = endX - pointRadius;
    } else {
      endLabelX = endX = stopX;
      paintLabel.setTextAlign(Align.CENTER);
    }

    if (mIsBZLine) {
      // 绘制贝塞尔曲线
      drawBZLine(startX, startY, stopX, stopY, endX, canvas);
    } else {
      // 转折线
      drawBrokenLine(startX, startY, stopX, stopY, endX, canvas);
    }

    // 标签点NONE,BEGIN,END,ALL
    drawPoint(startX, startY, stopX, stopY, endX, pointRadius, canvas);

    if (showLabel) // 标签
    {
      if (null == plotLabel) {
        DrawHelper.getInstance()
            .drawRotateText(text, endLabelX, stopY, itemAngle, canvas, paintLabel);
      } else {
        plotLabel.drawLabel(canvas, paintLabel, text, endLabelX, stopY, itemAngle);
      }
    }

    return (new PointF(endLabelX, stopY));
  }
Пример #7
0
  /** 得到所有相关的交叉点坐标 */
  private void calcAllPoint() {
    float cirX = plotArea.getCenterX();
    float cirY = plotArea.getCenterY();

    // 标签个数决定角的个数
    int labelsCount = getPlotAgentNumber();
    // 轴线tick总数
    int dataAxisTickCount = getAxisTickCount();

    // 扇形角度,依标签个数决定
    float pAngle = MathHelper.getInstance().div(360f, labelsCount); //   72f;

    // 270为中轴线所处圆心角
    float initOffsetAgent = MathHelper.getInstance().sub(270f, pAngle);

    // 依标签总个数算出环数,依数据刻度数决定
    float avgRadius = MathHelper.getInstance().div(getRadius(), (dataAxisTickCount - 1));

    // 当前半径
    float curRadius = 0.0f;
    // 当前圆心角偏移量
    float offsetAgent = 0.0f;

    // 坐标与圆心角
    mArrayDotX = new Float[dataAxisTickCount][labelsCount];
    mArrayDotY = new Float[dataAxisTickCount][labelsCount];
    mArrayLabelAgent = new Float[labelsCount];

    mArrayLabelX = new Float[dataAxisTickCount][labelsCount];
    mArrayLabelY = new Float[dataAxisTickCount][labelsCount];

    int labelHeight = DrawHelper.getInstance().getPaintFontHeight(getLabelPaint());
    float labelRadius = this.getRadius() + labelHeight;
    float currAgent = 0.0f;

    for (int i = 0; i < dataAxisTickCount; i++) // 数据轴
    {
      curRadius = avgRadius * i; // 当前半径长度,依此算出各节点坐标

      for (int j = 0; j < labelsCount; j++) {
        offsetAgent = MathHelper.getInstance().add(initOffsetAgent, pAngle * j);
        currAgent = MathHelper.getInstance().add(offsetAgent, pAngle);

        // 计算位置
        MathHelper.getInstance().calcArcEndPointXY(cirX, cirY, curRadius, currAgent);
        // 点的位置
        mArrayDotX[i][j] = MathHelper.getInstance().getPosX();
        mArrayDotY[i][j] = MathHelper.getInstance().getPosY();

        // 记下每个标签对应的圆心角
        if (0 == i) mArrayLabelAgent[j] = currAgent;

        // 外围标签位置
        MathHelper.getInstance().calcArcEndPointXY(cirX, cirY, labelRadius, currAgent);
        mArrayLabelX[i][j] = MathHelper.getInstance().getPosX();
        mArrayLabelY[i][j] = MathHelper.getInstance().getPosY();
      } // end for labelCount
    } // end for datacount
  }
Пример #8
0
  @Override
  protected boolean renderPlot(Canvas canvas) {
    // 数据源
    List<PieData> chartDataSource = this.getDataSource();
    if (null == chartDataSource) {
      Log.e(TAG, "数据源为空.");
      return false;
    }

    // 计算中心点坐标
    float cirX = plotArea.getCenterX();
    float cirY = plotArea.getCenterY();
    float radius = getRadius();

    // 确定去饼图范围
    float arcLeft = sub(cirX, radius);
    float arcTop = sub(cirY, radius);
    float arcRight = add(cirX, radius);
    float arcBottom = add(cirY, radius);
    RectF arcRF0 = new RectF(arcLeft, arcTop, arcRight, arcBottom);

    // 画笔初始化
    Paint paintArc = new Paint();
    paintArc.setAntiAlias(true);

    float initOffsetAngle = mOffsetAngle;
    float offsetAngle = initOffsetAngle;
    // 3D
    float currentAngle = 0.0f;

    for (int i = 0; i < mRender3DLevel; i++) {
      canvas.save(Canvas.MATRIX_SAVE_FLAG);
      canvas.translate(0, mRender3DLevel - i);
      for (int j = 0; j < chartDataSource.size(); j++) {
        PieData cData = chartDataSource.get(j);
        paintArc.setColor(cData.getSliceColor());
        currentAngle = cData.getSliceAngle();
        if (Float.compare(currentAngle, 0.0f) == 0 || Float.compare(currentAngle, 0.0f) == -1)
          continue;

        if (cData.getSelected()) // 指定突出哪个块
        {
          // 偏移圆心点位置(默认偏移半径的1/10)
          float newRadius = div(radius, SELECTED_OFFSET);
          // 计算百分比标签
          MathHelper.getInstance()
              .calcArcEndPointXY(cirX, cirY, newRadius, add(offsetAngle, div(currentAngle, 2f)));

          float arcLeft2 = sub(MathHelper.getInstance().getPosX(), radius);
          float arcTop2 = sub(MathHelper.getInstance().getPosY(), radius);
          float arcRight2 = add(MathHelper.getInstance().getPosX(), radius);
          float arcBottom2 = add(MathHelper.getInstance().getPosY(), radius);

          RectF arcRF1 = new RectF(arcLeft2, arcTop2, arcRight2, arcBottom2);
          canvas.drawArc(arcRF1, offsetAngle, currentAngle, true, paintArc);
        } else {
          canvas.drawArc(arcRF0, offsetAngle, currentAngle, true, paintArc);
        }
        // 下次的起始角度
        offsetAngle = add(offsetAngle, currentAngle);
        // k += 2;
      }
      canvas.restore();
      offsetAngle = initOffsetAngle;
    }

    // 平面
    currentAngle = 0.0f;
    offsetAngle = initOffsetAngle;

    for (int j = 0; j < chartDataSource.size(); j++) {
      PieData cData = chartDataSource.get(j);
      currentAngle = cData.getSliceAngle();
      int darkColor = DrawHelper.getInstance().getDarkerColor((int) cData.getSliceColor());
      paintArc.setColor(darkColor);

      if (cData.getSelected()) // 指定突出哪个块
      {
        // 偏移圆心点位置(默认偏移半径的1/10)
        float newRadius = div(radius, SELECTED_OFFSET);
        // 计算百分比标签
        MathHelper.getInstance()
            .calcArcEndPointXY(cirX, cirY, newRadius, add(offsetAngle, div(currentAngle, 2f)));

        float arcLeft2 = sub(MathHelper.getInstance().getPosX(), radius);
        float arcTop2 = sub(MathHelper.getInstance().getPosY(), radius);
        float arcRight2 = add(MathHelper.getInstance().getPosX(), radius);
        float arcBottom2 = add(MathHelper.getInstance().getPosY(), radius);

        RectF arcRF1 = new RectF(arcLeft2, arcTop2, arcRight2, arcBottom2);
        canvas.drawArc(arcRF1, offsetAngle, (float) currentAngle, true, paintArc);
        renderLabel(
            canvas,
            cData.getLabel(),
            MathHelper.getInstance().getPosX(),
            MathHelper.getInstance().getPosY(),
            radius,
            offsetAngle,
            currentAngle);
      } else {
        canvas.drawArc(arcRF0, offsetAngle, (float) currentAngle, true, paintArc);
        renderLabel(canvas, cData.getLabel(), cirX, cirY, radius, offsetAngle, currentAngle);
      }

      // 保存角度
      saveArcRecord(j, cirX, cirY, radius, offsetAngle, currentAngle);

      // 下次的起始角度
      offsetAngle = add(offsetAngle, currentAngle);
    }
    // 图KEY
    plotLegend.renderPieKey(canvas, this.getDataSource());
    return true;
  }