gov-uk-dashboards 15.2.1__tar.gz → 16.1.0__tar.gz

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.
Files changed (113) hide show
  1. {gov_uk_dashboards-15.2.1/gov_uk_dashboards.egg-info → gov_uk_dashboards-16.1.0}/PKG-INFO +1 -1
  2. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/helpers/plotting_helper_functions.py +2 -4
  3. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/plotly/stacked_barchart.py +3 -2
  4. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/plotly/time_series_chart.py +90 -47
  5. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/constants.py +3 -0
  6. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0/gov_uk_dashboards.egg-info}/PKG-INFO +1 -1
  7. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/setup.py +1 -1
  8. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/LICENSE +0 -0
  9. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/MANIFEST.in +0 -0
  10. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/README.md +0 -0
  11. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/__init__.py +0 -0
  12. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/__init__.py +0 -0
  13. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/attach-event-to-dash.js +0 -0
  14. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/dashboard.css +0 -0
  15. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/fonts/bold-affa96571d-v2.woff +0 -0
  16. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/fonts/bold-b542beb274-v2.woff2 +0 -0
  17. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/fonts/light-94a07e06a1-v2.woff2 +0 -0
  18. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/fonts/light-f591b13f7d-v2.woff +0 -0
  19. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/get_assets_folder.py +0 -0
  20. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/govuk-frontend-3.14.0.min.js +0 -0
  21. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/DLUHC_WHITE_Master_AW_sm.png +0 -0
  22. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/MHCLG-favicon.png +0 -0
  23. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/MHCLG_favicon.png +0 -0
  24. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/dcms_coatofarms.png +0 -0
  25. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/dluhc_favicon.ico +0 -0
  26. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/gov_favicon.ico +0 -0
  27. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/govuk-crest.svg +0 -0
  28. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/hm-government-logo.png +0 -0
  29. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/mhclg_coat_of_arms.png +0 -0
  30. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/mhclg_white_no_background.png +0 -0
  31. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/oflog/MedianAbsolute.png +0 -0
  32. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/oflog/how_to_1_selecting_data.png +0 -0
  33. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/oflog/how_to_2_viewing_tabs.png +0 -0
  34. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/oflog/how_to_3_viewing_charts.png +0 -0
  35. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/oflog/how_to_4_viewing_trends.png +0 -0
  36. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/images/oflog/how_to_5_viewing_tables.png +0 -0
  37. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/mobile-nav.js +0 -0
  38. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/topojson/usa_110m.json +0 -0
  39. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/assets/topojson/world_110m.json +0 -0
  40. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/axes.py +0 -0
  41. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/colours.py +0 -0
  42. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/__init__.py +0 -0
  43. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/__init__.py +0 -0
  44. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/apply_and_reset_filters_buttons.py +0 -0
  45. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/banners.py +0 -0
  46. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/card.py +0 -0
  47. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/card_full_width.py +0 -0
  48. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/collapsible_panel.py +0 -0
  49. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/comparison_la_filter_button.py +0 -0
  50. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/context_banner.py +0 -0
  51. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/create_download_chart_button.py +0 -0
  52. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/create_download_data_button.py +0 -0
  53. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/dashboard_container.py +0 -0
  54. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/details.py +0 -0
  55. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/download_button.py +0 -0
  56. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/filter_panel.py +0 -0
  57. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/footer.py +0 -0
  58. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/graph.py +0 -0
  59. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/header.py +0 -0
  60. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/heading.py +0 -0
  61. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/home_page_link_button.py +0 -0
  62. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/html_list.py +0 -0
  63. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/key_value_pair.py +0 -0
  64. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/main_content.py +0 -0
  65. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/navbar.py +0 -0
  66. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/no_data_message.py +0 -0
  67. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/notification_banner.py +0 -0
  68. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/paragraph.py +0 -0
  69. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/phase_banner.py +0 -0
  70. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/row_component.py +0 -0
  71. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/side_navbar.py +0 -0
  72. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/table.py +0 -0
  73. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/tooltip.py +0 -0
  74. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/tooltip_title.py +0 -0
  75. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/visualisation_commentary.py +0 -0
  76. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/visualisation_title.py +0 -0
  77. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/dash/warning_text.py +0 -0
  78. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/helpers/__init__.py +0 -0
  79. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/helpers/display_chart_or_table_with_header.py +0 -0
  80. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/helpers/generate_dash_graph_from_figure.py +0 -0
  81. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/helpers/update_layout_bgcolor_margin.py +0 -0
  82. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/plotly/__init__.py +0 -0
  83. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/plotly/captioned_figure.py +0 -0
  84. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/plotly/choropleth_map.py +0 -0
  85. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/components/plotly/enums.py +0 -0
  86. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/figures/__init__.py +0 -0
  87. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/figures/chart_data.py +0 -0
  88. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/figures/enums/__init__.py +0 -0
  89. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/figures/enums/dash_patterns.py +0 -0
  90. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/figures/line_chart.py +0 -0
  91. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/figures/styles/__init__.py +0 -0
  92. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/figures/styles/line_style.py +0 -0
  93. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/formatting/__init__.py +0 -0
  94. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/formatting/human_readable.py +0 -0
  95. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/formatting/round_and_add_prefix_and_suffix.py +0 -0
  96. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/formatting/rounding.py +0 -0
  97. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/lib/__init__.py +0 -0
  98. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/lib/dap/__init__.py +0 -0
  99. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/lib/dap/dap_deployment.py +0 -0
  100. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/lib/dap/get_dataframe_from_cds.py +0 -0
  101. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/lib/datetime_functions/__init__.py +0 -0
  102. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/lib/datetime_functions/datetime_functions.py +0 -0
  103. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/lib/enable_basic_auth.py +0 -0
  104. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/lib/http_headers.py +0 -0
  105. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/lib/logging.py +0 -0
  106. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/symbols.py +0 -0
  107. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/template.html +0 -0
  108. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards/template.py +0 -0
  109. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards.egg-info/SOURCES.txt +0 -0
  110. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards.egg-info/dependency_links.txt +0 -0
  111. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards.egg-info/requires.txt +0 -0
  112. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/gov_uk_dashboards.egg-info/top_level.txt +0 -0
  113. {gov_uk_dashboards-15.2.1 → gov_uk_dashboards-16.1.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gov_uk_dashboards
3
- Version: 15.2.1
3
+ Version: 16.1.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
@@ -1,9 +1,7 @@
1
1
  """Helper functions for use to plot charts"""
2
2
 
3
3
 
4
- from gov_uk_dashboards.constants import (
5
- CHART_LABEL_FONT_SIZE,
6
- )
4
+ from gov_uk_dashboards.constants import CHART_LABEL_FONT_SIZE
7
5
 
8
6
 
9
7
  def get_legend_configuration(itemclick=True, itemdoubleclick=True):
@@ -22,7 +20,7 @@ def get_legend_configuration(itemclick=True, itemdoubleclick=True):
22
20
  "y": -0.22,
23
21
  "yanchor": "top",
24
22
  "traceorder": "normal",
25
- "orientation": "v",
23
+ "orientation": "h",
26
24
  "font": {"size": CHART_LABEL_FONT_SIZE},
27
25
  "itemclick": "toggle" if itemclick else False,
28
26
  "itemdoubleclick": "toggle" if itemdoubleclick else False,
@@ -13,6 +13,7 @@ from gov_uk_dashboards.constants import (
13
13
  DATE_VALID,
14
14
  FINANCIAL_YEAR_ENDING,
15
15
  HOVER_TEXT_HEADERS,
16
+ LEGEND_SPACING,
16
17
  MAIN_TITLE,
17
18
  MEASURE,
18
19
  SUBTITLE,
@@ -157,7 +158,7 @@ class StackedBarChart:
157
158
  customdata=self._get_custom_data(self.line_trace_name, df),
158
159
  mode="lines",
159
160
  line={"color": colour, "width": 3},
160
- name=self.line_trace_name,
161
+ name=self.line_trace_name + LEGEND_SPACING,
161
162
  hovertemplate=self._get_hover_template(self.line_trace_name),
162
163
  legendrank=99999, # a high number to ensure it is bottom of the legend
163
164
  )
@@ -214,7 +215,7 @@ class StackedBarChart:
214
215
  return go.Bar(
215
216
  x=df[self.x_axis_column],
216
217
  y=df[self.y_axis_column],
217
- name=trace_name,
218
+ name=trace_name + LEGEND_SPACING,
218
219
  hovertemplate=[
219
220
  self._get_hover_template(trace_name) for i in range(df.shape[0])
220
221
  ],
@@ -12,8 +12,8 @@ from gov_uk_dashboards.constants import (
12
12
  CHART_LABEL_FONT_SIZE,
13
13
  CUSTOM_DATA,
14
14
  DATE_VALID,
15
- FILL_TO_PREVIOUS_TRACE,
16
15
  HOVER_TEXT_HEADERS,
16
+ LEGEND_SPACING,
17
17
  MAIN_TITLE,
18
18
  REMOVE_INITIAL_MARKER,
19
19
  SUBTITLE,
@@ -66,15 +66,18 @@ class TimeSeriesChart:
66
66
  trace_name_column: Optional[str] = None,
67
67
  xaxis_tick_text_format: XAxisFormat = XAxisFormat.YEAR.value,
68
68
  verticle_line_x_value_and_name: tuple = None,
69
- last_2_traces_filled=False,
69
+ filled_traces_dict: dict[str] = None,
70
70
  trace_names_to_prevent_hover_of_first_point_list=None,
71
71
  x_axis_column=DATE_VALID,
72
72
  x_unified_hovermode: Optional[bool] = False,
73
73
  x_hoverformat: Optional[str] = None,
74
+ x_unified_hovertemplate: Optional[str] = None,
74
75
  x_axis_title: Optional[str] = None,
75
76
  download_chart_button_id: Optional[str] = None,
76
77
  download_data_button_id: Optional[str] = None,
77
78
  number_of_traces_colour_shift_dict: Optional[dict] = None,
79
+ additional_line: Optional[dict] = None,
80
+ hover_distance: Optional[int] = 1,
78
81
  ):
79
82
  self.title_data = title_data
80
83
  self.y_axis_column = y_column
@@ -88,18 +91,21 @@ class TimeSeriesChart:
88
91
  self.trace_name_column = trace_name_column
89
92
  self.xaxis_tick_text_format = xaxis_tick_text_format
90
93
  self.verticle_line_x_value_and_name = verticle_line_x_value_and_name
91
- self.last_2_traces_filled = last_2_traces_filled
94
+ self.filled_traces_dict = filled_traces_dict
92
95
  self.trace_names_to_prevent_hover_of_first_point = (
93
96
  trace_names_to_prevent_hover_of_first_point_list
94
97
  )
95
98
  self.x_axis_column = x_axis_column
96
99
  self.x_unified_hovermode = x_unified_hovermode
97
100
  self.x_hoverformat = x_hoverformat
101
+ self.x_unified_hovertemplate = x_unified_hovertemplate
98
102
  self.x_axis_title = x_axis_title
99
103
  self.download_chart_button_id = download_chart_button_id
100
104
  self.download_data_button_id = download_data_button_id
101
105
  self.markers = ["square", "diamond", "circle", "triangle-up"]
102
106
  self.number_of_traces_colour_shift_dict = number_of_traces_colour_shift_dict
107
+ self.additional_line = additional_line
108
+ self.hover_distance = hover_distance
103
109
  self.colour_list = self._get_colour_list()
104
110
  self.fig = self.create_time_series_chart()
105
111
 
@@ -136,7 +142,24 @@ class TimeSeriesChart:
136
142
  )
137
143
 
138
144
  fig = go.Figure()
139
- for i, (df, trace_name, colour, marker) in enumerate(
145
+ if self.additional_line:
146
+ x_0 = self.additional_line["x0"]
147
+ y_0 = self.additional_line["y0"]
148
+ x_1 = self.additional_line["x1"]
149
+ y_1 = self.additional_line["y1"]
150
+ line_color = self.additional_line["color"]
151
+ trace_connector = go.Scatter(
152
+ x=[x_0, x_1],
153
+ y=[y_0, y_1],
154
+ mode="lines",
155
+ name="Transition",
156
+ line={"color": line_color},
157
+ hoverinfo="skip", # 👈 This line disables hover for this trace
158
+ showlegend=False, # Optional: hide it from legend too
159
+ )
160
+ fig.add_trace(trace_connector)
161
+ # pylint: disable=unused-variable
162
+ for i, (df, trace_name, colour, marker,) in enumerate(
140
163
  zip(
141
164
  self._get_df_list_for_time_series(),
142
165
  self.trace_name_list,
@@ -144,11 +167,6 @@ class TimeSeriesChart:
144
167
  self.markers,
145
168
  )
146
169
  ):
147
- is_last = is_second_last = False
148
- if self.last_2_traces_filled is True:
149
- number_of_traces = len(self._get_df_list_for_time_series())
150
- is_last = i == number_of_traces - 1
151
- is_second_last = i == number_of_traces - 2
152
170
  if REMOVE_INITIAL_MARKER in df.columns and True in df.get_column(
153
171
  REMOVE_INITIAL_MARKER
154
172
  ):
@@ -159,27 +177,61 @@ class TimeSeriesChart:
159
177
  self.create_time_series_trace(
160
178
  df.sort(self.x_axis_column),
161
179
  trace_name,
162
- (
163
- {"width": 0}
164
- if is_last or is_second_last
165
- else {"dash": "solid", "color": colour}
166
- ),
167
- fill=(
168
- "tonexty"
169
- if FILL_TO_PREVIOUS_TRACE in df.columns
170
- and True in df.get_column(FILL_TO_PREVIOUS_TRACE)
171
- else None
172
- ),
173
- hover_label=(
174
- {"bgcolor": AFAccessibleColours.TURQUOISE.value}
175
- if is_last or is_second_last
176
- else None
177
- ),
178
- marker=(
179
- {"opacity": 0}
180
- if is_last or is_second_last
181
- else {"symbol": marker, "size": marker_sizes, "opacity": 1}
180
+ line_style={"dash": "solid", "color": colour},
181
+ marker={"symbol": marker, "size": marker_sizes, "opacity": 1},
182
+ ),
183
+ )
184
+
185
+ if self.filled_traces_dict:
186
+ fill_df = self.filtered_df.filter(
187
+ pl.col(self.trace_name_column).is_in(
188
+ [
189
+ self.filled_traces_dict["upper"],
190
+ self.filled_traces_dict["lower"],
191
+ ]
192
+ )
193
+ ).sort(self.x_axis_column)
194
+ x_series = fill_df[self.x_axis_column].unique().sort().to_list()
195
+ upper_trace = self.filled_traces_dict["upper"]
196
+ lower_trace = self.filled_traces_dict["lower"]
197
+ y_upper = fill_df.filter(pl.col(self.trace_name_column) == upper_trace)[
198
+ self.y_axis_column
199
+ ].to_list()
200
+ y_lower = fill_df.filter(pl.col(self.trace_name_column) == lower_trace)[
201
+ self.y_axis_column
202
+ ].to_list()
203
+ y_upper_formatted_value = fill_df.filter(
204
+ pl.col(self.trace_name_column) == upper_trace
205
+ )["FORMATTED_VALUE"].to_list()
206
+ y_lower_formatted_value = fill_df.filter(
207
+ pl.col(self.trace_name_column) == lower_trace
208
+ )["FORMATTED_VALUE"].to_list()
209
+ formatted_dates = fill_df.filter(
210
+ pl.col(self.trace_name_column) == upper_trace
211
+ )["FORMATTED_DATE"].to_list()
212
+ hover_text = [
213
+ f"{self.filled_traces_dict['name']} - {date}: "
214
+ f"{low_value} - {high_value}<extra></extra>"
215
+ for low_value, high_value, date in zip(
216
+ y_lower_formatted_value,
217
+ y_upper_formatted_value,
218
+ formatted_dates,
219
+ )
220
+ ]
221
+
222
+ hover_text_full = hover_text + hover_text[::-1]
223
+ fig.add_trace(
224
+ go.Scatter(
225
+ x=x_series + x_series[::-1],
226
+ y=y_upper + y_lower[::-1],
227
+ fill="toself",
228
+ fillcolor=get_rgba_from_hex_colour_and_alpha(
229
+ AFAccessibleColours.TURQUOISE.value, alpha=0.2
182
230
  ),
231
+ line={"color": "rgba(255,255,255,0)"},
232
+ name=self.filled_traces_dict["name"] + LEGEND_SPACING,
233
+ hovertemplate=hover_text_full,
234
+ hoveron="points",
183
235
  )
184
236
  )
185
237
  self._format_x_axis(fig)
@@ -232,10 +284,10 @@ class TimeSeriesChart:
232
284
  xref="x domain",
233
285
  yref="y domain",
234
286
  x=1,
235
- y=-0.25,
287
+ y=-0.2,
236
288
  text=self.x_axis_title,
237
289
  showarrow=False,
238
- font={"size": CHART_LABEL_FONT_SIZE},
290
+ font={"size": 16},
239
291
  )
240
292
 
241
293
  fig.update_layout(
@@ -243,7 +295,7 @@ class TimeSeriesChart:
243
295
  font={"size": CHART_LABEL_FONT_SIZE},
244
296
  yaxis_tickformat=",",
245
297
  hovermode="x unified" if self.x_unified_hovermode is True else "closest",
246
- hoverdistance=100, # Increase distance to simulate hover 'always on'
298
+ hoverdistance=self.hover_distance, # Increase distance to simulate hover 'always on'
247
299
  )
248
300
  return fig
249
301
 
@@ -264,8 +316,6 @@ class TimeSeriesChart:
264
316
  df: pl.DataFrame,
265
317
  trace_name: str,
266
318
  line_style: dict[str, str],
267
- fill: str,
268
- hover_label: dict[str, str],
269
319
  marker: dict[str, str],
270
320
  ):
