1

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.

2
  • 1
    What problem you are facing here? Commented May 26, 2020 at 10:52
  • Im not sure how to pass type data and number in the build chart method, please help me in this. Commented May 26, 2020 at 11:25

2 Answers 2

2

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.

5
  • this.chartColor = []; this.chartValues.push("rgba(75, 192, 192, 1)"; Like wise we need to create new array and push the color ? Commented May 26, 2020 at 11:49
  • var x = Math.floor(Math.random() * 256); var y = Math.floor(Math.random() * 256); var z = Math.floor(Math.random() * 256); var bgColor = "rgb(" + x + "," + y + "," + z + ")"; this.chartColor.push(bgColor); Commented May 26, 2020 at 11:53
  • Yes @SFDC_Beginner, you can generate random colors and add them to an array, use refer that array in the chart data. Commented May 26, 2020 at 12:01
  • 1
    Thanks Rahul, It's Working Fine Commented May 26, 2020 at 12:02
  • 1
    @SFDC_Beginner please mark as accepted if it works for you. Commented May 26, 2020 at 12:13
2

You could also consider another approach and use this library

This way you would be able to use the reactivity of the library and only deal with the data fetching on your side

<c-chart
    type="pie"
    responsive="true"
  >
    <c-dataset
      labels={chartLabels}
    >
      <c-data
        label="# of Votes"
        detail={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)"
          ]'
        borderwidth="1"
      ></c-data>
    </c-dataset>
  </c-chart>

Where chartValues and chartLabels are tracked property and set by the buildChart method

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .