D3.js is a JavaScript library for manipulating documents based on data (creating data visualizations in the browser). D3.js helps you bring data to life using HTML, SVG, and CSS.

D3 allows you to bind arbitrary data to a Document Object Model (DOM), and then apply data-driven transformations to the document. For example, you can use D3 to generate an HTML table from an array of numbers. Or, use the same data to create an interactive SVG bar/pie chart with smooth transitions and interaction.

D3 is built on top of several common web standards like HTML, SVG, The DOM, and CSS.

Different Aspects of D3 JS

SVG: Scalable Vector Graphics is an XML format used for drawing. You can think of SVG in a lot of the same terms as the DOM – there are elements with parents and children and attributes, and you can respond to the same mouse/touch events.

SVG defines tags for lots of basic shapes, like <rect> and <circle> and <line>.

Example:

    <svg width="300" height="150">

    <circle cx="30"  cy="50" r="25" />

     <rect x="10"  y="80" width="40" height="40"  fill="steelBlue" />

      </svg>

SVG has the <g> tag for an arbitrary group .The <text> tag is good for simple labels. The <path> tag is powerful but complex, it can be used for either lines or arbitrary filled-in shapes depending on the styling.

    <svg width="300" height="180">

       <g transform="translate(5, 15)">

              <text x="0" y="0">Howdy!</text>

   </g>

        <g transform="translate(5, 55)">  /*Path is used mostly in Pie chart*/

       <path d="M0,50 L50,0 Q100,0 100,50" fill="none" stroke-width="3" stroke="black" />

               </g>

</svg>

Scales: D3 has objects called scales that help map values across coordinate systems. There are different kinds of scales (linear, logarithmic, linear for time). Scales are configured with a domain and a range, they map from the data to the approprate part of the screen (screen space).

Example:

var x0 = d3.scale.ordinal().rangeRoundBands([0, width], .1);

var x1 = d3.scale.ordinal();

                  var y = d3.scale.linear().range([height, 0]);

Axes:  We can build an axis, and apply it to a scale.

Example:

var xAxis = d3.svg.axis().scale(x0).orient("bottom");

var yAxis = d3.svg.axis().scale(y).orient("left").ticks(10)  .tickFormat(d3.format(".2s"));

 

Data Binding and its Different Aspects

We can bind data like Json/CSV etc.

Selections: (d3.selectAll())

D3 selections are a group of elements that match a query.

d3.select (String selector) -> (d3.selection)

Joins: selection.data ()

Selections are used to map pieces of our data to elements in the DOM.

Example:

var json_data =[{region_cd: "AFR", region_name: "Africa", kpi_max_target_val: 95}

              {region_cd: "SAM", region_name: "South America", kpi_max_target_val: 80}

              {region_cd: "NAM", region_name: "Northern America",kpi_max_target_val: 89}]

Each object in this array to turn into a <rect> tag, inside of our <svg>

<svg>

<rect />

<rect />

<rect />

</svg>

use .data() to bind our data to the selection.

var bar = svg.selectAll(“.bar”)

.data(json_data)

.enter().append(“g”)

.attr(“class”, “rect”)

.attr(“width”, rect_width)

Adding Elements: selection.enter ()

The part of a D3 selection that represents these element-less data-points is selection.enter ();

var newRects = rects.enter();

Transitions: selection.transition ()

One of D3’s most visually pleasing features is its ability to help with transitions.

Examples of bar graph by Ajax call on return Json data:

Examples of bar graph by Ajax call on return Json dataHTML:

<div class="well well-sm" id=" div_body " style="height: auto">

                               </div>

Ajax call:

