Crear un panel dinámico paso a paso

Este tutorial tiene como finalidad crear un panel muy fácilmente utilizando widgets, herramientas CSS y AngularJS facilitadas por la plataforma OpenDataSoft.

Conceptos básicos
  • Seleccionar un juego de datos

  • Crear una página

  • Añadir una vista de mapa

  • Añadir una vista de tabla

  • Añadir un gráfico

  • Vincularlo todo

  • Añadir un formulario de búsqueda de texto

  • Añadir filtros

  • Descubrir las clases CSS para desarrollar fácilmente un diseño con capacidad de respuesta

  • Examinar con más detalle el "contexto"

  • Añadir un contador de registros

  • Añadir un vínculo de descarga

  • Crear indicadores KPI

Ir más lejos : AngularJS y uso avanzado de los widgets
  • Descubrir las directivas AngularJS

  • Jugar con ellos creando una vista dinámica - ng-if

  • Colorear el KPI - ng-class

  • Refinar los widgets al hacer clic

Conceptos básicos

Seleccionar un juego de datos

Este tutorial se basa en el juego de datos de registros de compañías de Francia (año 2016).

Primero tiene que añadir este juego de datos en el dominio:

  • entreprises-immatriculees-en-2016

Puede usar simplemente el botón Añadir un juego de datos de la red OpenDataSoft cuando añada un juego de datos nuevo en el juego de datos.

Crear una página

Vaya a Back office -> Páginas -> Página nueva.
Especifique un sufijo de dirección URL de la página (y, de forma opcional, un valor de Título y Descripción) y haga clic en Guardar.
Haga clic en Editar en modo experto para acceder directamente al código CSS/HTML de la página.

Ahora debería ver este código HTML en la página:

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

A partir de ahora, todo el código se añadirá en ods-box div, de este modo:

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

        CODE HERE

    </div>
</div>

Guarde los cambios y abra la página.

Si no ve el botón Abrir página en la parte superior derecha de la pantalla, actualice la página.

También puede volver al menú Páginas de la barra de navegación para ver la lista de páginas y hacer clic en el ojo para acceder a ella directamente.

Añadir una vista de mapa

La manera más fácil de empezar es utilizar vínculos de compartir y el código bajo cada una de las visualizaciones de datos.

Vaya al juego de datos, acceda a la ficha de mapa y, a continuación, bajo el mapa, haga clic en widget y simplemente copie y pegue el código en la página personalizada.

<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>

Cada uno de los bloques se describe más adelante; por ahora, simplemente obtenga una vista previa de la página haciendo clic en el botón Vista previa de la parte central derecha del explorador.

Le recomendamos que abra la página en una ficha nueva del explorador para que la carga sea más rápida (actualice esta ficha siempre que desee observar la versión nueva).

Debería tener este aspecto (el mapa de base del mapa variará según la configuración del dominio):

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

Añadir una vista de tabla

Ahora, siguiendo en la pantalla de exploración del juego de datos, vaya a la vista de tabla (ficha Tabla) y, en el vínculo de compartir de widget, simplemente copie y pegue el código bajo el mapa.

<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>

Guarde los cambios, actualice y observe que el panel ahora tiene 2 data-vizualisation:

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

Añadir un gráfico

Nuevamente en el juego de datos, vaya a la vista de gráfico, seleccione un eje X y un eje Y, obtenga el código del widget, y realice una tarea de copiar y pegar.

Un ejemplo de gráfico interesante para esta documentación consiste en visualizar el número de empresas por región.

Eje X: Région (área administrativa) Eje Y: count (recuento)

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

Guarde los cambios, actualice y observe cómo debería tener este aspecto:

<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

Añadir un formulario de búsqueda de texto

Ahora que tenemos un contexto único para trabajar y todos los widgets están vinculados entre sí, podemos añadir otro widget avanzado. ¡Empecemos con una barra de búsqueda!

Abra una ficha nueva con la documentación de widgets completa para ver la lista de widgets disponibles.

La barra de búsqueda se denomina odsTextSearch. Tiene varios parámetros opcionales y solo uno obligatorio: ¡el contexto!

Para empezar iremos a lo sencillo y utilizaremos esta sintaxis:

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

mycontext es el nombre de mi contexto en mi página personalizada.

Ahora, añada una barra de búsqueda en la parte superior del panel:

<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>

¡Guarde los cambios, actualice y haga una búsqueda!

