Search code examples
javascriptajaxcsvflaskgoogle-visualization

How do you call a python api or local data into the js lib google.visualization.DataTable()?


I have been working for 2 weeks to try and get a CSV file (local) To load google.visualization.DataTable(). Or I would love to Us Ajax to call a Python flask API I created. I would like to create a Gantt chart dynamically.

My code:

    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js" ></script>
    <script type="text/javascript">
    
    // Load the Visualization API and the piechart package.
    google.charts.load('current', {'packages':['gantt']});
    google.charts.setOnLoadCallback(drawChart);
    
    function daysToMilliseconds(days) {
      return days * 24 * 60 * 60 * 1000;
    }
    



  function drawChart() {
      var jsonData = $.ajax({
          url: "http://127.0.0.1:5042/crudSEapi/D3test",
          dataType: "json",
          async: false
          }).responseText;
          var jsonData = JSON.parse(jsonData);
          // Create our data table out of JSON data loaded from server.
          var data = new google.visualization.DataTable(jsonData);
      // Create our data table out of JSON data loaded from server.
    
      console.log(jsonData["Column 0"])
      data.addColumn('string',jsonData["Column 0"]);
      data.addColumn(jsonData["Column 1"][1], jsonData["Column 1"][0]);
     
      
      data.addRows([
        [jsonData["Column 1"][2]]
       
      ]);


        // Instantiate and draw our chart, passing in some options.

        var options = {
          height: 275,
          gantt: {
            criticalPathEnabled: false, // Critical path arrows will be the same as other arrows.
            arrow: {
              angle: 100,
              width: 5,
              color: 'green',
              radius: 0
            }
          }
        };
        var container = document.getElementById('chart_div');
        var chart = new google.visualization.Gantt(container);
    
    // throw error for testing

    google.visualization.events.addListener(chart, 'ready', function () {
      throw new Error('Test Google Error');
    });

      // listen for error
      google.visualization.events.addListener(chart, 'error', function (err) {
        // check error

      });
        chart.draw(data, options);
    }



  </script>
         
     
          <main id="main">
              <section id="data-section">
                  <h2>Data Input</h2>
                  <div id="data"></div>
              </section>
          </main>
          <h2>chart output</h2>
    
          <div id="chart_div"></div>
      
      <script>
          function apicall(url) {
              $.ajax({
                  type:"POST", url:url, 
                  success: (data) => { $("#data").html(data); }
              });
          }
          window.onload = function () {
              apicall("http://127.0.0.1:5042/crudSEapi/D3test");
          }
      </script>

 

No mater how many YouTube videos I watch, I can't understand how to do an Ajax call from my Python Flask API AND load the needed data to google.visualization.DataTable() for dynamic creation of a Gantt chart:) please help

really my issue is a lack of Mastery of JS. How do I import data from API or a Local CSV? How do I Parse the data, then Organize the data to be used in google.visualization.DataTable(). I wish I could find a simple example. please help...

My Python Flask Api Code:

import json
@crudSEapi.route("/D3test", methods=["GET", "POST"])
def d3():
    df = pd.read_csv("SkillBook/static/Sheet4.csv")
    chartdata = df.to_json()
    data = json.dumps(chartdata, indent=2)
    print(data)
    return Response(data)

CSV file:

id,title,start,end,dependencies,completed
m1,milestone 1,addDuration(startOfDay(new Date()),addDuration(startOfDay(new Date()),m2: start-to-start,0.6
m2,milestone 2,addDuration(startOfDay(new Date()),addDuration(startOfDay(new Date()),[m3: end-to-start,m4: end-to-end],0
m3,milestone 3,addDuration(startOfDay(new Date()),addDuration(startOfDay(new Date()),,0.75
m4,milestone 4,addDuration(startOfDay(new Date()),addDuration(startOfDay(new Date()),,0.2

the output should look like this: enter image description here


Solution

  • I figured it out thanks to @WhiteHat.

    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="https://unpkg.com/jquery-csv@1.0.21/src/jquery.csv.js"></script>
    <div id="chart_div"></div>
    <li><input></li>
    <li><input></li>
    <li><input></li>
    <button>update data in chart</button>
    <button>print SVG</button>
    <script>
       function toMilliseconds(minutes) {
         return minutes * 60 * 1000;
       }
       
       google.charts.load('current', {
         callback: function () {
           $.get("/static/Sheet4.csv", function(csvString) {
             var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});
             console.log(arrayData[6][1])
             var data = new google.visualization.DataTable();
         
             data.addColumn(arrayData[2][1], arrayData[1][1]);
             data.addColumn(arrayData[2][2], arrayData[1][2]);
             data.addColumn(arrayData[2][4], arrayData[1][4]);
             data.addColumn(arrayData[2][5], arrayData[1][5]);
             data.addColumn(arrayData[2][6], arrayData[1][6]);
             data.addColumn(arrayData[2][7], arrayData[1][7]);
             data.addColumn(arrayData[2][8], arrayData[1][8]);
             data.addRows([
             [
             arrayData[3][1],
             arrayData[3][2],
               null,
               null,
               toMilliseconds(5),
               100,
               null,
             ],
             [
             arrayData[4][1],
             arrayData[4][2],
               null,
               null,
               toMilliseconds(70),
               100,
               null,
             ],
             [
             arrayData[5][1],
             arrayData[5][2],
               null,
               null,
               toMilliseconds(10),
               100,
               arrayData[3][1],
             ],
             [
             arrayData[6][1],
             arrayData[6][2],
               null,
               null,
               toMilliseconds(45),
               75,
               arrayData[5][1],
             ],
             [
             arrayData[7][1],
             arrayData[7][2],
               null,
               null,
               toMilliseconds(10),
               0,
               arrayData[6][1],
               ],
             [
             arrayData[8][1],
             arrayData[8][2],         
              null,
               null,
               toMilliseconds(2),
               0,
               arrayData[5][1],
             ],
           ]);
             
       
             var options = {
               height: 275,
               gantt: {
                 criticalPathEnabled: false, // Critical path arrows will be the same as other arrows.
                 arrow: {
                   angle: 100,
                   width: 5,
                   color: 'green',
                   radius: 0
                 }
               }
             };
             var container = document.getElementById('chart_div');
             var chart = new google.visualization.Gantt(container);
         
       
             chart.draw(data, options);
           });
         },
         packages: ['gantt']
       });
       
       
       
       
       
    </script>
    

    And my CSV:

    step0,step1,step2,step3,step4,step5,Step6,step7,step8
    Purpose,Task ID,Task Name,Resource ID,Start,End,Duration,Percent Complete,Dependencies
    Data Type,string,string,string,date,date,number,number,string
    Prject1data1,Test1,test1x,test1y,test1z,0,1,2,test1a
    Prject1data2,Test2,test2x,test2y,test2z,0,1,2,test2a
    Prject1data3,Test3,test3x,test3y,test3z,0,1,2,test3a
    Prject1data4,Test4,test4x,test4y,test4z,0,1,2,test4a
    Prject1data5,Test5,test5x,test5y,test5z,0,1,2,test4a
    Prject1data6,Test6,test6x,test6y,test6z,0,1,2,test4a
    Prject1data7,Test7,test7x,test7y,test7z,0,1,2,test4a
    

    Next step: Change Input To dynamic. I will create inputs form on website to change the data

    I will allow CSV to be upload and parsed no mater the size of the CSV file