2

Why can not I draw a circle with d3.js in a lightning component?

appl.app:

<aura:application >
    <c:libComp/>
</aura:application>

comp.cmp:

<aura:component>
    <ltng:require scripts="{!$Resource.d3Lib}"
                  afterScriptsLoaded="{!c.drawACircle}" />
</aura:component>

compController.js:

({
    drawACircle: function () {
        //Make an SVG Container
        var svgContainer = d3.select("body").append("svg")
                                            .attr("width", 200)
                                            .attr("height", 200);

        //Draw the Circle
        var circle = svgContainer.append("circle")
                                 .attr("cx", 30)
                                 .attr("cy", 30)
                                 .attr("r", 20)
    }
});

According to this I am doing everything correctly.

But here is the error message:

Uncaught TypeError: Cannot read property 'document' of undefined throws at https://oobarbazanoo-dev-ed.lightning.force.com/resource/1527188162000/d3Lib:15:4187

enter image description here

In the d3Lib I put all that is written over here.

4
  • adding some debug info would probably help your cause and others to better help you
    – glls
    May 24, 2018 at 18:40
  • Cannot read document, it looks like D3 was trying to manipulate DOM, May 24, 2018 at 19:22
  • @PranayJaiswal, yeah. What can I do about it? May 24, 2018 at 19:33
  • 1
    Ah, looks like I misread the error. I mistakenly though it was happening in your controller. As it stands, that error likely means that the version of D3 you're using isn't compatible with Locker Service. Try using an older version, or a newer version, or honestly, just write your own SVG code if all you need is a small handful of features.
    – sfdcfox
    May 24, 2018 at 19:52

1 Answer 1

4

You can use lightning: container to accomplish this. Lightning:container was designed to use 3rd party libraries which are not locker service friendly in lightning components.

HTML file:

<html>
<head>
<script src="d3.v3.min.js"></script>

</head>

<body>
MyBody
</body>

<script src="use.js"></script>
</html>

use.js

var svgContainer = d3.select("body").append("svg")
                                .attr("width", 200)
                                .attr("height", 200);

//Draw the Circle
var circle = svgContainer.append("circle")
                     .attr("cx", 30)
                     .attr("cy", 30)
                     .attr("r", 20);

console.log(svgContainer);
console.log('circel drawn');

Manifest file for CSP:

{
    "landing-pages" : [
        {
            "path": "home.html",
            "content-security-policy-type": "Minimum"
        }
    ]
 }

and finnally the downloaded D3js file,refrenced in HTMl.

Create a zip of all those 4 files and upload as a static resouces named as "d3Demo".

enter image description here

And then in you lightning component/application refer the lightning:container as

<aura:application >
    <lightning:container src="{!$Resource.d3Demo+'/home.html'}" />

</aura:application>

Thasts it done. D3js in lightning components, no need to worry about locker services.

Source:https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/container_overview.htm

You must log in to answer this question.

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