Créer un tableau de bord dynamique - pas à pas !

L’objectif de ce tutoriel est de créer très facilement un tableau de bord en utilisant les outils CSS, AngularJS et les widgets fournis par la plateforme OpenDataSoft.

Concepts de base
  • choisir un jeu de données

  • créer une page

  • ajouter une vue carte

  • ajouter une vue tableau

  • ajouter un graphe

  • lier tous ces éléments ensemble !

  • ajouter un formulaire de recherche textuelle

  • ajouter des filtres

  • découvrir les classes CSS pour un développement responsive en toute facilité

  • étudier le “contexte” plus en profondeur

  • ajouter un compteur d’enregistrements

  • ajouter un lien de téléchargement

  • créer des KPI

Aller plus loin : AngularJS et utilisation avancée des widgets
  • découvrir les directives AngularJS

  • jouer avec en créant une vue dynamique - ng-if

  • intégrer un code couleur à la directive ng-class de vos KPI

  • widgets d’affinage par clic

Concepts de base

Choisir un jeu de données

Ce tutoriel se base sur le jeu de données contenant les entreprises immatriculées en France (au cours de l’année 2016).

Vous devez tout d’abord ajouter le jeu de données suivant sur votre domaine :

  • entreprises-immatriculees-en-2016

Vous pouvez simplement utiliser le bouton Ajouter un jeu de données depuis le réseau OpenDataSoft lorsque vous ajoutez une nouvelle source de données dans votre jeu de données.

créer une page

Accédez à Back office -> Pages -> Nouvelle page
Saisissez un suffixe d’URL de page, et si vous le souhaitez un titre et une description, puis cliquez sur Enregistrer.
Cliquez sur Éditer en mode expert pour accéder directement au code CSS/HTML de la page.

Le code HTML suivant doit désormais s’afficher sur votre page :

<div class="container-fluid">
    <div class="ods-box" ></div>
</div>

Désormais, tout le code sera ajouté entre des tags div avec la classe ods-box, comme illustré dans l’exemple ci-dessous :

<div class="container-fluid">
    <div class="ods-box">

        CODE HERE

    </div>
</div>

Enregistrez et ouvrez votre page.

Si vous ne voyez pas le bouton Ouvrir la page dans le coin supérieur droit de l’écran, actualisez la page.

Vous pouvez également revenir au menu Pages depuis la barre de navigation, afin d’afficher la liste des pages. Cliquez ensuite sur l’icône en forme d’œil pour accéder directement à cette liste.

Ajouter une vue carte

Pour commencer, la méthode la plus simple consiste à utiliser les liens de partage et le code affichés sous chaque visualisation de données.

Accédez à votre jeu de données, cliquez sur l’onglet carte, puis, sous la carte, cliquez sur widget et copiez/collez simplement le code dans la page personnalisée.

<div class="container-fluid">
    <div class="ods-box">

        <ods-dataset-context
                             context="entreprisesimmatriculeesen2016"
                             entreprisesimmatriculeesen2016-dataset="entreprises-immatriculees-en-2016"
                             entreprisesimmatriculeesen2016-parameters="{'disjunctive.libelle':true,'disjunctive.code_postal':true,'disjunctive.ville':true,'disjunctive.region':true,'disjunctive.greffe':true,'sort':'date_d_immatriculation'}">
            <ods-map context="entreprisesimmatriculeesen2016" location="3,18.59479,25.24143" basemap="mapbox.light">
            </ods-map>
        </ods-dataset-context>

    </div>
</div>

Chaque bloc sera expliqué plus tard. Pour l’instant, contentez-vous de prévisualiser votre page en cliquant sur le bouton Aperçu situé au centre de votre navigateur.

Nous vous conseillons d’ouvrir votre page dans un nouvel onglet du navigateur pour accélérer son chargement (actualisez cet onglet à chaque fois que vous souhaitez voir les modifications apportées à la page).

Votre carte devrait ressembler à ceci (le fond de carte peut varier en fonction des paramètres de votre domaine) :

../../../_images/dashboard__add-a-map-view.png

Ajouter une vue tableau

À présent, toujours sur l’écran d’exploration du jeu de données, accédez à la vue tableau (onglet Tableau), cliquez sur le lien de partage widget et copiez/collez simplement le code sous la carte.

<div class="container-fluid">
    <div class="ods-box">

        <ods-dataset-context
                             context="entreprisesimmatriculeesen2016"
                             entreprisesimmatriculeesen2016-dataset="entreprises-immatriculees-en-2016"
                             entreprisesimmatriculeesen2016-parameters="{'disjunctive.libelle':true,'disjunctive.code_postal':true,'disjunctive.ville':true,'disjunctive.region':true,'disjunctive.greffe':true,'sort':'date_d_immatriculation'}">
            <ods-map context="entreprisesimmatriculeesen2016" location="3,18.59479,25.24143" basemap="mapbox.light">
            </ods-map>
        </ods-dataset-context>

        <ods-dataset-context
                             context="entreprisesimmatriculeesen2016"
                             entreprisesimmatriculeesen2016-dataset="entreprises-immatriculees-en-2016"
                             entreprisesimmatriculeesen2016-parameters="{'disjunctive.libelle':true,'disjunctive.code_postal':true,'disjunctive.ville':true,'disjunctive.region':true,'disjunctive.greffe':true,'sort':'date_d_immatriculation'}">
            <ods-table context="entreprisesimmatriculeesen2016"
                       sort="date_d_immatriculation">
            </ods-table>
        </ods-dataset-context>

    </div>
</div>

Enregistrez, actualisez la page et découvrez que le tableau de bord comporte désormais deux visualisations de données :

../../../_images/dashboard__add-a-table-view.png

Ajouter un graphe

De retour dans le jeu de données, accédez à la vue graphe, sélectionnez un axe X et un axe Y, obtenez le code du widget et copiez/collez-le.

Afin d’illustrer cette documentation avec un graphe intéressant, nous allons afficher le nombre d’entreprises par région.

Axe X : Région Axe Y : Compte

../../../_images/dashboard__add-a-chart-setup.png

Enregistrez, actualisez la page, le code devrait ressembler à ceci :

<div class="container-fluid">
    <div class="ods-box">

        <ods-dataset-context
                             context="entreprisesimmatriculeesen2016"
                             entreprisesimmatriculeesen2016-dataset="entreprises-immatriculees-en-2016"
                             entreprisesimmatriculeesen2016-parameters="{'disjunctive.libelle':true,'disjunctive.code_postal':true,'disjunctive.ville':true,'disjunctive.region':true,'disjunctive.greffe':true,'sort':'date_d_immatriculation'}">
            <ods-map context="entreprisesimmatriculeesen2016" location="2,18.59479,25.24143" basemap="mapbox.light">
            </ods-map>
        </ods-dataset-context>

        <ods-dataset-context
                             context="entreprisesimmatriculeesen2016"
                             entreprisesimmatriculeesen2016-dataset="entreprises-immatriculees-en-2016"
                             entreprisesimmatriculeesen2016-parameters="{'disjunctive.libelle':true,'disjunctive.code_postal':true,'disjunctive.ville':true,'disjunctive.region':true,'disjunctive.greffe':true,'sort':'date_d_immatriculation'}">
            <ods-table context="entreprisesimmatriculeesen2016"
                       sort="date_d_immatriculation">
            </ods-table>
        </ods-dataset-context>

        <ods-dataset-context
                             context="entreprisesimmatriculeesen2016"
                             entreprisesimmatriculeesen2016-dataset="entreprises-immatriculees-en-2016"
                             entreprisesimmatriculeesen2016-parameters="{'disjunctive.libelle':true,'disjunctive.code_postal':true,'disjunctive.ville':true,'disjunctive.region':true,'disjunctive.greffe':true,'sort':'date_d_immatriculation'}">
            <ods-chart>
                <ods-chart-query context="entreprisesimmatriculeesen2016" field-x="region">
                    <ods-chart-serie expression-y="siren" chart-type="line" function-y="COUNT" color="#66c2a5" scientific-display="true">
                    </ods-chart-serie>
                </ods-chart-query>
            </ods-chart>
        </ods-dataset-context>

    </div>
</div>
../../../_images/dashboard__add-a-chart.png

Ajouter un formulaire de recherche textuelle

Maintenant que nous travaillons sur un seul contexte, et que tous nos widgets sont liés les uns aux autres, nous pouvons ajouter de nouveaux widgets plus complexes. Commençons par une barre de recherche !

Ouvrez la documentation complète sur les widgets dans un nouvel onglet pour consulter la liste des widgets disponibles.

Le widget de la barre de recherche est appelé odsTextSearch. Il présente plusieurs paramètres, dont un seul doit obligatoirement être renseigné : le contexte !

Ne compliquons pas les choses pour le moment, et utilisons le code ci-dessous :

<ods-text-search context="mycontext"></ods-text-search>

mycontext est le nom de votre contexte sur votre page personnalisée.

Ajoutons maintenant une barre de recherche en haut du tableau de bord :

<div class="container-fluid">
    <div class="ods-box">

        <ods-dataset-context
                             context="entreprisesimmatriculeesen2016"
                             entreprisesimmatriculeesen2016-dataset="entreprises-immatriculees-en-2016"
                             entreprisesimmatriculeesen2016-parameters="{'disjunctive.libelle':true,'disjunctive.code_postal':true,'disjunctive.ville':true,'disjunctive.region':true,'disjunctive.greffe':true,'sort':'date_d_immatriculation'}">

            <ods-text-search context="entreprisesimmatriculeesen2016"></ods-text-search>

            <ods-map context="entreprisesimmatriculeesen2016" location="2,18.59479,25.24143" basemap="mapbox.light">
            </ods-map>

            <ods-table context="entreprisesimmatriculeesen2016"
                       sort="date_d_immatriculation">
            </ods-table>

            <ods-chart>
                <ods-chart-query context="entreprisesimmatriculeesen2016" field-x="region">
                    <ods-chart-serie expression-y="siren" chart-type="line" function-y="COUNT" color="#66c2a5" scientific-display="true">
                    </ods-chart-serie>
                </ods-chart-query>
            </ods-chart>

        </ods-dataset-context>

    </div>
</div>

