Android自定义条形对比统计图

本文实例为大家分享了Android自定义条形对比统计图的具体代码,供大家参考,具体内容如下

一、测试截图

二、实现方法

package com.xtravel.widget;

import java.util.Timer;

import java.util.TimerTask;

import android.annotation.SuppressLint;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.view.View;

/**

* @name 自定义数据中心旅客分析变化趋势图

* @Descripation <br>

* 1、根据用户提供的数据(两组float[]数)智能绘制数据的对比条形图。<br>

* 2、绘制图表信息:边框、表名、建立二维坐标系、刻度数量、刻度值、单位、网络线、图例、数据系列。<br>

* 3、其中Y轴的最大刻度值是用户所提供数据中float[]的最大值,分度值是最大刻度值与刻度数目的比。<br>

* 4、绘制用户数据对比条形图:启动线程,遍历数组值,不断在原图上刷新。<br>

* @author Freedoman

* @date 2014-9-17

* @version 1.0

*/

public class DataCenterCustomBarChart extends View {

// 框架起点坐标、中心坐标、宽高

private final int FRAME_X = 20;

private final int FRAME_Y = 20;

private final int FRAME_WIDTH = 1000;

private final int FRAME_HEIGHT = 350;

private final int FRAME_CENTER_X = FRAME_WIDTH / 2 + FRAME_X;

private final int FRAME_CENTER_Y = FRAME_HEIGHT / 2 + FRAME_Y;

// 二维坐标系原点坐标

private final int ORIGIN_X = FRAME_X + 100;

private final int ORIGIN_Y = FRAME_Y + FRAME_HEIGHT - 100;

// XY轴终点坐标

private final int XAXIS_X = FRAME_X + FRAME_WIDTH - 200;

private final int XAXIS_Y = ORIGIN_Y;

private final int YAXIS_X = ORIGIN_X;

private final int YAXIS_Y = FRAME_Y + 50;

// XY轴刻度数

private int countX;

private int countY;

// XY轴分度值、真实数据分度值

private float intervalX;

private float intervalY;

private float intervalPress;

// 单位名称

private String nameX;

private String nameY;

// 图表名称

private String chartTitle;

// 用户数据

private int[] data1;

private int[] data2;

private int currentPosition;

/**

* 用户建立图表

*

* @param context

* @param chartTitle

* 表名称

* @param nameXAxis

* X轴单位

* @param nameYAxis

* Y轴单位

* @param countY

* Y轴刻度数目

* @param thisYearWeekPerson

* 用户数据

* @param lastYearWeekPerson

* 用户数据

*/

public DataCenterCustomBarChart(Context context, String chartTitle,

String nameXAxis, String nameYAxis, int countY,

int[] thisYearWeekPerson, int[] lastYearWeekPerson) {

super(context);

this.chartTitle = chartTitle;

// x轴刻度数量以用户数据最大数据为依据,y轴刻度数量由用户来指定

this.countX = thisYearWeekPerson.length > lastYearWeekPerson.length ? thisYearWeekPerson.length

: lastYearWeekPerson.length;

this.countY = countY;

this.nameX = nameXAxis;

this.nameY = nameYAxis;

this.data1 = thisYearWeekPerson;

this.data2 = lastYearWeekPerson;

// 计算XY轴分度值 = 轴长/刻度数

this.intervalX = (XAXIS_X - ORIGIN_X) / countX;

this.intervalY = (ORIGIN_Y - YAXIS_Y) / countY;

// 计算用户数据分度值 = 用户数据最大值/ 刻度数

float max1 = findMaxData(thisYearWeekPerson);

float max2 = findMaxData(lastYearWeekPerson);

this.intervalPress = (max1 > max2 ? max1 : max2) / countY;

// startDrawDynomicBar();

}

/**

* 动态绘制任务

*/

public void freshDynomicBar() {

final Timer timer = new Timer();

TimerTask timerTask = new TimerTask() {

@Override

public void run() {

currentPosition++;

postInvalidate();

if (currentPosition == countX) {

timer.cancel();

}

}

};

timer.schedule(timerTask, 100, 800);

}

/**

* 绘制图表

*/

@SuppressLint("DrawAllocation")

public void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.drawColor(Color.WHITE);

Paint paint = new Paint();

initAXIS(canvas, paint, chartTitle);

drawDynamicBar1(canvas, paint, data1);

drawDynamicBar2(canvas, paint, data2);

}

/**

* 初始化图表基本信息<br>

* 表名、坐标系、刻度数量、刻度值、网络线、图例、数据系列

*

* @param canvas

*/

