Enlazar Grafico (Google Charts) con Datatables

Enlazar Grafico (Google Charts) con Datatables

JuanAlbertoJuanAlberto Posts: 14Questions: 4Answers: 0
edited August 2023 in Free community support

Tengo un DataTable con registros cargados desde un archivo excel, estoy conectándole un Grafico pero aun no logro siquiera que el Grafico se visualice en la pagina. la carga del datatable con registros esta trabajando bien, el tema es que da la sensación que la función updateBarChart() del Grafico llega antes de la inicialización de la tabla. dejo los codigos para su ayuda a la solución.

index.html

<div class= "Grafico2" style="margin-left: -80px;">     
         <div id="chart_div" style="width: 900px; height: 462px;" ></div>
    </div>  
    <script src="./script.js"></script>
   <script src="./chart2.js"></script>  
  </body>
</html> 

script.js

let data;
// Esta función inicializa el DataTable con las opciones especificadas en 'dataTableOptions'.
// Selecciona el elemento con el id "example" y crea el DataTable con las opciones en 'dataTableOptions'.
const initDataTable = () => {
  dataTable = $('#example').DataTable(dataTableOptions);
  //console.log("DataTable initialized")
  //console.log(dataTable); // Agrega esta línea para verificar los datos del DataTable
};
const loadJsonDataToDataTable = (jsonData) => {
  if (!jsonData || jsonData.length === 0) {
    return;
  }
  // Limpiar el DataTable antes de cargar nuevos datos.
  dataTable.clear().draw();
  // Agregar los registros al DataTable iterando por cada objeto en jsonData.
  jsonData.forEach((data) => {
    // Verificar si la columna Almacén está vacía.
   if (data[9] !== "") {
    // Convertir el objeto de datos a un array con las columnas seleccionadas en el orden deseado.
    const rowData = [
            data.Almc,
            data.Articulo,
            data.Descripcion,
            data.Stock,
            data.InvAsigTotal,
            data.Reserva,
            data.Transito,
            data.CntOrd,
            data.CntAsig,
            data.CntPick,
            data.FaltPick
    ]
    //console.log(rowData);
    // Convertir el array a formato JSON con comillas dobles y luego analizarlo para asegurar el formato JSON válido.
    const jsonString = JSON.stringify(rowData);
    const jsonDataParsed = JSON.parse(jsonString);
  
    // Agregar el objeto jsonDataParsed directamente como una nueva fila al DataTable.
    dataTable.row.add(jsonDataParsed).draw();
  }
  });
};

document.getElementById("fileUpload").addEventListener("change", function (event) {
  // Obtener el archivo seleccionado del input file.
  const selectedFile = event.target.files[0];

  // Verificar si se seleccionó un archivo.
  if (selectedFile) {
    // Crear un nuevo objeto FileReader.
    var fileReader = new FileReader();

    // Definir la función de callback para cuando el archivo se haya leído completamente.
    fileReader.onload = function (event) {
      // Obtener los datos del archivo leído como una cadena binaria.
      var data = event.target.result;
      
      // Leer el archivo como un libro de Excel usando la biblioteca XLSX.
      var workbook = XLSX.read(data, { type: "binary" });

      var jsonData = [];

      // Iterar a través de cada hoja del libro de Excel.
      workbook.SheetNames.forEach(sheet => {
        // Convertir la hoja actual a un array de objetos JSON y agregarlo a jsonData usando el operador spread (...)
        var rowObject = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheet]);
        jsonData.push(...rowObject);
      });
      //console.log(jsonData);
      // Llamar a la función para cargar los datos al DataTable con el JSON obtenido del archivo Excel.
      loadJsonDataToDataTable(jsonData);
    };

    // Leer el archivo seleccionado como una cadena binaria para poder procesarlo con la biblioteca XLSX.
    fileReader.readAsBinaryString(selectedFile);
  }

});

// Ejecutar la función initDataTable al cargar la página para inicializar el DataTable.
window.addEventListener('load', () => {
  initDataTable();

  updateBarChart()
});

chart2.js
google.charts.load('current', { 'packages': ['corechart'] });
google.charts.setOnLoadCallback(() => {
    updateBarChart();
  });
