import { LightningElement ,track,wire,api} from 'lwc';
import { loadScript } from 'lightning/platformResourceLoader';
import HIGHCHARTS from "@salesforce/resourceUrl/D3chartjs";
import partnerSpendData from '@salesforce/apex/AccountSnapshot_Partnerdetails.getAccSnapshotPartnerDetailNew';
export default class AccountPieChart extends LightningElement {
@track error;
@track data;
@api recordid;
chartResourcesLoaded=false;
@wire(partnerSpendData, {accountId : '$recordid'})
partnerSpend({error,data}){
if(data){
this.data = data.map(record => {
return {
y: record.data,
name: record.Name
}
});
console.log("++++Data++++",data);
this.error=undefined;
this.runHighcharts();
}
else if (error) {
this.error = error;
this.partnerSpend = undefined;
}
}
renderedCallback() {
loadScript(this, HIGHCHARTS + "/highcharts.js")
.then(() => {
console.log("SUCCESS: highcharts.js");
loadScript(this, HIGHCHARTS + "/highcharts-3d.js")
.then(() => {
console.log("SUCCESS: highcharts.js");
loadScript(this, HIGHCHARTS + "/exporting.js")
.then(() => {
console.log("SUCCESS: exporting.js");
loadScript(this, HIGHCHARTS + "/export-data.js")
.then(() => {
console.log("SUCCESS: export-data.js");
// this.runHighcharts();
loadScript(this, HIGHCHARTS + "/accessibility.js")
.then(() => {
console.log("SUCCESS: accessibility.js");
this.chartResourcesLoaded = true;
this.runHighcharts();
})
.catch(error => console.log("ERROR: accessibility.js"));
})
.catch(error => console.log("ERROR: export-data.js"));
})
.catch(error => console.log("ERROR: exporting.js"));
})
.catch(error => console.log("ERROR: highcharts-3d.js"));
})
.catch(error => console.log("ERROR: highcharts.js"));
}
runHighcharts() {
if(this.chartResourcesLoaded && this.data){
const containerId = this.template.querySelector('div').id;
console.log('containerId: ',containerId);
let container = this.template.querySelector('.chartContainer')
console.log('data: ',this.data);
Highcharts.chart(container, {
chart: {
type: 'pie',
options3d: {
enabled: true,
alpha: 45,
beta: 0
}
},
title: {
text: 'Browser market shares in January, 2018'
},
credits: {
enabled: false
},
exporting: {
enabled: false
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
accessibility: {
point: {
valueSuffix: '%'
}
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
depth : 35,
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.percentage:.1f} %'
}
}
},
series: [{
type: 'pie',
data: this.data
}],
}
);
}
}
}
-
Are you getting the data from the apex code in the required format of HightCharts?– Rahul GawaleCommented Oct 6, 2020 at 8:55
-
yes. I am getting data in json format. my question is how i can pass the data from wire method to chart because if i am trying to access data outside wire then it is showing undefined in log.– SFDC PersonCommented Oct 6, 2020 at 9:28
1 Answer
I think its just a sequence issue. The chart seems to be rendered before you get the data from the wired apex method.
You need to make sure that before you render the chart, scripts and the data are loaded.
Also, you need to make sure that the chart resources are loaded only once. For that, you need to set a property when the loading is complete.
So in the innermost loadScript
call create and set a flag chartResourcesLoaded
to true.
...
loadScript(this, HIGHCHARTS + "/accessibility.js")
.then(() => {
this.chartResourcesLoaded = true;
this.runHighcharts();
}
...
Now, you also need to make sure that the code in the runHighcharts()
function does not run until you get the data from the wired call. So wrap that code in if
condition like below.
runHighcharts() {
if(this.chartResourcesLoaded && this.data){
// all your existing code
}
}
Also please note that you are using a wrong query selector to get the container of the chart.
this.template.querySelector('div')
With the above, you are never sure which div you are querying. So instead of using the generic selector, add a class(say chart-container
) to the div in which you want to render the chart and use the class selector like below.
this.template.querySelector('.chart-container')
Update You need to convert the data in the below format.
data: [{
name: 'Chrome',
y: 61.41,
sliced: true,
selected: true
}, {
name: 'Internet Explorer',
y: 11.84
}]
Which you can do using the below code. note that I have used array.map function to convert the data format.
@wire(AccountDataNew, {accountId : '$recordid'})
AccountData({error,data}){
if(data){
this.data = data.map(record => {
return {
y: record.data,
name: record.Name
}
});
console.log("++++Data++++",data);
this.error=undefined;
this.runHighcharts();
}
else if (error) {
this.error = error;
this.partnerSpend = undefined;
}
}