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
- Create a new empty ASP.NET web project (
AspNetToJs
). Add new web form ShowDataV1.aspx.
- Create a folder "scripts" inside the solution. Add the d3js library in it. I used version 4.
- 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
- 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.
- 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>
- 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">
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)
.on("mouseover", function (d, i) {
var txt = document.getElementById(svg_id + "_txt");
if (txt) {
txt.innerHTML = d.data.label + " (" + d.data.value + ")";
}
});
arcs.append("svg:text")
.attr("transform", function (d) {
d.innerRadius = radius / 2.0;
d.outerRadius = radius;
return "translate(" + arc.centroid(d) + ")";})
.attr("text-anchor", "middle")
.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.
- 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.
var pie_chart_data = [];
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".
- 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);
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.