flutterpiechart_flutter 做一个带线指示的饼状图_weixin_39531834的博客-程序员宅基地

技术标签: flutterpiechart  

是一个饼状图,但是不适用,因为数据比较多的时候显示就很密集,所以要用线,添加了一些,不过目前文字大小还没怎么计算,所以是写固定的

整个代码如下

import 'package:flutter/material.dart';

import 'piechart.dart';

import 'PieData.dart';

import 'dart:math';

class View extends CustomPainter{

//中间文字

var text='111';

bool isChange=false;

//当前选中的扇形

var currentSelect=0;

//画笔

Paint _mPaint;

Paint TextPaint;

// 扇形大小

int mWidth, mHeight;

// 圆半径

num mRadius, mInnerRadius,mBigRadius;

// 扇形起始弧度(Andorid中是角度)

num mStartAngle = 0;

// 矩形(扇形绘制的区域)

Rect mOval,mBigOval;

// 扇形 数据

List mData;

PieData pieData;

// 构造函数,接受需要的参数值

View(this.mData,this.pieData,this.currentSelect,this.isChange);

/**

* 重写 paint方法,在其中写绘制饼状图的逻辑

*/

@override

void paint(Canvas canvas, Size size) {

// 初始化各类工具等

_mPaint = new Paint();

TextPaint = new Paint();

mHeight=100;mWidth=100;

/// 生成纵轴文字的TextPainter

TextPainter textPainter = TextPainter(

textDirection: TextDirection.ltr,

maxLines: 1,

);

// 文字画笔 风格定义

TextPainter _newVerticalAxisTextPainter(String text) {

return textPainter

..text = TextSpan(

text: text,

style: new TextStyle(

color: Colors.black,

fontSize: 10.0,

),

);

}

// 正常半径

mRadius = 50.0;

//加大半径 用来绘制被选中的扇形区域

mBigRadius=55.0;

//內园半径

mInnerRadius = mRadius * 0.50;

// 未选中的扇形绘制的矩形区域

mOval = Rect.fromLTRB(-mRadius, -mRadius, mRadius, mRadius);

// 选中的扇形绘制的矩形区域

mBigOval = Rect.fromLTRB(-mBigRadius, -mBigRadius, mBigRadius,

mBigRadius);

//当没有数据时 直接返回

if (mData.length == null || mData.length <= 0) {

return;

}

///绘制逻辑与Android差不多

canvas.save();

// 将坐标点移动到View的中心

canvas.translate(50.0, 50.0);

// 1. 画扇形

num startAngle = 0.0;

bool draw=false;

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

PieData p = mData[i];

double hudu=p.percentage;

//计算当前偏移量(单位为弧度)

double sweepAngle = 2*pi*hudu;

// print(sweepAngle);

//画笔的颜色

_mPaint..color = p.color;

if(currentSelect>=0 && i==currentSelect){

//如果当前为所选中的扇形 则将其半径加大 突出显示

canvas.drawArc(mBigOval, startAngle, sweepAngle, true, _mPaint);

Paint _paint=new Paint();

_paint.color=Color(0xff91c954);

_paint.strokeWidth=1.0;

Offset offset=Offset(mRadius*0.75*cos(startAngle+sweepAngle/2.0),mRadius*0.75*sin(startAngle+sweepAngle/2.0));

// print(mRadius*0.75*sin(2*pi*270.0/360.0));

// print(mRadius*0.75*cos(2*pi*270.0/360.0));

// if(!draw){print(offset);

//print(mRadius*0.75*sin(2*pi*270.0/360.0));

// print(mRadius*0.75*cos(2*pi*270.0/360.0));

TextPainter t=TextPainter(text: TextSpan(text: "11%",style: TextStyle(color: Colors.black),),textDirection: TextDirection.ltr,

maxLines: 1,);

canvas.drawLine(offset, Offset(mRadius*1.25*cos(startAngle+sweepAngle/2.0),mRadius*1.25*sin(startAngle+sweepAngle/2.0)), _paint);

if(mRadius*0.75*cos(startAngle+sweepAngle/2.0)<0){

Offset offset1=new Offset(mRadius*1.25*cos(startAngle+sweepAngle/2.0)-mRadius*0.2, mRadius*1.25*sin(startAngle+sweepAngle/2.0));

canvas.drawLine(Offset(mRadius*1.25*cos(startAngle+sweepAngle/2.0),mRadius*1.25*sin(startAngle+sweepAngle/2.0)), offset1, _paint);

// canvas.restore();

t.layout();

t.paint(canvas, Offset(mRadius*1.25*cos(startAngle+sweepAngle/2.0)-mRadius*0.2-20.0, mRadius*1.25*sin(startAngle+sweepAngle/2.0)-10.0));

}else{

Offset offset1=new Offset(mRadius*1.25*cos(startAngle+sweepAngle/2.0)+mRadius*0.2, mRadius*1.25*sin(startAngle+sweepAngle/2.0));

canvas.drawLine(Offset(mRadius*1.25*cos(startAngle+sweepAngle/2.0),mRadius*1.25*sin(startAngle+sweepAngle/2.0)), offset1, _paint);

// canvas.restore();

t.layout();

t.paint(canvas, Offset(mRadius*1.25*cos(startAngle+sweepAngle/2.0)-mRadius*0.2+20.0, mRadius*1.25*sin(startAngle+sweepAngle/2.0)-10.0));

}

// draw=true;

// }

}else{

// 绘制没被选中的扇形 正常半径

canvas.drawArc(mOval, startAngle, sweepAngle, true, _mPaint);

Offset origin=Offset((-mRadius+mRadius)/2.0, (-mRadius+mRadius)/2.0);

Paint _paint=new Paint();

_paint.color=Color(0xff91c954);

_paint.strokeWidth=1.0;

Offset offset=Offset( mRadius*0.75*cos(startAngle+sweepAngle/2.0),mRadius*0.75*sin(startAngle+sweepAngle/2.0));

canvas.drawLine(offset, Offset(mRadius*1.25*cos(startAngle+sweepAngle/2.0),mRadius*1.25*sin(startAngle+sweepAngle/2.0)), _paint);

TextPainter t=TextPainter(text: TextSpan(text: "11%",style: TextStyle(color: Colors.black),),textDirection: TextDirection.ltr,

maxLines: 1,);

if(mRadius*0.75*cos(startAngle+sweepAngle/2.0)<0){

Offset offset1=new Offset(mRadius*1.25*cos(startAngle+sweepAngle/2.0)-mRadius*0.2, mRadius*1.25*sin(startAngle+sweepAngle/2.0));

canvas.drawLine(Offset(mRadius*1.25*cos(startAngle+sweepAngle/2.0),mRadius*1.25*sin(startAngle+sweepAngle/2.0)), offset1, _paint);

// canvas.restore();

t.layout();

t.paint(canvas, Offset(mRadius*1.25*cos(startAngle+sweepAngle/2.0)-mRadius*0.2-25.0, mRadius*1.25*sin(startAngle+sweepAngle/2.0)-10.0));

}else{

Offset offset1=new Offset(mRadius*1.25*cos(startAngle+sweepAngle/2.0)+mRadius*0.2, mRadius*1.25*sin(startAngle+sweepAngle/2.0));

canvas.drawLine(Offset(mRadius*1.25*cos(startAngle+sweepAngle/2.0),mRadius*1.25*sin(startAngle+sweepAngle/2.0)), offset1, _paint);

// canvas.restore();

t.layout();

t.paint(canvas, Offset(mRadius*1.25*cos(startAngle+sweepAngle/2.0)-mRadius*0.2+20.0, mRadius*1.25*sin(startAngle+sweepAngle/2.0)-10.0));

}

// draw=true;

// }

}

//计算每次开始绘制的弧度

startAngle += sweepAngle ;

// print(startAngle);

}

// canvas.drawRect(mOval, _mPaint); // 矩形区域

// 2.画内圆

_mPaint..color = Colors.white;

canvas.drawCircle(Offset.zero, mInnerRadius, _mPaint);

canvas.restore();

//当前百分比值

double percentage = pieData.percentage*100;

// 绘制文字内容

var texts ='${percentage}%';

var tp = _newVerticalAxisTextPainter(texts)..layout();

// Text的绘制起始点 = 可用宽度 - 文字宽度 - 左边距

var textLeft = 35.0;

tp.paint(canvas, Offset(textLeft, 50.0 - tp.height / 2));

}

