SVG Gráfica Bianual

Casi todo lo que tenga una fecha de inicio y una fecha final se puede ver beneficiado del uso de este SVG 


Cómo se ve?

ejemplo calendario.gif


Qué se necesita?
2 tablas una Tabla padre (donde se mostrará la gráfica) y una tabla hija (que contiene las fechas de inicio y las fechas finales) 

Requisitos de las tablas
La tabla padre (Calendario) no tiene requisitos fuera de su ID

La tabla Hija(Eventos) necesita aparte de su [ID]
[Evento] un nombre o palabra para identificar el "evento"
[Calendario] de tipo Ref (Referencia al Calendario o tabla padre)
[Categoría] de tipo Enum (para el código que comparto solo puede haber un máximo de 4 categorías)
[Fecha_Inicio] de tipo Date
[Fecha_Final]  de tipo Date

Qué empiece la magia 
1.-
Primero vamos a crear una columna virtual [Evento_SVG] tipo texto su fórmula será la siguiente:

IFS(
AND(
YEAR([Fecha_Inicio])=YEAR(TODAY())+1,YEAR([Fecha_Final])=YEAR(TODAY())+1
),
CONCATENATE(
"<!-- Rectángulo -->
<rect x=#",
NUMBER(
SWITCH(MONTH([Fecha_Inicio]),
1,75,
2,118,
3,161,
4,204,
5,247,
6,290,
7,333,
8,376,
9,419,
10,462,
11,505,
12,548,
""
)
)+DAY([Fecha_Inicio])*1.43,
"# y=#",
SWITCH([Categoría],
"Categoría 1",85,
"Categoría 2",155,
"Categoría 3",225,
"Categoría 4",295,
""
),
"# width=#",
HOUR([Fecha_Final]-[Fecha_Inicio])/24*1.43,
"# height='35' rx='10' ry='10' fill=#",
SWITCH([Categoría],
"Categoría 1","rgba(31, 207, 208, 0.62)",
"Categoría 2","rgba(69, 0, 165, 0.62)",
"Categoría 3","rgba(52, 182, 1, 0.62)",
"Categoría 4","rgba(185, 97, 4, 0.62)",
""
),
"#>
</rect>"
),
AND(
YEAR([Fecha_Inicio])=YEAR(TODAY()),YEAR([Fecha_Final])=YEAR(TODAY())
),

CONCATENATE(
"<!-- Rectángulo -->
<rect x=#",
NUMBER(
SWITCH(MONTH([Fecha_Inicio]),
1,75,
2,118,
3,161,
4,204,
5,247,
6,290,
7,333,
8,376,
9,419,
10,462,
11,505,
12,548,
""
)
)+DAY([Fecha_Inicio])*1.43,
"# y=#",
SWITCH([Categoría],
"Categoría 1",50,
"Categoría 2",120,
"Categoría 3",190,
"Categoría 4",260,
""
),
"# width=#",
HOUR([Fecha_Final]-[Fecha_Inicio])/24*1.43,
"# height='35' rx='10' ry='10' fill=#",
SWITCH([Categoría],
"Categoría 1","rgba(31, 207, 208, 0.62)",
"Categoría 2","rgba(107, 30, 216, 0.62)",
"Categoría 3","rgba(85, 210, 35, 0.62)",
"Categoría 4","rgba(223, 130, 34, 0.62)",
""
),
"#>
</rect>"
),
AND(
YEAR([Fecha_Inicio])=YEAR(TODAY()),YEAR([Fecha_Final])=YEAR(TODAY())+1
),

CONCATENATE(
"<!-- Rectángulo -->
<rect x=#",
NUMBER(
SWITCH(MONTH([Fecha_Inicio]),
1,75,
2,118,
3,161,
4,204,
5,247,
6,290,
7,333,
8,376,
9,419,
10,462,
11,505,
12,548,
""
)
)+DAY([Fecha_Inicio])*1.43,
"# y=#",
SWITCH([Categoría],
"Categoría 1",50,
"Categoría 2",120,
"Categoría 3",190,
"Categoría 4",260,
""
),
"# width=#",
HOUR([Fecha_Final]-[Fecha_Inicio])/24*1.43,
"# height='35' rx='10' ry='10' fill=#",
SWITCH([Categoría],
"Categoría 1","rgba(31, 207, 208, 0.62)",
"Categoría 2","rgba(107, 30, 216, 0.62)",
"Categoría 3","rgba(85, 210, 35, 0.62)",
"Categoría 4","rgba(223, 130, 34, 0.62)",
""
),
"#>
</rect>
<!-- Rectángulo -->
<rect x='75' y=#",
SWITCH([Categoría],
"Categoría 1",85,
"Categoría 2",155,
"Categoría 3",225,
"Categoría 4",295,
""
),
"# width=#",
NUMBER(
SWITCH(MONTH([Fecha_Final]),
1,0,
2,43,
3,86,
4,129,
5,172,
6,215,
7,258,
8,301,
9,344,
10,387,
11,430,
12,473,
""
)
)+DAY([Fecha_Final])*1.43,
"# height='35' rx='10' ry='10' fill=#",
SWITCH([Categoría],
"Categoría 1","rgba(31, 207, 208, 0.62)",
"Categoría 2","rgba(69, 0, 165, 0.62)",
"Categoría 3","rgba(52, 182, 1, 0.62)",
"Categoría 4","rgba(185, 97, 4, 0.62)",
""
),
"#>
</rect>"
),
AND(
YEAR([Fecha_Inicio])=YEAR(TODAY())-1,YEAR([Fecha_Final])=YEAR(TODAY())
),
CONCATENATE(
"<!-- Rectángulo -->
<rect x='75' y=#",
SWITCH([Categoría],
"Categoría 1",50,
"Categoría 2",120,
"Categoría 3",190,
"Categoría 4",260,
""
),
"# width=#",
NUMBER(
SWITCH(MONTH([Fecha_Final]),
1,0,
2,43,
3,86,
4,129,
5,172,
6,215,
7,258,
8,301,
9,344,
10,387,
11,430,
12,473,
""
)
)+DAY([Fecha_Final])*1.43,
"# height='35' rx='10' ry='10' fill=#",
SWITCH([Categoría],
"Categoría 1","rgba(70, 223, 225, 0.62)",
"Categoría 2","rgba(154, 90, 243, 0.62)",
"Categoría 3","rgba(125, 229, 84, 0.62)",
"Categoría 4","rgba(245, 157, 66, 0.62)",
""
),
"#>
</rect>"
)
)

