Bas Pauw
Bas Pauw

Reputation: 262

Creating a Highchart for every data set

I'm sure that someone already encountered this problem and posted here, but I just couldn't find it. So sorry for the dupe. I am making a dashboard where there has to be a chart for every data set from the database.

I tried doing it with sending the data to a directive and draw the chart from within the directive's controller with the data passed to the directive.

This is the partial view

<div class="row">
<div class="col col-md-9">
    <input type="text" class="form-control" ng-model="nameFilter" placeholder="Search for...">
</div>
</div>

<div class="row" ng-if="loading">
<div class="col col-md-6 col-md-offset-3">
    <img src="../img/loader.gif"/>
</div>
</div>
<div class="row" ng-repeat="app in apps | filter: nameFilter">
     <app-card name="app.name" android="app.android" ios="app.ios" date="app.date"></app-card>
</div>

The partial sends data to the directive

var app = angular.module('app');

app.directive('appCard', function() {
    return {
        restrict: 'E',
        scope: {
            name: '=name',
            android: '=android',
            ios: '=ios',
            date: '=date'
        },
        templateUrl: 'http://testsite.nl/dashboard/partials/directives/app-card.html'
    };
});

The directives template

<div class="panel panel-info app-card" ng-controller="appCardController">
    <div class="panel-heading">
        <div class="row">
            <h4 class="col col-md-5">{{name}}</h4>


        </div>
    </div>
    <div class="panel-body">
        <div class="col col-md-12">
            <h3>Android downloads: {{android}}</h3>
            <h3>iOS downloads: {{ios}}</h3>
            <div id="container" style="min-width: 310px; height:250px; margin: 0 auto;"></div>
        </div>
    </div>
</div>

And the controller looks like this

app.controller('appCardController', ['$scope', function($scope){
    console.log("Downloads: " + $scope.android);
    Highcharts.chart('container', {
        chart: {
            type: 'area'
        },
        title: {

            text: 'Aantal downloads'
        },
        xAxis: {
            allowDecimals: false,
            categories: $scope.date
        },
        yAxis: {
            title: { text:'Donwloads' },
            floor: 0,
            ceiling: getMaxDownloadCount()
        },
        tooltip: {
            pointFormat: '{series.name} <b>{point.y:,.0f}</b>'
        },
        series: [{
            name: 'Android',
            data: convertAndroidArrayToInts($scope.android)
        },
        {
            name: 'iOS',
            data: convertIosArrayToInts($scope.ios)
        }]
    });

    function convertAndroidArrayToInts(array){
        var androidArray = new Array();
        for(var i =0; i < array.length; i++){
            androidArray.push(parseInt(array[i]));
        }

        return androidArray
    }
    function convertIosArrayToInts(array){
        var iosArray = new Array();
        for(var i =0; i < array.length; i++){
            iosArray.push(parseInt(array[i]));
        }
        console.log(iosArray);
        return iosArray
    }
}]);

It shows the directive templates with the correct name and array values, the only problem is that there is only one chart drawn, which is the chart beloning to the last item in the list, but it is located in the first template.

How would I be able to make it so every template contains a chart beloning to its data?

Upvotes: 3

Views: 99

Answers (1)

Daniel Dawes
Daniel Dawes

Reputation: 1005

I answered a very similar question related to using angular-chart, see my plunker here: https://plnkr.co/edit/8fJ4u0U2fL4lYTioCbG0?p=preview

The question/answer here: angular ng-repeat with directive

The actual issue you face is that the ID is container, and you cannot have duplicate "id" attributes in the DOM, so it will only find the first one.

Assuming the "name" is unique, change the controller so it uses the directives scope.name on Highchart.chart and change the directive template so the <div id="container"> becomes <div id="{{name}}"

After this you should have unique ID's and it will work

Hope that makes sense.

Upvotes: 3

Related Questions