Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3 - adding grid to simple line chart

In the following simple line chart, I want to add grid to x and y axis. Can someone help me in that?

SNIPPET:

<html>

<head>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.12/angular.min.js"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.min.js"></script>

</head> 

<body ng-app="myApp" ng-controller="myCtrl"> 

    <svg></svg>

    <script>

        //module declaration 
        var app = angular.module('myApp',[]);

        //Controller declaration
        app.controller('myCtrl',function($scope){

            $scope.svgWidth = 800;//svg Width
            $scope.svgHeight = 500;//svg Height 

            //Data in proper format 
            var data = [
                  {"letter": "A","frequency": "5.01"},
                  {"letter": "B","frequency": "7.80"},
                  {"letter": "C","frequency": "15.35"},
                  {"letter": "D","frequency": "22.70"},
                  {"letter": "E","frequency": "34.25"},
                  {"letter": "F","frequency": "10.21"},
                  {"letter": "G","frequency": "7.68"},
            ];

                //removing prior svg elements ie clean up svg 
                d3.select('svg').selectAll("*").remove();

                //resetting svg height and width in current svg 
                d3.select("svg").attr("width", $scope.svgWidth).attr("height", $scope.svgHeight);

                //Setting up of our svg with proper calculations 
                var svg = d3.select("svg");
                var margin = {top: 20, right: 20, bottom: 30, left: 40};
                var width = svg.attr("width") - margin.left - margin.right;
                var height = svg.attr("height") - margin.top - margin.bottom;

                //Plotting our base area in svg in which chart will be shown 
                var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

                //X and Y scaling 
                var x = d3.scaleBand().rangeRound([0, width]).padding(0.4);
                var y = d3.scaleLinear().rangeRound([height, 0]);

                x.domain(data.map(function(d) { return d.letter; }));
                y.domain([0, d3.max(data, function(d) { return +d.frequency; })]);

                //Final Plotting 

                //for x axis 
                g.append("g")
                    .call(d3.axisBottom(x))
                    .attr("transform", "translate(0," + height + ")");

                //for y axis 
                g.append("g")
                    .call(d3.axisLeft(y))
                    .append("text").attr("transform", "rotate(-90)").attr("text-anchor", "end");

                //the line function for path 
                var lineFunction = d3.line()
                    .x(function(d) {return x(d.letter); })
                    .y(function(d) { return y(d.frequency); })
                    .curve(d3.curveLinear);

                //defining the lines
                var path = g.append("path");

                //plotting lines
                path
                    .attr("d", lineFunction(data))
                    .attr("stroke", "blue")
                    .attr("stroke-width", 2)
                    .attr("fill", "none");

        });

    </script> 

</body> 

</html> 

RESULT:

enter image description here

Please, help me in finding how to add grids to the chart on both x and y axis.

like image 830
Deadpool Avatar asked Nov 23 '16 13:11

Deadpool


People also ask

How do you add a grid to a graph?

Click the chart, and then click the Chart Design tab. Click Add Chart Element > Gridlines. Choose the axis that you want to apply the gridlines to or click More Gridline Options to open the Format Major Gridlines pane.

What is the syntax to draw a line in D3?

const svg = d3. select('#svg1'); The value returned by d3. select('#svg1') has functions that are appended in a chaining fashion to further modify the selected SVG element.

What is the use of plot to D3?

Plot represents a chart in its own terms. D3 transforms the native DOM; it describes incremental changes to standard HTML or SVG elements and their attributes. It has no notion of a “bar”, let alone a bar chart, but you can use it to append and transform an SVG <rect> , which serves the role of a bar.


1 Answers

There are two main ways to create the grid lines, one of them is setting innerTickSize to a negative number (see this other answer). The problem with this approach is that you lose the outward ticks. So, I'll explain the second way:

First, set a class for both your axes:

//for x axis 
g.append("g")
     .attr("class", "xAxis")
     .call(d3.axisBottom(x))
     .attr("transform", "translate(0," + height + ")");

 //for y axis 
 g.append("g")
     .attr("class", "yAxis")
     .call(d3.axisLeft(y))
     .append("text").attr("transform", "rotate(-90)").attr("text-anchor", "end");

And then, using these classes, append the lines:

d3.selectAll("g.yAxis g.tick")
    .append("line")
    .attr("class", "gridline")
    .attr("x1", 0)
    .attr("y1", 0)
    .attr("x2", width)
    .attr("y2", 0);

d3.selectAll("g.xAxis g.tick")
    .append("line")
    .attr("class", "gridline")
    .attr("x1", 0)
    .attr("y1", -height)
    .attr("x2", 0)
    .attr("y2", 0);

Here is a demo:

//Data in proper format 
            var data = [
                  {"letter": "A","frequency": "5.01"},
                  {"letter": "B","frequency": "7.80"},
                  {"letter": "C","frequency": "15.35"},
                  {"letter": "D","frequency": "22.70"},
                  {"letter": "E","frequency": "34.25"},
                  {"letter": "F","frequency": "10.21"},
                  {"letter": "G","frequency": "7.68"},
            ];
						
						var width = 500, height = 300;

                //removing prior svg elements ie clean up svg 
                d3.select('svg').selectAll("*").remove();

                //resetting svg height and width in current svg 
                d3.select("svg").attr("width", width).attr("height", height);

                //Setting up of our svg with proper calculations 
                var svg = d3.select("svg");
                var margin = {top: 20, right: 20, bottom: 30, left: 40};
                var width = svg.attr("width") - margin.left - margin.right;
                var height = svg.attr("height") - margin.top - margin.bottom;

                //Plotting our base area in svg in which chart will be shown 
                var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

                //X and Y scaling 
                var x = d3.scaleBand().rangeRound([0, width]).padding(0.4);
                var y = d3.scaleLinear().rangeRound([height, 0]);

                x.domain(data.map(function(d) { return d.letter; }));
                y.domain([0, d3.max(data, function(d) { return +d.frequency; })]);

                //Final Plotting 

                //for x axis 
                g.append("g")
								.attr("class", "xAxis")
                    .call(d3.axisBottom(x))
                    .attr("transform", "translate(0," + height + ")");

                //for y axis 
                g.append("g")
								.attr("class", "yAxis")
                    .call(d3.axisLeft(y))
                    .append("text").attr("transform", "rotate(-90)").attr("text-anchor", "end");
										
										 d3.selectAll("g.yAxis g.tick") 
        .append("line") 
            .attr("class", "gridline")
            .attr("x1", 0) 
            .attr("y1", 0)
            .attr("x2", width)
            .attr("y2", 0);
            
         d3.selectAll("g.xAxis g.tick") 
        .append("line") 
            .attr("class", "gridline")
            .attr("x1", 0) 
            .attr("y1", -height)
            .attr("x2", 0)
            .attr("y2", 0);

                //the line function for path 
                var lineFunction = d3.line()
                    .x(function(d) {return x(d.letter); })
                    .y(function(d) { return y(d.frequency); })
                    .curve(d3.curveLinear);

                //defining the lines
                var path = g.append("path");

                //plotting lines
                path
                    .attr("d", lineFunction(data))
                    .attr("stroke", "blue")
                    .attr("stroke-width", 2)
                    .attr("fill", "none");
.gridline{
stroke: black;
shape-rendering: crispEdges;
stroke-opacity: .2;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
like image 61
Gerardo Furtado Avatar answered Sep 30 '22 14:09

Gerardo Furtado