layrz-sdk 3.1.14__py3-none-any.whl → 3.1.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of layrz-sdk might be problematic. Click here for more details.
- layrz_sdk/__init__.py +1 -1
- layrz_sdk/constants.py +19 -5
- layrz_sdk/entities/__init__.py +138 -129
- layrz_sdk/entities/asset.py +76 -60
- layrz_sdk/entities/asset_operation_mode.py +31 -31
- layrz_sdk/entities/broadcast_request.py +12 -12
- layrz_sdk/entities/broadcast_response.py +12 -12
- layrz_sdk/entities/broadcast_result.py +20 -20
- layrz_sdk/entities/broadcast_status.py +28 -28
- layrz_sdk/entities/case.py +52 -52
- layrz_sdk/entities/case_ignored_status.py +26 -26
- layrz_sdk/entities/case_status.py +23 -23
- layrz_sdk/entities/charts/axis_config.py +15 -15
- layrz_sdk/entities/charts/bar_chart.py +175 -175
- layrz_sdk/entities/charts/chart_alignment.py +27 -27
- layrz_sdk/entities/charts/chart_color.py +44 -44
- layrz_sdk/entities/charts/chart_configuration.py +10 -10
- layrz_sdk/entities/charts/chart_data_serie.py +19 -19
- layrz_sdk/entities/charts/chart_data_serie_type.py +28 -28
- layrz_sdk/entities/charts/chart_data_type.py +27 -27
- layrz_sdk/entities/charts/chart_render_technology.py +30 -30
- layrz_sdk/entities/charts/column_chart.py +201 -201
- layrz_sdk/entities/charts/html_chart.py +38 -38
- layrz_sdk/entities/charts/line_chart.py +248 -248
- layrz_sdk/entities/charts/map_center_type.py +22 -22
- layrz_sdk/entities/charts/map_chart.py +108 -108
- layrz_sdk/entities/charts/map_point.py +22 -22
- layrz_sdk/entities/charts/number_chart.py +54 -54
- layrz_sdk/entities/charts/pie_chart.py +131 -131
- layrz_sdk/entities/charts/radar_chart.py +81 -81
- layrz_sdk/entities/charts/radial_bar_chart.py +131 -131
- layrz_sdk/entities/charts/scatter_chart.py +210 -210
- layrz_sdk/entities/charts/scatter_serie.py +13 -13
- layrz_sdk/entities/charts/scatter_serie_item.py +8 -8
- layrz_sdk/entities/charts/table_chart.py +54 -54
- layrz_sdk/entities/charts/table_header.py +8 -8
- layrz_sdk/entities/charts/table_row.py +9 -9
- layrz_sdk/entities/charts/timeline_chart.py +79 -79
- layrz_sdk/entities/charts/timeline_serie.py +10 -10
- layrz_sdk/entities/charts/timeline_serie_item.py +12 -12
- layrz_sdk/entities/checkpoint.py +17 -17
- layrz_sdk/entities/comment.py +16 -16
- layrz_sdk/entities/custom_field.py +10 -10
- layrz_sdk/entities/custom_report_page.py +40 -40
- layrz_sdk/entities/device.py +18 -13
- layrz_sdk/entities/event.py +23 -23
- layrz_sdk/entities/geofence.py +11 -11
- layrz_sdk/entities/last_message.py +12 -12
- layrz_sdk/entities/message.py +23 -23
- layrz_sdk/entities/modbus/__init__.py +9 -0
- layrz_sdk/entities/modbus/config.py +19 -0
- layrz_sdk/entities/modbus/parameter.py +110 -0
- layrz_sdk/entities/modbus/schema.py +10 -0
- layrz_sdk/entities/modbus/status.py +16 -0
- layrz_sdk/entities/modbus/wait.py +134 -0
- layrz_sdk/entities/outbound_service.py +10 -10
- layrz_sdk/entities/position.py +116 -116
- layrz_sdk/entities/presence_type.py +16 -16
- layrz_sdk/entities/report.py +289 -289
- layrz_sdk/entities/report_col.py +40 -40
- layrz_sdk/entities/report_configuration.py +8 -8
- layrz_sdk/entities/report_data_type.py +28 -28
- layrz_sdk/entities/report_format.py +27 -27
- layrz_sdk/entities/report_header.py +43 -43
- layrz_sdk/entities/report_page.py +15 -15
- layrz_sdk/entities/report_row.py +28 -28
- layrz_sdk/entities/sensor.py +11 -11
- layrz_sdk/entities/static_position.py +17 -0
- layrz_sdk/entities/telemetry/__init__.py +6 -0
- layrz_sdk/entities/telemetry/assetmessage.py +159 -0
- layrz_sdk/entities/telemetry/devicemessage.py +122 -0
- layrz_sdk/entities/text_alignment.py +26 -26
- layrz_sdk/entities/trigger.py +11 -11
- layrz_sdk/entities/user.py +10 -10
- layrz_sdk/entities/waypoint.py +18 -18
- layrz_sdk/helpers/__init__.py +5 -5
- layrz_sdk/helpers/color.py +44 -44
- layrz_sdk/lcl/__init__.py +5 -5
- layrz_sdk/lcl/core.py +848 -848
- {layrz_sdk-3.1.14.dist-info → layrz_sdk-3.1.16.dist-info}/METADATA +54 -49
- layrz_sdk-3.1.16.dist-info/RECORD +85 -0
- {layrz_sdk-3.1.14.dist-info → layrz_sdk-3.1.16.dist-info}/licenses/LICENSE +6 -6
- layrz_sdk-3.1.14.dist-info/RECORD +0 -75
- {layrz_sdk-3.1.14.dist-info → layrz_sdk-3.1.16.dist-info}/WHEEL +0 -0
- {layrz_sdk-3.1.14.dist-info → layrz_sdk-3.1.16.dist-info}/top_level.txt +0 -0
layrz_sdk/entities/case.py
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
"""Events entities"""
|
|
2
|
-
|
|
3
|
-
import sys
|
|
4
|
-
from datetime import datetime
|
|
5
|
-
from typing import Any, Optional
|
|
6
|
-
|
|
7
|
-
from pydantic import BaseModel, Field, model_validator
|
|
8
|
-
|
|
9
|
-
from .case_ignored_status import CaseIgnoredStatus
|
|
10
|
-
from .case_status import CaseStatus
|
|
11
|
-
from .comment import Comment
|
|
12
|
-
from .trigger import Trigger
|
|
13
|
-
|
|
14
|
-
if sys.version_info >= (3, 11):
|
|
15
|
-
from typing import Self
|
|
16
|
-
else:
|
|
17
|
-
from typing_extensions import Self
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class Case(BaseModel):
|
|
21
|
-
"""Case entity"""
|
|
22
|
-
|
|
23
|
-
pk: int = Field(description='Defines the primary key of the case')
|
|
24
|
-
trigger: Trigger = Field(description='Defines the trigger of the case')
|
|
25
|
-
asset_id: int = Field(description='Defines the asset ID of the case')
|
|
26
|
-
comments: list[Comment] = Field(default_factory=list, description='Defines the comments of the case')
|
|
27
|
-
opened_at: datetime = Field(description='Defines the date when the case was opened')
|
|
28
|
-
closed_at: Optional[datetime] = Field(default=None, description='Defines the date when the case was closed')
|
|
29
|
-
status: CaseStatus = Field(description='Defines the status of the case', default=CaseStatus.CLOSED)
|
|
30
|
-
ignored_status: CaseIgnoredStatus = Field(
|
|
31
|
-
description='Defines the ignored status of the case',
|
|
32
|
-
default=CaseIgnoredStatus.NORMAL,
|
|
33
|
-
)
|
|
34
|
-
sequence: Optional[int | str] = Field(
|
|
35
|
-
default=None,
|
|
36
|
-
description='Defines the sequence of the case. This is a unique identifier for the case',
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
@model_validator(mode='before')
|
|
40
|
-
def _validate_model(cls: Self, data: dict[str, Any]) -> dict[str, Any]:
|
|
41
|
-
"""Validate model"""
|
|
42
|
-
sequence = data.get('sequence')
|
|
43
|
-
if sequence is not None and isinstance(sequence, int):
|
|
44
|
-
trigger = data['trigger']
|
|
45
|
-
if not isinstance(trigger, Trigger):
|
|
46
|
-
data['sequence'] = f'{trigger["code"]}/{data["pk"]}'
|
|
47
|
-
else:
|
|
48
|
-
data['sequence'] = f'{trigger.code}/{sequence}'
|
|
49
|
-
else:
|
|
50
|
-
data['sequence'] = f'GENERIC/{data["pk"]}'
|
|
51
|
-
|
|
52
|
-
return data
|
|
1
|
+
"""Events entities"""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from typing import Any, Optional
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, Field, model_validator
|
|
8
|
+
|
|
9
|
+
from .case_ignored_status import CaseIgnoredStatus
|
|
10
|
+
from .case_status import CaseStatus
|
|
11
|
+
from .comment import Comment
|
|
12
|
+
from .trigger import Trigger
|
|
13
|
+
|
|
14
|
+
if sys.version_info >= (3, 11):
|
|
15
|
+
from typing import Self
|
|
16
|
+
else:
|
|
17
|
+
from typing_extensions import Self
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Case(BaseModel):
|
|
21
|
+
"""Case entity"""
|
|
22
|
+
|
|
23
|
+
pk: int = Field(description='Defines the primary key of the case')
|
|
24
|
+
trigger: Trigger = Field(description='Defines the trigger of the case')
|
|
25
|
+
asset_id: int = Field(description='Defines the asset ID of the case')
|
|
26
|
+
comments: list[Comment] = Field(default_factory=list, description='Defines the comments of the case')
|
|
27
|
+
opened_at: datetime = Field(description='Defines the date when the case was opened')
|
|
28
|
+
closed_at: Optional[datetime] = Field(default=None, description='Defines the date when the case was closed')
|
|
29
|
+
status: CaseStatus = Field(description='Defines the status of the case', default=CaseStatus.CLOSED)
|
|
30
|
+
ignored_status: CaseIgnoredStatus = Field(
|
|
31
|
+
description='Defines the ignored status of the case',
|
|
32
|
+
default=CaseIgnoredStatus.NORMAL,
|
|
33
|
+
)
|
|
34
|
+
sequence: Optional[int | str] = Field(
|
|
35
|
+
default=None,
|
|
36
|
+
description='Defines the sequence of the case. This is a unique identifier for the case',
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
@model_validator(mode='before')
|
|
40
|
+
def _validate_model(cls: Self, data: dict[str, Any]) -> dict[str, Any]:
|
|
41
|
+
"""Validate model"""
|
|
42
|
+
sequence = data.get('sequence')
|
|
43
|
+
if sequence is not None and isinstance(sequence, int):
|
|
44
|
+
trigger = data['trigger']
|
|
45
|
+
if not isinstance(trigger, Trigger):
|
|
46
|
+
data['sequence'] = f'{trigger["code"]}/{data["pk"]}'
|
|
47
|
+
else:
|
|
48
|
+
data['sequence'] = f'{trigger.code}/{sequence}'
|
|
49
|
+
else:
|
|
50
|
+
data['sequence'] = f'GENERIC/{data["pk"]}'
|
|
51
|
+
|
|
52
|
+
return data
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
from enum import Enum
|
|
3
|
-
|
|
4
|
-
if sys.version_info >= (3, 11):
|
|
5
|
-
from typing import Self
|
|
6
|
-
else:
|
|
7
|
-
from typing_extensions import Self
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class CaseIgnoredStatus(Enum):
|
|
11
|
-
"""
|
|
12
|
-
Case ignore status, will define what kind ignore happened.
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
NORMAL = 'NORMAL'
|
|
16
|
-
IGNORED = 'IGNORED'
|
|
17
|
-
PRESET = 'PRESET'
|
|
18
|
-
AUTO = 'AUTO'
|
|
19
|
-
|
|
20
|
-
def __str__(self: Self) -> str:
|
|
21
|
-
"""Readable property"""
|
|
22
|
-
return self.name
|
|
23
|
-
|
|
24
|
-
def __repr__(self: Self) -> str:
|
|
25
|
-
"""Readable property"""
|
|
26
|
-
return f'CaseIgnoredStatus.{self.name}'
|
|
1
|
+
import sys
|
|
2
|
+
from enum import Enum
|
|
3
|
+
|
|
4
|
+
if sys.version_info >= (3, 11):
|
|
5
|
+
from typing import Self
|
|
6
|
+
else:
|
|
7
|
+
from typing_extensions import Self
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CaseIgnoredStatus(Enum):
|
|
11
|
+
"""
|
|
12
|
+
Case ignore status, will define what kind ignore happened.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
NORMAL = 'NORMAL'
|
|
16
|
+
IGNORED = 'IGNORED'
|
|
17
|
+
PRESET = 'PRESET'
|
|
18
|
+
AUTO = 'AUTO'
|
|
19
|
+
|
|
20
|
+
def __str__(self: Self) -> str:
|
|
21
|
+
"""Readable property"""
|
|
22
|
+
return self.name
|
|
23
|
+
|
|
24
|
+
def __repr__(self: Self) -> str:
|
|
25
|
+
"""Readable property"""
|
|
26
|
+
return f'CaseIgnoredStatus.{self.name}'
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
from enum import Enum
|
|
3
|
-
|
|
4
|
-
if sys.version_info >= (3, 11):
|
|
5
|
-
from typing import Self
|
|
6
|
-
else:
|
|
7
|
-
from typing_extensions import Self
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class CaseStatus(Enum):
|
|
11
|
-
"""Case status enum"""
|
|
12
|
-
|
|
13
|
-
PENDING = 'PENDING'
|
|
14
|
-
FOLLOWED = 'FOLLOWED'
|
|
15
|
-
CLOSED = 'CLOSED'
|
|
16
|
-
|
|
17
|
-
def __str__(self: Self) -> str:
|
|
18
|
-
"""Readable property"""
|
|
19
|
-
return self.name
|
|
20
|
-
|
|
21
|
-
def __repr__(self: Self) -> str:
|
|
22
|
-
"""Readable property"""
|
|
23
|
-
return f'CaseStatus.{self.name}'
|
|
1
|
+
import sys
|
|
2
|
+
from enum import Enum
|
|
3
|
+
|
|
4
|
+
if sys.version_info >= (3, 11):
|
|
5
|
+
from typing import Self
|
|
6
|
+
else:
|
|
7
|
+
from typing_extensions import Self
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CaseStatus(Enum):
|
|
11
|
+
"""Case status enum"""
|
|
12
|
+
|
|
13
|
+
PENDING = 'PENDING'
|
|
14
|
+
FOLLOWED = 'FOLLOWED'
|
|
15
|
+
CLOSED = 'CLOSED'
|
|
16
|
+
|
|
17
|
+
def __str__(self: Self) -> str:
|
|
18
|
+
"""Readable property"""
|
|
19
|
+
return self.name
|
|
20
|
+
|
|
21
|
+
def __repr__(self: Self) -> str:
|
|
22
|
+
"""Readable property"""
|
|
23
|
+
return f'CaseStatus.{self.name}'
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
|
-
from pydantic import BaseModel, Field
|
|
4
|
-
|
|
5
|
-
from .chart_data_type import ChartDataType
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class AxisConfig(BaseModel):
|
|
9
|
-
"""Axis configuration"""
|
|
10
|
-
|
|
11
|
-
label: str = Field(default='', description='Label of the axis')
|
|
12
|
-
measure_unit: str = Field(default='', description='Measure unit of the axis')
|
|
13
|
-
min_value: Optional[float] = Field(default=None, description='Minimum value of the axis')
|
|
14
|
-
max_value: Optional[float] = Field(default=None, description='Maximum value of the axis')
|
|
15
|
-
data_type: ChartDataType = Field(default=ChartDataType.DATETIME, description='Data type of the axis')
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from .chart_data_type import ChartDataType
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AxisConfig(BaseModel):
|
|
9
|
+
"""Axis configuration"""
|
|
10
|
+
|
|
11
|
+
label: str = Field(default='', description='Label of the axis')
|
|
12
|
+
measure_unit: str = Field(default='', description='Measure unit of the axis')
|
|
13
|
+
min_value: Optional[float] = Field(default=None, description='Minimum value of the axis')
|
|
14
|
+
max_value: Optional[float] = Field(default=None, description='Maximum value of the axis')
|
|
15
|
+
data_type: ChartDataType = Field(default=ChartDataType.DATETIME, description='Data type of the axis')
|
|
@@ -1,175 +1,175 @@
|
|
|
1
|
-
"""Bar chart"""
|
|
2
|
-
|
|
3
|
-
import sys
|
|
4
|
-
from typing import Any
|
|
5
|
-
|
|
6
|
-
from pydantic import BaseModel, Field
|
|
7
|
-
|
|
8
|
-
from .axis_config import AxisConfig
|
|
9
|
-
from .chart_alignment import ChartAlignment
|
|
10
|
-
from .chart_data_serie import ChartDataSerie
|
|
11
|
-
from .chart_data_serie_type import ChartDataSerieType
|
|
12
|
-
from .chart_render_technology import ChartRenderTechnology
|
|
13
|
-
|
|
14
|
-
if sys.version_info >= (3, 11):
|
|
15
|
-
from typing import Self
|
|
16
|
-
else:
|
|
17
|
-
from typing_extensions import Self
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class BarChart(BaseModel):
|
|
21
|
-
"""Bar chart configuration"""
|
|
22
|
-
|
|
23
|
-
x_axis: ChartDataSerie = Field(description='Defines the X Axis of the chart')
|
|
24
|
-
y_axis: list[ChartDataSerie] = Field(description='Defines the Y Axis of the chart', default_factory=list)
|
|
25
|
-
title: str = Field(default='Chart', description='Title of the chart')
|
|
26
|
-
align: ChartAlignment = Field(default=ChartAlignment.CENTER, description='Alignment of the title')
|
|
27
|
-
x_axis_config: AxisConfig = Field(
|
|
28
|
-
default_factory=lambda: AxisConfig(),
|
|
29
|
-
description='Configuration of the X Axis',
|
|
30
|
-
)
|
|
31
|
-
y_axis_config: AxisConfig = Field(
|
|
32
|
-
default_factory=lambda: AxisConfig(),
|
|
33
|
-
description='Configuration of the Y Axis',
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
def render(
|
|
37
|
-
self: Self,
|
|
38
|
-
technology: ChartRenderTechnology = ChartRenderTechnology.SYNCFUSION_FLUTTER_CHARTS,
|
|
39
|
-
) -> dict[str, Any]:
|
|
40
|
-
"""
|
|
41
|
-
Render chart to a graphic Library.
|
|
42
|
-
|
|
43
|
-
:param technology: The technology to use to render the chart.
|
|
44
|
-
:type technology: ChartRenderTechnology
|
|
45
|
-
|
|
46
|
-
:return: The configuration of the chart.
|
|
47
|
-
:rtype: dict[str, Any]
|
|
48
|
-
"""
|
|
49
|
-
if technology == ChartRenderTechnology.GRAPHIC:
|
|
50
|
-
return {
|
|
51
|
-
'library': 'GRAPHIC',
|
|
52
|
-
'chart': 'BAR',
|
|
53
|
-
'configuration': self._render_graphic(),
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if technology == ChartRenderTechnology.SYNCFUSION_FLUTTER_CHARTS:
|
|
57
|
-
return {
|
|
58
|
-
'library': 'SYNCFUSION_FLUTTER_CHARTS',
|
|
59
|
-
'chart': 'BAR',
|
|
60
|
-
'configuration': self._render_syncfusion_flutter_charts(),
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if technology == ChartRenderTechnology.APEX_CHARTS:
|
|
64
|
-
return {
|
|
65
|
-
'library': 'APEXCHARTS',
|
|
66
|
-
'chart': 'BAR',
|
|
67
|
-
'configuration': self._render_apexcharts(),
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return {
|
|
71
|
-
'library': 'FLUTTER',
|
|
72
|
-
'chart': 'TEXT',
|
|
73
|
-
'configuration': [f'Unsupported rendering technology {technology.name}'],
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
def _render_syncfusion_flutter_charts(self: Self) -> dict[str, Any]:
|
|
77
|
-
"""
|
|
78
|
-
Converts the configuration of the chart to Syncfusion Flutter Charts.
|
|
79
|
-
"""
|
|
80
|
-
series = []
|
|
81
|
-
|
|
82
|
-
for serie in self.y_axis:
|
|
83
|
-
values = []
|
|
84
|
-
for i, value in enumerate(serie.data):
|
|
85
|
-
x_axis = self.x_axis.data[i]
|
|
86
|
-
values.append({'xAxis': x_axis, 'yAxis': value})
|
|
87
|
-
|
|
88
|
-
series.append(
|
|
89
|
-
{
|
|
90
|
-
'label': serie.label,
|
|
91
|
-
'color': serie.color,
|
|
92
|
-
'values': values,
|
|
93
|
-
}
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
return {
|
|
97
|
-
'series': series,
|
|
98
|
-
'xAxis': {
|
|
99
|
-
'label': self.x_axis_config.label,
|
|
100
|
-
'measureUnit': self.x_axis_config.measure_unit,
|
|
101
|
-
'dataType': self.x_axis_config.data_type.value,
|
|
102
|
-
'minValue': self.x_axis_config.min_value,
|
|
103
|
-
'maxValue': self.x_axis_config.max_value,
|
|
104
|
-
},
|
|
105
|
-
'yAxis': {
|
|
106
|
-
'label': self.y_axis_config.label,
|
|
107
|
-
'measureUnit': self.y_axis_config.measure_unit,
|
|
108
|
-
'dataType': self.y_axis_config.data_type.value,
|
|
109
|
-
'minValue': self.y_axis_config.min_value,
|
|
110
|
-
'maxValue': self.y_axis_config.max_value,
|
|
111
|
-
},
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
def _render_graphic(self: Self) -> list[dict[str, Any]]:
|
|
115
|
-
"""
|
|
116
|
-
Converts the configuration of the chart to Flutter library graphic.
|
|
117
|
-
"""
|
|
118
|
-
|
|
119
|
-
series = []
|
|
120
|
-
|
|
121
|
-
for serie in self.y_axis:
|
|
122
|
-
for i, value in enumerate(serie.data):
|
|
123
|
-
x_axis = self.x_axis.data[i]
|
|
124
|
-
series.append(
|
|
125
|
-
{
|
|
126
|
-
'label': serie.label,
|
|
127
|
-
'color': serie.color,
|
|
128
|
-
'category': x_axis,
|
|
129
|
-
'value': value,
|
|
130
|
-
}
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
return series
|
|
134
|
-
|
|
135
|
-
def _render_apexcharts(self: Self) -> dict[str, Any]:
|
|
136
|
-
"""
|
|
137
|
-
Converts the configuration of the chart to Javascript library ApexCharts.
|
|
138
|
-
"""
|
|
139
|
-
|
|
140
|
-
series = []
|
|
141
|
-
colors = []
|
|
142
|
-
|
|
143
|
-
for serie in self.y_axis:
|
|
144
|
-
modified_serie = {'name': serie.label, 'data': serie.data}
|
|
145
|
-
|
|
146
|
-
if serie.serie_type is not ChartDataSerieType.NONE:
|
|
147
|
-
modified_serie['type'] = serie.serie_type.value
|
|
148
|
-
|
|
149
|
-
series.append(modified_serie)
|
|
150
|
-
colors.append(serie.color)
|
|
151
|
-
|
|
152
|
-
config = {
|
|
153
|
-
'series': series,
|
|
154
|
-
'colors': colors,
|
|
155
|
-
'xaxis': {
|
|
156
|
-
'categories': self.x_axis.data,
|
|
157
|
-
'type': self.x_axis.data_type.value,
|
|
158
|
-
'title': {'text': self.x_axis.label},
|
|
159
|
-
},
|
|
160
|
-
'title': {
|
|
161
|
-
'text': self.title,
|
|
162
|
-
'align': self.align.value,
|
|
163
|
-
'style': {'fontFamily': 'Fira Sans Condensed', 'fontSize': '20px', 'fontWeight': 'normal'},
|
|
164
|
-
},
|
|
165
|
-
'plotOptions': {'bar': {'horizontal': True, 'borderRadius': 4}},
|
|
166
|
-
'dataLabels': {'enabled': False},
|
|
167
|
-
'chart': {
|
|
168
|
-
'type': 'bar',
|
|
169
|
-
'animations': {'enabled': False},
|
|
170
|
-
'toolbar': {'show': False},
|
|
171
|
-
'zoom': {'enabled': False},
|
|
172
|
-
},
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return config
|
|
1
|
+
"""Bar chart"""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from .axis_config import AxisConfig
|
|
9
|
+
from .chart_alignment import ChartAlignment
|
|
10
|
+
from .chart_data_serie import ChartDataSerie
|
|
11
|
+
from .chart_data_serie_type import ChartDataSerieType
|
|
12
|
+
from .chart_render_technology import ChartRenderTechnology
|
|
13
|
+
|
|
14
|
+
if sys.version_info >= (3, 11):
|
|
15
|
+
from typing import Self
|
|
16
|
+
else:
|
|
17
|
+
from typing_extensions import Self
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class BarChart(BaseModel):
|
|
21
|
+
"""Bar chart configuration"""
|
|
22
|
+
|
|
23
|
+
x_axis: ChartDataSerie = Field(description='Defines the X Axis of the chart')
|
|
24
|
+
y_axis: list[ChartDataSerie] = Field(description='Defines the Y Axis of the chart', default_factory=list)
|
|
25
|
+
title: str = Field(default='Chart', description='Title of the chart')
|
|
26
|
+
align: ChartAlignment = Field(default=ChartAlignment.CENTER, description='Alignment of the title')
|
|
27
|
+
x_axis_config: AxisConfig = Field(
|
|
28
|
+
default_factory=lambda: AxisConfig(),
|
|
29
|
+
description='Configuration of the X Axis',
|
|
30
|
+
)
|
|
31
|
+
y_axis_config: AxisConfig = Field(
|
|
32
|
+
default_factory=lambda: AxisConfig(),
|
|
33
|
+
description='Configuration of the Y Axis',
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
def render(
|
|
37
|
+
self: Self,
|
|
38
|
+
technology: ChartRenderTechnology = ChartRenderTechnology.SYNCFUSION_FLUTTER_CHARTS,
|
|
39
|
+
) -> dict[str, Any]:
|
|
40
|
+
"""
|
|
41
|
+
Render chart to a graphic Library.
|
|
42
|
+
|
|
43
|
+
:param technology: The technology to use to render the chart.
|
|
44
|
+
:type technology: ChartRenderTechnology
|
|
45
|
+
|
|
46
|
+
:return: The configuration of the chart.
|
|
47
|
+
:rtype: dict[str, Any]
|
|
48
|
+
"""
|
|
49
|
+
if technology == ChartRenderTechnology.GRAPHIC:
|
|
50
|
+
return {
|
|
51
|
+
'library': 'GRAPHIC',
|
|
52
|
+
'chart': 'BAR',
|
|
53
|
+
'configuration': self._render_graphic(),
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if technology == ChartRenderTechnology.SYNCFUSION_FLUTTER_CHARTS:
|
|
57
|
+
return {
|
|
58
|
+
'library': 'SYNCFUSION_FLUTTER_CHARTS',
|
|
59
|
+
'chart': 'BAR',
|
|
60
|
+
'configuration': self._render_syncfusion_flutter_charts(),
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if technology == ChartRenderTechnology.APEX_CHARTS:
|
|
64
|
+
return {
|
|
65
|
+
'library': 'APEXCHARTS',
|
|
66
|
+
'chart': 'BAR',
|
|
67
|
+
'configuration': self._render_apexcharts(),
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
'library': 'FLUTTER',
|
|
72
|
+
'chart': 'TEXT',
|
|
73
|
+
'configuration': [f'Unsupported rendering technology {technology.name}'],
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
def _render_syncfusion_flutter_charts(self: Self) -> dict[str, Any]:
|
|
77
|
+
"""
|
|
78
|
+
Converts the configuration of the chart to Syncfusion Flutter Charts.
|
|
79
|
+
"""
|
|
80
|
+
series = []
|
|
81
|
+
|
|
82
|
+
for serie in self.y_axis:
|
|
83
|
+
values = []
|
|
84
|
+
for i, value in enumerate(serie.data):
|
|
85
|
+
x_axis = self.x_axis.data[i]
|
|
86
|
+
values.append({'xAxis': x_axis, 'yAxis': value})
|
|
87
|
+
|
|
88
|
+
series.append(
|
|
89
|
+
{
|
|
90
|
+
'label': serie.label,
|
|
91
|
+
'color': serie.color,
|
|
92
|
+
'values': values,
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
'series': series,
|
|
98
|
+
'xAxis': {
|
|
99
|
+
'label': self.x_axis_config.label,
|
|
100
|
+
'measureUnit': self.x_axis_config.measure_unit,
|
|
101
|
+
'dataType': self.x_axis_config.data_type.value,
|
|
102
|
+
'minValue': self.x_axis_config.min_value,
|
|
103
|
+
'maxValue': self.x_axis_config.max_value,
|
|
104
|
+
},
|
|
105
|
+
'yAxis': {
|
|
106
|
+
'label': self.y_axis_config.label,
|
|
107
|
+
'measureUnit': self.y_axis_config.measure_unit,
|
|
108
|
+
'dataType': self.y_axis_config.data_type.value,
|
|
109
|
+
'minValue': self.y_axis_config.min_value,
|
|
110
|
+
'maxValue': self.y_axis_config.max_value,
|
|
111
|
+
},
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
def _render_graphic(self: Self) -> list[dict[str, Any]]:
|
|
115
|
+
"""
|
|
116
|
+
Converts the configuration of the chart to Flutter library graphic.
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
series = []
|
|
120
|
+
|
|
121
|
+
for serie in self.y_axis:
|
|
122
|
+
for i, value in enumerate(serie.data):
|
|
123
|
+
x_axis = self.x_axis.data[i]
|
|
124
|
+
series.append(
|
|
125
|
+
{
|
|
126
|
+
'label': serie.label,
|
|
127
|
+
'color': serie.color,
|
|
128
|
+
'category': x_axis,
|
|
129
|
+
'value': value,
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
return series
|
|
134
|
+
|
|
135
|
+
def _render_apexcharts(self: Self) -> dict[str, Any]:
|
|
136
|
+
"""
|
|
137
|
+
Converts the configuration of the chart to Javascript library ApexCharts.
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
series = []
|
|
141
|
+
colors = []
|
|
142
|
+
|
|
143
|
+
for serie in self.y_axis:
|
|
144
|
+
modified_serie = {'name': serie.label, 'data': serie.data}
|
|
145
|
+
|
|
146
|
+
if serie.serie_type is not ChartDataSerieType.NONE:
|
|
147
|
+
modified_serie['type'] = serie.serie_type.value
|
|
148
|
+
|
|
149
|
+
series.append(modified_serie)
|
|
150
|
+
colors.append(serie.color)
|
|
151
|
+
|
|
152
|
+
config = {
|
|
153
|
+
'series': series,
|
|
154
|
+
'colors': colors,
|
|
155
|
+
'xaxis': {
|
|
156
|
+
'categories': self.x_axis.data,
|
|
157
|
+
'type': self.x_axis.data_type.value,
|
|
158
|
+
'title': {'text': self.x_axis.label},
|
|
159
|
+
},
|
|
160
|
+
'title': {
|
|
161
|
+
'text': self.title,
|
|
162
|
+
'align': self.align.value,
|
|
163
|
+
'style': {'fontFamily': 'Fira Sans Condensed', 'fontSize': '20px', 'fontWeight': 'normal'},
|
|
164
|
+
},
|
|
165
|
+
'plotOptions': {'bar': {'horizontal': True, 'borderRadius': 4}},
|
|
166
|
+
'dataLabels': {'enabled': False},
|
|
167
|
+
'chart': {
|
|
168
|
+
'type': 'bar',
|
|
169
|
+
'animations': {'enabled': False},
|
|
170
|
+
'toolbar': {'show': False},
|
|
171
|
+
'zoom': {'enabled': False},
|
|
172
|
+
},
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return config
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
"""Chart alignment"""
|
|
2
|
-
|
|
3
|
-
import sys
|
|
4
|
-
from enum import Enum
|
|
5
|
-
|
|
6
|
-
if sys.version_info >= (3, 11):
|
|
7
|
-
from typing import Self
|
|
8
|
-
else:
|
|
9
|
-
from typing_extensions import Self
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ChartAlignment(Enum):
|
|
13
|
-
"""
|
|
14
|
-
Chart Alignment
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
CENTER = 'center'
|
|
18
|
-
LEFT = 'left'
|
|
19
|
-
RIGHT = 'right'
|
|
20
|
-
|
|
21
|
-
def __str__(self: Self) -> str:
|
|
22
|
-
"""Readable property"""
|
|
23
|
-
return self.name
|
|
24
|
-
|
|
25
|
-
def __repr__(self: Self) -> str:
|
|
26
|
-
"""Readable property"""
|
|
27
|
-
return f'ChartAlignment.{self.name}'
|
|
1
|
+
"""Chart alignment"""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from enum import Enum
|
|
5
|
+
|
|
6
|
+
if sys.version_info >= (3, 11):
|
|
7
|
+
from typing import Self
|
|
8
|
+
else:
|
|
9
|
+
from typing_extensions import Self
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ChartAlignment(Enum):
|
|
13
|
+
"""
|
|
14
|
+
Chart Alignment
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
CENTER = 'center'
|
|
18
|
+
LEFT = 'left'
|
|
19
|
+
RIGHT = 'right'
|
|
20
|
+
|
|
21
|
+
def __str__(self: Self) -> str:
|
|
22
|
+
"""Readable property"""
|
|
23
|
+
return self.name
|
|
24
|
+
|
|
25
|
+
def __repr__(self: Self) -> str:
|
|
26
|
+
"""Readable property"""
|
|
27
|
+
return f'ChartAlignment.{self.name}'
|