d3.v3.min.js:1 Error: attribute height: Expected length, “NaN” while loading a d3 chart in a modal popup -- [Question Asked]

Query asked by user

I have been trying to load a bigger size chart in modal popup onClick of smaller chart . I have made the chart responsive by resizing it’s viewbox . But the issue i am now facing is that the first chart is becoming responsive and loading on the main page . But when i am clicking that graph to load a bigger chart in viewbox , i am getting an error d3.v3.min.js:1 Error: attribute height: Expected length, ‚ÄúNaN‚Äù .

And the strange thing is i am using the same directive & same controller for both the charts , for the first chart the viewbox width is giving a value but for other it’s giving NaN .

Any help is appreciated thanks in advance .

var app = angular.module('chartApp', []);

app.controller('TimeReportCtrl', ['$scope', function($scope){

    $scope.reportData={"other_time":0,"ais_time":0,"agendas_time":0,"preps_time":1,"meeting_time":7};

    console.log($scope.reportData.other_time);

    if(($scope.reportData.other_time== 0) && ($scope.reportData.ais_time==0) && ($scope.reportData.agendas_time==0) && ($scope.reportData.preps_time==0) && ($scope.reportData.meeting_time==0))
    {

        $scope.noData = false;
    }
    else
    {
       
        $scope.noData = true;
    }

    $scope.timeReportData=[];

    for(var i in $scope.reportData){

        $scope.timeReportData.push({labelData:i,count:$scope.reportData[i]});
    }

    $scope.timeReport=[];


    for(var i=0;i<$scope.timeReportData.length;i++)
    {   $scope.data=(($scope.timeReportData[i]).labelData);


        switch ($scope.data){

            case "meeting_time":
                $scope.timeReport.push({label:"Meeting Time",count:$scope.timeReportData[i].count});
                break;

            case "ais_time":
                $scope.timeReport.push({label:"ActionItem",count:$scope.timeReportData[i].count});
                break;

            case "agendas_time" :
                $scope.timeReport.push({label:"Agendas Preparation",count:$scope.timeReportData[i].count});
                break;
            case "preps_time":
                $scope.timeReport.push({label:"Meeting Preparation",count:$scope.timeReportData[i].count});
                break;

            case "other_time":
                $scope.timeReport.push({label:"Other",count:$scope.timeReportData[i].count});
                break;

        }

    }
   



}]);