private void initAXIS(Canvas canvas, Paint paint, String chartTitle) {

// 画边框

paint.setColor(Color.GRAY);

paint.setStyle(Paint.Style.STROKE);

paint.setStrokeWidth(6);

canvas.drawRect(FRAME_X, FRAME_Y, FRAME_WIDTH, FRAME_HEIGHT, paint);

// 画坐标轴

paint.setColor(Color.BLACK);

paint.setStyle(Paint.Style.STROKE);

paint.setStrokeWidth(5);

// X轴及方向箭头

canvas.drawLine(ORIGIN_X, ORIGIN_Y, XAXIS_X, XAXIS_Y, paint);

canvas.drawLine(XAXIS_X, XAXIS_Y, XAXIS_X - 10, XAXIS_Y - 10, paint);

canvas.drawLine(XAXIS_X, XAXIS_Y, XAXIS_X - 10, XAXIS_Y + 10, paint);

// Y轴及方向箭头

canvas.drawLine(ORIGIN_X, ORIGIN_Y, YAXIS_X, YAXIS_Y, paint);

canvas.drawLine(YAXIS_X, YAXIS_Y, YAXIS_X - 10, YAXIS_Y + 10, paint);

canvas.drawLine(YAXIS_X, YAXIS_Y, YAXIS_X + 10, YAXIS_Y + 10, paint);

// 图表名称(2014年五月第一周)

paint.setColor(Color.BLACK);

paint.setStyle(Paint.Style.FILL);

paint.setTextSize(20);// 设置字体大小

paint.setStrokeWidth(2);

canvas.drawText(chartTitle, FRAME_CENTER_X - 100, FRAME_Y + 30, paint);

// 绘制数据系列20*20矩形(今年、去年)

paint.setColor(Color.CYAN);

canvas.drawRect(FRAME_WIDTH - 100, FRAME_CENTER_Y - 30,

FRAME_WIDTH - 70, FRAME_CENTER_Y, paint);

canvas.drawText("今年", FRAME_WIDTH - 60, FRAME_CENTER_Y, paint);

paint.setColor(Color.MAGENTA);

canvas.drawRect(FRAME_WIDTH - 100, FRAME_CENTER_Y, FRAME_WIDTH - 70,

FRAME_CENTER_Y + 30, paint);

canvas.drawText("去年", FRAME_WIDTH - 60, FRAME_CENTER_Y + 30, paint);

// 画网格线

paint.setColor(Color.GRAY);

paint.setStyle(Paint.Style.STROKE);

paint.setStrokeWidth(2);

// 横线(从x轴依次向上画)

for (int i = 0; i <= countY; i++) {

canvas.drawLine(ORIGIN_X, ORIGIN_Y - i * intervalY, XAXIS_X,

ORIGIN_Y - i * intervalY, paint);

}

// 竖线(从y轴依次向右画)

for (int i = 0; i <= countX; i++) {

canvas.drawLine(ORIGIN_X + i * intervalX, ORIGIN_Y, ORIGIN_X + i

* intervalX, YAXIS_Y, paint);

}

// X轴刻度值(沿X轴方向1、2、3...),轴名称

paint.setColor(Color.BLUE);

paint.setStyle(Paint.Style.FILL);

paint.setStrokeWidth(2);

paint.setTextSize(30);

for (int i = 0; i <= countX; i++) {

canvas.drawText("" + i, ORIGIN_X + i * intervalX, ORIGIN_Y + 50,

paint);

}

paint.setTextSize(20);

// Y轴刻度值(沿Y轴方向,用户提供的数据)轴名称

for (int i = 1; i <= countY; i++) {

canvas.drawText("" + (int) (i * intervalPress), ORIGIN_X - 80,

ORIGIN_Y - i * intervalY + 5, paint);

}

paint.setTextSize(20);

canvas.drawText("(" + nameX + ")", XAXIS_X + 40, XAXIS_Y + 50, paint);

canvas.drawText("(" + nameY + ")", YAXIS_X - 30, YAXIS_Y - 20, paint);

}

/**

* 绘制data1变化趋势线 <br>

*/

@SuppressLint("ResourceAsColor")

private void drawDynamicBar1(Canvas canvas, Paint paint, int[] data) {

float curRectX_data1 = ORIGIN_X + intervalX - 30;

float curRectY_data1;

for (int i = 1; i < currentPosition; i++, curRectX_data1 += intervalX) {

// 绘制data1的动态条形

paint.setColor(Color.CYAN);

curRectY_data1 = data[i - 1] / intervalPress * intervalY;

canvas.drawRect(curRectX_data1, ORIGIN_Y - curRectY_data1,

curRectX_data1 + 30, ORIGIN_Y, paint);

}

}

/**

* 绘制data2变化趋势线

*/

@SuppressLint("ResourceAsColor")

private void drawDynamicBar2(Canvas canvas, Paint paint, int[] data) {

float curRectX_data2 = ORIGIN_X + intervalX;

float curRectY_data2;

for (int i = 1; i < currentPosition; i++, curRectX_data2 += intervalX) {

// 绘制data2的动态条形

paint.setColor(Color.MAGENTA);

curRectY_data2 = data[i - 1] / intervalPress * intervalY;

canvas.drawRect(curRectX_data2, ORIGIN_Y - curRectY_data2,

curRectX_data2 + 30, ORIGIN_Y, paint);

}

}

/**

* 查找数组的最大值

*

* @param data

* @return float

*/

private int findMaxData(int[] data) {

int max = data[0];

for (int i = 1; i < data.length; i++) {

if (data[i] > max) {

max = data[i];

}

}

return max;

}

/**

* 计算今年游客数相对去年的增长率

*

* @return float 增长率百分数

*/

public float getGrowthRate() {

float sumYear = 0, sumLastYear = 0;

for (int i = 0; i < data1.length; i++) {

sumYear += data1[i];

sumLastYear += data2[i];

}

return (sumYear - sumLastYear) / sumLastYear * 100;

}

/**

* 统计一周总人数

*

* @return int 人数

*/

public int getSumWeek() {

int sum = 0;

for (int i = 0; i < data1.length; i++) {

sum += data1[i];

}

return sum;

}

/**

* 统计一周平均每天旅客数量

*

* @return int

*/

public int getAverageWeek() {

return getSumWeek() / data1.length;

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 Android自定义条形对比统计图 的全部内容, 来源链接: utcz.com/p/242867.html

回到顶部