【HarmonyOS】【JAVA UI】鴻蒙 自定義折線圖

来源:https://www.cnblogs.com/developer-huawei/archive/2022/03/23/16033625.html
-Advertisement-
Play Games

關於HarmonyOS 自定義View我們可以學習HarmonyOS自定義組件 這篇文檔,今天描述自定義折線圖的功能,我們從“準備工作”、“初始化畫筆”、“繪畫折線圖”、“運行效果圖”,這四個方面進行描述 1. 準備工作 想要實現折線圖我們瞭解Paint,獲取屏幕的寬高,這幾個功能的實現 獲取屏幕的 ...


关于HarmonyOS 自定义View我们可以学习HarmonyOS自定义组件 这篇文档,今天描述自定义折线图的功能,我们从“准备工作”、“初始化画笔”、“绘画折线图”、“运行效果图”,这四个方面进行描述

image.png

1. 准备工作

想要实现折线图我们了解Paint获取屏幕的宽高,这几个功能的实现

获取屏幕的宽高的代码如下

/**
 * 获取屏幕宽
 *
 * @param context context
 * @return int
 */
public static int getWindowWidth(Context context) {
    DisplayManager displayManager = DisplayManager.getInstance();
    Optional<Display> defaultDisplay = displayManager.getDefaultDisplay(context);
    return defaultDisplay.get().getAttributes().width;
}
 
/**
 * 获取屏幕高
 *
 * @param context context
 * @return int
 */
public static int getWindowHeight(Context context) {
    DisplayManager displayManager = DisplayManager.getInstance();
    Optional<Display> defaultDisplay = displayManager.getDefaultDisplay(context);
    return defaultDisplay.get().getAttributes().height;
}

2. 初始化画笔

主要实现画笔的设置颜色,设置宽度,设置画笔风格

private void initPaint() {
    myPaint = new Paint();
    myPaint.setColor(defaultColor);
    myPaint.setStrokeWidth(ringWidth);
    myPaint.setStyle(Paint.Style.STROKE_STYLE);
}

3. 绘画折线图

我们要学会Point,和canvas.drawTextcanvas.drawLine绘画Y轴的坐标,绘画x轴坐标,绘画折线图三个方面进行实现

3.1 绘画Y轴的坐标代码如下

//Todo 绘画Y轴
//todo 绘画Y线
float mYHeigh = mScreenHeight * mYHeightPercent;
Point mYstartPoint = new Point(mYStartPointX, mYStartPointY);
Point mYEndPoint = new Point(mYStartPointX, mYHeigh);
Line yLine = new Line(mYstartPoint, mYEndPoint);
canvas.drawLine(yLine, myPaint);//绘画y线
//TODO 绘画Y轴刻度线
for (int i = 0; i <= 10; i++) {
    Point mYScalesStartPoint = new Point(mYStartPointX, (mYHeigh - mYStartPointY) * i / 10 + mYStartPointY);
    Point mYScalesEndPoint = new Point(mYStartPointX + mScaleLength, (mYHeigh - 50) * i / 10 + mYStartPointY);
    Line yScalesLine = new Line(mYScalesStartPoint, mYScalesEndPoint);
    canvas.drawLine(yScalesLine, myPaint);
    //Todo 画Y轴刻度
    Paint mPaint = getPaint();
    canvas.drawText(mPaint, ((int) (((float) (10 - i) / 10) * 100)) + "", mYStartPointX - 100, (mYHeigh - 50) * i / 10 + mYStartPointY);
}

3.2 绘画X轴的坐标代码如下

//Todo 绘画X轴
Point mXstartPoint = new Point(mYStartPointX, mYHeigh);
Point mXEndPoint = new Point(mScreenWidth, mYHeigh);
Line XLine = new Line(mXstartPoint, mXEndPoint);
canvas.drawLine(XLine, myPaint); //绘画x线
//Todo 获取x轴长度
float mXwidth = mScreenWidth - mYStartPointX;
//TODO 绘画X轴刻度线
for (int i = 0; i <= 12; i++) {
    Point mXScalesStartPoint;
    Point mXScalesEndPoint;
    mXScalesStartPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh);
    mXScalesEndPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh - mScaleLength);
    Line XScalesLine = new Line(mXScalesStartPoint, mXScalesEndPoint);
    canvas.drawLine(XScalesLine, myPaint); //Todo 画x轴刻度
    //Todo 绘画月份
    Paint mPaint = getPaint();
    mPaint.setTextSize(30);
    if (i != 0) {
        canvas.drawText(mPaint, i + "月", mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh + 100);
    }
}

3.3 绘画折线代码如下