app.directive('timeReport', function($parse, $window){
    return{
        restrict:'EA',

        scope: {data: '=data'},
        link: function(scope, element, attrs) {



            scope.$watch('data', function (data) {

                if (data) {
                    var data = scope.data;
                    var margin = {top: 20, right: 20, bottom: 30, left: 40};
                    var width = 400;
                    var height = 400;
                    var radius = Math.min(width, height) / 2;
                    var donutWidth = 50;
                    var legendRectSize = 16;
                    var legendSpacing = 6;

                    var color = d3.scale.20();
                    var el=element[0];
                    var svg = d3.select(el)
                        .append('svg')
                        .attr('width', width+(margin.right+margin.left))
                        .attr('height', height+(margin.top+margin.bottom))
                        .call(responsivefy)
                        .append('g')
                        .attr('transform', 'translate(' + (width / 2) +
                            ',' + (height / 2) + ')')
                        ;

                    var arc = d3.svg.arc()
                        .innerRadius(radius - donutWidth)
                        .outerRadius(radius);

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

                    var tooltip = d3.select(el)
                        .append('div')
                        .attr('class', 'tooltip');

                    tooltip.append('div')
                        .attr('class', 'label');

                    tooltip.append('div')
                        .attr('class', 'count');

                    tooltip.append('div')
                        .attr('class', 'percent');


                    data.forEach(function (d) {
                        d.count = +d.count;
                        d.enabled = true;                                         // NEW
                    });

                    var path = svg.selectAll('path')
                        .data(pie(data))
                        .enter()
                        .append('path')
                        .attr('d', arc)
                        .attr('fill', function (d, i) {
                            return color(d.data.label);
                        })                                                        // UPDATED (removed semicolon)
                        .each(function (d) {
                            this._current = d;
                        });                // NEW

                    path.on('mouseover', function (d) {
                        var total = d3.sum(data.map(function (d) {
                            return (d.enabled) ? d.count : 0;                       // UPDATED
                        }));
                        var percent = Math.round(1000 * d.data.count / total) / 10;
                        tooltip.select('.label').html(d.data.label);
                        tooltip.select('.count').html(d.data.count);
                        tooltip.select('.percent').html(percent + '%');
                        tooltip.style('display', 'block');
                    });

                    path.on('mouseout', function () {
                        tooltip.style('display', 'none');
                    });

                  

                    var legend = svg.selectAll('.legend')
                        .data(color.domain())
                        .enter()
                        .append('g')
                        .attr('class', 'legend')
                        .attr('transform', function (d, i) {
                            var height = legendRectSize + legendSpacing;
                            var offset = height * color.domain().length / 2;
                            var horz = -2 * legendRectSize;
                            var vert = i * height - offset;
                            return 'translate(' + horz + ',' + vert + ')';
                        });

                    legend.append('rect')
                        .attr('width', legendRectSize)
                        .attr('height', legendRectSize)
                        .style('fill', color)
                        .style('stroke', color)
                        .on('click', function (label) {
                            var rect = d3.select(this);
                            var enabled = true;
                            var totalEnabled = d3.sum(data.map(function (d) {
                                return (d.enabled) ? 1 : 0;
                            }));

                            if (rect.attr('class') === 'disabled') {
                                rect.attr('class', '');
                            } else {
                                if (totalEnabled < 2) return;
                                rect.attr('class', 'disabled');
                                enabled = false;
                            }

                            pie.value(function (d) {
                                if (d.label === label) d.enabled = enabled;
                                return (d.enabled) ? d.count : 0;
                            });

                            path = path.data(pie(data));

                            path.transition()
                                .duration(750)
                                .attrTween('d', function (d) {
                                    var interpolate = d3.interpolate(this._current, d);
                                    this._current = interpolate(0);
                                    return function (t) {
                                        return arc(interpolate(t));
                                    };
                                });
                        });

                    legend.append('text')
                        .attr('x', legendRectSize + legendSpacing)
                        .attr('y', legendRectSize - legendSpacing)
                        .text(function (d) {
                            return d;
                        });



                }

                function responsivefy(svg) {
                    console.log("inside responsivefy");
                    // get container + svg aspect ratio
                    var container = d3.select(svg.node().parentNode),
                        width = parseInt(svg.style("width")),
                        height = parseInt(svg.style("height")),
                        aspect = width / height;
                        console.log("width of container");
                    console.log(width);

                    console.log(container.style("width"));

                    svg.attr("viewBox", "0 0 " + width + " " + height)
                        .attr("perserveAspectRatio", "xMinYMid")
                        .call(resize);



                    d3.select(window).on("resize." + container.attr("id"), resize);

                    // get width of container and resize svg to fit it
                    function resize() {

                        var targetWidth = parseInt(container.style("width"));
                        console.log(targetWidth);
                        svg.attr("width", targetWidth);
                        svg.attr("height", Math.round(targetWidth / aspect));
                    }
                };
            })
        }
    };
});
.tooltip {
    background: #eee;
    box-shadow: 0 0 5px #999999;
    color: #333;
    display: none;
    font-size: 12px;
    left: 130px;
    padding: 10px;
    position: absolute;
    text-align: center;
    top: 95px;
    width: 80px;
    z-index: 10;
}
.legend {
    font-size: 7px;
}
rect {
    cursor: pointer;
    stroke-width: 2;
}
rect.disabled {
    fill: transparent !important;
}
<html>
<head>
    <link rel="stylesheet" href="report.css" type="text/css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" type="text/css">

</head>
<body>


<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-moment/0.10.3/angular-moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script src="script.js"></script>


<div ng-app="chartApp">


    <div class="col-lg-6 col-sm-12" data-toggle="modal" data-target="#myModal" style="
        width: 700px;
    ">


        <div  class="panel panel-default" ng-controller="TimeReportCtrl" ng-show="noData"  style="
        width: 50%;
        height: 50%;
    " >
            <div class="panel-heading">Monthly User Report</div>




            <div   class="panel-body"  >


                <div time-report data="timeReport"></div>

            </div>
        </div>
    </div>

    
    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                    <h4 class="modal-title" id="myModalLabel">Reports</h4>
                </div>

                <div class="modal-footer">
                    <div  class="panel panel-default" ng-controller="TimeReportCtrl" ng-show="noData"  >
                        <div class="panel-heading">Monthly User Report</div>




                        <div   class="panel-body"  >


                            <div time-report data="timeReport"></div>

                        </div>
                    </div>
                </div>
                <!-- /.modal-content -->
            </div>
            <!-- /.modal-dialog -->
        </div>

    </div>
</div>
</body>
</html>

Solution

Try this way.

d3.select(window).on("resize", resize);

// get width of container and resize svg to fit it
function resize() {
    var containerWidth = parseInt(container.style("width"));
    var targetWidth = containerWidth ? containerWidth : parseInt(svg.style("width"));
    console.log(targetWidth);
    svg.attr("width", targetWidth);
    svg.attr("height", Math.round(targetWidth / aspect));
}
var app = angular.module('chartApp', []);

