环形图 自定义(一)

需求:自定义环形图(饼图),实现2项数据配比显示;

效果图:

实现分析:

1.目录结构:

代码实现:

1. color.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- 饼图 -->
    <color name="pie_progress_bank">#fd8f8b</color>
    <color name="pie_progress_fund">#2999f9</color>
    <color name="text_tag_bg">#aaaaaa</color>
    <color name="text_progress_bg">#fb4b45</color>
    <color name="text_term_bg">#aaaaaa</color>

</resources>

2. fragment_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.jjc.demo.MainActivity$PlaceholderFragment" >

    <com.jjc.demo.RingView
        android:id="@+id/ringview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

3. RingView.java

package com.jjc.demo;

import java.math.BigDecimal;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.View;

/**
 * 当前环形图实现原理,先画一个完整环形,然后再画一部分环形,两者叠加,显示两种不同的配比;
 * @author ThinkPad
 *
 */
public class RingView extends View{

    /** 当前进度 */
    private int progress;
    /** 总进度 */
    private int max;

    private Paint paint;
    private RectF oval;

    private int width;
    private int height;

    private String term = "";

    /** 半径 */
    private float radius;

    /** 画笔宽度 */
    private float paintWidth;

    /** 组合字体 */
//    private float tagTextSize;

    /** 配比字体 */
    private float progressTextSize;

//    private float tagTextSize;

    /** 期限字体 */
//    private float termTextSize;

    private double rate;

    /**
     * 设置总数
     * @param max
     */
    public void setMax(int max) {
        this.max = max;
    }

    public void setPaintWidth(float paintWidth) {
        this.paintWidth = paintWidth;
    }

    /**
     * 设置进度
     * @param progress
     */
    public void setProgress(int progress) {
        this.progress = progress;
        invalidate();
    }

    /**
     * 设置收益率
     * @param rate
     */
    public void setRate(double rate) {
        this.rate = round(rate, 2, 4);
    }

    public void setTerm(String term) {
        this.term = term;

    }

    public RingView(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint();
        oval = new RectF();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        height = canvas.getHeight();
        width = canvas.getWidth();

        initRadius();
        initPaint();
        initDebugLine(canvas ,false);
        initBankPaint(canvas);
        initFundPaint(canvas);

        initDescrip(canvas);
    }

    /**
     * 测试文字是否居中,标尺线
     */
    private void initDebugLine(Canvas canvas ,boolean isDebug) {

        if(isDebug){
            //竖线
            paint.setColor(Color.BLACK); canvas.drawLine(width/2, 0, width/2, height, paint);
            //横线
            paint.setColor(Color.GRAY); canvas.drawLine(0, height/2, width, height/2, paint);
        }
    }

    /**
     * 比较高度和宽度,然后取短的作为圆环的半径
     */
    private void initRadius() {
        if (width > height) {
            radius = (float) (height * 0.4);
        } else {
            radius = (float) (width * 0.4);
        }
    }