Enregistrez, actualisez la page et vous pouvez effectuer des recherches !

Par exemple, recherchez ‘club de sport’ dans le sud de la France :

../../../_images/dashboard__add-search-bar.png

Ajouter des filtres

Tout comme dans la vue d’exploration, il est très intéressant de disposer de filtres pour les jeux de données, afin d’affiner vos recherches. Le widget des filtres ods est appelé ods-facets

La méthode la plus simple consiste à afficher toutes les facettes :

<ods-facets context="mycontext"></ods-facets>

Il peut être plus intelligent de sélectionner uniquement les facettes requises en spécifiant l’id du champ (et pas son nom !) :

<ods-facets context="mycontext">
    <h3>First field</h3>
    <ods-facet name="myfield"></ods-facet>

    <h3>Second field</h3>
    <ods-facet name="mysecondfield"></ods-facet>
</ods-facets>

Remarque

Pour obtenir l’id d’un champ, vous devez connaître le schéma du jeu de données. Il est disponible dans l’onglet informations du jeu de données. Le schéma du jeu de données indique toutes les informations relatives à chaque champ : nom, description, id, type et un exemple de valeur. Il est généralement recommandé de connaître le type et l’id de chaque champ lorsque vous utilisez des paramètres de widgets avancés.

Dans cet exemple de tableau de bord, nous utiliserons 2 filtres : le secteur d’activité de l’entreprise et la ville. Ajoutez ce code à côté de la barre de recherche :

Il est désormais bien plus facile de rechercher un club de sport à Paris !

../../../_images/dashboard__add-filters.png

Découvrir les classes CSS pour un développement responsive en toute facilité

Notre tableau de bord commence à prendre forme, mais tous les widgets sont actuellement dans la même colonne, les uns à la suite des autres sans aucune modification esthétique.

Remarque

À ce stade du tutoriel, vous devez avoir connaissance des capacités de mise en forme CSS et HTML dont dispose la plateforme. Veuillez lire attentivement la documentation sur la gestion des dispositions en grille responsive.

Nous allons séparer l’écran en deux zones principales : sur la gauche, une barre de navigation, et sur la droite, le contenu principal. La barre de navigation sera composée de la barre de recherche et des filtres, la zone du contenu principal sera quant à elle composée du tableau, de la carte et du graphe.

La page ressemblera à ceci :

../../../_images/dashboard__css-responsive-layout-1.png

Bootstrap (l’outil de gestion de la disposition en grille) divise la page en 12 colonnes. Nous allons allouer 3 colonnes à la barre de navigation et 9 au contenu. Nous allons diviser l’écran en fonction des dispositifs, en commençant par ceux de taille moyenne. Les classes CSS sont col-md-3 et col-md-9

En ce qui concerne le widget de tableau et de graphe, nous allons diviser la zone en deux parties égales, c’est-à-dire en 6 colonnes chacune. La classe CSS est col-md-6

Une dernière précision : pour pouvoir utiliser les classes CSS col-xx-yy, ces dernières doivent toujours se trouver à l’intérieur d’un élément row ! Vous devez donc commencer par définir des lignes, puis les diviser !

../../../_images/dashboard__css-responsive-layout-2.png

Le bloc HTML doit alors ressembler à ceci :

<div class="container-fluid">

    <div class="ods-box">

        <ods-dataset-context
                             context="entreprisesimmatriculeesen2016"
                             entreprisesimmatriculeesen2016-dataset="entreprises-immatriculees-en-2016"
                             entreprisesimmatriculeesen2016-parameters="{'disjunctive.libelle':true,'disjunctive.code_postal':true,'disjunctive.ville':true,'disjunctive.region':true,'disjunctive.greffe':true,'sort':'date_d_immatriculation'}">

            <div class="row">

                <!-- NAVIGATION BAR -->
                <div class="col-md-3">
                        <ods-text-search />
                        <ods-facets />
                </div>

                <!-- MAIN CONTENT -->
                <div class="col-md-9">

                    <!-- ROW 1 : The Map -->
                    <div class="row">
                    <ods-map />
                    </div>

                    <!-- ROW 2 : Chart and table -->
                    <div class="row">
                        <div class="col-md-6">
                        <ods-table />
                        </div>

                        <div class="col-md-6">
                        <ods-chart />
                        </div>
                    </div>

                </div>
            </div>
        </ods-dataset-context>
    </div>
</div>

Nous avons désormais un véritable tableau de bord, il ne reste plus qu’à espacer les éléments, car ils sont encore très proches les uns des autres. Cet aspect est directement traité dans la CSS, l’utilisation des règles margin et padding permet de réaliser facilement l’espacement.

Cependant, la plateforme dispose également d’une classe CSS appelée ods-box. Elle permet d’encapsuler n’importe quel élément dans un cadre à bord fin et arrondi. Nous allons l’utiliser pour encapsuler la barre de navigation, la carte, le tableau et le graphe.

Le code HTML complet est désormais le suivant :