Por ejemplo, busque 'sport club' en el sur de Francia:

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

Añadir filtros

Como en la vista Explorar, es muy interesante tener filtros de juegos de datos para acotar la búsqueda. El widget de filtros de ODS se denomina ods-facets.

La manera más sencilla es visualizar todas las facetas:

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

Una forma más avanzada consiste en seleccionar únicamente las facetas necesarias especificando el ID de campo (no el nombre):

<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>

Nota

Para obtener el ID de campo, tiene que conocer el esquema del juego de datos. Está disponible en la ficha de información del juego de datos. El esquema del juego de datos muestra toda la información de cada uno de los campos: nombre, descripción, ID, tipo y un ejemplo de valor. Suele ser útil conocer el tipo y el ID de cada uno de los campos al usar parámetros de widgets avanzados.

En este ejemplo de panel, utilizaremos 2 filtros: el sector de actividad de la empresa y la ciudad. Añada este código cerca de la barra de búsqueda:

¡Ahora es mucho más sencillo buscar un club deportivo en París!

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

Descubrir las clases CSS para desarrollar fácilmente un diseño con capacidad de respuesta

Este panel empieza a tener un buen aspecto, pero los widgets están en la misma columna, todos seguidos y sin un estilo personalizado.

Nota

En este punto, debe conocer las posibilidades de estilo de la plataforma en relación con CSS y HTML. Lea atentamente la documentación acerca de la gestión del diseño de cuadrícula con capacidad de respuesta.

Dividiremos la pantalla en 2 áreas principales: a la izquierda, una barra de navegación; a la derecha, el contenido principal. La barra de navegación alojará la barra de búsqueda y los filtros; el contenido incluirá la tabla, el mapa o el gráfico.

Tendrá el aspecto siguiente:

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

Bootsrap (la herramienta de gestión de diseño de cuadrícula) divide la página en 12 columnas. Destinaremos 3 columnas a la barra de navegación y 9 al contenido. Dividiremos la pantalla para los dispositivos a partir de un tamaño medio. Las clases CSS son col-md-3 y col-md-9.

En cuanto al widget de tabla y gráfico, dividiremos el área en 2 del mismo tamaño, es decir, de 6 columnas cada una. La clase CSS es col-md-6.

Un último detalle: para usar las clases CSS col-xx-yy, siempre deben estar dentro de un elemento row. ¡Así que primero defina las filas y después divida las filas!

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

El bloque HTML debería tener el aspecto siguiente:

<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>

Ahora tenemos un panel real, y un último detalle será mejorar la nitidez de los elementos, ya que siguen estando todos juntos. Es un aspecto de CSS puro, y el uso de las reglas margin y padding cumplirá fácilmente este objetivo.

Pero la plataforma también suministra una clase CSS denominada ods-box. Encapsula cualquier elemento en un cuadro con un borde redondeado fino. La usaremos para encapsular la barra de navegación, el mapa, la tabla y el gráfico.

El código HTML completo ahora es:

<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

Examinar con más detalle el "contexto"

Ahora sabemos que el contexto es el pivote clave que existe entre todos los widgets, así como el vínculo entre estos y los datos. Algunos widgets lo consumen o leen: el widget odsTable lo emplea para obtener registros y visualizarlos. Otros widgets lo modifican o actúan en él: odsTextSearch lo consulta aplicando una consulta de búsqueda o un filtro. Hay widgets que hacen ambas tareas: odsFacets obtiene filtros, los visualiza y permite aplicar un filtro en el contexto.

Para continuar adelante, resulta interesante ver ahora cómo el widget modifica el contexto y qué tipo de información podemos obtener de él.

Nota

  • Como la biblioteca de widgets de OpenDataSoft se basa en AngularJS utilizaremos su sintaxis para leer el contexto.
    • El contexto es una variable AngularJS.

    • El contexto puede entenderse como un objeto JSON simple, con corchetes, listas de valores claves, etc.

    • Para evaluar una expresión en AngularJS utilizamos esta sintaxis: {{ acción1 o variable1 }}

Por último, para leer el contexto, basta con añadir este código en un espacio vacío:

<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 -->
                        . . . .

Guarde los cambios y actualice. Observará un bloque json sin formato bonito en la parte superior de la página; con una impresión en formato bonito en su entorno de desarrollo preferido (o con una bonita impresora json en línea como la de CuriousConcept ), debería ver algo parecido a esto:

