Nie tak dawno temu, bo 1 stycznia 2021 opublikowałem artykuł o tym jak wdrożyć na stronie WWW, na przykładzie WordPrerssa interaktywne Wheel Of Life (koło życia) generowane przy pomocy biblioteki amCharts. W ostatnim akapicie napisałem, że „jeśli chodzi o moje zadanie to najpewniej na tym koniec, dalej już koleżanka musi sobie ten wykres zasilić treścią”, co oczywiście koleżanka zrobiła. W ostatnim zdaniu jednakże napisałem „chyba że jeszcze coś jej do głowy wpadnie”. Ten artykuł powstaje w lutym, ale notatki i historia korespondencji z koleżanką wskazują, że nie zakończył się jeszcze pierwszy tydzień stycznia, a już dostałem od koleżanki pytanie, czy można by… I nie musiałem wykazywać tu żadnych nadzwyczajnych umiejętności związanych z przewidywaniem przyszłości, by wiedzieć, że tak będzie. Że to tylko kwestia czasu… ;-)

Eksport do PDF i modyfikacja zawartości w amCharts

Koło życia działa, z tego co wiem, to nawet cieszy się sporym zainteresowaniem wśród „klienteli” koleżanki, ale koleżanka wpadła na pomysł, że fajnie jakby można było wypełnione koło życia nie tylko pobrać w PDF zamiast PNG, ale też by można było dołożyć do takiego dokumentu dodatkowe informacje. Zaczynając od logo i tytułu wykresu, daty wygenerowania dokumentu, aż po dodatkowe informacje, wyjaśniające, o co w ogóle w tym wykresie chodzi.

To, co ułatwiło moje zadanie, to przejście z generowania plików w formacie PNG na format PDF. Wynika to z tego, że w amCharts z różnych względów nie możemy podczas eksportu do pliku dodać zewnętrznych danych. W przypadku formatu PDF jest podobnie, ale amCharts do generowania tego typu plików korzysta z biblioteki pdfmake, a to oznacza, że mamy dużo większe możliwości ingerencji w ostateczny plik. Dzięki temu w prosty sposób mogłem zrobić to, co koleżanka sobie wymyśliła…

Na pierwszy ogień zmiana dostępnych opcji eksportu. Pozbywamy się PDFa i drukowania, a wstawiamy format PDF:


chart.exporting.menu = new am4core.ExportMenu();
chart.exporting.filePrefix = "webinsider-wol-" + (new Date().toISOString().slice(0, 10)).replace(/[^0-9]/g, "").toString();
  
chart.exporting.menu.items = [{
	"label": "...",
	"menu": [
		{ "type": "pdf", "label": "Pobierz PDF", "options": { "addURL": false } }
	]
}];

Od razu dodałem tutaj jeszcze jedną modyfikację, tak by plik PDF nie nazywał się „webisnider-wol.pdf”, a od razu w nazwie miał datę, czyli np. „webinsider-wol-20210209.pdf”. Dzięki temu łatwiej porównać wyniki z kolejnych podejść do koła życia.

Dalszy krok, to dodanie (cały czas pracujemy w sekcji JavaScript amCharts) na samym końcu funkcji, która będzie odpowiadała za wygenerowanie pliku PDF z kolejnymi zmianami:

chart.exporting.adapter.add("pdfmakeDocument", function(pdf, target) {

}

Do tej globalnej funkcji wstawiamy funkcję, która dodaje tytuł wykresu:


pdf.doc.content.unshift({
	text: "Webinsider.pl WoL Demo",
	margin: [0, 30],
	style: {
		fontSize: 14,
		bold: false,
		opacity: 0.5,
		alignment: 'center'
	}
});

Następnie dodajemy logo, które będzie wyświetlać się tuż pod wykresem:


pdf.doc.content.push({
	image: "data:image/png;base64,...",
	width: 150,
	margin: [ 0, 0, 0, 25 ],
	style: {
		alignment: 'right'
	}
});

Grafiki nie wrzucałem przez link, a bezpośrednio w kod, korzystając z logo przekonwertowanego wcześniej do formatu base64.  Np. zamiast:

image: "data:image/png;base64,...",

Będzie:

image: "data:image/png;base64,iVBORw0KGgoAA(...)QQAAAABJRU5ErkJggg==",

Na koniec najważniejsze, czyli dodatkowy tekst pod wykresem:


pdf.doc.content.push(
	{ text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam orci elit, iaculis ac tortor in, porttitor dictum felis. Quisque vehicula facilisis ultricies. Ut suscipit pulvinar magna, ac egestas massa tempus et.\n\nDonec ullamcorper rutrum facilisis. Etiam sed metus non dui aliquam sodales id vel est. Aenean porttitor quam dolor, venenatis sagittis augue sagittis at. Pellentesque turpis eros, accumsan sed gravida nec, vulputate ac diam. Morbi semper, neque vitae tincidunt facilisis, erat arcu tristique tortor, non feugiat ipsum lacus non turpis.\n\n',
	style: {
		fontSize: 12,
		opacity: 0.5,
		alignment: 'justify'
	}},
	{ text: 'Zapraszamy na Webinsider.pl', link: 'https://webinsider.pl',
	style: {
		fontSize: 12,
		opacity: 0.5,
		alignment: 'center',
		bold: true
	}}
)

W powyższym przykładzie są to 2 akapity tekstu (można każdy akapit dać jako oddzielną sekcję „text”, można je rozdzielić 2 znakami nowej linii, tak jak ja to zrobiłem w tym przypadku (\n\n)), oraz linijkę z tekstem „zapraszamy na Webinsider.pl”, która jednocześnie jest linkiem.

Czyli cała funkcja odpowiedzialna za modyfikację pliku PDF, ze wszystkimi powyższymi zmianami będzie wyglądała tak:

chart.exporting.adapter.add("pdfmakeDocument", function(pdf, target) {
 

	pdf.doc.content.unshift({
		text: "Webinsider.pl WoL Demo",
		margin: [0, 30],
		style: {
			fontSize: 14,
			bold: false,
			opacity: 0.5,
			alignment: 'center'
		}
	});
  

	pdf.doc.content.push({
		image: "data:image/png;base64,iVBORw0KGgoAA(...)QQAAAABJRU5ErkJggg==",
		width: 150,
		margin: [ 0, 0, 0, 25 ],
		style: {
			alignment: 'right'
		}
	});
  

	pdf.doc.content.push(
		{ text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam orci elit, iaculis ac tortor in, porttitor dictum felis. Quisque vehicula facilisis ultricies. Ut suscipit pulvinar magna, ac egestas massa tempus et.\n\nDonec ullamcorper rutrum facilisis. Etiam sed metus non dui aliquam sodales id vel est. Aenean porttitor quam dolor, venenatis sagittis augue sagittis at. Pellentesque turpis eros, accumsan sed gravida nec, vulputate ac diam. Morbi semper, neque vitae tincidunt facilisis, erat arcu tristique tortor, non feugiat ipsum lacus non turpis.\n\n',
		style: {
			fontSize: 12,
			opacity: 0.5,
			alignment: 'justify'
		}},
		{ text: 'Zapraszamy na Webinsider.pl', link: 'https://webinsider.pl',
		style: {
			fontSize: 12,
			opacity: 0.5,
			alignment: 'center',
			bold: true
		}}
	);
	
	return pdf;
});

Co w efekcie da plik PDF z taką zawartością:

Nie wiem, czy to już koniec mojej przygody z kołem życia na amCharts, bo choć koleżanka od ponad miesiąca nie ma nowych życzeń (przynajmniej w tym kontekście ;-)), to jest to na tyle fajne „narzędzie”, że pewnie prędzej czy później sam z niego skorzystam w jakimś swoim projekcie. Zresztą od momentu publikacji pierwszego poradnika na temat wdrożenia koła życia w WordPressie regularnie otrzymuję zapytania o wdrożenie takiego rozwiązania… :-)

(!) Zgłoś błąd na stronie