    private void initPaint() {
        if(paintWidth == 0){
            paintWidth = radius/10;
        }

        paint.setAntiAlias(true);// 设置是否抗锯齿
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);// 帮助消除锯齿
    }

    private void initBankPaint(Canvas canvas) {
        paint.setColor(getResources().getColor(R.color.pie_progress_bank));// 设置银行理财画笔

        /** 银行理财标注 */
        // 设置样式-填充
        paint.setStyle(Style.FILL);
        // 绘制一个矩形
        canvas.drawRect(new Rect(10, height-35, 22, height-15), paint);
        paint.setTextSize((float) (radius/5.5));// 设置标注文字的大小
        canvas.drawText("银行理财", 35, height-18, paint);

        /** 银行理财的饼图  */
        paint.setStrokeWidth(paintWidth);// 设置画笔宽度
        paint.setStyle(Style.STROKE);// 设置中空的样式
        canvas.drawCircle(width / 2, height / 2, radius, paint);
    }

    private void initFundPaint(Canvas canvas) {
        paint.setColor(getResources().getColor(R.color.pie_progress_fund));// 设置货币基金画笔

        /** 货币基金标注 */
        // 设置样式-填充
        paint.setStyle(Style.FILL);
        // 绘制一个矩形
        canvas.drawRect(new Rect(10, height-65, 22, height-45), paint);
        paint.setTextSize((float) (radius/5.5));// 设置标注文字的大小
        canvas.drawText("货币基金", 35, height-48, paint);

        /** 货币基金的饼图  */
        paint.setStrokeWidth(paintWidth);// 设置画笔宽度
        paint.setStyle(Style.STROKE);// 设置中空的样式
        oval.set((width / 2 - radius), (height / 2 - radius),
                (width / 2 + radius), (height / 2 + radius));
        canvas.drawArc(oval, -90, ((float) progress / max) * 360, false, paint);// 画圆弧,第二个参数为:起始角度,第三个为跨的角度,第四个为true的时候是实心,false的时候为空心
    }

    private void initDescrip(Canvas canvas) {
        paint.reset();// 将画笔重置
        paint.setStrokeWidth(3);// 再次设置画笔的宽度

        progressTextSize = (float) (radius / 2);

        paint.setTextSize((float) (radius / 7));// 设置标记文字的大小
        paint.setColor(getResources().getColor(R.color.text_tag_bg));// 设置画笔颜色
        canvas.drawText("组合收益率", (float) (width / 2 - radius / 2.8),
                (float) (height / 2 - progressTextSize * 0.5), paint);

        paint.setTextSize((float) (radius / 7));// 设置期限文字的大小
        paint.setColor(getResources().getColor(R.color.text_term_bg));// 设置画笔颜色
        canvas.drawText(term, (float) (width / 2 - radius / 4.5),
                (float) (height / 2 + progressTextSize * 0.7), paint);

        /** 配比数 */
        paint.setTextSize(progressTextSize);// 设置进度文字的大小
        paint.setColor(getResources().getColor(R.color.text_progress_bg));// 设置画笔颜色

        canvas.drawText(rate+"",
                (float) (width / 2 - progressTextSize * 1.1),
                (float) (height / 2 + progressTextSize / 2.5), paint);

        paint.setTextSize((float) (radius / 5));// 设置百分号的大小
        canvas.drawText("%",
                (float) (width / 2 + progressTextSize * 0.9),
                (float) (height / 2 + progressTextSize / 2.5), paint);
    }

    /**
     * 对double数据进行取精度.
     * <p>
     * For example: <br>
     * double value = 100.345678; <br>
     * double ret = round(value,4,BigDecimal.ROUND_HALF_UP); <br>
     * ret为100.3457 <br>
     *
     * @param value
     *            double数据.
     * @param scale
     *            精度位数(保留的小数位数).
     * @param roundingMode
     *            精度取值方式.
     * @return 精度计算后的数据.
     */
    private double round(double value, int scale, int roundingMode) {
        BigDecimal bd = new BigDecimal(value);
        bd = bd.setScale(scale, roundingMode);
        double d = bd.doubleValue();
        bd = null;
        return d;
    }

}

4.MainActivity.java

package com.jjc.demo;

import android.support.v7.app.ActionBarActivity;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment()).commit();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        private View rootView;
        private RingView ringView;

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            rootView = inflater.inflate(R.layout.fragment_main, container, false);
            return rootView;
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            initView();
        }

        private void initView() {
            ringView = (RingView) rootView.findViewById(R.id.ringview);
            ringView.setMax(100);
            ringView.setRate(5.43);
            ringView.setTerm("六个月");
            ringView.setProgress(40);
        }

    }

}

代码:http://pan.baidu.com/s/1eQzk5SQ

时间: 2024-08-01 09:44:07

环形图 自定义(一)的相关文章

iOS 画环形图

由于新项目的的需求,需要画环形图,由于以前都没接触过这一类(我是菜鸟),去cocochina山找到了一个案例,个人觉得还可以,分享一下 github 地址https://github.com/zhouxing5311/ZZCircleProgress 这个使用起来非常的简单 作者开放了很多接口,可以根据自己的需求进行更改 一般就是声明一个累类就Ok了 具体实现的代码如下 可能我的代码有点不一样,我自己加入了一些元素进去 //无小圆点.同动画时间 self.zzCircleProgress = [

