antonymilne Claude commited on
Commit
5d3ed2f
Β·
1 Parent(s): e6217b4

Further refactor KPI cards and simplify page structure

Browse files

- Create create_kpi_card_figure helper to reduce KPI card repetition
- Simplify RadioItems options to list of values instead of dictionaries
- Condense grid layout using list multiplication ([[0, 0, 0]] * 3 + ...)
- Reorder page arguments: title, layout, components, controls
- Restore layout comment explaining grid height ratios

πŸ€– Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

Files changed (1) hide show
  1. app.py +61 -109
app.py CHANGED
@@ -45,6 +45,30 @@ order_kpi_df = create_kpi_data(superstore_df, value_col="Order ID")
45
  customer_kpi_df = create_kpi_data(superstore_df, value_col="Customer ID")
46
 
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  def create_chart_container_with_nav(id, figure, nav_href=None):
49
  """Create a container with a chart and optional navigation button."""
50
  components = [vm.Graph(id=f"{id}_chart", figure=figure)]
@@ -62,62 +86,22 @@ def create_chart_container_with_nav(id, figure, nav_href=None):
62
  return vm.Container(id=id, components=components, layout=layout, variant="filled")
63
 
64
 
 
 
65
  overview_page = vm.Page(
66
  title="Overview",
 
 
67
  components=[
68
  vm.Container(
69
  id="kpi-cards",
70
  title="πŸ’‘ Click on a KPI card to update the charts below.",
71
  components=[
72
- vm.Figure(
73
- figure=kpi_card_reference(
74
- data_frame=sales_kpi_df,
75
- value_column="total_2017",
76
- reference_column="total_2016",
77
- reference_format="{delta_relative:+.1%} vs. last year (${reference:,.0f})",
78
- title="Sales",
79
- value_format="${value:,.0f}",
80
- icon="bar_chart",
81
- ),
82
- actions=va.set_control(control="metric", value="Sales"),
83
- ),
84
- vm.Figure(
85
- figure=kpi_card_reference(
86
- data_frame=profit_kpi_df,
87
- value_column="total_2017",
88
- reference_column="total_2016",
89
- reference_format="{delta_relative:+.1%} vs. last year (${reference:,.0f})",
90
- title="Profit",
91
- value_format="${value:,.0f}",
92
- icon="money_bag",
93
- ),
94
- actions=va.set_control(control="metric", value="Profit"),
95
- ),
96
- vm.Figure(
97
- figure=kpi_card_reference(
98
- data_frame=order_kpi_df,
99
- value_column="total_2017",
100
- reference_column="total_2016",
101
- reference_format="{delta_relative:+.1%} vs. last year ({reference:,.0f})",
102
- title="Orders",
103
- value_format="{value:,.0f}",
104
- icon="orders",
105
- # agg_func="nunique",
106
- ),
107
- actions=va.set_control(control="metric", value="Order ID"),
108
- ),
109
- vm.Figure(
110
- figure=kpi_card_reference(
111
- data_frame=customer_kpi_df,
112
- value_column="total_2017",
113
- reference_column="total_2016",
114
- title="Customers",
115
- reference_format="{delta_relative:+.1%} vs. last year ({reference:,.0f})",
116
- value_format="{value:,.0f}",
117
- icon="group",
118
- # agg_func="nunique",
119
- ),
120
- actions=va.set_control(control="metric", value="Customer ID"),
121
  ),
122
  ],
123
  layout=vm.Grid(grid=[[0, 1, 2, 3]]),
@@ -150,15 +134,7 @@ overview_page = vm.Page(
150
  controls=[
151
  vm.Parameter(
152
  id="metric",
153
- selector=vm.RadioItems(
154
- options=[
155
- {"value": "Sales", "label": "Sales"},
156
- {"value": "Profit", "label": "Profit"},
157
- {"value": "Order ID", "label": "Orders"},
158
- {"value": "Customer ID", "label": "Customers"},
159
- ],
160
- title="Metric",
161
- ),
162
  targets=[
163
  "region_bar_chart.value_col",
164
  "category_bar_chart.value_col",
@@ -166,72 +142,27 @@ overview_page = vm.Page(
166
  "line_month_chart.value_col",
167
  "segment_bar_chart.value_col",
168
  ],
169
- show_in_url=True,
170
  visible=False,
171
  ),
172
  ],
173
- layout=vm.Grid(
174
- grid=[
175
- [0, 0, 0],
176
- [0, 0, 0],
177
- [0, 0, 0],
178
- [1, 1, 2],
179
- [1, 1, 2],
180
- [1, 1, 2],
181
- [1, 1, 2],
182
- [1, 1, 2],
183
- [3, 4, 5],
184
- [3, 4, 5],
185
- [3, 4, 5],
186
- [3, 4, 5],
187
- [3, 4, 5],
188
- ],
189
- ),
190
  )
191
 
192
  regions_page = vm.Page(
193
  title="Regions",
194
  components=[
195
  vm.Container(
196
- controls=[
197
- vm.Filter(
198
- id="pg2-filter-1",
199
- column="State_Code",
200
- selector=vm.Dropdown(),
201
- visible=False,
202
- ),
203
- vm.Filter(
204
- column="Segment",
205
- selector=vm.Checklist(title="Choose segment"),
206
- ),
207
- vm.Filter(
208
- column="Category",
209
- selector=vm.Checklist(title="Choose category"),
210
- ),
211
- vm.Parameter(
212
- id="pg2-parameter-2",
213
- selector=vm.RadioItems(
214
- options=["Sales", "Profit"],
215
- title="Choose metric",
216
- ),
217
- targets=[
218
- "region_map_chart.value_col",
219
- "pg2-chart-1.x",
220
- ],
221
- ),
222
- ],
223
  layout=vm.Grid(grid=[[0, 1]]),
224
  components=[
225
  vm.Container(
226
  variant="filled",
227
- title="",
228
  components=[
229
  vm.Graph(
230
  id="region_map_chart",
231
  header="πŸ’‘ Click on a state to filter charts on the right.",
232
  figure=create_map_bubble_new(superstore_df, value_col="Sales", custom_data=["State_Code"]),
233
  actions=[
234
- va.set_control(control="pg2-filter-1", value="State_Code"),
235
  ],
236
  ),
237
  ],
@@ -259,6 +190,31 @@ regions_page = vm.Page(
259
  variant="filled",
260
  ),
261
  ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
  ),
263
  ],
264
  )
@@ -302,10 +258,8 @@ products_page = vm.Page(
302
  title="Products",
303
  components=[
304
  vm.Container(
305
- title="",
306
  components=[
307
  vm.Container(
308
- title="",
309
  components=[
310
  vm.Graph(
311
  id="pg4-chart-1",
@@ -318,7 +272,6 @@ products_page = vm.Page(
318
  variant="filled",
319
  ),
320
  vm.Container(
321
- title="",
322
  components=[
323
  vm.AgGrid(
324
  id="table",
@@ -330,7 +283,6 @@ products_page = vm.Page(
330
  variant="filled",
331
  ),
332
  vm.Container(
333
- title="",
334
  components=[
335
  vm.Graph(
336
  id="pg4-chart-3",
 
45
  customer_kpi_df = create_kpi_data(superstore_df, value_col="Customer ID")
46
 
47
 
48
+ def create_kpi_card_figure(data_frame, title, icon, metric_value=None, is_currency=True):
49
+ """Create a KPI card figure with click action."""
50
+ # TODO: make this consistent
51
+ if metric_value is None:
52
+ metric_value = title
53
+
54
+ currency_prefix = "$" if is_currency else ""
55
+ value_format = f"{currency_prefix}{{value:,.0f}}"
56
+ reference_format = f"{{delta_relative:+.1%}} vs. last year ({currency_prefix}{{reference:,.0f}})"
57
+
58
+ return vm.Figure(
59
+ figure=kpi_card_reference(
60
+ data_frame=data_frame,
61
+ value_column="total_2017",
62
+ reference_column="total_2016",
63
+ value_format=value_format,
64
+ reference_format=reference_format,
65
+ title=title,
66
+ icon=icon,
67
+ ),
68
+ actions=va.set_control(control="metric", value=metric_value),
69
+ )
70
+
71
+
72
  def create_chart_container_with_nav(id, figure, nav_href=None):
73
  """Create a container with a chart and optional navigation button."""
74
  components = [vm.Graph(id=f"{id}_chart", figure=figure)]
 
86
  return vm.Container(id=id, components=components, layout=layout, variant="filled")
87
 
88
 
89
+ # TODO: chart title spacing, use container.title?
90
+
91
  overview_page = vm.Page(
92
  title="Overview",
93
+ # Grid that consists of rows with height ratio 3:5:5.
94
+ layout=vm.Grid(grid=[[0, 0, 0]] * 3 + [[1, 1, 2]] * 5 + [[3, 4, 5]] * 5),
95
  components=[
96
  vm.Container(
97
  id="kpi-cards",
98
  title="πŸ’‘ Click on a KPI card to update the charts below.",
99
  components=[
100
+ create_kpi_card_figure(sales_kpi_df, "Sales", "bar_chart"),
101
+ create_kpi_card_figure(profit_kpi_df, "Profit", "money_bag"),
102
+ create_kpi_card_figure(order_kpi_df, "Orders", "orders", metric_value="Order ID", is_currency=False),
103
+ create_kpi_card_figure(
104
+ customer_kpi_df, "Customers", "group", metric_value="Customer ID", is_currency=False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  ),
106
  ],
107
  layout=vm.Grid(grid=[[0, 1, 2, 3]]),
 
134
  controls=[
135
  vm.Parameter(
136
  id="metric",
137
+ selector=vm.RadioItems(options=["Sales", "Profit", "Order ID", "Customer ID"]),
 
 
 
 
 
 
 
 
138
  targets=[
139
  "region_bar_chart.value_col",
140
  "category_bar_chart.value_col",
 
142
  "line_month_chart.value_col",
143
  "segment_bar_chart.value_col",
144
  ],
145
+ show_in_url=True, # TODO: think about where this needed
146
  visible=False,
147
  ),
148
  ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  )
150
 
151
  regions_page = vm.Page(
152
  title="Regions",
153
  components=[
154
  vm.Container(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  layout=vm.Grid(grid=[[0, 1]]),
156
  components=[
157
  vm.Container(
158
  variant="filled",
 
159
  components=[
160
  vm.Graph(
161
  id="region_map_chart",
162
  header="πŸ’‘ Click on a state to filter charts on the right.",
163
  figure=create_map_bubble_new(superstore_df, value_col="Sales", custom_data=["State_Code"]),
164
  actions=[
165
+ va.set_control(control="state_filter", value="State_Code"),
166
  ],
167
  ),
168
  ],
 
190
  variant="filled",
191
  ),
192
  ],
193
+ controls=[
194
+ vm.Filter(
195
+ id="state_filter",
196
+ column="State_Code",
197
+ visible=False,
198
+ ),
199
+ vm.Filter(
200
+ column="Segment",
201
+ selector=vm.Checklist(title="Choose segment"),
202
+ ),
203
+ vm.Filter(
204
+ column="Category",
205
+ selector=vm.Checklist(title="Choose category"),
206
+ ),
207
+ vm.Parameter(
208
+ selector=vm.RadioItems(
209
+ options=["Sales", "Profit"],
210
+ title="Choose metric",
211
+ ),
212
+ targets=[
213
+ "region_map_chart.value_col",
214
+ "pg2-chart-1.x",
215
+ ],
216
+ ),
217
+ ],
218
  ),
219
  ],
220
  )
 
258
  title="Products",
259
  components=[
260
  vm.Container(
 
261
  components=[
262
  vm.Container(
 
263
  components=[
264
  vm.Graph(
265
  id="pg4-chart-1",
 
272
  variant="filled",
273
  ),
274
  vm.Container(
 
275
  components=[
276
  vm.AgGrid(
277
  id="table",
 
283
  variant="filled",
284
  ),
285
  vm.Container(
 
286
  components=[
287
  vm.Graph(
288
  id="pg4-chart-3",