当前位置:网站首页>饼状统计图,带有标注线,都可以自行设定其多种参数选项
饼状统计图,带有标注线,都可以自行设定其多种参数选项
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>
边栏推荐
- After interviewing and tutoring several children, I found some problems!
- 5 minutes, excellent customer service chat handling skills
- JS merge multiple objects and remove duplicates
- Markdown to realize text link jump
- pyQt 常用系统的事件
- LabVIEW查找n个元素数组中的质数
- The article takes you to understand the security of Windows operating system and protect your computer from infringement
- orb slam build bug: undefined reference to symbol ‘_ZN5boost6system15system_categoryEv‘
- 单目双视三维坐标确定
- The JS macro of WPS implements the separation method of picture text in the same paragraph
猜你喜欢

Markdown to realize text link jump

Opencv实现图像的基本变换

李白最经典的20首诗排行榜

jwt(json web token)

2021-03-11 comp9021 class 8 notes

The article takes you to understand the security of Windows operating system and protect your computer from infringement

Maya re deployment

问题4 — DatePicker日期选择器,2个日期选择器(开始、结束日期)的禁用

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

A preliminary study of IO model
随机推荐
一文带你了解Windows操作系统安全,保护自己的电脑不受侵害
App Startup
ZUCC_ Principles of compiling language and compilation_ Experiment 02 fsharp Ocaml language
IIS build wordpress5.7 manually
pyQt 常用系统的事件
【毕业季】你好陌生人,这是一封粉色信笺
JUC个人简单笔记
[xinliu-s6 new model +sa 3-star Xinghai] the new two-way server of the third generation chip was launched and the product was updated~
Introduction to RCNN, fast RCNN and fast RCNN
jwt(json web token)
问题3 — messageBox弹框,修改默认背景色
Two methods of QT exporting PDF files
ZUCC_ Principles of compiling language and compilation_ Experiment 01 language analysis and introduction
Robot acceleration level task priority inverse kinematics
论文笔记: 多标签学习 DM2L
小黑ai4code代码baseline啃食1
Longhorn installation and use
487. number of maximum consecutive 1 II ●●
Building a static website with eleventy
js滚动div滚动条到底部