

In a nutshell
EU DataViz 2021 was an international conference on open data and data visualisation addressing the needs of the public sector across the EU. Online from Luxembourg to the world, it was organised by the Publications Office of the European Union as part of the EU Open Data Days. The conference was funded by ISA2 programme of the European Union.
Held on 23 and 24 November 2021, this free online conference provided the opportunity to share experiences and latest trends in open data and data visualisation. The first day focused on ways to ensure open data is freely available for reuse, which in turn improves transparency and leads to better decision-making and citizen engagement. The second day highlighted data visualisation as a powerful tool for various purposes, from making complex information accessible in a meaningful way to exploring policy scenarios.
EU DataViz brought together the open data and data visualisation community, including policymakers, researchers, academia, private entities, students and citizens interested in the power of open data as a factor determining our future.
The recordings of the event sessions and presentations are available in the Programme tab.
How can value be generated from open data?
The amount of data made freely available by public authorities is rising. In addition, situations such as the COVID-19 pandemic highlight the importance of reliable and connected information and effective communication. How can we ensure that open data is available and can be interlinked and reused to generate value?
Creating a common European data space is an essential step towards bringing the value of data to people and organisations and developing effective solutions.
Furthermore, data visualisation helps unleash the potential of the existing data and communicate complex messages clearly. It can be applied across multiple sectors and areas of life, such as mobility, health or energy.
Testimonials
The following has evaluated to null or missing:
==> jsonimg.groupId [in template "10157#10197#7974329" at line 45, column 84]
----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: #assign urlJsonImg = urlJsonImg + jso... [in template "10157#10197#7974329" at line 45, column 49]
----
1<div id="carouselExampleCaptions" class="carousel slide show-neighbors" data-ride="carousel" data-pause="hover" data-interval="false">
2
3 <ol class="carousel-indicators">
4 <#list entries as entry>
5 <li data-target="#carouselExampleCaptions" data-slide-to="${entry_index}" data-target="#eu-pub-carousel" class="${(entry_index==0)?string('active', '')}"> </li>
6 </#list>
7 </ol>
8
9 <div class="carousel-inner">
10 <#if entries?has_content>
11 <#list entries as curEntry>
12 <#assign curEntry = curEntry />
13 <#assign assetRenderer = curEntry.getAssetRenderer() />
14 <#assign className = assetRenderer.getClassName() />
15 <#assign article = assetRenderer.getArticle() />
16 <#assign docXml = saxReaderUtil.read(curEntry.getAssetRenderer().getArticle().getContent()) />
17
18 <#assign rootElement = docXml.getRootElement() />
19 <#assign availableLocales = rootElement.attribute("available-locales").getText() />
20 <#assign defaultLocale = rootElement.attribute("default-locale").getText() />
21
22 <#if article.isApproved() >
23 <#assign articleId = article.getArticleId() />
24
25 <#assign background = docXml.valueOf("//dynamic-element[@name='Background']/dynamic-content[@language-id='"+defaultLocale+"']/text()") />
26 <#assign imageAlt = docXml.valueOf("//dynamic-element[@name='ImageAlt']/dynamic-content[@language-id='"+defaultLocale+"']/text()") />
27 <#assign textColor = docXml.valueOf("//dynamic-element[@name='TextColor']/dynamic-content[@language-id='"+defaultLocale+"']/text()") />
28
29 <#if (availableLocales?contains(locale)) >
30 <#assign title = docXml.valueOf("//dynamic-element[@name='Content_Title']/dynamic-content[@language-id='"+locale+"']/text()") />
31 <#assign content = docXml.valueOf("//dynamic-element[@name='Content']/dynamic-content[@language-id='"+locale+"']/text()") />
32 <#assign target = docXml.valueOf("//dynamic-element[@name='Target']/dynamic-content[@language-id='"+locale+"']/text()") />
33 <#assign priority = docXml.valueOf("//dynamic-element[@name='Priority']/dynamic-content[@language-id='"+locale+"']/text()") />
34 <#else>
35 <#assign title = docXml.valueOf("//dynamic-element[@name='Content_Title']/dynamic-content[@language-id='"+defaultLocale+"']/text()") />
36 <#assign content = docXml.valueOf("//dynamic-element[@name='Content']/dynamic-content[@language-id='"+defaultLocale+"']/text()") />
37 <#assign target = docXml.valueOf("//dynamic-element[@name='Target']/dynamic-content[@language-id='"+defaultLocale+"']/text()") />
38 <#assign priority = docXml.valueOf("//dynamic-element[@name='Priority']/dynamic-content[@language-id='"+defaultLocale+"']/text()") />
39 </#if>
40
41
42 <#assign img = docXml.valueOf("//dynamic-element[@name='Image10711']/dynamic-content[@language-id='"+defaultLocale+"']/text()") />
43 <#assign jsonimg = jsonFactoryUtil.createJSONObject(img)>
44 <#assign urlJsonImg = "/documents/" >
45 <#assign urlJsonImg = urlJsonImg + jsonimg.groupId >
46 <#assign urlJsonImg = urlJsonImg + "/" + jsonimg.fileEntryId >
47 <#assign urlJsonImg = urlJsonImg + "/" + jsonimg.name >
48 <#assign urlJsonImg = urlJsonImg + "/" + jsonimg.uuid >
49
50 <div class="carousel-item ${(curEntry_index==0)?string('active', '')}" articleId="${articleId}">
51 <div class="item__third item__third${curEntry_index%3}" access-index="${curEntry_index}" data-caption="#caption${curEntry_index}" style="background: ${background};">
52 <a tabindex="-1" href="${target}" class="caroulsel-img-link ${defaultLocale}"><img src="${urlJsonImg}" class="d-block w-200" alt="Photo of ${imageAlt}"></a>
53 <div class="carousel-caption d-md-block">
54 <h5><a tabindex="-1" href="${target}" style="color: ${textColor} !important;">${title}</a></h5>
55 <div class="carousel-description" style="color: ${textColor} !important;">${content}</div>
56 </div>
57 </div>
58 </div>
59
60 </#if>
61
62 </#list>
63 </#if>
64 </div>
65
66 <a class="carousel-control-prev" href="#carouselExampleCaptions" role="button" data-slide="prev">
67 <span class="carousel-control-prev-icon" aria-hidden="true"></span>
68 <span class="sr-only">Previous</span>
69 </a>
70 <a class="carousel-control-next" href="#carouselExampleCaptions" role="button" data-slide="next">
71 <span class="carousel-control-next-icon" aria-hidden="true"></span>
72 <span class="sr-only">Next</span>
73 </a>
74 <div aria-live="polite" aria-atomic="true" class="liveregion visuallyhidden">Item <span class="active">0</span> of <span class="total">0</span></div>
75 </div>
76
77<script>
78$(document).ready(function() {
79 var carouselItems = document.querySelectorAll('.carousel-item');
80 Array.prototype.forEach.call (carouselItems, function (carouselItem) {
81 carouselItem.children[1].children[0].setAttribute("tabindex", "0");
82 carouselItem.children[1].querySelector("h5 a").setAttribute("tabindex", "0");
83 });
84
85 //set accessibility values
86 var activeSlide = document.querySelector('.carousel-item.active .item__third:nth-child(2)').getAttribute("access-index");
87 var numberOfSlides = document.querySelectorAll('.carousel-item').length;
88 document.querySelector('.liveregion.visuallyhidden span.active').innerHTML = parseInt(activeSlide) + 1;
89 document.querySelector('.liveregion.visuallyhidden span.total').innerHTML = numberOfSlides;
90});
91
92// identify an element to observe
93const elementToObserve = document.querySelector(".carousel .carousel-inner");
94
95// create a new instance of `MutationObserver` named `observer`,
96// passing it a callback function
97const observer = new MutationObserver(function() {
98 var activeSlide = document.querySelector('.carousel-item.active .item__third:nth-child(2)').getAttribute("access-index");
99 var numberOfSlides = document.querySelectorAll('.carousel-item').length;
100 document.querySelector('.liveregion.visuallyhidden span.active').innerHTML = parseInt(activeSlide) + 1;
101 document.querySelector('.liveregion.visuallyhidden span.total').innerHTML = numberOfSlides;
102});
103observer.observe(elementToObserve,
104 {subtree: true,
105 childList: true,
106 attributes: true,
107 attributeOldValue: true
108 });
109</script>
110
111<style>
112.text-container.carousel-caption {
113 position: absolute;
114 right: 1%;
115 bottom: unset;
116 left: unset;
117 z-index: 10;
118 padding-top: 5px;
119 padding-bottom: 5px;
120 color: #FFF;
121 text-align: left;
122}
123.text-container{
124 position: absolute;
125 z-index: 1;
126 background-color: #fff;
127 right: 1%;
128 top: 20px;
129 width: 45%;
130 padding: 5px;
131 opacity: 0.8;
132}
133
134.carousel.pointer-event {
135 touch-action: pan-y;
136}
137
138.show-neighbors {
139 overflow: hidden;
140 height: 330px;
141}
142.show-neighbors .item__third:first-child,
143.show-neighbors .item__third:last-child {
144 display: none;
145}
146
147.carousel-control-prev, .carousel-control-next{
148 top:-40px;
149}
150
151.carousel-indicators li {
152 width: 10px;
153 height: 10px;
154 border: 1px solid #697188;
155 border-radius: 100%;
156}
157.carousel-indicators {
158 bottom: 10px;
159}
160
161.carousel-indicators .active, .carousel-indicators .nav-underline .tab.active a, .nav-underline .tab.active .carousel-indicators a{
162 background: #697188;
163}
164
165.carousel-caption{
166 position: absolute;
167 right: 30px;
168 bottom: 0;
169 z-index: 10;
170 width: 43%;
171 padding-top: 47px;
172 top: 0;
173 color: #FFF;
174 left: unset;
175 text-align: left;
176}
177
178.carousel-control-next-icon{
179 background-image: url("data:image/svg+xml,%3Csvg width='50' height='50' viewBox='0 0 50 50' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='25' cy='25' r='23' fill='%23112250' fill-opacity='0.75' stroke='white' stroke-width='4'/%3E%3Cpath d='M20 35L30 25L20 15' stroke='white' stroke-width='4' stroke-miterlimit='10'/%3E%3C/svg%3E%0A");
180 width:50px;
181 height:50px;
182}
183
184.carousel-control-prev-icon{
185 background-image: url("data:image/svg+xml,%3Csvg width='50' height='50' viewBox='0 0 50 50' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='25' cy='25' r='23' transform='rotate(-180 25 25)' fill='%23112250' fill-opacity='0.75' stroke='white' stroke-width='4'/%3E%3Cpath d='M29.9999 15L19.9999 25L29.9999 35' stroke='white' stroke-width='4' stroke-miterlimit='10'/%3E%3C/svg%3E%0A");
186 width:50px;
187 height:50px;
188}
189
190.carousel-item img {
191 vertical-align: middle;
192 border-style: none;
193 width: 100%;
194}
195
196.carousel-caption h5 a {
197 color: #fff !important;
198 overflow: hidden;
199 display: -webkit-box;
200 -webkit-line-clamp: 3;
201 -webkit-box-orient: vertical;
202 font-size: 20px;
203 line-height: 25px;
204}
205.carousel-control-prev, .carousel-control-next {
206opacity:unset;
207}
208
209.carousel-caption .carousel-description {
210 overflow: hidden;
211 display: -webkit-box;
212 -webkit-line-clamp: 5;
213 -webkit-box-orient: vertical;
214 font-size: 14px;
215 line-height: 20px;
216}
217
218.show-neighbors .item__third {
219 min-width: 599px;
220 min-height: 270px;
221 border-right: 4px solid #fff !important;
222 border-left: 4px solid #fff !important;
223}
224.carousel-item img {
225 vertical-align: unset;
226 border-style: unset;
227 max-width: 259px;
228 max-height: 240px;
229 border: 1px solid #BBBBBB;
230 width: auto;
231 float: right;
232}
233.item__third .caroulsel-img-link{
234 display: block;
235 max-width: 50%;
236 position: absolute;
237 left: 26%;
238 top: 50%;
239 transform: translate(-50%, -50%);
240 -ms-transform: translate(-50%, -50%);
241 -webkit-transform: translate(-50%, -50%);
242}
243
244
245/*-------------non - mobile--------------*/
246@media (min-width: 426px) {
247 .show-neighbors .carousel-indicators {
248 margin-right: 25%;
249 margin-left: 25%;
250 }
251 .show-neighbors .carousel-control-prev,
252 .show-neighbors .carousel-control-next {
253 width: 10%;
254 z-index: 11;
255 /* .carousel-caption has z-index 10 */
256 }
257 .show-neighbors .carousel-inner {
258 width: 150%;
259 left: -25%;
260 }
261 .show-neighbors .carousel-item-next:not(.carousel-item-left),
262 .show-neighbors .carousel-item-right.active {
263 -webkit-transform: translate3d(33%, 0, 0);
264 transform: translate3d(33%, 0, 0);
265 }
266 .show-neighbors .carousel-item-prev:not(.carousel-item-right),
267 .show-neighbors .carousel-item-left.active {
268 -webkit-transform: translate3d(-33%, 0, 0);
269 transform: translate3d(-33%, 0, 0);
270 }
271 .show-neighbors .item__third {
272 display: block !important;
273 float: left;
274 position: relative;
275 /* captions can now be added */
276 width: 33.33333333%;
277 }
278}
279
280
281/*-------------small desktop--------------*/
282@media(min-width: 992px) and (max-width: 1261px){
283 .carousel-item img {
284 max-width: 190px;
285 max-height: 180px;
286 }
287 .show-neighbors .item__third {
288 min-width: 448px;
289 }
290 .item__third .caroulsel-img-link {
291 left: 24%;
292 top: 51%;
293 }
294 .carousel-caption {
295 width: 50%;
296 right: 10px;
297 }
298}
299
300
301@media(min-width: 426px) and (max-width: 991px){
302 .carousel-item-next, .carousel-item-prev {
303 display: none !important;
304 }
305}
306
307
308/*-------------mobile & tablet--------------*/
309@media only screen and (max-width: 991px) {
310 .carousel-indicators {
311 bottom: -13px;
312 }
313
314 .show-neighbors {
315 overflow: hidden;
316 height: 210px;
317 }
318
319 .carousel-control-next-icon, .carousel-control-prev-icon{
320 width:22px;
321 height:22px;
322 }
323
324 .carousel-caption {
325 right: 15px;
326 width: 42%;
327 padding-top: 20px;
328 }
329
330 .carousel-caption h5 a {
331 color: #fff !important;
332 overflow: hidden;
333 display: -webkit-box;
334 -webkit-line-clamp: 2;
335 -webkit-box-orient: vertical;
336 font-size: 0.8rem;
337 line-height: 16px;
338 }
339
340 .carousel-caption .carousel-description {
341 overflow: hidden;
342 display: -webkit-box;;
343 -webkit-line-clamp: 4;
344 -webkit-box-orient: vertical;
345 font-size: 0.7rem;
346 line-height: 15px;
347 }
348
349 .show-neighbors {
350 width: 79vw;
351 margin-bottom: 25px;
352 }
353 .carousel-control-prev, .carousel-control-next {
354 top: 0;
355 z-index: 100;
356 }
357 .maincontentarea .portlet-boundary{
358 width: 100%;
359 }
360 .carousel-item img {
361 max-width: 110px;
362 max-height: 170px;
363 }
364 .show-neighbors .item__third {
365 min-height: 186px;
366 }
367
368}
369
370/*-------------tablet--------------*/
371@media(min-width: 426px) and (max-width: 991px){
372 .show-neighbors {
373 width: 100%;
374 }
375 .show-neighbors .carousel-inner {
376 width: 100%;
377 left: 0;
378 }
379 .show-neighbors .item__third {
380 width: 100%;
381 min-height: 186px;
382 }
383 .carousel-item img {
384 max-width: 310px;
385 width: 80%;
386 }
387 .carousel-item.active .item__third:not(:first-child){
388 display: none !important;
389 }
390
391 .show-neighbors .item__third {
392 width: 100%;
393 min-height: 275px;
394 min-width: 895px;
395 }
396
397 .show-neighbors .carousel-inner {
398 width: 100%;
399 left: 0px;
400 }
401 .carousel-item.active .item__third:not(:first-child){
402 display: none !important;
403 }
404
405 .show-neighbors .item__third {
406 width: 100%;
407 min-height: 210px;
408 min-width: auto;
409 }
410
411 .show-neighbors {
412 overflow: hidden;
413 height: 235px;
414 }
415
416 .carousel-caption {
417 right: 10%;
418 width: 37%;
419 padding-top: 49px;
420 }
421}
422
423
424/*-------------mobile-------426-------*/
425@media only screen and (max-width: 767px) {
426 .carousel-caption {
427 right: 15%;
428 width: unset;
429 padding-top: unset;
430 top:unset;
431 left:15%;
432 text-align: center;
433 }
434
435 .item__third .caroulsel-img-link {
436 display: block;
437 max-width: 50%;
438 position: absolute;
439 top: 5%;
440 transform: unset;
441 -ms-transform: translate(-50%, -50%);
442 -webkit-transform: unset;position: absolute;
443 left: 0;
444 right: 0;
445 margin-left: auto;
446 margin-right: auto;
447 }
448 .carousel-item img {
449 float: none;
450 margin: auto;
451 max-width: 130px;
452 max-height: 110px;
453 }
454
455 .carousel-caption .carousel-description {
456 display:none;
457 }
458 .show-neighbors {
459 width: auto !important;
460 }
461
462 .maincontentarea {
463 width: 100% !important;
464 }
465 .maincontent .portlet-layout>section {
466 padding: 0 !important;
467 }
468}
469</style>
470
471
472
473<script type="text/javascript">
474$('.carousel-item', '.show-neighbors').each(function(){
475 var next = $(this).next();
476 if (! next.length) {
477 next = $(this).siblings(':first');
478 }
479 next.children(':first-child').clone().appendTo($(this));
480}).each(function(){
481 var prev = $(this).prev();
482 if (! prev.length) {
483 prev = $(this).siblings(':last');
484 }
485 prev.children(':nth-last-child(2)').clone().prependTo($(this));
486});
487
488
489YUI().use('node', function(Y) {
490 Y.all('.eu-pub-carousel .carousel-item a').on('click', function(e) {
491 e.preventDefault();
492 if ('undefined' === typeof _webtrends) {
493 return;
494 }
495 _webtrends.dcsMultiTrack('WT.dl', '29', 'DCSext.w_home_element', 'Carousel');
496 window.location.href = e.currentTarget.get('href');
497 });
498});
499</script>
500<script src='/o/OPPortalEE/external/touchswipe/jquery.touchSwipe.min.js'></script>
501<script type="text/javascript">
502 $(".carousel-item").swipe({
503 swipe: function (event, direction, distance, duration, fingerCount, fingerData) {
504 if (direction == 'left') $(this).carousel('next');
505 if (direction == 'right') $(this).carousel('prev');
506 },
507 allowPageScroll: "vertical"
508 });
509</script>























