$.ajax({

           url: "Controller/GetGraph",

           dataType: "json",

           contentType: "application/json",

           type: "POST",

           datatype: "json",

           data: JSON.stringify({ data: data}),

           success: function (data, e) {

               //var margin = {top: 5, right: 10, bottom: 10, left: 10}

               var margin = { top: (parseInt(d3.select(' #div_body ').style('width'), 10) / 10), right: (parseInt(d3.select(' #div_body ').style('width'), 10) / 20), bottom: (parseInt(d3.select(' #div_body ').style('width'), 10) / 5), left: (parseInt(d3.select(' #div_body ').style('width'), 10) / 20) },

                   width = parseInt(d3.select(' #div_body ').style('width'), 10) - margin.left - margin.right,

                   //height = 500 - margin.top - margin.bottom;

                   height = (parseInt(d3.select(' #div_body ').style('height')) - 70);

               var rect_width = 0;

               var x0 = d3.scale.ordinal()

                   .rangeRoundBands([0, width], .1);

               var x1 = d3.scale.ordinal();

               var y = d3.scale.linear()

                   .range([height, 0]);

               var colorRange = d3.scale.category20();

               var color = d3.scale.ordinal()

                   .range(colorRange.range());

               var xAxis = d3.svg.axis()

                           .scale(x0)

                           .orient("bottom");

               var yAxis = d3.svg.axis()

                   .scale(y)

                   .orient("left").ticks(10)

                   .tickFormat(d3.format(".2s"));

               var tooltip = d3.select("#div_body ").append("div").attr("class", "toolTip");

               var svg = d3.select("#div_body ").append("svg")

                         .attr("width", width + margin.left + margin.right)

                         .attr("height", height + margin.top + margin.bottom)

                         .append("g")

                         .attr("transform", "translate(" + 30 + "," + 30 + ")");

               var jsonData = data.aaData;

               var obj = JSON.parse(formattedJson);

               var maxIndex = obj.map(function (a) { return JSON.stringify(a).length; }).indexOf(Math.max.apply(Math, obj.map(function (a) { return JSON.stringify(a).length; })));

               var supplierNames = d3.keys(obj[maxIndex]).filter(function (key) { return (key != 'region_name' && key != 'max_target_val'); });

               obj.forEach(function (d) {

                   d.valores = supplierNames.map(function (name) { return { name: name, value: +d[name] }; });

               });

               rect_width = (width / obj.length) - 10;

               x0.domain(obj.map(function (d) { return d.region_name; }));

               x1.domain(supplierNames).rangeRoundBands([0, x0.rangeBand()]);

               y.domain([-1, d3.max(obj, function (d) { return d3.max(d.valores, function (d) { return 100; }); })]);

               svg.append("g")

                .attr("class", "x axis")

                .attr("transform", "translate(0," + height + ")")

                .call(xAxis);

               svg.append("g")

                .attr("class", "y axis")

                .attr("id", "air_svg")

                .call(yAxis)

                .append("text")

                .attr("transform", "rotate(-90)")

                .attr("y", 6)

                .attr("dy", ".71em")

                .style("text-anchor", "end")

                .text("Targets");

               var bar = svg.selectAll(".bar")

               .data(obj)

               .enter().append("g")

               .attr("class", "rect")

               .attr("width", rect_width)

               .attr("transform", function (d) { return "translate(" + x0(d.region_name) + ",0)"; });

               bar.selectAll("rect")

                 .data(function (d) { return d.valores; })

                 .enter().append("rect")

                 .attr("width", x1.rangeBand())//  x1.rangeBand()

                 .attr("x", function (d) { return x1(d.name); })

                 .attr("y", function (d) {

                     if (isNaN(d.value)) {

                         return "";

                     } else {

                         return y(d.value);

                     }

                 })

                 .attr("value", function (d) { return d.name; })

                 .attr("height", function (d) {

                     if (isNaN(d.value)) {

                         return "";

                     } else {

                         return height - y(d.value);

                     }

                     // return height - y(d.value);

                 })

                 .style("fill", function (d) { return color(d.name); });


               //For target value displaying on the top of each the bargraph

               bar.selectAll("text")

                   .data(function (d) { return d.valores; })

                  .enter().append("text")

                  .attr("class", "textlabel")

                  .attr("x", function (d) { return x1(d.name) + (x1.rangeBand() / 2); })

                  .attr("y", function (d) {

                      if (isNaN(d.value)) {

                          return "";

                      } else {

                          return y(d.value);

                      }

                  })

                  .text(function (d) {

                      if (isNaN(d.value)) {

                          return "";

                      } else {

                          return d.value + " %";

                      }

                  });

               //For line showing for max target

               var median = bar.append("line")

                                   .attr("x1", 0)

                                   .attr("y1", function (d) { return y(d.max_target_val) })

                                   .attr("x2", rect_width - 10)

                                   .attr("y2", function (d) { return y(d.max_target_val) })

                                   .attr("stroke-width", 2)

                                   .attr("stroke", "black").on("mousemove", function (d) {

                                       tooltip.style("left", d3.event.pageX - 50 + "px")

                                              .style("top", d3.event.pageY - 70 + "px")

                                              .style("display", "inline-block")

                                              .html("Max Target Value: " + "<br>" + d.max_target_val);

                                   })

                                   .on("mouseout", function (d) { tooltip.style("display", "none"); });

               //For legend

               var offset = 0;

               var legendBlockWidth = 15;

               var textMargin = 3;

               var legend = svg.selectAll('.legend')

                   .data(supplierNames.slice())

                   .enter().append('g')

                   .attr("class", "legend")

                   .each(function (key, i) {

                       var item = d3.select(this);

                       var text = item.append('text')

                           .attr("x", 20)

                             .attr("y", 10)

                         .text(key).attr("class", "textselected")

                           .style("text-anchor", "start")

                           .style("font-size", 12);

                       var rect = item.append('rect')

                                   .attr("x", 0)

                                   .attr("y", 0)

                                   .attr("width", 10)

                                   .attr("height", 10)

                                   .style("fill", color);

                       item.attr('transform', function () {

                           return 'translate(' + offset + ',-30)';

                       });

                       // Update the offset

                       offset += text.node().getBBox().width + legendBlockWidth + textMargin * 3;

                   });

           },

           error: function () {

               var msg = ['No records found'];

               showMessage('warn', msg, 2000);

               return false;

           }

       });

