HarmonyOS鸿蒙Next中制作圆形环状百分比图表
HarmonyOS鸿蒙Next中制作圆形环状百分比图表
CustomPieChart({ unit: ‘%’, money: ‘’ })
当第四项’D’ 值为 0.00时 绘制的圆形效果不对,无法正确显示其他值的占比, 请问该如何修改?
CustomPieChart({
unit: '%',
money: ''
})
@Component
export struct CustomPieChart {
// 获取上下文
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
// 饼图数据
@Prop picChartElements: PicChartElement[] = [
new PicChartElement('A', 92.51),
new PicChartElement('B', 5.63),
new PicChartElement('C', 1.33),
new PicChartElement('D', 0.00),
new PicChartElement('E', 0.53)
]
// 圆半径
@State circle_radius: number = 60
// 单位
@State unit: string = ""
//总资产
@Prop money: string = ''
@Prop colors: string[] =
["#3c6ef5", "#76a0ff", "#79d4fe", "#926cfd", "#ae5dba", "#c67cd3", "#c43f5e", "#f4a994", "#fe6833", "#efd796"]
private picValueChanged() {
let t = 0
this.picChartElements.forEach((value) => {
t += value.quantity
})
let pa: PicChartElement[] = []
for (let i = 0; i < this.picChartElements.length; i++) {
pa.push(this.picChartElements[i])
pa.push(new PicChartElement('', t / 200))
}
let total = 0
pa.forEach((value) => {
total += value.quantity
})
// 初始化 弧线的终止弧度
let lastEndAngle = -0.5 * Math.PI
// 封装饼图数据
pa.forEach((value, index) => {
let percent = value.quantity / (total)
value.percent = percent
value.beginAngle = lastEndAngle
value.endAngle = (percent * 2 * Math.PI) + lastEndAngle
lastEndAngle = value.endAngle
if (index % 2 !== 0) {
value.color = '#00000000'
} else {
value.color = this.colors[index / 2]
}
//value.color = this.colors[index]
// 返回封装好的对象
return value
})
// this.context.reset()
pa.forEach((item) => {
// 创建一个新的控制路径
this.context.beginPath()
// 路径从当前点移动到指定点
this.context.moveTo(this.circle_radius, this.circle_radius)
// 绘制弧线路径(弧线圆心的x坐标值,弧线圆心的y坐标值,弧线的圆半径,弧线的起始弧度,弧线的终止弧度)
this.context.arc(this.circle_radius, this.circle_radius, this.circle_radius, item.beginAngle,
item.endAngle)
// 指定绘制的填充色
this.context.fillStyle = item.color
// 对封闭路径进行填充
this.context.fill()
})
}
aboutToAppear() {
// this.picValueChanged()
}
build() {
Row({ space: 10 }) {
Stack() {
Canvas(this.context)// 高度为半径2倍
.height('100%')// 纵横比,宽度和高度一样
.width('100%')// 画布组件的事件回调,可以在此时进行绘制
.onReady(() => {
this.picValueChanged()
})
Stack() {
Circle({ width: this.circle_radius * 2 - 15, height: this.circle_radius * 2 - 15 })
.stroke('#FFFFFF')
.fill('#FFFFFF')
Text(this.money + '\n总资产')
.textAlign(TextAlign.Center)
.maxLines(-1)
.width('100%')
.height('100%')
}
.width(this.circle_radius * 2 - 15)
.height(this.circle_radius * 2 - 15)
}
.width(this.circle_radius * 2)
.height(this.circle_radius * 2)
Blank()
.layoutWeight(1)
Column() {
ForEach(this.picChartElements, (item: PicChartElement) => {
Row({ space: 10 }) {
// 标注圆点颜色
Divider()
.vertical(true)
.height(10)
.strokeWidth(5)
.color(item.color)
Row() {
// 标注文本
Text(item.element).fontSize(12)
.textAlign(TextAlign.Start)
.layoutWeight(1)
// 标注数量
Text(item.quantity + this.unit).fontSize(12)
.textAlign(TextAlign.End)
}
.layoutWeight(1)
.justifyContent(FlexAlign.SpaceBetween)
}
.width('100%')
.height(30)
.alignItems(VerticalAlign.Center)
})
}
.width(130)
}
.width('100%')
.padding({ left: 20, right: 20 })
}
}
export class PicChartElement {
element: Resource | string // 显示文本
quantity: number // 数量
percent: number = 0 // 百分比
beginAngle: number = 0 // 弧线的起始弧度
endAngle: number = 0 // 弧线的终止弧度
color: string // 颜色
constructor(element: Resource | string, quantity: number, color: string = '') {
this.element = element
this.quantity = quantity
this.color = color
}
}
更多关于HarmonyOS鸿蒙Next中制作圆形环状百分比图表的实战教程也可以访问 https://www.itying.com/category-93-b0.html
pa push的时候没有过滤0的项
更多关于HarmonyOS鸿蒙Next中制作圆形环状百分比图表的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
包含0的值是必须要过滤的吗? 有的时候不用过滤0显示也是正确的,
在HarmonyOS鸿蒙Next中制作圆形环状百分比图表,可以使用Canvas组件进行绘制。通过Canvas的arc
方法,可以绘制圆形路径,并设置起始角度和结束角度以实现环状效果。使用lineWidth
属性调整环的宽度,strokeStyle
设置颜色。结合requestAnimationFrame
实现动态百分比变化。具体实现可参考鸿蒙开发文档中的Canvas API。
问题出在picValueChanged
方法中处理0值数据时的逻辑。当某项值为0时,当前代码仍会为它分配一个弧段,这会导致其他部分的占比计算错误。
建议修改picValueChanged
方法,在计算前先过滤掉0值的数据项:
private picValueChanged() {
// 过滤掉0值数据
const validElements = this.picChartElements.filter(item => item.quantity > 0);
let t = 0
validElements.forEach((value) => {
t += value.quantity
})
let pa: PicChartElement[] = []
for (let i = 0; i < validElements.length; i++) {
pa.push(validElements[i])
pa.push(new PicChartElement('', t / 200))
}
// 剩余逻辑保持不变...
}
这样修改后,当D项值为0时,它会被排除在计算之外,其他各项的占比就能正确显示了。同时记得更新ForEach循环中的数据源为过滤后的validElements
,以保证图例显示一致。
这个修改保持了原有环形图的效果,只是不再为0值项分配空间,更符合数据可视化的常规做法。