/*\r
+\r
* Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.\r
* Description: heartRate view\r
* Author:\r
* Create: 2021-07-26\r
- */\r
+ */\r
\r
#include <securec.h>\r
#include "HeartRateView.h"\r
#include "ScreenModels.h"\r
#include "ui_resource_image.h"\r
#include "common/image_cache_manager.h"\r
-\r
-namespace OHOS {\r
-static HeartRateView *g_pHeartRateView = nullptr;\r
+#define HEART_DATA_TEST 1\r
+namespace OHOS\r
+{\r
+ static HeartRateView *g_pHeartRateView = nullptr;\r
\r
// 背景坐标图形\r
-#define ACT_IMAGE_X 0 // 图片坐标起点\r
-#define ACT_IMAGE_Y 115 // 图片坐标起点\r
-#define ACT_IMAGE_COOR_X 45 // 200刻度线到最左端的像素点\r
+#define ACT_IMAGE_X 38 // 图片坐标起点\r
+#define ACT_IMAGE_Y 130 // 图片坐标起点\r
+#define ACT_IMAGE_COOR_X 80 // 200刻度线到最左端的像素点\r
#define ACT_IMAGE_COOR_Y 145 // 200刻度线到顶端的像素点\r
#define ACT_IMAGE_COOR_PIXELS 160 // 实际背景坐标0到200心率值的实际像素点\r
#define ACT_IMAGE_COOR_VALUE HEART_RATE_LIMIT_UPPER // 图片刻度表示的心率范围\r
-#define ACT_IMAGE_COOR_WIDTH 454\r
-#define ACT_IMAGE_COOR_HEIGHT 220\r
+#define ACT_IMAGE_COOR_WIDTH 390\r
+#define ACT_IMAGE_COOR_HEIGHT 200\r
\r
// 心电图坐标适配\r
#define COORDINATE_VALUE 5 // 余量\r
// 心形心跳\r
#define HEARTBEAT_IMAGE_WIDTH 92\r
#define HEARTBEAT_IMAGE_HEIGHT 92\r
-#define HEARTBEAT_IMAGE_X 130\r
-#define HEARTBEAT_IMAGE_Y 25\r
+#define HEARTBEAT_IMAGE_X 105\r
+#define HEARTBEAT_IMAGE_Y 50\r
#define HEARTBEAT_IMAGE_NUM 19\r
#define HEARTBEAT_DELAY 50\r
\r
#define REST_HEART_TEXT_HEIGHT2 (REST_HEART_TEXT_FONT_SIZE + 5)\r
\r
// 每秒心率\r
-#define PERSEC_HEART_RATE_FONT_SIZE 45\r
-#define PERSEC_HEART_RATE_X 225\r
-#define PERSEC_HEART_RATE_Y 55\r
-#define PERSEC_HEART_RATE_WIDTH 90\r
+#define PERSEC_HEART_RATE_FONT_SIZE 60\r
+#define PERSEC_HEART_RATE_X 202\r
+#define PERSEC_HEART_RATE_Y 62\r
+#define PERSEC_HEART_RATE_WIDTH 102\r
#define PERSEC_HEART_RATE_HEIGHT (PERSEC_HEART_RATE_FONT_SIZE + 5)\r
\r
#define PERSEC_HEART_TEXT_FONT_SIZE 30\r
#define PERSEC_HEART_TEXT_WIDTH 75\r
#define PERSEC_HEART_TEXT_HEIGHT (PERSEC_HEART_TEXT_FONT_SIZE + 5)\r
\r
-// 心跳image\r
-static ImageAnimatorInfo g_heartBeatImageInfo[HEARTBEAT_IMAGE_NUM] = {\r
- {PNG_A004_070_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_071_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_072_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_073_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_074_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_075_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_076_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_077_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_078_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_079_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
-\r
- {PNG_A004_080_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_081_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_082_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_083_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_084_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_085_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_086_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_087_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
- {PNG_A004_088_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
- IMG_SRC_FILE_PATH},\r
-};\r
-\r
-HeartRateView::HeartRateView()\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView");\r
- dataNume = 0;\r
- currIndex = 0;\r
- serialIndex = 0;\r
- maxRate = 0;\r
- minRate = HEART_RATE_LIMIT_UPPER;\r
- InitHeartRateData();\r
- SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);\r
-\r
- g_pHeartRateView = this;\r
-}\r
-\r
-HeartRateView::~HeartRateView()\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::~HeartRateView");\r
- if (viewiInitStatus) {\r
- int32_t i;\r
- RemoveAll();\r
- delete imageViewCoordinate;\r
- imageViewCoordinate = nullptr;\r
-\r
- chart->ClearDataSerial();\r
- for (i = 0; i < HEART_AVE_NUM; i++) {\r
- delete dataSerial[i];\r
- dataSerial[i] = nullptr;\r
- }\r
- delete chart;\r
- chart = nullptr;\r
- delete imageViewTop;\r
- imageViewTop = nullptr;\r
- delete imageViewBottom;\r
- imageViewBottom = nullptr;\r
- delete dataTopAndbottom;\r
- dataTopAndbottom = nullptr;\r
- imageAnimator->Stop();\r
- delete imageAnimator;\r
- imageAnimator = nullptr;\r
- delete topRate;\r
- topRate = nullptr;\r
- delete bottomRate;\r
- bottomRate = nullptr;\r
- delete ratePerSec;\r
- ratePerSec = nullptr;\r
- delete ratePerSecText;\r
- ratePerSecText = nullptr;\r
- delete restRate;\r
- restRate = nullptr;\r
- delete restRateText1;\r
- restRateText1 = nullptr;\r
- delete restRateText2;\r
- restRateText2 = nullptr;\r
- }\r
- g_pHeartRateView = nullptr;\r
-}\r
-\r
-HeartRateView *HeartRateView::GetInstance(void)\r
-{\r
- return g_pHeartRateView;\r
-}\r
-\r
-int32_t HeartRateView::InitHeartRateData(void) // 初始化心率数据,将存放心率数据的有效字节设置为无效值\r
-{\r
- heartRateData[0].x = INVALID_HEART_VALUE;\r
- heartRateData[0].y = INVALID_HEART_VALUE;\r
-\r
- int32_t ret = memset_s(heartRateData, sizeof(Point) * HEART_AVE_NUM, INVALID_HEART_VALUE, sizeof(Point) * HEART_AVE_NUM);\r
- if (ret != 0) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[InitHeartRateData] memset_s heartRateData fail! ret = %d", ret);\r
- }\r
- return ret;\r
-}\r
-\r
-int32_t HeartRateView::SetHeartRateData(Point *rateData, uint32 rateDataSize)\r
-{\r
- if (rateData == nullptr) {\r
- return OHOS_FAILURE;\r
- }\r
-\r
- if (rateDataSize > sizeof(Point) * HEART_AVE_NUM) {\r
- rateDataSize = sizeof(Point) * HEART_AVE_NUM;\r
- }\r
- InitHeartRateData();\r
- int32_t ret = memcpy_s(heartRateData, sizeof(Point) * HEART_AVE_NUM, rateData, rateDataSize);\r
- if (ret != EOK) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memcpy_s heartRateData fail! ret = %d", ret);\r
- return OHOS_FAILURE;\r
- }\r
- return OHOS_SUCCESS;\r
-}\r
-\r
-\r
-int32_t HeartRateView::HeartRateDataProc(void)\r
-{\r
- Point datain[HEART_AVE_NUM];\r
- int32_t ret = memcpy_s(datain, sizeof(Point) * HEART_AVE_NUM, heartRateData, sizeof(Point) * HEART_AVE_NUM);\r
- if (ret != EOK) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memcpy_s rateDataTmp fail! ret = %d", ret);\r
- return OHOS_FAILURE;\r
- }\r
-\r
- ret = memset_s(rateDataTmp, sizeof(Point) * HEART_AVE_NUM, INVALID_HEART_VALUE, sizeof(Point) * HEART_AVE_NUM); // 替换为无效值\r
- if (ret != EOK) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memset_s rateDataTmp fail! ret = %d", ret);\r
- return OHOS_FAILURE;\r
- }\r
-\r
- dataNume = 0;\r
- for (int32_t i = 0; i < HEART_AVE_NUM; i++) {\r
- if (datain[i].x >= 0 && datain[i].x < HEART_AVE_NUM && datain[i].y > 0 &&\r
- datain[i].y <= HEART_RATE_LIMIT_UPPER) {\r
- rateDataTmp[dataNume].x = datain[i].x + COORDINATE_VALUE;\r
- rateDataTmp[dataNume].y = datain[i].y * ACT_IMAGE_COOR_PIXELS / ACT_IMAGE_COOR_VALUE;\r
- dataNume++;\r
- }\r
- }\r
- return OHOS_SUCCESS;\r
-}\r
-\r
-void HeartRateView::SetLabel(UILabel *label, LabelInfo labelInfo)\r
-{\r
- label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelInfo.fontSize);\r
- label->SetPosition(labelInfo.x, labelInfo.y);\r
- label->Resize(labelInfo.width, labelInfo.height);\r
- label->SetStyle(STYLE_BACKGROUND_COLOR, OPA_TRANSPARENT);\r
- Add(label);\r
-}\r
-\r
-void HeartRateView::HeartRateLabelDisplay(void)\r
-{\r
- LabelInfo PerSecLabel = { PERSEC_HEART_RATE_FONT_SIZE, PERSEC_HEART_RATE_X, PERSEC_HEART_RATE_Y,\r
- PERSEC_HEART_RATE_WIDTH, PERSEC_HEART_RATE_HEIGHT };\r
- LabelInfo PerSecTextLabel = { PERSEC_HEART_TEXT_FONT_SIZE, PERSEC_HEART_TEXT_X, PERSEC_HEART_TEXT_Y,\r
- PERSEC_HEART_TEXT_WIDTH, PERSEC_HEART_TEXT_HEIGHT };\r
-\r
- LabelInfo topLabel = { HEART_RATE_LIMIT_FONT_SIZE, TOP_TEXT_X, TOP_TEXT_Y, TOP_TEXT_WIDTH, TOP_TEXT_HEIGHT };\r
- LabelInfo bottomLabel = { HEART_RATE_LIMIT_FONT_SIZE, BOTTOM_TEXT_X, BOTTOM_TEXT_Y, BOTTOM_TEXT_WIDTH,\r
- BOTTOM_TEXT_HEIGHT };\r
-\r
- LabelInfo restRateLabel = { REST_HEART_RATE_FONT_SIZE, REST_HEART_RATE_X, REST_HEART_RATE_Y, REST_HEART_RATE_WIDTH,\r
- REST_HEART_RATE_HEIGHT };\r
- LabelInfo restRateTextLabel1 = { REST_HEART_TEXT_FONT_SIZE, REST_HEART_TEXT_X1, REST_HEART_TEXT_Y1,\r
- REST_HEART_TEXT_WIDTH1, REST_HEART_TEXT_HEIGHT1 };\r
- LabelInfo restRateTextLabel2 = { REST_HEART_TEXT_FONT_SIZE, REST_HEART_TEXT_X2, REST_HEART_TEXT_Y2,\r
- REST_HEART_TEXT_WIDTH2, REST_HEART_TEXT_HEIGHT2 };\r
-\r
- topRate = new UILabel();\r
- bottomRate = new UILabel();\r
- ratePerSec = new UILabel();\r
- ratePerSecText = new UILabel();\r
- restRate = new UILabel();\r
- restRateText1 = new UILabel();\r
- restRateText2 = new UILabel();\r
-\r
- if (topRate == nullptr || bottomRate == nullptr || ratePerSec == nullptr || ratePerSecText == nullptr ||\r
- restRate == nullptr || restRateText1 == nullptr || restRateText2 == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateLabelDisplay] new UILabel fail");\r
- }\r
-\r
- // 实时心率\r
- SetLabel(ratePerSec, PerSecLabel);\r
- SetLabel(ratePerSecText, PerSecTextLabel);\r
- ratePerSec->SetText("--");\r
- ratePerSecText->SetText("次/分");\r
-\r
- // 最高最低心率\r
- SetLabel(topRate, topLabel);\r
- SetLabel(bottomRate, bottomLabel);\r
- topRate->SetText("--");\r
- bottomRate->SetText("--");\r
-\r
- // 静息心率\r
- SetLabel(restRate, restRateLabel);\r
- SetLabel(restRateText1, restRateTextLabel1);\r
- SetLabel(restRateText2, restRateTextLabel2);\r
- restRateText1->SetText("静息");\r
- restRate->SetText("--");\r
- restRateText2->SetText("次/分");\r
-}\r
-\r
-void HeartRateView::HeartRateCoordinate(void)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateCoordinate start");\r
- // 坐标图片\r
- imageViewCoordinate = new UIImageView();\r
- if (imageViewCoordinate == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateCoordinate] new imageViewCoordinate fail");\r
- return;\r
- }\r
- imageViewCoordinate->SetPosition(ACT_IMAGE_X, ACT_IMAGE_Y);\r
- imageViewCoordinate->SetWidth(ACT_IMAGE_COOR_WIDTH);\r
- imageViewCoordinate->SetHeight(ACT_IMAGE_COOR_HEIGHT);\r
- Add(imageViewCoordinate);\r
-\r
- // 心电图坐标适配\r
- chart = new UIChartPolyline();\r
- if (chart == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateCoordinate] new chart fail");\r
- return;\r
- }\r
- chart->SetPosition(COORDINATE_POINT_X, COORDINATE_POINT_Y);\r
- chart->SetWidth(COORDINATE_WIDTH);\r
- chart->SetHeight(COORDINATE_HEIGHT);\r
- chart->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);\r
- chart->SetStyle(STYLE_BACKGROUND_OPA, 0);\r
- chart->SetStyle(STYLE_LINE_WIDTH, 1); // line width\r
-\r
- UIXAxis &xAxis = chart->GetXAxis();\r
- UIYAxis &yAxis = chart->GetYAxis();\r
- xAxis.SetDataRange(0, COORDINATE_WIDTH); // 24小时对应的秒数\r
- yAxis.SetDataRange(0, COORDINATE_HEIGHT);\r
- xAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
- yAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
- chart->SetGradientOpacity(COORDINATE_GRAD_MIN_OPA, COORDINATE_GRAD_MAX_OPA);\r
- Add(chart);\r
-}\r
-\r
-void HeartRateView::InsertTopAndBottomRateImage(void)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::InsertTopAndBottomRateImage start");\r
- imageViewTop = new UIImageView();\r
- imageViewBottom = new UIImageView();\r
- if (imageViewTop == nullptr || imageViewBottom == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[InsertTopAndBottomRateImage] new imageViewTop or imageViewBottom fail");\r
- return;\r
- }\r
- imageViewTop->SetPosition(TOP_IMAGE_X, TOP_IMAGE_Y);\r
- imageViewTop->SetWidth(TOP_IMAGE_WIDTH);\r
- imageViewTop->SetHeight(TOP_IMAGE_HEIGHT);\r
- Add(imageViewTop);\r
- imageViewBottom->SetPosition(BOTTOM_IMAGE_X, BOTTOM_IMAGE_Y);\r
- imageViewBottom->SetWidth(BOTTOM_IMAGE_WIDTH);\r
- imageViewBottom->SetHeight(BOTTOM_IMAGE_HEIGHT);\r
- Add(imageViewBottom);\r
-}\r
-\r
-void HeartRateView::UpdataTopAndBottomRate(void)\r
-{\r
- if (chart == nullptr) {\r
- return;\r
- }\r
- if (dataTopAndbottom != nullptr) {\r
- chart->DeleteDataSerial(dataTopAndbottom);\r
- delete dataTopAndbottom;\r
- dataTopAndbottom = nullptr;\r
- }\r
- dataTopAndbottom = new UIChartDataSerial();\r
- if (dataTopAndbottom == nullptr) {\r
- return;\r
- }\r
- if (dataNume != 1) {\r
- dataTopAndbottom->SetMaxDataCount(dataNume); // number of data points\r
- dataTopAndbottom->AddPoints(rateDataTmp, dataNume); // number of data points\r
- } else {\r
- Point tmp[NUM_2];\r
- tmp[0].x = tmp[1].x = rateDataTmp[0].x;\r
- tmp[0].y = tmp[1].y = rateDataTmp[0].y;\r
- dataTopAndbottom->SetMaxDataCount(NUM_2); // number of data points\r
- dataTopAndbottom->AddPoints(tmp, NUM_2); // number of data points\r
- }\r
- dataTopAndbottom->SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0)); // 设置透明\r
- chart->AddDataSerial(dataTopAndbottom);\r
- chart->Invalidate();\r
-\r
- UIChartDataSerial::PointStyle pointStyle;\r
- // 最低心跳\r
- dataTopAndbottom->EnableBottomPoint(true);\r
- pointStyle.radius = BOTTOM_RADIUS; // Inner radius\r
- pointStyle.fillColor = Color::Gray();\r
- pointStyle.strokeWidth = BOTTOM_STROKE_WIDTH; // border width\r
- pointStyle.strokeColor = Color::Black();\r
- dataTopAndbottom->SetBottomPointStyle(pointStyle);\r
- chart->Invalidate();\r
-\r
- uint16_t bottom = dataTopAndbottom->GetValleyData() * ACT_IMAGE_COOR_VALUE / ACT_IMAGE_COOR_PIXELS;\r
- // 最高心跳\r
- dataTopAndbottom->EnableTopPoint(true);\r
- pointStyle.fillColor = Color::Red();\r
- pointStyle.radius = TOP_RADIUS; // Inner radius\r
- pointStyle.strokeColor = Color::Black();\r
- pointStyle.strokeWidth = TOP_STROKE_WIDTH; // border width\r
- dataTopAndbottom->SetTopPointStyle(pointStyle);\r
- chart->Invalidate();\r
-\r
- uint16_t top = dataTopAndbottom->GetPeakData() * ACT_IMAGE_COOR_VALUE / ACT_IMAGE_COOR_PIXELS;\r
- if (top <= HEART_RATE_LIMIT_UPPER) {\r
- maxRate = (maxRate >= top) ? maxRate : top;\r
- }\r
- if (bottom != 0) {\r
- minRate = (minRate <= bottom) ? minRate : bottom;\r
- }\r
-}\r
-\r
-void HeartRateView::ElectrocardiogramOnePoint(Point *rateData, uint16_t index)\r
-{\r
- Point tmp[NUM_2];\r
-\r
- if (rateData == nullptr || chart == nullptr || index >= HEART_AVE_NUM || serialIndex >= HEART_AVE_NUM) {\r
- return;\r
- }\r
-\r
- tmp[0].x = tmp[1].x = rateData[index].x;\r
- tmp[0].y = tmp[1].y = rateData[index].y;\r
-\r
- dataSerial[serialIndex] = new UIChartDataSerial();\r
- if (dataSerial[serialIndex] == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[ElectrocardiogramOnePoint] new dataSerial[%d] fail", serialIndex);\r
- serialIndex++;\r
- return;\r
- }\r
-\r
- dataSerial[serialIndex]->SetMaxDataCount(HEART_AVE_NUM); // 设置最大显示的像素点\r
- dataSerial[serialIndex]->AddPoints(tmp, NUM_2);\r
- dataSerial[serialIndex]->SetLineColor(Color::Red());\r
- dataSerial[serialIndex]->SetFillColor(Color::Red());\r
- dataSerial[serialIndex]->EnableGradient(true);\r
-\r
- chart->AddDataSerial(dataSerial[serialIndex]);\r
- chart->Invalidate();\r
- serialIndex++;\r
-}\r
-\r
-void HeartRateView::ElectrocardiogramMultiPoint(Point *rateData, uint16_t rateDataNume)\r
-{\r
- uint16_t i = 0;\r
- uint16_t j = 0;\r
- uint16_t tmp = 1;\r
- if (rateData == nullptr || chart == nullptr || rateDataNume > HEART_AVE_NUM) {\r
- return;\r
- }\r
-\r
- while (i < rateDataNume) {\r
- while ((j + 1 < rateDataNume) && (rateData[j + 1].x - rateData[j].x <= NUM_4)) { // 15分钟对应的秒数\r
- tmp++;\r
- j++;\r
- }\r
- if (tmp == 1) {\r
- ElectrocardiogramOnePoint(rateData, i);\r
- } else {\r
- if (serialIndex >= HEART_AVE_NUM) {\r
- return;\r
- }\r
- if (serialIndex > 0 && dataSerial[serialIndex - 1] != nullptr && i == 0) {\r
- dataSerial[serialIndex - 1]->AddPoints(rateData + 1, tmp - 1); // number of data points\r
- chart->Invalidate();\r
- } else {\r
- dataSerial[serialIndex] = new UIChartDataSerial();\r
- if (dataSerial[serialIndex] == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[ElectrocardiogramMultiPoint] new dataSerial[%d] fail", serialIndex);\r
- serialIndex++;\r
- return;\r
- }\r
-\r
- dataSerial[serialIndex]->SetMaxDataCount(HEART_AVE_NUM); // number of data points\r
- dataSerial[serialIndex]->AddPoints(rateData + i, tmp); // number of data points\r
- dataSerial[serialIndex]->SetLineColor(Color::Red());\r
- dataSerial[serialIndex]->SetFillColor(Color::Red());\r
- dataSerial[serialIndex]->EnableGradient(true);\r
-\r
- chart->AddDataSerial(dataSerial[serialIndex]);\r
- chart->Invalidate();\r
- serialIndex++;\r
- }\r
- }\r
- i += tmp;\r
- j = i;\r
- tmp = 1;\r
- }\r
-}\r
-\r
-void HeartRateView::HeartRateElectrocardiogram(void)\r
-{\r
- if (dataNume == 0) {\r
- return;\r
- }\r
- serialIndex = 0;\r
- if (dataNume != 1) {\r
- ElectrocardiogramMultiPoint(rateDataTmp, dataNume); // 多个点\r
- } else {\r
- ElectrocardiogramOnePoint(rateDataTmp, 0); // 一个点\r
- }\r
- currIndex = dataNume;\r
-}\r
-\r
-void HeartRateView::HeartbeatImageAnimator()\r
-{\r
- imageAnimator = new UIImageAnimatorView();\r
- if (imageAnimator == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartbeatImageAnimator] new imageAnimator fail");\r
- return;\r
- }\r
- imageAnimator->SetPosition(HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT);\r
- imageAnimator->SetImageAnimatorSrc(g_heartBeatImageInfo, HEARTBEAT_IMAGE_NUM, HEARTBEAT_DELAY);\r
- imageAnimator->SetRepeat(true);\r
- Add(imageAnimator);\r
- imageAnimator->Start();\r
-}\r
-\r
-void HeartRateView::HeartbeatImageAnimatorStart(void)\r
-{\r
- if (imageAnimator != nullptr) {\r
- imageAnimator->Start();\r
- }\r
-}\r
-\r
-void HeartRateView::HeartbeatImageAnimatorStop(void)\r
-{\r
- if (imageAnimator != nullptr) {\r
- imageAnimator->Stop();\r
- }\r
-}\r
-\r
-bool HeartRateView::InitView(void)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView::InitView");\r
- HeartRateDataProc();\r
- HeartRateLabelDisplay();\r
- HeartbeatImageAnimator();\r
- HeartRateCoordinate();\r
- InsertTopAndBottomRateImage();\r
- HeartRateElectrocardiogram();\r
- UpdataTopAndBottomRate();\r
- HeartbeatImageAnimatorStop();\r
- InitRefreshInterface();\r
- return true;\r
-}\r
-\r
-void HeartRateView::PreLoad(void)\r
-{\r
- if (!viewiInitStatus) {\r
- if (InitView()) {\r
- viewiInitStatus = true;\r
- }\r
- }\r
-\r
- if (!resLoadStatus) {\r
- ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewTop, HEART_HEARTRATE_TOP);\r
- ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewBottom, HEART_HEARTRATE_BOTTOM);\r
- ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewCoordinate, HEART_HEARTRATECOOR);\r
- resLoadStatus = true;\r
- }\r
-}\r
-\r
-void HeartRateView::UnLoad(void)\r
-{\r
- if (resLoadStatus) {\r
- ImageInfo* img = nullptr;\r
- imageViewTop->SetSrc(img);\r
- imageViewBottom->SetSrc(img);\r
- imageViewCoordinate->SetSrc(img);\r
- ImageCacheManager::GetInstance().UnloadAllInMultiRes(HEART_IAMGES);\r
- resLoadStatus = false;\r
- }\r
-}\r
-\r
-void HeartRateView::InitRefreshInterface(void)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView::InitRefreshInterface");\r
-\r
- Point *rateData = HeartModel::GetInstance()->GetAveHeartRate();\r
- uint16_t len = HeartModel::GetInstance()->GetAveHeartRateCount();\r
- SetHeartRateData(rateData, sizeof(Point) * len);\r
- uint16_t maxHeartRate = HeartModel::GetInstance()->GetHeartRateMax();\r
- uint16_t minHeartRate = HeartModel::GetInstance()->GetHeartRateMin();\r
- RefreshElectrocardiogram();\r
- if (maxHeartRate > 0 && maxHeartRate < HEART_RATE_LIMIT_UPPER) {\r
- RefreshHeartRateMax(HeartModel::GetInstance()->GetHeartRateMax());\r
- }\r
- if (minHeartRate > 0 && minHeartRate < HEART_RATE_LIMIT_UPPER) {\r
- RefreshHeartRateMin(HeartModel::GetInstance()->GetHeartRateMin());\r
- }\r
-}\r
-\r
-// 刷新心率曲线\r
-void HeartRateView::RefreshElectrocardiogram(void)\r
-{\r
- int32_t ret = HeartRateDataProc();\r
- if (ret != OHOS_SUCCESS) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[RefreshElectrocardiogram()] fail");\r
- return;\r
- }\r
- Point *rate = rateDataTmp;\r
-\r
- if (chart == nullptr) {\r
- return;\r
- }\r
-\r
- if (currIndex >= HEART_AVE_NUM) {\r
- currIndex = HEART_AVE_NUM;\r
- }\r
- if (dataNume > currIndex) {\r
- uint16_t tmp = dataNume - currIndex;\r
- if (currIndex > 0) {\r
- rate += (currIndex - 1);\r
- tmp += 1;\r
- }\r
- ElectrocardiogramMultiPoint(rate, tmp);\r
- currIndex = dataNume;\r
- } else if (dataNume == currIndex) { // 当前点平均心率刷新\r
- if (serialIndex > 0 && serialIndex <= HEART_AVE_NUM && dataSerial[serialIndex - 1] != nullptr) {\r
- Point modPoint;\r
- modPoint.x = rate[currIndex - 1].x;\r
- modPoint.y = rate[currIndex - 1].y;\r
-\r
- uint16_t count = dataSerial[serialIndex - 1]->GetDataCount();\r
- dataSerial[serialIndex - 1]->ModifyPoint(count - 1, modPoint);\r
- chart->Invalidate();\r
- }\r
- } else {\r
- return;\r
- }\r
- UpdataTopAndBottomRate(); // 最高、最低心率\r
-}\r
-\r
-// 清空心率曲线\r
-void HeartRateView::ClearElectrocardiogram(void)\r
-{\r
- int32_t i;\r
- dataNume = 0;\r
- currIndex = 0;\r
- maxRate = 0;\r
- minRate = HEART_RATE_LIMIT_UPPER;\r
- InitHeartRateData();\r
-\r
- if (chart == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "chart == nullptr");\r
- return;\r
- }\r
-\r
- if (ratePerSec != nullptr && topRate != nullptr && bottomRate != nullptr && restRate != nullptr) {\r
- ratePerSec->SetText("--");\r
- topRate->SetText("--");\r
- bottomRate->SetText("--");\r
- restRate->SetText("--");\r
- }\r
-\r
- chart->DeleteDataSerial(dataTopAndbottom);\r
- delete dataTopAndbottom;\r
- dataTopAndbottom = nullptr;\r
- for (i = 0; i < serialIndex; i++) {\r
- delete dataSerial[i];\r
- dataSerial[i] = nullptr;\r
- }\r
- chart->ClearDataSerial();\r
-\r
- serialIndex = 0;\r
- chart->Invalidate();\r
-}\r
-\r
-// 刷新每秒上报的心率\r
-void HeartRateView::RefreshHeartRatePerSec(uint16_t value)\r
-{\r
- char heartRate[NUM_4] = "--";\r
- int32_t ret = 0;\r
-\r
- if (ratePerSec == nullptr) {\r
- return;\r
- }\r
-\r
- if (value == 0) {\r
- ratePerSec->SetText("--");\r
- HeartbeatImageAnimatorStop();\r
- return;\r
- }\r
- HeartbeatImageAnimatorStart();\r
- if (value > NUM_99) {\r
- ret = sprintf_s(heartRate, sizeof(heartRate), "%u", value);\r
- } else {\r
- ret = sprintf_s(heartRate, sizeof(heartRate), " %u", value);\r
- }\r
- if (ret > EOK) {\r
- ratePerSec->SetText(heartRate);\r
- }\r
-}\r
-\r
-// 刷新最大心率\r
-void HeartRateView::RefreshHeartRateMax(uint16_t max)\r
-{\r
- char top[NUM_4] = "--";\r
- int32_t ret = 0;\r
- maxRate = (maxRate >= max) ? maxRate : max;\r
- if (topRate == nullptr) {\r
- return;\r
- }\r
- if (maxRate <= HEART_RATE_LIMIT_LOWER) {\r
- topRate->SetText("--");\r
- return;\r
- }\r
- ret = sprintf_s(top, sizeof(top), "%u", maxRate);\r
- if (ret > EOK) {\r
- topRate->SetText(top);\r
- }\r
-}\r
-\r
-// 刷新最小心率\r
-void HeartRateView::RefreshHeartRateMin(uint16_t min)\r
-{\r
- char bottom[NUM_4] = "--";\r
- int32_t ret = 0;\r
-\r
- minRate = (minRate <= min) ? minRate : min;\r
- if (bottomRate == nullptr) {\r
- return;\r
- }\r
- if (minRate >= HEART_RATE_LIMIT_UPPER) {\r
- bottomRate->SetText("--");\r
- return;\r
- }\r
- ret = sprintf_s(bottom, sizeof(bottom), "%u", minRate);\r
- if (ret > EOK) {\r
- bottomRate->SetText(bottom);\r
- }\r
-}\r
-\r
-// 刷新静息心率\r
-void HeartRateView::RefreshRestHeartRate(uint16_t value)\r
-{\r
- char heartRate[NUM_4] = "--";\r
- int32_t ret = 0;\r
-\r
- if (restRate == nullptr) {\r
- return;\r
- }\r
-\r
- if (value == 0 || value == (uint16_t)0xFFFF) { // 无效值\r
- restRate->SetText("--");\r
- } else {\r
- if (value > NUM_99) {\r
- ret = sprintf_s(heartRate, sizeof(heartRate), "%u", value);\r
- } else {\r
- ret = sprintf_s(heartRate, sizeof(heartRate), " %u", value);\r
- }\r
-\r
- if (ret > EOK) {\r
- restRate->SetText(heartRate);\r
- }\r
- }\r
-}\r
-} // namespace OHOS\r
+ // 心跳image\r
+ static ImageAnimatorInfo g_heartBeatImageInfo[HEARTBEAT_IMAGE_NUM] = {\r
+ {PNG_A004_070_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_071_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_072_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_073_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_074_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_075_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_076_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_077_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_078_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_079_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+\r
+ {PNG_A004_080_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_081_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_082_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_083_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_084_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_085_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_086_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_087_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ {PNG_A004_088_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+ };\r
+\r
+ HeartRateView::HeartRateView()\r
+ {\r
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView");\r
+ dataNume = 0;\r
+ currIndex = 0;\r
+ serialIndex = 0;\r
+ maxRate = 0;\r
+ minRate = HEART_RATE_LIMIT_UPPER;\r
+ InitHeartRateData();\r
+ SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);\r
+\r
+ g_pHeartRateView = this;\r
+ }\r
+\r
+ HeartRateView::~HeartRateView()\r
+ {\r
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::~HeartRateView");\r
+ if (viewiInitStatus == true)\r
+ {\r
+ int32_t i;\r
+ RemoveAll();\r
+ UnLoadHeartRateImageRes();\r
+ delete imageViewCoordinate;\r
+ imageViewCoordinate = nullptr;\r
+\r
+ chart->ClearDataSerial();\r
+ for (i = 0; i < HEART_AVE_NUM; i++)\r
+ {\r
+ delete dataSerial[i];\r
+ dataSerial[i] = nullptr;\r
+ }\r
+ delete chart;\r
+ chart = nullptr;\r
+ delete imageViewTop;\r
+ imageViewTop = nullptr;\r
+ delete imageViewBottom;\r
+ imageViewBottom = nullptr;\r
+ delete dataTopAndbottom;\r
+ dataTopAndbottom = nullptr;\r
+ imageAnimator->Stop();\r
+ delete imageAnimator;\r
+ imageAnimator = nullptr;\r
+ delete topRate;\r
+ topRate = nullptr;\r
+ delete bottomRate;\r
+ bottomRate = nullptr;\r
+ delete ratePerSec;\r
+ ratePerSec = nullptr;\r
+ delete ratePerSecText;\r
+ ratePerSecText = nullptr;\r
+ delete restRate;\r
+ restRate = nullptr;\r
+ delete restRateText1;\r
+ restRateText1 = nullptr;\r
+ delete restRateText2;\r
+ restRateText2 = nullptr;\r
+ }\r
+ g_pHeartRateView = nullptr;\r
+ }\r
+\r
+ HeartRateView *HeartRateView::GetInstance(void)\r
+ {\r
+ return g_pHeartRateView;\r
+ }\r
+\r
+ int32_t HeartRateView::InitHeartRateData(void) // 初始化心率数据,将存放心率数据的有效字节设置为无效值\r
+ {\r
+ int32_t ret;\r
+\r
+ heartRateData[0].x = INVALID_HEART_VALUE;\r
+ heartRateData[0].y = INVALID_HEART_VALUE;\r
+\r
+ ret = memset_s(heartRateData, sizeof(Point) * HEART_AVE_NUM, INVALID_HEART_VALUE, sizeof(Point) * HEART_AVE_NUM);\r
+ if (ret != 0)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[InitHeartRateData] memset_s heartRateData fail! ret = %d", ret);\r
+ }\r
+ return ret;\r
+ }\r
+\r
+ int32_t HeartRateView::SetHeartRateData(Point *rateData, uint32 rateDataSize)\r
+ {\r
+ int ret;\r
+\r
+ if (rateData == nullptr)\r
+ {\r
+ return OHOS_FAILURE;\r
+ }\r
+\r
+ if (rateDataSize > sizeof(Point) * HEART_AVE_NUM)\r
+ {\r
+ rateDataSize = sizeof(Point) * HEART_AVE_NUM;\r
+ }\r
+ InitHeartRateData();\r
+ ret = memcpy_s(heartRateData, sizeof(Point) * HEART_AVE_NUM, rateData, rateDataSize);\r
+ if (ret != EOK)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memcpy_s heartRateData fail! ret = %d", ret);\r
+ return OHOS_FAILURE;\r
+ }\r
+\r
+ return OHOS_SUCCESS;\r
+ }\r
+ int32_t HeartRateView::HeartRateDataProc(void)\r
+ {\r
+ int32_t i, ret;\r
+ Point datain[HEART_AVE_NUM];\r
+ ret = memcpy_s(datain, sizeof(Point) * HEART_AVE_NUM, heartRateData, sizeof(Point) * HEART_AVE_NUM);\r
+ if (ret != EOK)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memcpy_s rateDataTmp fail! ret = %d", ret);\r
+ return OHOS_FAILURE;\r
+ }\r
+\r
+ ret = memset_s(rateDataTmp, sizeof(Point) * HEART_AVE_NUM, INVALID_HEART_VALUE, sizeof(Point) * HEART_AVE_NUM); // 替换为无效值\r
+ if (ret != EOK)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memset_s rateDataTmp fail! ret = %d", ret);\r
+ return OHOS_FAILURE;\r
+ }\r
+\r
+ dataNume = 0;\r
+ for (i = 0; i < HEART_AVE_NUM; i += 15) // 每跨过15个点代表一个小时\r
+ {\r
+ if (datain[i].x >= 0 && datain[i].x < HEART_AVE_NUM && datain[i].y > 0 &&\r
+ datain[i].y <= HEART_RATE_LIMIT_UPPER)\r
+ {\r
+ rateDataTmp[dataNume].x = datain[i].x + COORDINATE_VALUE;\r
+ rateDataTmp[dataNume].y = datain[i].y * ACT_IMAGE_COOR_PIXELS / ACT_IMAGE_COOR_VALUE;\r
+ dataNume++;\r
+ }\r
+ }\r
+ return OHOS_SUCCESS;\r
+ }\r
+ void HeartRateView::SetLabel(UILabel *label, LabelInfo labelInfo)\r
+ {\r
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelInfo.fontSize);\r
+ label->SetPosition(labelInfo.x, labelInfo.y);\r
+ label->Resize(labelInfo.width, labelInfo.height);\r
+ label->SetStyle(STYLE_BACKGROUND_COLOR, OPA_TRANSPARENT);\r
+ Add(label);\r
+ }\r
+\r
+ void HeartRateView::HeartRateLabelDisplay(void)\r
+ {\r
+ LabelInfo PerSecLabel = {PERSEC_HEART_RATE_FONT_SIZE, PERSEC_HEART_RATE_X, PERSEC_HEART_RATE_Y,\r
+ PERSEC_HEART_RATE_WIDTH, PERSEC_HEART_RATE_HEIGHT};\r
+ LabelInfo PerSecTextLabel = {PERSEC_HEART_TEXT_FONT_SIZE, PERSEC_HEART_TEXT_X, PERSEC_HEART_TEXT_Y,\r
+ PERSEC_HEART_TEXT_WIDTH, PERSEC_HEART_TEXT_HEIGHT};\r
+\r
+ LabelInfo topLabel = {HEART_RATE_LIMIT_FONT_SIZE, TOP_TEXT_X, TOP_TEXT_Y, TOP_TEXT_WIDTH, TOP_TEXT_HEIGHT};\r
+ LabelInfo bottomLabel = {HEART_RATE_LIMIT_FONT_SIZE, BOTTOM_TEXT_X, BOTTOM_TEXT_Y, BOTTOM_TEXT_WIDTH,\r
+ BOTTOM_TEXT_HEIGHT};\r
+\r
+ LabelInfo restRateLabel = {REST_HEART_RATE_FONT_SIZE, REST_HEART_RATE_X, REST_HEART_RATE_Y, REST_HEART_RATE_WIDTH,\r
+ REST_HEART_RATE_HEIGHT};\r
+ LabelInfo restRateTextLabel1 = {REST_HEART_TEXT_FONT_SIZE, REST_HEART_TEXT_X1, REST_HEART_TEXT_Y1,\r
+ REST_HEART_TEXT_WIDTH1, REST_HEART_TEXT_HEIGHT1};\r
+ LabelInfo restRateTextLabel2 = {REST_HEART_TEXT_FONT_SIZE, REST_HEART_TEXT_X2, REST_HEART_TEXT_Y2,\r
+ REST_HEART_TEXT_WIDTH2, REST_HEART_TEXT_HEIGHT2};\r
+\r
+ topRate = new UILabel();\r
+ bottomRate = new UILabel();\r
+ ratePerSec = new UILabel();\r
+ ratePerSecText = new UILabel();\r
+ restRate = new UILabel();\r
+ restRateText1 = new UILabel();\r
+ restRateText2 = new UILabel();\r
+\r
+ if (topRate == nullptr || bottomRate == nullptr || ratePerSec == nullptr || ratePerSecText == nullptr ||\r
+ restRate == nullptr || restRateText1 == nullptr || restRateText2 == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateLabelDisplay] new UILabel fail");\r
+ }\r
+\r
+ // 实时心率\r
+ SetLabel(ratePerSec, PerSecLabel);\r
+ SetLabel(ratePerSecText, PerSecTextLabel);\r
+ ratePerSec->SetText("--");\r
+ ratePerSec->SetFont(GILROY_BOLD_FONT, PERSEC_HEART_RATE_FONT_SIZE);\r
+ ratePerSecText->SetText("次/分");\r
+\r
+ // 最高最低心率\r
+ SetLabel(topRate, topLabel);\r
+ SetLabel(bottomRate, bottomLabel);\r
+ topRate->SetText("--");\r
+ bottomRate->SetText("--");\r
+\r
+ // 静息心率\r
+ SetLabel(restRate, restRateLabel);\r
+ SetLabel(restRateText1, restRateTextLabel1);\r
+ SetLabel(restRateText2, restRateTextLabel2);\r
+ restRateText1->SetText("静息");\r
+ restRate->SetText("--");\r
+ restRateText2->SetText("次/分");\r
+ }\r
+\r
+ void HeartRateView::HeartRateCoordinate(void)\r
+ {\r
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateCoordinate start");\r
+ // 坐标图片\r
+ imageViewCoordinate = new UIImageView();\r
+ if (imageViewCoordinate == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateCoordinate] new imageViewCoordinate fail");\r
+ return;\r
+ }\r
+ imageViewCoordinate->SetPosition(ACT_IMAGE_X, ACT_IMAGE_Y);\r
+ imageViewCoordinate->SetWidth(ACT_IMAGE_COOR_WIDTH);\r
+ imageViewCoordinate->SetHeight(ACT_IMAGE_COOR_HEIGHT);\r
+ Add(imageViewCoordinate);\r
+\r
+ // 心电图坐标适配\r
+ chart = new UIChartPolyline();\r
+ if (chart == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateCoordinate] new chart fail");\r
+ return;\r
+ }\r
+ chart->SetPosition(COORDINATE_POINT_X, COORDINATE_POINT_Y);\r
+ chart->SetWidth(COORDINATE_WIDTH);\r
+ chart->SetHeight(COORDINATE_HEIGHT);\r
+ chart->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);\r
+ chart->SetStyle(STYLE_BACKGROUND_OPA, 0);\r
+ chart->SetStyle(STYLE_LINE_WIDTH, 1); // line width\r
+\r
+ UIXAxis &xAxis = chart->GetXAxis();\r
+ UIYAxis &yAxis = chart->GetYAxis();\r
+ xAxis.SetDataRange(0, COORDINATE_WIDTH); // 24小时对应的秒数\r
+ yAxis.SetDataRange(0, COORDINATE_HEIGHT);\r
+ xAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
+ yAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
+ chart->SetGradientOpacity(COORDINATE_GRAD_MIN_OPA, COORDINATE_GRAD_MAX_OPA);\r
+\r
+\r
+ // Point pointArray[5] = {{0, 200}, {1, 70}, {2, 80}, {3, 70}, {4, 43}};\r
+ // dataSerial->AddPoints(pointArray, 5);\r
+ // chart->AddDataSerial(dataSerial);\r
+\r
+ Add(chart);\r
+ }\r
+\r
+ void HeartRateView::InsertTopAndBottomRateImage(void)\r
+ {\r
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::InsertTopAndBottomRateImage start");\r
+ imageViewTop = new UIImageView();\r
+ imageViewBottom = new UIImageView();\r
+ if (imageViewTop == nullptr || imageViewBottom == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[InsertTopAndBottomRateImage] new imageViewTop or imageViewBottom fail");\r
+ return;\r
+ }\r
+ imageViewTop->SetPosition(TOP_IMAGE_X, TOP_IMAGE_Y);\r
+ imageViewTop->SetWidth(TOP_IMAGE_WIDTH);\r
+ imageViewTop->SetHeight(TOP_IMAGE_HEIGHT);\r
+ Add(imageViewTop);\r
+ imageViewBottom->SetPosition(BOTTOM_IMAGE_X, BOTTOM_IMAGE_Y);\r
+ imageViewBottom->SetWidth(BOTTOM_IMAGE_WIDTH);\r
+ imageViewBottom->SetHeight(BOTTOM_IMAGE_HEIGHT);\r
+ Add(imageViewBottom);\r
+ }\r
+\r
+ void HeartRateView::UpdataTopAndBottomRate(void)\r
+ {\r
+ uint16_t bottom, top;\r
+ if (chart == nullptr)\r
+ {\r
+ return;\r
+ }\r
+ if (dataTopAndbottom != nullptr)\r
+ {\r
+ chart->DeleteDataSerial(dataTopAndbottom);\r
+ delete dataTopAndbottom;\r
+ dataTopAndbottom = nullptr;\r
+ }\r
+ dataTopAndbottom = new UIChartDataSerial();\r
+ if (dataTopAndbottom == nullptr)\r
+ {\r
+ return;\r
+ }\r
+ if (dataNume != 1)\r
+ {\r
+ dataTopAndbottom->SetMaxDataCount(dataNume); // number of data points\r
+ dataTopAndbottom->AddPoints(rateDataTmp, dataNume); // number of data points\r
+ }\r
+ else\r
+ {\r
+ Point tmp[NUM_2];\r
+ tmp[0].x = tmp[1].x = rateDataTmp[0].x;\r
+ tmp[0].y = tmp[1].y = rateDataTmp[0].y;\r
+ dataTopAndbottom->SetMaxDataCount(NUM_2); // number of data points\r
+ dataTopAndbottom->AddPoints(tmp, NUM_2); // number of data points\r
+ }\r
+ dataTopAndbottom->SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0)); // 设置透明\r
+ chart->AddDataSerial(dataTopAndbottom);\r
+ chart->Invalidate();\r
+\r
+ UIChartDataSerial::PointStyle pointStyle;\r
+ // 最低心跳\r
+ dataTopAndbottom->EnableBottomPoint(true);\r
+ pointStyle.radius = BOTTOM_RADIUS; // Inner radius\r
+ pointStyle.fillColor = Color::Gray();\r
+ pointStyle.strokeWidth = BOTTOM_STROKE_WIDTH; // border width\r
+ pointStyle.strokeColor = Color::Black();\r
+ dataTopAndbottom->SetBottomPointStyle(pointStyle);\r
+ chart->Invalidate();\r
+\r
+ bottom = dataTopAndbottom->GetValleyData() * ACT_IMAGE_COOR_VALUE / ACT_IMAGE_COOR_PIXELS;\r
+ // 最高心跳\r
+ dataTopAndbottom->EnableTopPoint(true);\r
+ pointStyle.fillColor = Color::Red();\r
+ pointStyle.radius = TOP_RADIUS; // Inner radius\r
+ pointStyle.strokeColor = Color::Black();\r
+ pointStyle.strokeWidth = TOP_STROKE_WIDTH; // border width\r
+ dataTopAndbottom->SetTopPointStyle(pointStyle);\r
+ chart->Invalidate();\r
+\r
+ top = dataTopAndbottom->GetPeakData() * ACT_IMAGE_COOR_VALUE / ACT_IMAGE_COOR_PIXELS;\r
+ if (top <= HEART_RATE_LIMIT_UPPER)\r
+ {\r
+ maxRate = (maxRate >= top) ? maxRate : top;\r
+ }\r
+ if (bottom != 0)\r
+ {\r
+ minRate = (minRate <= bottom) ? minRate : bottom;\r
+ }\r
+ }\r
+\r
+ void HeartRateView::ElectrocardiogramOnePoint(Point *rateData, uint16_t index)\r
+ {\r
+ Point tmp[NUM_2];\r
+\r
+ if (rateData == nullptr || chart == nullptr || index >= HEART_AVE_NUM || serialIndex >= HEART_AVE_NUM)\r
+ {\r
+ return;\r
+ }\r
+\r
+ tmp[0].x = tmp[1].x = rateData[index].x;\r
+ tmp[0].y = tmp[1].y = rateData[index].y;\r
+\r
+ dataSerial[serialIndex] = new UIChartDataSerial();\r
+ if (dataSerial[serialIndex] == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[ElectrocardiogramOnePoint] new dataSerial[%d] fail", serialIndex);\r
+ serialIndex++;\r
+ return;\r
+ }\r
+\r
+ dataSerial[serialIndex]->SetMaxDataCount(HEART_AVE_NUM); // 设置最大显示的像素点\r
+ dataSerial[serialIndex]->AddPoints(tmp, NUM_2);\r
+ dataSerial[serialIndex]->SetLineColor(Color::Red());\r
+ dataSerial[serialIndex]->SetFillColor(Color::Red());\r
+ dataSerial[serialIndex]->EnableGradient(true);\r
+\r
+ chart->AddDataSerial(dataSerial[serialIndex]);\r
+ chart->Invalidate();\r
+ serialIndex++;\r
+ }\r
+\r
+ void HeartRateView::ElectrocardiogramMultiPoint(Point *rateData, uint16_t rateDataNume)\r
+ {\r
+ uint16_t i = 0;\r
+ uint16_t j = 0;\r
+ uint16_t tmp = 1;\r
+ if (rateData == nullptr || chart == nullptr || rateDataNume > HEART_AVE_NUM)\r
+ {\r
+ return;\r
+ }\r
+\r
+ while (i < rateDataNume)\r
+ {\r
+ while ((j + 1 < rateDataNume) && (rateData[j + 1].x - rateData[j].x <= NUM_4))\r
+ { // 15分钟对应的秒数\r
+ tmp++;\r
+ j++;\r
+ }\r
+ if (tmp == 1)\r
+ {\r
+ ElectrocardiogramOnePoint(rateData, i);\r
+ }\r
+ else\r
+ {\r
+ if (serialIndex >= HEART_AVE_NUM)\r
+ {\r
+ return;\r
+ }\r
+ if (serialIndex > 0 && dataSerial[serialIndex - 1] != nullptr && i == 0)\r
+ {\r
+ dataSerial[serialIndex - 1]->AddPoints(rateData + 1, tmp - 1); // number of data points\r
+ chart->Invalidate();\r
+ }\r
+ else\r
+ {\r
+ dataSerial[serialIndex] = new UIChartDataSerial();\r
+ if (dataSerial[serialIndex] == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[ElectrocardiogramMultiPoint] new dataSerial[%d] fail", serialIndex);\r
+ serialIndex++;\r
+ return;\r
+ }\r
+\r
+ dataSerial[serialIndex]->SetMaxDataCount(HEART_AVE_NUM); // number of data points\r
+ dataSerial[serialIndex]->AddPoints(rateData + i, tmp); // number of data points\r
+ dataSerial[serialIndex]->SetLineColor(Color::Red());\r
+ dataSerial[serialIndex]->SetFillColor(Color::Red());\r
+ dataSerial[serialIndex]->EnableGradient(true);\r
+\r
+ chart->AddDataSerial(dataSerial[serialIndex]);\r
+ chart->Invalidate();\r
+ serialIndex++;\r
+ }\r
+ }\r
+ i += tmp;\r
+ j = i;\r
+ tmp = 1;\r
+ }\r
+ }\r
+\r
+ void HeartRateView::HeartRateElectrocardiogram(void)\r
+ {\r
+ if (dataNume == 0)\r
+ {\r
+ return;\r
+ }\r
+ serialIndex = 0;\r
+ if (dataNume != 1)\r
+ {\r
+ ElectrocardiogramMultiPoint(rateDataTmp, dataNume); // 多个点\r
+ }\r
+ else\r
+ {\r
+ ElectrocardiogramOnePoint(rateDataTmp, 0); // 一个点\r
+ }\r
+ currIndex = dataNume;\r
+ }\r
+\r
+ void HeartRateView::HeartbeatImageAnimator()\r
+ {\r
+ imageAnimator = new UIImageAnimatorView();\r
+ if (imageAnimator == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartbeatImageAnimator] new imageAnimator fail");\r
+ return;\r
+ }\r
+ imageAnimator->SetPosition(HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT);\r
+ imageAnimator->SetImageAnimatorSrc(g_heartBeatImageInfo, HEARTBEAT_IMAGE_NUM, HEARTBEAT_DELAY);\r
+ imageAnimator->SetRepeat(true);\r
+ Add(imageAnimator);\r
+ imageAnimator->Start();\r
+ }\r
+\r
+ void HeartRateView::HeartbeatImageAnimatorStart(void)\r
+ {\r
+ if (imageAnimator != nullptr)\r
+ {\r
+ imageAnimator->Start();\r
+ }\r
+ }\r
+\r
+ void HeartRateView::HeartbeatImageAnimatorStop(void)\r
+ {\r
+ if (imageAnimator != nullptr)\r
+ {\r
+ imageAnimator->Stop();\r
+ }\r
+ }\r
+\r
+ bool HeartRateView::InitView(void)\r
+ {\r
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::InitView");\r
+ HeartRateDataProc();\r
+ HeartRateLabelDisplay();\r
+ HeartbeatImageAnimator();\r
+ HeartRateCoordinate();\r
+ InsertTopAndBottomRateImage();\r
+ HeartRateElectrocardiogram();\r
+ UpdataTopAndBottomRate();\r
+ // HeartbeatImageAnimatorStop(); 进入界面进行 动画播放\r
+ InitRefreshInterface();\r
+ return true;\r
+ }\r
+\r
+ /*预加载心率图片资源*/\r
+ void HeartRateView::PreLoadHeartRateImageRes(void)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::PreLoadHeartRateImageRes");\r
+ if (!resLoadStatus)\r
+ {\r
+ /*心率背景图*/\r
+ ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewTop, HEART_RATE_TOP);\r
+ ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewBottom, HEART_RATE_BOTTOM);\r
+ ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewCoordinate, HEART_RATE_COOR);\r
+ resLoadStatus = true;\r
+ }\r
+ }\r
+\r
+ /*卸载心率图片资源*/\r
+ void HeartRateView::UnLoadHeartRateImageRes(void)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::UnLoadHeartRateImageRes");\r
+ if (resLoadStatus)\r
+ {\r
+ ImageInfo *img = nullptr;\r
+ imageViewTop->SetSrc(img);\r
+ imageViewBottom->SetSrc(img);\r
+ imageViewCoordinate->SetSrc(img);\r
+ // ImageCacheManager::GetInstance().UnloadAllInMultiRes(HEART_IAMGES);\r
+ ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_RATE_TOP, HEART_IAMGES);\r
+ ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_RATE_BOTTOM, HEART_IAMGES);\r
+ ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_RATE_COOR, HEART_IAMGES);\r
+ resLoadStatus = false;\r
+ }\r
+ }\r
+\r
+ void HeartRateView::PreLoad(void)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::PreLoad");\r
+ if (!viewiInitStatus)\r
+ {\r
+ if (InitView())\r
+ {\r
+ viewiInitStatus = true;\r
+ }\r
+ }\r
+ PreLoadHeartRateImageRes();\r
+ }\r
+\r
+ void HeartRateView::UnLoad(void)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::UnLoad");\r
+ UnLoadHeartRateImageRes();\r
+ }\r
+\r
+ void HeartRateView::InitRefreshInterface(void)\r
+ {\r
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView::InitRefreshInterface");\r
+\r
+ Point *rateData = HeartModel::GetInstance()->GetAveHeartRate();\r
+ uint16_t len = HeartModel::GetInstance()->GetAveHeartRateCount();\r
+ SetHeartRateData(rateData, sizeof(Point) * len);\r
+ // 展示最大,最小,最近一次心率\r
+ uint16_t maxRate = HeartModel::GetInstance()->GetHeartRateMax();\r
+ uint16_t minRate = HeartModel::GetInstance()->GetHeartRateMin();\r
+ uint16_t perRate = HeartModel::GetInstance()->GetHeartdata();\r
+ RefreshElectrocardiogram();\r
+ if (maxRate > 0 && maxRate < HEART_RATE_LIMIT_UPPER)\r
+ {\r
+ RefreshHeartRateMax(HeartModel::GetInstance()->GetHeartRateMax());\r
+ }\r
+ if (minRate > 0 && minRate < HEART_RATE_LIMIT_UPPER)\r
+ {\r
+ RefreshHeartRateMin(HeartModel::GetInstance()->GetHeartRateMin());\r
+ }\r
+ if (perRate > 0 && perRate < HEART_RATE_LIMIT_UPPER)\r
+ {\r
+ HeartModel::GetInstance()->SetHeartRatePerSec(perRate);\r
+ }\r
+ }\r
+\r
+ // 刷新心率曲线\r
+ void HeartRateView::RefreshElectrocardiogram(void)\r
+ {\r
+ int32_t ret;\r
+ uint16_t tmp, count;\r
+ Point *rate = nullptr;\r
+ Point modPoint;\r
+\r
+ ret = HeartRateDataProc();\r
+ if (ret != OHOS_SUCCESS)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[RefreshElectrocardiogram()] fail");\r
+ return;\r
+ }\r
+ rate = rateDataTmp;\r
+\r
+ if (chart == nullptr)\r
+ {\r
+ return;\r
+ }\r
+\r
+ if (currIndex >= HEART_AVE_NUM)\r
+ {\r
+ currIndex = HEART_AVE_NUM;\r
+ }\r
+ if (dataNume > currIndex)\r
+ {\r
+ tmp = dataNume - currIndex;\r
+ if (currIndex > 0)\r
+ {\r
+ rate += (currIndex - 1);\r
+ tmp += 1;\r
+ }\r
+ ElectrocardiogramMultiPoint(rate, tmp);\r
+ currIndex = dataNume;\r
+ }\r
+ else if (dataNume == currIndex)\r
+ { // 当前点平均心率刷新\r
+ if (serialIndex > 0 && serialIndex <= HEART_AVE_NUM && dataSerial[serialIndex - 1] != nullptr)\r
+ {\r
+ modPoint.x = rate[currIndex - 1].x;\r
+ modPoint.y = rate[currIndex - 1].y;\r
+\r
+ count = dataSerial[serialIndex - 1]->GetDataCount();\r
+ dataSerial[serialIndex - 1]->ModifyPoint(count - 1, modPoint);\r
+ chart->Invalidate();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ return;\r
+ }\r
+ UpdataTopAndBottomRate(); // 最高、最低心率\r
+ }\r
+\r
+ // 清空心率曲线\r
+ void HeartRateView::ClearElectrocardiogram(void)\r
+ {\r
+ int32_t i;\r
+ dataNume = 0;\r
+ currIndex = 0;\r
+ maxRate = 0;\r
+ minRate = HEART_RATE_LIMIT_UPPER;\r
+ InitHeartRateData();\r
+\r
+ if (chart == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "chart == nullptr");\r
+ return;\r
+ }\r
+\r
+ if (ratePerSec != nullptr && topRate != nullptr && bottomRate != nullptr && restRate != nullptr)\r
+ {\r
+ ratePerSec->SetText("--");\r
+ topRate->SetText("--");\r
+ bottomRate->SetText("--");\r
+ restRate->SetText("--");\r
+ }\r
+\r
+ chart->DeleteDataSerial(dataTopAndbottom);\r
+ delete dataTopAndbottom;\r
+ dataTopAndbottom = nullptr;\r
+ for (i = 0; i < serialIndex; i++)\r
+ {\r
+ delete dataSerial[i];\r
+ dataSerial[i] = nullptr;\r
+ }\r
+ chart->ClearDataSerial();\r
+\r
+ serialIndex = 0;\r
+ chart->Invalidate();\r
+ }\r
+\r
+ // 刷新每秒上报的心率\r
+ void HeartRateView::RefreshHeartRatePerSec(uint16_t value)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView %d", value);\r
+\r
+ char heartRate[NUM_4] = "--";\r
+ int32_t ret = 0;\r
+\r
+ if (ratePerSec == nullptr)\r
+ {\r
+ return;\r
+ }\r
+ HeartbeatImageAnimatorStart(); // 界面创建实现动画跳动\r
+ if (value == 0)\r
+ {\r
+ ratePerSec->SetText("--");\r
+ // HeartbeatImageAnimatorStop();\r
+ return;\r
+ }\r
+ // HeartbeatImageAnimatorStart();\r
+ if (value > NUM_99)\r
+ {\r
+ ret = sprintf_s(heartRate, sizeof(heartRate), "%u", value);\r
+ }\r
+ else\r
+ {\r
+ ret = sprintf_s(heartRate, sizeof(heartRate), " %u", value);\r
+ }\r
+ if (ret > EOK)\r
+ {\r
+ ratePerSec->SetText(heartRate);\r
+ }\r
+ }\r
+\r
+ // 刷新最大心率\r
+ void HeartRateView::RefreshHeartRateMax(uint16_t max)\r
+ {\r
+ char top[NUM_4] = "--";\r
+ int32_t ret = 0;\r
+ maxRate = (maxRate >= max) ? maxRate : max;\r
+ if (topRate == nullptr)\r
+ {\r
+ return;\r
+ }\r
+ if (maxRate <= HEART_RATE_LIMIT_LOWER)\r
+ {\r
+ topRate->SetText("--");\r
+ return;\r
+ }\r
+ ret = sprintf_s(top, sizeof(top), "%u", maxRate);\r
+ if (ret > EOK)\r
+ {\r
+ topRate->SetText(top);\r
+ }\r
+ }\r
+\r
+ // 刷新最小心率\r
+ void HeartRateView::RefreshHeartRateMin(uint16_t min)\r
+ {\r
+ char bottom[NUM_4] = "--";\r
+ int32_t ret = 0;\r
+\r
+ minRate = (minRate <= min) ? minRate : min;\r
+ if (bottomRate == nullptr)\r
+ {\r
+ return;\r
+ }\r
+ if (minRate >= HEART_RATE_LIMIT_UPPER)\r
+ {\r
+ bottomRate->SetText("--");\r
+ return;\r
+ }\r
+ ret = sprintf_s(bottom, sizeof(bottom), "%u", minRate);\r
+ if (ret > EOK)\r
+ {\r
+ bottomRate->SetText(bottom);\r
+ }\r
+ }\r
+\r
+ // 刷新静息心率\r
+ void HeartRateView::RefreshRestHeartRate(uint16_t value)\r
+ {\r
+ char heartRate[NUM_4] = "--";\r
+ int32_t ret = 0;\r
+\r
+ if (restRate == nullptr)\r
+ {\r
+ return;\r
+ }\r
+\r
+ if (value == 0 || value == (uint16_t)0xFFFF)\r
+ {\r
+ // 无效值\r
+ restRate->SetText("--");\r
+ }\r
+ else\r
+ {\r
+ if (value > NUM_99)\r
+ {\r
+ ret = sprintf_s(heartRate, sizeof(heartRate), "%u", value);\r
+ }\r
+ else\r
+ {\r
+ ret = sprintf_s(heartRate, sizeof(heartRate), " %u", value);\r
+ }\r
+\r
+ if (ret > EOK)\r
+ {\r
+ restRate->SetText(heartRate);\r
+ }\r
+ }\r
+ }\r
+#if 0\r
+#ifdef __cplusplus\r
+ extern "C"\r
+ {\r
+#endif\r
+ /* 定时器回调函数 */\r
+ void HeartTimerCallback()\r
+ {\r
+ g_motionTimes++;\r
+ HeartCardPresenter *gHeartCardPresenter = HeartPresenter::GetInstance();\r
+ if (gHeartCardPresenter == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartTimerCallback::gHeartCardPresenter new fail");\r
+ return;\r
+ }\r
+ // gHeartCardPresenter->ModifiesTime();\r
+ // PRINT("HeartTimerCallback\r\n");\r
+ }\r
+\r
+ /* 开启定时器 */\r
+ void InitTimer(void)\r
+ {\r
+ if (g_startCounting != NULL)\r
+ {\r
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartModel::HeartTimer already exists!!");\r
+ return;\r
+ }\r
+ g_startCounting = osTimerNew((osTimerFunc_t)HeartTimerCallback, osTimerPeriodic, NULL, NULL);\r
+ if (g_startCounting == NULL)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartModel::HeartTimer osTimerNew failed!!");\r
+ return;\r
+ }\r
+ int tick = osMs2Tick(MS_ONE_SECONDS);\r
+ osStatus_t retTimer = osTimerStart(g_startCounting, tick);\r
+ if (retTimer != osOK)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartModel::HeartTimer osTimerStart failed, ret = %lx!!", retTimer);\r
+ if (g_startCounting != NULL)\r
+ {\r
+ retTimer = osTimerDelete(g_startCounting);\r
+ if (retTimer != osOK)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartModel::osTimerDelete failed, ret = %lx!!", retTimer);\r
+ return;\r
+ }\r
+ g_startCounting = NULL;\r
+ }\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitTimer!");\r
+ return;\r
+ }\r
+ }\r
+ /* 关闭定时器 */\r
+ void DisableTimer(void)\r
+ {\r
+ if (g_startCounting != NULL)\r
+ {\r
+ osStatus_t ret = osTimerDelete(g_startCounting);\r
+ if (ret != osOK)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ScanTimerCallback osTimerDelete failed, ret = %lx!!", ret);\r
+ return;\r
+ }\r
+ g_startCounting = NULL;\r
+ PRINT("g_motionTimes:%d\r\n", sportdata->duration);\r
+ g_motionTimes = 0;\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DisableTimer!");\r
+ }\r
+ }\r
+ /* 暂停定时器 */\r
+ void PauseTimer(void)\r
+ {\r
+ // 检查定时器是否存在\r
+ if (g_startCounting != NULL)\r
+ {\r
+ // 暂停定时器,但不删除它\r
+ osStatus_t ret = osTimerStop(g_startCounting);\r
+ if (ret != osOK)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopWatch_PauseTimer osTimerStop failed, ret = %lx!!", ret);\r
+ }\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PauseTimer!");\r
+ }\r
+ }\r
+\r
+ /*恢复定时器*/\r
+ void ResumeTimer(void)\r
+ {\r
+ // 检查定时器是否存在\r
+ if (g_startCounting != NULL)\r
+ {\r
+ int tick = osMs2Tick(MS_ONE_SECONDS);\r
+ // 恢复定时器\r
+ osStatus_t ret = osTimerStart(g_startCounting, tick);\r
+ if (ret != osOK)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ResumeTimer osTimerStart failed, ret = %lx!!", ret);\r
+ }\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ResumeTimer!");\r
+ }\r
+ }\r
+\r
+#ifdef __cplusplus\r
+ }\r
+#endif\r
+#endif\r
+} // namespace OHOS
\ No newline at end of file