0

I have created a directive named ng-chart as:

(function () {
'use strict';
angular
    .module('app')
    .directive('ngChart', ['$http', '$compile', 'DashboardService', '$q', '$timeout', '$modal', 'FlashService', function ($http, $compile, DashboardService, $q, $timeout, $modal, FlashService) {

        return {
            restrict: 'E',
            scope:
            {
                chartObj: "=?"
            },
            template: "<div style='position:relative;'>" +
                "<span style='position:absolute;top:0px;right: 27px;' id='spanMaxRestore' title='Maximize' ng-click='btnResizeClick()'><img style='width:18px;' src='../Dashboard/Images/bakupRestore.png' alt='Restore'/></span>" +
                "<span style='position:absolute;top:0px;right: 50px;' title='Configure' ng-click='btnSettingClick()'><img style='width:18px;' src='../Dashboard/Images/setting.png' alt='Configure'/></span>" +
                "<span style='position:absolute;top:0px;right:0px;' title='Close' onclick='this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode); return false;'><img src='/precisioncare/Dashboard/Images/dialog_close.png' alt='close chart'/></span><br/>" +
                "<div style='position:absolute; width:400px;'><img src='data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA=='/></div>" +
                "</div>",

            link: function (scope, iElement, iAttrs, ctrl)
            {
                scope.iElement = iElement;
                $(iElement).on('resize', function () {
                    scope.resize(iElement);
                });

                $(iElement).resizable();
                $(iElement).draggable();

                alert(scope.chartObj.dashUserElementId);

                scope.$watch('chartObj', function (chartData) {

                    if (chartData != "" && chartData != undefined) {
                        $timeout(function () {

                            var elem_id = scope.chartObj.dashUserElementId; //Element id.
                            var elem_data_source = scope.chartObj.dashUserElementDataSource; //Data query to retrive the data from database.
                            var displaytypeid = scope.chartObj.dashUserElementConfigDisplayTypeId; // Display type id of current element.


                            var divContainer = iElement.find('div');
                            scope.containerToDisplay = divContainer[1];
                            var dataObject = JSON.stringify({ "element_id": elem_id, "dataquery": elem_data_source, "Configurable": scope.chartObj.dashuserelement_date_range_origin });
                            //Return data series, Query parameter, and column name.
                            DashboardService.drawDashboardElement("getElementDataQuery", dataObject).then(function (response) {
                                var resultD = JSON.parse(response.d);
                                //If result is not empty then call drawChart method with passing parameter ResultD , displaytypeId and container to display.
                                if (resultD != undefined && resultD != "")
                                    scope.drawChart(resultD, displaytypeid, scope.containerToDisplay, elem_id);
                            },
                            function (error) {
                                // promise rejected, could log the error with: 
                                console.log('error', error);
                            });

                        }, 0);
                    }

                });

            },
            controller: function ($scope) {

                $scope.drawChart = function (resultD, displaytypeid, divId,elementId) {}  // some other charting code/functions here   }  }]); })();

The above snippet is of my directive which are called on my html view using ng-repeater as

<div ng-controller="DashboardController" style="width:100%; height:100%;">
    <div id="divChart" style="width:100%;" class="clearFloat">
        <ng-chart ng-repeat="adelement in UserConfigList" chart-obj="adelement" style='display: inline-block; margin: 20px; width: 400px; height: 450px; background-color: white'>
         </ng-chart>
    </div>  </div>

Now What i want to achieve is I want to add one more chart to my dashboard at runtime on charts series click event(I have used Highchart.js) for the same. So if user drags in or clicks on any section of the pie chart I want to draw one more ng-chart at runtime. here is what I am trying:

    var template = "<ng-chart chart-obj="+ $scope.chartObj +" style='display: inline-block; margin: 20px; width: 400px; height: 450px; background-color: white'></ng-chart>";

    var newElement = $compile(template)($scope);

    $("#divChart").append(newElement);

    $scope.insertHere = newElement;

But this does not seems to be working,anything missing/wrong in the code above ? I want to pass chart-Obj available in the current scope of the directive to new directive of same type(ng-chart)

1 Answer 1

1

You're making one tiny mistake, angular doesn't $compile your object variable. Instead it looks for the variable on the scope by referencing it.

So your fix would be:

var template = '<ng-chart chart-obj="chartObj" style="display: inline-block; margin: 20px; width: 400px; height: 450px; background-color: white"></ng-chart>';

Next you would you want to create the compiled element first, and then add it to the $scope.

So like this:

var element = angular.element(template);

var compiled = $compile(element);

$('#divChart').append(element);

$timeout(function() {
    compiled($scope);
});

Also the $scope.$watch in your directive link function won't work, because it's a deep object, and you should add as a third parameter true if you want $scope.$watch. But because you defined the object in your scope as a two-way binded variable. You don't even need it.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks @Pepjin, and now I am getting the correct data in the chart-Obj but graph is not getting rendered when added at runtime ?
@Mr.SHAW see my edits, hopefully that solves your problem :)
Thanks..for your edits and inputs..I removed watch on 'chart-Obj' from the directive and it did the trick.
@Mr.SHAW Can you accept my answer, for future people with the same problem?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.