French version
Please refer to this tutorial to see how to implement this template on your portal.
Dataset in use: datavizgallery
(See it on userclub domain)
Fields in use:
theme | date | photo | title | iddataset | datavizlink |
---|---|---|---|---|---|
Administration | 2022-02-22 | issy.jpeg | Jumelages et partenariats internationaux d’Issy-les-Moulineaux | jumelages-partenariats-internationaux-issy | https://data.issy.com/explore/dataset/jumelages-partenariats-internationaux-issy/jumelages/?sort=annee |
Budget | 2022-01-03 | cannes.jpeg | Budget primitif 2021 | “budget-primitif-2021 | resultats-et-excedents |
Délibérations | 2022-01-01 | soissons.jpeg | Délibérations du Conseil Municipal de Soissons | deliberations-du-conseil-municipal-de-soissons | https://data.ville-soissons.fr/pages/deliberations_conseils_municipaux/ |
Services | 2023-03-01 | bordeaux.jpeg | Les équipements de Bordeaux Métropole | equipement-public-bordeaux | https://opendata.bordeaux-metropole.fr/pages/equipements/ |
<div class="container">
<ods-dataset-context context="ctx,ctxdate"
ctx-dataset="datavizgallery"
ctxdate-dataset="datavizgallery"
ctx-parameters="{'sort':'date','disjunctive.theme':'true'}">
<h1 class="page-title">Dataviz Gallery</h1>
<p class="page-subtitle">
Sur cette page vous pouvez trouver les dernières visualisations crées sur notre portail.
</p>
<div class="content-card search-module-container">
<!-- SEARCH -->
<div class="search-module">
<i class="fa fa-search search-module-icon" aria-hidden="true"></i>
<input placeholder="Rechercher" ng-model="ctx.parameters['q']"
ng-model-options="{ updateOn: 'keyup', debounce: { 'default': 300, 'blur': 0 }}"
class="search-module-input" type="text" />
<button class="search-module-clear" ng-if="ctx.parameters['q']"
ng-click="ctx.parameters['q'] = undefined">
<i class="fa fa-times-circle" aria-hidden="true"></i>
</button>
</div>
<!-- FILTERS Search & Select -->
<div class="filter-list">
<div ods-facet-results="theme" ods-facet-results-facet-name="theme"
ods-facet-results-context="ctx" ods-facet-results-sort="alphanum">
<ods-select ng-if="theme"
selected-values="ctx.parameters['refine.theme']" multiple="false"
options="theme" label-modifier="name" value-modifier="name"
placeholder="Sélectionnez un thème"></ods-select>
</div>
<div class="clear-filters"
ng-show="ctx.parameters['refine.theme'].length >0 ">
<div class="clear-filters-button" role="button" ng-click="ctx.parameters['refine.theme'] = undefined;">
Supprimer le filtre
<i class="fa fa-times-circle" aria-hidden="true"></i>
</div>
</div>
</div>
<!-- FILTERS date - If you want to add a date filter to your template, you can do it by removing this line (45) and the line 80
<div class="filter-date"
ng-init="bounds = {'min':undefined, 'max':undefined, 'minselection':undefined, 'maxselection':undefined}">
<div ods-adv-analysis="dateanalysis"
ods-adv-analysis-context="ctxdate"
ods-adv-analysis-select="min(date) as mindate, max(date) as maxdate">
{{ bounds.min = (dateanalysis[0].mindate | moment : 'YYYY-MM-DD') ; '' }}
{{ bounds.max = (dateanalysis[0].maxdate | moment : 'YYYY-MM-DD') ; '' }}
</div>
<ods-date-range-slider ng-if="bounds.min && bounds.max"
context="ctx"
initial-from="{{ bounds.min }}"
initial-to="{{ bounds.max }}"
start-bound="bounds.min"
end-bound="bounds.max"
date-field="date"
precision="day"
from="bounds.minselection"
to="bounds.maxselection">
</ods-date-range-slider>
<div ng-if="bounds.min && bounds.max"
class="filter-date-button"
ng-class="{'filter-date-button-disabled':
bounds.minselection == bounds.min &&
bounds.maxselection == bounds.max}"
ng-click="bounds.minselection = bounds.min;
bounds.maxselection = bounds.max">
Toute la période <i class="fa fa-arrows-h" aria-hidden="true"></i>
</div>
</div>
remove this other line to activate the date filter option -->
</div>
<!-- KPIs -->
<section class="kpis-container row row-equal-height">
<!-- KPI box component -->
<div class="kpi-card"
tabindex="0"
ods-adv-analysis="agg"
ods-adv-analysis-context="ctx"
ods-adv-analysis-select="count(*) as x">
<p class="kpi-title">
{{ (agg[0].x || 0) | number : (kpi.precision || 0) }}
<span ng-if="kpi.unit" class="kpi-unit">{{ kpi.unit }}</span>
</p>
<p class="page-subtitle">
data visualisation<span ng-if="agg[0].x>1">s</span> sélectionnée<span ng-if="agg[0].x>1">s</span>
</p>
</div>
</section>
<!-- CARDS -->
<section>
<div class="row row-equal-height"
ods-results="items"
ods-results-context="ctx"
ods-results-max="100">
<div ng-repeat="item in items" class="col-md-4">
<div class="access-card">
<div class="access-card-container">
<a href="{{item.fields.datavizlink}}" target="_blank">
<div class="access-card-img"
style="background-image: url('/assets/theme_image/{{item.fields.photo}}')">
<h3 class="access-card-pretitle">{{item.fields.theme}}</h3>
</div>
</a>
<div class="access-card-content">
<h2 class="access-card-title">{{ item.fields.title }}</h2>
<!-- remove this line and line 128 to add the date of creation of your dataset
<p>Date de création : {{item.fields.date | date}}</p>
-->
<p>Jeu<span ng-if="(item.fields.iddataset | split: ';').length >1">x</span> de données utilisé<span ng-if="(item.fields.iddataset | split: ';').length >1">s</span> : </p>
<ul>
<li ng-repeat="dataset in (item.fields.iddataset | split: ';')">
<ods-catalog-context context="catalogue"
catalogue-parameters="{'refine.datasetid':dataset}">
<span ods-results="listedataset"
ods-results-context="catalogue"
ods-results-max="10">
<a ng-href="/explore/dataset/{{dataset}}" target="_blank">{{listedataset[0].metas.title}}</a>
</span>
</ods-catalog-context>
</li>
</ul>
</div>
</div>
<div class="access-card-button">
<a href="{{item.fields.datavizlink}}" target="_blank"><div class="access-card-button-content">
Accéder
</div>
</a>
</div>
</div>
</div>
</div>
</section>
<!-- End of cards section-->
</ods-dataset-context>
</div>
/* General Layout
========================================================================== */
:root {
--secondary-color: black;
}
main {
margin: 6rem 0 3em 0;
}
@media screen and (min-width: 992px) {
.row-equal-height {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin-bottom: 20px;
}
/* Fix for early content wrapping in Safari*/
.row-equal-height:before,
.row-equal-height:after {
content: normal;
}
}
.page-title {
font-size: 3rem;
font-weight: bold;
margin-top: 0;
margin-bottom: 1rem;
}
.page-subtitle {
font-size: 1.2rem;
line-height: 2;
margin-top: 0;
margin-bottom: 3rem;
}
.margin-bottom-20 {
margin-bottom: 20px;
}
/* Search Module
========================================================================== */
.search-module-container {
padding: 26px;
margin-bottom: 25px;
}
.search-module {
display: flex;
align-items: stretch;
border-bottom: 1px solid #dee5ef;
margin-bottom: 13px;
transition: all .2s;
}
.search-module:hover,
.search-module:focus-within {
border-bottom-color: var(--links);
}
.search-module-icon {
color: #898d92;
margin-right: 8px;
align-self: center;
}
.search-module-input {
background-color: transparent;
width: 100%;
outline: none;
border: none;
padding: 12px 0;
transition: all .2s;
color: var(--text);
}
.search-module-input::placeholder {
transition: all .2s;
}
.search-module-clear {
color: #898d92;
font-size: 1rem;
background: transparent;
border: none;
margin: 0;
outline: none;
padding: 0 0 0 12px;
transition: all .2s;
}
.search-module-clear:hover {
opacity: .65;
}
.search-module:hover .search-module-icon,
.search-module:focus-within .search-module-icon,
.search-module:hover .search-module-input::placeholder,
.search-module:focus-within .search-module-input::placeholder {
color: var(--links)
}
/* Filters
========================================================================== */
.filter-list {
display: flex;
flex-wrap: wrap;
position: relative;
}
.filter-list>* {
margin: 0 0 10px;
width: 100%;
}
.odswidget-select .odswidget-select-dropdown.open .odswidget-select-dropdown-menu {
width: 100%
}
.clear-filters {
display: flex;
align-items: center;
justify-content: center;
}
.clear-filters-button:hover {
opacity: 0.65;
}
.odswidget-select,
.odswidget-select .odswidget-select-dropdown {
width: 100%;
}
@media screen and (min-width: 500px) {
.filter-list>* {
margin: 0 10px 10px 0;
width: inherit;
}
.odswidget-select .odswidget-select-dropdown.open .odswidget-select-dropdown-menu {
width: max-content;
min-width: 240px;
}
}
/*********** Filter date ************/
.filter-date {
display: flex;
flex-direction: column;
align-items: center;
margin: 13px 26px 32px 26px;
}
.odswidget-date-range-slider {
width: 100%;
}
.filter-date-button {
margin-left: 0;
margin-top: 13px;
white-space: nowrap;
text-decoration: underline;
}
.filter-date-button:not(.filter-date-button-disabled):hover {
opacity: 0.65;
}
.filter-date-button-disabled {
opacity: 0.5;
pointer-event: none;
text-decoration: none;
}
@media screen and (min-width: 500px) {
.filter-date {
flex-direction: row;
}
.filter-date-button {
margin-left: 50px;
margin-top: 0;
}
}
/* date range slider style override */
.odswidget-date-range-slider .irs--flat .irs-from,
.odswidget-date-range-slider .irs--flat .irs-single,
.odswidget-date-range-slider .irs--flat .irs-to {
color: var(--text);
border: 1px solid #cbd2db;
border-radius: 2rem;
background: #FFFFFF;
}
.odswidget-date-range-slider .irs--flat .irs-from:before,
.odswidget-date-range-slider .irs--flat .irs-single:before,
.odswidget-date-range-slider .irs--flat .irs-to:before {
border-top-color: var(--text);
}
.odswidget-date-range-slider .irs--flat .irs-bar {
background-color: var(--highlight);
}
.odswidget-date-range-slider .irs--flat .irs-handle>i:first-child {
background-color: var(--highlight);
}
.odswidget-date-range-slider .irs--flat .irs-handle.state_hover>i:first-child,
.odswidget-date-range-slider .irs--flat .irs-handle:hover>i:first-child {
background-color: var(--text);
}
/* Content Card
========================================================================== */
.content-card {
background-color: var(--boxes-background);
border-radius: 4px;
height: 100%;
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.13);
}
.content-card-button {
color: var(--highlight);
border: 1px solid var(--highlight);
background: transparent;
display: inline-block;
text-align: center;
font-size: .867rem;
border-radius: 4px;
padding: .5rem 1.15rem;
text-decoration: none;
transition: all .2s;
}
.content-card-button:hover {
background-color: var(--highlight);
color: #FFFFFF;
text-decoration: none;
}
/* KPI Card
========================================================================== */
@media screen and (min-width: 992px) {
.kpis-container {
display: flex;
justify-content: center;
}
}
.kpi-card {
background-color: var(--boxes-background);
height: 100%;
padding: 30px;
border-radius: 4px;
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.13);
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
text-align: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
text-align: center;
}
.kpi-title {
font-weight: normal;
color: var(--highlight);
font-size: 3.2rem;
margin-top: 0;
margin-bottom: 7px;
max-width: 100%;
}
.kpi-unit {
font-size: 0.8em;
color: var(--secondary-color);
}
/* Access-card
========================================================================== */
.col-md-4 {
padding-bottom: 20px
}
ul {
padding-left: 13px;
}
.access-card {
border-radius: 10px;
background-color: #fff;
height: 100%;
background-color: #f6f8fb;
box-shadow: 0px 6px 13px rgba(0, 0, 0, 0.13);
transition: all 0.3s;
display: block;
color: var(--text);
margin-bottom: 10px;
display: flex;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
}
.access-card:hover {
box-shadow: 0px 6px 13px rgba(0, 0, 0, 0.5);
text-decoration: none;
overflow: hidden;
}
.access-card-img {
background-repeat: no-repeat;
background-size: cover;
background-position: center;
height: 250px;
position: relative;
border-radius: 10px 10px 0 0;
}
.access-card-content {
padding: 26px 26px 10px 26px;
}
.access-card-pretitle {
text-transform: uppercase;
color: #FFF;
background-color: var(--links) ;
border-radius: 3px;
font-weight: 400;
margin: 0px;
font-size: 12px;
position: absolute;
bottom: 15px;
left: 26px;
padding: 5px;
}
.access-card-title {
font-weight: 400;
margin: 10px 0px;
font-size: 22px;
border-bottom: solid var(--highlight) 2px;
padding-bottom: 10px;
}
.access-card-subtitle {
font-size: 16px;
font-weight: 400;
margin: 0px 0px 10px 0px;
}
.access-card-content p {
margin: 5px 0px;
}
.access-card-button {
display: flex;
justify-content: center;
margin: 0px 26px 26px;
padding-top: 0px;
}
.access-card-button:hover {
opacity: 0.7;
}
.access-card-button-content {
background-color: var(--highlight);
text-align: center;
color: #FFF;
border-radius: 24px;
padding: 10px 20px 10px 20px;
width: fit-content;
}