2.- En la tabla padre o Calendario vamos a crear una columna virtual [Calendario_SVG] de tipo Imágen la contendrá la siguiente fórmula:

"data&colon;image/svg+xml;utf8,"&ENCODEURL(SUBSTITUTE(CONCATENATE("<svg width='600' height='400' xmlns='http://www.w3.org/2000/svg'>

<!-- Eje X (Tiempo en meses) con líneas verticales -->
<line x1='75' y1='350' x2='75' y2='50' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:2' />
<text x='85' y='350' font-family='Arial' font-size='14' fill='black' font-weight='bold'>Ene.</text>

<line x1='118' y1='350' x2='118' y2='50' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:2' />
<text x='128' y='350' font-family='Arial' font-size='14' fill='black' font-weight='bold'>Feb.</text>

<line x1='161' y1='350' x2='161' y2='50' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:2' />
<text x='171' y='350' font-family='Arial' font-size='14' fill='black' font-weight='bold'>Mar.</text>

<line x1='204' y1='350' x2='204' y2='50' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:2' />
<text x='214' y='350' font-family='Arial' font-size='14' fill='black' font-weight='bold'>Abr.</text>

<line x1='247' y1='350' x2='247' y2='50' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:2' />
<text x='257' y='350' font-family='Arial' font-size='14' fill='black' font-weight='bold'>May.</text>

<line x1='290' y1='350' x2='290' y2='50' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:2' />
<text x='300' y='350' font-family='Arial' font-size='14' fill='black' font-weight='bold'>Jun.</text>

<line x1='333' y1='350' x2='333' y2='50' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:2' />
<text x='343' y='350' font-family='Arial' font-size='14' fill='black' font-weight='bold'>Jul.</text>

<line x1='376' y1='350' x2='376' y2='50' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:2' />
<text x='386' y='350' font-family='Arial' font-size='14' fill='black' font-weight='bold'>Ago.</text>

<line x1='419' y1='350' x2='419' y2='50' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:2' />
<text x='425' y='350' font-family='Arial' font-size='14' fill='black' font-weight='bold'>Sept.</text>

<line x1='462' y1='350' x2='462' y2='50' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:2' />
<text x='472' y='350' font-family='Arial' font-size='14' fill='black' font-weight='bold'>Oct.</text>

<line x1='505' y1='350' x2='505' y2='50' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:2' />
<text x='515' y='350' font-family='Arial' font-size='14' fill='black' font-weight='bold'>Nov.</text>

<line x1='548' y1='350' x2='548' y2='50' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:2' />
<text x='558' y='350' font-family='Arial' font-size='14' fill='black' font-weight='bold'>Dic.</text>

<line x1='591' y1='350' x2='591' y2='50' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:2' />

<!-- Eje Y (Categoría) -->

<text x='0' y='85' font-family='Arial' font-size='14' fill='black' font-weight='bold'>Categoría 1</text>
<text x='0' y='155' font-family='Arial' font-size='14' fill='black' font-weight='bold'>Categoría 2</text>
<text x='0' y='225' font-family='Arial' font-size='13.5' fill='black' font-weight='bold'>Categoría 3</text>
<text x='0' y='295' font-family='Arial' font-size='13.5' fill='black' font-weight='bold'>Categoría 4</text>

<!-- Líneas horizontales para marcar las secciones -->
<line x1='75' y1='50' x2='590' y2='50' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:1;stroke:gray' />
<line x1='75' y1='120' x2='590' y2='120' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:1;stroke:gray' />
<line x1='75' y1='190' x2='590' y2='190' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:1;stroke:gray' />
<line x1='75' y1='260' x2='590' y2='260' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:1;stroke:gray' />
<line x1='75' y1='330' x2='590' y2='330' style='stroke:rgba(128, 128, 128, 0.5);stroke-width:1;stroke:gray' />




<!-- Línea de tiempo hoy -->
<line x1=#",NUMBER(SWITCH(MONTH(TODAY()),
1,75,
2,118,
3,161,
4,204,
5,247,
6,290,
7,333,
8,376,
9,419,
10,462,
11,505,
12,548,
""))+DAY(TODAY())*1.43,"#y1='42' x2=#",NUMBER(SWITCH(MONTH(TODAY()),
1,75,
2,118,
3,161,
4,204,
5,247,
6,290,
7,333,
8,376,
9,419,
10,462,
11,505,
12,548,
""))+DAY(TODAY())*1.43,"#y2='330' style='stroke:dashed;stroke-width:2;stroke:Blue' />


<!-- Etiqueta de 'Hoy' -->
<text x=""",
NUMBER(SWITCH(MONTH(TODAY()),
1,75,
2,118,
3,161,
4,204,
5,247,
6,290,
7,333,
8,376,
9,419,
10,462,
11,505,
12,548,
""))+DAY(TODAY())*1.43-50,
""" y='40' font-family='Arial' font-size='14' fill='blue'>",TEXT(TODAY(),"D/MM/YY"),"</text>

",SUBSTITUTE(
[Related Eventos][Evento_SVG]," , ","
"),"

</svg>
"
),"#"," ' ")
)

 Eso es todo! 

