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