• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "frameworks/bridge/js_frontend/engine/v8/v8_chart_bridge.h"
17 
18 #include "frameworks/bridge/common/utils/utils.h"
19 
20 namespace OHOS::Ace::Framework {
21 
22 namespace {
23 
24 constexpr uint32_t VALID_ARRAY_LENGTH = 2;
25 constexpr uint32_t ARRAY_X_VALUE = 0;
26 constexpr uint32_t ARRAY_Y_VALUE = 1;
27 
GetAttrOptionsAxis(v8::Local<v8::Context> ctx,v8::Local<v8::Value> valObject,AxisOption & axisOption)28 void GetAttrOptionsAxis(v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, AxisOption& axisOption)
29 {
30     v8::Isolate* isolate = ctx->GetIsolate();
31     v8::HandleScope handleScope(isolate);
32 
33     if (!valObject->IsObject()) {
34         LOGE("none found attrs");
35         return;
36     }
37     v8::Local<v8::Object> v8ValObj;
38     if (!valObject->ToObject(ctx).ToLocal(&v8ValObj)) {
39         LOGE("Value to Object fail");
40         return;
41     }
42     v8::Local<v8::Array> properties = v8ValObj->GetOwnPropertyNames(ctx).ToLocalChecked();
43     int32_t len = properties->Length();
44 
45     for (int32_t i = 0; i < len; i++) {
46         v8::Local<v8::Value> key;
47         if (!properties->Get(ctx, i).ToLocal(&key)) {
48             LOGW("key is null. Ignoring!");
49             continue;
50         }
51         v8::String::Utf8Value keyV8Str(isolate, key);
52         const char* keyStr = *keyV8Str;
53         if (keyStr == nullptr) {
54             continue;
55         }
56         v8::Local<v8::Value> val = v8ValObj->Get(ctx, key).ToLocalChecked();
57         if (val->IsNumber() || val->IsBoolean() || val->IsString()) {
58             static const std::unordered_map<std::string,
59                 void (*)(v8::Local<v8::Context>, v8::Local<v8::Value>, AxisOption&)>
60                 chartOptionAxisMap = {
61                     { "min",
62                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, AxisOption& axis) {
63                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
64                             const char* valStr = *valV8Str;
65                             if (valStr != nullptr) {
66                                 axis.min = StringToDouble(valStr);
67                             }
68                         } },
69                     { "max",
70                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, AxisOption& axis) {
71                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
72                             const char* valStr = *valV8Str;
73                             if (valStr != nullptr) {
74                                 axis.max = StringToDouble(valStr);
75                             }
76                         } },
77                     { "axisTick",
78                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, AxisOption& axis) {
79                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
80                             const char* valStr = *valV8Str;
81                             if (valStr != nullptr) {
82                                 axis.tickNumber = StringToInt(valStr);
83                             }
84                         } },
85                     { "display",
86                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, AxisOption& axis) {
87                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
88                             const char* valStr = *valV8Str;
89                             if (valStr != nullptr) {
90                                 axis.display = StringToBool(valStr);
91                             }
92                         } },
93                     { "color",
94                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, AxisOption& axis) {
95                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
96                             const char* valStr = *valV8Str;
97                             if (valStr != nullptr) {
98                                 axis.color = Color::FromString(valStr);
99                             }
100                         } },
101                 };
102             auto iter = chartOptionAxisMap.find(keyStr);
103             if (iter != chartOptionAxisMap.end()) {
104                 iter->second(ctx, val, axisOption);
105             } else {
106                 LOGD("key : %{public}s unsupported. Ignoring!", keyStr);
107             }
108         } else {
109             LOGD("key : %{public}s, value of unsupported type. Ignoring!", keyStr);
110         }
111     }
112 }
113 
GetAttrOptionsSeriesPoint(v8::Local<v8::Context> ctx,v8::Local<v8::Value> valObject,PointInfo & pointInfo)114 void GetAttrOptionsSeriesPoint(v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, PointInfo& pointInfo)
115 {
116     v8::Isolate* isolate = ctx->GetIsolate();
117     v8::HandleScope handleScope(isolate);
118 
119     if (!valObject->IsObject()) {
120         LOGE("none found attrs");
121         return;
122     }
123     v8::Local<v8::Object> v8ValObj;
124     if (!valObject->ToObject(ctx).ToLocal(&v8ValObj)) {
125         LOGE("Value to Object fail");
126         return;
127     }
128     v8::Local<v8::Array> properties = v8ValObj->GetOwnPropertyNames(ctx).ToLocalChecked();
129     int32_t len = properties->Length();
130     pointInfo.SetDisplay(true);
131     for (int32_t i = 0; i < len; i++) {
132         v8::Local<v8::Value> key;
133         if (!properties->Get(ctx, i).ToLocal(&key)) {
134             LOGW("key is null. Ignoring!");
135             continue;
136         }
137         v8::String::Utf8Value keyV8Str(isolate, key);
138         const char* keyStr = *keyV8Str;
139         if (keyStr == nullptr) {
140             continue;
141         }
142         v8::Local<v8::Value> val = v8ValObj->Get(ctx, key).ToLocalChecked();
143         if (val->IsString() || val->IsNumber() || val->IsBoolean()) {
144             static const std::unordered_map<std::string,
145                 void (*)(v8::Local<v8::Context>, v8::Local<v8::Value>, PointInfo&)>
146                 chartOptionsPointMap = {
147                     { "shape",
148                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, PointInfo& pointInfo) {
149                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
150                             const char* valStr = *valV8Str;
151                             if (valStr != nullptr) {
152                                 PointShape shape =
153                                     (strcmp(valStr, "circle") == 0)
154                                         ? PointShape::CIRCLE
155                                         : (strcmp(valStr, "square") == 0) ? PointShape::SQUARE : PointShape::TRIANGLE;
156                                 pointInfo.SetPointShape(shape);
157                             }
158                         } },
159                     { "display",
160                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, PointInfo& pointInfo) {
161                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
162                             const char* valStr = *valV8Str;
163                             if (valStr != nullptr) {
164                                 pointInfo.SetDisplay(StringToBool(valStr));
165                             }
166                         } },
167                     { "size",
168                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, PointInfo& pointInfo) {
169                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
170                             const char* valStr = *valV8Str;
171                             if (valStr != nullptr) {
172                                 pointInfo.SetPointSize(StringToDimension(valStr));
173                             }
174                         } },
175                     { "strokeWidth",
176                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, PointInfo& pointInfo) {
177                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
178                             const char* valStr = *valV8Str;
179                             if (valStr != nullptr) {
180                                 pointInfo.SetPointStrokeWidth(StringToDimension(valStr));
181                             }
182                         } },
183                     { "strokeColor",
184                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, PointInfo& pointInfo) {
185                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
186                             const char* valStr = *valV8Str;
187                             if (valStr != nullptr) {
188                                 pointInfo.SetStrokeColor(Color::FromString(valStr));
189                             }
190                         } },
191                     { "fillColor",
192                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, PointInfo& pointInfo) {
193                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
194                             const char* valStr = *valV8Str;
195                             if (valStr != nullptr) {
196                                 pointInfo.SetFillColor(Color::FromString(valStr));
197                             }
198                         } },
199                 };
200             auto iter = chartOptionsPointMap.find(keyStr);
201             if (iter != chartOptionsPointMap.end()) {
202                 iter->second(ctx, val, pointInfo);
203             } else {
204                 LOGD("key : %{public}s unsupported. Ignoring!", keyStr);
205             }
206         } else {
207             LOGD("key : %{public}s, value of unsupported type. Ignoring!", keyStr);
208         }
209     }
210 }
211 
GetChartAttrOptionsSeriesLineStyle(v8::Local<v8::Context> ctx,v8::Local<v8::Value> valObject,ChartOptions & chartOptions)212 void GetChartAttrOptionsSeriesLineStyle(
213     v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, ChartOptions& chartOptions)
214 {
215     v8::Isolate* isolate = ctx->GetIsolate();
216     v8::HandleScope handleScope(isolate);
217 
218     if (!valObject->IsObject()) {
219         LOGE("none found attrs");
220         return;
221     }
222     v8::Local<v8::Object> v8ValObj;
223     if (!valObject->ToObject(ctx).ToLocal(&v8ValObj)) {
224         LOGE("Value to Object fail");
225         return;
226     }
227     v8::Local<v8::Array> properties = v8ValObj->GetOwnPropertyNames(ctx).ToLocalChecked();
228     int32_t len = properties->Length();
229 
230     for (int32_t i = 0; i < len; i++) {
231         v8::Local<v8::Value> key;
232         if (!properties->Get(ctx, i).ToLocal(&key)) {
233             LOGW("key is null. Ignoring!");
234             continue;
235         }
236         v8::String::Utf8Value keyV8Str(isolate, key);
237         const char* keyStr = *keyV8Str;
238         if (keyStr == nullptr) {
239             continue;
240         }
241         v8::Local<v8::Value> val = v8ValObj->Get(ctx, key).ToLocalChecked();
242         if (val->IsString() || val->IsBoolean() || val->IsNumber()) {
243             static const std::unordered_map<std::string,
244                 void (*)(v8::Local<v8::Context>, v8::Local<v8::Value>, ChartOptions&)>
245                 chartOptionsSeriesLineStyleMap = {
246                     { "width",
247                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, ChartOptions& chartOptions) {
248                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
249                             const char* valStr = *valV8Str;
250                             if (valStr != nullptr) {
251                                 chartOptions.SetLineWidth(StringToDouble(valStr));
252                             }
253                         } },
254                     { "smooth",
255                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, ChartOptions& chartOptions) {
256                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
257                             const char* valStr = *valV8Str;
258                             if (valStr != nullptr) {
259                                 chartOptions.SetSmoothFlag(StringToBool(valStr));
260                             }
261                         } },
262                     { "lineGradient",
263                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, ChartOptions& chartOptions) {
264                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
265                             const char* valStr = *valV8Str;
266                             if (valStr != nullptr) {
267                                 chartOptions.SetWholeLineGradient(StringToBool(valStr));
268                             }
269                         } },
270                     { "targetColor",
271                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, ChartOptions& chartOptions) {
272                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
273                             const char* valStr = *valV8Str;
274                             if (valStr != nullptr) {
275                                 chartOptions.SetTargetColor(Color::FromString(valStr));
276                             }
277                         } },
278                 };
279             auto iter = chartOptionsSeriesLineStyleMap.find(keyStr);
280             if (iter != chartOptionsSeriesLineStyleMap.end()) {
281                 iter->second(ctx, val, chartOptions);
282             } else {
283                 LOGD("key : %{public}s unsupported. Ignoring!", keyStr);
284             }
285         } else {
286             LOGD("value of unsupported type. Ignoring!");
287         }
288     }
289 }
290 
GetChartAttrOptionsSeriesLoop(v8::Local<v8::Context> ctx,v8::Local<v8::Value> valObject,ChartOptions & chartOptions)291 void GetChartAttrOptionsSeriesLoop(
292     v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, ChartOptions& chartOptions)
293 {
294     v8::Isolate* isolate = ctx->GetIsolate();
295     v8::HandleScope handleScope(isolate);
296 
297     if (!valObject->IsObject()) {
298         LOGE("none found attrs");
299         return;
300     }
301     v8::Local<v8::Object> v8ValObj;
302     if (!valObject->ToObject(ctx).ToLocal(&v8ValObj)) {
303         LOGE("Value to Object fail");
304         return;
305     }
306     v8::Local<v8::Array> properties = v8ValObj->GetOwnPropertyNames(ctx).ToLocalChecked();
307     int32_t len = properties->Length();
308 
309     chartOptions.SetLoop(true);
310     for (int32_t i = 0; i < len; i++) {
311         v8::Local<v8::Value> key;
312         if (!properties->Get(ctx, i).ToLocal(&key)) {
313             LOGW("key is null. Ignoring!");
314             continue;
315         }
316         v8::String::Utf8Value keyV8Str(isolate, key);
317         const char* keyStr = *keyV8Str;
318         if (keyStr == nullptr) {
319             continue;
320         }
321         v8::Local<v8::Value> val = v8ValObj->Get(ctx, key).ToLocalChecked();
322         if (val->IsString() || val->IsBoolean() || val->IsNumber()) {
323             static const std::unordered_map<std::string,
324                 void (*)(v8::Local<v8::Context>, v8::Local<v8::Value>, ChartOptions&)>
325                 chartOptionsSeriesLoopMap = {
326                     { "margin",
327                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, ChartOptions& chartOptions) {
328                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
329                             const char* valStr = *valV8Str;
330                             if (valStr != nullptr) {
331                                 chartOptions.SetErasePointNumber(StringToInt(valStr));
332                             }
333                         } },
334                     { "gradient",
335                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, ChartOptions& chartOptions) {
336                             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
337                             const char* valStr = *valV8Str;
338                             if (valStr != nullptr) {
339                                 chartOptions.SetLineGradient(StringToBool(valStr));
340                             }
341                         } },
342                 };
343             auto iter = chartOptionsSeriesLoopMap.find(keyStr);
344             if (iter != chartOptionsSeriesLoopMap.end()) {
345                 iter->second(ctx, val, chartOptions);
346             } else {
347                 LOGD("key : %{public}s unsupported. Ignoring!", keyStr);
348             }
349         } else {
350             LOGD("value of unsupported type. Ignoring!");
351         }
352     }
353 }
354 
GetChartAttrOptionsSeries(v8::Local<v8::Context> ctx,v8::Local<v8::Value> valObject,ChartOptions & chartOptions)355 void GetChartAttrOptionsSeries(v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, ChartOptions& chartOptions)
356 {
357     v8::Isolate* isolate = ctx->GetIsolate();
358     v8::HandleScope handleScope(isolate);
359 
360     if (!valObject->IsObject()) {
361         LOGE("none found attrs");
362         return;
363     }
364     v8::Local<v8::Object> v8ValObj;
365     if (!valObject->ToObject(ctx).ToLocal(&v8ValObj)) {
366         LOGE("Value to Object fail");
367         return;
368     }
369     v8::Local<v8::Array> properties = v8ValObj->GetOwnPropertyNames(ctx).ToLocalChecked();
370     int32_t len = properties->Length();
371     for (int32_t i = 0; i < len; i++) {
372         v8::Local<v8::Value> key;
373         if (!properties->Get(ctx, i).ToLocal(&key)) {
374             LOGW("key is null. Ignoring!");
375             continue;
376         }
377         v8::String::Utf8Value keyV8Str(isolate, key);
378         const char* keyStr = *keyV8Str;
379         if (keyStr == nullptr) {
380             continue;
381         }
382         v8::Local<v8::Value> val = v8ValObj->Get(ctx, key).ToLocalChecked();
383         if (val->IsObject()) {
384             static const std::unordered_map<std::string,
385                 void (*)(v8::Local<v8::Context>, v8::Local<v8::Value>, ChartOptions&)>
386                 chartOptionsSeriesMap = {
387                     { "lineStyle",
388                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, ChartOptions& chartOptions) {
389                             GetChartAttrOptionsSeriesLineStyle(ctx, valObject, chartOptions);
390                         } },
391                     { "loop",
392                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, ChartOptions& chartOptions) {
393                             GetChartAttrOptionsSeriesLoop(ctx, valObject, chartOptions);
394                         } },
395                     { "headPoint",
396                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, ChartOptions& chartOptions) {
397                             PointInfo pointInfo;
398                             GetAttrOptionsSeriesPoint(ctx, valObject, pointInfo);
399                             chartOptions.SetHeadPoint(pointInfo);
400                         } },
401                     { "topPoint",
402                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, ChartOptions& chartOptions) {
403                             PointInfo pointInfo;
404                             GetAttrOptionsSeriesPoint(ctx, valObject, pointInfo);
405                             chartOptions.SetTopPoint(pointInfo);
406                         } },
407                     { "bottomPoint",
408                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, ChartOptions& chartOptions) {
409                             PointInfo pointInfo;
410                             GetAttrOptionsSeriesPoint(ctx, valObject, pointInfo);
411                             chartOptions.SetBottomPoint(pointInfo);
412                         } },
413                 };
414             auto iter = chartOptionsSeriesMap.find(keyStr);
415             if (iter != chartOptionsSeriesMap.end()) {
416                 iter->second(ctx, val, chartOptions);
417             } else {
418                 LOGD("key : %{public}s unsupported. Ignoring!", keyStr);
419             }
420         } else {
421             LOGD("value of unsupported type. Ignoring!");
422         }
423     }
424 }
425 
ParseTextInfoAndSegmentInfo(v8::Local<v8::Context> ctx,v8::Local<v8::Value> val,const char * keyStr,TextInfo & textInfo,SegmentInfo & segmentInfo)426 void ParseTextInfoAndSegmentInfo(v8::Local<v8::Context> ctx, v8::Local<v8::Value> val, const char* keyStr,
427     TextInfo& textInfo, SegmentInfo& segmentInfo)
428 {
429     v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
430     const char* valStr = *valV8Str;
431     if (valStr == nullptr) {
432         LOGI("fail to parse style in chart. Ignoring!");
433         return;
434     }
435     if (strcmp(keyStr, "description") == 0) {
436         textInfo.SetTextValue(valStr);
437     } else if (strcmp(keyStr, "textLocation") == 0) {
438         if (strcmp(valStr, "top") == 0) {
439             textInfo.SetPlacement(Placement::TOP);
440         } else if (strcmp(valStr, "bottom") == 0) {
441             textInfo.SetPlacement(Placement::BOTTOM);
442         } else if (strcmp(valStr, "none") == 0) {
443             textInfo.SetPlacement(Placement::NONE);
444         }
445     } else if (strcmp(keyStr, "lineDash") == 0) {
446         std::vector<std::string> dash;
447         StringUtils::StringSplitter(valStr, ',', dash);
448         if (dash.size() == 1 || dash.size() == 3) {
449             if (dash[0] == "dashed") {
450                 segmentInfo.SetLineType(LineType::DASHED);
451             } else {
452                 segmentInfo.SetLineType(LineType::SOLID);
453             }
454             if (dash.size() > 1) {
455                 segmentInfo.SetSolidWidth(StringToDouble(dash[1]));
456             }
457             if (dash.size() > 2) {
458                 segmentInfo.SetSpaceWidth(StringToDouble(dash[2]));
459             }
460         }
461     } else if (strcmp(keyStr, "lineColor") == 0) {
462         segmentInfo.SetSegmentColor(Color::FromString(valStr));
463     } else if (strcmp(keyStr, "textColor") == 0) {
464         textInfo.SetColor(Color::FromString(valStr));
465     } else {
466         LOGD("key : %{public}s unsupported. Ignoring!", keyStr);
467     }
468 }
469 
ParseAttrDataStyle(v8::Local<v8::Context> ctx,v8::Local<v8::Value> valObject,LineInfo & line,double index)470 void ParseAttrDataStyle(v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, LineInfo& line, double index)
471 {
472     v8::Isolate* isolate = ctx->GetIsolate();
473     v8::HandleScope handleScope(isolate);
474 
475     if (!valObject->IsObject()) {
476         LOGE("none found attrs");
477         return;
478     }
479 
480     v8::Local<v8::Object> v8ValObj;
481     if (!valObject->ToObject(ctx).ToLocal(&v8ValObj)) {
482         LOGE("Value to Object fail");
483         return;
484     }
485     v8::Local<v8::Array> properties = v8ValObj->GetOwnPropertyNames(ctx).ToLocalChecked();
486     int32_t len = properties->Length();
487     PointInfo pointInfo;
488     TextInfo textInfo;
489     SegmentInfo segmentInfo;
490     for (int32_t i = 0; i < len; i++) {
491         v8::Local<v8::Value> key;
492         if (!properties->Get(ctx, i).ToLocal(&key)) {
493             LOGW("key is null. Ignoring!");
494             continue;
495         }
496         v8::String::Utf8Value keyV8Str(isolate, key);
497         const char* keyStr = *keyV8Str;
498         if (keyStr == nullptr) {
499             continue;
500         }
501         v8::Local<v8::Value> val = v8ValObj->Get(ctx, key).ToLocalChecked();
502         if (val->IsNumber()) {
503             if (strcmp(keyStr, "value") == 0) {
504                 auto numberValue = val->ToNumber(ctx).ToLocalChecked();
505                 pointInfo.SetX(index);
506                 if (numberValue.IsEmpty()) {
507                     continue;
508                 }
509                 pointInfo.SetY(numberValue->Value());
510             }
511         } else if (val->IsString()) {
512             ParseTextInfoAndSegmentInfo(ctx, val, keyStr, textInfo, segmentInfo);
513         } else if (val->IsObject()) {
514             if (strcmp(keyStr, "pointStyle") == 0) {
515                 GetAttrOptionsSeriesPoint(ctx, val, pointInfo);
516             }
517         }
518     }
519     line.SetPointInfo(pointInfo);
520     line.SetSegmentInfo(segmentInfo);
521     line.SetTextInfo(textInfo);
522 }
523 
GetAttrDataSetData(v8::Local<v8::Context> ctx,v8::Local<v8::Value> dataArrayVal,MainChart & dataSet)524 void GetAttrDataSetData(v8::Local<v8::Context> ctx, v8::Local<v8::Value> dataArrayVal, MainChart& dataSet)
525 {
526     v8::Isolate* isolate = ctx->GetIsolate();
527     v8::HandleScope handleScope(isolate);
528 
529     v8::Local<v8::Object> v8DataArrayVal = dataArrayVal->ToObject(ctx).ToLocalChecked();
530     if (!dataArrayVal->ToObject(ctx).ToLocal(&v8DataArrayVal)) {
531         LOGE("Value to Object fail");
532         return;
533     }
534     v8::Local<v8::Array> properties = v8DataArrayVal->GetOwnPropertyNames(ctx).ToLocalChecked();
535     int32_t subLen = properties->Length();
536 
537     std::vector<LineInfo> points;
538     for (int32_t j = 0; j < subLen; ++j) {
539         v8::Local<v8::Value> itemKey = properties->Get(ctx, j).ToLocalChecked();
540         v8::Local<v8::Value> dataArrayItemVal = v8DataArrayVal->Get(ctx, itemKey).ToLocalChecked();
541         LineInfo lineInfo;
542         PointInfo pointInfo;
543         if (dataArrayItemVal->IsArray()) { // Coordinates are two-dimensional arrays
544             v8::Local<v8::Array> itemArray = v8::Local<v8::Array>::Cast(dataArrayItemVal);
545             uint32_t dataArrayIterLen = itemArray->Length();
546 
547             if (dataArrayIterLen != VALID_ARRAY_LENGTH) { // Check coordinates are not two-dimensional arrays
548                 LOGW("Attr Datasets data type unsupported!");
549                 continue;
550             }
551             v8::Local<v8::Value> xVal = itemArray->Get(ctx, ARRAY_X_VALUE).ToLocalChecked();
552             v8::String::Utf8Value xValV8Str(isolate, xVal);
553             const char* x = *xValV8Str;
554             if (x != nullptr) {
555                 pointInfo.SetX(StringToDouble(x));
556             }
557 
558             v8::Local<v8::Value> yVal = itemArray->Get(ctx, ARRAY_Y_VALUE).ToLocalChecked();
559             v8::String::Utf8Value yValV8Str(isolate, yVal);
560             const char* y = *yValV8Str;
561             if (y != nullptr) {
562                 pointInfo.SetY(StringToDouble(y));
563             }
564             lineInfo.SetPointInfo(pointInfo);
565         } else if (dataArrayItemVal->IsNumber()) { // Coordinates as a one-dimensional array
566             v8::String::Utf8Value onlyYStringVal(isolate, dataArrayItemVal);
567             const char* onlyY = *onlyYStringVal;
568             if (onlyY != nullptr) {
569                 // When only the Y value is passed in, the X value is sequentially +1
570                 pointInfo.SetX(static_cast<double>(j));
571                 pointInfo.SetY(StringToDouble(onlyY));
572             }
573             lineInfo.SetPointInfo(pointInfo);
574         } else if (dataArrayItemVal->IsObject()) {
575             ParseAttrDataStyle(ctx, dataArrayItemVal, lineInfo, static_cast<double>(j));
576         } else {
577             LOGW("value of unsupported type. Ignoring!");
578             continue;
579         }
580         points.push_back(lineInfo);
581     }
582     dataSet.SetData(points);
583 }
584 
ParseAttrSegment(v8::Local<v8::Context> ctx,v8::Local<v8::Value> valObject,Segment & segment)585 void ParseAttrSegment(v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, Segment& segment)
586 {
587     v8::Isolate* isolate = ctx->GetIsolate();
588     v8::HandleScope handleScope(isolate);
589 
590     if (!valObject->IsObject()) {
591         LOGE("none found attrs");
592         return;
593     }
594 
595     v8::Local<v8::Object> v8ValObj;
596     if (!valObject->ToObject(ctx).ToLocal(&v8ValObj)) {
597         LOGE("Value to Object fail");
598         return;
599     }
600     v8::Local<v8::Array> properties = v8ValObj->GetOwnPropertyNames(ctx).ToLocalChecked();
601     int32_t len = properties->Length();
602 
603     for (int32_t i = 0; i < len; i++) {
604         v8::Local<v8::Value> key;
605         if (!properties->Get(ctx, i).ToLocal(&key)) {
606             LOGW("key is null. Ignoring!");
607             continue;
608         }
609         v8::String::Utf8Value keyV8Str(isolate, key);
610         const char* keyStr = *keyV8Str;
611         if (keyStr == nullptr) {
612             continue;
613         }
614         v8::Local<v8::Value> val = v8ValObj->Get(ctx, key).ToLocalChecked();
615         if (!val->IsNumber() && !val->IsString()) {
616             LOGI("value of unsupported type in chart. Ignoring!");
617             continue;
618         }
619         v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
620         const char* valStr = *valV8Str;
621         if (valStr == nullptr) {
622             LOGI("fail to parse style in chart. Ignoring!");
623             continue;
624         }
625         if (strcmp(keyStr, "gradient") == 0) {
626             segment.SetColorDescriptor(valStr);
627             segment.SetColorType(SegmentStyleType::USE_GRADIENT);
628         } else if (strcmp(keyStr, "startColor") == 0) {
629             segment.SetStartColor(Color::FromString(valStr));
630             if (segment.GetColorType() != SegmentStyleType::USE_GRADIENT) {
631                 segment.SetColorType(SegmentStyleType::USE_COLOR);
632             }
633         } else if (strcmp(keyStr, "endColor") == 0) {
634             segment.SetEndColor(Color::FromString(valStr));
635             if (segment.GetColorType() != SegmentStyleType::USE_GRADIENT) {
636                 segment.SetColorType(SegmentStyleType::USE_COLOR);
637             }
638         } else if (strcmp(keyStr, "value") == 0) {
639             segment.SetValue(StringToDouble(valStr));
640         } else if (strcmp(keyStr, "name") == 0) {
641             segment.SetSegmentName(valStr);
642         } else {
643             LOGI("key : %{public}s unsupported. Ignoring!", keyStr);
644         }
645     }
646 }
647 
GetAttrDataset(v8::Local<v8::Context> ctx,v8::Local<v8::Value> valObject,MainChart & dataSet)648 void GetAttrDataset(v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, MainChart& dataSet)
649 {
650     v8::Isolate* isolate = ctx->GetIsolate();
651     v8::HandleScope handleScope(isolate);
652 
653     if (!valObject->IsObject()) {
654         LOGE("none found attrs");
655         return;
656     }
657     v8::Local<v8::Object> v8ValObj;
658     if (!valObject->ToObject(ctx).ToLocal(&v8ValObj)) {
659         LOGE("Value to Object fail");
660         return;
661     }
662     v8::Local<v8::Array> properties = v8ValObj->GetOwnPropertyNames(ctx).ToLocalChecked();
663     int32_t len = properties->Length();
664 
665     for (int32_t i = 0; i < len; i++) {
666         v8::Local<v8::Value> key;
667         if (!properties->Get(ctx, i).ToLocal(&key)) {
668             LOGW("key is null. Ignoring!");
669             continue;
670         }
671         v8::String::Utf8Value keyV8Str(isolate, key);
672         const char* keyStr = *keyV8Str;
673         if (keyStr == nullptr) {
674             continue;
675         }
676         v8::Local<v8::Value> val = v8ValObj->Get(ctx, key).ToLocalChecked();
677         if (val->IsNumber() || val->IsBoolean() || val->IsString()) {
678             v8::String::Utf8Value valV8Str(ctx->GetIsolate(), val);
679             const char* valStr = *valV8Str;
680 
681             if (valStr != nullptr) {
682                 if (strcmp(keyStr, "gradient") == 0) {
683                     dataSet.SetGradient(StringToBool(valStr));
684                 } else if (strcmp(keyStr, "strokeColor") == 0) {
685                     dataSet.SetStrokeColor(Color::FromString(valStr));
686                 } else if (strcmp(keyStr, "fillColor") == 0) {
687                     dataSet.SetFillColor(Color::FromString(valStr));
688                 } else {
689                     LOGD("key : %{public}s unsupported. Ignoring!", keyStr);
690                 }
691             }
692         } else if (val->IsArray() || strcmp(keyStr, "data") == 0) {
693             GetAttrDataSetData(ctx, val, dataSet);
694         } else {
695             LOGD("value of unsupported type. Ignoring!");
696         }
697     }
698 }
699 
700 } // namespace
701 
GetAttrOptionsObject(v8::Local<v8::Context> ctx,v8::Local<v8::Value> valObject)702 void V8ChartBridge::GetAttrOptionsObject(v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject)
703 {
704     v8::Isolate* isolate = ctx->GetIsolate();
705     v8::HandleScope handleScope(isolate);
706 
707     if (!valObject->IsObject()) {
708         LOGE("none found attrs");
709         return;
710     }
711     v8::Local<v8::Object> v8ValObj;
712     if (!valObject->ToObject(ctx).ToLocal(&v8ValObj)) {
713         LOGE("Value to Object fail");
714         return;
715     }
716     v8::Local<v8::Array> properties = v8ValObj->GetOwnPropertyNames(ctx).ToLocalChecked();
717     int32_t len = properties->Length();
718     for (int32_t i = 0; i < len; i++) {
719         v8::Local<v8::Value> key;
720         if (!properties->Get(ctx, i).ToLocal(&key)) {
721             LOGW("key is null. Ignoring!");
722             continue;
723         }
724         v8::String::Utf8Value keyV8Str(isolate, key);
725         const char* keyStr = *keyV8Str;
726         if (keyStr == nullptr) {
727             continue;
728         }
729         v8::Local<v8::Value> val = v8ValObj->Get(ctx, key).ToLocalChecked();
730         if (val->IsObject() || val->IsString() || val->IsBoolean() || val->IsNumber()) {
731             static const std::unordered_map<std::string,
732                 void (*)(v8::Local<v8::Context>, v8::Local<v8::Value>, ChartOptions&)>
733                 chartOptionsMap = {
734                     { "xAxis",
735                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, ChartOptions& chartOptions) {
736                             AxisOption xAxis;
737                             GetAttrOptionsAxis(ctx, valObject, xAxis);
738                             chartOptions.SetXAxis(xAxis);
739                         } },
740                     { "yAxis",
741                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, ChartOptions& chartOptions) {
742                             AxisOption yAxis;
743                             GetAttrOptionsAxis(ctx, valObject, yAxis);
744                             chartOptions.SetYAxis(yAxis);
745                         } },
746                     { "series",
747                         [](v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject, ChartOptions& chartOptions) {
748                             GetChartAttrOptionsSeries(ctx, valObject, chartOptions);
749                         } },
750                 };
751 
752             auto iter = chartOptionsMap.find(keyStr);
753 
754             if (iter != chartOptionsMap.end()) {
755                 iter->second(ctx, val, chartOptions_);
756             } else {
757                 LOGD("key : %{public}s unsupported. Ignoring!", keyStr);
758             }
759         } else {
760             LOGD("value of unsupported type. Ignoring!");
761         }
762     }
763 }
764 
GetAttrDatasets(v8::Local<v8::Context> ctx,v8::Local<v8::Value> valArray)765 void V8ChartBridge::GetAttrDatasets(v8::Local<v8::Context> ctx, v8::Local<v8::Value> valArray)
766 {
767     v8::Isolate* isolate = ctx->GetIsolate();
768     v8::HandleScope handleScope(isolate);
769 
770     v8::Local<v8::Object> v8ValObj;
771     if (!valArray->ToObject(ctx).ToLocal(&v8ValObj)) {
772         LOGE("Value to Object fail");
773         return;
774     }
775     v8::Local<v8::Array> properties = v8ValObj->GetOwnPropertyNames(ctx).ToLocalChecked();
776     int32_t len = properties->Length();
777 
778     for (int32_t i = 0; i < len; ++i) {
779         v8::Local<v8::Value> itemKey = properties->Get(ctx, i).ToLocalChecked();
780         v8::Local<v8::Value> itemVal = v8ValObj->Get(ctx, itemKey).ToLocalChecked();
781         MainChart chart;
782         if (itemVal->IsObject()) {
783             GetAttrDataset(ctx, itemVal, chart);
784             datasets_.push_back(chart);
785         }
786     }
787 }
788 
ParseAttrSegmentArray(v8::Local<v8::Context> ctx,v8::Local<v8::Value> valArray)789 void V8ChartBridge::ParseAttrSegmentArray(v8::Local<v8::Context> ctx, v8::Local<v8::Value> valArray)
790 {
791     v8::Isolate* isolate = ctx->GetIsolate();
792     v8::HandleScope handleScope(isolate);
793 
794     v8::Local<v8::Object> v8ValObj;
795     if (valArray->ToObject(ctx).IsEmpty() || !valArray->ToObject(ctx).ToLocal(&v8ValObj)) {
796         LOGE("Value to Object fail");
797         return;
798     }
799     v8::Local<v8::Array> properties = v8ValObj->GetOwnPropertyNames(ctx).ToLocalChecked();
800     int32_t len = properties->Length();
801 
802     for (int32_t i = 0; i < len; ++i) {
803         v8::Local<v8::Value> itemKey = properties->Get(ctx, i).ToLocalChecked();
804         v8::Local<v8::Value> itemVal = v8ValObj->Get(ctx, itemKey).ToLocalChecked();
805 
806         if (itemVal->IsObject()) {
807             Segment segment;
808             ParseAttrSegment(ctx, itemVal, segment);
809             segments_.push_back(segment);
810         }
811     }
812 }
813 
ParseAttrSingleSegment(v8::Local<v8::Context> ctx,v8::Local<v8::Value> valObject)814 void V8ChartBridge::ParseAttrSingleSegment(v8::Local<v8::Context> ctx, v8::Local<v8::Value> valObject)
815 {
816     segments_.clear();
817     Segment segment;
818     ParseAttrSegment(ctx, valObject, segment);
819     segments_.push_back(segment);
820 }
821 
822 } // namespace OHOS::Ace::Framework