<div class="container-fluid">
    <div class="ods-box">
        <ods-dataset-context
                             context="entreprisesimmatriculeesen2016"
                             entreprisesimmatriculeesen2016-dataset="entreprises-immatriculees-en-2016"
                             entreprisesimmatriculeesen2016-parameters="{'disjunctive.libelle':true,'disjunctive.code_postal':true,'disjunctive.ville':true,'disjunctive.region':true,'disjunctive.greffe':true,'sort':'date_d_immatriculation'}">
            <div class="row">

                <!-- NAVIGATION BAR -->
                <div class="col-md-3">
                    <div class="ods-box">
                        <ods-text-search context="entreprisesimmatriculeesen2016"></ods-text-search>
                        <ods-facets context="entreprisesimmatriculeesen2016">
                            <h3>Activity</h3>
                            <ods-facet name="libelle"></ods-facet>
                            <h3>City</h3>
                            <ods-facet name="ville"></ods-facet>
                        </ods-facets>
                    </div>
                </div>

                <!-- MAIN CONTENT -->
                <div class="col-md-9">

                    <!-- ROW 1 : The Map -->
                    <div class="row">
                        <div class="ods-box">
                            <ods-map context="entreprisesimmatriculeesen2016" location="2,18.59479,25.24143" basemap="mapbox.light">
                            </ods-map>
                        </div>
                    </div>

                    <!-- ROW 2 : Chart and table -->
                    <div class="row">
                        <div class="col-md-6">
                            <div class="ods-box">
                                <ods-table context="entreprisesimmatriculeesen2016"
                                           sort="date_d_immatriculation">
                                </ods-table>
                            </div>
                        </div>
                        <div class="col-md-6">
                            <div class="ods-box">
                                <ods-chart>
                                    <ods-chart-query context="entreprisesimmatriculeesen2016" field-x="region">
                                        <ods-chart-serie expression-y="siren" chart-type="line" function-y="COUNT" color="#66c2a5" scientific-display="true">
                                        </ods-chart-serie>
                                    </ods-chart-query>
                                </ods-chart>
                            </div>
                        </div>
                    </div>

                </div>
            </div>
        </ods-dataset-context>
    </div>
</div>
../../../_images/dashboard__css-responsive-layout-3.png

Étudier le “contexte” plus en profondeur

Nous savons désormais que le contexte est ce qui permet de connecter les widgets les uns aux autres et de les lier aux données. Certains widgets consomment/lisent des données : le widget odsTable les utilise pour obtenir et afficher les enregistrements. Certains widgets utilisent/modifient les données : le widget odsTextSearch les interroge en envoyant des requêtes ou en appliquant des filtres. Certains widgets font tout cela à la fois : le widget odsFacets obtient des filtres, les affiche et permet d’appliquer un filtre sur le contexte.

Pour aller plus loin, découvrons maintenant comment les widgets modifient le contexte et quels types d’informations ils peuvent en retirer.

Remarque

  • Étant donné que la bibliothèque des widgets OpenDataSoft repose sur AngularJS, nous allons utiliser sa syntaxe pour lire le contexte.
    • Le contexte est une variable AngularJS.

    • Le contexte peut être envisagé comme un simple objet JSON, avec des accolades, des listes de valeurs de clés, etc.

    • Pour évaluer une expression AngularJS, la syntaxe suivante est utilisée : {{ action1 or variable1 }}

En conclusion, pour lire le contexte, ajoutez simplement le bout de code suivant dans un espace vide :

<div class="container-fluid">
    <div class="ods-box">
        <ods-dataset-context
                             context="entreprisesimmatriculeesen2016"
                             entreprisesimmatriculeesen2016-dataset="entreprises-immatriculees-en-2016"
                             entreprisesimmatriculeesen2016-parameters="{'disjunctive.libelle':true,'disjunctive.code_postal':true,'disjunctive.ville':true,'disjunctive.region':true,'disjunctive.greffe':true,'sort':'date_d_immatriculation'}">

            {{ entreprisesimmatriculeesen2016 }}

            <div class="row">

                <!-- NAVIGATION BAR -->
                        . . . .

Enregistrez et actualisez la page : vous devriez voir un objet JSON en impression brute en haut de votre page, en le transformant en impression élégante dans votre environnement de développement favori (ou avec un outil de formatage JSON en ligne, tel que CuriousConcept ), votre code devrait ressembler à ceci :

