1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ui_test_chart_polyline.h"
17 
18 #include "common/screen.h"
19 
20 namespace OHOS {
21 namespace {
22 static int16_t g_blank = 20;
23 static int32_t g_curSerialCount = 0;
24 static int32_t g_curArrayCount = 0;
25 static bool g_secondScreenFlag = false;
26 static bool g_addPointsFlag = false;
27 static bool g_hidePointsFlag = false;
28 } // namespace
29 
SetUp()30 void UITestChartPolyline::SetUp()
31 {
32     if (container_ == nullptr) {
33         container_ = new UIScrollView();
34         container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT);
35         container_->SetHorizontalScrollState(false);
36         container_->SetThrowDrag(true);
37     }
38 
39     dataSerial_[0] = new UIChartDataSerial();
40     dataSerial_[0]->SetMaxDataCount(5); // 5: number of data points
41     Point pointArray[5] = {{0, 2478}, {1, 2600}, {2, 3000}, {3, 3200}, {4, 3500}};
42     dataSerial_[0]->AddPoints(pointArray, 5); // 5: number of data points
43     dataSerial_[0]->SetLineColor(Color::Red());
44     dataSerial_[0]->SetFillColor(Color::Red());
45     dataSerial_[0]->EnableGradient(true);
46 
47     dataSerial_[1] = new UIChartDataSerial();
48     dataSerial_[1]->SetMaxDataCount(5); // 5: number of data points
49     Point pointArray1[5] = {{0, 2000}, {1, 0}, {2, 800}, {3, 700}, {4, 433}};
50     dataSerial_[1]->AddPoints(pointArray1, 5); // 5: number of data points
51     dataSerial_[1]->SetLineColor(Color::Green());
52     dataSerial_[1]->SetFillColor(Color::Green());
53     dataSerial_[1]->EnableGradient(true);
54 
55     dataSerial_[2] = new UIChartDataSerial(); // 2: array index
56     dataSerial_[2]->SetMaxDataCount(5);       // 2: array index, 5: number of data points
57     Point pointArray2[5] = {{0, 100}, {1, 200}, {2, 300}, {3, 400}, {4, 500}};
58     dataSerial_[2]->AddPoints(pointArray2, 5);   // 2: array index, 5: number of data points
59     dataSerial_[2]->SetLineColor(Color::Blue()); // 2: array index
60     curDataIndex_ = 0;
61 }
62 
InnerDeleteChildren(UIView * view) const63 void UITestChartPolyline::InnerDeleteChildren(UIView* view) const
64 {
65     if (view == nullptr) {
66         return;
67     }
68     while (view != nullptr) {
69         UIView* tempView = view;
70         view = view->GetNextSibling();
71         if (tempView->IsViewGroup()) {
72             InnerDeleteChildren(static_cast<UIViewGroup*>(tempView)->GetChildrenHead());
73         }
74         if (tempView->GetViewType() == UI_AXIS) {
75             return;
76         }
77         if (tempView->GetParent()) {
78             static_cast<UIViewGroup*>(tempView->GetParent())->Remove(tempView);
79         }
80         delete tempView;
81     }
82 }
83 
TearDown()84 void UITestChartPolyline::TearDown()
85 {
86     ECGAnimator_->Stop();
87     delete ECGAnimator_;
88     ECGAnimator_ = nullptr;
89     chart_->ClearDataSerial();
90     for (uint8_t i = 0; i < DATA_NUM; i++) {
91         delete dataSerial_[i];
92         dataSerial_[i] = nullptr;
93     }
94     InnerDeleteChildren(container_);
95     container_ = nullptr;
96     lastX_ = 0;
97     lastY_ = 0;
98     positionX_ = 0;
99     positionY_ = 0;
100     g_curSerialCount = 0;
101     g_curArrayCount = 0;
102     g_secondScreenFlag = false;
103     g_addPointsFlag = false;
104     g_hidePointsFlag = false;
105 }
106 
GetTestView()107 const UIView* UITestChartPolyline::GetTestView()
108 {
109     UIKitChartPolylineTestAddDataSerial001();
110     UIKitChartPolylineTestEnableReverse002();
111     UIKitChartPolylineTestSetGradientBottom003();
112     UIKitChartPolylineTestAddPoints004();
113 
114     return container_;
115 }
116 
UIKitChartPolylineTestAddDataSerial001()117 void UITestChartPolyline::UIKitChartPolylineTestAddDataSerial001()
118 {
119     UILabel* label = new UILabel();
120     container_->Add(label);
121     lastY_ = TEXT_DISTANCE_TO_TOP_SIDE;
122     // 29: label height
123     label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, lastY_, Screen::GetInstance().GetWidth(), 29);
124     label->SetText("chart添加、删除数据串 ");
125     label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE);
126 
127     chart_ = new UIChartPolyline();
128     chart_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE);
129     chart_->SetWidth(454);  // 454: width
130     chart_->SetHeight(250); // 250: height
131 
132     UIXAxis& xAxis = chart_->GetXAxis();
133     UIYAxis& yAxis = chart_->GetYAxis();
134     xAxis.SetMarkNum(5);         // 5: number of scales
135     xAxis.SetDataRange(0, 5);    // 0: minimum value, 5: maximum value
136     yAxis.SetDataRange(0, 5000); // 0: minimum value, 5000: maximum value
137 
138     chart_->SetGradientOpacity(25, 127); // 25: min opacity, 127: max opacity
139     chart_->AddDataSerial(dataSerial_[0]);
140     curDataIndex_++;
141     container_->Add(chart_);
142     SetLastPos(chart_);
143 
144     addDataSerialBtn_ = new UILabelButton();
145     deleteDataSerialBtn_ = new UILabelButton();
146     clearDataSerialBtn_ = new UILabelButton();
147     topPointBtn_ = new UILabelButton();
148     bottomPointBtn_ = new UILabelButton();
149     headPointBtn_ = new UILabelButton();
150 
151     positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE;
152     positionY_ = lastY_ + 10; // 10: increase y-coordinate
153     SetUpButton(addDataSerialBtn_, "添加数据 ", UI_TEST_POLYLINE_ADD_DATA);
154     positionX_ = addDataSerialBtn_->GetX() + addDataSerialBtn_->GetWidth() + g_blank;
155     positionY_ = addDataSerialBtn_->GetY();
156     SetUpButton(deleteDataSerialBtn_, "删除数据 ", UI_TEST_POLYLINE_DELETE_DATA);
157     positionX_ = deleteDataSerialBtn_->GetX() + deleteDataSerialBtn_->GetWidth() + g_blank;
158     positionY_ = deleteDataSerialBtn_->GetY();
159     SetUpButton(clearDataSerialBtn_, "清空数据 ", UI_TEST_POLYLINE_CLEAR_DATA);
160 
161     positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE;
162     SetUpButton(topPointBtn_, "最高点 ", UI_TEST_POLYLINE_HIGHESET_POINT);
163     positionX_ = topPointBtn_->GetX() + topPointBtn_->GetWidth() + g_blank;
164     positionY_ = topPointBtn_->GetY();
165     SetUpButton(bottomPointBtn_, "最低点 ", UI_TEST_POLYLINE_LOWEST_POINT);
166     positionX_ = bottomPointBtn_->GetX() + bottomPointBtn_->GetWidth() + g_blank;
167     positionY_ = bottomPointBtn_->GetY();
168     SetUpButton(headPointBtn_, "最新点 ", UI_TEST_POLYLINE_NEW_POINT);
169 }
170 
UIKitChartPolylineTestEnableReverse002()171 void UITestChartPolyline::UIKitChartPolylineTestEnableReverse002()
172 {
173     reverseBtn_ = new UILabelButton();
174     positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE;
175     SetUpButton(reverseBtn_, "翻转 ", UI_TEST_POLYLINE_FLIP);
176     SetLastPos(reverseBtn_);
177 }
178 
UIKitChartPolylineTestSetGradientBottom003()179 void UITestChartPolyline::UIKitChartPolylineTestSetGradientBottom003()
180 {
181     gradientBottomBtn_ = new UILabelButton();
182     positionX_ = reverseBtn_->GetX() + reverseBtn_->GetWidth() + g_blank;
183     positionY_ = reverseBtn_->GetY();
184     SetUpButton(gradientBottomBtn_, "填充底部位置 ", UI_TEST_POLYLINE_FILL_BOTTOM);
185     SetLastPos(gradientBottomBtn_);
186 }
187 namespace {
188 const int16_t DATA_COUNT = 480;
189 }
190 /* ECG test data */
191 static int16_t g_ECGData[DATA_COUNT] = {
192     68, 70, 73, 83, 95,  107, 118, 127, 118, 103, 90, 77, 66, 61, 57,  58,  60,  61,  62,  62, 63, 64, 64, 65, 67, 69,
193     70, 71, 73, 75, 76,  78,  78,  79,  80,  80,  80, 80, 80, 80, 79,  78,  77,  76,  75,  73, 72, 71, 70, 70, 70, 70,
194     70, 70, 70, 70, 71,  71,  71,  71,  71,  71,  72, 72, 72, 72, 73,  73,  73,  73,  74,  74, 74, 74, 75, 75, 75, 75,
195     75, 75, 75, 75, 74,  74,  74,  74,  74,  74,  74, 73, 73, 73, 73,  73,  73,  73,  73,  73, 73, 73, 73, 73, 72, 71,
196     71, 71, 70, 70, 70,  70,  71,  73,  75,  78,  80, 81, 82, 82, 82,  80,  78,  76,  73,  71, 69, 69, 68, 68, 68, 68,
197     68, 70, 76, 88, 100, 111, 122, 126, 112, 98,  85, 73, 61, 58, 57,  59,  60,  61,  62,  62, 63, 64, 65, 66, 68, 69,
198     70, 72, 74, 76, 77,  78,  79,  79,  80,  80,  80, 80, 79, 79, 79,  78,  77,  76,  74,  73, 72, 71, 70, 70, 70, 70,
199     70, 70, 70, 71, 71,  71,  71,  71,  71,  72,  72, 72, 72, 73, 73,  73,  73,  74,  74,  74, 74, 74, 75, 75, 75, 75,
200     75, 75, 75, 75, 74,  74,  74,  74,  74,  74,  73, 73, 73, 73, 73,  73,  73,  73,  73,  73, 73, 73, 73, 72, 72, 71,
201     71, 70, 70, 69, 70,  70,  72,  74,  76,  78,  80, 82, 82, 82, 81,  79,  77,  75,  72,  70, 69, 68, 68, 68, 68, 68,
202     69, 72, 80, 93, 104, 115, 126, 121, 106, 93,  80, 68, 59, 57, 58,  60,  61,  62,  62,  63, 63, 64, 65, 67, 68, 70,
203     71, 73, 75, 76, 77,  78,  79,  80,  80,  80,  80, 80, 79, 79, 78,  78,  76,  75,  74,  72, 71, 70, 70, 70, 70, 70,
204     70, 70, 70, 71, 71,  71,  71,  71,  71,  72,  72, 72, 73, 73, 73,  73,  74,  74,  74,  74, 74, 75, 75, 75, 75, 75,
205     75, 75, 75, 75, 74,  74,  74,  74,  74,  73,  73, 73, 73, 73, 73,  73,  73,  73,  73,  73, 73, 73, 73, 72, 72, 71,
206     71, 70, 70, 69, 70,  71,  72,  75,  77,  79,  81, 82, 82, 82, 80,  79,  76,  74,  71,  70, 69, 68, 68, 68, 68, 69,
207     70, 75, 85, 97, 109, 120, 127, 115, 101, 88,  75, 64, 57, 56, 58,  60,  61,  62,  62,  63, 64, 65, 66, 67, 69, 71,
208     72, 74, 75, 77, 78,  79,  79,  80,  80,  80,  80, 80, 79, 79, 78,  77,  76,  74,  73,  72, 71, 70, 70, 70, 70, 70,
209     70, 70, 71, 71, 71,  71,  71,  71,  72,  72,  72, 72, 80, 93, 104, 115, 126, 121, 106, 93, 80, 68, 59, 57, 58, 60,
210     61, 62, 62, 63, 63,  64,  65,  67,  68,  70,  71, 73};
211 
212 class ImageAnimatorCallbackDemo : public OHOS::AnimatorCallback {
213 public:
ImageAnimatorCallbackDemo(UIChartDataSerial * serial)214     explicit ImageAnimatorCallbackDemo(UIChartDataSerial* serial) : times_(0), serial_(serial) {}
215 
~ImageAnimatorCallbackDemo()216     ~ImageAnimatorCallbackDemo() {}
217 
Callback(UIView * view)218     virtual void Callback(UIView* view)
219     {
220         if (view == nullptr) {
221             return;
222         }
223         if (!g_addPointsFlag) {
224             return; /* Control the addition of points by button, and automate if commented out */
225         }
226         if (times_++ != 6) { /* Add 10 points for every 6 ticks */
227             return;
228         }
229         times_ = 0;
230         if (g_curSerialCount == 0) {
231             view->Invalidate();
232         }
233         Point pointArray1[10];
234         for (uint16_t i = 0; i < 10; i++) { // 10: array max index
235             pointArray1[i].x = g_curSerialCount;
236             pointArray1[i].y = g_ECGData[g_curArrayCount];
237             g_curSerialCount++;
238             g_curArrayCount++;
239             if (g_curArrayCount == DATA_COUNT) {
240                 g_curArrayCount = 0;
241             }
242             if (!g_secondScreenFlag) {
243                 serial_->AddPoints(&pointArray1[i], 1);
244             } else {
245                 serial_->ModifyPoint(g_curSerialCount, pointArray1[i]);
246                 if (g_hidePointsFlag) {
247                     serial_->HidePoint(g_curSerialCount, 30); // 30: the number of points
248                 }
249             }
250         }
251         if (g_curSerialCount > 454) { // 454: max serial count
252             g_curSerialCount = 0;
253             g_secondScreenFlag = true;
254         }
255 
256         UIChart* chart = static_cast<UIChart*>(view);
257         chart->RefreshChart();
258         g_addPointsFlag = false;
259     }
260 
261 protected:
262     int16_t times_;
263     UIChartDataSerial* serial_;
264 };
265 
UIKitChartPolylineTestAddPoints004()266 void UITestChartPolyline::UIKitChartPolylineTestAddPoints004()
267 {
268     UIViewGroup* uiViewGroup = new UIViewGroup();
269     // 2: x-coordinate, half of screen width; 2: half of screen width; 470: screen height
270     uiViewGroup->SetPosition(Screen::GetInstance().GetWidth() / 2, 0, Screen::GetInstance().GetWidth() / 2, 470);
271     container_->Add(uiViewGroup);
272 
273     UILabel* label = new UILabel();
274     uiViewGroup->Add(label);
275     label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE,
276                        Screen::GetInstance().GetWidth() / 2 - TEXT_DISTANCE_TO_LEFT_SIDE, // 2: half of screen width;
277                        TITLE_LABEL_DEFAULT_HEIGHT);
278     label->SetText("chart追加点、修改点、平滑化");
279     label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE);
280 
281     ECGChart_ = new UIChartPolyline();
282     // 454: new width, 250: new height
283     ECGChart_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE, 454, 250);
284     uiViewGroup->Add(ECGChart_);
285     SetLastPos(ECGChart_);
286     ECGChart_->SetStyle(STYLE_LINE_WIDTH, 5); // 5: line width
287 
288     UIXAxis& xAxis = ECGChart_->GetXAxis();
289     UIYAxis& yAxis = ECGChart_->GetYAxis();
290     xAxis.SetDataRange(0, 454); // 454: maximum value
291     xAxis.SetMarkNum(10);       // 10: number of scales
292     yAxis.SetDataRange(0, 200); // 200: maximum value
293 
294     ECGDataSerial_ = new UIChartDataSerial();
295     ECGDataSerial_->SetMaxDataCount(454); // 454: number of data points
296     ECGDataSerial_->SetLineColor(Color::Red());
297     ECGDataSerial_->EnableHeadPoint(true);
298     ECGChart_->AddDataSerial(ECGDataSerial_);
299     ImageAnimatorCallbackDemo* imageAnimCallback = new ImageAnimatorCallbackDemo(ECGDataSerial_);
300     ECGAnimator_ = new OHOS::Animator(imageAnimCallback, ECGChart_, 0, true);
301     ECGAnimator_->Start();
302 
303     addPointsBtn_ = new UILabelButton();
304     smoothBtn_ = new UILabelButton();
305     hidePointsBtn_ = new UILabelButton();
306 
307     // 2: half of screen width
308     positionX_ = Screen::GetInstance().GetWidth() / 2 + VIEW_DISTANCE_TO_LEFT_SIDE;
309     positionY_ = lastY_ + 10; // 10: increase y-coordinate
310     SetUpButton(addPointsBtn_, "添加点 ", UI_TEST_POLYLINE_ADD_POINT);
311 
312     positionX_ = addPointsBtn_->GetX() + addPointsBtn_->GetWidth() + g_blank;
313     positionY_ = addPointsBtn_->GetY();
314     SetUpButton(smoothBtn_, "平滑化 ", UI_TEST_POLYLINE_SMOOTHING);
315 
316     positionX_ = smoothBtn_->GetX() + smoothBtn_->GetWidth() + g_blank;
317     positionY_ = smoothBtn_->GetY();
318     SetUpButton(hidePointsBtn_, "隐藏点 ", UI_TEST_POLYLINE_HIDE_POINT);
319 }
320 
OnClick(UIView & view,const ClickEvent & event)321 bool UITestChartPolyline::OnClick(UIView& view, const ClickEvent& event)
322 {
323     UIChartDataSerial::PointStyle pointStyle;
324     pointStyle.fillColor = Color::White();
325     pointStyle.radius = 5; // 5: Inner radius
326     pointStyle.strokeColor = Color::Red();
327     pointStyle.strokeWidth = 2; // 2: border width
328 
329     if (&view == addDataSerialBtn_) {
330         if (curDataIndex_ >= DATA_NUM) {
331             return true;
332         }
333         chart_->AddDataSerial(dataSerial_[curDataIndex_]);
334         curDataIndex_++;
335         chart_->Invalidate();
336     } else if (&view == deleteDataSerialBtn_) {
337         if (curDataIndex_ == 0) {
338             return true;
339         }
340         chart_->DeleteDataSerial(dataSerial_[curDataIndex_ - 1]);
341         curDataIndex_--;
342         chart_->Invalidate();
343     } else if (&view == clearDataSerialBtn_) {
344         chart_->ClearDataSerial();
345         curDataIndex_ = 0;
346         chart_->Invalidate();
347     } else if (&view == topPointBtn_) {
348         dataSerial_[0]->EnableTopPoint(true);
349         pointStyle.strokeColor = Color::Red();
350         dataSerial_[0]->SetTopPointStyle(pointStyle);
351         chart_->Invalidate();
352     } else if (&view == bottomPointBtn_) {
353         dataSerial_[0]->EnableBottomPoint(true);
354         pointStyle.strokeColor = Color::Blue();
355         dataSerial_[0]->SetBottomPointStyle(pointStyle);
356         chart_->Invalidate();
357     } else if (&view == headPointBtn_) {
358         dataSerial_[0]->EnableHeadPoint(true);
359         pointStyle.strokeColor = Color::Yellow();
360         dataSerial_[0]->SetHeadPointStyle(pointStyle);
361         chart_->Invalidate();
362     } else if (&view == reverseBtn_) {
363         chart_->EnableReverse(true);
364         chart_->Invalidate();
365     } else {
366         ClickExpand(view, pointStyle);
367     }
368     return true;
369 }
370 
ClickExpand(UIView & view,UIChartDataSerial::PointStyle pointStyle)371 bool UITestChartPolyline::ClickExpand(UIView& view, UIChartDataSerial::PointStyle pointStyle)
372 {
373     if (&view == gradientBottomBtn_) {
374         chart_->SetGradientBottom(50); // 50: bottom of the filling range
375         chart_->Invalidate();
376     } else if (&view == addPointsBtn_) {
377         g_addPointsFlag = true;
378     } else if (&view == smoothBtn_) {
379         ECGDataSerial_->EnableSmooth(true);
380         ECGChart_->Invalidate();
381     } else if (&view == hidePointsBtn_) {
382         g_hidePointsFlag = true;
383     }
384     return true;
385 }
386 
SetUpButton(UILabelButton * btn,const char * title,const char * id)387 void UITestChartPolyline::SetUpButton(UILabelButton* btn, const char* title, const char* id)
388 {
389     if (btn == nullptr || title == nullptr || id == nullptr) {
390         return;
391     }
392     container_->Add(btn);
393     btn->SetPosition(positionX_, positionY_, BUTTON_WIDHT2, BUTTON_HEIGHT2);
394     positionY_ += btn->GetHeight() + 10; // 10: increase height
395     btn->SetText(title);
396     btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE);
397     btn->SetOnClickListener(this);
398     btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED);
399     btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED);
400     btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE);
401     btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED);
402     btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED);
403     btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE);
404     btn->SetViewId(id);
405     container_->Invalidate();
406 }
407 
SetLastPos(UIView * view)408 void UITestChartPolyline::SetLastPos(UIView* view)
409 {
410     if (view == nullptr) {
411         return;
412     }
413     lastX_ = view->GetX();
414     lastY_ = view->GetY() + view->GetHeight();
415 }
416 } // namespace OHOS
417