//Todo 绘画折线
Point mXPolyPoint = null;
float Percentage = 0f;
for (int i = 1; i < myData.length + 1; i++) {
    if (i == 1) {
        Percentage = myData[i - 1] / 100f;
         mXPolyPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i,
                 mYHeigh - (float) (mYHeigh - mYStartPointY) * Percentage);
    } else {
        Percentage = myData[i - 1] / 100f;
        Point mNextPolyPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i,
                mYHeigh - (float) (mYHeigh - mYStartPointY) * Percentage);
        Paint mPaint = getPaint();
        mPaint.setColor(Color.RED);
        mPaint.setTextSize(100);
        Line mPolyline = new Line(mXPolyPoint, mNextPolyPoint);
        canvas.drawLine(mPolyline, mPaint); //绘画两个月份点之间连线
        mXPolyPoint = mNextPolyPoint;
    }
}

4. 运行效果

4.1 全部代码如下

package com.harmony.alliance.mydemo.view;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.Line;
import ohos.agp.utils.Point;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import java.util.Optional;
 
public class CustomComponent extends Component implements  Component.DrawTask {
    private Paint myPaint;
    private Color defaultColor = new Color(Color.rgb(237, 98, 98));
    //画笔的宽度
    private float ringWidth = 10;
    private int mScreenWidth;//屏幕宽度
    private int mScreenHeight;//屏幕高度
    private float mYHeightPercent = 0.8f;//Y轴百分比
    //todo Y轴起始点坐标x点
    private float mYStartPointX = 200;
    //todo Y轴起始点坐标y点
    private float mYStartPointY = 50;
    private float mScaleLength = 50;
    private int[] myData = new int[]{68, 10, 45, 10, 88, 63, 60, 55, 79, 34, 52, 77};
 
    public CustomComponent(Context context) {
        this(context, null);
    }
 
    //如需支持xml创建自定义组件,必须添加该构造方法
    public CustomComponent(Context context, AttrSet attrSet) {
        super(context, attrSet);
        //todo 获取屏幕宽高
        mScreenWidth = getWindowWidth(context);
        mScreenHeight = getWindowHeight(context);
        // 初始化画笔
        initPaint();
        // 添加绘制任务
        addDrawTask(this);
    }
 
 
    private void initPaint() {
        myPaint = new Paint();
        myPaint.setColor(defaultColor);
        myPaint.setStrokeWidth(ringWidth);
        myPaint.setStyle(Paint.Style.STROKE_STYLE);
    }
 
 
    @Override
    public void onDraw(Component component, Canvas canvas) {
        //Todo 绘画Y轴
        //todo 绘画Y线
        float mYHeigh = mScreenHeight * mYHeightPercent;
        Point mYstartPoint = new Point(mYStartPointX, mYStartPointY);
        Point mYEndPoint = new Point(mYStartPointX, mYHeigh);
        Line yLine = new Line(mYstartPoint, mYEndPoint);
        canvas.drawLine(yLine, myPaint);//绘画y线
        //TODO 绘画Y轴刻度线
        for (int i = 0; i <= 10; i++) {
            Point mYScalesStartPoint = new Point(mYStartPointX, (mYHeigh - mYStartPointY) * i / 10 + mYStartPointY);
            Point mYScalesEndPoint = new Point(mYStartPointX + mScaleLength, (mYHeigh - 50) * i / 10 + mYStartPointY);
            Line yScalesLine = new Line(mYScalesStartPoint, mYScalesEndPoint);
            canvas.drawLine(yScalesLine, myPaint);
            //Todo 画Y轴刻度
            Paint mPaint = getPaint();
            canvas.drawText(mPaint, ((int) (((float) (10 - i) / 10) * 100)) + "", mYStartPointX - 100, (mYHeigh - 50) * i / 10 + mYStartPointY);
        }
        //Todo 绘画X轴
        Point mXstartPoint = new Point(mYStartPointX, mYHeigh);
        Point mXEndPoint = new Point(mScreenWidth, mYHeigh);
        Line XLine = new Line(mXstartPoint, mXEndPoint);
        canvas.drawLine(XLine, myPaint);//绘画x线
        //Todo 获取x轴长度
        float mXwidth = mScreenWidth - mYStartPointX;
        //TODO 绘画X轴刻度线
        for (int i = 0; i <= 12; i++) {
            Point mXScalesStartPoint;
            Point mXScalesEndPoint;
            mXScalesStartPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh);
            mXScalesEndPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh - mScaleLength);
            Line XScalesLine = new Line(mXScalesStartPoint, mXScalesEndPoint);
            canvas.drawLine(XScalesLine, myPaint);      //Todo 画x轴刻度
            //Todo 绘画月份
            Paint mPaint = getPaint();
            mPaint.setTextSize(30);
            if (i != 0) {
                canvas.drawText(mPaint, i + "月", mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh + 100);
            }
        }
 
 
        //Todo 绘画折线
        Point mXPolyPoint = null;
        float Percentage = 0f;
        for (int i = 1; i < myData.length + 1; i++) {
            if (i == 1) {
                Percentage = myData[i - 1] / 100f;
                mXPolyPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i,
                        mYHeigh - (float) (mYHeigh - mYStartPointY) * Percentage);
            } else {
                Percentage = myData[i - 1] / 100f;
                Point mNextPolyPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i,
                        mYHeigh - (float) (mYHeigh - mYStartPointY) * Percentage);
                Paint mPaint = getPaint();
                mPaint.setColor(Color.RED);
                mPaint.setTextSize(100);
                Line mPolyline = new Line(mXPolyPoint, mNextPolyPoint);
                canvas.drawLine(mPolyline, mPaint);//绘画两个月份点之间连线
                mXPolyPoint = mNextPolyPoint;
            }
 
        }
 
    }
 
    /**
     * 获取屏幕宽
     *
     * @param context context
     * @return int
     */
    public static int getWindowWidth(Context context) {
        DisplayManager displayManager = DisplayManager.getInstance();
        Optional<Display> defaultDisplay = displayManager.getDefaultDisplay(context);
        return defaultDisplay.get().getAttributes().width;
    }
 
    /**
     * 获取屏幕高
     *
     * @param context context
     * @return int
     */
    public static int getWindowHeight(Context context) {
        DisplayManager displayManager = DisplayManager.getInstance();
        Optional<Display> defaultDisplay = displayManager.getDefaultDisplay(context);
        return defaultDisplay.get().getAttributes().height;
    }
 
 
    //初始化刻度线的画笔
    public Paint getPaint() {
        Paint paint = new Paint();
        paint.setColor(Color.RED);
        paint.setTextSize(50);
        return paint;
    }
}

 4.2 新建AbilitySlice 然后在xml布局中写如下代码

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:alignment="center"
    ohos:orientation="vertical">
 
    <com.harmony.alliance.mydemo.view.CustomComponent
        ohos:width="match_parent"
        ohos:height="match_parent">
 
    </com.harmony.alliance.mydemo.view.CustomComponent>
 
