Integración de librería PivotGrid de DevExtreme

Rubén, desarrollador de España,  me explicó que necesitaba hacer análisis de información de sus sistemas y requería, así lo vi yo, de una solución de tabla Pivot y gráficos.

Estuvimos viendo la solución que ya disponíamos pero no me satisfacía la presentación de la misma, así que busqué otra solución y me gustó esta de DevExpreme. Espero que a vosotros también os guste.

Esta librería es gratis, si no la utilizamos de forma comercial.

Objetivos del ejemplo

  • Identificar los campos “dimensiones” y “valores” en el cubo de datos.
  • Poder definir los signos de puntuación para los valores según el idioma y el tipo de dato.
  • Poder utilizar el producto en distintos idiomas. ¡¡¡ Siempre probando en Español !!!
  • Poder utilizar la funcionalidad de gráficos integrados con los datos de la tabla.
  • Poder definir los colores que deseo aplicar a una de las “dimensiones” (hemos conseguido resolverlo)

DEMO: https://fhumanes.com/pivot_grid

Solución Técnica

He realizado el ejemplo en PHPRunner 10.4, igual que el anterior de la tabla Pivot.

He hecho un conjunto de botones con el fin de obtener o no los gráficos y cambiar el tipo del mismo.

Dispone de la funcionalidad de exportar los gráficos y la tabla de datos. Ambas exportaciones son muy buenas.

Dispone de un selector de campos para definir la tabla pivote y ajustarla a las necesidades del usuario.

He puesto, además del ejemplo, las opciones de:

  • Ver la tabla de datos “Escaños”.
  • Ejemplo de los dos ejercicios que he hecho fuera de PHPRunner hasta definir el formato que quería usar. Esto puede ser útil para probar las cientos de posibilidades que tiene el producto.
  • También he dejado una opción con el report que se puede crear con el estándar de PHPRunner  y como podréis ver es bastante “malo”.

El snippet que utilizado y que he ubicado en el directorio MyCodepivot001.php“, es:

<?php
@ini_set("display_errors","1");
@ini_set("display_startup_errors","1");
require_once("include/dbcommon.php");


// List of colors of Candidaturas
$colores = '';
$sql="SELECT Codigo, Color FROM candidatura";
$resql=DB::Query($sql,$conn);
while($row = $resql->fetchAssoc()) {
    $colores .= "'".$row['Codigo']."' : '".$row['Color']."',";
}
if (!isset($_SESSION['Graphics'])){
    $_SESSION['Graphics']= '';
}
$Graphics = $_SESSION['Graphics'];

