0

I am new to Angular and just getting used to how everything fits together. I want to display a chart through a directive. This chart will be static data so will neither be dynamically loaded nor updated, it is taken from a JSON.

I have referenced here but the main difference is that I am not loading Highcharts in the view. I am loading it globally in the .js file from my bower_components directory. This is my code:

.js

/* global Highcharts */

angular.module("fusoDataLoggerChart", [])

    .controller("fusoDataLoggerChartController", ["$http", "$scope", function($http, $scope) {
        "use strict";

         $scope.data = {
             "activities": [
                {},
                {},
                {
                    "title": "Engine speed",
                    "type": "DATA_LOGGER",
                    "result": {
                        "Engine speed": {
                            "data": [
                                {
                                    "timestamp": 0,
                                    "value": {
                                        "type": "QUANTITY",
                                        "unit": "rpm",
                                        "value": 900
                                    }
                                },
                                {
                                    "timestamp": 1000,
                                    "value": {
                                        "type": "QUANTITY",
                                        "unit": "rpm",
                                        "value": 1000
                                    }
                                },
                                {
                                    "timestamp": 2000,
                                    "value": {
                                        "type": "QUANTITY",
                                        "unit": "rpm",
                                        "value": 2000
                                    }
                                }
                            ]
                        },
                        "Accelerator pedal position": {
                            "data": [
                                {
                                    "timestamp": 0,
                                    "value": {
                                        "type": "QUANTITY",
                                        "unit": "%",
                                        "value": 0
                                    }
                                },
                                {
                                    "timestamp": 1000,
                                    "value": {
                                        "type": "QUANTITY",
                                        "unit": "%",
                                        "value": 10.6
                                    }
                                },
                                {
                                    "timestamp": 2000,
                                    "value": {
                                        "type": "QUANTITY",
                                        "unit": "%",
                                        "value": 11
                                     }
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }])

    .directive("fusoDataLoggerChart", function() {
        "use strict";

        return {
            scope: {},
            restrict: 'E',
            link: function(scope) {
                scope.dataLoggerData = scope.data["activities"][2]["result"];

                scope.timestamps     = getData()[0];
                scope.engineSpeeds   = getData()[1];
                scope.pedalPositions = getData()[2];

                var chart = new Highcharts.Chart({
                    chart: {
                        type: 'line',
                        animation: false,
                        renderTo: "DataLoggerChartContainer",
                        zoomType: 'x'
                    },
                    credits: {
                        enabled: false
                    },
                    title: {
                        text: null
                    },
                    xAxis: {
                        type: "linear",
                        title: {
                            text: "Timestamp"
                        },
                        min: 0,
                        categories: scope.timestamps
                    },
                    yAxis: [{       //Engine Speed
                        title: {
                            text: 'Engine Speed'
                        },
                        labels: {
                            format: '{value} RPM'
                        },
                        opposite: true
                    }, {            //Accelerator Pedal Position
                        title: {
                            text: 'Accelerator Pedal Position'
                        },
                        labels: {
                            format: '{value} %'
                        },
                        min: 0,
                        max: 100,
                        // FIXME: 'allowDecimal' may not work
                        allowDecimal: true
                    }],
                    series: [{
                        name: 'Engine Speed',
                        type: 'spline',
                        yAxis: 1,
                        tooltip: {
                            valueSuffix: ' RPM'
                        },
                        data: scope.engineSpeeds
                    }, {
                        name: 'Accelerator Pedal Position',
                        type: 'spline',
                        yAxis: 2,
                        tooltip: {
                            valueSuffix: ' %'
                        },
                        data: scope.pedalPositions
                    }]
                });

                function getData() {
                    var timestamps      = [],
                        engineSpeeds    = [],
                        pedalPositions  = [];

                    var engineSpeedData = scope.dataLoggerData["Engine Speed"]["data"],
                        pedalPosData    = scope.dataLoggerData["Accelerator Pedal Position"]["data"];

                    for (var i in engineSpeedData) {
                        timestamps.push(engineSpeedData[i].timestamp);
                    }

                    for (var j in engineSpeedData) {
                        engineSpeeds.push(engineSpeedData[j].value.value);
                    }

                    for (var k in pedalPosData) {
                        pedalPositions.push(pedalPosData[k].value.value);
                    }

                    return [timestamps, engineSpeeds, pedalPositions];
                }
            }
        }
    });

HTML

<fuso-data-logger-chart>
    <div id="DataLoggerChartContainer"></div>
</fuso-data-logger-chart>

When I go to where the chart is to be rendered, nothing is shown (and only the HTML code set manually is displayed with nothing inside when I check in DevTools).

N.B: I realize I do not need the controller yet but it is there as in future the JSON will be got from a rest call from within the controller

Any help appreciated.

4
  • Are you sure that Angular is running properly? Your directive code looks fine and so does the controller. Any chance you could create a plunker or something? I could troubleshoot it much easier if I could see it all together to figure out what's wrong. Commented May 18, 2016 at 22:25
  • Also, to ensure that your directive code is actually running, try adding an console.log('code is running') in the link() function. If that works, try adding a console.log(chart) after your chart definition to ensure that the chart is indeed being created by HighCharts. I often think the problem must be more complex but in doing this action, sometimes I discover a really simple mistake I overlooked. Commented May 18, 2016 at 22:37
  • I have put a few console.log()'s but nothing is output, which suggests to me that for some reason the directive is not being called Commented May 19, 2016 at 7:48
  • I created a plunker here and even add in a ng-app and ng-controller into the html but still does not seem to work. (The highcharts might not have been loaded properly but even the console.log() statements should be executed) Commented May 19, 2016 at 7:59

2 Answers 2

1

This isn't a full answer to your question, but I noticed a way you can make your HTML directive a little cleaner so that you could instead use this format:

<fuso-data-logger-chart></fuso-data-logger-chart>

You don't need the <div id="DataLoggerChartContainer">. You can embed that in the directive definition as a template:

.directive("fusoDataLoggerChart", function() {
        "use strict";

        return {
            scope: {},
            restrict: 'E',
            transclude: true,
            template: '<div id="DataLoggerChartContainer"></div>'
            link: function(scope) {
                ... your other code ...
            }
        }
});
Sign up to request clarification or add additional context in comments.

1 Comment

I attempted that but the template was not added. I, again, think this is because the directive is not being invoked for some reason
1

I have figured out the problem. There were multiple errors but I'll leave this here so maybe someone else can find it useful:

  1. Highcharts and my FusoDataLoggerChart.js were not loaded into index.html (<script src="modules/readVehicleData/FusoDataLoggerChart.js"></script>) meaning that they couldn't be seen by Angular.
  2. In my directive, I was trying to access the local scope (scope.data) in the link() function instead of trying to access the parent scope in the controller where the data is set. To access the parent scope, scope.$parent.data worked for me (N.B: was only 'data' for me as that's the value I set)

Comments

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.