HarmonyOS Next 有遮盖的折线图

最近在学习鸿蒙App开发,刚好学到画折线图这部分,也有一些第三方库,功能确实很强大,基本都满足一般的需要。本着学习的态度,弄清楚原理,就手动做了demo,以备记录。好了,废话少说,直接上代码。

`@Entry @Component export struct TestChartPage { private settings: RenderingContextSettings = new RenderingContextSettings(true) private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) private readonly POINT_COLOR = '#ff0000' private readonly POINT_RADIUS = 4 @State points:number\[\]\[\]= \[\] aboutToAppear(): void {

ini 复制代码
let randomArray:number[][]= []
const count = 7
const maxWidth = 350
const offset = maxWidth / (count - 1)

for (let i = 0;i < count;i++){
  let x = offset * i
  if (x == 0) {
    x = 10
  }
  let y = Math.floor(Math.random() * 300) + 1;
  randomArray.push([x,y])
}

this.points = randomArray

}

// 绘制数据点 点的位置不是很准确,有待优化。 private drawDataPoints() { this.points.forEach(point => { this.context.beginPath() this.context.arc(point0, point1, this.POINT_RADIUS, 0, Math.PI * 2) this.context.fillStyle = this.POINT_COLOR this.context.fill() }) }

build() { Column() { Canvas(this.context) .backgroundColor(Color.Orange) .width('100%') .height(400) .onReady(() => { this.context.strokeStyle = '#0078ff'; this.context.lineWidth = 2;

ini 复制代码
      this.context.beginPath();
      this.context.moveTo(this.points[0][0], this.points[0][1]);

      for (let i = 0; i < this.points.length - 1; i++) {
        const p0 = this.points[i];
        const p1 = this.points[i + 1];
        const t0 = this.points[i];
        const t1 = this.points[i + 1];
        const k = 1/3;

        const x1 = p0[0] + t0[0] * k;
        const y1 = p0[1] + t0[1] * k;

        const x2 = p1[0] - t1[0] * k;
        const y2 = p1[1] - t1[1] * k;

        this.context.bezierCurveTo(x1, y1,x2, y2, p1[0], p1[1]);
      }

      this.context.lineTo(this.points[this.points.length - 1][0],400)
      this.context.lineTo(this.points[0][0],400)
      this.context.lineTo(this.points[0][0],this.points[0][1])

      //  创建渐变填充
      const gradient = this.context.createLinearGradient(0, 0, 0, 400);
      gradient.addColorStop(0, 'rgba(135, 206, 235, 0.5)'); // 半透明蓝色
      gradient.addColorStop(1, 'rgba(135, 206, 235, 1)'); // 完全透明
      this.context.closePath();
      this.context.fillStyle = gradient;
      this.context.fill();
      
      this.context.beginPath();
      this.context.moveTo(this.points[0][0], this.points[0][1]);
      for (let i = 0; i < this.points.length - 1; i++) {
        const p0 = this.points[i];
        const p1 = this.points[i + 1];
        const t0 = this.points[i];
        const t1 = this.points[i + 1];
        const k = 1/3;

        const x1 = p0[0] + t0[0] * k;
        const y1 = p0[1] + t0[1] * k;

        const x2 = p1[0] - t1[0] * k;
        const y2 = p1[1] - t1[1] * k;

        this.context.bezierCurveTo(x1, y1,x2, y2, p1[0], p1[1]);
      }
      this.context.stroke();
      // 绘制数据点
      this.drawDataPoints()
    })
}
.height('100%')
.width('100%')

} } `

最终的效果图如下:

相关推荐
Liora_Yvonne3 小时前
不懂后端,只会 TypeScript,想独立做完整项目?这套全栈底座就是给前端准备的
前端·后端·全栈
前端Hardy3 小时前
GitHub 爆火!236K+ Star!一套 Skills 让 AI 按工程师方式写代码
前端·后端
烬羽3 小时前
AI Coding 全流程实战:从需求到上线,我用 AI 开发了一个 NPM 包
前端·react.js·ai编程
前进的程序员3 小时前
Codex破局:前端组件秒级生成|提速React/Vue开发,可复用提示词+实战调试经验
前端·vue.js·react.js·codex
前端snow4 小时前
ai agent ---output汇总
前端
4311媒体网4 小时前
帝国CMS网站自定义搭建技巧
服务器·开发语言·前端
JunjunZ4 小时前
Vue 3 文件预览的通用设计与实现
前端·vue.js
CappuccinoRose4 小时前
ES6+ 核心语法糖
前端·es6·解构·可选链·空值合并
两只羊ovo4 小时前
Promise.all 并发请求实战:从串行 await 到双段并行
前端
七牛开发者4 小时前
解读 Cordis:dsh 一切皆插件背后的运行时设计
前端·javascript·后端