鸿蒙Next数据量环形图标Gauge介绍

当我们需要环形展示数据进度,但是又不想使用一个完整的圆环时,Progress组件就不能满足我们的需求,例如汽车的速度表盘,这时我们就需要用引入Gauge组件,他可以满足环形进度展示的同时,设置起始角度,达到不封闭环形的数据展示。

看一下简单的实现效果

使用介绍:

1.Gauge使用时必须设置Gauge(options:{value: number, min?: number, max?: number}),其中,最小值默认0,最大值默认100

2.Gauge支持包含一个子组件,子组件的内容区为圆环外圆相切的矩形,如同大正方形区域,可以绘制表盘刻度,指针实现汽车表盘功能。

3.可以通过设置startAngle、endAngle,改变初始值角度

4.description设置内容区,如同小矩形区域,可以根据需求填充内容

5.背景色分段渐变环最大显示段数为9段

源码:

scss 复制代码
@Entry
@ComponentV2
struct GaugeTest {
  @Local value: number = 10 //当前数据值
  @Local min: number = 0 //当前数据段最小值
  @Local max: number = 200 //当前数据段最大值
  @Local startAngle: number = 0 //起始角度位置
  @Local endAngle: number = 360 //终止角度位置
  @Local strokeWidth: number = 4 //环形厚度
  @Local colors: ResourceColor | LinearGradient | Array<[ResourceColor | LinearGradient, number]> = '#a5d61d'
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
  @Local centerX:number=0
  @Local centerY:number=0
  @Builder
  descriptionBuilder() {
    Stack() {
      Text('内容区')
    }
    .width('100%')
    .height("100%")
    .border({ width: 1 })
  }

  build() {
    Column({ space: 10 }) {
      Gauge({ value: this.value, min: this.min, max: this.max })
      {
        Stack(){
          Text('可以放一个子组件,子组件内容区黑色边框内').width('30%')
          Canvas(this.context)
            .width('100%')
            .height('100%')
            .onReady(() => {
              this.context.strokeStyle = '#0000ff';
              this.context.lineWidth = 2;
              this.context.moveTo(this.centerX, this.centerY);
              this.context.lineTo(this.centerX, this.strokeWidth);
              this.context.stroke();
          })
            .rotate({ centerX:this.centerX,centerY:this.centerY,angle:this.cacleAngle() })
            .animation({duration:300,iterations:1})
        }
        .onSizeChange((oldValue: SizeOptions, newValue: SizeOptions) => {
            this.centerX=(newValue.width as number)/2
            this.centerY=(newValue.height as number)/2-this.strokeWidth
        })
        .width('100%')
        .height("100%")
        .border({ width: 1 })
      }
        .width(300)
        .height(300)
        .startAngle(this.startAngle)
        .endAngle(this.endAngle)
        .colors(this.colors)
        .strokeWidth(this.strokeWidth)
        .description(this.descriptionBuilder)
        .indicator({  //指针样式
          icon:$r('app.media.svg_triangle')

        })
      Column(){
        Text('定制Gauge内容区')
        Gauge({ value: this.value, min: this.min, max: this.max })
          .contentModifier(new MyGaugeStyle())
      }
      Row({ space: 10 }) {
        Column() {
          Text("最小值")
          Counter() {
            Text(this.min.toString())
          }
          .onInc(() => {
            this.min += 10;
          })
          .onDec(() => {
            this.min -= 10;
          })
        }
        Column() {
          Text("当前值")
          Counter() {
            Text(this.value.toString())
          }
          .onInc(() => {
            if (this.value<this.max) {
              this.value+=10
            }
          })
          .onDec(() => {
            if (this.value > this.min) {
              this.value-= 10;
            }
          })
        }
        Column() {
          Text("最大值")
          Counter() {
            Text(this.max.toString())
          }
          .onInc(() => {
            this.max += 10;
          })
          .onDec(() => {
            this.max -= 10;
          })
        }
      }
      Row({ space: 10 }) {
        Column() {
          Text("起始角度")
          Counter() {
            Text(this.startAngle.toString())
          }
          .onInc(() => {
            this.startAngle+= 10
          })
          .onDec(() => {
            if (this.startAngle > 0) {
              this.startAngle-= 10;
            }
          })
        }
        Column() {
          Text("终止角度")
          Counter() {
            Text(this.endAngle.toString())
          }
          .onInc(() => {
            this.endAngle += 10;
          })
          .onDec(() => {
            this.endAngle -= 10;
          })
        }
        Column() {
          Text("环形厚度")
          Counter() {
            Text(this.strokeWidth.toString())
          }
          .onInc(() => {
            this.strokeWidth ++;
          })
          .onDec(() => {
            if (this.strokeWidth > 0) {
              this.strokeWidth--;
            }
          })
        }
      }

      Row({ space: 10 }){
        Button('纯色').onClick(()=>{
          this.colors = '#a5d61d'
        })
        Button('单渐变').onClick(()=>{
        this.colors=new LinearGradient([{ color: "#dbefa5", offset: 0 }, { color: "#a5d61d", offset: 1 }])
        })
        Button('分段渐变').onClick(()=>{
          this.colors=[            [new LinearGradient([{ color: "#dbefa5", offset: 0 }, { color: "#a5d61d", offset: 1 }]), 5],
            [new LinearGradient([{ color: "#fceb99", offset: 0 }, { color: "#f7ce00", offset: 1 }]), 3],
            [new LinearGradient([{ color: "#f8c5a6", offset: 0 }, { color: "#ed6f21", offset: 1 }]), 2]
            ]
        })
      }
    }
    .width('100%')
    .alignItems(HorizontalAlign.Center)
  }

