How to create charts using D3 Library in Lightning Components

D3.js is the most popular library for creating interactive charts in any web application. You can also use D3.js library in Lightning components for graphical representation of data. These charts can be used to give sales insights to a member ( Salesforce user) of the sales team.  This article will show how can we leverage D3.js to build charts with a simple example.

First, let’s see the component code.

D3Charts.cmp

Screenshot_2

D3ChartsController.js
({
    initD3Charts : function(component, event, helper) {

        var width = 960;
        var height = 500;

        // Create SVG element, we can't just use  tag in lightning component
        // So creating one dynamically using jquery
        var svg = d3.select("body")
        .append("svg")
        .attr("width", width)
        .attr("height", height);	

        // Calling server-action to get the data
        var action = component.get("c.getData");

        // Create a callback that is executed after
        // the server-side action returns
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                let data = response.getReturnValue();
                console.log(data);
                // Render the returned data as a pie chart
                helper.renderChart( component, data );
            }
            else if(state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " +
                                    errors[0].message);
                    }
                } else {
                    console.log("Unknown error");
                }
            }
        });

        $A.enqueueAction(action);

    }
})
D3ChartsHelper.js
({
    renderChart : function( component, data ) {
        var svg = d3.select("svg"),
            width = +svg.attr("width"),
            height = +svg.attr("height"),
            radius = Math.min(width, height) / 2,
            g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

        var color = d3.scaleOrdinal(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

        var pie = d3.pie()
        .sort(null)
        .value(function(d) { return d.candidates; });

        var path = d3.arc()
        .outerRadius(radius - 10)
        .innerRadius(0);

        var label = d3.arc()
        .outerRadius(radius - 80)
        .innerRadius(radius - 80);

        var arc = g.selectAll(".arc")
        .data(pie(data))
        .enter().append("g")
        .attr("class", "arc");

        arc.append("path")
        .attr("d", path)
        .attr("fill", function(d) { return color(d.data.age); });

        arc.append("text")
        .attr("transform", function(d) { return "translate(" + label.centroid(d) + ")"; })
        .attr("dy", "0.35em")
        .text(function(d) { return d.data.age; });
    }
})

So, we have included d3.js library along with jquery.js and then called a server-side action when the script has loaded in order to fetch the chart data. In the defined callback function we passed that data to a helper function which rendered the chart.

D3ChartsController.apex
public class D3ChartsController {
  
    @AuraEnabled
    public static List getData(){
      
        // For this example, it's just a static data but it can be generated 
        // as per any business logic
        List lstData = new List();
        lstData.add( new PieChart( '=65', 61 ) );
        return lstData;
    }
    
    public class PieChart {
        @AuraEnabled public String age;
        @AuraEnabled public Integer candidates;
        
        public PieChart( String age, Integer candidates ) {
            this.age = age;
            this.candidates = candidates;
        }
    }
}
Screenshot_4
Preview

Reference to resources –

 

5 thoughts on “How to create charts using D3 Library in Lightning Components

  1. Hi Naval,
    Thanks for the example.
    However, I have a problem.
    The afterScriptsLoaded=”{!c.initD3Charts}” isn’t being called/actioned.
    I can’t see why.
    Any suggestions?

  2. I found a way to ‘tag’ to a thanks to joshbirk at https://gist.github.com/joshbirk/08be97d92b91c3bdc9e1
    It seems D3 can select a if the name is prefixed with a ‘#’ sign.

    add a div to your component:

    then replace the dynamic scalable vector graphic creation with new code:

    /*
    var svg = d3.select(“body”)
    .append(“svg”)
    .attr(“width”, width)
    .attr(“height”, height);
    */
    var svg = d3.select(“#diagram”).append(“svg”)
    .attr(“width”, width)
    .attr(“height”, width)
    .attr(“preserveAspectRatio”, “xMidYMid”)
    .attr(“viewBox”, “-50 -50 1200 1200”);

    nb: there’s a couple of extra attributes there that look fun and will need more research!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.