{
   "name":"entreprisesimmatriculeesen2016",
   "type":"dataset",
   "domainUrl":"",
   "dataset":{
      "datasetid":"entreprises-immatriculees-en-2016",
      "has_records":true,
      "metas":{
         "publisher":"Infogreffe",
         "domain":"fpassaniti",
         "license":"Licence ouverte / Open Licence",
         "description":"<p><strong>RCS - Liste des entreprises immatriculées en 2016</strong></p><hr/>\n<p>Liste des sociétés commerciales immatriculées au registre du commerce et des sociétés en 2016.</p>",
         "language":"fr",
         "records_count":114129,
         "title":"Entreprises immatriculées en 2016",
         "attributions":"Infogreffe",
         "modified":"2016-09-14T15:16:33+02:00",
         "theme":"Immatriculations",
         "references":"Création, Immatriculation, Registre du commerce et des sociétés",
         "visibility":"restricted",
         "data_processed":"2016-09-14T10:30:30+02:00",
         "metadata_processed":"2016-09-14T15:16:47+02:00",
         "keyword":[
            "création",
            "immatriculation",
            "sociétés",
            "entreprises"
         ]
      },
      "features":[
         "geo",
         "analyze",
         "timeserie"
      ],
      . . .
      "fields":         . . .,
      "extra_metas":{
         "visualization":{
            "map_tooltip_fields": . . .
            "calendar_enabled":false,
            "map_tooltip_html_enabled":false,
            "image_tooltip_html_enabled":false,
            "map_tooltip_title":"denomination",
            "table_default_sort_field":"date_d_immatriculation",
            "table_fields": . . .
            "map_marker_hidemarkershape":false,
            "analyze_default":". . .",
            "calendar_tooltip_html_enabled":false
         },
         "explore":{
            "download_count":0,
            "feedback_enabled":false
         },
         "processing":{
            "processing_modified":"2016-06-14T12:25:59+02:00",
            "records_size":0,
            "security_last_modified":"2016-09-14T15:16:44+02:00"
         },
         "publishing":{
            "status":"processing_all_dataset_data",
            "extractors":[
               "csvfile"
            ],
            "properties":[
               "scheduled"
            ],
            "last_modified_user":"olivier.ishacian",
            "published":true
         }
      },
      "billing_plans":[

      ]
   },
   "parameters":{
      "disjunctive.libelle":true,
      "disjunctive.code_postal":true,
      "disjunctive.ville":true,
      "disjunctive.region":true,
      "disjunctive.greffe":true,
      "sort":"date_d_immatriculation"
   },
   "nhits":114559
}

Étant donné qu’il s’agit d’un objet JSON, nous pouvons utiliser une expression AngularJS pour naviguer dans sa structure, afin d’obtenir la valeur de n’importe quelle clé. Par exemple, pour obtenir le titre du jeu de données, accédez au contexte, puis à la liste dataset, puis à la liste metas, pour enfin atteindre la valeur du titre. Encapsulée dans un gros en-tête (tag HTML h1), l’expression devrait ressembler à ceci :

<div class="container-fluid">
    <div class="ods-box">
        <ods-dataset-context
                             context="entreprisesimmatriculeesen2016"
                             entreprisesimmatriculeesen2016-dataset="entreprises-immatriculees-en-2016"
                             entreprisesimmatriculeesen2016-parameters="{'disjunctive.libelle':true,'disjunctive.code_postal':true,'disjunctive.ville':true,'disjunctive.region':true,'disjunctive.greffe':true,'sort':'date_d_immatriculation'}">

            <h1>
                {{ entreprisesimmatriculeesen2016.dataset.metas.title }}
            </h1>

            <div class="row">

                <!-- NAVIGATION BAR -->
../../../_images/dashboard__context-1.png

Maintenant que nous avons vu ce qu’est le contexte, nous devons nous intéresser à sa création. odsDatasetContext est utilisé pour créer un contexte, en se basant sur un id de jeu de données, et éventuellement sur d’autres paramètres.

<ods-dataset-context
    context="entreprisesimmatriculeesen2016"
    entreprisesimmatriculeesen2016-dataset="entreprises-immatriculees-en-2016"
    entreprisesimmatriculeesen2016-parameters="{'disjunctive.libelle':true,'disjunctive.code_postal':true,'disjunctive.ville':true,'disjunctive.region':true,'disjunctive.greffe':true,'sort':'date_d_immatriculation'}">
</ods-dataset-context>

Comme indiqué dans la documentation, 2 paramètres sont obligatoires : le nom du contexte et l’id du jeu de données. 1 paramètre supplémentaire a été copié. mycontext-parameters est utilisé pour définir des filtres spécifiques ou effectuer des requêtes sur le contexte. Ici, le mode disjonctif est défini sur true pour 5 champs, et le dernier paramètre est un tri en fonction de la valeur du champ date_d_immatriculation.

Remarque

Lorsque le mode disjonctif est défini sur true pour le champ d’une facette, cela active le mode de filtrage à choix multiples. L’utilisateur peut ainsi appliquer un filtre tout en pouvant voir et/ou sélectionner d’autres valeurs.

Nous allons à présent supprimer cet attribut facultatif et voir ce que cela change.

<ods-dataset-context
     context="entreprisesimmatriculeesen2016"
     entreprisesimmatriculeesen2016-dataset="entreprises-immatriculees-en-2016">
</ods-dataset-context>

Tout d’abord, le contexte, si nous l’affichons, le bloc des paramètres JSON est désormais bien plus petit :

Ajoutez ce qui suit dans votre code :

{{ entreprisesimmatriculeesen2016.parameters }}

Enregistrez, actualisez la page et observez le résultat :

    "parameters":{
            "sort":"date_d_immatriculation"
}

Nous avons toujours un paramètre de tri, même si nous l’avons effacé dans le widget de création de contexte (odsDatasetContext), en raison du paramètre de tri du jeu de données dans la vue tableau.

Dernier test : appliquez un filtre sur n’importe quelle facette et observez comment l’objet context.parameters est mis à jour.

../../../_images/dashboard__context-2.png

Remarque

Observez également le comportement ‘normal’ des facettes : lorsqu’une valeur est sélectionnée, toutes les autres sont masquées.