  cacleAngle():number{
   let offsetAngle = Math.abs((360-this.startAngle)-(360-this.endAngle))
    if (offsetAngle==360) {
      offsetAngle=0
    }

    return (this.value*(360-offsetAngle)/this.max)+this.startAngle
  }
}
@Builder
function buildGauge(config: GaugeConfiguration) {
  Column() {
    Progress({ value: config.value, total: config.max, type: ProgressType.Linear  })
      .color("#a5d61d")
      .width(200)
  }
  .width("100%")
  .padding(10)
  .alignItems(HorizontalAlign.Center)
}
class MyGaugeStyle implements ContentModifier<GaugeConfiguration> {

  constructor() {
  }

  applyContent(): WrappedBuilder<[GaugeConfiguration]> {
    return wrapBuilder(buildGauge)
  }
}
相关推荐
别说我什么都不会6 分钟前
【OpenHarmony】 鸿蒙网络请求库之ohos_ntp
网络协议·harmonyos
很萌很帅的恶魔神ww1 小时前
HarmonyOS Next 之-组件之弹窗
harmonyos
很萌很帅的恶魔神ww1 小时前
HarmonyOS Next 底部 Tab 栏组件开发实战
harmonyos
云_杰1 小时前
HarmonyOS ——Telephony Kit(蜂窝通信服务)教程
harmonyos
很萌很帅的恶魔神ww1 小时前
HarmonyOS Next 之轮播图开发指南(Swiper组件)
harmonyos
别说我什么都不会2 小时前
【OpenHarmony】 鸿蒙网络请求库之eventsource
harmonyos
颜颜颜yan_4 小时前
【HarmonyOS5】掌握UIAbility启动模式:Singleton、Specified、Multiton
后端·架构·harmonyos
二蛋和他的大花6 小时前
HarmonyOS运动开发:深度解析文件预览的正确姿势
华为·harmonyos
长弓三石6 小时前
鸿蒙网络编程系列53-仓颉版TCP连接超时分析示例
前端·harmonyos
libo_20257 小时前
DevEco Studio测试用例录制功能详解(HarmonyOS 5)
harmonyos