Search code examples
djangochartsjinja2

Django - display the same chart in loop in jinja template with chart.js


I would like to display the same chart (of course with different data and labels) in loop. At this moment I have:

 <tbody>
        {% for key, value in game_details.items %}
            <tr>
                <td>{{ key }}</td>
                <td>{{ value.all }}</td>
                <td>{{ value.win }}</td>
                <td>{{ value.lost }}</td>
            </tr>
            <tr>
                <td>
                    <canvas id="myChart" width="400" height="400"></canvas>
                    <script>
                        const ctx = document.getElementById('myChart').getContext('2d');
                        const myChart = new Chart(ctx, {
                            type: 'pie',
                            data: {
                                labels: ['Win', 'Lost'],
                                datasets: [{
                                    label: '# of Votes',
                                    data: [{{ value.win }}, {{ value.lost }}],
                                    backgroundColor: [
                                        'rgba(255, 99, 132, 0.2)',
                                        'rgba(54, 162, 235, 0.2)',
                                    ],
                                    borderColor: [
                                        'rgba(255, 99, 132, 1)',
                                        'rgba(54, 162, 235, 1)',
                                    ],
                                    borderWidth: 1
                                }]
                            },
                            options: {
                                scales: {
                                    y: {
                                        beginAtZero: true
                                    }
                                }
                            }
                        });
                    </script>
                </td>
            </tr>
        {% endfor %}
        </tbody>

The first chart is displayed, but when I'm looking in console I can see: Uncaught SyntaxError: Identifier 'ctx' has already been declared (at (index):179:29). So my loop can't create another chart, because ctx is already declared. My goal is to display chart for each iteration over dictionary. I was looking at this post, but it doesn't sole my problem. How can I do it properly?


Solution

  • Construct your canvas identifier and those JavaScript constant names with the loop index loop.index:

    For example:

    {% for key, value in game_details.items %}
      <canvas id="myChart{{ loop.index }}" width="400" height="400"></canvas>
      <script>
        const ctx{{ loop.index }} = document.
          getElementById('myChart{{ loop.index }}').
          getContext('2d');
        const myChart{{ loop.index }} = new Chart(ctx{{ loop.index }}, {
          type: 'pie',
          data: {
            labels: ['Win', 'Lost'],
            datasets: [{
              label: '# of Votes',
              data: [{{ value.win }}, {{ value.lost }}],
              backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
              ],
              borderColor: [
                'rgba(255, 99, 132, 1)',
                'rgba(54, 162, 235, 1)',
             ],
             borderWidth: 1
           }]
         },
         options: {
           scales: {
             y: {
               beginAtZero: true
             }
           }
         }
       });
     </script>
    {% endfor %}