{
   "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
}

Como es json, con la expresión AngularJS podemos navegar en su estructura para obtener el valor de cualquier clave. Por ejemplo, para obtener el título de juego de datos, vamos del contexto a la lista dataset y después a la lista metas, y ya podemos conseguir el valor de título. Encapsulado en un gran encabezado (etiqueta HTML h1), tiene este aspecto:

<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

Ahora que hemos visto qué es el contexto, debemos examinar su creación. Se utiliza odsDatasetContext para crear un contexto, a partir de un ID de juego de datos y opcionalmente otros parámetros.

<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>

Como señala la documentación, hay 2 parámetros obligatorios: el nombre de contexto y el ID de juego de datos. En este caso, se ha copiado 1 parámetro adicional. mycontext-parameters permite definir filtros específicos o una consulta al contexto. Aquí, se ha establecido el modo disyuntivo en true para 5 campos, y el último parámetro establece una ordenación para date_d_immatriculation.

Nota

El modo disyuntivo establecido como true en un campo de faceta activa el modo de filtro de opción múltiple. Permite al usuario aplicar un filtro, y aún así poder ver y/o seleccionar otros valores.

Eliminaremos este atributo opcional y observaremos los cambios.

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

Primero el contexto; si lo visualizamos, el bloque de parámetros json ahora es mucho más pequeño:

En el código, añada:

{{ entreprisesimmatriculeesen2016.parameters }}

Guarde los cambios, actualice y observe:

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

Todavía tenemos un parámetro de ordenación, aunque lo hayamos suprimido del widget de creación de contexto (odsDatasetContext), debido a la configuración del orden del juego de datos en la vista de tabla.

Última prueba: aplique un filtro en cualquier faceta y observe cómo se actualiza el objeto context.parameters.

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

Nota

Observe también el comportamiento 'estándar' de las facetas: cuando se selecciona un valor, todos los demás se ocultan.

Añadir un contador de registros y la última fecha de procesamiento

Es el momento de obtener más datos interesantes de este contexto:

  • La cantidad total de registros

  • El número total de coincidencias para la consulta del usuario y/o los filtros

  • La última fecha de procesamiento del juego de datos

{
   "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
}

A continuación:

  • El acceso a la cantidad total de registros se realizará mediante: {{  entreprisesimmatriculeesen2016.dataset.metas.records_count }}

  • El número total de coincidencias: {{  entreprisesimmatriculeesen2016.nhits }}

  • La última fecha de procesamiento: {{  entreprisesimmatriculeesen2016.dataset.metas.data_processed }}

Para terminar incluimos estos bloques en el código HTML, delimitados por código HTML y CSS para una bonita presentación.

Los registros y las coincidencias (nhits) figuran en la parte superior de la barra de navegación; y la fecha de procesamiento, en la parte inferior:

<!-- 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>

Guarde los cambios, actualice y observe:

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

Está bien, pero el formato numérico y de fecha es algo adusto. Para corregirlo, introduciremos un concepto AngularJS puro denominado filtros. La documentación completa de los filtros AngularJS se encuentra aquí.

Un filtro es una función u operación que se puede aplicar a una variable o valor de una expresión AngularJS.

En este caso, utilizaremos el filtro number para imprimir en un formato bonito los valores numéricos (cada 3 dígitos añada un espacio o una coma, según el país) y el filtro date para transformar el formato técnico ISO en un formato natural.

<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>

Nota

Para "invocar" un filtro, escriba la barra vertical '|' al final de la expresión. Algunos filtros aceptan parámetros específicos; el filtro de fecha admite un patrón o formato de fecha. Ejemplo: expr. | date : 'M/d/yy' expr. | date : 'medium'.

Guarde los cambios, actualice y observe:

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

Conceptos avanzados: AngularJS

Descubrir las directivas AngularJS

Una directiva AngularJS puede entenderse como un atributo HTML que se puede añadir a cualquier elemento HTML. Muchas están disponibles en la plataforma y se pueden emplear para añadir un comportamiento dinámico a los paneles.

A continuación se muestra un subconjunto de las directivas más utilizadas:

  • ng-init: inicializar una variable

  • ng-click: evaluar una expresión cuando el usuario haga clic en el elemento

  • ng-class: aplicar una clase CSS en función de una variable o condición

  • ng-if: mostrar u ocultar un elemento en función de una condición

  • ng-repeat: iterar en una lista o matriz y repetir el elemento HTML para cada una de las iteraciones

  • ng-change: evaluar una expresión cuando el usuario cambie el valor de un elemento HTML Select

