File size: 6,714 Bytes
3673dd2
45fa4c5
ab48cc8
45fa4c5
3673dd2
e00bb68
b76fcbc
e00bb68
8b89324
7990606
 
 
8b89324
18f19b5
 
 
 
 
acd93d4
 
 
 
 
 
3673dd2
7202737
3673dd2
0c855e3
b76fcbc
ea88ce5
 
5ea24dc
ea88ce5
 
b6475f9
35befed
ea88ce5
93e61b0
c065ffc
 
 
8a56502
ee8f205
ea88ce5
0d23f91
 
 
 
f65da4a
 
 
 
 
 
 
 
906f5df
18f19b5
 
 
 
 
 
 
 
9ea8d02
18f19b5
 
9ea8d02
18f19b5
 
d8c8ec3
 
18f19b5
ee8f205
9ea8d02
 
ee8f205
 
 
 
b76fcbc
9ea8d02
18f19b5
ab441ce
 
ee8f205
d8c8ec3
 
 
 
b76fcbc
 
d8c8ec3
 
 
f65da4a
4256751
d8c8ec3
ab441ce
 
d8c8ec3
18f19b5
 
9ea8d02
4874512
ab441ce
18f19b5
b76fcbc
 
 
 
d8c8ec3
 
 
80723cc
5ea24dc
4ce4306
80723cc
d8c8ec3
25dd4a7
 
 
d8c8ec3
906f5df
 
d8c8ec3
 
80723cc
d8c8ec3
 
25dd4a7
d8c8ec3
 
 
 
25dd4a7
d8c8ec3
 
 
 
3a1048d
196411a
 
 
 
 
 
 
 
 
 
 
 
 
 
6aac1b4
d8c8ec3
 
 
 
 
3673dd2
a6a9d6a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import streamlit as st
import plotly.express as px
import pandas as pd
from datetime import datetime, timedelta

# Configuración de la página
st.set_page_config(page_title="Generador de Franjas de Tiempo", layout="wide")

# Función para convertir HEX a RGBA con transparencia
def hex_to_rgba(hex_color, alpha=1.0):
    hex_color = hex_color.lstrip('#')
    return f'rgba({int(hex_color[0:2], 16)},{int(hex_color[2:4], 16)},{int(hex_color[4:6], 16)},{alpha})'

# Colores predefinidos
predefined_colors = [
    "#FF5C5C", "#5CCFFF", "#FFA500", "#90EE90", "#9370DB", "#FFD700"
]

# Lista de fuentes más utilizadas
font_options = [
    "Times New Roman", "Arial", "Helvetica", "Calibri", "Verdana", 
    "Tahoma", "Georgia", "Garamond", "Courier New", "Brush Script MT"
]

# Sidebar para la configuración del gráfico
st.sidebar.header("Configuración del Gráfico")

# Título del gráfico
chart_title = st.sidebar.text_input("Título del Gráfico", "Gráfico de Franjas de Tiempo")

# Seleccionar formato de tiempo
time_format = st.sidebar.selectbox("Formato de Tiempo", ["Año", "Mes y Año"])

# Ingresar valores para franjas de tiempo
num_y_vars = st.sidebar.number_input("Número de Variables Y", min_value=1, max_value=30, value=3, step=1)

y_values = {}
for i in range(num_y_vars):
    year = 2020 + i % 10  # Esto asegura que el año sea siempre válido
    y_start = st.sidebar.text_input(f"Fecha de Inicio para Y-{i+1} (YYYY-MM-DD)", key=f"y_start_{i}", value=f"{year}-01-01")
    y_end = st.sidebar.text_input(f"Fecha de Fin para Y-{i+1} (YYYY-MM-DD)", key=f"y_end_{i}", value=f"{year + 1}-12-31")
    y_name = st.sidebar.text_input(f"Nombre de la Variable Y-{i+1}", key=f"y_name_{i}", value=f"Y-{i+1}")
    y_values[y_name] = (y_start, y_end)

# Personalizar las etiquetas de los ejes
x_axis_label = st.sidebar.text_input("Etiqueta para el Eje X", "Tiempo")
y_axis_label = st.sidebar.text_input("Etiqueta para el Eje Y", "Variables")

# Opciones adicionales
with st.sidebar.expander("Opciones Adicionales"):
    superposed = st.checkbox("Superpuestas", value=False)
    bar_width = st.slider("Ancho de la Barra de Variable", min_value=0.1, max_value=1.0, value=0.5, step=0.1)
    show_grid = st.checkbox("Mostrar Líneas de Rejilla", value=True)
    opacity = st.slider("Opacidad (%)", min_value=0, max_value=100, value=100, step=1) / 100
    border_width = st.slider("Grosor del Borde", min_value=0.0, max_value=3.0, value=1.0, step=0.1)
    border_opacity = st.slider("Opacidad del Borde (%)", min_value=0, max_value=100, value=100, step=1) / 100