Ajouter un compteur d’enregistrements et la date de dernier traitement

Il est temps d’obtenir des informations plus intéressantes à partir de ce contexte :

  • le nombre total d’enregistrements

  • le nombre total d’enregistrements correspondant à la requête et/ou aux filtres de l’utilisateur

  • la date de dernier traitement du jeu de données

{
   "name":"entreprisesimmatriculeesen2016",
   . . .
   "dataset":{
      "datasetid":"entreprises-immatriculees-en-2016",
      "has_records":true,
      "metas":{
         . . .
         "records_count":114129,
         . . .
         "data_processed":"2016-09-14T10:30:30+02:00",
         . . .
      },
      . . .
   },
   "nhits":115055
}

Puis :

  • le nombre total d’enregistrements sera accessible à l’aide de l’expression : {{ entreprisesimmatriculeesen2016.dataset.metas.records_count }}

  • le nombre total de correspondances : {{ entreprisesimmatriculeesen2016.nhits }}

  • la date de dernier traitement : {{ entreprisesimmatriculeesen2016.dataset.metas.data_processed }}

Pour terminer, nous allons inclure les blocs suivants dans notre code HTML, entourés de code HTML et CSS permettant d’obtenir une mise en forme soignée.

Enregistrements et nhits en haut de la barre de navigation, date de traitement en bas :

<!-- NAVIGATION BAR -->
<div class="col-md-3">
    <div class="ods-box">

        <h3>
            {{  entreprisesimmatriculeesen2016.nhits }} records
        </h3>
        <h5>
            <i>
                out of a total of {{  entreprisesimmatriculeesen2016.dataset.metas.records_count }} records in the dataset
            </i>
        </h5>

        <ods-text-search context="entreprisesimmatriculeesen2016"></ods-text-search>
        <ods-facets context="entreprisesimmatriculeesen2016">
            <h3>Activity</h3>
            <ods-facet name="libelle"></ods-facet>
            <h3>City</h3>
            <ods-facet name="ville"></ods-facet>
        </ods-facets>

        <h5>
            <i>
                Last modified date : {{  entreprisesimmatriculeesen2016.dataset.metas.data_processed }}
            </i>
        </h5>

    </div>
</div>

Enregistrez, actualisez la page et observez le résultat :

../../../_images/dashboard__add-counters.png

C’est bien, mais le format des chiffres et de la date est un peu indigeste. Pour améliorer cela, nous allons introduire un concept AngularJS pur, à savoir les filtres. Cliquez ici pour consulter la documentation complète sur les filtres AngularJS

Un filtre est une fonction ou une opération pouvant être appliquée sur une variable ou sur une valeur dans une expression AngularJS.

Dans notre cas, nous allons utiliser le filtre number pour obtenir une impression élégante des valeurs numériques (ajouter une espace ou une virgule tous les 3 chiffres en fonction du pays), et le filtre date pour transformer le format technique ISO en un format lisible facilement.

<h3>
    {{  entreprisesimmatriculeesen2016.nhits | number }} records
</h3>
<h5>
    <i>
        out of a total of {{  entreprisesimmatriculeesen2016.dataset.metas.records_count | number }} records in the dataset
    </i>
</h5>

. . .

<h5>
    <i>
        Last modified date : {{  entreprisesimmatriculeesen2016.dataset.metas.data_processed | date : 'medium' }}
    </i>
</h5>

Remarque

Pour “appeler” un filtre, utilisez une barre verticale ‘|’ à la fin de l’expression. Certains filtres acceptent des paramètres spécifiques, le filtre de date accepte un format ou un modèle de date. Exemple : expr. | date : 'M/d/yy' expr. | date : 'medium'

Enregistrez, actualisez la page et observez le résultat :

../../../_images/dashboard__add-counters-ng-filter.png

Aller plus loin : AngularJS

Découvrir les directives AngularJS

Une directive AngularJS peut être considérée comme un attribut HTML pouvant être ajouté à n’importe quel élément HTML. De nombreuses directives sont disponibles sur la plateforme et peuvent être utilisées pour rendre les tableaux de bord dynamiques.

Voici une liste comprenant quelques-unes des directives les plus couramment utilisées :

  • ng-init : initialiser une variable

  • ng-click : évaluer une expression lorsqu’un utilisateur clique sur un élément

  • ng-class : appliquer une classe CSS en fonction d’une variable ou d’une condition

  • ng-if : afficher ou masquer un élément en fonction d’une condition

  • ng-repeat : effectuer une itération sur une liste ou un tableau, répéter l’élément HTML pour chaque itération

  • ng-change : évaluer une expression lorsque l’utilisateur modifie la valeur d’un élément HTML Select

ng-if : afficher ou masquer un widget en fonction des filtres sélectionnés par l’utilisateur

Dans notre tableau de bord, nous avons le graphe linéaire des régions, mais également un filtre par ville ! Lorsque l’utilisateur sélectionne une ville pour filtrer les résultats, le graphe devient inutile car il n’affiche qu’une seule valeur.

Il pourrait donc être intéressant de masquer le widget de région lorsqu’une activité est sélectionnée, et d’afficher un autre graphe à la place.

