He encontrado la razón tanto para el comportamiento inicial como para la solución alternativa (y todo es específico de amCharts (nada que ver con SVG per se), así que estoy reformulando el título en consecuencia.
Lo que sucede es que cuando amCharts crea el SVG, necesita (o al menos, decide) definir el ancho y el alto en términos absolutos. Estos se basan en el tamaño del div de destino, obtenido a través de las propiedades offsetWidth
y offsetHeight
.
La pestaña inactiva tiene el conjunto de propiedades display: none
, y como resultado, esta parte del DOM ni siquiera se representa, por lo que devuelve cero para ambas propiedades de tamaño. Esto finalmente lleva a que amCharts cree un gráfico SVG 0x0 cuando se llama al chart.write
para el div oculto.
El ajuste de tamaño corrige las cosas porque cada gráfico registra un oyente en el evento de ventana onresize
, que llama al método handleResize
del gráfico. Esto obliga a volver a calcular el ancho y el alto en función de las nuevas dimensiones (actuales) del div.
Así que en conclusión creo que hay dos maneras alternativas de manejar esta situación:
- llamada
chart.write
para un gráfico cuando y sólo cuando la lengüeta se hace visible.
- Llame al método
handleResize
de cada gráfico cuando cambien las pestañas.
(La primera opción evita el golpe inicial de hacer un gráfico invisible, pero luego hace redibujo un completo cada vez que se cambian las fichas. Este último recibe un golpe por adelantado, pero es probable que más rápido después de eso. Por marcas de bonificación , la mejor solución sería representar cada gráfico exactamente una vez entre cada cambio de tamaño, la primera vez que se hace visible, pero eso es mucho más complejo ya que implicaría interferir con los detectores de eventos predeterminados, entre otras cosas).
Actualización: hay más complicaciones con la representación de un gráfico invisible; en particular, encontré problemas con los cálculos de altura sin tener en cuenta el espacio requerido por el eje del dominio y, por lo tanto, estirar el gráfico fuera de su div. Esto no se solucionó al llamar al handleResize
: llamar al measureMargins
de antemano parecía que debería funcionar pero no lo hizo. (Probablemente haya otro método que uno podría llamar después de esto para hacerlo funcionar como resetMargins
pero en este punto comenzó a sentirse muy escamoso ...)
Como tal, no creo que sea práctico representar un gráfico para el primera vez en un div no visible, así que fui con alguna combinación de las viñetas de arriba. Escucho cuando la pestaña de un gráfico se vuelve visible por primera vez y luego llamo al chart.write
para obtener el objeto de gráfico apropiado, y cada vez que cambian las pestañas, todos los gráficos previamente renderizados reciben el tamaño.
No es un tutorial sobre este tema realizado por amCharts: http://blog.amcharts.com/2012/08/displaying-javascript-charts-in-tabs-or. html – zeroin
Highcharts/Highstock también tiene este problema. – iman
Agregar chart.invalidateSize(); en la pestaña, haga clic. Ref: https://www.amcharts.com/tutorials/displaying-charts-in-tabs-or-other-dynamic-page-elements/ – Raja