Eurocrimes is an interactive data visualization project developed for theblacksea.eu. It is part of a series of in-depth journalistic investigations regarding crime and immigration across the EU.

About theblacksea.eu: We reveal fascinating, contentious and inspiring stories from the Black Sea region for a global audience, using deep reportage, tough fact-checking and a balanced perspective.

About Eurocrimes: Romania is the European country with the greatest number of its expats in prison in the EU. An international team of journalists across six nations with data from 25 countries has revealed these stats - and investigated why this is happening.


Live Demo: planet34.org / theblacksea.eu

Source: github.com








The project was built on the skeleton boilerplate using D3.js library for data binding to DOM elements and SVG drawing.

In the article one can find four interactive graphs and a few others which are served as JPGs. The interactive ones are rendered responsive on the client in SVG using external data files as sources. Some data processing is done on the fly as the files are loaded while some others have been manually sorted beforehand to speed up production.

Chord Diagram

The chord diagram is a graphical way to display and easily understand mutual relationships between entities. The raw data is data is usually represented by a matrix. We used this type of diagram to show where EU nationals are imprisoned abroad across the EU.

Below is a small sample of the original data used in the chord. Host countries are listed in the first column.

          Austria  Belgium  Bulgaria  Croatia  Cyprus
Austria   X        2575     15733     40006     325
Belgium   3020     X        26415     1216      410
Bulgaria  519      1061     X         92        714
Croatia   5148     375      305       X         0
Cyprus    394      291      6857      93        X

My implementation is based on Steven Hall's excellent examples (web/repo). I've rewritten most of it to fit the scope of the project and added extra functionality: better (logical) grouping of arcs, smoother display of elements with easing, on-click selections, events and states.

Map Diagram

To better illustrate overall migration relationships between EU member states we used an interactive choropleth map of Europe where users can select a country and visually understand migration numbers through shades of color.

The map itself was difficult to get right. The available (free) maps from either openstreetmaps or naturalearthdata are geometrically complex and contain the entire world. In order for the map to be usable it needs to be simplified (smaller render times when interacting) and it needs to have less of the world in it as users only see a part of it.

I edited the map with SAGA GIS to erase everything that would not be in the viewport and to bind the correct data to each country element. The second step was to simplify the geometry. SAGA's simplification algorithm didn't do a good job as it does not retain the line intersections between countries, creating white space between country borders. Mapshaper is a great tool that solves this problem and outputs light, useable files.

Should you need a simple map of Europe with basic data properties feel free to use the one I made. The format is TopoJSON and it works best with a Lambert azimuthal equal-area projection.

Here's an example data object from the map.

"__data__": {
  "type": "Feature",
  "properties": {
    "NAME": "Spain",
    "CONTINENT": "Europe",
    "REGION_UN": "Europe",
    "SUBREGION": "Southern Europe",
    "EU_MEMBER": "1"
  "geometry": {
  "diaspora": {
    "Austria": 8844,
    "Belgium": 43052,
    "Bulgaria": 130116,
    "Croatia": 1684,
    "Cyprus": 366,
    "Czech": 8548,
    "Denmark": 11269,
    "Estonia": 1875,
    "Finland": 11803,
    "France": 201769,
    "Germany": 200870,
    "Greece": 3982,
    "Hungary": 9297,
    "Ireland": 14651,
    "Italy": 100304,
    "Latvia": 3987,
    "Lithuania": 16837,
    "Luxembourg": 1425,
    "Malta": 312,
    "Netherlands": 46181,
    "Poland": 64960,
    "Portugal": 114661,
    "Romania": 658132,
    "Slovakia": 7297,
    "Slovenia": 1312,
    "Sweden": 19056,
    "UK": 308821

The diaspora object is not part of the map base data such as Region or Name. As the page is loaded and processed, the extra data is bound from external sources.

Proportion Chart

We wanted to use this chart to highlight the fact that the biggest group of prisoners across the EU is by far locals in their home country (82%) and that imprisoned expats are a very small minority.

Going for a visual representation which would help people understand the scale of these numbers we made a diagram in which each 1000 prisoners were represented by a square. After building a prototype we realized it just takes too much screen space considering the sum of all groups is 600000+.

We bumped the people per square number to 10000 but that was still too much to display. It did achieve what we intended however the end result was not aesthetically pleasing. The sane solution was to just calculate the proportion of each group and draw a square per 1%. This allowed for a more condensed chart even though in the end it became a pie chart in disguise.

The way I built the chart allows for a lot of flexibility by just changing some variables, you can easily change all the parameters on the fly and see how that fits with the page layout.

peopleSquare = 1;   // People per square - 1 if %, higher number if absolute representation
squarePadding = 20; // Inner spacing between squares
squareSize = 0;     // Calculated according to canvas size but can be specified as an absolute value
sqSizeProp = 20;    // Size modifier for squares
internalMargins = 0;// Padding inside the canvas

The project is MIT licensed. Sources are available in the git repo.