@override

bool shouldRepaint(CustomPainter oldDelegate) {

return true;

}

}

绘制text之前,一定要调用layout这个函数,这个跟安卓很像

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_39531834/article/details/114995229

智能推荐

java动态规划算法_南风知易✓✓✓的博客-程序员宅基地

java 动态规划算法递归算法的时间复杂度=递归的次数递归函数本身的时间复杂度*

典型电路的收集与记录__Jason^_^的博客-程序员宅基地

5V to 3V3通过AMS1117-3.3,将电压降至3V3,钽电容是必须的。蜂鸣器电路通过ss8050的NPN三极管实现对蜂鸣器的控制LED电路通过限流电阻对LED的电流和亮度进行控制。但每种颜色所配合的电阻还需实验,达到LED能亮同时又不晃眼睛的效果。...

Spinner的两种调用数据放式_faith_boys的博客-程序员宅基地

ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, mLmtdReptStr);adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);mSpinner.setAd

ROS arbotix踩坑:‘rospkg‘、except UnicodeDecodeError, exc、dynamic module does not define init function_#君君#的博客-程序员宅基地_ros 安装rospkg

在执行roslaunch mbot_description arbotix_mbot_with_camera_xacro.launch文件时,即包含arbotix模块的程序时,报错No module named ‘rospkg’ 。报错No module named 'rospkg'经过对大家文章的查看,发现基本集中在把环境配置为python3.或者安装rospkg。但是仍没有解决。查看opt/ros/melodic/lib/python2.7/dist-packages,发现根本没有ro.