$html = <<<EOT
   <script src=" https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js"></script>

    <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/21.2.5/css/dx.common.css" />
    <!-- DevExtreme theme -->
    <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/21.2.5/css/dx.light.compact.css" />
    <!--  <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/21.2.5/css/dx.darkmoon.compact.css" />  -->

    <script src="https://cdn3.devexpress.com/jslib/21.2.5/js/dx.all.js"></script>

    <!-- Dictionary files for English and Spanish languages -->   
    <!-- <script src="https://cdn3.devexpress.com/jslib/21.2.5/js/localization/dx.messages.en.js"></script> -->
    <script src="https://cdn3.devexpress.com/jslib/21.2.5/js/localization/dx.messages.es.js"></script>

    <script src="elecciones_json001.php"></script>  <!-- Load data for Pivot -->

    <style>
        #pivotgrid {
            margin-top: 20px;
        }
        
        .currency {
            text-align: center;
        }
    </style>
    <script>
        $(() => {

EOT;
if ($Graphics <> '') {

$html .= <<<EOT
        const pivotGridChart = $('#pivotgrid-chart').dxChart({
        commonSeriesSettings: {
            type: '$Graphics',  // 'bar'
        },
        palette: 'Soft', // 'Bright' | 'Harmony Light' | 'Ocean' | 'Pastel' | 'Soft' | 'Soft Pastel' | 'Vintage' | 'Violet' | 'Carmine' | 'Dark Moon' | 'Dark Violet' | 'Green Mist' | 'Soft Blue' | 'Material' | 'Office' 
        export: {
            enabled: true,
        },
        /*
        legend: {
                verticalAlignment: 'bottom',
                horizontalAlignment: 'center',
        },
        */
        tooltip: {
            enabled: true,
            format: {type: "decimal"},
            customizeTooltip(args) {
            return {
                html: `\${args.seriesName} <div class='currency'>\${args.valueText}</div>`,
                };
            },
        },
        size: {
            height: 300,
        },
        adaptiveLayout: {
            width: 450,
        },
        }).dxChart('instance');
EOT;
}
$html .= <<<EOT
        const pivotGrid = $('#pivotgrid').dxPivotGrid({
        allowSortingBySummary: true,
        allowFiltering: true,
        showBorders: true,
        showColumnGrandTotals: false,
        showRowGrandTotals: false,
        showRowTotals: false,
        showColumnTotals: false,
        fieldChooser: {
            enabled: true,
            height: 400,
            title: "Selector campos"
        },
        dataSource: {
            fields: [{
            caption: 'Siglas',
            width: 100,
            dataField: 'Siglas',
            area: 'row',
            // sortBySummaryField: 'Escaños',
            }, {
                caption: 'Candidatura',
                dataField: 'Candidatura',
                width: 100,
                // area: 'row',  
            }, {
            caption: 'Convocatoria',
            dataField: 'Convocatoria',
            width: 50,
            area: 'column',
            }, {
            caption: 'Escaños',
            dataField: 'Escaños',
            dataType: 'number', 
            summaryType: 'sum',
            format: {type: "decimal" },
            area: 'data',
            }, {
                caption: 'Votos',
                dataField: 'Votos',
                dataType: 'number', 
                summaryType: 'sum',
                format:  "##,###,##0",
                area: 'data',
            }, {
                caption: '% Votos',
                dataField: '% Votos',
                dataType: 'number', 
                summaryType: 'sum',
                format: "#0.00'%'",
                area: 'data',
            }
            ],
            store: votos,
        },
        export: {
            enabled: true
            },
            texts: {
                collapseAll: "Collapse All",
                dataNotAvailable: "N/A",
                expandAll: "Expand All",
                exportToExcel: "Exportar a fichero Excel",
                grandTotal: "Total General",
                noData: "No data",
                removeAllSorting: "Remove All Sorting",
                showFieldChooser: "Mostrar el selector de campos" ,
                sortColumnBySummary: "Sort {0} by This Column",
                sortRowBySummary: "Sort {0} by This Row",
                total: "{0} Total"
            },
        }).dxPivotGrid('instance');
EOT;
if ($Graphics <> '') {

$html .= <<<EOT
   pivotGrid.bindChart(pivotGridChart, {
      dataFieldsDisplayMode: 'splitPanes',
      alternateDataFields: false,
      customizeSeries: function (seriesName, seriesOptions) {
        // console.log('Serie: ',seriesName);
        // console.log('Opciones: ',seriesOptions);
        const myArray = seriesName.split(" | ");
        // console.log('array: ',myArray);
        // Search Colors
        const index = colors.findIndex(object => {
            return object.Siglas === myArray[0];
          });
        if(index > -1){
            seriesOptions.color = colors[index]['Color'];
            // console.log('Index: ',index); // SET Color
            // console.log('Color: ',colors[index]['Color']);
        }        
        return seriesOptions;
      }
    });
EOT;
}

$html .= <<<EOT
        DevExpress.localization.locale(navigator.language);

        // setTimeout(expand, 0);
        });       
    </script>

    <div class="pivot-container">
        <center><h3>Resultados Elecciones de la Comunidad de Madrid</h3></center>
      <div id="pivotgrid-group">
        <div id="pivotgrid-chart"></div>
        <div id="pivotgrid"></div>
      </div>
    </div>

EOT;

echo $html;

Los datos son cargados a través de este código “elecciones_json001.php“:

<?php
@ini_set("display_errors","1");
@ini_set("display_startup_errors","1");
require_once("include/dbcommon.php");
header("Expires: Thu, 01 Jan 1970 00:00:01 GMT"); 
global $conn;
// Array of Colors of Siglas
$all_colors = [];
$sql="select Codigo Siglas, Color from escanos
join candidatura on (idCandidatura = Candidatura_idCandidatura)
order by Codigo asc";
$resql=DB::Query($sql,$conn);
while($row = $resql->fetchAssoc()) {
    $all_colors[] = $row;
}
$colors = json_encode($all_colors, JSON_UNESCAPED_UNICODE); // convert Array to Json

// Construct JSON
$all_row = [];
$sql = $_SESSION['SQL001']; //  Bring the Select page with the filters done
if (!isset($_SESSION['SQL001'])) {
    $sql="select
    -- idEscanos,
    -- Orden_Ana Orden,
    convocatoria.Titulo Convocatoria,
    Codigo Siglas,
    candidatura.Titulo Candidatura,
    -- Color,
    Votos,
    PorcVotos `% Votos`,
    Escanos `Escaños`
    from escanos
    join convocatoria on (idConvocatoria = Convocatoria_idConvocatoria and EsAsamblea = 1)
    join candidatura on (idCandidatura = Candidatura_idCandidatura)
    order by Orden_Ana desc";
}
$resql=DB::Query($sql,$conn);
while($row = $resql->fetchAssoc()) {
    $all_rows[] = $row;
}
$data = json_encode($all_rows, JSON_UNESCAPED_UNICODE); // convert Array to Json
echo "const votos = ".$data.";";
echo "const colors = ".$colors.";";
?>

Para cualquier problema de este ejemplo, gustosamente os responderé y resolveré las dudas que tengáis. Hacedme las preguntas a través de mi email [email protected]

También, como siempre hago, os dejo los fuentes del ejemplo para que lo podáis reproducir en vuestros equipos.

Adjuntos

Archivo Tamaño de archivo Descargas
zip Backup de la Base de Datos 478 KB 1190
zip PHPRunner 10.4, actualizado 18/03/2022 68 KB 231

Blog personal para facilitar soporte gratuito a usuarios de PHPRunner