espero que a alguien le sirva, recuerda que puedes modificar las columnas virtuales para que se ajusten a tu caso de uso

A tener en cuenta
No va a funcionar si el evento comenzó el año antepasado al actual ó si termina dentro de 2 años o más


Espero que otros miembros de la comunidad me corrijan en caso de que las fórmulas no estén bien ó si es posible optimizarlas.
También hice pruebas usando <Title> para mostrar los detalles a modo de tooltip pero solo funciona cuando le das click derecho en el SVG / abrir imagen en una pestaña nueva.

3 8 519
  • UX
8 REPLIES 8

Aurelien
Google Developer Expert
Google Developer Expert

Hi @Kabuliño 

Thanks for the tip, but I don't understand Spanish. I think I'm not the only one.

Can you please translate it all, so that it turns accessible for everyone on the community? 🙂

FWIW, here's a rough-and-ready translation to English from Google.

¡Gracias, @Kabuliño, por desarrollar y compartir esta técnica innovadora! Se pide mucho una gráfica tipo Gantt.

Yes, in fact, I first thought about using a Gantt chart from quickchart.io but it was too difficult for me so I decided to try with SVG and this was the result. I know there is a lot to improve, mainly  that it can be adapted and customized for each use case.

I thought about putting a part of the SVG in real columns to make it easier to understand and customize the SVG.
I hope to soon make an update showing how the number of categories can be determined as needed, as well as the colors (in the example I gave I am using 3 colors per category).

The only thing that I have no idea if it is possible but that I would love to achieve is to show the dates and details of the event as a tooltip or something similar

Excelente!

No hay manera que puedas compartir tu app??

Gracias!

Lo que explico en el post es básicamente toda la app. si tienes alguna duda puedes preguntar.


Por el momento estoy algo ocupado con mi trabajo pero estoy pensando en hacer un app para generar el gráfico tipo Gantt personalizado, me gustaría compartírsela a alguien que la pueda publicar para que esté disponible para todos y no tenga que estar compartiendo uno por uno. 

Igual estoy ocupado por eso preguntaba si la podias compartir pero gracias por el tip.  Ya que tenga tiempo lo pondre en practica.

Saludos.

Desde el año pasado tengo lista la app (Gantt_Genetaror) para generar el svg tipo Gantt pero no había tenido el tiempo para hacer el video muestra hasta el día hoy, espero les guste.

Demostración del funcionamiento de la app (video) 

Mi idea es compartirla con alguien que la pueda publicar para poder compartirla con la comunidad.
Es bienvenida toda crítica y sugerencia para mejorar la app antes de que se publique (Si es que en algún momento llega a publicarse)

Top Labels in this Space