Retournez à la vue d’exploration du jeu de données, accédez à l’onglet analyse et configurez un nouveau graphe, par exemple :

Un camembert indiquant le nombre d’entreprises immatriculées chaque mois de l’année, avec un tri.
  • Axe X : date d’immatriculation, tri par mois

  • Y : camembert, Axe Y : compte

  • Copiez et collez le code du widget sous le graphe.

  • Supprimez la déclaration de contexte collée

  • Changez le nom du contexte utilisé dans ce nouveau graphe (si nécessaire).

Nous pouvons maintenant utiliser la directive ng-if sur chaque widget afin d’afficher l’un ou l’autre widget.

La condition sera, si le contexte est affiné, afficher ou masquer. Nous avons vu que la liste des affinages est disponible dans context.parameters. Étant donné que les paramètres sont un dictionnaire de valeurs de clés, pour obtenir le paramètre d’affinage myfield, nous tentons d’accéder à : mycontext.parameters['refine.myfield']

Appliqué à notre jeu de données, le code ressemble à ceci :

<div class="col-md-6">
    <div class="ods-box">
        <ods-chart ng-if="! entreprisesimmatriculeesen2016.parameters['refine.ville']">
            <ods-chart-query context="entreprisesimmatriculeesen2016" field-x="region">
                <ods-chart-serie expression-y="siren" chart-type="line" function-y="COUNT" color="#66c2a5" scientific-display="true">
                </ods-chart-serie>
            </ods-chart-query>
        </ods-chart>

        <ods-chart ng-if="entreprisesimmatriculeesen2016.parameters['refine.ville']">
            <ods-chart-query context="entreprisesimmatriculeesen2016" field-x="date_d_immatriculation" maxpoints="20" timescale="month" sort="serie1-1">
                <ods-chart-serie expression-y="siren" chart-type="pie" function-y="COUNT" color="range-custom" scientific-display="true">
                </ods-chart-serie>
            </ods-chart-query>
        </ods-chart>
    </div>
</div>

Remarque

  • La condition ng-if du graphe des régions peut être traduite par Afficher le graphique si un paramètre d’affinage est appliqué sur la facette **ville**.
    • Le caractère ! permet d’obtenir le résultat opposé, la condition peut alors être traduite par Afficher le graphe si AUCUN paramètre d’affinage n’est appliqué sur la facette **ville**.

    • Afin de comprendre comment cela fonctionne, n’hésitez pas à afficher la valeur context.parameters dans votre tableau de bord à chaque fois que vous l’utilisez !

ng-init / ng-click / ng-if /ng-class : créer des onglets pour passer d’une vue à une autre

Cet exemple utilise 4 directives différentes.

  • ng-init pour déclarer une variable, afin de savoir quel onglet afficher

  • ng-if pour afficher uniquement un onglet à la fois, en fonction de la valeur de la variable

  • ng-click pour modifier la valeur de la variable, afin de passer d’un onglet à un autre

  • ng-class pour changer la couleur de l’onglet, afin d’indiquer quel onglet est actuellement sélectionné

Commençons par la structure HTML :

    <div class="row">
    <ul>
        <li>
            FIRST TAB BUTTON
        </li>
        <li>
            SECOND TAB BUTTON
        </li>
        <li>
            THIRD TAB BUTTON
        </li>
    </ul>
</div>

<div class="row">
    <div>
        FIRST CONTENT
    </div>
    <div>
        SECOND CONTENT
    </div>
    <div>
        THIRD CONTENT
    </div>
</div>

Initialisez une variable appelée tab avec ng-init :

<ul ng-init="tab='first'">

Sur les boutons de chaque onglet, ajoutez une directive ng-click pour définir la valeur tab :

    <li ng-click="tab='first'">
    FIRST TAB BUTTON
</li>
<li ng-click="tab='second'">
    SECOND TAB BUTTON
</li>
<li ng-click="tab='third'">
    THIRD TAB BUTTON
</li>

Ensuite, sur chaque bloc de contenu, ajoutez une condition ng-if pour l’afficher :

<div class="row">
    <div ng-if="tab=='first'">
        FIRST CONTENT
    </div>
    <div ng-if="tab=='second'">
        SECOND CONTENT
    </div>
    <div ng-if="tab=='third'">
        THIRD CONTENT
    </div>
</div>

Enregistrez, actualisez la page et effectuez des tests. Vous devriez constater qu’en cliquant sur le bouton de l’onglet, le contenu est modifié !

Nous devons maintenant utiliser un bout de code CSS pour donner au bouton un beau style, nous l’avons déjà utilisé : ods-button ods-button--primary. Ajoutons également les classes items` et item.

Le code ressemble à ceci :

<ul class="items" ng-init="tab='first'">
    <li class="item ods-button ods-button--primary" ng-click="tab='first'">
        FIRST TAB BUTTON
    </li>
    <li class="item ods-button ods-button--primary" ng-click="tab='second'">
        SECOND TAB BUTTON
    </li>
    <li class="item ods-button ods-button--primary" ng-click="tab='third'">
        THIRD TAB BUTTON
    </li>
</ul>

Et ajoutez cela au bloc CSS :

.items {
    display: flex; /* Display in line */
    list-style-type: none; /* Remove the list bullet */
}

.item {
    margin: 0 20px; /* give some space left and right */
}

Enfin, toujours avec le code CSS, nous voulons mettre en valeur l’onglet sélectionné en l’affichant avec une couleur différente. Nous allons également utiliser un bouton prédéfini : ods-button--danger (en rouge). Cette classe CSS doit uniquement être définie pour une condition spécifique avec ng-class. La syntaxe est la suivante : ng-class=”{‘css-class’: variable == value}”`

