Using Thymeleaf inline JavaScript with D3.js

The fancy data visualization for the lazy backend developer
January 31, 2019 by Michael

I gave this talk several times now and every time I got asked how I created this visualization, clustering the genres I’m listening to by decade and country:



I just did a super spontaneous video for that. Key take away: Just use server side rendered HTML through Thymeleaf, obviously running on Spring Boot, render the content model as inlined Javascript and be good to go. Want an API later on?

Structure your Spring MVC controller and your service or repository layer in a way that makes it actually reusable.

Anyway, here’s the short clip and below the relevant code snippets:

Spring MVC controller, GenresController.java, either returning a String, denoting the template to be rendered, or the Model as just the response body:

@GetMapping(value = { "", "/" }, produces = MediaType.TEXT_HTML_VALUE)
public ModelAndView genres() {
 
	var model = genresModel();
	return new ModelAndView("genres", model);
}
 
@GetMapping(value = { "", "/" }, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public Map<String, Object> genresModel() {
 
	var genres = this.genreRepository.findAll(Sort.by("name").ascending());
	var allSubgrenes = genreRepository.findAllSubgrenes();
	var top10Subgenres = allSubgrenes.stream().sorted(comparingLong(Subgenre::getFrequency).reversed()).limit(10).collect(toList());
	return Map.of(
			"genres", genres,
			"subgenres", allSubgrenes,
			"top10Subgenres", top10Subgenres
	);
}

The Thymeleaf template genres.html. The standard controller above renders it when / is requested, accepting text/html.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      xmlns:th="http://www.thymeleaf.org"
      layout:decorate="~{layout}">
<head>
    <title th:text="#{genres}">Placeholder</title>
    <script th:inline="javascript">
        var subgenres = /*[[${subgenres}]]*/ {};
    </script>
</head>
<body>
<!-- Some more content -->
</body>
</html>

Calling this thing application.js is way too much. It’s a simple function, reading in the global subgenres variable and displays it as a nice D3.js chart.

Remember: This is also no silver bullet and I absolutely don’t have anything agains todays Javascript development. I just feel more at home near a database.

2 comments

  1. Minty wrote:

    Exactly what I was looking for in terms of integrating Thymeleaf and D3.js – thanks for the post.

    Posted on June 13, 2019 at 11:42 PM | Permalink
  2. Michael wrote:

    Great to hear! Thanks for your feedback.

    Posted on June 15, 2019 at 9:32 PM | Permalink
Post a Comment

Your email is never published. We need your name and email address only for verifying a legitimate comment. For more information, a copy of your saved data or a request to delete any data under this address, please send a short notice to michael@simons.ac from the address you used to comment on this entry.
By entering and submitting a comment, wether with or without name or email address, you'll agree that all data you have entered including your IP address will be checked and stored for a limited time by Automattic Inc., 60 29th Street #343, San Francisco, CA 94110-4929, USA. only for the purpose of avoiding spam. You can deny further storage of your data by sending an email to support@wordpress.com, with subject “Deletion of Data stored by Akismet”.
Required fields are marked *