alesssz
alesssz

Reputation: 520

jsreport, dynamic number of charts through jquery

I'm using JSreport 3.4.1. and Chart.js 3.8.0. From a server API I'm getting a series of data to create n. charts. The problem is that the number of charts are never the same (they depend on various parameters in a database).

I cannot create n. static charts for the reason above, so I was trying to dynamically create and inject them in the DOM through jQuery, but I'm having some difficulties:

It successfully creates the first chart, but with incorrect data (like it isn't waiting for the trigger input), and the second chart isn't shown at all.

enter image description here

Any idea on how to create a dynamic number of charts based on the number of objects (inside an array) that arrives through an API?

const datasets = {
  "datasets": [{
      "dynamic_id": 0,
      "NomeAnomalia": "MIT Appoggi",
      "GruppiAnomalie": 199,
      "anomalyList": [{
        "GruppiAnomalie": 199,
        "Code": "Classe 1\nApp1",
        "Name": "Piastra di base deformata",
        "Class": "Classe 1",
        "Severity": "0 - Lieve",
        "Value": 100
      }],
      "pieChartData": [{
          "severityName": "Lieve",
          "severityValue": 100
        },
        {
          "severityName": "Media",
          "severityValue": 0
        },
        {
          "severityName": "Forte",
          "severityValue": 0
        }
      ]
    },
    {
      "dynamic_id": 1,
      "NomeAnomalia": "MIT Impalcati,Travi,Traversi CA CAP",
      "GruppiAnomalie": 199,
      "anomalyList": [{
        "GruppiAnomalie": 199,
        "Code": "Classe 1\nApp1",
        "Name": "Piastra di base deformata",
        "Class": "Classe 1",
        "Severity": "0 - Lieve",
        "Value": 100
      }],
      "pieChartData": [{
          "severityName": "Lieve",
          "severityValue": 100
        },
        {
          "severityName": "Media",
          "severityValue": 0
        },
        {
          "severityName": "Forte",
          "severityValue": 0
        }
      ]
    }
  ]
}
var content = document.getElementById('content');

for (dataset of datasets.datasets) {
  var divPieChart = `
    <div class="row">
      <div class="col-sm-12">
        <div class="chart-container">
          <canvas id="bar_chart_${dataset.dynamic_id}"></canvas>
        </div>
      </div>
    </div>`;

  content.innerHTML += divPieChart;

  var bar_chart_ctx = document.getElementById(`bar_chart_${dataset.dynamic_id}`).getContext('2d');
  var bar_chart = new Chart(bar_chart_ctx, {
    type: 'bar',
    data: {
      labels: [1, 2, 3],
      datasets: [{
        "label": "2017",
        "data": [5, 3, 7.5],
        "backgroundColor": ["rgba(215, 221, 234)"]
      }]
    },
    options: {
      maintainAspectRatio: false,
      devicePixelRatio: 1.5,
      plugins: {
        legend: {
          display: true,
          position: "top"
        }
      },
      scales: {
        y: {
          beginAtZero: true
        }
      },
      animation: {
        onComplete: function() {
          // set the PDF printing trigger when the animation is done
          // to have this working, the chrome-pdf menu in the left must
          // have the wait for printing trigger option selected
          window.JSREPORT_READY_TO_START = true
        }
      }
    }
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<div id="test"></div>
<div id="content"></div>

I've set a playground with mock data (not really needed cause I've put static data inside the charts) so you can see what I mean: playground test

Thank you

EDIT
I figured out how to do it (JSReport specifically): in JSReport, window.JSREPORT_READY_TO_START = true tells the report that all the components in the page are done to print. Breaking down the "creation" of the html and the "creation" of the charts into two separates loop, using the length of the dataset as control, makes the work (only JSReport, I won't post a snippet cause it won't work the same as window.JSREPORT_READY_TO_START = true is not present).
Here's the playground if someone needs it: playground test

Upvotes: 1

Views: 212

Answers (0)

Related Questions