271
321
  """Creates a trace for the plot.
@@ -275,27 +325,17 @@ class TimeSeriesChart:
275
325
  y_value column and columns defined in self.hover_data[CUSTOM_DATA].
276
326
  trace_name (str): Name of trace.
277
327
  line_style (dict[str, str]): Properties for line_style parameter.
278
- fill (str): Properties for fill parameter.
279
- hover_label (dict[str,str]): Properties for hoverlabel parameter.
280
328
  marker (dict[str,str]): Properties for marker parameter.
281
329
  """
282
330
  return go.Scatter(
283
331
  x=df[self.x_axis_column],
284
332
  y=df[self.y_axis_column],
285
333
  line=line_style,
286
- name=self._get_trace_name(trace_name),
334
+ name=self._get_trace_name(trace_name) + LEGEND_SPACING,
287
335
  hovertemplate=self._get_hover_template(df, trace_name),
288
336
  customdata=self._get_custom_data(df, trace_name),
289
337
  marker=marker,
290
- fill=fill,
291
- hoverlabel=hover_label,
292
- fillcolor=(
293
- get_rgba_from_hex_colour_and_alpha(
294
- AFAccessibleColours.TURQUOISE.value, alpha=0.2
295
- )
296
- if fill
297
- else None
298
- ),
338
+ hoverlabel=None,
299
339
  showlegend=(
300
340
  trace_name in self.legend_dict if self.legend_dict is not None else True
301
341
  ),
@@ -315,7 +355,10 @@ class TimeSeriesChart:
315
355
 
316
356
  def _get_custom_hover_template(self, i, df, trace_name):
317
357
  if self.x_unified_hovermode is True:
358
+ if self.x_unified_hovertemplate is not None:
359
+ return self.x_unified_hovertemplate.format(trace_name=trace_name)
318
360
  return f"{trace_name}: " + "%{customdata[0]}<extra></extra>"
361
+
319
362
  hover_text_headers = self.hover_data[trace_name][HOVER_TEXT_HEADERS]
320
363
  if (
321
364
  self.hover_data_for_traces_with_different_hover_for_last_point is not None
@@ -494,7 +537,7 @@ class TimeSeriesChart:
494
537
  def _get_colour_list(self):
495
538
  """Returns a list of colours."""
496
539
  number_of_traces = len(self.trace_name_list)
497
- if number_of_traces == 2:
540
+ if number_of_traces == 2 and self.filled_traces_dict is None:
498
541
  colour_list = [
499
542
  AFAccessibleColours.DARK_BLUE.value,
500
543
  AFAccessibleColours.ORANGE.value,
@@ -13,5 +13,8 @@ FILL_TO_PREVIOUS_TRACE = "Fill to previous trace"
13
13
  REMOVE_INITIAL_MARKER = "Remove initial marker"
14
14
  YEAR = "Year"
15
15
 
16
+
16
17
  UNIT_SIZE = "Unit size"
17
18
  DEFAULT_COLOURSCALE = "tealgrn"
19
+
20
+ LEGEND_SPACING = "\u00A0" * 5
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gov_uk_dashboards
3
- Version: 15.2.1
3
+ Version: 16.1.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
@@ -10,7 +10,7 @@ setup(
10
10
  author="Department for Levelling Up, Housing and Communities",
11
11
  description="Provides access to functionality common to creating a data dashboard.",
12
12
  name="gov_uk_dashboards",
13
- version="15.2.1",
13
+ version="16.1.0",
14
14
  long_description=long_description,
15
15
  long_description_content_type="text/markdown",
16
16
  packages=find_packages(),