1 /*
2 * Copyright (c) 2021-2022 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 "frameworks/bridge/common/dom/dom_chart.h"
17
18 #include "frameworks/bridge/common/utils/utils.h"
19
20 #include "base/utils/linear_map.h"
21 #include "base/utils/string_utils.h"
22 #include "base/utils/utils.h"
23 #include "core/components/common/properties/color_factory.h"
24
25 namespace OHOS::Ace::Framework {
26 namespace {
27
28 const char LIGHT_RED_COLOR[] = "#EB4034";
29 const char LIGHT_GREEN_COLOR[] = "#AEEB34";
30 const char LIGHT_BLUE_COLOR[] = "#34EBD9";
31 constexpr double PROGRESS_DEFAULT_MAX_VALUE = 100.0;
32 constexpr uint32_t METHOD_APPEND_ARGS_SIZE = 1;
33
34 } // namespace
35
GetSpecializedComponent()36 RefPtr<Component> DOMChart::GetSpecializedComponent()
37 {
38 if (chartType_ == ChartType::BAR || chartType_ == ChartType::LINE) {
39 return chartChild_;
40 }
41 if (chartType_ == ChartType::GAUGE) {
42 return progressChild_;
43 }
44 return dataPanelChild_;
45 }
46
DOMChart(NodeId nodeId,const std::string & nodeName)47 DOMChart::DOMChart(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName) {}
48
SetChartAttrOptions(const ChartOptions & chartOptions)49 void DOMChart::SetChartAttrOptions(const ChartOptions& chartOptions)
50 {
51 chartOptions_ = chartOptions;
52 }
53
SetChartAttrDatasets(const std::vector<MainChart> & datasets)54 void DOMChart::SetChartAttrDatasets(const std::vector<MainChart>& datasets)
55 {
56 chartDatasets_ = datasets;
57 isResetPosition_ = false;
58 position_ = 0;
59 seriesNum_ = 0;
60 lineData_.clear();
61 isSetFirst_ = false;
62 }
63
SetChartAttrSegments(const std::vector<Segment> & segments)64 void DOMChart::SetChartAttrSegments(const std::vector<Segment>& segments)
65 {
66 segments_ = segments;
67 }
68
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)69 bool DOMChart::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
70 {
71 // this map should be sorted by key.
72 static const LinearMapNode<void (*)(const std::string&, DOMChart&)> chartAttrsOperators[] = {
73 { DOM_CHART_ANIMATION_DURATION,
74 [](const std::string& val, DOMChart& chart) {
75 chart.animationDuration_ = StringToDouble(val);
76 } },
77 { DOM_AUTO_SCALE,
78 [](const std::string& val, DOMChart& chart) {
79 chart.autoScale_ = StringToBool(val);
80 } },
81 { DOM_EFFECTS_ON,
82 [](const std::string& val, DOMChart& chart) {
83 chart.showEffect_ = StringToBool(val);
84 } },
85 { DOM_PROGRESS_PERCENT,
86 [](const std::string& val, DOMChart& chart) {
87 chart.percent_ = StringToDouble(val);
88 if (chart.percent_ > chart.max_) {
89 chart.percent_ = chart.max_;
90 }
91 if (chart.percent_ < chart.min_) {
92 chart.percent_ = chart.min_;
93 }
94 } },
95 { DOM_CHART_TYPE,
96 [](const std::string& val, DOMChart& chart) {
97 if (val == DOM_CHART_TYPE_GAUGE) {
98 chart.chartType_ = ChartType::GAUGE;
99 } else if (val == DOM_CHART_TYPE_BAR) {
100 chart.chartType_ = ChartType::BAR;
101 } else if (val == DOM_CHART_TYPE_LINE) {
102 chart.chartType_ = ChartType::LINE;
103 } else if (val == DOM_CHART_TYPE_PROGRESS) {
104 chart.chartType_ = ChartType::PROGRESS;
105 } else if (val == DOM_CHART_TYPE_RAINBOW) {
106 chart.chartType_ = ChartType::RAINBOW;
107 } else if (val == DOM_CHART_TYPE_LOADING) {
108 chart.chartType_ = ChartType::LOADING;
109 } else {
110 LOGI("chart type error %{public}s, now using loading", val.c_str());
111 chart.chartType_ = ChartType::LINE;
112 }
113 } },
114 };
115 auto operatorIter = BinarySearchFindIndex(chartAttrsOperators, ArraySize(chartAttrsOperators), attr.first.c_str());
116 if (operatorIter != -1) {
117 chartAttrsOperators[operatorIter].value(attr.second, *this);
118 return true;
119 }
120 return false;
121 }
122
SetSpecializedStyle(const std::pair<std::string,std::string> & style)123 bool DOMChart::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
124 {
125 // this map should be sorted by key.
126 static const LinearMapNode<void (*)(const std::string&, DOMChart&)> chartStylesOperators[] = {
127 { DOM_BACKGROUND_COLOR,
128 [](const std::string& val, DOMChart& chart) {
129 if (chart.chartType_ == ChartType::LINE || (chart.chartType_ == ChartType::BAR) ||
130 (chart.chartType_ == ChartType::GAUGE)) {
131 auto declaration = chart.GetDeclaration();
132 if (declaration) {
133 auto backgroundColor = chart.ParseColor(val);
134 declaration->GetBackDecoration()->SetBackgroundColor(backgroundColor);
135 declaration->SetHasBackGroundColor(true);
136 declaration->SetHasDecorationStyle(true);
137 return;
138 }
139 }
140 chart.backgroundColor_ = chart.ParseColor(val);
141 chart.trackColorSet_ = true;
142 } },
143 { DOM_CENTER_X,
144 [](const std::string& val, DOMChart& chart) {
145 chart.centerX_.first = StringToDouble(val);
146 chart.centerX_.second = true;
147 } },
148 { DOM_CENTER_Y,
149 [](const std::string& val, DOMChart& chart) {
150 chart.centerY_.first = StringToDouble(val);
151 chart.centerY_.second = true;
152 } },
153 { DOM_COLORS_ARRAY,
154 [](const std::string& val, DOMChart& chart) {
155 chart.colors_.clear();
156 StringUtils::StringSplitter(val, ',', chart.colors_);
157 } },
158 { DOM_TEXT_FONT_FAMILY,
159 [](const std::string& val, DOMChart& chart) {
160 chart.fontFamily_ = ConvertStrToFontFamilies(val);
161 } },
162 { DOM_TEXT_FONT_SIZE,
163 [](const std::string& val, DOMChart& chart) {
164 chart.textSize_ = StringToDouble(val);
165 } },
166 { DOM_PROGRESS_RADIUS,
167 [](const std::string& val, DOMChart& chart) {
168 chart.radius_.first = StringToDouble(val);
169 chart.radius_.second = true;
170 } },
171 { DOM_START_DEGREE,
172 [](const std::string& val, DOMChart& chart) {
173 chart.startAngle_.first = StringToDouble(val);
174 chart.startAngle_.second = true;
175 } },
176 { DOM_PROGRESS_STROKE_WIDTH,
177 [](const std::string& val, DOMChart& chart) {
178 chart.strokeWidth_.first = chart.ParseDimension(val);
179 chart.strokeWidth_.second = true;
180 } },
181 { DOM_SWEEP_DEGREE,
182 [](const std::string& val, DOMChart& chart) {
183 chart.totalAngle_.first = StringToDouble(val);
184 chart.totalAngle_.second = true;
185 } },
186 { DOM_WEIGHTS_ARRAY,
187 [](const std::string& val, DOMChart& chart) {
188 chart.weights_.clear();
189 StringUtils::StringSplitter(val, ',', chart.weights_);
190 } },
191 };
192 auto operatorIter =
193 BinarySearchFindIndex(chartStylesOperators, ArraySize(chartStylesOperators), style.first.c_str());
194 if (operatorIter != -1) {
195 chartStylesOperators[operatorIter].value(style.second, *this);
196 return true;
197 }
198 return false;
199 }
200
OnSetStyleFinished()201 void DOMChart::OnSetStyleFinished()
202 {
203 // colors or weight are illegal, and set default color and weight
204 if (colors_.empty() || weights_.empty() || colors_.size() != weights_.size()) {
205 colors_.push_back(ParseColor(LIGHT_RED_COLOR));
206 colors_.push_back(ParseColor(LIGHT_GREEN_COLOR));
207 colors_.push_back(ParseColor(LIGHT_BLUE_COLOR));
208 // equally separate the range
209 weights_.push_back(1);
210 weights_.push_back(1);
211 weights_.push_back(1);
212 }
213 if (!centerY_.second || !centerX_.second || !radius_.second) {
214 centerY_.first = -1.0;
215 centerX_.first = -1.0;
216 radius_.first = -1.0;
217 centerY_.second = false;
218 centerX_.second = false;
219 radius_.second = false;
220 }
221 }
222
223 // Sets other properties of a point, except coordinates.
SetPoint(PointInfo & pointInfo,PointInfo getPointInfo)224 void DOMChart::SetPoint(PointInfo& pointInfo, PointInfo getPointInfo)
225 {
226 if (!getPointInfo.GetFillColorString().empty()) {
227 getPointInfo.SetFillColor(ParseColor(getPointInfo.GetFillColorString()));
228 }
229 pointInfo.SetFillColor(getPointInfo.GetFillColor());
230 if (!getPointInfo.GetStrokeColorString().empty()) {
231 getPointInfo.SetStrokeColor(ParseColor(getPointInfo.GetStrokeColorString()));
232 }
233 pointInfo.SetStrokeColor(getPointInfo.GetStrokeColor());
234 pointInfo.SetPointStrokeWidth(getPointInfo.GetPointStrokeWidth());
235 pointInfo.SetPointSize(getPointInfo.GetPointSize());
236 pointInfo.SetPointShape(getPointInfo.GetPointShape());
237 pointInfo.SetDisplay(getPointInfo.GetDisplay());
238 }
239
SetChart(MainChart & chartDataset)240 void DOMChart::SetChart(MainChart& chartDataset)
241 {
242 chartDataset.SetLineWidth(chartOptions_.GetLineWidth());
243 chartDataset.SetSmoothFlag(chartOptions_.GetSmoothFlag());
244 chartDataset.SetLineGradient(chartOptions_.GetLineGradient());
245 chartDataset.SetWholeLineGradient(chartOptions_.GetWholeLineGradient());
246 chartDataset.SetTargetColor(chartOptions_.GetTargetColor());
247 chartDataset.SetErasePointNumber(chartOptions_.GetErasePointNumber());
248 chartDataset.SetTextSize(textSize_);
249 chartDataset.SetFontFamily(fontFamily_);
250
251 auto points = chartDataset.GetData();
252 if (points.empty()) {
253 LOGD("points is empty, chart has no data to set.");
254 return;
255 }
256
257 // parse color from color string
258 for (auto& point : points) {
259 auto pointInfo = point.GetPointInfo();
260 if (!pointInfo.GetStrokeColorString().empty()) {
261 pointInfo.SetStrokeColor(ParseColor(pointInfo.GetStrokeColorString()));
262 }
263 if (!pointInfo.GetFillColorString().empty()) {
264 pointInfo.SetFillColor(ParseColor(pointInfo.GetFillColorString()));
265 }
266 auto segment = point.GetSegmentInfo();
267 if (!segment.GetColorString().empty()) {
268 segment.SetSegmentColor(ParseColor(segment.GetColorString()));
269 }
270 auto text = point.GetTextInfo();
271 if (!text.GetColorString().empty()) {
272 text.SetColor(ParseColor(text.GetColorString()));
273 }
274 point.SetPointInfo(pointInfo);
275 point.SetSegmentInfo(segment);
276 point.SetTextInfo(text);
277 }
278
279 // remove points out of range. get topPoint and bottomPoint.
280 sort(points.begin(), points.end(),
281 [](LineInfo a, LineInfo b) { return a.GetPointInfo().GetX() < b.GetPointInfo().GetX(); });
282
283 PointInfo headPoint;
284 PointInfo topPoint = points.begin()->GetPointInfo();
285 PointInfo bottomPoint = points.begin()->GetPointInfo();
286
287 for (auto pointInfo = points.begin(); pointInfo != points.end();) {
288 auto point = pointInfo->GetPointInfo();
289 auto segment = pointInfo->GetSegmentInfo();
290 if (segment.GetSegmentColor() == Color::TRANSPARENT) {
291 segment.SetSegmentColor(chartDataset.GetStrokeColor());
292 pointInfo->SetSegmentInfo(segment);
293 }
294 if ((chartType_ == ChartType::LINE && point.GetX() < chartOptions_.GetXAxis().min) ||
295 (chartType_ == ChartType::LINE && point.GetX() > chartOptions_.GetXAxis().max) ||
296 ((chartType_ != ChartType::LINE && chartType_ != ChartType::BAR)
297 && (point.GetY() < chartOptions_.GetYAxis().min || point.GetY() > chartOptions_.GetYAxis().max))) {
298 points.erase(pointInfo);
299 } else {
300 if (point.GetY() > topPoint.GetY()) {
301 topPoint = point;
302 }
303 if (point.GetY() < bottomPoint.GetY()) {
304 bottomPoint = point;
305 }
306 ++pointInfo;
307 }
308 }
309 chartDataset.SetData(points);
310
311 if (!points.empty()) {
312 headPoint = points[points.size() - 1].GetPointInfo();
313 SetPoint(headPoint, chartOptions_.GetHeadPoint());
314 chartDataset.SetHeadPoint(headPoint);
315 }
316
317 SetPoint(topPoint, chartOptions_.GetTopPoint());
318 chartDataset.SetTopPoint(topPoint);
319
320 SetPoint(bottomPoint, chartOptions_.GetBottomPoint());
321 chartDataset.SetBottomPoint(bottomPoint);
322 }
323
PrepareSpecializedComponent()324 void DOMChart::PrepareSpecializedComponent()
325 {
326 if (chartType_ == ChartType::GAUGE) {
327 if (!progressChild_) {
328 progressChild_ =
329 AceType::MakeRefPtr<ProgressComponent>(0.0, 0.0, 0.0, PROGRESS_DEFAULT_MAX_VALUE, ProgressType::GAUGE);
330 }
331 progressChild_->SetValue(percent_);
332 progressChild_->SetMaxValue(max_);
333 progressChild_->SetMinValue(min_);
334 progressChild_->GetTrack()->SetIndicatorFlag(true);
335 progressChild_->GetTrack()->SetSectionsStyle(colors_, weights_);
336 progressChild_->GetTrack()->SetTrackThickness(strokeWidth_.first);
337 progressChild_->GetTrack()->GetTrackInfo()->SetStartDegree(startAngle_.first);
338 progressChild_->GetTrack()->GetTrackInfo()->SetSweepDegree(totalAngle_.first);
339 progressChild_->GetTrack()->SetCenterX(centerX_.first);
340 progressChild_->GetTrack()->SetCenterY(centerY_.first);
341 progressChild_->GetTrack()->SetRadius(radius_.first);
342 } else if (chartType_ == ChartType::BAR || chartType_ == ChartType::LINE) {
343 if (!chartChild_) {
344 chartChild_ = AceType::MakeRefPtr<ChartComponent>(chartType_);
345 }
346 chartChild_->SetHorizontalOption(chartOptions_.GetXAxis());
347 chartChild_->SetVerticalOption(chartOptions_.GetYAxis());
348 // Convert the data in options to mainchart
349 for (auto& charDataset : chartDatasets_) {
350 SetChart(charDataset);
351 }
352 chartChild_->SetMainCharts(chartDatasets_);
353 } else if (chartType_ == ChartType::PROGRESS || chartType_ == ChartType::LOADING) {
354 dataPanelChild_ = AceType::MakeRefPtr<ProgressDataPanelComponent>(chartType_);
355 dataPanelChild_->InitalStyle(GetThemeManager());
356 dataPanelChild_->SetEffects(showEffect_);
357 if (trackColorSet_) {
358 dataPanelChild_->SetTrackColor(backgroundColor_);
359 }
360 dataPanelChild_->SetAutoScale(autoScale_);
361 if (segments_.empty()) {
362 LOGI("progress chart hasn't set segment");
363 return;
364 }
365 auto progressDataPanel = AceType::DynamicCast<ProgressDataPanelComponent>(dataPanelChild_);
366 if (segments_[0].GetColorType() == SegmentStyleType::USE_COLOR) {
367 progressDataPanel->SetStartColor(segments_[0].GetStartColor());
368 progressDataPanel->SetEndColor(segments_[0].GetEndColor());
369 } else if (segments_[0].GetColorType() == SegmentStyleType::USE_GRADIENT) {
370 auto& colorManager = ColorFactory::GetInstance();
371 auto colorPair = colorManager.GetColorTuple(segments_[0].GetColorDescriptor());
372 progressDataPanel->SetStartColor(colorPair.first);
373 progressDataPanel->SetEndColor(colorPair.second);
374 }
375 // for else case, keep default color
376 progressDataPanel->SetProgressValue(segments_[0].GetValue());
377 if (strokeWidth_.second) {
378 dataPanelChild_->SetThickness(strokeWidth_.first);
379 }
380 } else if (chartType_ == ChartType::RAINBOW) {
381 dataPanelChild_ = AceType::MakeRefPtr<PercentageDataPanelComponent>(chartType_);
382 dataPanelChild_->SetAnimationDuration(animationDuration_);
383 dataPanelChild_->SetEffects(showEffect_);
384 dataPanelChild_->SetAutoScale(autoScale_);
385 auto percentageDataPanel = AceType::DynamicCast<PercentageDataPanelComponent>(dataPanelChild_);
386 // the angle range is from 0 to 360.
387 percentageDataPanel->SetStartDegree(startAngle_.second ? startAngle_.first : 0.0);
388 percentageDataPanel->SetSweepDegree(totalAngle_.second ? totalAngle_.first : 360.0);
389 percentageDataPanel->ClearSegment();
390 if (segments_.empty()) {
391 LOGI("progress chart hasn't set segment");
392 return;
393 }
394 for (const auto& segment : segments_) {
395 percentageDataPanel->AppendSegment(segment);
396 }
397 dataPanelChild_->InitalStyle(GetThemeManager());
398 if (trackColorSet_) {
399 dataPanelChild_->SetTrackColor(backgroundColor_);
400 }
401 if (strokeWidth_.second) {
402 dataPanelChild_->SetThickness(strokeWidth_.first);
403 }
404 }
405 }
406
CallSpecializedMethod(const std::string & method,const std::string & args)407 void DOMChart::CallSpecializedMethod(const std::string& method, const std::string& args)
408 {
409 if (method != DOM_METHOD_APPEND) {
410 LOGD("Not support method %{private}s yet!", method.c_str());
411 return;
412 }
413 std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(args);
414 if (!argsValue || !argsValue->IsArray() || argsValue->GetArraySize() != METHOD_APPEND_ARGS_SIZE) {
415 LOGE("parse args error");
416 return;
417 }
418
419 std::unique_ptr<JsonValue> serialValue = argsValue->GetArrayItem(0)->GetValue("serial");
420 if (!serialValue || !serialValue->IsNumber()) {
421 LOGE("get serial failed");
422 return;
423 }
424 seriesNum_ = serialValue->GetInt();
425
426 std::unique_ptr<JsonValue> dataValue = argsValue->GetArrayItem(0)->GetValue("data");
427 if (!dataValue || !dataValue->IsArray()) {
428 LOGE("get data failed");
429 return;
430 }
431 int32_t arraySize = dataValue->GetArraySize();
432 auto chartDatas = chartChild_->GetMainCharts();
433
434 if (seriesNum_ < 0 || (static_cast<size_t>(seriesNum_) >= chartDatas.size())) {
435 LOGE("series number is greater or equal to the size of chart");
436 return;
437 }
438
439 if (!isSetFirst_) {
440 isSetFirst_ = true;
441 for (int32_t i = 0; i < static_cast<int32_t>(chartDatas.size()); i++) {
442 lineData_.emplace_back(chartOptions_.GetXAxis().min, false);
443 }
444 }
445
446 // get the head point position of the series data to be updated.
447 position_ = lineData_[seriesNum_].first;
448 isResetPosition_ = lineData_[seriesNum_].second;
449
450 for (int32_t i = 0; i < arraySize; i++) {
451 std::unique_ptr<JsonValue> coorVal = dataValue->GetArrayItem(i);
452 if (!coorVal || !coorVal->IsNumber()) {
453 LOGE("get coorVal failed");
454 return;
455 }
456 int32_t coorY = coorVal->GetInt();
457 if (coorY <= chartOptions_.GetYAxis().max && coorY >= chartOptions_.GetYAxis().min) {
458 UpdateChartData(coorY, chartDatas);
459 }
460 }
461
462 // save the head point position of the updated series data.
463 lineData_[seriesNum_].first = position_;
464 lineData_[seriesNum_].second = isResetPosition_;
465
466 UpdateTopBottomPoint(chartDatas);
467
468 chartChild_->SetMainCharts(chartDatas);
469 auto node = DOMNode::GetRootComponent();
470 node->MarkNeedUpdate();
471 auto pipelineContext = pipelineContext_.Upgrade();
472 if (!pipelineContext) {
473 LOGE("pipelineContext_ is nullptr");
474 return;
475 }
476 pipelineContext->ScheduleUpdate(node);
477 }
478
UpdateTopBottomPoint(std::vector<MainChart> & data)479 void DOMChart::UpdateTopBottomPoint(std::vector<MainChart>& data)
480 {
481 Point bottomPt = Point(0, 0);
482 Point topPt = Point(0, 0);
483 auto pointVec = data[seriesNum_].GetData();
484 double minY = pointVec[0].GetPointInfo().GetY();
485 double maxY = pointVec[0].GetPointInfo().GetY();
486
487 for (auto iter : pointVec) {
488 if (iter.GetPointInfo().GetY() <= minY) {
489 bottomPt.SetX(iter.GetPointInfo().GetX());
490 bottomPt.SetY(iter.GetPointInfo().GetY());
491 minY = iter.GetPointInfo().GetY();
492 }
493 if (iter.GetPointInfo().GetY() >= maxY) {
494 topPt.SetX(iter.GetPointInfo().GetX());
495 topPt.SetY(iter.GetPointInfo().GetY());
496 maxY = iter.GetPointInfo().GetY();
497 }
498 }
499 auto bottomPoint = data[seriesNum_].GetBottomPoint();
500 bottomPoint.SetX(bottomPt.GetX());
501 bottomPoint.SetY(bottomPt.GetY());
502 data[seriesNum_].SetBottomPoint(bottomPoint);
503
504 auto topPoint = data[seriesNum_].GetTopPoint();
505 topPoint.SetX(topPt.GetX());
506 topPoint.SetY(topPt.GetY());
507 data[seriesNum_].SetTopPoint(topPoint);
508 }
509
UpdateChartData(int32_t coorY,std::vector<MainChart> & data)510 void DOMChart::UpdateChartData(int32_t coorY, std::vector<MainChart>& data)
511 {
512 if (isResetPosition_) {
513 position_ = position_ + 1;
514 } else {
515 position_ = static_cast<int32_t>(data[seriesNum_].GetData().size());
516 }
517 if (position_ > chartOptions_.GetXAxis().max || position_ < chartOptions_.GetXAxis().min) {
518 return;
519 }
520 if (chartOptions_.GetLoop() && position_ > chartOptions_.GetXAxis().max - 1) {
521 isResetPosition_ = true;
522 position_ = chartOptions_.GetXAxis().min;
523 Point coor = Point(position_, coorY);
524 PointInfo point = PointInfo(coor);
525 SegmentInfo segment;
526 segment.SetSegmentColor(data[seriesNum_].GetStrokeColor());
527 LineInfo line = LineInfo(point);
528 line.SetSegmentInfo(segment);
529 data[seriesNum_].ReplaceData(position_, line);
530 data[seriesNum_].SetErasePointNumber(chartOptions_.GetErasePointNumber());
531 data[seriesNum_].SetHeadPointIndex(position_);
532 } else {
533 Point coor = Point(position_, coorY);
534 PointInfo point = PointInfo(coor);
535 SegmentInfo segment;
536 segment.SetSegmentColor(data[seriesNum_].GetStrokeColor());
537 LineInfo line = LineInfo(point);
538 line.SetSegmentInfo(segment);
539 if (!isResetPosition_) {
540 data[seriesNum_].AppendData(line);
541 } else {
542 data[seriesNum_].ReplaceData(position_, line);
543 data[seriesNum_].SetHeadPointIndex(position_);
544 }
545 }
546 auto headPoint = data[seriesNum_].GetHeadPoint();
547 headPoint.SetX(position_);
548 headPoint.SetY(coorY);
549 data[seriesNum_].SetHeadPoint(headPoint);
550 }
551
552 } // namespace OHOS::Ace::Framework
553