简介
随着移动应用的不断发展,数据可视化成为提高用户体验和数据交流的重要手段之一。在OpenAtom OpenHarmony(简称“OpenHarmony”)应用开发中,一个强大而灵活的图表库是实现这一目标的关键。
在ohpm中心仓中,汇聚了众多开发者贡献的图表库,其中之一就是MPChart。自其发布以来,MPChart已被广泛应用于各类应用程序,它为开发者提供了丰富的功能和灵活性,使得创建各种类型的图表变得轻而易举。
效果图
特性与优势
1.多样的图表类型:MPChart支持多种图表类型,从基本的折线图、柱状图、圆饼图、散点图到更复杂的蜡烛图、雷达图、瀑布图和组合图等,开发者可以根据项目需要选择最适合的图表类型。2.高度可定制:该库允许开发者通过代码自定义图表的外观和行为,从而实现个性化的设计,可以定制图表的颜色、字体、坐标轴样式等,以满足项目的UI需求。3.动画效果:MPChart内置了丰富的动画效果,使得图表的展示更加生动有趣。这不仅提升了用户体验,也使得数据的变化更加直观。
新版本使用说明
MPChart在2023年6月1日推出了首个正式版2.0.0,该版本主要利用Path和Shape组件实现了图表的绘制。而后,经过了多个版本的优化与迭代,在2024年1月8日,MPChart迎来重大更新,发布了采用Canvas组件绘制的重构版本3.0.0-rc.0,标志着MPChart库进入全新阶段。与先前版本相比,重构版本在细节处理和功能拓展上均进行了显著优化,同时要求SDK版本在API10以上。截至发稿前,MPChart重构版本还处于rc版本阶段。以下是MPChart重构版本新增和优化的一些功能:
1.图表支持按百分比设置宽高尺寸;且当图表尺寸调整时,能够自动重绘以适配新的大小,确保内容的准确展示。
BarChart({ model: this.model })
.width('100%')
.height('70%')
2.新增图表横向滚动功能,使得宽幅数据图表得以部分显示。用户仅需滑动屏幕便可逐步浏览全部信息。该功能不仅提升了信息的细节展示,还扩大了可视内容的范围。
3.新增了对自定义点击、长按、双击、拖拽等事件的支持。用户可以设置监听器监听这些交互,并且支持引入自定义组件以响应这些动作。
4.对组合图进行了扩展,新增设置瀑布图的支持。
5.对手势缩放以及双击缩放的交互进行了优化,提高了操作的流畅性。6.提供了更加简化的使用体验,使用时需要定义的代码量更少。这些改进使得MPChart更加易用且功能丰富,满足了用户对高效图表工具的需求。因代码重构,MPChart 2.7.0及以下版本(以下简称”2.7版本“)使用的方法和MPChart 3.0.0-rc.0及以上版本(以下检查”3.0版本”)略有不同,接下来分别介绍使用方法。
一、创建图表对象
首先需要创建一个model对象,用来承载图表数据。1)3.0版本
this.model = new LineChartModel();
2)2.7版本2.7版本需要在创建model对象并且传入数据后调用init方法进行初始化。
this.model = new LineChartModel();
//省略传入数据代码
model.init();
二、设置图表数据
1)3.0版本
// 创建一个 JArrayList 对象,用于存储 EntryOhos 类型的数据
let values: JArrayList<EntryOhos> = new JArrayList<EntryOhos>();
// 循环生成 1 到 20 的随机数据,并添加到 values 中
for (let i = 1; i <= 20; i++) {
values.add(new EntryOhos(i, Math.random() * 100));
}
// 创建 LineDataSet 对象,使用 values 数据,并设置数据集的名称为 'DataSet'
let dataSet = new LineDataSet(values, 'DataSet');
let dataSetList: JArrayList<ILineDataSet> = new JArrayList<ILineDataSet>();
dataSetList.add(dataSet);
// 创建 LineData 对象,使用 dataSetList数据,并将其传递给model
let lineData: LineData = new LineData(dataSetList);
this.model.setData(lineData);
使用JArrayList 存储 EntryOhos 类型的数据,然后通过 LineDataSet 和 LineData 对象来设置图表的数据集。最后,将数据传递给model。在2.7版本中,需要将最后一行的setData方法替换为setLineData方法,即this.model.setLineData(lineData)。
三、引入图表组件
在页面布局中引入LineChart组件,可通过属性设置图表的宽高,背景色等。1)3.0版本
LineChart({ model: this.model })
.width('100%')
.height('100%')
.backgroundColor(Color.White)
2)2.7版本2.7版本不支持通过组件.width和.height设置宽高属性,而是通过model的setWidth()和setHeight()方法设置宽高,并且不能设置百分比宽高,只能设置固定的数值宽高。
aboutToAppear() {
//...
this.model.setWidth(300);
this.model.setHeight(300);
this.model.init();
}
LineChart({ lineChartModel: $model })
通过以上三步即可创建一个基础的LineChart,效果图如下:
3.0版本的页面完整代码如下:
import {
JArrayList,EntryOhos,LineDataSet,ILineDataSet,LineData,LineChart,LineChartModel,
} from '@ohos/mpchart';
@Entry
@Component
struct Index {
private model: LineChartModel = new LineChartModel();
aboutToAppear() {
// 创建一个 JArrayList 对象,用于存储 EntryOhos 类型的数据
let values: JArrayList<EntryOhos> = new JArrayList<EntryOhos>();
// 循环生成 1 到 20 的随机数据,并添加到 values 中
for (let i = 1; i <= 20; i++) {
values.add(new EntryOhos(i, Math.random() * 100));
}
// 创建 LineDataSet 对象,使用 values 数据,并设置数据集的名称为 'DataSet'
let dataSet = new LineDataSet(values, 'DataSet');
let dataSetList: JArrayList<ILineDataSet> = new JArrayList<ILineDataSet>();
dataSetList.add(dataSet);
// 创建 LineData 对象,使用 dataSetList数据,并将其传递给model
let lineData: LineData = new LineData(dataSetList);
this.model?.setData(lineData);
}
build() {
Column() {
LineChart({ model: this.model })
.width('100%')
.height('100%')
.backgroundColor(Color.White)
}
}
}
2.7版本的页面完整代码如下:
import {
LineChart,LineChartModel,XAxis,XAxisPosition,YAxis,
AxisDependency,YAxisLabelPosition,LineData,LineDataSet,EntryOhos,JArrayList,ILineDataSet
} from '@ohos/mpchart'
@Entry
@Component
struct Basic {
topAxis: XAxis = new XAxis(); //顶部X轴
bottomAxis: XAxis = new XAxis(); //底部X轴
mWidth: number = 350; //表的宽度
mHeight: number = 300; //表的高度
leftAxis: YAxis | null = null;
rightAxis: YAxis | null = null;
lineData: LineData | null = null;
@State
lineChartModel: LineChartModel = new LineChartModel();
titleSelcetString: string = 'X'
public aboutToAppear() {
this.lineData = this.initCurveData(30, 180);
this.topAxis.setLabelCount(4, false);
this.topAxis.setPosition(XAxisPosition.TOP);
this.topAxis.setAxisMinimum(11);
this.topAxis.setAxisMaximum(44);
this.bottomAxis.setLabelCount(4, false);
this.bottomAxis.setPosition(XAxisPosition.BOTTOM);
this.bottomAxis.setAxisMinimum(11);
this.bottomAxis.setAxisMaximum(44);
this.leftAxis = new YAxis(AxisDependency.LEFT);
this.leftAxis.setLabelCount(10, false);
this.leftAxis.setPosition(YAxisLabelPosition.OUTSIDE_CHART);
this.leftAxis.setAxisMinimum(10);
this.leftAxis.setAxisMaximum(200);
this.rightAxis = new YAxis(AxisDependency.RIGHT);
this.rightAxis.setDrawGridLines(false);
this.rightAxis.setLabelCount(10, false);
this.rightAxis.setAxisMinimum(10); // this replaces setStartAtZero(true)
this.rightAxis.setAxisMaximum(200);
this.leftAxis.setDrawLimitLinesBehindData(true);
this.lineChartModel.setTopAxis(this.topAxis);
this.lineChartModel.setBottomAxis(this.bottomAxis);
this.lineChartModel.setWidth(this.mWidth);
this.lineChartModel.setHeight(this.mHeight);
if (this.leftAxis) {
this.lineChartModel.setLeftAxis(this.leftAxis);
}
if (this.rightAxis) {
this.lineChartModel.setRightAxis(this.rightAxis);
}
if (this.lineData) {
this.lineChartModel.setLineData(this.lineData);
}
this.lineChartModel.init();
}
/**
* 初始化数据
* @param count 曲线图点的个数
* @param range y轴范围
*/
private initCurveData(count: number, range: number): LineData {
let values = new JArrayList<EntryOhos>();
for (let i = 0; i < count; i++) {
let val: number = Math.random() * range;
values.add(new EntryOhos(i, val));
}
let dataSet = new JArrayList<ILineDataSet>();
let set1 = new LineDataSet(values, "DataSet 1");
dataSet.add(set1);
return new LineData(dataSet)
}
build() {
Column() {
Stack({ alignContent: Alignment.TopStart }) {
LineChart({ lineChartModel: $lineChartModel })
}
}
}
}
除了基本设置之外,我们还可以进行图表的其他个性化设置,接下来介绍图表的个性化设置。
四、个性化设置
1、XY轴的绘制1)3.0版本3.0版本中可以通过如下代码获取到x轴/y轴对象。
//获取x轴
let xAxis = model.getXAxis();
//获取左y轴
let leftAxis = model.getAxisLeft();
//获取右y轴
let rightAxis = model.getAxisRight();
2)2.7版本2.7版本可以通过如下代码设置x轴/y轴对象。
//x轴
let topAxis = new XAxis();
//...省略设置属性方法
topAxis.setPosition(XAxisPosition.TOP);
//左y轴
let leftAxis = new YAxis(AxisDependency.LEFT);
//...省略设置属性方法
this.lineChartModel.setLeftAxis(leftAxis);
//右y轴
let rightAxis = new YAxis(AxisDependency.RIGHT);
//...省略设置属性方法
this.lineChartModel.setRightAxis(rightAxis);
获取x轴和左右y轴对象之后,可以调用以下方法设置它们的属性,在3.0版本和2.7版本中都可使用。
x轴/y轴都可设置:
●setEnabled(enabled: boolean):设置轴是否被绘制。默认绘制,设置为false则不会被绘制。●setDrawLabels(enabled: boolean):设置为true绘制轴的标签。
●setDrawAxisLine(enabled: boolean): 设置为true绘制轴线。
●setDrawGridLines(enabled: boolean): 设置为true绘制网格线。
●setTextColor(color: string | number | CanvasGradient | CanvasPattern): 设置轴标签文本颜色。●setTextSize(size: number):设置轴标签的字体大小。setTypeface(tf: FontFamily):设置轴标签的FontFamily,指定字体系列,支持如下几种类型:‘sans-serif’, ‘serif’, ‘monospace’。
●setGridColor(color: number): 设置网格线颜色。
●setGridLineWidth(width: number):设置网格线宽度。
●setAxisLineColor(color: number):设置此轴的坐标轴的颜色。
●setAxisLineWidth(width: number): 设置此轴的坐标轴的宽度。
●enableGridDashedLine(lineLength: number, spaceLength: number, phase: number): 显示网格线虚线模式,"lineLength"控制短线条的长度,"spaceLength"控制两段线之间的间隔长度,"phase"控制开始的点。●setAxisMaxValue(max: number):设置一个自定义的最大值,如果设置了数值,这个值将不会依赖于提供的数据自动计算。
●setAxisMinValue(min: number): 设置一个自定义的最小值。如果设置了数值,这个值将不会依赖于提供的数据进行自动计算。
x轴专属设置:
●setAvoidFirstLastClipping(enabled: boolean):如果设置为true,图表将避免在图表或屏幕的边缘的标签条目被裁剪掉。
●setPosition(pos: XAxisPosition):设置XAxis应该出现的位置。可以选择TOP,BOTTOM,BOTH_SIDED,TOP_INSIDE或者BOTTOM_INSIDE。
y轴专属设置:
●setInverted(enabled: boolean): 如果设置为true,这个轴将被反向,那意味着最大值将被放到底部,最小值将被放到顶部。
●setSpaceTop(percent: number):设置在图表上最高处的值相比轴上最高值的顶端空间(占总轴范围的百分比)。
●setSpaceBottom(percent: number): 设置在图表上最低处的值相比轴上最低处值的底部空间(总轴范围的百分比)。
●setPosition(pos: YAxisLabelPosition):设置轴标签应该被绘制的位置。INSIDE_CHART或者OUTSIDE_CHART中的一个。
2、图表交互设置图表model对象可调用以下方法进行图表交互个性化设置:
●setTouchEnabled( enabled: boolean): 允许打开或者关闭与图表的所有触摸交互的情况。●setDragEnabled( enabled: boolean): 打开或关闭对图表的拖动。
●setScaleEnabled(enabled: boolean):打开或关闭对图表所有轴的的缩放。
●setScaleXEnabled(enabled: boolean): 打开或关闭x轴的缩放●setScaleYEnabled(enabled: boolean): 打开或关闭y轴的缩放。
●setPinchZoom(enabled: boolean): 如果设置为true,手势捏合缩放被打开。如果设置为false,x和y轴可以被手势捏合缩放。
●setHighlightPerTapEnabled(enabled: boolean): 如果设置为true,在图表中选中触发高亮效果。●setHighlightPerDragEnabled(enabled: boolean): 设置为true时允许在手指滑动结束时显示高亮效果。默认:true
●setHighlightIndicatorEnabled(enabled: boolean): 如果设置为true, 选中数据时,将展示指标线。
●此方法为dataset设置:setVisibleXRangeMaximum(maxXRange:number):设置x轴最多显示数据条数,(要在设置数据源后调用,否则是无效的)
3、颜色设置
1)数据集颜色设置针对某个数据集,可以使用 dataSet.setColor(color:number) 方法来设置其颜色。例如,在折线图中:
this.dataSet.setColorByColor(Color.Blue); //设置折线的颜色为蓝色
2)渐变颜色设置对于一些图表元素,可以使用渐变颜色。可以通过 dataSet.setGradientFillColor() 方法来实现。这通常用于折线图的填充色效果。
let gradientFillColor = new JArrayList<ChartColorStop>();
gradientFillColor.add(["#0C0099CC", 0.2]);
gradientFillColor.add(["#7F0099CC", 0.4]);
gradientFillColor.add(["#0099CC", 1.0]);
this.dataSet.setGradientFillColor(gradientFillColor);
3)多种颜色设置如果想为数据点设置不同的颜色,可以通过设置dataSet.setColorsByVariable(colors: number[]) 方法,传入一个颜色列表。
dataSet.setColorsByVariable([
ColorTemplate.colorRgb(192, 255, 140),
ColorTemplate.colorRgb(255, 247, 140),
ColorTemplate.colorRgb(255, 208, 140)]);
4、自定义坐标轴标签如果不想用坐标轴本身的阿拉伯数字标签,也可以自定义坐标轴标签,实现方法是通过创建自定义类实现IAxisValueFormatter接口,修改其中的getFormattedValue方法,最后调用坐标轴对象的setValueFormatter方法就可以实现自定义坐标轴标签,3.0和2.7版本代码相同,如下所示:
class MyAxisValueFormatter implements IAxisValueFormatter {
getFormattedValue(value: number, axis: AxisBase): string {
let mmdd = new Date().toDateString().split(' ')
let day = Number(mmdd[2]) + value / 20
let hours = new Date().getHours() + value / 20
console.log('lz getFormattedValue value:' + value)
return day + ' ' + mmdd[1] + ' ' + hours
}
}
...
this.topAxis.setValueFormatter(new TopAxisValueFormatter())
实现效果如图所示:
五、MPChart常见问题
1 . 如何隐藏Y轴线
this.model.getAxisLeft().setEnabled(false) //隐藏左边Y轴轴线,此时标签数字也隐藏
如果想隐藏轴线但是想显示数字标签:
this.model.getAxisRight().setDrawAxisLine(false);
2 . 如何控制Y轴线数据标签个数
this.model.getAxisLeft().setLabelCount(8, false);//设置了8个
3 . 如何设置轴线颜色,宽度等信息
let leftAxis = this.model.getAxisLeft();
leftAxis.setPosition(YAxisLabelPosition.OUTSIDE_CHART);//显示轴线在图表内部则使用INSIDE_CHART
this.leftAxis.setAxisLineColor(ColorTemplate.rgb("#ff0000"));//设置轴线颜色
leftAxis.setAxisLineWidth(1);// 设置轴线宽度
leftAxis.setTextSize(20);//设置y轴标签字体大小
leftAxis.setDrawGridLines(true);//设置显示网格线
写在最后
●如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
●点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
●关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
●更多鸿蒙最新技术知识点,请移步前往小编:https://gitee.com/