• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "bridge/declarative_frontend/jsview/js_data_panel.h"
17 
18 #include <vector>
19 
20 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
21 #include "bridge/declarative_frontend/jsview/js_linear_gradient.h"
22 #include "bridge/declarative_frontend/jsview/js_utils.h"
23 #include "bridge/declarative_frontend/jsview/models/data_panel_model_impl.h"
24 #include "core/components/data_panel/data_panel_theme.h"
25 #include "core/components_ng/pattern/data_panel/data_panel_model_ng.h"
26 
27 namespace OHOS::Ace {
28 
29 std::unique_ptr<DataPanelModel> DataPanelModel::instance_ = nullptr;
30 std::mutex DataPanelModel::mutex_;
31 
GetInstance()32 DataPanelModel* DataPanelModel::GetInstance()
33 {
34     if (!instance_) {
35         std::lock_guard<std::mutex> lock(mutex_);
36         if (!instance_) {
37 #ifdef NG_BUILD
38             instance_.reset(new NG::DataPanelModelNG());
39 #else
40             if (Container::IsCurrentUseNewPipeline()) {
41                 instance_.reset(new NG::DataPanelModelNG());
42             } else {
43                 instance_.reset(new Framework::DataPanelModelImpl());
44             }
45 #endif
46         }
47     }
48     return instance_.get();
49 }
50 
51 } // namespace OHOS::Ace
52 namespace OHOS::Ace::Framework {
53 
54 constexpr size_t MAX_COUNT = 9;
55 
JSBind(BindingTarget globalObj)56 void JSDataPanel::JSBind(BindingTarget globalObj)
57 {
58     JSClass<JSDataPanel>::Declare("DataPanel");
59     JSClass<JSDataPanel>::StaticMethod("create", &JSDataPanel::Create);
60     JSClass<JSDataPanel>::StaticMethod("closeEffect", &JSDataPanel::CloseEffect);
61 
62     JSClass<JSDataPanel>::StaticMethod("valueColors", &JSDataPanel::ValueColors);
63     JSClass<JSDataPanel>::StaticMethod("trackBackgroundColor", &JSDataPanel::TrackBackground);
64     JSClass<JSDataPanel>::StaticMethod("strokeWidth", &JSDataPanel::StrokeWidth);
65     JSClass<JSDataPanel>::StaticMethod("trackShadow", &JSDataPanel::ShadowOption);
66 
67     JSClass<JSDataPanel>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
68     JSClass<JSDataPanel>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
69     JSClass<JSDataPanel>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
70     JSClass<JSDataPanel>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
71     JSClass<JSDataPanel>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
72     JSClass<JSDataPanel>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
73     JSClass<JSDataPanel>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
74 
75     JSClass<JSDataPanel>::InheritAndBind<JSViewAbstract>(globalObj);
76 }
77 
Create(const JSCallbackInfo & info)78 void JSDataPanel::Create(const JSCallbackInfo& info)
79 {
80     if (!info[0]->IsObject()) {
81         return;
82     }
83     auto param = JsonUtil::ParseJsonString(info[0]->ToString());
84     if (!param || param->IsNull()) {
85         return;
86     }
87     // max
88     auto max = param->GetDouble("max", 100.0);
89     // values
90     auto values = param->GetValue("values");
91     if (!values || !values->IsArray()) {
92         return;
93     }
94     auto type = param->GetValue("type");
95     size_t length = static_cast<size_t>(values->GetArraySize());
96     std::vector<double> dateValues;
97     double dataSum = 0.0;
98     for (size_t i = 0; i < length && i < MAX_COUNT; i++) {
99         auto item = values->GetArrayItem(i);
100         if (!item || !item->IsNumber()) {
101             continue;
102         }
103         auto value = item->GetDouble();
104         if (LessOrEqual(value, 0.0)) {
105             value = 0.0;
106         }
107         dataSum += value;
108         if (GreatOrEqual(dataSum, max) && max > 0) {
109             value = max - (dataSum - value);
110             if (NearEqual(value, 0.0)) {
111                 break;
112             }
113         }
114         dateValues.emplace_back(value);
115     }
116     if (LessOrEqual(max, 0.0)) {
117         max = dataSum;
118     }
119     size_t dataPanelType = 0;
120     if (type->IsNumber()) {
121         if (type->GetInt() == static_cast<int32_t>(ChartType::LINE)) {
122             dataPanelType = 1;
123         } else if (type->GetInt() == static_cast<int32_t>(ChartType::RAINBOW)) {
124             dataPanelType = 0;
125         }
126     }
127     DataPanelModel::GetInstance()->Create(dateValues, max, dataPanelType);
128 }
129 
CloseEffect(const JSCallbackInfo & info)130 void JSDataPanel::CloseEffect(const JSCallbackInfo& info)
131 {
132     bool isCloseEffect = true;
133     if (info[0]->IsBoolean()) {
134         isCloseEffect = info[0]->ToBoolean();
135     }
136     DataPanelModel::GetInstance()->SetEffect(isCloseEffect);
137 }
138 
ValueColors(const JSCallbackInfo & info)139 void JSDataPanel::ValueColors(const JSCallbackInfo& info)
140 {
141     if (info.Length() < 1) {
142         return;
143     }
144 
145     std::vector<OHOS::Ace::NG::Gradient> valueColors;
146     if (!info[0]->IsArray() || info[0]->IsEmpty()) {
147         ConvertThemeColor(valueColors);
148         DataPanelModel::GetInstance()->SetValueColors(valueColors);
149         return;
150     }
151 
152     auto paramArray = JSRef<JSArray>::Cast(info[0]);
153     size_t length = paramArray->Length();
154     for (size_t i = 0; i < length && i < MAX_COUNT; i++) {
155         auto item = paramArray->GetValueAt(i);
156         OHOS::Ace::NG::Gradient gradient;
157         if (!ConvertGradientColor(item, gradient)) {
158             valueColors.clear();
159             ConvertThemeColor(valueColors);
160             break;
161         }
162         valueColors.emplace_back(gradient);
163     }
164     DataPanelModel::GetInstance()->SetValueColors(valueColors);
165 }
166 
TrackBackground(const JSCallbackInfo & info)167 void JSDataPanel::TrackBackground(const JSCallbackInfo& info)
168 {
169     if (info.Length() < 1) {
170         return;
171     }
172     Color color;
173     if (!ParseJsColor(info[0], color)) {
174         RefPtr<DataPanelTheme> theme = GetTheme<DataPanelTheme>();
175         color = theme->GetBackgroundColor();
176     }
177 
178     DataPanelModel::GetInstance()->SetTrackBackground(color);
179 }
180 
StrokeWidth(const JSCallbackInfo & info)181 void JSDataPanel::StrokeWidth(const JSCallbackInfo& info)
182 {
183     if (info.Length() < 1) {
184         return;
185     }
186 
187     RefPtr<DataPanelTheme> theme = GetTheme<DataPanelTheme>();
188     CalcDimension strokeWidthDimension;
189     if (!ParseJsDimensionVp(info[0], strokeWidthDimension)) {
190         strokeWidthDimension = theme->GetThickness();
191     }
192 
193     // If the parameter value is string(''), parse result 0.
194     // The value of 0 is allowed, but the value of string('') is not allowed, so use theme value.
195     if (info[0]->IsString() && info[0]->ToString().empty()) {
196         strokeWidthDimension = theme->GetThickness();
197     }
198 
199     if (strokeWidthDimension.IsNegative() || strokeWidthDimension.Unit() == DimensionUnit::PERCENT) {
200         strokeWidthDimension = theme->GetThickness();
201     }
202     DataPanelModel::GetInstance()->SetStrokeWidth(strokeWidthDimension);
203 }
204 
ShadowOption(const JSCallbackInfo & info)205 void JSDataPanel::ShadowOption(const JSCallbackInfo& info)
206 {
207     OHOS::Ace::NG::DataPanelShadow shadow;
208     if (info[0]->IsNull()) {
209         shadow.isShadowVisible = false;
210         DataPanelModel::GetInstance()->SetShadowOption(shadow);
211         return;
212     }
213     if (!info[0]->IsObject()) {
214         return;
215     }
216     auto paramObject = JSRef<JSObject>::Cast(info[0]);
217     JSRef<JSVal> jsRadius = paramObject->GetProperty("radius");
218     JSRef<JSVal> jsOffsetX = paramObject->GetProperty("offsetX");
219     JSRef<JSVal> jsOffsetY = paramObject->GetProperty("offsetY");
220 
221     RefPtr<DataPanelTheme> theme = GetTheme<DataPanelTheme>();
222     double radius = 0.0;
223     if (!ParseJsDouble(jsRadius, radius)) {
224         radius = theme->GetTrackShadowRadius().ConvertToVp();
225     }
226 
227     if (NonPositive(radius)) {
228         radius = theme->GetTrackShadowRadius().ConvertToVp();
229     }
230 
231     double offsetX = 0.0;
232     if (!ParseJsDouble(jsOffsetX, offsetX)) {
233         offsetX = theme->GetTrackShadowOffsetX().ConvertToVp();
234     }
235 
236     double offsetY = 0.0;
237     if (!ParseJsDouble(jsOffsetY, offsetY)) {
238         offsetY = theme->GetTrackShadowOffsetY().ConvertToVp();
239     }
240 
241     std::vector<OHOS::Ace::NG::Gradient> shadowColors;
242     auto colors = paramObject->GetProperty("colors");
243     if (!colors->IsEmpty() && colors->IsArray()) {
244         auto colorsArray = JSRef<JSArray>::Cast(colors);
245         for (size_t i = 0; i < colorsArray->Length(); i++) {
246             auto item = colorsArray->GetValueAt(i);
247             OHOS::Ace::NG::Gradient gradient;
248             if (!ConvertGradientColor(item, gradient)) {
249                 shadowColors.clear();
250                 ConvertThemeColor(shadowColors);
251                 break;
252             }
253             shadowColors.emplace_back(gradient);
254         }
255     }
256 
257     shadow.radius = radius;
258     shadow.offsetX = offsetX;
259     shadow.offsetY = offsetY;
260     shadow.colors = shadowColors;
261     DataPanelModel::GetInstance()->SetShadowOption(shadow);
262 }
263 
ConvertGradientColor(const JsiRef<JsiValue> & itemParam,OHOS::Ace::NG::Gradient & gradient)264 bool JSDataPanel::ConvertGradientColor(const JsiRef<JsiValue>& itemParam, OHOS::Ace::NG::Gradient& gradient)
265 {
266     if (!itemParam->IsObject()) {
267         return ConvertResourceColor(itemParam, gradient);
268     }
269 
270     JSLinearGradient* jsLinearGradient = JSRef<JSObject>::Cast(itemParam)->Unwrap<JSLinearGradient>();
271     if (!jsLinearGradient) {
272         return ConvertResourceColor(itemParam, gradient);
273     }
274 
275     size_t colorLength = jsLinearGradient->GetGradient().size();
276     for (size_t colorIndex = 0; colorIndex < colorLength; colorIndex++) {
277         OHOS::Ace::NG::GradientColor gradientColor;
278         gradientColor.SetLinearColor(LinearColor(jsLinearGradient->GetGradient().at(colorIndex).first));
279         gradientColor.SetDimension(jsLinearGradient->GetGradient().at(colorIndex).second);
280         gradient.AddColor(gradientColor);
281     }
282     return true;
283 }
284 
ConvertResourceColor(const JsiRef<JsiValue> & itemParam,OHOS::Ace::NG::Gradient & gradient)285 bool JSDataPanel::ConvertResourceColor(const JsiRef<JsiValue>& itemParam, OHOS::Ace::NG::Gradient& gradient)
286 {
287     Color color;
288     if (!ParseJsColor(itemParam, color)) {
289         LOGE("ParseJsColor error.");
290         return false;
291     }
292     OHOS::Ace::NG::GradientColor gradientColorStart;
293     gradientColorStart.SetLinearColor(LinearColor(color));
294     gradientColorStart.SetDimension(Dimension(0.0));
295     gradient.AddColor(gradientColorStart);
296     OHOS::Ace::NG::GradientColor gradientColorEnd;
297     gradientColorEnd.SetLinearColor(LinearColor(color));
298     gradientColorEnd.SetDimension(Dimension(1.0));
299     gradient.AddColor(gradientColorEnd);
300     return true;
301 }
302 
ConvertThemeColor(std::vector<OHOS::Ace::NG::Gradient> & colors)303 void JSDataPanel::ConvertThemeColor(std::vector<OHOS::Ace::NG::Gradient>& colors)
304 {
305     RefPtr<DataPanelTheme> theme = GetTheme<DataPanelTheme>();
306     auto themeColors = theme->GetColorsArray();
307     for (const auto& item : themeColors) {
308         OHOS::Ace::NG::Gradient gradient;
309         OHOS::Ace::NG::GradientColor gradientColorStart;
310         gradientColorStart.SetLinearColor(LinearColor(item.first));
311         gradientColorStart.SetDimension(Dimension(0.0));
312         gradient.AddColor(gradientColorStart);
313         OHOS::Ace::NG::GradientColor gradientColorEnd;
314         gradientColorEnd.SetLinearColor(LinearColor(item.second));
315         gradientColorEnd.SetDimension(Dimension(1.0));
316         gradient.AddColor(gradientColorEnd);
317         colors.emplace_back(gradient);
318     }
319 }
320 } // namespace OHOS::Ace::Framework
321