app.controller('TimeReportCtrl', ['$scope', function($scope){

    $scope.reportData={"other_time":0,"ais_time":0,"agendas_time":0,"preps_time":1,"meeting_time":7};

    console.log($scope.reportData.other_time);

    if(($scope.reportData.other_time== 0) && ($scope.reportData.ais_time==0) && ($scope.reportData.agendas_time==0) && ($scope.reportData.preps_time==0) && ($scope.reportData.meeting_time==0))
    {

        $scope.noData = false;
    }
    else
    {
       
        $scope.noData = true;
    }

    $scope.timeReportData=[];

    for(var i in $scope.reportData){

        $scope.timeReportData.push({labelData:i,count:$scope.reportData[i]});
    }

    $scope.timeReport=[];


    for(var i=0;i<$scope.timeReportData.length;i++)
    {   $scope.data=(($scope.timeReportData[i]).labelData);


        switch ($scope.data){

            case "meeting_time":
                $scope.timeReport.push({label:"Meeting Time",count:$scope.timeReportData[i].count});
                break;

            case "ais_time":
                $scope.timeReport.push({label:"ActionItem",count:$scope.timeReportData[i].count});
                break;

            case "agendas_time" :
                $scope.timeReport.push({label:"Agendas Preparation",count:$scope.timeReportData[i].count});
                break;
            case "preps_time":
                $scope.timeReport.push({label:"Meeting Preparation",count:$scope.timeReportData[i].count});
                break;

            case "other_time":
                $scope.timeReport.push({label:"Other",count:$scope.timeReportData[i].count});
                break;

        }

    }
   



}]);





app.directive('timeReport', function($parse, $window){
    return{
        restrict:'EA',

        scope: {data: '=data'},
        link: function(scope, element, attrs) {



            scope.$watch('data', function (data) {

                if (data) {
                    var data = scope.data;
                    var margin = {top: 20, right: 20, bottom: 30, left: 40};
                    var width = 400;
                    var height = 400;
                    var radius = Math.min(width, height) / 2;
                    var donutWidth = 50;
                    var legendRectSize = 16;
                    var legendSpacing = 6;

                    var color = d3.scale.20();
                    var el=element[0];
                    var svg = d3.select(el)
                        .append('svg')
                        .attr('width', width+(margin.right+margin.left))
                        .attr('height', height+(margin.top+margin.bottom))
                        .call(responsivefy)
                        .append('g')
                        .attr('transform', 'translate(' + (width / 2) +
                            ',' + (height / 2) + ')')
                        ;

                    var arc = d3.svg.arc()
                        .innerRadius(radius - donutWidth)
                        .outerRadius(radius);

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

                    var tooltip = d3.select(el)
                        .append('div')
                        .attr('class', 'tooltip');

                    tooltip.append('div')
                        .attr('class', 'label');

                    tooltip.append('div')
                        .attr('class', 'count');

                    tooltip.append('div')
                        .attr('class', 'percent');


                    data.forEach(function (d) {
                        d.count = +d.count;
                        d.enabled = true;                                         // NEW
                    });

                    var path = svg.selectAll('path')
                        .data(pie(data))
                        .enter()
                        .append('path')
                        .attr('d', arc)
                        .attr('fill', function (d, i) {
                            return color(d.data.label);
                        })                                                        // UPDATED (removed semicolon)
                        .each(function (d) {
                            this._current = d;
                        });                // NEW

                    path.on('mouseover', function (d) {
                        var total = d3.sum(data.map(function (d) {
                            return (d.enabled) ? d.count : 0;                       // UPDATED
                        }));
                        var percent = Math.round(1000 * d.data.count / total) / 10;
                        tooltip.select('.label').html(d.data.label);
                        tooltip.select('.count').html(d.data.count);
                        tooltip.select('.percent').html(percent + '%');
                        tooltip.style('display', 'block');
                    });

                    path.on('mouseout', function () {
                        tooltip.style('display', 'none');
                    });

                  

                    var legend = svg.selectAll('.legend')
                        .data(color.domain())
                        .enter()
                        .append('g')
                        .attr('class', 'legend')
                        .attr('transform', function (d, i) {
                            var height = legendRectSize + legendSpacing;
                            var offset = height * color.domain().length / 2;
                            var horz = -2 * legendRectSize;
                            var vert = i * height - offset;
                            return 'translate(' + horz + ',' + vert + ')';
                        });

                    legend.append('rect')
                        .attr('width', legendRectSize)
                        .attr('height', legendRectSize)
                        .style('fill', color)
                        .style('stroke', color)
                        .on('click', function (label) {
                            var rect = d3.select(this);
                            var enabled = true;
                            var totalEnabled = d3.sum(data.map(function (d) {
                                return (d.enabled) ? 1 : 0;
                            }));

                            if (rect.attr('class') === 'disabled') {
                                rect.attr('class', '');
                            } else {
                                if (totalEnabled < 2) return;
                                rect.attr('class', 'disabled');
                                enabled = false;
                            }

                            pie.value(function (d) {
                                if (d.label === label) d.enabled = enabled;
                                return (d.enabled) ? d.count : 0;
                            });

                            path = path.data(pie(data));

                            path.transition()
                                .duration(750)
                                .attrTween('d', function (d) {
                                    var interpolate = d3.interpolate(this._current, d);
                                    this._current = interpolate(0);
                                    return function (t) {
                                        return arc(interpolate(t));
                                    };
                                });
                        });

                    legend.append('text')
                        .attr('x', legendRectSize + legendSpacing)
                        .attr('y', legendRectSize - legendSpacing)
                        .text(function (d) {
                            return d;
                        });



                }

                function responsivefy(svg) {
                    console.log("inside responsivefy");
                    // get container + svg aspect ratio
                    var container = d3.select(svg.node().parentNode),
                        width = parseInt(svg.style("width")),
                        height = parseInt(svg.style("height")),
                        aspect = width / height;
                        console.log("width of container");
                    console.log(width);

                    console.log(container.style("width"));

                    svg.attr("viewBox", "0 0 " + width + " " + height)
                        .attr("perserveAspectRatio", "xMinYMid")
                        .call(resize);



                    d3.select(window).on("resize", resize);

                    // get width of container and resize svg to fit it
                    function resize() {
                        var containerWidth = parseInt(container.style("width"));
                        var targetWidth = containerWidth?containerWidth:parseInt(svg.style("width"));
                        console.log(targetWidth);
                        svg.attr("width", targetWidth);
                        svg.attr("height", Math.round(targetWidth / aspect));
                    }
                };
            })
        }
    };
});
.tooltip {
    background: #eee;
    box-shadow: 0 0 5px #999999;
    color: #333;
    display: none;
    font-size: 12px;
    left: 130px;
    padding: 10px;
    position: absolute;
    text-align: center;
    top: 95px;
    width: 80px;
    z-index: 10;
}
.legend {
    font-size: 7px;
}
rect {
    cursor: pointer;
    stroke-width: 2;
}
rect.disabled {
    fill: transparent !important;
}
<html>
<head>
    <link rel="stylesheet" href="report.css" type="text/css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" type="text/css">

