当前位置: 首页 > news >正文

flutter 雷达图

通过CustomPainter自定义雷达图

效果如下

 主要代码

import 'package:flutter/material.dart';
import 'dart:math';
import 'dash_painter.dart';
import 'model/charts_model.dart';class RadarChart extends StatelessWidget {final List<ChartModel> list;final double maxValue;final Color radarColor;final Color dataColor;const RadarChart({super.key,required this.list,this.maxValue = 100,this.radarColor = Colors.grey,this.dataColor = Colors.green,});@overrideWidget build(BuildContext context) {return CustomPaint(painter: RadarChartPainter(list: list,maxValue: maxValue,radarColor: radarColor,dataColor: dataColor,numLayers: 4,),);}
}class RadarChartPainter extends CustomPainter {final int numLayers;final List<ChartModel> list;final double maxValue;final Color radarColor;final Color dataColor;List<Offset> startList = []; //存放第一层的点List<Offset> endList = []; //存放最外层的点List<Offset> textOffsetList = [];final int _offsetDy = 20;final int _offsetDx = 5;RadarChartPainter({required this.numLayers,required this.list,required this.maxValue,required this.radarColor,required this.dataColor,});@overridevoid paint(Canvas canvas, Size size) {final center = Offset(size.width / 2, size.height / 2);final radius = size.width / 2;final dataPoints = <Offset>[];final radarPaint = Paint()..color = radarColor..style = PaintingStyle.stroke;final bgPaint = Paint()..color = const Color(0xFFCAD0E8).withOpacity(.4)..style = PaintingStyle.fill;//画背景颜色for (var layer = 1; layer <= numLayers; layer++) {if (layer == 3) {final layerRadius = radius * (layer / numLayers);final radarPath = Path();for (var i = 0; i < 6; i++) {//每一层的6个点final angle = (2 * pi / 6) * i - (pi / 2);final x = center.dx + layerRadius * cos(angle);final y = center.dy + layerRadius * sin(angle);final point = Offset(x, y);if (i == 0) {radarPath.moveTo(point.dx, point.dy);} else {radarPath.lineTo(point.dx, point.dy);}}radarPath.close();canvas.drawPath(radarPath, bgPaint);}}//连接每一层的6个点和文字for (var layer = 1; layer <= numLayers; layer++) {final layerRadius = radius * (layer / numLayers);final radarPath = Path();for (var i = 0; i < 6; i++) {final angle = (2 * pi / 6) * i - (pi / 2);final x = center.dx + layerRadius * cos(angle);final y = center.dy + layerRadius * sin(angle);final point = Offset(x, y);if (i == 0) {radarPath.moveTo(point.dx, point.dy);} else {radarPath.lineTo(point.dx, point.dy);}//保存第一层的点if (layer == 1) {startList.add(point);}//保存最外层的点,用于后面画第一层的最外层点的连线if (layer == 4) {endList.add(point);//画label文字const textStyle = TextStyle(fontSize: 12, fontWeight: FontWeight.bold, color: Color(0XFF999999));final textSpan = TextSpan(text: list[i].label, style: textStyle);final textPainter = TextPainter(text: textSpan,textDirection: TextDirection.ltr,);textPainter.layout();double w = textPainter.width;Offset off = const Offset(0, 0);if (i == 0) {off = Offset(point.dx - w * 0.5, point.dy - _offsetDy);} else if (i == 1 || i == 2) {off = Offset(point.dx + _offsetDx, point.dy);} else if (i == 4 || i == 5) {off = Offset(point.dx - _offsetDx - w, point.dy);} else if (i == 3) {off = Offset(point.dx - w * 0.5, point.dy);}textPainter.paint(canvas, off);}}radarPath.close();const DashPainter(span: 3, step: 3).paint(canvas, radarPath, radarPaint);}//画第一层的点到最外层的点的连线for (var i = 0; i < 6; i++) {final path = Path();path.moveTo(startList[i].dx, startList[i].dy);path.lineTo(endList[i].dx, endList[i].dy);const DashPainter(span: 4, step: 9).paint(canvas, path, radarPaint);}//画数据区域final dataPaint = Paint()..color = dataColor..style = PaintingStyle.stroke..strokeWidth = 2.0;final dataFillPaint = Paint()..color = dataColor.withOpacity(.3)..style = PaintingStyle.fill..strokeWidth = 2.0;final dataPath = Path();for (var i = 0; i < 6; i++) {final angle = (2 * pi / 6) * i - (pi / 2);final value = list[i].y;final normalizedValue = value / maxValue;final dataRadius = radius * 0.75 * normalizedValue + radius * 0.25;final x = center.dx + dataRadius * cos(angle);final y = center.dy + dataRadius * sin(angle);final point = Offset(x, y);if (i == 0) {dataPath.moveTo(point.dx, point.dy);} else {dataPath.lineTo(point.dx, point.dy);}dataPoints.add(point);}dataPath.close();canvas.drawPath(dataPath, dataFillPaint);canvas.drawPath(dataPath, dataPaint);final dataPointPaint = Paint()..color = dataColor;for (var point in dataPoints) {canvas.drawCircle(point, 4.0, dataPointPaint);}}@overridebool shouldRepaint(covariant CustomPainter oldDelegate) {return true;}
}

