散状花瓣图,玫瑰图,南丁格尔图

业务图,业务代码

public class RoseChart extends View {
    //图标尺寸
    private        int           chart_size;
    private static Context       context;
    //传入参数(各个风向百分比)
    private        List<Float>   percentageList;
    private        List<String>  nameList;
    private        List<Integer> colorList;
    //画笔初始化
    private        Paint         paintArc        = new Paint();//扇形图
    private        Paint         paintLabel      = new Paint();//一层一层圈
    private        Paint         paintCircular   = new Paint();//中间圆
    // 画笔绘制中间的文字
    private        Paint         paintCenterText = new Paint();
    private        String        mText           = "000%";
    ;

    public RoseChart(Context context) {
        super(context, null);
        this.context = context;
        initData();
    }

    private void initData() {
        percentageList = new ArrayList<>();
        percentageList.add(40f);
        percentageList.add(50f);
        percentageList.add(60f);
        percentageList.add(35f);
        percentageList.add(70f);
        percentageList.add(80f);
        percentageList.add(90f);
        nameList = new ArrayList<>();
        nameList.add("N");
        nameList.add("NNE");
        nameList.add("NE");
        nameList.add("ENE");
        nameList.add("E");
        nameList.add("ESE");
        nameList.add("SE");
        colorList = new ArrayList<>();
        colorList.add(Color.RED);
        colorList.add(Color.BLUE);
        colorList.add(Color.YELLOW);
        colorList.add(Color.GRAY);
        colorList.add(Color.MAGENTA);
        colorList.add(Color.LTGRAY);
        colorList.add(Color.CYAN);
        colorList.add(Color.GREEN);
        mText = "45%";
    }

    public RoseChart(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        initData();

    }

    @Override
    public void onDraw(Canvas canvas) {
        //画布背景
        canvas.drawColor(getResources().getColor(R.color.white));

        float cirX = getWidth() / 2;
        float cirY = getHeight() / 2;
        //计算绘制区域半径
        float radius = (float) (getHeight() * 0.42);//150;
        paintLabel.setColor(Color.parseColor("#DDDDDD"));
        paintLabel.setAntiAlias(true);
        paintArc.setAntiAlias(true);
        //位置计算类
        XChartCalc xcalc = new XChartCalc();

        float Percentage   = 0.0f;
        float CurrPer      = 0.0f;//绘制 扇形区域 当前起始角度
        float CurrPerLabel = 0.0f;//绘制 风向标识 当前起始角度
        float NewRaidus    = 0.0f;

        //计算每个扇区的圆心角度数
        //        Percentage = 360 / arrPerLabel.length;
        //        Percentage = (float) (Math.round(Percentage * 100)) / 100;
        Percentage = (float) round(360.00 / nameList.size(), 2);

        //计算起始扇形区域角度(默认顺时针方向 N-->NNE-->NE-->ENE-->E.....填充扇区)
        CurrPer -= (float) round((Percentage - 4) / 2, 2);
        CurrPerLabel -= (float) round((Percentage - 4) / 2, 2);

        //绘制外圈,等分比
        paintLabel.setStyle(Paint.Style.STROKE);
        paintLabel.setStrokeCap(Paint.Cap.BUTT);
        canvas.drawCircle(cirX, cirY, radius, paintLabel);
        canvas.drawCircle(cirX, cirY, (float) (radius * 0.875), paintLabel);
        canvas.drawCircle(cirX, cirY, (float) (radius * 0.75), paintLabel);
        canvas.drawCircle(cirX, cirY, (float) (radius * 0.625), paintLabel);
        canvas.drawCircle(cirX, cirY, (float) (radius * 0.5), paintLabel);
        canvas.drawCircle(cirX, cirY, (float) (radius * 0.375), paintLabel);

        //绘制三个不同百分比标识
        //1,取出最大百分比
        Float max = Collections.max(percentageList);

        //绘制 风向 扇区
        for (int i = 0; i < percentageList.size(); i++) {
            //将百分比转换为新扇区的半径
            if (percentageList.get(i) == max) {
                NewRaidus = radius;
            } else {
                NewRaidus = radius * (percentageList.get(i) / max);
                NewRaidus = (float) (Math.round(NewRaidus * 100)) / 100;
            }

            float NewarcLeft   = cirX - NewRaidus;
            float NewarcTop    = cirY - NewRaidus;
            float NewarcRight  = cirX + NewRaidus;
            float NewarcBottom = cirY + NewRaidus;
            RectF NewarcRF     = new RectF(NewarcLeft, NewarcTop, NewarcRight, NewarcBottom);
            //分配颜色
            paintArc.setColor(colorList.get(i));
            paintArc.setAlpha(255);
            //在饼图中显示所占比例
            canvas.drawArc(NewarcRF, CurrPer - 90, Percentage, true, paintArc);
            //下次的起始角度
            CurrPer += Percentage;
        }

        //绘制外圈风向标识
        for (int j = 0; j < nameList.size(); j++) {
            //计算百分比标签
            xcalc.CalcArcEndPointXY(cirX, cirY, radius, (float) (CurrPerLabel + (Percentage - 4) * 0.5));
            //标识
            paintLabel.setColor(Color.BLACK);
            paintLabel.setTextSize(getResources().getDimension(R.dimen.RoseChart_direction));
            paintLabel.setStrokeWidth((float) 0.8);
            canvas.drawText(nameList.get(j), xcalc.getPosX(), xcalc.getPosY(), paintLabel);
            //下次的起始角度
            CurrPerLabel += Percentage;
        }
        paintLabel.setColor(Color.BLACK);

        //中心画圆
        paintCircular.setColor(Color.WHITE);
        canvas.drawCircle(cirX, cirY, (float) (radius * 0.25), paintCircular);

        //绘制中心文字
        paintCenterText.setColor(Color.BLACK);
        paintCenterText.setTextSize(60);        paintCenterText.setTypeface(Typeface.DEFAULT_BOLD);//设置粗体        // 要重新设置宽度为0
        paintCenterText.setStrokeWidth(0);
        // 得到指定文本边界的指定大小

        Rect bounds = new Rect();
        paintCenterText.getTextBounds(mText, 0, mText.length(), bounds);
        canvas.drawText(mText, cirX - bounds.width() / 2, cirY + bounds.height() / 2, paintCenterText);

    }

