Android圖表繪制

由于最新項(xiàng)目需要用到圖表顯示數(shù)據(jù),所以參考網(wǎng)上的資源,寫(xiě)了一個(gè)demo二鳄,主要是通過(guò)在Activity發(fā)送不同的數(shù)據(jù)到view里面刷新顯示,每發(fā)送一次數(shù)據(jù)媒怯,就顯示幾個(gè)隨機(jī)數(shù)到view顯示订讼。
顯示效果如圖:


這里寫(xiě)圖片描述

代碼注釋比較詳細(xì),就不做太多說(shuō)明了扇苞。
ZywChartView.java

@SuppressLint("DrawAllocation")
public class ZywChartView extends View {

    private String TAG = "ZywChartView";
    // 默認(rèn)邊距
    
    private float Margin = 40;
    
    //圓半徑
    private int circleRadius = 8;
    
    // X,Y軸的單位長(zhǎng)度
    private float Xscale = 20;
    private float Yscale = 20;
    
    //X軸第1個(gè)節(jié)點(diǎn)到最后1個(gè)節(jié)點(diǎn)的長(zhǎng)度
    private float xLength;
    //Y軸第1個(gè)節(jié)點(diǎn)到最后1個(gè)節(jié)點(diǎn)的長(zhǎng)度
    private float yLength;
    
    //X軸第1個(gè)節(jié)點(diǎn)的偏移量
    private float xFirstPointOffset;
    
    //y軸顯示的節(jié)點(diǎn)間隔距離
    private int yScaleForData = 5;

    //畫(huà)線顏色
    private int lineColor = this.getResources().getColor(R.color.saswell_yellow);

    // 原點(diǎn)坐標(biāo)
    private float Xpoint;
    private float Ypoint;
    
    private String yUnit = "";
    private String xUnit = "";

    // X,Y軸上面的顯示文字
    private String[] Xlabel = { "1", "2", "3", "4", "5", "6", "7"};
    private String[] Ylabel = { "0", "1", "2", "3", "4", "5", "6", "7", "8",
            "9", "10" };
    
    private final static int Y_SCALE_FOR_DATA_DAY = 5; 
    private final static int Y_SCALE_FOR_DATA_WEEK = 2; 
    private final static int Y_SCALE_FOR_DATA_MOUNTH = 2; 
    
    // 曲線數(shù)據(jù)
    private int[] Data = {5, 5, 5, 5, 5, 5, 5};
    
    public ZywChartView(Context context, String[] xlabel, String[] ylabel, int[] data) {
        super(context);
        this.Xlabel = xlabel;
        this.Ylabel = ylabel;
        this.Data = data;
    }