Example of Pie chart:

Example of Pie chart  $.ajax({

url: "/controller/GetPieGraph",

dataType: "json",

contentType: "application/json",

type: "POST",

datatype: "json",

data: JSON.stringify({ mode: mode }),

success: function (data, e) {

// Define the margin, radius, and color scale. Colors are assigned lazily, so

// if you want deterministic behavior, define a domain for the color scale.

var m = 10,

r = 100,

z = d3.scale.category20c();

var colorRange = d3.scale.category20();

var color = d3.scale.ordinal()

.range(colorRange.range());

// Define a pie layout: the pie angle encodes the count of flights. Since our

// data is stored in CSV, the counts are strings which we coerce to numbers.

var pie = d3.layout.pie()

.value(function (d) { return +d.kpi_target_val; })

.sort(function (a, b) { return b.kpi_target_val - a.kpi_target_val; });

// Define an arc generator. Note the radius is specified here, not the layout.

var arc = d3.svg.arc()

.innerRadius(r / 1.5)

.outerRadius(r);

// Nest the flight data by originating airport. Our data has the counts per

// airport and carrier, but we want to group counts by airport.

var obj_data = data.aaData;

var region = d3.nest()

.key(function (d) { return d.region_name; })

.entries(obj_data);

var supliers = d3.nest()

.key(function (d) { return d.splr_name; })

.entries(obj_data);

var offset = 0;

var legendBlockWidth = 15;

var textMargin = 3;

//.append("div")

var svg = d3.select("#div_body")

.append("svg")

.attr("height", 50)

.attr("width", "300%")

.append("g")

.attr("transform", "translate(" + 30 + "," + 30 + ")");

var legend = svg.selectAll('.legend')

.data(supliers.slice())

.enter().append('g')

.attr("class", "legend")

.each(function (key, i) {

var item = d3.select(this);

var text = item.append('text')

.attr("x", 20)

.attr("y", 10)

.text(key.key).attr("class", "textselected")

.style("text-anchor", "start")

.style("font-size", 12);

var rect = item.append('rect')

.attr("x", 0)

.attr("y", 0)

.attr("width", 10)

.attr("height", 10)

.style("fill", function (d) {

return z(d.key);

});

item.attr('transform', function () {

return 'translate(' + offset + ',-30)';

});

// Update the offset

offset += text.node().getBBox().width + legendBlockWidth + textMargin * 3;

});

var svg = d3.select("#div_body").selectAll("div")

.data(region)

.enter().append("div")

.style("display", "inline-block")

.style("width", (r + m) * 2 + "px")

.style("height", (r + m) * 2 + "px")

.append("svg")

.attr("width", (r + m) * 2)

.attr("height", (r + m) * 2)

.append("g")

.attr("transform", "translate(" + (r + m) + "," + (r + m) + ")");

// Add a label for the airport. The `key` comes from the nest operator.

svg.append("text")

.attr("dy", ".35em")

.attr("text-anchor", "middle")

.text(function (d) { return d.key; });

// Pass the nested per-airport values to the pie layout. The layout computes

// the angles for each arc. Another g element will hold the arc and its label.

var g = svg.selectAll("g")

.data(function (d) {

return pie(d.values);

})

.enter().append("g");

// Add a colored arc path, with a mouseover title showing the count.

g.append("path")

.attr("d", arc)

.style("fill", function (d) {

return z(d.data.splr_name);

})

.append("title")

.text(function (d) { return d.data.splr_name + " : " + d.data.kpi_target_val + " %"; });

// Add a label to the larger arcs, translated to the arc centroid and rotated.

g.filter(function (d) { return d.endAngle - d.startAngle > .2; }).append("text")

.attr("dy", ".35em")

.attr("text-anchor", "middle")

.attr("transform", function (d) { return "translate(" + arc.centroid(d) + ")rotate(" + angle(d) + ")"; })

.text(function (d) { return (d.data.kpi_target_val + "%"); });

// Computes the label angle of an arc, converting from radians to degrees.

function angle(d) {

var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;

return a > 90 ? a - 180 : a;

}

},

error: function () {

var msg = ['No records found'];

showMessage ('warn', msg, 2000);

return false;

}

});

This Article is presented by ESSPL: IT Services and Solutions, If you have any suggesions then please mention it in comment box below.