[SalesForce] Chart with Dynamic data LWC

Trying to display the Dynamic data in Pie chart using Chartjs, Below is the Code.

To build the chart, how to pass the Dynamic Chart label and Chart data.

This is the response I'm returning from Controller. {"CS Payroll":40,"Salesforce Implementation":20}

 @track opportunityData = [];
  @wire(aggregateEmployeeProjectHours, { loggedinUserId: "0031I000008Lx44QAC" })
  opptyData({ error, data }) {
    let responsedataJson = JSON.stringify(data);
    let responseErrorJson = JSON.stringify(error);
    console.log("Chart data" + responsedataJson);
    console.log("Chart Error" + responseErrorJson);
    if (data) {
      let oppData = Object.assign({}, data);

      for (let key in oppData) {
        if (oppData.hasOwnProperty(key)) {
          let tempData = [key, oppData[key]];
          this.opportunityData.push(tempData);
        }
      }
    }
    // alert(this.opportunityData);
    if (error) {
      console.log("Chart errior" + error);
    }
  }

Apex:

@AuraEnabled(cacheable=true)
    public static Map<String, decimal> aggregateEmployeeProjectHours(Id loggedinUserId){
        Map<String, decimal> timeSheetHoursMap = new Map<String, decimal>();
        for(AggregateResult aggr : [SELECT Sum(emitCS__Hours__c), emitCS__Project__r.Name FROM emitCS__Time_Sheet_Details__c Group by emitCS__Project__r.Name]) {
            timeSheetHoursMap.put((String)(aggr.get('Name')), (decimal)(aggr.get('expr0')));
        }
        system.debug('timeSheetHoursMap' + timeSheetHoursMap);
        return timeSheetHoursMap;
    }
renderedCallback() {
    // alert("rendered");
    if (!this.chartJSLoaded) {
      // alert("chartJSLoaded" + this.chartJSLoaded);
      loadScript(this, ChartJS)
        .then(() => {
          this.chartJSLoaded = true;

          this.buildChart();
        })
        .catch((error) => {
          this.dispatchEvent(
            new ShowToastEvent({
              title: "Error Loading Chart JS",
              message: error.message,
              variant: "error"
            })
          );           
        });
    }
  }

  buildChart() {
    let canvas = this.template.querySelector("canvas");
    let context = canvas.getContext("2d");
    this.chart = new window.Chart(context, {
      type: "pie",
      data: {
        labels: [
          "Testing CS",
          "Salesforce Implementation",
          "CRM Implementation",
          "Other project"
        ],
        datasets: [
          {
            // label: "# of Votes",
            //data: [12, 19, 3, 5, 2, 3],
            data: [20, 45, 32, 52],
            backgroundColor: [
              "rgba(255, 99, 132, 0.2)",
              "rgba(54, 162, 235, 0.2)",
              "rgba(255, 206, 86, 0.2)",
              "rgba(75, 192, 192, 0.2)"
            ],
            borderColor: [
              "rgba(255, 99, 132, 1)",
              "rgba(54, 162, 235, 1)",
              "rgba(255, 206, 86, 1)",
              "rgba(75, 192, 192, 1)"

            ]

          }
        ]
      },
      options: {

        responsive: true
      }
    });
  }

In the Above Build chart for my testing Purpose i have hard coded the values.

Best Answer

Get the labels and values in separate arrays from the wired method result. Say chartLabels and chartValues. Get those filled using wired result data, and then call the buildChart function.

this.chartLabels = [];
this.chartValues = [];
for (let key in oppData) {
    if (oppData.hasOwnProperty(key)) {
      this.chartLabels.push(key);
      this.chartValues.push(oppData[key]);
    }
}
this.buildChart();

But before that, you need to make some changes to the buildChart function. So it refers to the arrays we created.

buildChart() {
    let canvas = this.template.querySelector("canvas");
    let context = canvas.getContext("2d");
    this.chart = new window.Chart(context, {
      type: "pie",
      data: {
        labels: this.chartLabels,
        datasets: [
          {
            // label: "# of Votes",
            //data: [12, 19, 3, 5, 2, 3],
            data: this.chartValues,
            backgroundColor: [
              "rgba(255, 99, 132, 0.2)",
              "rgba(54, 162, 235, 0.2)",
              "rgba(255, 206, 86, 0.2)",
              "rgba(75, 192, 192, 0.2)"
            ],
            borderColor: [
              "rgba(255, 99, 132, 1)",
              "rgba(54, 162, 235, 1)",
              "rgba(255, 206, 86, 1)",
              "rgba(75, 192, 192, 1)"

            ]

          }
        ]
      },
      options: {

        responsive: true
      }
    });
 }

Optionally you can set the chart colors in the same way.

Related Topic