ng-if: mostrar u ocultar un widget en función de la selección de filtro del usuario

¡En el panel tenemos el gráfico de líneas de región, y también el filtro de ciudad! Cuando el usuario seleccione una ciudad como filtro, el gráfico no tendrá ninguna utilidad ya que solo tiene un valor para visualizar.

Podría ser interesante ocultar el widget de región cuando se seleccione una actividad, y mostrar otro gráfico en su lugar.

Volvamos a la vista Explorar del juego de datos; vaya a la ficha de análisis y configure un gráfico nuevo, por ejemplo:

Un gráfico circular con el número de empresas registradas para cada uno de los meses del año, en orden.
  • Eje X: fecha de registro, por mes

  • Y: gráfico circular, eje Y: recuento

  • Copie y pegue el código del widget bajo el gráfico.

  • Elimine la declaración de contexto pegada.

  • Cambie el nombre de contexto empleado en este gráfico nuevo (si es necesario).

Ahora podemos utilizar la directiva ng-if en cada uno de los widgets para visualizar uno u otro.

La condición será: si se aplica o no un refinamiento en el contexto, mostrar u ocultar. Hemos visto que la lista de refinamientos está disponible en context.parameters. Como los parámetros son un diccionario de valores clave, para obtener el parámetro de refinamiento myfield, intentamos acceder a: mycontext.parameters['refine.myfield'].

Una vez aplicado al juego de datos, tiene este aspecto:

<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>

Nota

  • La condición ng-if del gráfico de región se puede traducir como Mostrar el gráfico si hay un refinamiento en la faceta de ciudad **ville**.
    • El carácter ! permite obtener lo contrario, y la condición se puede traducir como Mostrar el gráfico si NO hay ningún refinamiento en la faceta de ciudad **ville**

    • Para entender fácilmente su funcionamiento, no dude en visualizar el valor context.parameters en el panel cada vez que lo utilice.

ng-init / ng-click / ng-if /ng-class: crear fichas para cambiar entre vistas

En este ejemplo se utilizan 4 directivas.

  • ng-init para declarar una variable para el seguimiento de la ficha que se visualiza

  • ng-if para visualizar una sola ficha cada vez, según el valor de la variable

  • ng-click para cambiar el valor de la variable a fin de cambiar de una ficha a otra

  • ng-class para cambiar color de la ficha con objeto de mostrar qué ficha está seleccionada

Así que, en primer lugar, la estructura 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>

Inicialice una variable denominada tab con ng-init:

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

En cada uno de los botones de la ficha, añada un ng-click para configurar el valor de 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>

A continuación, en cada uno de los bloques de contenido, añada una condición ng-if para su visualización:

<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>

Guarde los cambios, actualice y pruebe; observará que, si hace clic en el botón de ficha, ¡el contenido cambia!

Ahora necesita algo de código CSS para tener un estilo de botón real, como ya hemos visto: ods-button ods-button--primary. Vamos a añadir también una clase items e item.

Tiene este aspecto:

<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>

Añada esto en el bloque 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 */
}

Por último, todavía con CSS, queremos resaltar con otro color la ficha que está seleccionada. Utilizaremos también un botón predefinido: ods-button--danger (en rojo) Esta clase CSS solo debe establecerse para una condición específica con ng-class. El patrón es: ng-class="{'clase-css': variable == valor}".

El código HTML final tiene este aspecto:

<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>

¡Guarde los cambios, actualice y pruebe a cambiar entre fichas!

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

A continuación, podemos incluir esto en el panel para añadir visualizaciones adicionales sin tener un panel demasiado pesado (de cargar o leer). Para dar espacio a la tabla y el gráfico, demasiado pequeños, los incluiremos en una ficha; también añadiremos un tercer gráfico, a partir de otro eje (la fecha, por ejemplo). La segunda fila pasará a ser la fila tabulada, y cada uno de los widgets (tabla y gráficos) será el contenido de cada una de las fichas.

El contenido principal tiene este aspecto:

<!-- 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>

Para centrar los botones de ficha, edite el código CSS con:

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

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

Y por último, guarde los cambios y actualice:

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