    public ZywChartView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        Log.e(TAG,"ZywChartView(Context context, AttributeSet attrs, int defStyleAttr)");
    }

    public ZywChartView(Context context, AttributeSet attrs) {
        super(context, attrs);
        
        init();
        xFirstPointOffset = 2 * this.Margin;
        Log.e(TAG,"ZywChartView(Context context, AttributeSet attrs)");
    }

    public ZywChartView(Context context) {
        super(context);
        Log.e(TAG,"ZywChartView(Context context)");
    }

    /**
     * 設(shè)置顯示的數(shù)據(jù)
     * @param str要顯示的數(shù)據(jù)字符串
     * @author zyw
     */
    public void setData(String str){
        String[] tempData;
        tempData = str.split(",");  
        int yDataLength = 0;
        Log.e(TAG, "str = " + str);
        Data = new int[tempData.length];
        Xlabel = new String[tempData.length];
        
        if(tempData.length >= 28){
            yScaleForData = Y_SCALE_FOR_DATA_MOUNTH;
            yDataLength = 25;
            xUnit = getResources().getString(R.string.x_unit_month);
            yUnit = getResources().getString(R.string.y_unit_month);
        }else if(tempData.length >= 12){
            yScaleForData = Y_SCALE_FOR_DATA_DAY;
            yDataLength = 61;
            xUnit = getResources().getString(R.string.x_unit_day);
            yUnit = getResources().getString(R.string.y_unit_day);
        }else{
            yScaleForData = Y_SCALE_FOR_DATA_WEEK;
            yDataLength = 25;
            xUnit = getResources().getString(R.string.x_unit_week);
            yUnit = getResources().getString(R.string.y_unit_week);
        }
        
        Ylabel = new String[yDataLength];
        for(int i = 0; i < yDataLength; i++){
            Ylabel[i] = Integer.toString(i);
            //Log.e(TAG,"Ylable[" + i +  "]" + Ylabel[i]);
        }

        for(int i = 0; i < tempData.length; i++){
            Data[i] = Integer.parseInt(tempData[i]);
            //Log.e(TAG,"Data[" + i +  "]" + Data[i]);
            Xlabel[i] = Integer.toString(i + 1);
            Log.e(TAG,"Xlable[" + i +  "]" + Xlabel[i]);
        }
        
        invalidate();
    }

    // 初始化數(shù)據(jù)
    public void init() {
        Xpoint = this.Margin;
        Log.e(TAG, "this.getHeight() == " + this.getHeight());
        Ypoint = this.getHeight() - this.Margin;
        Xscale = (this.getWidth() - 4 * this.Margin) / (this.Xlabel.length);
        Yscale = (this.getHeight() - 3 * this.Margin) / (this.Ylabel.length);
        
        xLength = this.getWidth() - (4 * this.Margin);
        yLength = this.getHeight() - (2 * this.Margin);
        
        xFirstPointOffset = Xscale;
    }

    public float getMargin() {
        return Margin;
    }

    public void setMargin(int margin) {
        Margin = margin;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.BLACK);
        Log.e(TAG, "onDraw");
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setAntiAlias(true);
        paint.setColor(lineColor);
        paint.setStrokeWidth(3);
        init();
        this.drawXLine(canvas, paint);
        this.drawYLine(canvas, paint);
        this.drawDashPath(canvas);
        this.drawData(canvas);
        this.drawXUnit(canvas);
        this.drawYUnit(canvas);
    }

    //畫(huà)虛線
    private void drawDashPath(Canvas canvas) {
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(lineColor);
        paint.setStrokeWidth(3);
        Path path = new Path();
        //繪制長(zhǎng)度為10的實(shí)線欺殿,再繪制長(zhǎng)度為10的空白,再繪制長(zhǎng)度為10的實(shí)線鳖敷,再回執(zhí)長(zhǎng)度為10的空白脖苏,依次重復(fù),1為偏移量
        PathEffect effects = new DashPathEffect(new float[] { 10, 10, 10, 10}, 1);
        paint.setPathEffect(effects);

        // 縱向線
        for (int i = 0; i * Xscale < xLength; i++) {
            float startX = Xpoint + i * Xscale + xFirstPointOffset;
            float startY = Ypoint;
            float stopY = calY(Data[i]);
            path.moveTo(startX, startY);
            path.lineTo(startX, stopY);
            canvas.drawPath(path, paint);
        }
    }

    private void drawXUnit(Canvas canvas) {
        Paint p = new Paint();
        p.setAntiAlias(true);
        p.setColor(lineColor);
        p.setStrokeWidth(2);
        p.setTextSize(this.Margin / 2);
        canvas.drawText(xUnit, this.getWidth() - this.Margin * 2 + this.Margin / 4, Ypoint + this.Margin / 5, p);
    }
    
    private void drawYUnit(Canvas canvas) {
        Paint p = new Paint();
        p.setAntiAlias(true);
        p.setColor(lineColor);
        p.setStrokeWidth(2);
        p.setTextSize(this.Margin / 2);
        canvas.drawText(yUnit, this.Margin / 2, this.Margin / 2, p);
    }
    
    // 畫(huà)橫縱軸
    private void drawXLine(Canvas canvas, Paint p) {
        canvas.drawLine(Xpoint, Ypoint, this.getWidth() - this.Margin * 2, Ypoint,
                p);
        canvas.drawLine(this.getWidth() - this.Margin * 2, Ypoint, this.getWidth()
                - this.Margin * 2 - this.Margin / 3, Ypoint - this.Margin / 3, p);
        canvas.drawLine(this.getWidth() - this.Margin * 2, Ypoint, this.getWidth()
                - this.Margin * 2 - this.Margin / 3, Ypoint + this.Margin / 3, p);
    }
    
    private void drawYLine(Canvas canvas, Paint p) {
        canvas.drawLine(Xpoint, Ypoint, this.Margin, this.Margin, p);
        canvas.drawLine(Xpoint, this.Margin, Xpoint - Xpoint / 3, this.Margin
                + this.Margin / 3, p);
        canvas.drawLine(Xpoint, this.Margin, Xpoint + Xpoint / 3, this.Margin
                + this.Margin / 3, p);
    }

    // 畫(huà)數(shù)據(jù)
    private void drawData(Canvas canvas) {
        Paint p = new Paint();
        p.setAntiAlias(true);
        p.setColor(lineColor);
        p.setStrokeWidth(3);
        p.setTextSize(this.Margin / 2);
        //橫向
        for (int i = 0; i * Xscale < xLength; i++) {
            float startX = Xpoint + i * Xscale + xFirstPointOffset;
            canvas.drawText(this.Xlabel[i], startX - this.Margin / 4,
                    this.getHeight() - this.Margin / 4, p);
            canvas.drawCircle(startX, calY(Data[i]), circleRadius, p);
            if(i != 0){
                canvas.drawLine(Xpoint + (i - 1) * Xscale + xFirstPointOffset, calY(Data[i-1]), startX, calY(Data[i]), p);
            }
        }
        
        //縱向
        for (int i = 0; (yLength - i * Yscale) >= this.Margin; i += yScaleForData) {
            float startY = Ypoint - i * Yscale;
            canvas.drawText(this.Ylabel[i], this.Margin / 4, startY
                    + this.Margin / 4, p);
        }
    }

    /**
     * 
     * @param y  
     * @return
     */
    private float calY(int y){ 
        int y0 = 0 ;
        int y1 = 0 ;
        //  Log.i("zzzz", "y:"+y);
        try{
            y0 = Integer.parseInt(Ylabel[0]);
            //      Log.i("zzzz", "y0"+y0);
            y1 = Integer.parseInt(Ylabel[1]);
            //      Log.i("zzzz","y1"+y1);
        }catch(Exception e){
            //      Log.i("zzzz", "string changed is err");
            return 0;
        }
        try{
            //      Log.i("zzzz", "返回?cái)?shù)據(jù)"+(Ypoint-(y-y0)*Yscale/(y1-y0)) );
            return Ypoint - ((y-y0) * Yscale/(y1-y0));
        }catch(Exception e){
            //  Log.i("zzzz", "return is err");
            return 0;
        }
    }

}

