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  /**
17   * @addtogroup UI_Components
18   * @{
19   *
20   * @brief Defines UI components such as buttons, texts, images, lists, and progress bars.
21   *
22   * @since 1.0
23   * @version 1.0
24   */
25  
26  /**
27   * @file ui_chart.h
28   *
29   * @brief Defines the attributes of the chart component and provides functions for adding and deleting
30   *        data sets to display a chart.
31   *
32   * @since 1.0
33   * @version 1.0
34   */
35  
36  #ifndef GRAPHIC_LITE_UI_CHART_H
37  #define GRAPHIC_LITE_UI_CHART_H
38  
39  #include "components/ui_axis.h"
40  #include "components/ui_view_group.h"
41  #include "gfx_utils/list.h"
42  
43  namespace OHOS {
44  class UIChart;
45  /**
46   * @brief Defines a data set and provides functions such as adding and deleting data points.
47   *
48   * @since 1.0
49   * @version 1.0
50   */
51  class UIChartDataSerial : public HeapBase {
52  public:
53      /**
54       * @brief A constructor used to create a <b>UIChartDataSerial</b> instance.
55       *
56       * @since 1.0
57       * @version 1.0
58       */
59      UIChartDataSerial();
60  
61      /**
62       * @brief A destructor used to delete the <b>UIChartDataSerial</b> instance.
63       *
64       * @since 1.0
65       * @version 1.0
66       */
~UIChartDataSerial()67      virtual ~UIChartDataSerial()
68      {
69          if (pointArray_ != nullptr) {
70              UIFree(pointArray_);
71              pointArray_ = nullptr;
72          }
73      }
74  
75      /**
76       * @brief Sets the maximum number of data points that can be stored in a data set.
77       *
78       * This function must be called before data is added, deleted, or modified. Otherwise, data operations will fail.
79       *
80       * @param maxCount Indicates the number of data points. The default value is <b>0</b>.
81       *
82       * @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
83       * @since 1.0
84       * @version 1.0
85       */
86      bool SetMaxDataCount(uint16_t maxCount);
87  
88      /**
89       * @brief Modifies the value of a data point in the data set.
90       *
91       * @param index Indicates the index of the data point to modify.
92       * @param point Indicates the new value of the data point.
93       *
94       * @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
95       * @since 1.0
96       * @version 1.0
97       */
98      bool ModifyPoint(uint16_t index, const Point& point);
99  
100      /**
101       * @brief Obtains the coordinates in the chart for a data point in the data set.
102       *
103       * @param index Indicates the index of the data point to obtain.
104       * @param point Indicates the obtained coordinates. If the data set is not added to the chart,
105       *              the original value of the data point is printed.
106       *
107       * @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
108       * @since 1.0
109       * @version 1.0
110       */
111      bool GetPoint(uint16_t index, Point& point);
112  
113      /**
114       * @brief Obtains the coordinates in the chart for a original data point in the data set.
115       *
116       * @param index Indicates the index of the data point to obtain.
117       * @param point Indicates the obtained coordinates. the original value of the data point is printed.
118       *
119       * @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
120       */
121      bool GetOriginalPoint(uint16_t index, Point& point);
122  
123      /**
124       * @brief Backup a variable
125       *
126       * @param pointArrayBack Indicates a copy of the variable
127       *
128       * @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
129       */
130      bool PointArrayDup(Point** pointArrayBack);
131  
132      /**
133       * @brief Adds data points.
134       *
135       * The new data points are appended to the last added data. \n
136       * No more data points can be added if the maximum number is reached \n
137       *
138       * @param data  Indicates the pointer to the start address of the data point.
139       * @param count Indicates the number of data points to add.
140       * @return Returns <b>true</b> if the data points are added successfully; returns <b>false</b> otherwise.
141       * @since 1.0
142       * @version 1.0
143       */
144      bool AddPoints(const Point* data, uint16_t count);
145  
146      /**
147       * @brief Clears all data points.
148       *
149       * @since 1.0
150       * @version 1.0
151       */
152      void ClearData();
153  
154      /**
155       * @brief Obtains the number of data points available in the data set.
156       *
157       * @return Returns the number of data points.
158       * @since 1.0
159       * @version 1.0
160       */
GetDataCount()161      uint16_t GetDataCount() const
162      {
163          return dataCount_;
164      }
165  
166      /**
167       * @brief Sets whether to smooth a polyline.
168       *
169       * This function applies only to line charts. After the smoothing, some data is discarded.
170       * Therefore, the polyline does not pass through all data points. \n
171       * If <b>smooth</b> is set to <b>true</b>, the filling color, top point, and bottom point of a line chart have
172       * deviations. Therefore, you are advised not to use these functions at the same time. \n
173       *
174       * @param smooth Specifies whether to smooth a polyline. Value <b>true</b> means to smooth a polyline, and value
175       *               <b>false</b> means not to smooth a polyline. The default value is <b>false</b>.
176       * @since 1.0
177       * @version 1.0
178       */
EnableSmooth(bool smooth)179      void EnableSmooth(bool smooth)
180      {
181          smooth_ = smooth;
182      }
183  
184      /**
185       * @brief Checks whether smoothing is performed on a polyline.
186       *
187       * @return Returns <b>true</b> if smooth processing is performed on the polyline; returns <b>false</b> otherwise.
188       * @since 1.0
189       * @version 1.0
190       */
IsSmooth()191      bool IsSmooth() const
192      {
193          return smooth_;
194      }
195  
196      /**
197       * @brief Enables the fill color of a line chart.
198       *
199       * This function applies only to line charts. By default, the area between the polyline and the x-axis is filled.
200       * You can use {@link SetGradientBottom} to modify the filled region. \n
201       *
202       * @param enable Specifies whether to enable the fill color. Value <b>true</b> means to enable the fill color,
203       *               and value <b>false</b> means to disable the fill color. The default value is <b>false</b>.
204       * @since 1.0
205       * @version 1.0
206       */
EnableGradient(bool enable)207      void EnableGradient(bool enable)
208      {
209          enableGradient_ = enable;
210      }
211  
212      /**
213       * @brief Checks whether a polyline has a fill color.
214       *
215       * @return Returns <b>true</b> if there is a fill color; returns <b>false</b> otherwise.
216       * @since 1.0
217       * @version 1.0
218       */
IsGradient()219      bool IsGradient() const
220      {
221          return enableGradient_;
222      }
223  
224      /**
225       * @brief Obtains the index of the top point in the data set.
226       *
227       * @return Returns the index of the top point. If there are multiple top points, the first one is returned.
228       * @since 1.0
229       * @version 1.0
230       */
GetPeakIndex()231      uint16_t GetPeakIndex() const
232      {
233          return peakPointIndex_;
234      }
235  
236      /**
237       * @brief Obtains the index of the frontmost point (the latest added or modified data point in a data set).
238       *
239       * @return Returns the index of the frontmost point.
240       * @since 1.0
241       * @version 1.0
242       */
GetLatestIndex()243      uint16_t GetLatestIndex() const
244      {
245          return latestIndex_;
246      }
247  
248      /**
249       * @brief Obtains the index of the bottom point in a data set.
250       *
251       * @return Returns the index of the bottom point. If there are multiple bottom points, the first one is returned.
252       * @since 1.0
253       * @version 1.0
254       */
GetValleyIndex()255      uint16_t GetValleyIndex() const
256      {
257          return valleyPointIndex_;
258      }
259  
260      /**
261       * @brief Obtains the Y value of the top point in a data set.
262       *
263       * The Y value is the data added by users, not the pixel coordinate.
264       *
265       * @return Returns the Y value.
266       * @since 1.0
267       * @version 1.0
268       */
GetPeakData()269      int16_t GetPeakData() const
270      {
271          return peakData_;
272      }
273  
274      /**
275       * @brief Obtains the Y value of the bottom point in a data set.
276       *
277       * The Y value is the data added by users, not the pixel coordinate.
278       *
279       * @return Returns the Y value.
280       * @since 1.0
281       * @version 1.0
282       */
GetValleyData()283      int16_t GetValleyData() const
284      {
285          return valleyData_;
286      }
287  
SetLastPointIndex(uint16_t value)288      void SetLastPointIndex(uint16_t value)
289      {
290          lastPointIndex_ = value;
291      }
292  
GetLastPointIndex()293      uint16_t GetLastPointIndex() const
294      {
295          return lastPointIndex_;
296      }
297  
298      /**
299       * @brief Obtains the polyline color of the data set in a line chart.
300       *
301       * @return Returns the polyline color of the data set.
302       * @see SetLineColor
303       * @since 1.0
304       * @version 1.0
305       */
GetLineColor()306      ColorType GetLineColor() const
307      {
308          return serialColor_;
309      }
310  
311      /**
312       * @brief Obtains the fill color of the data set.
313       *
314       * @return Returns the fill color.
315       * @see SetFillColor
316       * @since 1.0
317       * @version 1.0
318       */
GetFillColor()319      ColorType GetFillColor() const
320      {
321          return fillColor_;
322      }
323  
324      /**
325       * @brief Sets the fill color of the data set.
326       *
327       * For a line chart, <b>color</b> refers to the fill color between the line and the x-axis.
328       * For a bar chart, <b>color</b> refers to the color of the bars.
329       *
330       * @param color Indicates the fill color to set.
331       * @see GetFillColor
332       * @since 1.0
333       * @version 1.0
334       */
SetFillColor(const ColorType & color)335      void SetFillColor(const ColorType& color)
336      {
337          fillColor_ = color;
338      }
339  
340      /**
341       * @brief Sets the polyline color of the data set in the line chart.
342       *
343       * This function applies only to line charts.
344       *
345       * @param color Indicates the polyline color to set.
346       * @see GetLineColor
347       * @since 1.0
348       * @version 1.0
349       */
SetLineColor(const ColorType & color)350      void SetLineColor(const ColorType& color)
351      {
352          serialColor_ = color;
353      }
354  
BindToChart(UIChart * chart)355      void BindToChart(UIChart* chart)
356      {
357          chart_ = chart;
358      }
359  
360      /**
361       * @brief Hides some points in the data set.
362       *
363       * This function applies only to line charts. After the points are hidden, the line connected by the points
364       * is not displayed. \n
365       * The top and bottom points may appear in the hidden region. If this method is enabled,
366       * you are not advised to enable the display of the top and bottom points.
367       *
368       * @param index Indicates the point from which the hide starts.
369       * @param count Indicates the number of points to hide.
370       * @since 1.0
371       * @version 1.0
372       */
373      void HidePoint(uint16_t index, uint16_t count);
374  
375      /**
376       * @brief Obtains the index from which the data set starts to hide.
377       *
378       * @return Returns the index.
379       * @see HidePoint
380       * @since 1.0
381       * @version 1.0
382       */
GetHideIndex()383      uint16_t GetHideIndex() const
384      {
385          return hideIndex_;
386      }
387  
388      /**
389       * @brief Obtains the number of hidden points in the data set.
390       *
391       * @return Returns the number of hidden points.
392       * @see HidePoint
393       * @since 1.0
394       * @version 1.0
395       */
GetHideCount()396      uint16_t GetHideCount() const
397      {
398          return hideCount_;
399      }
400  
401      /**
402       * @brief Defines the style for the top, bottom, and frontmost points in a line chart.
403       */
404      struct PointStyle : public HeapBase {
405          /** Fill color */
406          ColorType fillColor;
407          /** Border color */
408          ColorType strokeColor;
409          /** Inner radius */
410          uint16_t radius;
411          /** Border width, which extends outwards from the inner radius */
412          uint16_t strokeWidth;
413      };
414  
415      /**
416       * @brief Sets the style of the frontmost point on a polyline.
417       *
418       * @param style Indicates the style to set. For details, see {@link PointStyle}.
419       * @since 1.0
420       * @version 1.0
421       */
SetHeadPointStyle(const PointStyle & style)422      void SetHeadPointStyle(const PointStyle& style)
423      {
424          headPointStyle_ = style;
425      }
426  
427      /**
428       * @brief Sets the style of the top point of a polyline.
429       *
430       * @param style Indicates the style to set. For details, see {@link PointStyle}.
431       * @since 1.0
432       * @version 1.0
433       */
SetTopPointStyle(const PointStyle & style)434      void SetTopPointStyle(const PointStyle& style)
435      {
436          topPointStyle_ = style;
437      }
438  
439      /**
440       * @brief Sets the style of the bottom point of a polyline.
441       *
442       * @param style Indicates the style to set. For details, see {@link PointStyle}.
443       * @since 1.0
444       * @version 1.0
445       */
SetBottomPointStyle(const PointStyle & style)446      void SetBottomPointStyle(const PointStyle& style)
447      {
448          bottomPointStyle_ = style;
449      }
450  
451      /**
452       * @brief Obtains the style of the frontmost point on a polyline.
453       *
454       * @return Returns the style of the point. For details, see {@link PointStyle}.
455       * @since 1.0
456       * @version 1.0
457       */
GetHeadPointStyle()458      const PointStyle& GetHeadPointStyle() const
459      {
460          return headPointStyle_;
461      }
462  
463      /**
464       * @brief Obtains the style of the top point of a polyline.
465       *
466       * @return Returns the style of the point. For details, see {@link PointStyle}.
467       * @since 1.0
468       * @version 1.0
469       */
GetTopPointStyle()470      const PointStyle& GetTopPointStyle() const
471      {
472          return topPointStyle_;
473      }
474  
475      /**
476       * @brief Obtains the style of the bottom point of a polyline.
477       *
478       * @return Returns the style of the point. For details, see {@link PointStyle}.
479       * @since 1.0
480       * @version 1.0
481       */
GetBottomPointStyle()482      const PointStyle& GetBottomPointStyle() const
483      {
484          return bottomPointStyle_;
485      }
486  
487      /**
488       * @brief Enables the feature of drawing the frontmost point on a polyline.
489       *
490       * @param enable Specifies whether to draw the frontmost point. Value <b>true</b> means to draw the frontmost
491       *               point, and value <b>false</b> means not to draw the frontmost point.
492       * @since 1.0
493       * @version 1.0
494       */
EnableHeadPoint(bool enable)495      void EnableHeadPoint(bool enable)
496      {
497          enableHeadPoint_ = enable;
498      }
499  
500      /**
501       * @brief enableHeadPoint_.
502       *
503       * @return Returns enableHeadPoint_.
504       */
GetEnableHeadPoint()505      bool GetEnableHeadPoint() const
506      {
507          return enableHeadPoint_;
508      }
509  
510      /**
511       * @brief Enables the feature of drawing the top point of a polyline. If there are multiple top points,
512       *        only the first one is drawn.
513       *
514       * @param enable Specifies whether to draw the top point. Value <b>true</b> means to draw the top point,
515       *               and value <b>false</b> means not to draw the top point.
516       * @since 1.0
517       * @version 1.0
518       */
EnableTopPoint(bool enable)519      void EnableTopPoint(bool enable)
520      {
521          enableTopPoint_ = enable;
522      }
523  
524      /**
525       * @brief enableTopPoint_.
526       *
527       * @return Returns enableTopPoint_.
528       */
GetEnableTopPoint()529      bool GetEnableTopPoint() const
530      {
531          return enableTopPoint_;
532      }
533  
534      /**
535       * @brief Enables the feature of drawing the bottom point of a polyline. If there are multiple bottom points,
536       *        only the first one is drawn.
537       *
538       * @param enable Specifies whether to draw the bottom point. Value <b>true</b> means to draw the bottom point,
539       *               and value <b>false</b> means not to draw the bottom point.
540       * @since 1.0
541       * @version 1.0
542       */
EnableBottomPoint(bool enable)543      void EnableBottomPoint(bool enable)
544      {
545          enableBottomPoint_ = enable;
546      }
547  
548      /**
549       * @brief enableBottomPoint_.
550       *
551       * @return Returns enableBottomPoint_.
552       */
GetEnableBottomPoint()553      bool GetEnableBottomPoint() const
554      {
555          return enableBottomPoint_;
556      }
557  
558      void DrawPoint(BufferInfo& gfxDstBuffer, const Rect& mask);
559  
560      void Refresh();
561  
562  protected:
563      uint16_t maxCount_;
564      Point* pointArray_;
565  
566  private:
567      constexpr static uint16_t DEFAULT_POINT_RADIUS = 5;
568      constexpr static uint16_t MAX_POINTS_COUNT = 512;
569  
570      ColorType serialColor_;
571      ColorType fillColor_;
572      uint16_t dataCount_;
573      uint16_t peakPointIndex_;
574      int16_t peakData_;
575      int16_t valleyData_;
576      uint16_t valleyPointIndex_;
577      uint16_t lastPointIndex_;
578      uint16_t latestIndex_;
579      uint16_t hideIndex_;
580      uint16_t hideCount_;
581      bool smooth_ : 1;
582      bool enableGradient_ : 1;
583      bool enableHeadPoint_ : 1;
584      bool enableTopPoint_ : 1;
585      bool enableBottomPoint_ : 1;
586      PointStyle headPointStyle_;
587      PointStyle topPointStyle_;
588      PointStyle bottomPointStyle_;
589      UIChart* chart_;
590      Rect invalidateRect_;
591  
592      void RefreshInvalidateRect(uint16_t startIndex, uint16_t endIndex);
593      void RefreshInvalidateRect(uint16_t pointIndex, const PointStyle& style);
594      bool UpdatePeakAndValley(uint16_t startPos, uint16_t endPos);
595      void DoDrawPoint(BufferInfo& gfxDstBuffer, const Point& point, const PointStyle& style, const Rect& mask);
596  };
597  
598  /**
599   * @brief Defines the chart class and provides functions such as adding and deleting data sets to display a chart.
600   *
601   * @since 1.0
602   * @version 1.0
603   */
604  class UIChart : public UIViewGroup {
605  public:
606      /**
607       * @brief A constructor used to create a <b>UIChart</b> instance.
608       *
609       * @since 1.0
610       * @version 1.0
611       */
UIChart()612      UIChart() : enableReverse_(false), needRefresh_(false), mixData_(nullptr)
613      {
614          Add(&xAxis_);
615          Add(&yAxis_);
616          SetStyle(STYLE_LINE_WIDTH, 1);
617          SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);
618      }
619  
620      /**
621       * @brief A destructor used to delete the <b>UIChart</b> instance.
622       *
623       * @since 1.0
624       * @version 1.0
625       */
626      virtual ~UIChart();
627  
628      /**
629       * @brief Obtains the view type.
630       *
631       * @return Returns the view type. For details, see {@link UIViewType}.
632       * @since 1.0
633       * @version 1.0
634       */
GetViewType()635      UIViewType GetViewType() const override
636      {
637          return UI_CHART;
638      }
639  
640      /**
641       * @brief Sets the height for this component.
642       *
643       * @param height Indicates the height to set.
644       * @since 1.0
645       * @version 1.0
646       */
647      void SetHeight(int16_t height) override;
648  
649      /**
650       * @brief Sets the width for this component.
651       *
652       * @param width Indicates the width to set.
653       * @since 1.0
654       * @version 1.0
655       */
656      void SetWidth(int16_t width) override;
657  
OnPreDraw(Rect & invalidatedArea)658      bool OnPreDraw(Rect& invalidatedArea) const override
659      {
660          return false;
661      }
662  
663      void OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) override;
664  
665      /**
666       * @brief Adds a data set.
667       *
668       * @param dataSerial Indicates the pointer to the data set class. For details, see {@link UIChartDataSerial}.
669       * @return Returns <b>true</b> if the data set is added successfully; returns <b>false</b> otherwise.
670       * @see DeleteDataSerial
671       * @since 1.0
672       * @version 1.0
673       */
674      virtual bool AddDataSerial(UIChartDataSerial* dataSerial);
675  
676      /**
677       * @brief Deletes a data set.
678       *
679       * @param dataSerial Indicates the pointer to the data set class. For details, see {@link UIChartDataSerial}.
680       * @return Returns <b>true</b> if the data set is deleted successfully; returns <b>false</b> otherwise.
681       * @see AddDataSerial
682       * @since 1.0
683       * @version 1.0
684       */
685      virtual bool DeleteDataSerial(UIChartDataSerial* dataSerial);
686  
687      /**
688       * @brief Clears all data sets.
689       *
690       * @since 1.0
691       * @version 1.0
692       */
693      virtual void ClearDataSerial();
694  
695      /**
696       * @brief Refreshes a chart and redraws the dirty region.
697       *
698       * Only the parts that need to be redrawn are refreshed, for example, new data points.
699       * This function provides better performance than {@link Invalidate}.
700       *
701       * @since 1.0
702       * @version 1.0
703       */
704      virtual void RefreshChart() = 0;
705  
706      /**
707       * @brief Obtains the x-axis instance.
708       *
709       * @return Returns the x-axis instance.
710       * @since 1.0
711       * @version 1.0
712       */
GetXAxis()713      UIXAxis& GetXAxis()
714      {
715          return xAxis_;
716      }
717  
718      /**
719       * @brief Obtains the y-axis instance.
720       *
721       * @return Returns the y-axis instance.
722       * @since 1.0
723       * @version 1.0
724       */
GetYAxis()725      UIYAxis& GetYAxis()
726      {
727          return yAxis_;
728      }
729  
730      /**
731       * @brief Enables chart reverse.
732       *
733       * After the chart is reversed, the x-axis aligns with the top of the chart. The pixel position corresponding
734       * to the data point remains unchanged. Complementary filling is performed on the chart
735       * (only the part that is not filled previously will be filled).
736       *
737       * @param enable Specifies whether to enable chart reverse. Value <b>true</b> means to enable chart reverse,
738       *               and value <b>false</b> means not to enable chart reverse. The default value is <b>false</b>.
739       * @since 1.0
740       * @version 1.0
741       */
EnableReverse(bool enable)742      void EnableReverse(bool enable)
743      {
744          if (enableReverse_ != enable) {
745              enableReverse_ = enable;
746              xAxis_.EnableReverse(enable);
747              yAxis_.EnableReverse(enable);
748          }
749      }
750  
751  protected:
752      List<UIChartDataSerial*> list_;
753      UIXAxis xAxis_;
754      UIYAxis yAxis_;
755      bool enableReverse_;
756      bool needRefresh_;
757      uint8_t* mixData_;
758      virtual void DrawDataSerials(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) = 0;
759  };
760  
761  /**
762   * @brief Provides special functions for implementing a bar chart.
763   *
764   * @since 1.0
765   * @version 1.0
766   */
767  class UIChartPillar : public UIChart {
768  public:
769      /**
770       * @brief A constructor used to create a <b>UIChartPillar</b> instance.
771       *
772       * @since 1.0
773       * @version 1.0
774       */
UIChartPillar()775      UIChartPillar() {}
776  
777      /**
778       * @brief A destructor used to delete the <b>UIChartPillar</b> instance.
779       *
780       * @since 1.0
781       * @version 1.0
782       */
~UIChartPillar()783      virtual ~UIChartPillar() {}
784  
785      /**
786       * @brief Refreshes a bar chart and redraws the dirty region.
787       *
788       * Only the parts that need to be redrawn are refreshed, for example, new data points.
789       * This function provides better performance than {@link Invalidate}.
790       *
791       * @since 1.0
792       * @version 1.0
793       */
794      void RefreshChart() override;
795  
796  protected:
797      void DrawDataSerials(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) override;
798  
799  private:
800      static constexpr float DEFAULT_MARK_PERCENTAGE = 0.1f;
801  };
802  
803  /**
804   * @brief Provides special functions for implementing a polyline.
805   *
806   * @since 1.0
807   * @version 1.0
808   */
809  class UIChartPolyline : public UIChart {
810  public:
811      /**
812       * @brief A constructor used to create a <b>UIChartPolyline</b> instance.
813       *
814       * @since 1.0
815       * @version 1.0
816       */
UIChartPolyline()817      UIChartPolyline() : minOpa_(OPA_TRANSPARENT), maxOpa_(OPA_OPAQUE), gradientBottom_(0) {}
818  
819      /**
820       * @brief A destructor used to delete the <b>UIChartPolyline</b> instance.
821       *
822       * @since 1.0
823       * @version 1.0
824       */
~UIChartPolyline()825      virtual ~UIChartPolyline() {}
826  
827      /**
828       * @brief Refreshes a line chart and redraws the dirty region.
829       *
830       * Only the parts that need to be redrawn are refreshed, for example, new data points.
831       * This function provides better performance than {@link Invalidate}.
832       *
833       * @since 1.0
834       * @version 1.0
835       */
836      void RefreshChart() override;
837  
838      /**
839       * @brief Sets the opacity range of the fill color gradient.
840       *
841       * This function sets the opacity range between the top point and bottom point of the line chart.
842       * The opacity of each horizontal line is calculated based on the ratio.
843       *
844       * @param minOpa Indicates the opacity closest to the x-axis.
845       * @param maxOpa Indicates the opacity farthest away from the x-axis.
846       * @since 1.0
847       * @version 1.0
848       */
SetGradientOpacity(uint8_t minOpa,uint8_t maxOpa)849      void SetGradientOpacity(uint8_t minOpa, uint8_t maxOpa)
850      {
851          minOpa_ = minOpa;
852          maxOpa_ = maxOpa;
853          needRefresh_ = true;
854      }
855  
856      /**
857       * @brief Sets the distance between the bottom edge of the fill color range and the x-axis.
858       *
859       * This function fills in the area between the polyline and bottom of the line chart. For a chart that is not
860       * reversed, if the bottom is above the polyline, there is no filling. For a reversed chart,
861       * if the bottom is below the polyline, there is no filling.
862       *
863       * @param bottom Indicates the bottom of the filling range. The value is the distance to the x-axis.
864       * @since 1.0
865       * @version 1.0
866       */
SetGradientBottom(uint16_t bottom)867      void SetGradientBottom(uint16_t bottom)
868      {
869          gradientBottom_ = bottom;
870      }
871  
872  protected:
873      void DrawDataSerials(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) override;
874  
875  private:
876      struct ChartLine {
877          Point start;
878          Point end;
879      };
880  
881      struct CrossPointSet {
882          Point first;
883          Point second;
884          Point nextFirst;
885          bool firstFind;
886          bool secondFind;
887      };
888  
889      constexpr static uint8_t SMOOTH_SLOPE_ANGLE = 3;
890      constexpr static uint8_t LINE_JOIN_WIDTH = 3;
891      uint8_t minOpa_;
892      uint8_t maxOpa_;
893      uint16_t gradientBottom_;
894  
895      void GradientColor(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea, UIChartDataSerial* data);
896      void DrawGradientColor(BufferInfo& gfxDstBuffer,
897                             const Rect& invalidatedArea,
898                             UIChartDataSerial* data,
899                             const ChartLine& linePoints,
900                             const ChartLine& limitPoints,
901                             int16_t startY);
902      void DrawSmoothPolyLine(BufferInfo& gfxDstBuffer,
903                              uint16_t startIndex,
904                              uint16_t endIndex,
905                              const Rect& invalidatedArea,
906                              UIChartDataSerial* data);
907      void GetDataBySmooth(uint16_t startIndex, uint16_t endIndex, UIChartDataSerial* data);
908      bool Smooth(uint16_t startPos,
909                  Point& start,
910                  Point& end,
911                  Point& current,
912                  UIChartDataSerial* data,
913                  uint16_t& slope,
914                  uint16_t& preSlope);
915      void DrawPolyLine(BufferInfo& gfxDstBuffer,
916                        uint16_t startIndex,
917                        uint16_t endIndex,
918                        const Rect& invalidatedArea,
919                        UIChartDataSerial* data);
920      bool GetLineCrossPoint(const Point& p1, const Point& p2, const Point& p3, const Point& p4, Point& cross);
921      void FindCrossPoints(const ChartLine& line, const ChartLine& polyLine, CrossPointSet& cross);
922      void ReMeasure() override;
923      void CalcVerticalInfo(int16_t top, int16_t bottom, int16_t start, int16_t end, int16_t& y, int16_t& yHeight);
924      void SetDrawLineCross(BufferInfo& gfxDstBuffer,
925                            const Rect& invalidatedArea,
926                            UIChartDataSerial* data,
927                            CrossPointSet& cross,
928                            BaseGfxEngine* baseGfxEngine,
929                            int16_t startY,
930                            int16_t mixScale);
931  };
932  } // namespace OHOS
933  #endif // GRAPHIC_LITE_UI_CHART_H
934