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.
@@ -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
- y_column: str,
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 = y_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.trace_names_to_prevent_hover_of_first_point = (
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.trace_names_to_prevent_hover_of_first_point is not None
373
- and trace_name in self.trace_names_to_prevent_hover_of_first_point
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: 19.0.0
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=07egbXxZwWyhlwniQzbr7iBNGJkE2pdw96JaQSwdEGY,13111
84
- gov_uk_dashboards/components/plotly/time_series_chart.py,sha256=QD9HjXLjNIBA-NBZQUSL3TyIAvRGrBzwnYrRboROECg,23002
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-19.0.0.dist-info/licenses/LICENSE,sha256=GDiD7Y2Gx7JucPV1JfVySJeah-qiSyBPdpJ6RHCEHTc,1126
110
- gov_uk_dashboards-19.0.0.dist-info/METADATA,sha256=sp97E7xIhHGjoadUdtujJEuoKX3plUBKJNPSHTLegV8,5917
111
- gov_uk_dashboards-19.0.0.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
112
- gov_uk_dashboards-19.0.0.dist-info/top_level.txt,sha256=gPaN1P3-H3Rgi2me6tt-fX_cxo19CZfA4PjlZPjGRpo,18
113
- gov_uk_dashboards-19.0.0.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.1.0)
2
+ Generator: setuptools (80.3.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5