EnergyConsumptionActivity.java

public class EnergyConsumptionActivity extends Activity{
    private int randomNum;
    private RadioGroup rgModeSelect;
    private RadioButton rbDayMode,rbWeekMode,rbMonthMode;
    private String TAG = "MainActivity";
    private Button btnSetData,btnTitle;
    private ZywChartView myView;
    private String strData;
    private int mode,randomDataLength = 10;
    private final static int DAY_MODE = 1;
    private final static int WEEK_MODE = 2;
    private final static int MONTH_MODE = 3;

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

    private OnClickListener onClickListener = new OnClickListener() {
        
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.btnSetData:
                Log.e("ZYW", "set Data.");
                sendData(mode);
                break;
                
            case R.id.title_back:
                Log.e(TAG,"finish.");
                finish();
                break;
                
            default:
                break;
            }
            
        }
    };
    
    private OnCheckedChangeListener checkedChangeListener = new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            try {
                switch(checkedId){
                case R.id.rbDayMode:
                    mode = DAY_MODE;
                    randomDataLength = 60;
                    break;
                case R.id.rbWeekMode:
                    mode = WEEK_MODE;
                    randomDataLength = 24;
                    break;
                case R.id.rbmonthMode:
                    mode = MONTH_MODE;
                    randomDataLength = 24;
                    break;
                }
                sendData(mode);
                Log.e(TAG, "mode = " + mode);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    /**
     * 在0-randomDataLength中生成一個(gè)隨機(jī)數(shù)
     * @return 隨機(jī)生成的數(shù)字組合字符串: data1,data2,data3,...dataN
     */
    public String getRandomNum(int mode){
        String strRandomNum = "";
        int maxI = 7;
        //根據(jù)模式(天定踱、周棍潘、月)確定要繪制的折線圖
        switch (mode) {
        case DAY_MODE:
            maxI = 12;
            break;

        case WEEK_MODE:
            maxI = 7;
            break;

        case MONTH_MODE:
            maxI = 30;
            break;

        default:
            Log.e(TAG, "mode is error");
            break;
        }

        for(int i = 0; i < maxI; i++){
            //在0-randomDataLength中生成一個(gè)隨機(jī)數(shù)
            randomNum = (int) (Math.random()*randomDataLength);
            //Log.e(TAG, "randomNum ==" + randomNum);
            if(i != (maxI - 1)){
                strRandomNum += randomNum + ",";
            }
            else{
                strRandomNum += randomNum;
            }
        }
        Log.e(TAG, "strRandomNum ==" + strRandomNum);
        return strRandomNum;
    }

    /**
     * 發(fā)送數(shù)據(jù)
     * @param mode
     */
    public void sendData(int mode){
        strData = getRandomNum(mode);
        myView.setData(strData);
    }

    public void init(){
        btnSetData = (Button) findViewById(R.id.btnSetData);
        btnTitle = (Button) findViewById(R.id.title_back);
        myView = (ZywChartView) findViewById(R.id.myView);
        rbDayMode = (RadioButton) findViewById(R.id.rbDayMode);
        rbWeekMode = (RadioButton) findViewById(R.id.rbWeekMode);
        rbMonthMode = (RadioButton) findViewById(R.id.rbmonthMode);
        rgModeSelect = (RadioGroup) findViewById(R.id.rgModeSelect);
        
        rgModeSelect.setOnCheckedChangeListener(checkedChangeListener);
        btnTitle.setOnClickListener(onClickListener);
        btnSetData.setOnClickListener(onClickListener);
        
        rbDayMode.setChecked(true);
    }
}

