当前位置:网站首页>饼状统计图,带有标注线,都可以自行设定其多种参数选项
饼状统计图,带有标注线,都可以自行设定其多种参数选项
2022-06-24 07:01:00 【Simon66991】
PieChartView
package cn.simon.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
import cn.simon.R;
/** * 饼状统计图,带有标注线,都可以自行设定其多种参数选项 */
public class PieChartView extends View {
private TextPaint mTextPaint;
private float mTextWidth;
private float mTextHeight;
/** * 饼图半径 */
private float pieChartCircleRadius = 100;
private float textBottom;
/** * 记录文字大小 */
private float mTextSize = 14;
/** * 饼图所占矩形区域(不包括文字) */
private RectF pieChartCircleRectF = new RectF();
/** * 饼状图信息列表 */
private List<PieceDataHolder> pieceDataHolders = new ArrayList<>();
/** * 标记线长度 */
private float markerLineLength = 30f;
public PieChartView(Context context) {
super(context);
init(null, 0);
}
public PieChartView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0);
}
public PieChartView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs, defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
// Load attributes
final TypedArray a = getContext().obtainStyledAttributes(
attrs, R.styleable.PieChartView, defStyle, 0);
pieChartCircleRadius = a.getDimension(
R.styleable.PieChartView_circleRadius,
pieChartCircleRadius);
mTextSize = a.getDimension(R.styleable.PieChartView_textSize, mTextSize)/getResources().getDisplayMetrics().density;
a.recycle();
// Set up a default TextPaint object
mTextPaint = new TextPaint();
mTextPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextAlign(Paint.Align.LEFT);
// Update TextPaint and text measurements from attributes
invalidateTextPaintAndMeasurements();
}
private void invalidateTextPaintAndMeasurements() {
mTextPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mTextSize, getContext().getResources().getDisplayMetrics()));
Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
mTextHeight = fontMetrics.descent - fontMetrics.ascent;
textBottom = fontMetrics.bottom;
}
/** * 设置饼状图的半径 * * @param pieChartCircleRadius 饼状图的半径(px) */
public void setPieChartCircleRadius(int pieChartCircleRadius) {
this.pieChartCircleRadius = pieChartCircleRadius;
invalidate();
}
/** * 设置标记线的长度 * * @param markerLineLength 标记线的长度(px) */
public void setMarkerLineLength(int markerLineLength) {
this.markerLineLength = markerLineLength;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
initPieChartCircleRectF();
drawAllSectors(canvas);
}
private void drawAllSectors(Canvas canvas) {
float sum = 0f;
for (PieceDataHolder pieceDataHolder : pieceDataHolders) {
sum += pieceDataHolder.value;
}
float sum2 = 0f;
for (PieceDataHolder pieceDataHolder : pieceDataHolders) {
float startAngel = sum2 / sum * 360;
sum2 += pieceDataHolder.value;
float sweepAngel = pieceDataHolder.value / sum * 360;
drawSector(canvas, pieceDataHolder.color, startAngel, sweepAngel);
drawMarkerLineAndText(canvas, pieceDataHolder.color, startAngel + sweepAngel / 2, pieceDataHolder.marker);
}
}
private void initPieChartCircleRectF() {
pieChartCircleRectF.left = getWidth() / 2 - pieChartCircleRadius;
pieChartCircleRectF.top = getHeight() / 2 - pieChartCircleRadius;
pieChartCircleRectF.right = pieChartCircleRectF.left + pieChartCircleRadius * 2;
pieChartCircleRectF.bottom = pieChartCircleRectF.top + pieChartCircleRadius * 2;
}
/** * Gets the example dimension attribute value. * * @return The example dimension attribute value.(sp) */
public float getTextSize() {
return mTextSize;
}
/** * Sets the view's text dimension attribute value. In the PieChartView view, this dimension * is the font size. * * @param textSize The text dimension attribute value to use.(sp) */
public void setTextSize(float textSize) {
mTextSize = textSize;
invalidateTextPaintAndMeasurements();
}
/** * 设置饼状图要显示的数据 * * @param data 列表数据 */
public void setData(List<PieceDataHolder> data) {
if (data != null) {
pieceDataHolders.clear();
pieceDataHolders.addAll(data);
}
invalidate();
}
/** * 绘制扇形 * * @param canvas 画布 * @param color 要绘制扇形的颜色 * @param startAngle 起始角度 * @param sweepAngle 结束角度 */
protected void drawSector(Canvas canvas, int color, float startAngle, float sweepAngle) {
Paint paint = new Paint();
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
paint.setColor(color);
canvas.drawArc(pieChartCircleRectF, startAngle, sweepAngle, true, paint);
}
/** * 绘制标注线和标记文字 * * @param canvas 画布 * @param color 标记的颜色 * @param rotateAngel 标记线和水平相差旋转的角度 */
protected void drawMarkerLineAndText(Canvas canvas, int color, float rotateAngel, String text) {
Paint paint = new Paint();
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(color);
Path path = new Path();
path.close();
path.moveTo(getWidth() / 2, getHeight() / 2);
final float x = (float) (getWidth() / 2 + (markerLineLength + pieChartCircleRadius) * Math.cos(Math.toRadians(rotateAngel)));
final float y = (float) (getHeight() / 2 + (markerLineLength + pieChartCircleRadius) * Math.sin(Math.toRadians(rotateAngel)));
path.lineTo(x, y);
float landLineX;
if (270f > rotateAngel && rotateAngel > 90f) {
landLineX = x - 20;
} else {
landLineX = x + 20;
}
path.lineTo(landLineX, y);
canvas.drawPath(path, paint);
mTextPaint.setColor(color);
if (270f > rotateAngel && rotateAngel > 90f) {
float textWidth = mTextPaint.measureText(text);
canvas.drawText(text, landLineX - textWidth, y + mTextHeight / 2 - textBottom, mTextPaint);
} else {
canvas.drawText(text, landLineX, y + mTextHeight / 2 - textBottom, mTextPaint);
}
}
/** * 饼状图每块的信息持有者 */
public static final class PieceDataHolder {
/** * 每块扇形的值的大小 */
private float value;
/** * 扇形的颜色 */
private int color;
/** * 每块的标记 */
private String marker;
public PieceDataHolder(float value, int color, String marker) {
this.value = value;
this.color = color;
this.marker = marker;
}
}
}
attrs_pie_chart_view.xml
<resources>
<declare-styleable name="PieChartView">
<attr name="circleRadius" format="dimension" />
<attr name="textSize" format="dimension" />
<attr name="exampleDrawable" format="color|reference" />
</declare-styleable>
</resources>
边栏推荐
- leetcode 1268. Search Suggestions System(搜索推荐系统)
- pyQt 中 QMenu 响应
- 将mysql的数据库导出xxx.sql,将xxx.sql文件导入到服务器的mysql中。项目部署。
- Pat 1157: school anniversary
- ZUCC_编译语言原理与编译_实验04 语言与文法
- Tencent cloud ASR product PHP realizes real-time voice authentication request
- Cloudbase database migration scheme
- Tool functions – get all files in the project folder
- 2021-03-11 comp9021 class 8 notes
- Which is the first poem of Tang Dynasty?
猜你喜欢
![Fundamentals of 3D mathematics [17] inverse square theorem](/img/59/bef931d96883288766fc94e38e0ace.png)
Fundamentals of 3D mathematics [17] inverse square theorem