面试题:实现数组扁平化_weixin_34056162的博客-程序员宅基地

什么是数组扁平化数组扁平化是指将一个多维数组变为一维数组reduce 方法实现reduce 本身就是一个迭代循环器,通常用于累加,所以根据这一特点有以下:const arr1 = [1,[4,6],[8,3,[19,38]]]function flatten(arr) { return arr.reduce((result, item)=&gt; { return re...

JfreeChart用法总结_shiyan0634的博客-程序员宅基地

一、简介 WW 的发展使得基于因特网的应用程序不再局限于静态或者简单的动态内容提供。传统的一些以软件包形式发布应用程序例如报表系统等都在逐渐搬到因特网上。但是这两者之间有着天壤之别,虽然对于数据获取、业务处理等方面基本类似,但是最大的差别在于用户界面。为了能在web浏览器上显示要求用户界面使用 HTML以及图片的方式来展现数据,而传统的一些利用操作系统本身的控件来开发的用户界面无法适应琳琅满目

随便推点

Vscode的使用小技巧_weixin_30399821的博客-程序员宅基地

命令行启动code如果你的系统是Linux系统(我使用的是Ubuntu 16.04)这样就可以直接使用 code + filename来编辑文件(就像vi + filename)如果你的系统是MacOS 就需要在vscode里面按 command + shift + p 之后输入 shell 基本上在第一提示里面就会显示安装code,如图所示转载于:https://www.cnblo...

SpringMVC -> 转发(forward)和重定向(redirect)_欧皇小德子的博客-程序员宅基地_springmvc转发的关键字是redirect

默认写法就是转发:return的字符串将对应的前端页面转发到要求的url上配置了视图解析器的viewsresolver @RequestMapping("/hello/{a}/{b}") public String hello(@PathVariable int a, @PathVariable int b, Model model) { model.addAttribute("haha", "结果:" + (a + b)); return "hello"; }没有视图解析器

ros kinetic 自带opencv3 与 opencv 2 的兼容问题_原野寻踪的博客-程序员宅基地

问题分析自己写的系统必须基于opencv 2.x,而ros kinetic自带了opencv3的版本。于是在编译时报错:/usr/bin/ld: CMakeFiles/xxxx.cpp.o: undefined reference to symbol '_ZN2cv6String10deallocateEv'/opt/ros/kinetic/lib/x86_64-linux-gnu/l...

Latex002 | 详细教程:LaTeX 编译器哪个好?——如何在 Visual Studio Code 中全流程编写 LaTeX(上篇)_爱学习的Allan的博客-程序员宅基地_latex编译器

你是否在编写 LaTeX 过程中遇到了编译器“不给力”,无法自动补全、缩进等问题?本文比较了流行的 LaTeX 的编译器,并简要分析了其优势与不足,最终给出解决方案。

16 Java数组--数组的定义、声明和创建_一起加油(ง •̀_•́)ง的博客-程序员宅基地

数组的定义数组是相同类型数据的有序集合数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们。数组的声明首先必须声明数组变量,才能在程序中使用数组dataType[] arrayRefVar; //首选声明方法或dataType arrayRefVar[];Java语言使用new操作符来创建数组dataType[] arrayRefVar = new dataType[arraySize];