demo下載地址:http://download.csdn.net/detail/oqinyou/9492870

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子亦歉,更是在濱河造成了極大的恐慌恤浪,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肴楷,死亡現(xiàn)場(chǎng)離奇詭異水由,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)赛蔫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)砂客,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人濒募,你說(shuō)我怎么就攤上這事』幔” “怎么了瑰剃?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)筝野。 經(jīng)常有香客問(wèn)我晌姚,道長(zhǎng),這世上最難降的妖魔是什么歇竟? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任挥唠,我火速辦了婚禮,結(jié)果婚禮上焕议,老公的妹妹穿的比我還像新娘宝磨。我一直安慰自己,他們只是感情好盅安,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布唤锉。 她就那樣靜靜地躺著,像睡著了一般别瞭。 火紅的嫁衣襯著肌膚如雪窿祥。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,111評(píng)論 1 285
  • 那天蝙寨,我揣著相機(jī)與錄音晒衩,去河邊找鬼。 笑死墙歪,一個(gè)胖子當(dāng)著我的面吹牛听系,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播虹菲,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼跛锌,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起髓帽,我...
    開(kāi)封第一講書(shū)人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤菠赚,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后郑藏,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體衡查,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年必盖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拌牲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡歌粥,死狀恐怖塌忽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情失驶,我是刑警寧澤土居,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站嬉探,受9級(jí)特大地震影響擦耀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜涩堤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一眷蜓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胎围,春花似錦吁系、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至碧聪,卻和暖如春冒版,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背逞姿。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工辞嗡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人滞造。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓续室,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親谒养。 傳聞我的和親對(duì)象是個(gè)殘疾皇子挺狰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,517評(píng)論 25 707
  • 中學(xué)同學(xué)聚會(huì)丰泊,大家不外乎說(shuō)著一些不著痛癢的奉承話薯定,互相吹捧,也互相揶揄:誰(shuí)升官了瞳购,誰(shuí)發(fā)財(cái)了话侄,誰(shuí)離婚了。我只在一旁靜...
    jane持閱讀 735評(píng)論 13 18
  • 決定加入行動(dòng)營(yíng)学赛,我覺(jué)得自己是一種初生牛犢不怕虎的傻勁年堆。小灶群快要結(jié)營(yíng)了,心里很不舍盏浇,希望小灶群在我的生命中留下更深...
    愛(ài)寫(xiě)作的圈圈閱讀 263評(píng)論 0 6
  • 人生就像一杯茶变丧,不會(huì)苦一輩子,但總會(huì)苦一陣子绢掰。 時(shí)間又像一張網(wǎng)痒蓬,我們把它撒在哪,收獲就在哪里曼月! 奔波是快樂(lè)谊却,它讓我...
    旭小旦閱讀 125評(píng)論 0 0
  • 走過(guò)荒涼的街道柔昼,我不習(xí)慣慢跑哑芹,我習(xí)慣黑暗中的靜悄悄,遠(yuǎn)離熱鬧捕透,遠(yuǎn)離紛擾聪姿,一個(gè)人是一種美好。一個(gè)女人路過(guò)輕飄飄乙嘀,難道...
    李一十八閱讀 362評(píng)論 0 0