# Opción para múltiples colores
use_multiple_colors = st.sidebar.checkbox("Usar múltiples colores", value=True, key="use_multiple_colors")

# Seleccionar color(es) para el gráfico
selected_color = st.sidebar.color_picker("Color", "#24CBA0", key="single_color")

# Definir colores
if use_multiple_colors:
    colors = [st.sidebar.color_picker(f"Color {i+1}", predefined_colors[i % len(predefined_colors)], key=f"color_{i}")
              for i in range(num_y_vars)]
else:
    color = selected_color
    colors = [color] * num_y_vars  # Definir colors para casos donde no se usa múltiple colores

# Crear el DataFrame con franjas de tiempo
data_list = []
for idx, (y_name, (start_date, end_date)) in enumerate(y_values.items()):
    if start_date and end_date and y_name:
        color_with_opacity = hex_to_rgba(colors[idx], opacity)
        border_color_with_opacity = hex_to_rgba(colors[idx], border_opacity)
        data_list.append({
            'Variable': y_name,
            'Start': datetime.strptime(start_date, '%Y-%m-%d'),
            'End': datetime.strptime(end_date, '%Y-%m-%d'),
            'Category': '' if superposed else y_name,  # Cambiar categoría dependiendo de la opción seleccionada
            'Color': color_with_opacity,  # Asignar color a cada variable con opacidad
            'Border Width': border_width,
            'Border Color': border_color_with_opacity,  # Asignar color del borde con opacidad
            'Custom Hover': f'{y_name} ({start_date} - {end_date})'  # Texto personalizado para el hover
        })

data = pd.DataFrame(data_list)

# Ajustar fechas para simular apilamiento si está activado
if superposed:
    offset = timedelta(days=1)  # Ajusta el offset según el tamaño de la columna seleccionado
    for i in range(1, len(data)):
        data.loc[i, 'Start'] = data.loc[i-1, 'End']
        data.loc[i, 'End'] = data.loc[i, 'Start'] + (data.loc[i, 'End'] - data.loc[i, 'Start'])
    data['Category'] = ' '  # Usar una cadena vacía para ocultar el texto "Superpuestas"

# Crear gráfico de franjas de tiempo
fig = px.timeline(data, x_start="Start", x_end="End", y="Category", color="Variable", title=chart_title,
                  hover_data={'Variable': False, 'Start': False, 'End': False, 'Category': False, 'Custom Hover': True})

# Actualizar los colores y estilos de las franjas
for idx, row in data.iterrows():
    fig.data[idx].update(marker_color=row['Color'])
    fig.data[idx].update(marker_line=dict(width=row['Border Width'], color=row['Border Color']))
    fig.data[idx].update(hovertemplate=row['Custom Hover'])  # Usar el texto personalizado para el hover

# Ajustar el ancho de las barras si están superpuestas
if superposed:
    fig.update_traces(marker=dict(line_width=bar_width * 5))  # Ajusta el ancho de la barra en modo superpuesto

# Personalizar el formato de tiempo en el eje X
if time_format == "Año":
    tickformat = "%Y"
    dtick = "M12"  # Intervalo de 1 año
else:  # "Mes y Año"
    tickformat = "%b %Y"
    dtick = "M1"  # Intervalo de 1 mes

# Configuración de líneas de rejilla
grid_style = dict(showgrid=show_grid)

fig.update_layout(
    xaxis_title=x_axis_label,
    yaxis_title=y_axis_label,
    xaxis=dict(
        tickformat=tickformat,
        dtick=dtick,
        titlefont=dict(size=14),
        tickfont=dict(size=12),
        **grid_style
    ),
    yaxis=dict(
        titlefont=dict(size=14),
        tickfont=dict(size=12),
        **grid_style
    ),
    width=800,
    height=600,
    margin=dict(l=60, r=40, t=100, b=40),
    bargap=1-bar_width,  # Controlar el ancho de la barra con el bargap
    font=dict(family="Times New Roman", size=18, color="#374151"),  # Configuración de la fuente y color
    title=dict(
        text=chart_title,
        x=0.5,
        y=0.95,
        xanchor='center',
        yanchor='top',
        font=dict(
            family="Times New Roman",
            size=18,
            color="#374151",
            weight="normal"
        )
    ),
    legend_title_text=''  # Eliminar el texto del título de la leyenda
)

# Mostrar el gráfico
st.plotly_chart(fig)

# Información adicional
st.write("")