Search code examples
javascriptchartsgoogle-visualizationjinja2

Google Visualization Chart Multiple LineChart TimeSeries from Jinja


I have data coming in from Jinja which contains data for each user. It contains this kind of data:

{
{"user": "test1", "daily_scores": [0: "date":12/11/12, "score": 30, 1: "date":12/12/12, "score": 40 ]},
{"user": "test2", "daily_scores": [0: "date":12/11/12, "score": 30, 1: "date":12/12/12, "score": 20 ]},
{"user": "test3", "daily_scores": [0: "date":12/1/12, "score": 30, 1: "date":12/12/12, "score": 30 ]},
}

I was able to format it properly in JS and used in in google visualization however it doesnt show properly, it only shows one user:

enter image description here

My attempt at google visualization:

   <script>

    google.charts.load('current', {packages: ['corechart', 'line']});
    google.charts.setOnLoadCallback(drawCurveTypes);

function drawCurveTypes() {

    datas = JSON.parse({{persons_performance|tojson|safe}});



    var data = new google.visualization.DataTable();

    data.addColumn('date', 'Date');
    data.addColumn('number', 'Score');
    data.addColumn({ type: 'string', id: 'Person', role: 'annotation' });


    for (var i = 0; i < datas.length; i++) {

        person_name = datas[i]['user'];




        daily_score_datas = datas[i]['daily_scores']
        console.log(daily_score_datas)
        for (var i = 0; i < daily_score_datas.length; i++) {
            daily_score = daily_score_datas[i];
            daily_score_date = new Date(daily_score['date']);
            daily_score_score = daily_score['score'];
            data.addRow([daily_score_date, daily_score_score, person_name]);
       }

    }

      var options = {
        {#chartArea:{ width:"100%", height:"100%"},#}
        title: "Person Performance over Time",
        height: 500,
        width: 1300,
        hAxis: {
        title: 'Time',
        textPosition: 'none'
        },

        vAxis: {
          title: 'Score'
        },
        series: {
          1: {curveType: 'function'}
        },
        legend: {position: 'none'}
      };

      var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
      chart.draw(data, options);
    }


    </script>

It is weird because I clearly have three columns and three values for each row. I need help in making it so it would display into multiple lines per person with each of their score in the line. Thanks!


Solution

  • in order to create multiple lines in the chart,
    you need multiple series, or columns, in the data table.
    in other words, you need a column for each user...

    so instead of a single column...

    data.addColumn('date', 'Date');
    data.addColumn('number', 'Score');
    

    you need multiple, one for each user...

    data.addColumn('date', 'Date');
    data.addColumn('number', 'User 1');
    data.addColumn('number', 'User 2');
    data.addColumn('number', 'User 3');
    

    we can build the columns dynamically, from the data provided,
    but our approach will be a little different.

    we'll need to add the columns as we loop the data,
    then save the column index of the columns we created.
    which means we'll need to set the value of each cell, on each row, individually.

    for example, first create the data table with the date column...

    var data = new google.visualization.DataTable();
    data.addColumn('date', 'Date');
    

    then as we loop thru the data, add the user columns...

    datas.forEach(function (row) {
      // create the data table column for the user and user annotation
      var person_name = row['user'];
      var column_index = data.addColumn('number', person_name);
      var column_index_ann = data.addColumn({type: 'string', role: 'annotation'});
    
      // next, loop the scores for the user
      var daily_score_datas = row['daily_scores'];
      daily_score_datas.forEach(function (daily_score) {
       // get score values
        var daily_score_date = new Date(daily_score['date']);
        var daily_score_score = daily_score['score'];
    
        // add a new blank row and save row index
        var row_index = data.addRow();
    
        // set values for the date, user, and user annotation
        data.setValue(row_index, 0, daily_score_date);
        data.setValue(row_index, column_index, daily_score_score);
        data.setValue(row_index, column_index_ann, person_name);
      });
    });
    

    see following working example...

    google.charts.load('current', {
      packages: ['corechart']
    }).then(function drawCurveTypes() {
      var datas = [
        {"user": "test1", "daily_scores": [{"date":"12/11/2021", "score": 0}, {"date":"12/12/2021", "score": 40}]},
        {"user": "test2", "daily_scores": [{"date":"12/11/2021", "score": 10}, {"date":"12/12/2021", "score": 20}]},
        {"user": "test3", "daily_scores": [{"date":"12/11/2021", "score": 20}, {"date":"12/12/2021", "score": 30}]},
      ];
    
      var data = new google.visualization.DataTable();
      data.addColumn('date', 'Date');
    
      datas.forEach(function (row) {
        // create the data table column for the user and user annotation
        var person_name = row['user'];
        var column_index = data.addColumn('number', person_name);
        var column_index_ann = data.addColumn({type: 'string', role: 'annotation'});
    
        // next, loop the scores for the user
        var daily_score_datas = row['daily_scores'];
        daily_score_datas.forEach(function (daily_score) {
         // get score values
          var daily_score_date = new Date(daily_score['date']);
          var daily_score_score = daily_score['score'];
    
          // add a new blank row and save row index
          var row_index = data.addRow();
    
          // set values for the date, user, and user annotation
          data.setValue(row_index, 0, daily_score_date);
          data.setValue(row_index, column_index, daily_score_score);
          data.setValue(row_index, column_index_ann, person_name);
        });
      });
    
      var options = {
        //chartArea: {width:"100%", height:"100%"},
        title: "Person Performance over Time",
        height: 500,
        width: 1300,
        hAxis: {
          title: 'Time',
          textPosition: 'none'
        },
        vAxis: {
          title: 'Score'
        },
        series: {
          1: {curveType: 'function'}
        },
        legend: {position: 'none'}
      };
    
      var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
      chart.draw(data, options);
    });
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="chart_div"></div>