drguilhermeapolinario commited on
Commit
f2b61dd
·
verified ·
1 Parent(s): 63474f8

Update views/maps.py

Browse files
Files changed (1) hide show
  1. views/maps.py +504 -125
views/maps.py CHANGED
@@ -8,7 +8,10 @@ from streamlit_folium import folium_static
8
  import streamlit as st
9
  from streamlit_extras.stylable_container import stylable_container
10
  from streamlit_extras.add_vertical_space import add_vertical_space
11
-
 
 
 
12
 
13
  with stylable_container(
14
  key="banner",
@@ -51,137 +54,513 @@ long = -44.05603
51
  total_pop = gdf["POP"].sum()
52
  col1, col2, col3 = st.columns([1, 1, 5])
53
 
54
- with col1:
55
- # st.write(f"###### População Total: {total_pop:,}")
56
- map_type = st.selectbox("Tipo de mapa", ["População", "Densidade", "Heatmap"])
57
-
58
- with col2:
59
- # st.write(f"###### Número de Setores Censitários: {len(gdf)}")
60
- base_map = st.selectbox("Mapa base", ["Cartodb Positron", "OpenStreetMap"])
61
-
62
- with col3:
63
- total_pop = gdf["POP"].sum()
64
- st.write(
65
- f"### 👪 População Total: {total_pop:,} habitantes, dados do Censo 2022 IBGE"
66
- )
67
- st.write(f"### 🗺️ Número de Setores Censitários: {len(gdf)}")
68
-
69
-
70
- add_vertical_space(5)
71
 
 
72
 
73
- col1, col2 = st.columns(2)
74
- with col1:
75
- m = folium.Map(
76
- location=[LATITUDE, LONGITUDE], tiles=base_map, zoom_start=15
77
- )
78
- dns_p = "Densidade pop. (hab/km²) UBS Flamengo - IBGE 2022"
79
- if map_type in ["População", "Densidade"]:
80
- if map_type == "População":
81
- column = "POP"
82
- caption = "Pop. residente UBS Flamengo IBGE 2022"
83
- else:
84
- gdf["DENSIDADE"] = gdf["POP"] / gdf["AREA_KM2"]
85
- column = "DENSIDADE"
86
- caption = dns_p
87
- colorscale = px.colors.sequential.Viridis
88
- colormap = LinearColormap(
89
- colors=colorscale,
90
- vmin=gdf[column].min(),
91
- vmax=gdf[column].max(),
92
- caption=caption,
93
- )
94
- folium.GeoJson(
95
- gdf,
96
- style_function=lambda feature: {
97
- "fillColor": colormap(feature["properties"][column]),
98
- "color": "black",
99
- "weight": 1,
100
- "fillOpacity": 0.7,
101
- },
102
- highlight_function=lambda feature: {
103
- "fillColor": "#ffaf00",
104
- "color": "green",
105
- "weight": 3,
106
- "fillOpacity": 0.9,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  },
108
- tooltip=folium.features.GeoJsonTooltip(
109
- fields=["CD_SETOR", column, "AREA_KM2"],
110
- aliases=[
111
- "Setor Censitário:",
112
- f"{caption}:",
113
- "Área (km²):",
114
- ],
115
- style=(
116
- "background-color: white; color: #333333;"
117
- "font-family: calibri; font-size: 12px;"
118
- "padding: 10px;"
119
- ),
120
- ),
121
- ).add_to(m)
122
- colormap.add_to(m)
123
-
124
- elif map_type == "Heatmap":
125
- heat_data = [
126
- [
127
- row["geometry"].centroid.y,
128
- row["geometry"].centroid.x,
129
- row["POP"],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  ]
131
- for idx, row in gdf.iterrows()
132
- ]
133
- HeatMap(heat_data).add_to(m)
134
- folium.Marker(
135
- [lat, long],
136
- popup="UBS Flamengo",
137
- tooltip="UBS Flamengo",
138
- icon=folium.Icon(color="red", icon="info-sign"),
139
- ).add_to(m)
140
-
141
- STYLE_STATEMENT = (
142
- "<style>.leaflet-control-layers"
143
- "{ position: fixed; top: 10px; left: 50px; } </style>"
144
- )
145
- m.get_root().html.add_child(folium.Element(STYLE_STATEMENT))
146
- folium_static(m)
147
-
148
- with col2:
149
- fig = px.bar(
150
- gdf,
151
- x="CD_SETOR",
152
- y="POP",
153
- title="Distribuição da População por Setor Censitário",
154
- color="POP",
155
- color_continuous_scale=px.colors.sequential.Viridis,
156
- )
157
- st.plotly_chart(fig)
158
-
159
- age_columns = [
160
- "POP_0A4",
161
- "POP_5A9",
162
- "POP_10A14",
163
- "POP_15A19",
164
- "POP_20A24",
165
- "POP_25A29",
166
- "POP_30A34",
167
- "POP_35A39",
168
- "POP_40A44",
169
- "POP_45A49",
170
- "POP_50A54",
171
- "POP_55A59",
172
- "POP_60A64",
173
- "POP_65A69",
174
- "POP_70A74",
175
- "POP_75A79",
176
- "POP_80A84",
177
- "POP_85A89",
178
- "POP_90A94",
179
- "POP_95A99",
180
- "POP_100OUMAIS",
181
- ]
182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
 
 
 
185
  add_vertical_space(10)
186
 
187
 
 
8
  import streamlit as st
9
  from streamlit_extras.stylable_container import stylable_container
10
  from streamlit_extras.add_vertical_space import add_vertical_space
11
+ import streamlit_shadcn_ui as ui
12
+ from streamlit_option_menu import option_menu
13
+ import pandas as pd
14
+ import plotly.graph_objects as go
15
 
16
  with stylable_container(
17
  key="banner",
 
54
  total_pop = gdf["POP"].sum()
55
  col1, col2, col3 = st.columns([1, 1, 5])
56
 
57
+ st.title("Mapas da área")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
+ st.markdown(""" ### :world_map: **UBS Flamengo: (IBGE 2022)** """)
60
 
61
+ STYLE = "style.css"
62
+ STYLES = "styles.html"
63
+ with open(STYLE, "r", encoding="utf-8") as f:
64
+ st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
65
+
66
+ with open(STYLES, "r", encoding="utf-8") as f:
67
+ st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
68
+
69
+ @st.cache_resource
70
+ def load_data():
71
+ """
72
+ A function that loads and reads geojson data for UBS Flamengo and converts it to the specified coordinate reference system.
73
+ """
74
+ return gpd.read_file("views\\flamengo_ibge2022.geojson").to_crs(epsg=4326)
75
+
76
+ gdf = load_data()
77
+ LATITUDE = -19.971591804
78
+ LONGITUDE = -44.057912815
79
+ lat = -19.96214
80
+ long = -44.05603
81
+
82
+ total_pop = gdf["POP"].sum()
83
+ num_setores = len(gdf)
84
+
85
+ with st.expander("Visualização", expanded=True):
86
+ selected_tab = option_menu(
87
+ menu_title=None,
88
+ options=[
89
+ "Mapa IBGE",
90
+ "Área",
91
+ "População",
92
+ ],
93
+ icons=[
94
+ "person",
95
+ "geo-alt",
96
+ "capsule-pill"
97
+ ],
98
+ menu_icon="cast",
99
+ default_index=0,
100
+ orientation="horizontal",
101
+ styles={
102
+ "container": {
103
+ "padding": "5px",
104
+ "background-color": "#1E1E28",
105
+ "border-radius": "8px",
106
+ },
107
+ "icon": {
108
+ "color": "#64B5F6",
109
+ "font-size": "20px",
110
+ "padding-right": "8px",
111
+ },
112
+ "nav-link": {
113
+ "font-size": "16px",
114
+ "text-align": "center",
115
+ "margin": "5px",
116
+ "padding": "12px",
117
+ "background-color": "#2A2B3D",
118
+ "--hover-color": "#4B4B4B",
119
+ "color": "#FFFFFF",
120
+ "border-radius": "4px",
121
+ },
122
+ "nav-link-selected": {
123
+ "background-color": "#007BB5",
124
+ "color": "#FFFFFF",
125
+ "font-weight": "bold",
126
+ },
127
+ "separator": {
128
+ "border-color": "#303030",
129
+ "margin": "0 10px",
130
+ },
131
  },
132
+ )
133
+ if selected_tab == "Mapa IBGE":
134
+ col1, col2, col3, col4, col5 = st.columns([1.5, 1.5, 0.8, 5, 0.5])
135
+ with col1:
136
+ st.metric(label="👪 População Total", value=f"{total_pop:,} habitantes", help="Dados do Censo 2022 IBGE")
137
+ map_type = st.selectbox("Tipo de mapa", ["População", "Densidade", "Heatmap"])
138
+ with col2:
139
+ st.metric(label="🗺️ Número de Setores Censitários", value=f"{num_setores}", help="Dados do Censo 2022 IBGE")
140
+ base_map = st.selectbox("Mapa base", ["Cartodb Positron", "OpenStreetMap"])
141
+ with col4:
142
+ with st.container(border=False, height=400):
143
+ row1, row2, row3 = st.columns([0.5, 3, 0.9])
144
+ with row1:
145
+ st.write('')
146
+ with row2:
147
+ st.write("""
148
+ ### Definição de Setor Censitário
149
+ Um **setor censitário** é a menor unidade territorial utilizada pelo
150
+ Instituto Brasileiro de Geografia e Estatística (IBGE) para a coleta
151
+ de dados em censos demográficos.
152
+
153
+ Cada setor censitário é uma área contínua dentro de um município, delimitada
154
+ por características físicas e populacionais homogêneas, e geralmente contém
155
+ entre 250 e 350 domicílios.
156
+
157
+ Os setores censitários são fundamentais para a realização de pesquisas
158
+ detalhadas, pois permitem uma análise granular da distribuição populacional,
159
+ socioeconômica e das condições de moradia em diferentes regiões do país.
160
+ Essa unidade de medida é essencial para a elaboração de políticas públicas,
161
+ planejamento urbano, distribuição de recursos e outras atividades que
162
+ dependem de informações demográficas precisas. """)
163
+ with row3:
164
+ st.write('')
165
+ col1, col2 = st.columns(2)
166
+ with col1:
167
+ m = folium.Map(
168
+ location=[LATITUDE, LONGITUDE], tiles=base_map, zoom_start=15
169
+ )
170
+ dns_p = "Densidade pop. (hab/km²) UBS Flamengo - IBGE 2022"
171
+ if map_type in ["População", "Densidade"]:
172
+ if map_type == "População":
173
+ column = "POP"
174
+ caption = "Pop. residente UBS Flamengo IBGE 2022"
175
+ else:
176
+ gdf["DENSIDADE"] = gdf["POP"] / gdf["AREA_KM2"]
177
+ column = "DENSIDADE"
178
+ caption = dns_p
179
+ colorscale = px.colors.sequential.Viridis
180
+ colormap = LinearColormap(
181
+ colors=colorscale,
182
+ vmin=gdf[column].min(),
183
+ vmax=gdf[column].max(),
184
+ caption=caption,
185
+ )
186
+ folium.GeoJson(
187
+ gdf,
188
+ style_function=lambda feature: {
189
+ "fillColor": colormap(feature["properties"][column]),
190
+ "color": "black",
191
+ "weight": 1,
192
+ "fillOpacity": 0.7,
193
+ },
194
+ highlight_function=lambda feature: {
195
+ "fillColor": "#ffaf00",
196
+ "color": "green",
197
+ "weight": 3,
198
+ "fillOpacity": 0.9,
199
+ },
200
+ tooltip=folium.features.GeoJsonTooltip(
201
+ fields=["CD_SETOR", column, "AREA_KM2"],
202
+ aliases=[
203
+ "Setor Censitário:",
204
+ f"{caption}:",
205
+ "Área (km²):",
206
+ ],
207
+ style=(
208
+ "background-color: white; color: #333333;"
209
+ "font-family: calibri; font-size: 12px;"
210
+ "padding: 10px;"
211
+ ),
212
+ ),
213
+ ).add_to(m)
214
+ colormap.add_to(m)
215
+
216
+ elif map_type == "Heatmap":
217
+ heat_data = [
218
+ [
219
+ row["geometry"].centroid.y,
220
+ row["geometry"].centroid.x,
221
+ row["POP"],
222
+ ]
223
+ for idx, row in gdf.iterrows()
224
+ ]
225
+ HeatMap(heat_data).add_to(m)
226
+ folium.Marker(
227
+ [lat, long],
228
+ popup="UBS Flamengo",
229
+ tooltip="UBS Flamengo",
230
+ icon=folium.Icon(color="red", icon="info-sign"),
231
+ ).add_to(m)
232
+
233
+ STYLE_STATEMENT = (
234
+ "<style>.leaflet-control-layers"
235
+ "{ position: fixed; top: 10px; left: 50px; } </style>"
236
+ )
237
+ m.get_root().html.add_child(folium.Element(STYLE_STATEMENT))
238
+ folium_static(m)
239
+ with col2:
240
+ fig = px.bar(
241
+ gdf,
242
+ x="CD_SETOR",
243
+ y="POP",
244
+ title="Distribuição da População por Setor Censitário",
245
+ color="POP",
246
+ color_continuous_scale=px.colors.sequential.Viridis,
247
+ )
248
+ st.plotly_chart(fig)
249
+
250
+ age_columns = [
251
+ "POP_0A4", "POP_5A9", "POP_10A14", "POP_15A19", "POP_20A24",
252
+ "POP_25A29", "POP_30A34", "POP_35A39", "POP_40A44", "POP_45A49",
253
+ "POP_50A54", "POP_55A59", "POP_60A64", "POP_65A69", "POP_70A74",
254
+ "POP_75A79", "POP_80A84", "POP_85A89", "POP_90A94", "POP_95A99",
255
+ "POP_100OUMAIS",
256
+ ]
257
+
258
+ fig = px.bar()
259
+
260
+ elif selected_tab == "Área":
261
+ st.subheader("Crescimento populacional - UBS Flamengo")
262
+ with stylable_container(
263
+ key="banner",
264
+ css_styles="""
265
+ img {
266
+ width: 1800px;
267
+ height: 340px;
268
+ overflow: hidden;
269
+ position: relative;
270
+ object-fit: cover;
271
+ border-radius: 20px; /* Adiciona bordas arredondadas */
272
+ mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
273
+ -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); /* For Safari */
274
+ }
275
+ """,
276
+ ):
277
+ st.image("src/images/pop.jpg")
278
+ st.title("Crescimento populacional - UBS Flamengo")
279
+
280
+ raw_data = [
281
+ {"Mês": "mai-21", "Usuários": 3402, "Domicílios": 1440, "Famílias": 1269},
282
+ {"Mês": "jun-21", "Usuários": 3503, "Domicílios": 1462, "Famílias": 1304},
283
+ {"Mês": "jul-21", "Usuários": 3559, "Domicílios": 1478, "Famílias": 1323},
284
+ {"Mês": "ago-21", "Usuários": 3592, "Domicílios": 1490, "Famílias": 1338},
285
+ {"Mês": "set-21", "Usuários": 3755, "Domicílios": 1573, "Famílias": 1380},
286
+ {"Mês": "out-21", "Usuários": 3776, "Domicílios": 1533, "Famílias": 1384},
287
+ {"Mês": "nov-21", "Usuários": 3839, "Domicílios": 1553, "Famílias": 1397},
288
+ {"Mês": "dez-21", "Usuários": 3926, "Domicílios": 1581, "Famílias": 1423},
289
+ {"Mês": "jan-22", "Usuários": 3951, "Domicílios": 1596, "Famílias": 1437},
290
+ {"Mês": "fev-22", "Usuários": 4035, "Domicílios": 1638, "Famílias": 1465},
291
+ {"Mês": "mar-22", "Usuários": 4131, "Domicílios": 1672, "Famílias": 1500},
292
+ {"Mês": "abr-22", "Usuários": 4306, "Domicílios": 1723, "Famílias": 1555},
293
+ {"Mês": "mai-22", "Usuários": 4553, "Domicílios": 1795, "Famílias": 1625},
294
+ {"Mês": "jun-22", "Usuários": 4639, "Domicílios": 1817, "Famílias": 1653},
295
+ {"Mês": "jul-22", "Usuários": 4719, "Domicílios": 1848, "Famílias": 1676},
296
+ {"Mês": "ago-22", "Usuários": 4776, "Domicílios": 1869, "Famílias": 1687},
297
+ {"Mês": "set-22", "Usuários": 4831, "Domicílios": 1883, "Famílias": 1699},
298
+ {"Mês": "out-22", "Usuários": 4871, "Domicílios": 1900, "Famílias": 1709},
299
+ {"Mês": "nov-22", "Usuários": 4874, "Domicílios": 1906, "Famílias": 1708},
300
+ {"Mês": "dez-22", "Usuários": 4920, "Domicílios": 1914, "Famílias": 1720},
301
+ {"Mês": "jan-23", "Usuários": 5135, "Domicílios": 2006, "Famílias": 1776},
302
+ {"Mês": "fev-23", "Usuários": 5396, "Domicílios": 2084, "Famílias": 1848},
303
+ {"Mês": "mar-23", "Usuários": 5544, "Domicílios": 2127, "Famílias": 1893},
304
+ {"Mês": "abr-23", "Usuários": 5546, "Domicílios": 2140, "Famílias": 1910},
305
+ {"Mês": "mai-23", "Usuários": 5579, "Domicílios": 2164, "Famílias": 1920},
306
+ {"Mês": "jun-23", "Usuários": 5642, "Domicílios": 2181, "Famílias": 1946},
307
+ {"Mês": "jul-23", "Usuários": 5681, "Domicílios": 2200, "Famílias": 1961},
308
+ {"Mês": "ago-23", "Usuários": 5728, "Domicílios": 2208, "Famílias": 1972},
309
+ {"Mês": "set-23", "Usuários": 5774, "Domicílios": 2228, "Famílias": 1983},
310
+ {"Mês": "out-23", "Usuários": 5841, "Domicílios": 2245, "Famílias": 2007},
311
+ {"Mês": "nov-23", "Usuários": 5891, "Domicílios": 2297, "Famílias": 2027},
312
+ {"Mês": "dez-23", "Usuários": 5933, "Domicílios": 2281, "Famílias": 2036},
313
+ {"Mês": "jan-24", "Usuários": 5982, "Domicílios": 2307, "Famílias": 2050},
314
+ {"Mês": "fev-24", "Usuários": 6005, "Domicílios": 2333, "Famílias": 2057},
315
+ {"Mês": "mar-24", "Usuários": 6020, "Domicílios": 2327, "Famílias": 2070},
316
+ {"Mês": "abr-24", "Usuários": 6074, "Domicílios": 2370, "Famílias": 2095},
317
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
 
319
+ df = pd.DataFrame(raw_data)
320
+
321
+ @st.cache_data
322
+ def processar_dados(dados, intervalo):
323
+ """
324
+ Process data based on the specified interval and return the aggregated data.
325
+ Parameters:
326
+ - dados: List of dictionaries containing data for each month.
327
+ - intervalo: String indicating the interval for data aggregation.
328
+
329
+ Returns:
330
+ - List of dictionaries with aggregated data based on the specified interval.
331
+ """
332
+ if intervalo == "Mensal":
333
+ return dados
334
+ agrupamentos = {"Trimestral": 3, "Semestral": 6, "Anual": 12}
335
+ dados_agrupados = []
336
+ for i in range(0, len(dados), agrupamentos[intervalo]):
337
+ grupo = dados[i : i + agrupamentos[intervalo]]
338
+ ultimo_Mês = grupo[-1]["Mês"]
339
+ dados_agrupados.append(
340
+ {
341
+ "Mês": ultimo_Mês,
342
+ "Usuários": max(d["Usuários"] for d in grupo),
343
+ "Domicílios": max(d["Domicílios"] for d in grupo),
344
+ "Famílias": max(d["Famílias"] for d in grupo),
345
+ }
346
+ )
347
+ return dados_agrupados
348
+
349
+ @st.cache_data
350
+ def formatar_data(Mês):
351
+ """
352
+ A function that formats the data based on the input Mês parameter.
353
+
354
+ Parameters:
355
+ - Mês (str): A string containing the month and year separated by a hyphen.
356
+
357
+ Returns:
358
+ - str: A formatted string in the format "month/year".
359
+ """
360
+ m, a = Mês.split("-")
361
+ return f"{m}/{a}"
362
+
363
+ # Adicionando estilo personalizado
364
+ st.markdown(
365
+ """
366
+ <style>
367
+ .stSelectbox [data-baseweb="select"] {
368
+ max-width: 300px;
369
+ }
370
+ .st-emotion-cache-16idsys p {
371
+ font-size: 20px;
372
+ font-weight: bold;
373
+ color: #4FCBFC;
374
+ }
375
+ </style>
376
+ """,
377
+ unsafe_allow_html=True,
378
+ )
379
+
380
+ # Criando duas colunas para os menus de opções
381
+ col1, col2, col3 = st.columns([3, 2, 2])
382
+
383
+ with col1:
384
+ st.dataframe(df, use_container_width=True, height=250, hide_index=True)
385
+
386
+ with col2:
387
+ intervalo = option_menu(
388
+ "Intervalo de Tempo",
389
+ ["Mensal", "Trimestral", "Semestral", "Anual"],
390
+ icons=["calendar-month", "calendar-quarter", "calendar-half", "calendar-year"],
391
+ menu_icon="cast",
392
+ default_index=0,
393
+ styles={
394
+ "container": {"padding": "0!important", "background-color": "#f0f0f3", "border-radius": "15px", "box-shadow": "5px 5px 10px #d1d1d4, -5px -5px 10px #ffffff"},
395
+ "icon": {"color": "#007bff", "font-size": "18px"},
396
+ "nav-link": {
397
+ "font-size": "14px",
398
+ "text-align": "center",
399
+ "margin": "5px",
400
+ "padding": "10px",
401
+ "--hover-color": "#e6e6e9",
402
+ "color": "#333333",
403
+ "border-radius": "10px",
404
+ "transition": "all 0.3s ease",
405
+ },
406
+ "nav-link-selected": {"background-color": "#ffffff", "box-shadow": "inset 3px 3px 5px #d1d1d4, inset -3px -3px 5px #ffffff"},
407
+ "separator": {"border-color": "#e0e0e3"},
408
+ },
409
+ )
410
+
411
+ with col3:
412
+ metrica = option_menu(
413
+ "Métrica",
414
+ ["Todos", "Usuários", "Domicílios", "Famílias"],
415
+ icons=["list", "person", "house", "people"],
416
+ menu_icon="cast",
417
+ default_index=0,
418
+ styles={
419
+ "container": {"padding": "0!important", "background-color": "#f0f0f3", "border-radius": "15px", "box-shadow": "5px 5px 10px #d1d1d4, -5px -5px 10px #ffffff"},
420
+ "icon": {"color": "#007bff", "font-size": "18px"},
421
+ "nav-link": {
422
+ "font-size": "14px",
423
+ "text-align": "center",
424
+ "margin": "5px",
425
+ "padding": "10px",
426
+ "--hover-color": "#e6e6e9",
427
+ "color": "#333333",
428
+ "border-radius": "10px",
429
+ "transition": "all 0.3s ease",
430
+ },
431
+ "nav-link-selected": {"background-color": "#ffffff", "box-shadow": "inset 3px 3px 5px #d1d1d4, inset -3px -3px 5px #ffffff"},
432
+ "separator": {"border-color": "#e0e0e3"},
433
+ },
434
+ )
435
 
436
+ dados_processados = processar_dados(raw_data, intervalo)
437
+
438
+ # Switch para mostrar valores nos pontos
439
+ mostrar_valores = st.checkbox("Mostrar valores nos pontos", value=True)
440
+
441
+ # Criação do gráfico
442
+ fig = go.Figure()
443
+
444
+ metricas = ["Usuários", "Domicílios", "Famílias"] if metrica == "Todos" else [metrica]
445
+ cores = {"Usuários": "#007bff", "Domicílios": "#28a745", "Famílias": "#ffc107"}
446
+
447
+ # Slider Component
448
+ # st.sidebar.header("Ajustes dos Balões")
449
+ # balloon_positions = {}
450
+ # for m in metricas:
451
+ # balloon_positions[m] = st.sidebar.slider(
452
+ # f"Posição do balão para {m}", min_value=-100, max_value=0, value=-40, step=5
453
+ # )
454
+
455
+ annotations = []
456
+ for m in metricas:
457
+ x_data = [formatar_data(d["Mês"]) for d in dados_processados]
458
+ y_data = [d[m] for d in dados_processados]
459
+
460
+ fig.add_trace(
461
+ go.Scatter(
462
+ x=x_data,
463
+ y=y_data,
464
+ mode="lines+markers",
465
+ name=m,
466
+ line=dict(color=cores[m], width=3),
467
+ marker=dict(size=10, symbol="circle", line=dict(width=2, color="white")),
468
+ )
469
+ )
470
+ if mostrar_valores:
471
+ for i, (x, y) in enumerate(zip(x_data, y_data)):
472
+ annotations.append(
473
+ dict(
474
+ x=x,
475
+ y=y,
476
+ xref="x",
477
+ yref="y",
478
+ text=f"{y:,.0f}",
479
+ showarrow=True,
480
+ arrowhead=2,
481
+ ax=0,
482
+ ay=balloon_positions[m],
483
+ bgcolor=cores[m],
484
+ opacity=0.8,
485
+ bordercolor="white",
486
+ borderwidth=2,
487
+ borderpad=4,
488
+ font=dict(color="white", size=10),
489
+ boxshadow=dict(x=2, y=2, blur=3, color='rgba(0,0,0,0.3)'),
490
+ )
491
+ )
492
+ fig.update_layout(
493
+ title={
494
+ "text": "Crescimento na Área de Saúde",
495
+ "y": 0.95,
496
+ "x": 0.5,
497
+ "xanchor": "center",
498
+ "yanchor": "top",
499
+ "font": dict(size=24, color="#333333"),
500
+ },
501
+ xaxis_title="Mês",
502
+ yaxis_title="Quantidade",
503
+ legend_title="Métricas",
504
+ template="plotly_white",
505
+ plot_bgcolor="#f0f0f3",
506
+ paper_bgcolor="#f0f0f3",
507
+ font=dict(color="#333333"),
508
+ xaxis=dict(showgrid=True, gridcolor="#e0e0e3", tickangle=45),
509
+ yaxis=dict(showgrid=True, gridcolor="#e0e0e3"),
510
+ legend=dict(
511
+ bgcolor="rgba(255,255,255,0.8)",
512
+ bordercolor="#e0e0e3",
513
+ borderwidth=1,
514
+ font=dict(size=12, color="#333333"),
515
+ ),
516
+ margin=dict(l=50, r=50, t=80, b=50),
517
+ annotations=annotations,
518
+ shapes=[
519
+ dict(
520
+ type="rect",
521
+ xref="paper", yref="paper",
522
+ x0=0, y0=0, x1=1, y1=1,
523
+ line=dict(color="#e0e0e3", width=2),
524
+ fillcolor="#f0f0f3",
525
+ layer="below"
526
+ )
527
+ ]
528
+ )
529
+ fig.add_shape(
530
+ type="rect",
531
+ xref="paper", yref="paper",
532
+ x0=-0.05, y0=-0.05, x1=1.05, y1=1.05,
533
+ line=dict(color="rgba(0,0,0,0.1)", width=5),
534
+ fillcolor="rgba(0,0,0,0)",
535
+ layer="below"
536
+ )
537
+ fig.update_layout(
538
+ updatemenus=[
539
+ dict(
540
+ type="buttons",
541
+ direction="left",
542
+ buttons=[
543
+ dict(args=[{"visible": [True, True, True]}], label="Mostrar Tudo", method="restyle"),
544
+ dict(args=[{"visible": [True, False, False]}], label="Usuários", method="restyle"),
545
+ dict(args=[{"visible": [False, True, False]}], label="Domicílios", method="restyle"),
546
+ dict(args=[{"visible": [False, False, True]}], label="Famílias", method="restyle")
547
+ ],
548
+ pad={"r": 10, "t": 10},
549
+ showactive=True,
550
+ x=0.1,
551
+ xanchor="left",
552
+ y=1.1,
553
+ yanchor="top",
554
+ bgcolor="#ffffff",
555
+ bordercolor="#e0e0e3",
556
+ borderwidth=1,
557
+ font=dict(color="#333333"),
558
+ ),
559
+ ]
560
+ )
561
 
562
+ st.plotly_chart(fig, use_container_width=True)
563
+
564
  add_vertical_space(10)
565
 
566