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