</head>
<body>


<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-moment/0.10.3/angular-moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script src="script.js"></script>


<div ng-app="chartApp">


    <div class="col-lg-6 col-sm-12" data-toggle="modal" data-target="#myModal" style="
        width: 700px;
    ">


        <div  class="panel panel-default" ng-controller="TimeReportCtrl" ng-show="noData"  style="
        width: 50%;
        height: 50%;
    " >
            <div class="panel-heading">Monthly User Report</div>




            <div   class="panel-body"  >


                <div time-report data="timeReport"></div>

            </div>
        </div>
    </div>

    
    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                    <h4 class="modal-title" id="myModalLabel">Reports</h4>
                </div>

                <div class="modal-footer">
                    <div  class="panel panel-default" ng-controller="TimeReportCtrl" ng-show="noData"  >
                        <div class="panel-heading">Monthly User Report</div>




                        <div   class="panel-body"  >


                            <div time-report data="timeReport"></div>

                        </div>
                    </div>
                </div>
                <!-- /.modal-content -->
            </div>
            <!-- /.modal-dialog -->
        </div>

    </div>
</div>
</body>
</html>

Answered By – Gilsha

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0


What is Angular?

Angular is an open-source, JavaScript outline written in TypeScript. Google keeps up with it, and its basic role is to foster single-page activities. As an edge, Angular enjoys clear benefits while likewise outfitting a standard design for formulators to work with. It empowers stoners to deliver huge tasks in a viable way. textures overall lift web improvement viability and execution by outfitting an agreeable construction so that formulators do n't need to continue to modify regulation from scratch. textures are efficient devices that offer formulators a large group of extra elements that can be added to programming easily.

However, is JavaScript ideal for creating single-sprinter activities that bear particularity, testability, and trend-setter efficiency? maybe not.

JavaScript is the most by and large utilized client-side prearranging language. It's composed into HTML reports to empower relations with web sprinters in endless extraordinary ways. As a genuinely simple to-learn language with inescapable help, creating current operations is appropriate.

Nowadays, we have various textures and libraries intended to give essential outcomes. As for front end web advancement, Angular addresses incalculable, while possibly not all, of the issues formulators face while utilizing JavaScript all alone.
Who we are?

We are team of software engineers in multiple domains like Programming and coding, Fundamentals of computer science, Design and architecture, Algorithms and data structures, Information analysis, Debugging software and Testing software. We are working on Systems developer and application developer. We are curious, methodical, rational, analytical, and logical. Some of us are also conventional, meaning we're conscientious and conservative.

Answer collected from stackoverflow and other sources, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0