鸿蒙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 组件,用于显示图表。当 showUI 为 true 时,会显示一个垂直线、一个包含选中点数据的文本列、一个圆形游标和一个红色的点,以突出显示选中的数据点。
页面完整代码如下:
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图表自定义(六)在图表中绘制游标
在鸿蒙开发中,MPChart 是一个非常强大的图表库,它可以帮助我们创建各种精美的图表。今天,我们将继续探索鸿蒙MPChart的自定义功能,重点介绍如何在图表中绘制游标。 OpenHarmony三方库中心仓 一、效果演示 以下是效果演示图&…...
poi-tl+kkviewfile实现生成pdf业务报告
需求背景,需要把ai生成的一些业务数据,生成一份pdf报告 需求分析 简单来说,就是json生成pdf的方案。 直接生成pdf。适合一些pdf样式简单的场景,一般就是纯文本按序渲染,或者是纯表格。如果需要一些复杂的排布&#x…...
【Uniapp-Vue3】scroll-view可滚动视图区域组件
如果我们有一个区域有限的大盒子(黑),而我们要在盒子中装的东西(灰)过多,我们就会用到滚动视图: 表现在代码上就是下面这个样子: <template><view class"scrollView&…...
asp.net core webapi中的数据注解与数据验证
在这一课中,主要讲解了如何在 Web API 中使用数据注解(Data Annotations)和进行数据验证,以确保请求数据的有效性和完整性。 在 Web API 中,数据验证是确保客户端传递的数据符合业务规则和格式要求的关键步骤。数据注…...
PixPin—— 高效截图工具的下载与使用攻略
在日常的工作和学习中,一款好用的截图工具能极大地提高我们的效率。今天就来给大家介绍一款功能强大的截图工具 ——PixPin。 下载篇 PixPin 的下载非常简单,只需访问下载网站,在首页就能找到适合你操作系统的下载链接。如果你使用的是 Win…...
Go语言的 的多态性(Polymorphism)基础知识
Go语言的多态性(Polymorphism)基础知识 在编程语言中,多态性是一个核心概念,它允许同一接口被不同的数据类型所实现,从而在不影响代码结构的情况下增强代码的灵活性和可扩展性。在Go语言中,多态性通过接口…...
Vue框架主要用来做什么?Vue框架的好处和特性.
在快速发展的互联网时代,前端开发技术的变革日新月异,为开发者带来了前所未有的机遇与挑战。Vue.js,作为前端开发领域的一颗璀璨新星,以其轻量级、高效灵活的特性,赢得了广大开发者的青睐。本文将深入探讨Vue框架的主要…...
科普CMOS传感器的工作原理及特点
在当今数字化成像的时代,图像传感器无疑是幕后的关键 “功臣”,它宛如一位神奇的 “光影魔法师”,通过光电效应这一奇妙的物理现象,将光子巧妙地转换成电荷,为图像的诞生奠定基础。而在众多类型的图像传感器中…...
tensorflow 内存错误
使用tensorflow训练多个模型时,训练过程中容易出现内存错误,在这里记录一下解决办法。希望能帮到各位。 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 处理前: 处理后:...
计算机网络 (25)IPV6
前言 IPv6,全称为“互联网协议第6版”(Internet Protocol Version 6),是由互联网工程任务组(IETF)设计的用于替代IPv4的下一代IP协议。 一、产生背景 IPv4,即互联网协议第4版,是现行…...
小程序组件 —— 30 组件 - 背景图片的使用
在编写小程序的样式文件时,可以使用 background-image 属性来设置元素的背景图像;但是这个属性在微信小程序中使用时存在坑; 注意事项:微信小程序中的 background-iamge 不支持本地路径!需要使用网络图片,…...
《Opencv》信用卡信息识别项目
目录 一、项目介绍 二、数据材料介绍 1、模板图片(1张) 2、需要处理的信用卡图片(5张) 三、实现过程 1、导入需要用到的库 2、设置命令行参数 3、模板图像中数字的定位处理 4、信用卡图像处理 5、模板匹配 四、总结 一…...
Matlab贝叶斯估计MCMC分析药物对不同种群生物生理指标数据评估可视化
全文链接:https://tecdat.cn/?p38756 摘要:本文着重探讨了如何利用Matlab实现贝叶斯估计。阐述了具体的实现流程,涵盖数据加载、先验常数设定、马尔可夫链蒙特卡洛(MCMC)属性指定、模型构建、运行链条以及结果查看等环…...
java 转义 反斜杠 Unexpected internal error near index 1
代码: String str"a\\c"; //出现异常,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 攻击?如何防范? 答:DDoS 攻击是指利用大量的计算机或者其他网络设备,同时向目标网络或者服务器 发送 大量的数据流量,以致其无法正常工作,从而导致网络瘫痪或者服务器宕机的攻击行 为。 …...
在ubuntu22.04中使用bear命令追踪内核编译报错的原因分析和解决方案
1.说明 我在ubuntu22.04中使用bear命令追踪内核编译时发生如下报错: 如图,在链接名为libexec.so的动态库时发生错误 2 分析及解决过程 打印变量 LIB 发现其为空,也就是说 bear会去 /usr/bear/ 去找 libexec.so 去看一下 /usr/bear/是否存…...
【软考网工笔记】操作系统管理与配置——Windows
1-域名解析 Cache 域名解析 Cache 即 DNS 快取,DNS 快取需要应用客户机域名解析服务 DNSClient,其进程名为 svchost.exe -k NetworkService,可以输入命令:net stop dnscache 将其结束。原理是在 Windows 系统中,加入了…...
vue3 css实现文字输出带光标显示,文字输出完毕,光标消失的效果
Vue实现过程如下: <template><div ><p ref"dom_element" class"typing" :class"{over_fill: record_input_over}"></p></div> </template> <script setup> import {onMounted, ref} from…...
什么情况会导致JVM退出?
大家好,我是锋哥。今天分享关于【什么情况会导致JVM退出?】面试题。希望对大家有帮助; 什么情况会导致JVM退出? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 JVM(Java Virtual Machine)在不同情况下可能会退出&am…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...