// Función para crear o actualizar el gráfico de barras
function updateBarChart() {
    // Obtener el DataTable creado en script.js
    var dataTable = window.dataTable;
    //console.log("DataTable:", dataTable);
    if (!dataTable) {
       //console.error('DataTable is not available. Make sure the DataTable is loaded in script.js before chart2.js.');
        return;
    }

    // Obtener los datos del DataTable y organizarlos en arreglos para el gráfico
    let dataByAlmacen = {}; // Objeto para almacenar los datos por almacén

    // Recorrer las filas del DataTable (omitimos la primera fila que contiene los encabezados)
    let tableRows = dataTable.rows().data();
    tableRows.each(function (data) {
        let almacen = data[0]; // Columna de los almacenes
        let dato1 = parseFloat(data[7]); // Columna del dato1 (Ord)
        let dato2 = parseFloat(data[8]); // Columna del dato2 (Asig)
        let dato3 = parseFloat(data[9]); // Columna del dato3 (Pick)

        // Verificar si el almacén ya existe en el objeto, si no, lo agregamos con valores iniciales
        if (!dataByAlmacen[almacen]) {
            dataByAlmacen[almacen] = {
                dato1: 0,
                dato2: 0,
                dato3: 0
            };
        }

        // Acumulamos los datos en el objeto para el almacén correspondiente
        dataByAlmacen[almacen].dato1 += dato1;
        dataByAlmacen[almacen].dato2 += dato2;
        dataByAlmacen[almacen].dato3 += dato3;
    });

    // Crear el arreglo de datos para el gráfico
    var dataArray = [['Almacén', 'Ord', 'Asig', 'Pick']];
    for (var almacen in dataByAlmacen) {
        dataArray.push([
            almacen,
            dataByAlmacen[almacen].dato1,
            dataByAlmacen[almacen].dato2,
            dataByAlmacen[almacen].dato3
        ]);
    }

    var data = google.visualization.arrayToDataTable(dataArray);

    var options = {
        title: 'Tasa de Servicio: Asignacion de Articulos por Centro de Distribucion',
        titleTextStyle: { fontSize: 18 }, // Tamaño del título del gráfico
        vAxis: { title: 'Valores' },
        hAxis: { title: 'Almacén' },
        legend: { position: 'top' },
        bar: { groupWidth: '95%' } // Ajustar el ancho de las barras, un valor menor a 1 las hace más anchas
    };
    console.log("Data Array:", dataArray);
    console.log("Options:", options);
    // Crear o actualizar el gráfico de barras
    var barChart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
    barChart.draw(data, options);
    
}

Edited by Kevin: Syntax highlighting. Details on how to highlight code using markdown can be found in this guide

