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

鸿蒙MPChart图表自定义(六)在图表中绘制游标

在鸿蒙开发中,MPChart 是一个非常强大的图表库,它可以帮助我们创建各种精美的图表。今天,我们将继续探索鸿蒙MPChart的自定义功能,重点介绍如何在图表中绘制游标。

OpenHarmony三方库中心仓

一、效果演示

以下是效果演示图,从动图可以看出,这是一个渐变蓝色的曲线图表,通过手指在图表上点击或者长按住滑动,可以在图表顶部展示出数据点的基本信息。这个效果也比较简单,只需要通过自定义UI就可以轻松实现。

二、绘制游标的步骤

在鸿蒙MPChart中,绘制游标可以通过以下步骤实现:

1. 页面组件定义

@Entry
@Component
struct LongPressSlideCursorPage {

这里定义了一个名为 LongPressSlideCursorPage 的页面组件,使用了 @Entry@Component 装饰器,表示这是一个可以独立运行的页面组件。

2. 状态变量定义

@State private lineChartModel: LineChartModel = new LineChartModel();
@State positionX: number = 0;
@State positionY: number = 0;
@State cursorPositionX: number = 0;
@State cursorPositionY: number = 0;
@State dataX: number = 0;
@State dataY: number = 0;
@State showUI: boolean = false;
@State uiWidth: number = 0;
cursorSize: number = 100;

这些是页面的状态变量,用于存储图表模型、选中点的位置信息、游标位置信息、选中点的数据信息、是否显示UI、UI的宽度和游标的大小。

3. 数据选择监听器

@State private valueSelectedListener: OnChartValueSelectedListener = {onValueSelected: (e: EntryOhos, h: Highlight) => {this.showUI = true;this.dataX = Number(e.getX().toFixed(1));this.dataY = Number(e.getY().toFixed(1));let x = this.lineChartModel.getTransformer(AxisDependency.LEFT)?.getPixelForValues(e.getX(), e.getY()).x ?? 0;let y = this.lineChartModel.getTransformer(AxisDependency.LEFT)?.getPixelForValues(e.getX(), e.getY()).y ?? 0;this.positionX = x;this.positionY = y;if (x > this.uiWidth - this.cursorSize / 2 - 10) {x = this.uiWidth - this.cursorSize / 2 - 10;} else if (x < this.cursorSize / 2 + 10) {x = this.cursorSize / 2 + 10;}this.cursorPositionX = x;},onNothingSelected: () => {this.showUI = false;}
}

这是一个数据选择监听器,用于处理图表上的数据选中事件。当用户选中一个数据点时,会显示一个UI来显示选中点的详细信息。同时,会计算并设置游标的位置。

4. 数据初始化

aboutToAppear() {this.uiWidth = px2vp(display.getDefaultDisplaySync().width);let values: JArrayList<EntryOhos> = new JArrayList<EntryOhos>();for (let i = 1; i <= 30; i++) {values.add(new EntryOhos(i, Math.random() * 100));}let lineDataSet = new LineDataSet(values, 'DataSet');lineDataSet.setMode(Mode.CUBIC_BEZIER);lineDataSet.setDrawCircles(false);let lineDataSetList: JArrayList<ILineDataSet> = new JArrayList<ILineDataSet>();//渐变色填充let gradientFillColor = new JArrayList<ChartColorStop>();gradientFillColor.add(["#0099CC", 0.2]);gradientFillColor.add(["#7F0099CC", 0.4]);gradientFillColor.add(["#ffffff", 1.0]);lineDataSet.setGradientFillColor(gradientFillColor);lineDataSet.setDrawFilled(true);//不显示数值lineDataSet.setDrawValues(false);//设置线条颜色lineDataSet.setColorByColor(0x0099cc);//设置不显示指示线lineDataSet.setDrawHighlightIndicators(false);lineDataSetList.add(lineDataSet);let lineData: LineData = new LineData(lineDataSetList);this.lineChartModel?.setData(lineData);this.lineChartModel.setOnChartValueSelectedListener(this.valueSelectedListener);this.lineChartModel.setHighlightPerLongPressEnabled(false);this.lineChartModel.setVisibleXRangeMaximum(10);this.lineChartModel.setSwipeEnabled(true);//设置长按出游标 和 触发长按的时长this.lineChartModel.setLongPressCursorEnabled(true);this.lineChartModel.setLongPressDuration(160);}

在页面即将显示时,这段代码会初始化图表的数据。它创建了一个包含随机数据的 LineDataSet,设置了数据集的样式,如渐变填充颜色、不显示数据点等。然后将数据集添加到 LineData 对象中,并将其设置到图表模型中。同时,设置了图表的一些属性,如最大显示X轴范围、是否允许滑动、长按持续时间等。

5. 页面构建

build() {Stack() {LineChart({ model: this.lineChartModel }).width('100%').height('50%').backgroundColor(Color.White).margin({ top: 100 })if (this.showUI) {Line().startPoint([0, 0]).endPoint([0, this.lineChartModel.getContentRect().height()+ 100]).stroke(Color.Yellow).strokeWidth(4).position({ x: this.positionX }).opacity(0.5)Column() {Text(`x = ${this.dataX.toFixed(1).toString()}`).fontSize(20).fontWeight(FontWeight.Bolder)Text(`y = ${this.dataY.toString()}`).fontSize(20).fontWeight(FontWeight.Bolder)}.alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center).backgroundColor('#F2F2F2').position({ x: this.cursorPositionX - this.cursorSize / 2 }).width(this.cursorSize).aspectRatio(1).borderRadius(5)Circle({ width: 14, height: 14 }).position({ x: this.positionX - 7, y: this.positionY + 100 - 7}).fill(Color.White)Circle({ width: 10, height: 10 }).position({ x: this.positionX - 5, y: this.positionY + 100 - 5}).fill(Color.Red)}}
}

这段代码构建了页面的布局。首先是一个 LineChart 组件,用于显示图表。当 showUItrue 时,会显示一个垂直线、一个包含选中点数据的文本列、一个圆形游标和一个红色的点,以突出显示选中的数据点。

页面完整代码如下:

import {JArrayList,EntryOhos,ILineDataSet,LineData,LineChart,LineChartModel,Mode,LineDataSet,XAxisPosition,OnChartValueSelectedListener,Highlight,AxisDependency,ChartColorStop,
} from '@ohos/mpchart';
import display from '@ohos.display';/** CursorPage组件 */
@Entry
@Component
struct LongPressSlideCursorPage {/** LineChart 图表配置构建类 */@State private lineChartModel: LineChartModel = new LineChartModel();/** 选中点位置信息 */@State positionX: number = 0;@State positionY: number = 0;/**游标位置信息*/@State cursorPositionX: number = 0;@State cursorPositionY: number = 0;/** 选中点X轴数据信息*/@State dataX: number = 0;/** 选中点Y轴数据信息 */@State dataY: number = 0;/** 是否展示UI */@State showUI: boolean = false;/** UI宽度 */@State uiWidth: number = 0;/** UI高度 */@State uiHeight: number = 0;/**游标宽高**/cursorSize: number = 100;/** 数据选择监听 */private valueSelectedListener: OnChartValueSelectedListener = {onValueSelected: (e: EntryOhos, h: Highlight) => {/** 数据选中时显示气泡UI */this.showUI = true;/** 设置选中点的位置信息和数据信息 */this.dataX = Number(e.getX().toFixed(1));this.dataY = Number(e.getY().toFixed(1));let x = this.lineChartModel.getTransformer(AxisDependency.LEFT)?.getPixelForValues(e.getX(), e.getY()).x ?? 0;let y = this.lineChartModel.getTransformer(AxisDependency.LEFT)?.getPixelForValues(e.getX(), e.getY()).y ?? 0;this.positionX = x;this.positionY = y;if (x > this.uiWidth - this.cursorSize / 2 - 10) {x = this.uiWidth - this.cursorSize / 2 - 10;} else if (x < this.cursorSize / 2 + 10) {x = this.cursorSize / 2 + 10}this.cursorPositionX = x;},onNothingSelected: () => {/** 去除气泡UI */this.showUI = false;}}/** 数据初始化 */aboutToAppear() {this.uiWidth = px2vp(display.getDefaultDisplaySync().width);/** 创建一个 JArrayList 对象,用于存储 EntryOhos 类型的数据 */let values: JArrayList<EntryOhos> = new JArrayList<EntryOhos>();/** 循环生成 1 到 20 的随机数据,并添加到 values 中 */for (let i = 1; i <= 30; i++) {values.add(new EntryOhos(i, Math.random() * 100));}/** 创建 LineDataSet 对象,使用 values 数据,并设置数据集的名称为 'DataSet' */let lineDataSet = new LineDataSet(values, 'DataSet');lineDataSet.setMode(Mode.CUBIC_BEZIER);lineDataSet.setDrawCircles(false);let lineDataSetList: JArrayList<ILineDataSet> = new JArrayList<ILineDataSet>();//渐变色填充let gradientFillColor = new JArrayList<ChartColorStop>();gradientFillColor.add(["#0099CC", 0.2]);gradientFillColor.add(["#7F0099CC", 0.4]);gradientFillColor.add(["#ffffff", 1.0]);lineDataSet.setGradientFillColor(gradientFillColor);lineDataSet.setDrawFilled(true);lineDataSet.setDrawValues(false);lineDataSet.setColorByColor(0x0099cc);lineDataSet.setDrawHighlightIndicators(false);lineDataSetList.add(lineDataSet);/** 创建 LineData 对象,使用 lineDataSetList 数据,并将其传递给 lineChartModel */let lineData: LineData = new LineData(lineDataSetList);this.lineChartModel?.setData(lineData);this.lineChartModel.setOnChartValueSelectedListener(this.valueSelectedListener);this.lineChartModel.setHighlightPerLongPressEnabled(false);this.lineChartModel.setVisibleXRangeMaximum(10);this.lineChartModel.setSwipeEnabled(true);this.lineChartModel.setLongPressDuration(160);this.lineChartModel.setLongPressCursorEnabled(true);}build() {Stack() {LineChart({ model: this.lineChartModel }).width('100%').height('50%').backgroundColor(Color.White).margin({ top: 100 })if (this.showUI) {Line().startPoint([0, 0]).endPoint([0, this.lineChartModel.getContentRect().height()+ 100]).stroke(Color.Yellow).strokeWidth(4).position({ x: this.positionX }).opacity(0.5)Column() {Text(`x = ${this.dataX.toFixed(1).toString()}`).fontSize(20).fontWeight(FontWeight.Bolder)Text(`y = ${this.dataY.toString()}`).fontSize(20).fontWeight(FontWeight.Bolder)}.alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center).backgroundColor('#F2F2F2').position({ x: this.cursorPositionX - this.cursorSize / 2 }).width(this.cursorSize).aspectRatio(1).borderRadius(5)Circle({ width: 14, height: 14 }).position({ x: this.positionX - 7, y: this.positionY + 100 - 7}).fill(Color.White)Circle({ width: 10, height: 10 }).position({ x: this.positionX - 5, y: this.positionY + 100 - 5}).fill(Color.Red)}}}
}

三、总结

这段代码通过定义状态变量、数据选择监听器、数据初始化和页面构建,实现了在鸿蒙应用中绘制带有游标的折线图。用户可以通过长按图表来选中数据点,并显示相关的详细信息。这种交互方式提高了图表的可用性和用户体验。希望这篇文章能帮助你在鸿蒙开发中更好地使用MPChart图表库。

有疑问或者感兴趣的朋友,可以加QQ群沟通交流:274130009

相关文章:

鸿蒙MPChart图表自定义(六)在图表中绘制游标

在鸿蒙开发中&#xff0c;MPChart 是一个非常强大的图表库&#xff0c;它可以帮助我们创建各种精美的图表。今天&#xff0c;我们将继续探索鸿蒙MPChart的自定义功能&#xff0c;重点介绍如何在图表中绘制游标。 OpenHarmony三方库中心仓 一、效果演示 以下是效果演示图&…...

poi-tl+kkviewfile实现生成pdf业务报告

需求背景&#xff0c;需要把ai生成的一些业务数据&#xff0c;生成一份pdf报告 需求分析 简单来说&#xff0c;就是json生成pdf的方案。 直接生成pdf。适合一些pdf样式简单的场景&#xff0c;一般就是纯文本按序渲染&#xff0c;或者是纯表格。如果需要一些复杂的排布&#x…...

【Uniapp-Vue3】scroll-view可滚动视图区域组件

如果我们有一个区域有限的大盒子&#xff08;黑&#xff09;&#xff0c;而我们要在盒子中装的东西&#xff08;灰&#xff09;过多&#xff0c;我们就会用到滚动视图&#xff1a; 表现在代码上就是下面这个样子&#xff1a; <template><view class"scrollView&…...

asp.net core webapi中的数据注解与数据验证

在这一课中&#xff0c;主要讲解了如何在 Web API 中使用数据注解&#xff08;Data Annotations&#xff09;和进行数据验证&#xff0c;以确保请求数据的有效性和完整性。 在 Web API 中&#xff0c;数据验证是确保客户端传递的数据符合业务规则和格式要求的关键步骤。数据注…...

PixPin—— 高效截图工具的下载与使用攻略

在日常的工作和学习中&#xff0c;一款好用的截图工具能极大地提高我们的效率。今天就来给大家介绍一款功能强大的截图工具 ——PixPin。 下载篇 PixPin 的下载非常简单&#xff0c;只需访问下载网站&#xff0c;在首页就能找到适合你操作系统的下载链接。如果你使用的是 Win…...

Go语言的 的多态性(Polymorphism)基础知识

Go语言的多态性&#xff08;Polymorphism&#xff09;基础知识 在编程语言中&#xff0c;多态性是一个核心概念&#xff0c;它允许同一接口被不同的数据类型所实现&#xff0c;从而在不影响代码结构的情况下增强代码的灵活性和可扩展性。在Go语言中&#xff0c;多态性通过接口…...

Vue框架主要用来做什么?Vue框架的好处和特性.

在快速发展的互联网时代&#xff0c;前端开发技术的变革日新月异&#xff0c;为开发者带来了前所未有的机遇与挑战。Vue.js&#xff0c;作为前端开发领域的一颗璀璨新星&#xff0c;以其轻量级、高效灵活的特性&#xff0c;赢得了广大开发者的青睐。本文将深入探讨Vue框架的主要…...

科普CMOS传感器的工作原理及特点

在当今数字化成像的时代&#xff0c;图像传感器无疑是幕后的关键 “功臣”&#xff0c;它宛如一位神奇的 “光影魔法师”&#xff0c;通过光电效应这一奇妙的物理现象&#xff0c;将光子巧妙地转换成电荷&#xff0c;为图像的诞生奠定基础。而在众多类型的图像传感器中&#xf…...

tensorflow 内存错误

使用tensorflow训练多个模型时&#xff0c;训练过程中容易出现内存错误&#xff0c;在这里记录一下解决办法。希望能帮到各位。 2025-01-02 22:31:03.489713: W tensorflow/core/common_runtime/bfc_allocator.cc:275] Allocator (GPU_0_bfc) ran out of memory trying to all…...

spring boot解决swagger中的v2/api-docs泄露漏洞

在配置文件中添加以下配置 #解决/v2/api-docs泄露漏洞 springfox:documentation:swagger-ui:enabled: falseauto-startup: false 处理前&#xff1a; 处理后&#xff1a;...

计算机网络 (25)IPV6

前言 IPv6&#xff0c;全称为“互联网协议第6版”&#xff08;Internet Protocol Version 6&#xff09;&#xff0c;是由互联网工程任务组&#xff08;IETF&#xff09;设计的用于替代IPv4的下一代IP协议。 一、产生背景 IPv4&#xff0c;即互联网协议第4版&#xff0c;是现行…...

小程序组件 —— 30 组件 - 背景图片的使用

在编写小程序的样式文件时&#xff0c;可以使用 background-image 属性来设置元素的背景图像&#xff1b;但是这个属性在微信小程序中使用时存在坑&#xff1b; 注意事项&#xff1a;微信小程序中的 background-iamge 不支持本地路径&#xff01;需要使用网络图片&#xff0c;…...

《Opencv》信用卡信息识别项目

目录 一、项目介绍 二、数据材料介绍 1、模板图片&#xff08;1张&#xff09; 2、需要处理的信用卡图片&#xff08;5张&#xff09; 三、实现过程 1、导入需要用到的库 2、设置命令行参数 3、模板图像中数字的定位处理 4、信用卡图像处理 5、模板匹配 四、总结 一…...

Matlab贝叶斯估计MCMC分析药物对不同种群生物生理指标数据评估可视化

全文链接&#xff1a;https://tecdat.cn/?p38756 摘要&#xff1a;本文着重探讨了如何利用Matlab实现贝叶斯估计。阐述了具体的实现流程&#xff0c;涵盖数据加载、先验常数设定、马尔可夫链蒙特卡洛&#xff08;MCMC&#xff09;属性指定、模型构建、运行链条以及结果查看等环…...

java 转义 反斜杠 Unexpected internal error near index 1

代码&#xff1a; String str"a\\c"; //出现异常&#xff0c;Unexpected internal error near index 1 //System.out.println(str.replaceAll("\\", "c"));//以下三种都正确 System.out.println(str.replace(\\, c)); System.out.println(str.r…...

网络安全常见的问题

1. 什么是 DDoS 攻击&#xff1f;如何防范&#xff1f; 答&#xff1a;DDoS 攻击是指利用大量的计算机或者其他网络设备&#xff0c;同时向目标网络或者服务器 发送 大量的数据流量&#xff0c;以致其无法正常工作&#xff0c;从而导致网络瘫痪或者服务器宕机的攻击行 为。 …...

在ubuntu22.04中使用bear命令追踪内核编译报错的原因分析和解决方案

1.说明 我在ubuntu22.04中使用bear命令追踪内核编译时发生如下报错&#xff1a; 如图&#xff0c;在链接名为libexec.so的动态库时发生错误 2 分析及解决过程 打印变量 LIB 发现其为空&#xff0c;也就是说 bear会去 /usr/bear/ 去找 libexec.so 去看一下 /usr/bear/是否存…...

【软考网工笔记】操作系统管理与配置——Windows

1-域名解析 Cache 域名解析 Cache 即 DNS 快取&#xff0c;DNS 快取需要应用客户机域名解析服务 DNSClient&#xff0c;其进程名为 svchost.exe -k NetworkService&#xff0c;可以输入命令&#xff1a;net stop dnscache 将其结束。原理是在 Windows 系统中&#xff0c;加入了…...

vue3 css实现文字输出带光标显示,文字输出完毕,光标消失的效果

Vue实现过程如下&#xff1a; <template><div ><p ref"dom_element" class"typing" :class"{over_fill: record_input_over}"></p></div> </template> <script setup> import {onMounted, ref} from…...

什么情况会导致JVM退出?

大家好&#xff0c;我是锋哥。今天分享关于【什么情况会导致JVM退出?】面试题。希望对大家有帮助&#xff1b; 什么情况会导致JVM退出? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 JVM&#xff08;Java Virtual Machine&#xff09;在不同情况下可能会退出&am…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积

1.题目介绍 给定一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O…...

stm32wle5 lpuart DMA数据不接收

配置波特率9600时&#xff0c;需要使用外部低速晶振...

面试高频问题

文章目录 &#x1f680; 消息队列核心技术揭秘&#xff1a;从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"&#xff1f;性能背后的秘密1.1 顺序写入与零拷贝&#xff1a;性能的双引擎1.2 分区并行&#xff1a;数据的"八车道高速公路"1.3 页缓存与批量处理…...