Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Pie Chart with d3js - ASP.NET and JavaScript Integration Example

0.00/5 (No votes)
16 Aug 2016 1  
The article is about creating ASP.NET web form, which has d3js pie chart in it.

Introduction

The main purpose is to show how to create a server web page, that sends data to JavaScript visualization function. As there exists demand for interactive diagrams of different types on web pages and client-side js libraries have become better and easier to use, integrating different presentation frameworks in server applications is an important and popular task in web programming. There are a lot of options for this. In this article, the d3js library is used as a visualization tool, and data preparation work is done in ASP.NET web form.

The next part shows how to place d3js pie chart on an ASP.NET web page and initialize it with some data.

Creating an ASP.NET Web Form

  1. Create a new empty ASP.NET web project (AspNetToJs). Add new web form ShowDataV1.aspx.
  2. Create a folder "scripts" inside the solution. Add the d3js library in it. I used version 4.
  3. Add a script manager with reference to d3js. Script manager can be useful if you are going to make your JavaScript part more complex. Or just add script tag in the head section.
    <form id="form1" runat="server">
            <asp:ScriptManager runat="server">
                <Scripts>
                    <asp:ScriptReference Path="~/scripts/d3.min.js" />
                </Scripts>
            </asp:ScriptManager
  4. Identify how to get data from the date source. In this example, I used a collection of objects with the following simple structure:
    public class UserActionsData
        {
            public string ActionCode { get; set; }
            public int ActionCount { get; set; }
            public string ActionDetails { get; set; }
        }

    An array of UserActionsData will be passed to d3js in order to make an interactive pie chart, which displays details about selected slice inside a separate block. Here is some data used in this example:

    List<UserActionsData> sample_data = new List<UserActionsData> {
       new UserActionsData { ActionCode="A1", ActionCount=20, ActionDetails="Description for action 1" },
       new UserActionsData { ActionCode="A2", ActionCount=70, ActionDetails="Description for action 2" },
       new UserActionsData { ActionCode="A3", ActionCount=40, ActionDetails="Description for action 3" },
       new UserActionsData { ActionCode="A4", ActionCount=35, ActionDetails="Description for action 4" },
       new UserActionsData { ActionCode="A5", ActionCount=15, ActionDetails="Description for action 5" }
    };
    

    In real world project, it should be most likely a database query.

  5. Add two placeholders to the web page. Append one HTML element for the pie chart and the other - for details. The page will show details (ActionDetails property) in the separate HTML element (div with id = svg_panel_txt) when mouse is placed over the specified sector.
    <div>
       <svg id="svg_panel" width="280" height="280"></svg>
       <div id="svg_panel_txt"></div>
    </div>
  6. Add client-side visualization code, which will build the pie chart. The following script should be inserted in the head tag:
     <script type="text/javascript">
    // svg_id - id of target svg 
    // data - array of objects {label, value}
            function drawPieChartSVG(svg_id, data) { 
                var svg = document.getElementById(svg_id); 
                var width = svg.width.baseVal.value, 
                    height = svg.height.baseVal.value, 
                    radius = Math.min(width, height) / 2; 
                var colors = d3.scaleOrdinal(d3.schemeCategory10); 
                var arc = d3.arc() 
                    .outerRadius(radius - 10) 
                    .innerRadius(0) 
                    .padAngle(0.03); 
    
                var pie = d3.pie().value(function (d) { return d.value; }); 
                var root = d3.select("#" + svg_id) 
                    .datum(data) 
                    .attr("width", width) 
                    .attr("height", height) 
                    .append("g") 
                    .attr("transform", 
                    "translate(" + width / 2.0 + "," + height / 2.0 + ")"); 
    
                var arcs = root 
                    .selectAll("g.slice") 
                    .data(pie) 
                    .enter() 
                    .append("g") 
                    .attr("class", "slice"); 
    
                arcs 
                .append("path") 
                .attr("fill", function (d, i) { return colors(i); }) 
                .attr("d", arc) 
    
    // show details in the separate html element when mouse is over the specified sector
                .on("mouseover", function (d, i) { 
                    var txt = document.getElementById(svg_id + "_txt"); 
                    if (txt) { 
                        txt.innerHTML = d.data.label + " (" + d.data.value + ")"; 
                    } 
                }); 
    
    // place labels on the chart
                arcs.append("svg:text") 
                    .attr("transform", function (d) { 
                            d.innerRadius = radius / 2.0; 
                            d.outerRadius = radius; 
    // text will be inserted in the center of the current section
    
                            return "translate(" + arc.centroid(d) + ")";}) 
                    .attr("text-anchor", "middle") 
    
    // d.data - our data item, assigned to the current section. "label" is a part of our data object
                    .text(function (d, i) { return d.data.label; }); 
            }
    
        </script>

    Function drawPieChartSVG creates a new chart inside svg element with id svg_id from array "data". This code was created with the help of one example from d3js website.

  7. By now, there should be no build or runtime errors. If everything is ok, add data preparation code, which creates a collection of objects, each representing one slice. To make this data accessible to our visualization function, we will add a JavaScript variable, assign JSON string to it and then pass it to the function.
    //data for the pie chart
     var pie_chart_data = [];
    
    //draw the pie chart
     function updateChart() {
         drawPieChartSVG("svg_panel", pie_chart_data);        
    }

    Add another code after scriptmanager tag to call updateChart after all scripts have been loaded.

    <script type="text/javascript">
                Sys.Application.add_load(updateChart);
    </script>

    Sys.Application is ASP.NET Ajax client-side application object.

    As stated in MSDN, "Sys.Application is an object that exposes client events and manages client components that are registered with the application. The members of this object are available globally after the client application has been initialized".

  8. There are several ways to inject JavaScript in HTML page from code behind. We will assign value to the variable by means of JavaScript, prepared in C#.
    Code behind:
    protected void Page_Load(object sender, EventArgs e)
    {
         var serializer = new JavaScriptSerializer();
         var str_sample_data = serializer.Serialize(sample_data);
    
    // add script tag to the page
         this.ClientScript.RegisterClientScriptBlock(this.GetType(), 
              "mydata", "<script>pie_chart_data = " + str_sample_data + ";</script>");
    }

The generated JavaScript code will be appended before UI elements. As a result, data will be ready by the moment of updateChart function call.

Customizing the Way the Pie Chart Reads Data

Now let's change JavaScript code to make it read data correctly.

Define which field holds size of each slice. It is "ActionCount". Change this line:

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

to this one to make it compatible with our data:

var pie = d3.pie().value(function (d) { return d.ActionCount; });

Replace line:

.text(function (d, i) { return d.data.label; }); 

with this:

.text(function (d, i) { return d.data.ActionCode; }); 

mouseover event handler should look like:

function (d, i) { 
                var txt = document.getElementById(svg_id + "_txt"); 
                if (txt) { 
                    txt.innerHTML = d.data.ActionDetails + " (" + d.data.ActionCount + ")";
                } 
            }

Result

Run the web form. The expected result is shown below:

<img alt="" src="http://www.codeproject.com/KB/Articles/1118518/aspnet_to_js.PNG" style="height: 281px; width: 250px;" />

Conclusion

The new version of d3js is surprisingly different from the previous edition.

Though this pie chart was built right after loading the webpage, d3js diagrams can be dynamically updated in runtime as well.

Instead of calling ClientScript.RegisterClientScriptBlock, it is possible to get the same effect by passing script tag to Text attribute of asp:Label control element.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here