Answers

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951

    Thats a lot of code to look through to try understanding the code flow. If you want help debugging please provide a running test case so we can help debug.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Before doing that take a look at this Highcharts integration blog to see how to keep the chart updated based on the table display. The same idea would apply to the chart2 library.

    Kevin

  • JuanAlbertoJuanAlberto Posts: 14Questions: 4Answers: 0
    edited August 2023

    Tengo una duda, DataTable es compatible con Google Charts, (librerias)? porque los códigos que implemente para Gráficos me arrojan resultados conformes en la consola del navegador, sin embargo no imprimen en la pagina.
    Ahora estoy intentando terminar un Grafico highcharts y ya me empieza a cargar al DataTable.

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951

    I'm not familiar with Google Charts but I suspect there are API s you can use to populate the charts. You would use the Datatables API's like column().data() to get the data then manipulate the structure to match what is need for Google Charts and finally use their API's to populate the charts. Similar to the Highcharts example I linked to.

    Kevin

  • JuanAlbertoJuanAlberto Posts: 14Questions: 4Answers: 0

    El Datatable la tengo cargada dinámicamente con registros de Excel, ahora estoy intentando colocarle un grafico que sea dinámico en base a las variaciones que tenga el Datatable. Usando Grafico de Google Charts intento vincularlo al Datatable pero aun no consigo imprimir en la pagina, estuve probando el algoritmo del Grafico en el console del navegador y me indica que esta procesando el flujo de los datos del Datatable correctamente pero a pesar de ello no imprime nada en la pagina. Por eso que mi sospecha esta apuntando a la librería de Google Charts, no se si será un tema de incompatibilidad con el Datatable.

  • JuanAlbertoJuanAlberto Posts: 14Questions: 4Answers: 0

    Por lo que observo se adjunto sin querer los dos archivos script.js (Datatable se carga desde el archivo Excel) y chart2.js (Grafico se carga con registros del Datatable). Aqui va el chart2.js para que se diferencia del otro .js

    google.charts.load('current', { 'packages': ['corechart'] });
    google.charts.setOnLoadCallback(() => {
    updateBarChart();
    });
    // Función para crear o actualizar el gráfico de barras
    function updateBarChart() {
    console.log("Updating bar chart...");
    //Obtener el DataTable creado en script.js
    let dataTable = getDataTable(); //Este codigo REEMPLAZO a let dataTable = window.dataTable;
    console.log("DataTable:", dataTable);
    if (!dataTable) {
    console.error('DataTable is not available. Make sure the DataTable is loaded in script.js before chart2.js.');
    return;
    }

    // Obtener los datos del DataTable y organizarlos en arreglos para el gráfico
    let dataByAlmacen = {}; // Objeto para almacenar los datos por almacén
    
    // Recorrer las filas del DataTable (omitimos la primera fila que contiene los encabezados)
    let tableRows = dataTable.rows().data();
    tableRows.each(function (data) {
        let almacen = data[0]; // Columna de los almacenes
        let dato1 = parseFloat(data[7]); // Columna del dato1 (Ord)
        let dato2 = parseFloat(data[8]); // Columna del dato2 (Asig)
        let dato3 = parseFloat(data[9]); // Columna del dato3 (Pick)
    
        // Verificar si el almacén ya existe en el objeto, si no, lo agregamos con valores iniciales
        if (!dataByAlmacen[almacen]) {
            dataByAlmacen[almacen] = {
                dato1: 0,
                dato2: 0,
                dato3: 0
            };
        }
    
        // Acumulamos los datos en el objeto para el almacén correspondiente
        dataByAlmacen[almacen].dato1 += dato1;
        dataByAlmacen[almacen].dato2 += dato2;
        dataByAlmacen[almacen].dato3 += dato3;
    });
    
    // Crear el arreglo de datos para el gráfico
    var dataArray = [['Almacén', 'Ord', 'Asig', 'Pick']];
    for (var almacen in dataByAlmacen) {
        dataArray.push([
            almacen,
            dataByAlmacen[almacen].dato1,
            dataByAlmacen[almacen].dato2,
            dataByAlmacen[almacen].dato3
        ]);
    }
    
    var data = google.visualization.arrayToDataTable(dataArray);
    
    var options = {
        title: 'Tasa de Servicio: Asignacion de Articulos por Centro de Distribucion',
        titleTextStyle: { fontSize: 18 }, // Tamaño del título del gráfico
        vAxis: { title: 'Valores' },
        hAxis: { title: 'Almacén' },
        legend: { position: 'top' },
        bar: { groupWidth: '95%' } // Ajustar el ancho de las barras, un valor menor a 1 las hace más anchas
    };
    console.log("Data Array:", dataArray);
    console.log("Options:", options);
    // Crear o actualizar el gráfico de barras
    var barChart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
    barChart.draw(data, options);
    console.log("Bar Chart Drawn on the webpage");
    

    }

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951
    edited August 2023

    I built a simple example using this Google charts bar chart example. The key is to call google.charts.setOnLoadCallback() in initComplete to display the initial chart after Datatables initialization. The same is used in draw to keep the chart updated based on filtering the table.
    https://live.datatables.net/duwipoqu/1/edit

    Again I'm not familiar with Google Charts so I might be using it incorrectly. Use the Google documentation and forums like Stack Overflow for questions specific to Google Charts.

    Kevin

  • JuanAlbertoJuanAlberto Posts: 14Questions: 4Answers: 0

    El Grafico que estoy implementando es Grafico de columnas https://developers.google.com/chart/interactive/docs/gallery/columnchart?hl=es-419 q
    Si estoy usando la linea de código, google.charts.setOnLoadCallback() pero iniComplete option no, en algún momento intente colocarlo pero como no me funciono lo saque. Probablemente en mi código lo implemente mal.

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951

    If you need help troubleshooting please provide a link to your page or a test case replicating the issue.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • JuanAlbertoJuanAlberto Posts: 14Questions: 4Answers: 0

    Aquí tengo el enlace https://jsbin.com/wubevuzumo/edit?html,output
    pero hay un detalle, para cargar el Datatable se tiene que abrir un archivo Excel para cargar de registros (demora como tres segundos), además tiene que ser un Excel con ciertas características; que al menos que tenga 11 columnas con los siguientes encabezados para que el Datatable lo pueda reconocer:
    Almc,
    Articulo,
    Descripcion,
    Stock,
    InvAsigTotal,
    Reserva,
    Transito,
    CntOrd,
    CntAsig,
    CntPick,
    FaltPick

    A partir de esos registros en el Datatable es que se quiere crear un Grafico chart2.js, pero no se logra acceder a los datos del Datatable.
    El archivo chart2.js no lo pude subir al enlace, pero lo tengo aquí en el foro publicado.

Sign In or Register to comment.