小黑ai4code代码baseline啃食1

RCNN、Fast-RCNN、Faster-RCNN介绍

Opencv实现图像的基本变换

New technology practice, encapsulating the permission application library step by step with the activity results API

OpenCV to realize the basic transformation of image

ZUCC_ Principles of compiling language and compilation_ Experiment 08 parsing LR parsing

新技术实战,一步步用Activity Results API封装权限申请库

2021-03-11 comp9021 class 8 notes

ZUCC_编译语言原理与编译_实验06 07 语法分析 LL 分析
随机推荐
MATLAB Camera Calibrator相机标定
IIS build wordpress5.7 manually
【微服务~Nacos】Nacos服务提供者和服务消费者
05-ubuntu安装mysql8
AUTO PWN
11-- longest substring without repeated characters
Paper notes: multi label learning dm2l
LabVIEW查找n个元素数组中的质数
ZUCC_编译语言原理与编译_实验01 语言分析与简介
Micro build low code online "quick registration applet" capability
2021-06-24: find the length of the longest non repeating character substring in a string.
Robot acceleration level task priority inverse kinematics
Live broadcast review | detailed explanation of koordinator architecture of cloud native hybrid system (complete ppt attached)
487. 最大连续1的个数 II ●●
根据网络上的视频的m3u8文件通过ffmpeg进行合成视频
ZUCC_ Principles of compiling language and compilation_ Experiment 08 parsing LR parsing
OpenCV to realize the basic transformation of image
12-- merge two ordered linked lists
os. path. Pits encountered during the use of join()
Question bank and simulation examination for operation certificate of refrigeration and air conditioning equipment in 2022