项目地址 : flutter_radar: flutter 雷达图

相关文章:

flutter 雷达图

通过CustomPainter自定义雷达图 效果如下 主要代码 import package:flutter/material.dart; import dart:math; import dash_painter.dart; import model/charts_model.dart;class RadarChart extends StatelessWidget {final List<ChartModel> list;final double maxV…...

机器学习之损失函数(Loss Function)

损失函数&#xff08;Loss Function&#xff09;是机器学习和深度学习中的关键概念&#xff0c;它用于衡量模型的预测与实际目标之间的差异或误差。损失函数的选择对于模型的训练和性能评估至关重要&#xff0c;不同的任务和问题通常需要不同的损失函数。 以下是一些常见的损失…...

创邻科技张晨:图数据库,激活数据要素的新基建

“数据经济时代&#xff0c;数据要素产业链的各细分领域均蕴含机遇&#xff0c;图技术作为网络协同和数据智能的底层发动机&#xff0c;将深度掘金数字中国价值潜能”。 8月22日&#xff0c;在2023中国&#xff08;南京&#xff09;国际软件产品和信息服务交易博览会的信息技术…...

使用端口映射实现Spring Boot服务端接口的公网远程调试:详细配置与步骤解析

文章目录 前言1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 windows系统2.1.2 linux系统 2.2 创建隧道映射本地端口2.3 测试公网地址 3. 固定公网地址3.1 保留一个二级子域名3.2 配置二级子域名3.2 测试使用固定公网地址…...

stm32之点亮LED

今天&#xff0c;记录一下stm32如何点亮一个LED,程序本身十分简单&#xff0c;但主要是学习编程的格式。 led.h #ifndef _led_H #define _led_H#include "system.h"/* LED时钟端口、引脚定义 */ #define LED1_PORT GPIOB #define LED1_PIN GPIO_Pin_5 #d…...

SA8000认证的难点及注意事项

SA8000认证是什么&#xff1f; SA8000即“社会责任标准”&#xff0c;是Social Accountability 8000的英文简称&#xff0c;由社会责任国际组织(SAI)制定与执行&#xff0c;是全球首个道德规范国际标准。自1997年问世以来&#xff0c;它创建了一个衡量社会责任的共同语言&#…...

Java可视化物联网智慧工地SaaS平台源码:人脸识别考勤

基于微服务JavaSpring Cloud Vue UniApp MySql实现的智慧工地云平台源码 智慧工地是指利用云计算、大数据、物联网、移动互联网、人工智能等技术手段&#xff0c;为建筑施工现场提供智能硬件及物联网平台的解决方案&#xff0c;以实现建筑工地的实时化、可视化、多元化、智慧化…...

告别数字化系统“物理叠加”,华为云推动智慧门店价值跃迁

文|智能相对论 作者|叶远风 有大屏幕滚动播放广告&#xff1b; 有人脸识别系统让消费者自助结账&#xff1b; 有订单管理系统综合分析一段时间内总体经营情况&#xff1b; 有全门店监控直连总部机房&#xff1b; …… 以搭载数字化系统的硬件设备为表面特征的智慧门店&a…...

k8s 常用命令(四)

12、删除pod中的nginx服务及service [rootmaster ~]# kubectl delete deployment nginx -n kube-public [rootmaster ~]# kubectl delete svc -n kube-public nginx-service 13、查看endpoint的信息 [rootmaster ~]# kubectl get endpoints 14、修改/更新&#xff08;镜像、…...

大语言模型的分布式训练

什么是大语言模型 大语言模型(Large Language Model,缩写LLM),也称大型语言模型,是一种人工智能模型,旨在理解和生成人类语言。它们在大量的文本数据上进行训练,可以执行广泛的任务,包括文本总结、翻译、情感分析等等。LLM的特点是规模庞大,包含数十亿的参数,帮助它们学习语言…...

【JavaEE】Spring全家桶实现AOP-统一处理

【JavaEE】AOP&#xff08;2&#xff09; 文章目录 【JavaEE】AOP&#xff08;2&#xff09;1. 统一登录校验处理1.1 自定义拦截器1.2 将自定义拦截器加入到系统配置1.3 测试1.4 对于静态资源的处理1.5 小练习&#xff1a;统一登录拦截处理1.6 拦截器原理1.6.1 执行流程1.6.2 源…...

HQL解决连续三天登陆问题

1.背景 统计连续登录天数超过3天的用户&#xff0c;输出信息包括&#xff1a;用户id&#xff0c;登录天数&#xff0c;起始时间&#xff0c;结束时间&#xff1b; 2.准备数据 -- 建表 create table if not exists user_login_3days(user_id STRING,login_date date );--插入…...

(一)Docker简介(一篇足以)

一、简介 一个项目环境配置相当麻烦&#xff0c;如果换一台机器跑起来&#xff0c;所有配置就要重来一次&#xff0c;费力费时。很多人想到&#xff0c;能不能从根本上解决问题&#xff0c;软件可以带环境安装&#xff1f;也就是说&#xff0c;安装的时候&#xff0c;把原始环…...

RK3568 安卓源码编译

一.repo安卓编译工具 项目模块化/组件化之后各模块也作为独立的 Git 仓库从主项目里剥离了出去&#xff0c;各模块各自管理自己的版本。Android源码引用了很多开源项目&#xff0c;每一个子项目都是一个Git仓库&#xff0c;每个Git仓库都有很多分支版本&#xff0c;为了方便统…...

第4篇:vscode+platformio搭建esp32 arduino开发环境

第1篇:Arduino与ESP32开发板的安装方法 第2篇:ESP32 helloword第一个程序示范点亮板载LED 第3篇:vscode搭建esp32 arduino开发环境 1.配置默认安装路径&#xff0c;安装到D盘。 打开环境变量&#xff0c;点击新建 输入变量名PLATFORMIO_CORE_DIR与路径&#xff1a;D:\PLATF…...

2023前端面试笔记 —— CSS3

系列文章目录 内容链接2023前端面试笔记HTML52023前端面试笔记CSS3 文章目录 系列文章目录前言一、CSS选择器的优先级二、通过 CSS 的哪些方式可以实现隐藏页面上的元素三、px、em、rem之间有什么区别&#xff1f;四、让元素水平居中的方法有哪些五、在 CSS 中有哪些定位方式六…...

iOS 如何对整张图分别局部磨砂,并完全贴合

官方磨砂方式 - (UIVisualEffectView *)effectView{if(!_effectView){UIBlurEffect *blur [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];_effectView [[UIVisualEffectView alloc] initWithEffect:blur];}return _effectView; }使用这种方式对一张图的上半部分和…...

Packet_Tracer的使用

一、实验目的&#xff1a; 通过该实验了解Packet Tracer的使用方法&#xff0c;能够用Packet Tracer建立和模拟网络模型。 二、主要任务&#xff1a; 1.熟悉PT的界面&#xff0c;了解按键用途。 2.尝试自己建立一个小型网络&#xff0c;并测试连通性。 3.学习P…...

WPF如果未定义绑定的属性,程序如何处理

问题&#xff1a;wpf中&#xff0c;<Button IsEnabled"{Binding IsValid1}"></Button>&#xff0c;如果没定义绑定的属性IsValid1&#xff0c;可以正常用吗 解答&#xff1a;在 WPF 中&#xff0c;如果没有定义绑定的属性 IsValid1&#xff0c;会导致绑…...

韩国留学生生活之-租房篇,柯桥韩语培训留学韩语需要学到什么程度

对于计划在韩国留学的人来说&#xff0c;找到合适的租房是一个重要而且有挑战性的任务。 留学生遇到的常见租房类型为月付型、全税房。月付型就是我们常见的租房方式&#xff0c;一般都需要支付一个月或数个月月租的押金&#xff0c;按时间付房租即可&#xff0c;租期通常为一…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...