    public static class XChartCalc {
        private static float x;
        private static float y;
        private static float r;

        public static void CalcArcEndPointXY(float cirX, float cirY, float radius, float Percentage) {
            double a = 2 * Math.PI * (Percentage / 360);
            if (Percentage >= 0 && Percentage < 130) {
                r = radius + context.getResources().getDimension(R.dimen.RoseChart_distance1);
            } else if (Percentage >= 130 && Percentage < 180) {
                r = radius + context.getResources().getDimension(R.dimen.RoseChart_distance2);
            } else if (Percentage == 180) {
                r = radius + context.getResources().getDimension(R.dimen.RoseChart_distance3);
            } else if (Percentage > 180 && Percentage < 240) {
                r = radius + context.getResources().getDimension(R.dimen.RoseChart_distance4);
            } else if (Percentage > 240 && Percentage < 270) {
                r = radius + context.getResources().getDimension(R.dimen.RoseChart_distance5);
            } else if (Percentage == 270) {
                r = radius + context.getResources().getDimension(R.dimen.RoseChart_distance6);
            } else if (Percentage > 270 && Percentage < 300) {
                r = radius + context.getResources().getDimension(R.dimen.RoseChart_distance5);
            } else if (Percentage >= 300 && Percentage < 330) {
                r = radius + context.getResources().getDimension(R.dimen.RoseChart_distance6);
            } else if (Percentage >= 330 && Percentage < 350) {
                r = radius + context.getResources().getDimension(R.dimen.RoseChart_distance3);
            }
            y = cirY - (float) (r * (Math.cos(a)));
            x = cirX + (float) (r * (Math.sin(a)));
        }

        public static float getPosX() {
            return x;
        }

        public static float getPosY() {
            return y;
        }
    }

    /**
     * 返回指定小数位数
     *
     * @param v
     * @param scale
     * @return
     */
    public static double round(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The   scale   must   be   a   positive   integer   or   zero");
        }
        BigDecimal b   = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public void setColorText(List<String> nameSize,List<Float> percentSize,List<Integer> colorSize,String percentText) {
        percentageList.clear();
        nameList.clear();
        colorList .clear();
        mText = percentText;
        invalidate();
    }
}
<dimen name="RoseChart_persent">10sp</dimen>
<dimen name="RoseChart_direction">8sp</dimen>

<dimen name="RoseChart_distance1">4dp</dimen>
<dimen name="RoseChart_distance2">8dp</dimen>
<dimen name="RoseChart_distance3">10dp</dimen>
<dimen name="RoseChart_distance4">16dp</dimen>
<dimen name="RoseChart_distance5">22dp</dimen>
<dimen name="RoseChart_distance6">12dp</dimen>

//直接复制黏贴,运行就行,整合了好几篇博客写的

感谢https://blog.csdn.net/qq_35178316/article/details/61200170   这个写的是玫瑰图(复制黏贴的基本全部的代码)

https://blog.csdn.net/xcl168/article/details/23222417  这个写的是玫瑰图 (复制黏贴的部分样式调整的参考)

https://github.com/NewHuLe/RingProgressView   这个写的是环形进度圈(复制黏贴的中间的文字和中间白圆)

猜你喜欢

转载自blog.csdn.net/haiyoumeizhuce/article/details/111229735