Le code HTML final ressemble à ceci :

<div class="row">
    <ul class="items" ng-init="tab='first'">
        <li class="item ods-button ods-button--primary" ng-class="{'ods-button--danger': tab == 'first'}" ng-click="tab='first'">
            FIRST TAB BUTTON
        </li>
        <li class="item ods-button ods-button--primary" ng-class="{'ods-button--danger': tab == 'second'}" ng-click="tab='second'">
            SECOND TAB BUTTON
        </li>
        <li class="item ods-button ods-button--primary" ng-class="{'ods-button--danger': tab == 'third'}" ng-click="tab='third'">
            THIRD TAB BUTTON
        </li>
    </ul>
</div>

<div class="row">
    <div ng-if="tab=='first'" class="block">
        FIRST CONTENT
    </div>
    <div ng-if="tab=='second'" class="block">
        SECOND CONTENT
    </div>
    <div ng-if="tab=='third'" class="block">
        THIRD CONTENT
    </div>
</div>

Enregistrez, actualisez la page et passez d’un onglet à un autre !

../../../_images/dashboard__tab-view.png

Nous pouvons ensuite l’inclure à notre tableau de bord pour ajouter des visualisations de données supplémentaires sans alourdir excessivement le tableau de bord (trop long à charger ou difficile à lire). Pour agrandir un peu le tableau et le graphe, nous pouvons les inclure dans un onglet, nous allons également ajouter un troisième graphe, basé sur un autre axe (la date, par exemple). La seconde ligne deviendra la ligne du tableau, et chaque widget (tableau, graphique) deviendra le contenu de chaque onglet.

Le contenu principal ressemble à ceci :

<!-- MAIN CONTENT -->
<div class="col-md-9">

    <!-- ROW 1 : The Map -->
    <div class="row">
        <div class="ods-box">
            <ods-map context="entreprisesimmatriculeesen2016" location="2,18.59479,25.24143" basemap="mapbox.light">
            </ods-map>
        </div>
    </div>

    <!-- ROW 2 : Chart and table -->
    <div class="row items-row">
        <ul class="items" ng-init="tab='first'">
            <li class="item ods-button ods-button--primary" ng-class="{'ods-button--danger': tab == 'first'}" ng-click="tab='first'">
                Table
            </li>
            <li class="item ods-button ods-button--primary" ng-class="{'ods-button--danger': tab == 'second'}" ng-click="tab='second'">
                Region chart
            </li>
            <li class="item ods-button ods-button--primary" ng-class="{'ods-button--danger': tab == 'third'}" ng-click="tab='third'">
                Time serie
            </li>
        </ul>
    </div>

    <div class="row">
        <div ng-if="tab=='first'" class="block">
            <div class="ods-box">
                <ods-table context="entreprisesimmatriculeesen2016">
                </ods-table>
            </div>
        </div>
        <div ng-if="tab=='second'" class="block">
            <div class="ods-box" ng-if="! entreprisesimmatriculeesen2016.parameters['refine.ville']">
                <ods-chart>
                    <ods-chart-query context="entreprisesimmatriculeesen2016" field-x="region">
                        <ods-chart-serie expression-y="siren" chart-type="line" function-y="COUNT" color="#66c2a5" scientific-display="true">
                        </ods-chart-serie>
                    </ods-chart-query>
                </ods-chart>
            </div>
            <div class="ods-box" ng-if="entreprisesimmatriculeesen2016.parameters['refine.ville']">
                <ods-chart>
                    <ods-chart-query context="entreprisesimmatriculeesen2016" field-x="date_d_immatriculation" maxpoints="20" timescale="month" sort="serie1-1">
                        <ods-chart-serie expression-y="siren" chart-type="pie" function-y="COUNT" color="range-custom" scientific-display="true">
                        </ods-chart-serie>
                    </ods-chart-query>
                </ods-chart>
            </div>
        </div>
        <div ng-if="tab=='third'" class="block">
            <ods-chart timescale="year">
                <ods-chart-query context="entreprisesimmatriculeesen2016" field-x="date_d_immatriculation" timescale="day">
                    <ods-chart-serie expression-y="siren" chart-type="spline" function-y="COUNT" color="#ff0000" scientific-display="true">
                    </ods-chart-serie>
                </ods-chart-query>
            </ods-chart>

        </div>
    </div>
</div>

Pour centrer les boutons des onglets, éditez le code CSS comme suit :

.items-row {
    text-align: center; /* center all buttons */
}

.items {
    display: inline-flex; /* Display in line */
    list-style-type: none; /* Remove the list bullet */
}

Pour terminer, enregistrez et actualisez la page :

../../../_images/dashboard__with-tab.png