Jfreechart创建环形图

package com.lyf.iaqms; import java.awt.Color; import java.awt.Font; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFrame; import org.jfree.chart.JFreeChart; import org.jfree.chart.StandardChartTheme; import org.jfree.chart.axis.Numb

Sliverlight实例之 绘制扇形和环形图

原文:Sliverlight实例之 绘制扇形和环形图 未解决: 1,任意偏角,是个重点问题: (1),  另一边在弧上坐标 (2),  这个弧的弧度(ArcSegment中的Size或Angle属性) (3),  如何把这个弧度做成依赖属性配置的 2,做成一个自定义控件 有时间,再完成 准备知识: 1,  平面几何思维(三角形,圆,弧,曲线,斜率,方程式) 2,  三次贝塞尔曲线的数学公式 3,  定时器与动画的区别是时间序列 4,  缓动动画   一,1道几何题 已知两点坐标确定一条直线,直线

数据输入——生成你需要的echart图(堆积柱状图、扇形图、嵌套环形图)

最近论文需要一些比较直观的图表, 发现echart做出来的图还是比较美观的,这里介绍如何修改数据生成你需要的echart图. 1.堆积柱状图: http://echarts.baidu.com/examples/editor.html?c=bar-stack 以上的类型的颜色是自动分配的,stack属性可以将同一类型的数据放在一个矩形图中. 2.扇形图 http://echarts.baidu.com/examples/editor.html?c=pie-legend 1---->随机生成扇形图

echart 折线图、柱状图、饼图、环形图颜色修改

之前在做报表的时候用过echart 用完也就完了,而这次在用的时候已经忘了,所以这里简单记录一下,好记性不如烂笔头!!! 1.折线图修改颜色: [javascript] view plain copy xAxis: { type: 'category', boundaryGap: false, data: ['年龄','20岁以下','30岁','40岁','50岁','60岁','60岁以上'] }, yAxis: { type: 'value' }, series: [ { name:'员工

echarts组合环形图的参考例子

https://gallery.echartsjs.com/editor.html?c=x6LFNVgmfx 婚姻情况环形图 该例子提取placeHolderStyle公共变量 series: [ { name: 'Line 4', type: 'pie', clockWise: true, hoverAnimation: false, radius: ['65%', '75%'], itemStyle: dataStyle, data: [{ value: 7645434, name: '已婚

echarts白色实心环形图(空心饼图)的编写

// 数据接入机构统计let myDom = document.getElementById('myChart');let myWidth = myDom.offsetWidth - 5; // 获取容器宽度let myHeight = myDom.offsetHeight - 5; // 获取容器高度let myRadius = myHeight * 0.44 / 2; // 根据环形图内圈百分比获取内圆半径let myPX = (0.3 - (myRadius / myWidth)) * 1

写总结写报告 环形图的制作与应用

人一直追求完美,什么是美,文字的表现力不如语言,但是文图结合就不一样了,我想谁也不喜欢看着枯燥的文字,尤其是报告中,数字多了更让人觉得反感,作报告的时候PPT展示的时候,总不能就写个标题,或者全部都是一页页的文字吧,数据不仅仅是靠数字表现,因此伟大的人类发明了柱状图,圆饼图,折线图,环状图等等. 这样就可以一眼准确的看出系列总数和比例,这就又涉及到了一个词,"比例",比例如果只单调的罗列数据,当我们看到数字的时候并不会有什么感觉,或大或小,就好比我们花钱,为什么花人民币的时候心疼,而刷

百度的echart环形图颜色动态设置

自己参与的有一个项目需要用到环行图,考虑到百度的echart功能很强大兼容性又挺好就使用了这个插件,但是在颜色配置的时候出现了问题按照参考文档的方法是用color:Array这样的形式,但是不知道在哪里设置,在网上查了有两种说法,一种是直接在option里面配置  但是我试了之后直接报错了,还有一种是在>series->itemStyle->normal里面,但是设置之后奇怪的事情发生了,无论设置什么颜色都变成了黑色,至少改变了原来自带的颜色说明这个路径是对的,后来发现可以·用函数的方法