Znalazłem przyczynę zarówno wstępnego zachowania, jak i obejścia - i to wszystko jest specyficzne dla amCharts (nie ma nic wspólnego z SVG per se), więc odpowiednio zmieniam tytuł.
Co się dzieje, gdy amCharts tworzy SVG, musi (lub przynajmniej decyduje się) zdefiniować szerokość i wysokość w wartościach bezwzględnych. Są one oparte na rozmiarze docelowego elementu div uzyskanego za pomocą właściwości offsetWidth
i offsetHeight
.
Nieaktywna karta ma ustawioną właściwość display: none
iw rezultacie ta część DOM nie jest nawet renderowana, więc zwraca zero dla obu właściwości rozmiaru. To ostatecznie prowadzi do amCharts tworzenia wykresu SVG 0x0, gdy chart.write
jest wywoływana dla ukrytego div.
Zmiana rozmiaru rozwiązuje problem, ponieważ każdy wykres rejestruje odbiorcę w zdarzeniu okna onresize
, które wywołuje metodę z tabeli handleResize
. Wymusza to ponowne obliczenie szerokości i wysokości w oparciu o nowe (bieżące) wymiary elementu div.
Tak na zakończenie Myślę, że istnieją dwa sposoby, aby sobie z tym poradzić:
- połączeń
chart.write
na wykresie wtedy i tylko wtedy, gdy jego zakładka staje się widoczny.
- Zadzwoń do każdego z nich, używając metody
handleResize
, gdy zmieniają się karty.
(Pierwsza opcja pozwala uniknąć początkowego trafienia renderowania niewidocznej mapy, ale następnie wykonuje pełne przerysowanie za każdym razem, gdy zmienione są zakładki, która wykonuje uderzenie z góry, ale prawdopodobnie później szybciej. , najlepszym rozwiązaniem byłoby renderowanie każdego wykresu dokładnie jeden raz pomiędzy każdą zmianą rozmiarów, przy pierwszym wyświetleniu, ale jest to o wiele bardziej złożone, ponieważ wymagałoby to między innymi ingerencji w domyślne detektory zdarzeń.)
Aktualizacja: Istnieją dalsze komplikacje z renderowaniem niewidocznego wykresu; w szczególności, znalazłem problemy z obliczeniami wysokości nie biorąc pod uwagę przestrzeni wymaganej przez oś domeny, a więc wyciągając wykres z jego div. Nie zostało to naprawione przez wywołanie handleResize
- wywołanie wcześniej wyglądało tak, jak powinno, ale nie działa. (Prawdopodobnie istnieje inna metoda, którą można wywołać po tym, aby zadziałać tak, jak resetMargins
, ale w tym momencie zaczęło się wydawać bardzo niestabilne ...)
W związku z tym nie wydaje mi się praktyczne, aby wyrenderować wykres dla pierwszy raz na niewidocznym div, więc poszedłem z kombinacją powyższych kul. Słucham, kiedy zakładka wykresu staje się widoczna po raz pierwszy, a następnie wywołuje chart.write
dla odpowiedniego obiektu wykresu - a gdy zmieniają się tabulatory, wszystkie uprzednio renderowane wykresy są informowane, aby obsłużyć zmianę rozmiaru.
Jest poradnik na ten temat wykonanej przez amCharts: http://blog.amcharts.com/2012/08/displaying-javascript-charts-in-tabs-or. html – zeroin
Highcharts/Highstock również ma ten problem. – iman
Dodaj chart.invalidateSize(); w karcie kliknij. Ref: https://www.amcharts.com/tutorials/displaying-charts-in-tabs-or-other-dynamic-page-elements/ – Raja