</DirectionalLayout>

4.3 运行效果图

image.png


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天我們一起來探索一下ASP.NET Core框架中的Authorization。我們知道請求進入管道處理流程先會使用Authentication進行用戶認證,然後使用Authorization進行用戶授權。如果沒有看過認證過程的大家可以先轉到Authentication這一篇。 AddAuthor ...
  • Viewer.js庫是一個實用的js庫,用於圖片瀏覽,放大縮小翻轉幻燈片播放等實用操作 本文相關參考鏈接 JavaScript 模塊中的 JavaScript 隔離 Viewer.js工程 Blazor JS 隔離優勢 導入的 JS 不再污染全局命名空間。 庫和組件的使用者不需要導入相關的 JS。即 ...
  • 一 什麼是委托 可以認為委托是持有一個或多個方法的對象。可以執行委托,執行時委托會執行它所持有的方法。 從C++的角度理解,委托可以看成一個類型安全、面向對象的C++函數指針。 delegate void MyDel(int value); //聲明委托類型 class Program { void ...
  • 應用程式編程介面(API)是一組允許軟體組件進行交互的協議。中間介面通常用於簡化開發,使軟體團隊能夠重覆使用代碼。API還通過將應用程式與它們所運行的基礎設施脫鉤來抽象系統之間的功能。儘管API在現代商業中的好處和用例不斷增加,但固有的安全挑戰帶來了各種安全風險。 本文深入探討了與API漏洞相關的各 ...
  • 一、Nginx介紹 1.nginx是一個高性能HTTP伺服器,反向代理伺服器,郵件代理伺服器,TCP/UDP反向代理伺服器. 2.nginx處理請求是非同步非阻塞的,在高併發下nginx 能保持低資源低消耗高性能,主要用在集群系統中用於支持負載均衡. 3.nginx對靜態文件的處理速度也相當快,也可以 ...
  • 本文嘗試通過解釋 api 介面底層做了什麼來闡釋 linux 文件系統在設計層面的一些考慮,配合通俗易懂的日常命令和簡單程式來進行驗證,踐行“紙上得來終覺淺,絕知此事要躬行”的理念,目的是做一個 linux 文件系統的引入… ...
  • Centos7下載及安裝 1.下載虛擬機 虛擬機下載地址: https://www.vmware.com 或者 360一鍵安裝(推薦) 2.在虛擬機上安裝Centos7 2.1.通過鏡像進行安裝 這裡是阿裡雲Centos7的鏡像http://mirrors.aliyun.com/centos/7/i ...
  • 開發者通過華為分析服務下載所需的事件數據,這些數據可以導入到開發者自有的分析系統中,用於構建自定義報告或生成受眾群體的個性化分析等,從而幫助制定切實有效的營銷活動。數據導出支持按照用戶屬性和導出事件作為過濾條件,同時展示“預計可導出事件數”。開發者選擇不同的時間段和過濾條件,預估事件數就會隨之改變。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...