gov-uk-dashboards 19.0.0__py3-none-any.whl → 20.0.0__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.
- gov_uk_dashboards/components/plotly/stacked_barchart.py +22 -0
- gov_uk_dashboards/components/plotly/time_series_chart.py +49 -7
- {gov_uk_dashboards-19.0.0.dist-info → gov_uk_dashboards-20.0.0.dist-info}/METADATA +1 -1
- {gov_uk_dashboards-19.0.0.dist-info → gov_uk_dashboards-20.0.0.dist-info}/RECORD +7 -7
- {gov_uk_dashboards-19.0.0.dist-info → gov_uk_dashboards-20.0.0.dist-info}/WHEEL +1 -1
- {gov_uk_dashboards-19.0.0.dist-info → gov_uk_dashboards-20.0.0.dist-info}/licenses/LICENSE +0 -0
- {gov_uk_dashboards-19.0.0.dist-info → gov_uk_dashboards-20.0.0.dist-info}/top_level.txt +0 -0
@@ -67,6 +67,7 @@ class StackedBarChart:
|
|
67
67
|
hover_distance: Optional[int] = 1,
|
68
68
|
download_chart_button_id: Optional[str] = None,
|
69
69
|
download_data_button_id: Optional[str] = None,
|
70
|
+
total_trace_name: Optional[str] = None,
|
70
71
|
):
|
71
72
|
"""Initializes the StackedBarChart instance.
|
72
73
|
To display the chart, call the `get_stacked_bar_chart()` method.
|
@@ -90,6 +91,9 @@ class StackedBarChart:
|
|
90
91
|
if applicable. Defaults to None.
|
91
92
|
download_data_button_id (Optional[str], optional): ID for the data download button, if
|
92
93
|
applicable. Defaults to None.
|
94
|
+
total_trace_name (Optional[str], optional): Name for an optional total to be added to
|
95
|
+
bottom of hover text, must be in MEASURE column of df, line_trace_name will display
|
96
|
+
in legend. Defaults to None.
|
93
97
|
"""
|
94
98
|
self.title_data = title_data
|
95
99
|
self.y_axis_column = y_axis_column
|
@@ -104,6 +108,7 @@ class StackedBarChart:
|
|
104
108
|
self.hover_distance = hover_distance
|
105
109
|
self.download_chart_button_id = download_chart_button_id
|
106
110
|
self.download_data_button_id = download_data_button_id
|
111
|
+
self.total_trace_name = total_trace_name
|
107
112
|
self.fig = self.create_stacked_bar_chart()
|
108
113
|
|
109
114
|
def get_stacked_bar_chart(self) -> html.Div:
|
@@ -173,6 +178,23 @@ class StackedBarChart:
|
|
173
178
|
# pylint: disable=too-many-locals
|
174
179
|
|
175
180
|
fig = go.Figure()
|
181
|
+
if self.total_trace_name is not None:
|
182
|
+
df = self.df.filter(pl.col(MEASURE) == self.total_trace_name)
|
183
|
+
|
184
|
+
fig.add_trace(
|
185
|
+
go.Scatter(
|
186
|
+
x=df[self.x_axis_column],
|
187
|
+
y=df[self.y_axis_column],
|
188
|
+
customdata=self._get_custom_data(self.total_trace_name, df),
|
189
|
+
mode="markers",
|
190
|
+
marker={"color": "white", "opacity": 0},
|
191
|
+
name=self.total_trace_name + LEGEND_SPACING,
|
192
|
+
hovertemplate="Total income: %{customdata[0]}<extra></extra>",
|
193
|
+
showlegend=False,
|
194
|
+
hoverinfo="skip",
|
195
|
+
legendrank=1,
|
196
|
+
)
|
197
|
+
)
|
176
198
|
colour_list = (
|
177
199
|
AFAccessibleColours.CATEGORICAL.value
|
178
200
|
if len(self.trace_name_list) != 2
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"""get_time_series_chart function"""
|
2
2
|
|
3
3
|
from datetime import datetime, date
|
4
|
+
import json
|
4
5
|
from typing import Optional
|
5
6
|
from dateutil.relativedelta import relativedelta
|
6
7
|
from dash import html
|
@@ -58,7 +59,7 @@ class TimeSeriesChart:
|
|
58
59
|
def __init__(
|
59
60
|
self,
|
60
61
|
title_data: TitleDataStructure,
|
61
|
-
|
62
|
+
y_axis_column: str,
|
62
63
|
hover_data: HoverDataByTrace,
|
63
64
|
filtered_df: pl.DataFrame,
|
64
65
|
trace_name_list: list[str],
|
@@ -83,7 +84,7 @@ class TimeSeriesChart:
|
|
83
84
|
hover_distance: Optional[int] = 1,
|
84
85
|
):
|
85
86
|
self.title_data = title_data
|
86
|
-
self.y_axis_column =
|
87
|
+
self.y_axis_column = y_axis_column
|
87
88
|
self.hover_data = hover_data
|
88
89
|
self.hover_data_for_traces_with_different_hover_for_last_point = (
|
89
90
|
hover_data_for_traces_with_different_hover_for_last_point
|
@@ -95,7 +96,7 @@ class TimeSeriesChart:
|
|
95
96
|
self.xaxis_tick_text_format = xaxis_tick_text_format
|
96
97
|
self.verticle_line_x_value_and_name = verticle_line_x_value_and_name
|
97
98
|
self.filled_traces_dict = filled_traces_dict
|
98
|
-
self.
|
99
|
+
self.trace_names_to_prevent_hover_of_first_point_list = (
|
99
100
|
trace_names_to_prevent_hover_of_first_point_list
|
100
101
|
)
|
101
102
|
self.x_axis_column = x_axis_column
|
@@ -114,7 +115,6 @@ class TimeSeriesChart:
|
|
114
115
|
|
115
116
|
def get_time_series_chart(self) -> html.Div:
|
116
117
|
"""Creates and returns time series chart for display on application.
|
117
|
-
|
118
118
|
Returns:
|
119
119
|
html.Div: Styled div containing title, subtile and chart.
|
120
120
|
"""
|
@@ -132,6 +132,49 @@ class TimeSeriesChart:
|
|
132
132
|
self.download_data_button_id,
|
133
133
|
)
|
134
134
|
|
135
|
+
def is_json_serializable(self, value):
|
136
|
+
"Determines whether value can be converted to json format."
|
137
|
+
# pylint: disable=duplicate-code
|
138
|
+
try:
|
139
|
+
json.dumps(value)
|
140
|
+
return True
|
141
|
+
except (TypeError, OverflowError):
|
142
|
+
return False
|
143
|
+
|
144
|
+
def to_dict(self):
|
145
|
+
"Converts class attributes to json format."
|
146
|
+
# pylint: disable=duplicate-code
|
147
|
+
result = {}
|
148
|
+
for k, v in self.__dict__.items():
|
149
|
+
if self.is_json_serializable(v):
|
150
|
+
result[k] = v
|
151
|
+
elif isinstance(v, pl.DataFrame):
|
152
|
+
result[k] = {"_type": "polars_df", "data": v.to_dicts()}
|
153
|
+
elif isinstance(v, pl.Series):
|
154
|
+
result[k] = {"_type": "series", "data": v.to_list()}
|
155
|
+
else:
|
156
|
+
result[k] = f"<<non-serializable: {type(v).__name__}>>"
|
157
|
+
return result
|
158
|
+
|
159
|
+
@classmethod
|
160
|
+
def from_dict(cls, data):
|
161
|
+
"Creates a class instance from dict of attributes."
|
162
|
+
restored = {}
|
163
|
+
for k, v in data.items():
|
164
|
+
if k in ["markers", "colour_list", "fig"]:
|
165
|
+
continue
|
166
|
+
if isinstance(v, dict) and "_type" in v:
|
167
|
+
if v["_type"] == "polars_df":
|
168
|
+
restored[k] = pl.DataFrame(v["data"])
|
169
|
+
elif v["_type"] == "polars_series":
|
170
|
+
restored[k] = pl.Series(v["data"])
|
171
|
+
else:
|
172
|
+
# Fallback for unknown _type
|
173
|
+
restored[k] = v.get("data", None)
|
174
|
+
else:
|
175
|
+
restored[k] = v
|
176
|
+
return cls(**restored)
|
177
|
+
|
135
178
|
def get_time_series_chart_for_download(self):
|
136
179
|
"""Return fig with title and subtitle for download as png"""
|
137
180
|
return get_chart_for_download(self, self.create_time_series_chart())
|
@@ -340,7 +383,6 @@ class TimeSeriesChart:
|
|
340
383
|
legendgroup: str,
|
341
384
|
):
|
342
385
|
"""Creates a trace for the plot.
|
343
|
-
|
344
386
|
Args:
|
345
387
|
df (pl.DataFrame): Dataframe to use to create trace. Must contain "Date valid" column,
|
346
388
|
y_value column and columns defined in self.hover_data[CUSTOM_DATA].
|
@@ -369,8 +411,8 @@ class TimeSeriesChart:
|
|
369
411
|
(
|
370
412
|
""
|
371
413
|
if i == 0
|
372
|
-
and self.
|
373
|
-
and trace_name in self.
|
414
|
+
and self.trace_names_to_prevent_hover_of_first_point_list is not None
|
415
|
+
and trace_name in self.trace_names_to_prevent_hover_of_first_point_list
|
374
416
|
else self._get_custom_hover_template(i, df, trace_name)
|
375
417
|
)
|
376
418
|
for i in range(df.shape[0]) # the number of rows in df
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: gov_uk_dashboards
|
3
|
-
Version:
|
3
|
+
Version: 20.0.0
|
4
4
|
Summary: Provides access to functionality common to creating a data dashboard.
|
5
5
|
Author: Department for Levelling Up, Housing and Communities
|
6
6
|
Description-Content-Type: text/markdown
|
@@ -80,8 +80,8 @@ gov_uk_dashboards/components/plotly/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQ
|
|
80
80
|
gov_uk_dashboards/components/plotly/captioned_figure.py,sha256=T0sbtGTiJ79FXxVdPb__hqISuyTc3Dl11cKhgcuW-5U,2804
|
81
81
|
gov_uk_dashboards/components/plotly/choropleth_map.py,sha256=U9RmS3MZGloQAt9HoSYh3Xad205DDfZOjz91ZD_ydbI,9849
|
82
82
|
gov_uk_dashboards/components/plotly/enums.py,sha256=ebHiFQljA7O4HJxKoslqlNXcAjUZi1askpTSwxKEcYQ,850
|
83
|
-
gov_uk_dashboards/components/plotly/stacked_barchart.py,sha256=
|
84
|
-
gov_uk_dashboards/components/plotly/time_series_chart.py,sha256=
|
83
|
+
gov_uk_dashboards/components/plotly/stacked_barchart.py,sha256=61VgvGJhFX7C4QAk-A8ZF6DTNjDvZ7uU3vof54H5km4,14187
|
84
|
+
gov_uk_dashboards/components/plotly/time_series_chart.py,sha256=rsWaxh4fNbedz8NIQfwh5xUC2SOS7nCiR7uWXd3Hq6o,24637
|
85
85
|
gov_uk_dashboards/figures/__init__.py,sha256=_snQeNlM81nNKERl4gg9ScH2HYbtwaBjl8yQonccx34,712
|
86
86
|
gov_uk_dashboards/figures/chart_data.py,sha256=fEsNkQFzXKIQ0h7aLBWq3J1qAxHbxvJeKU23JrVodVc,757
|
87
87
|
gov_uk_dashboards/figures/line_chart.py,sha256=rEB51_z9cPl7BcT94iA6ZsZXzecnVCnGpQWW_9SNGUY,2813
|
@@ -106,8 +106,8 @@ gov_uk_dashboards/lib/datetime_functions/datetime_functions.py,sha256=BQgr8I_vFN
|
|
106
106
|
gov_uk_dashboards/lib/download_functions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
107
107
|
gov_uk_dashboards/lib/download_functions/convert_fig_to_image_and_download.py,sha256=JYDpWObBsiKG5Rtk2ElOTgHwfIR0cRmVocr8RlTfPZQ,534
|
108
108
|
gov_uk_dashboards/lib/download_functions/download_csv_with_headers.py,sha256=h50ejODCjoz9z-yqDt6nsE6jN6XxJN1DWH66CjLJiCk,4155
|
109
|
-
gov_uk_dashboards-
|
110
|
-
gov_uk_dashboards-
|
111
|
-
gov_uk_dashboards-
|
112
|
-
gov_uk_dashboards-
|
113
|
-
gov_uk_dashboards-
|
109
|
+
gov_uk_dashboards-20.0.0.dist-info/licenses/LICENSE,sha256=GDiD7Y2Gx7JucPV1JfVySJeah-qiSyBPdpJ6RHCEHTc,1126
|
110
|
+
gov_uk_dashboards-20.0.0.dist-info/METADATA,sha256=uXL0Qg3yth1-u_u1K5URWHxZYLj9kEkPNOEl76OmNU8,5917
|
111
|
+
gov_uk_dashboards-20.0.0.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
112
|
+
gov_uk_dashboards-20.0.0.dist-info/top_level.txt,sha256=gPaN1P3-H3Rgi2me6tt-fX_cxo19CZfA4PjlZPjGRpo,18
|
113
|
+
gov_uk_dashboards-20.0.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|