Heatmap.js directive for Angularjs

Problem

is there a angularJS directive for heatmap.js?

Can't find anything and can't get it to work Thanks

= Edit =

I get this error whether I used my code or the one below (both work). My problem was actually the version of the heatmap.js that that I was using from the bower. When I download the min.js used in the fiddle it all works fine.

TypeError: Cannot read property 'style' of null at Object.heatmap.resize (http://localhost:56080/app/bower_components/heatmap.js/src/heatmap.js:363:74) at Object.heatmap.init (http://localhost:56080/app/bower_components/heatmap.js/src/heatmap.js:386:20) at Object.heatmap (http://localhost:56080/app/bower_components/heatmap.js/src/heatmap.js:331:14) at Object.heatmapFactory.create (http://localhost:56080/app/bower_components/heatmap.js/src/heatmap.js:627:24) at link (http://localhost:56080/app/js/directives/MainDirective.js:9:36)

Problem courtesy of: Matthieu

Solution

Simple wrapper directive for heatmap.js

HTML

<div ng-app="myapp">
    <div ng-controller="MyCtrl1">
        <heat-map data="passed_data"></heat-map> 
    </div>
 </div>

JS

var myApp = angular.module('myapp',[]);

myApp
    .controller('MyCtrl1', function ($scope) {

           // now generate some random data
            var points = [];
            var max = 0;
            var width = 840;
            var height = 400;
            var len = 200;

            while (len--) {
                var val = Math.floor(Math.random()*100);
                max = Math.max(max, val);
                var point = {
                    x: Math.floor(Math.random()*width),
                    y: Math.floor(Math.random()*height),
                    value: val
                };
                points.push(point);
            }
            // heatmap data format
            $scope.passed_data = { 
                max: max, 
                data: points 
            };
    })
    .directive('heatMap', function(){
        return {
            restrict: 'E',
            scope: {
                data: '='
            },
            template: '<div container></div>',
            link: function(scope, ele, attr){
                scope.heatmapInstance = h337.create({
                  container: ele.find('div')[0]
                });
                scope.heatmapInstance.setData(scope.data);
            }

        };
    });

CSS

heat-map {
    width: 840px;
    height: 400px;
    display: block;
}

heat-map div {
     height: 100%;   
}

JsFiddle - http://jsfiddle.net/jigardafda/utjjatuo/2/

heatmap.js example reference link

http://www.patrick-wied.at/static/heatmapjs/example-minimal-config.html

Solution courtesy of: jad-panda

Discussion

jad-panda's answer (https://stackoverflow.com/a/30193896/3437606) is really helpfull.

But if you don't want to make the size of the heatmap hardcoded in css and apply them dynamicaly with ng-style, you have to make the following minor changes.

HTML

<div ng-style="heatMapStyle">
    <heat-map data="passed_data"></heat-map>
</div>

Controller

just add the style object to the $scope like

$scope.heatMapStyle = {
            "height": 100+ "px",
            "width": 150+ "px"
        };

The rest of the controler is the same as in jad-panda's answer.

Directive

.directive('heatMap', ['$timeout', function ($timeout) {
        return {
            restrict: 'E',
            scope: {
                data: '='
            },
            template: '<div container></div>',
            link: function (scope, ele, attr) {
                function init() {
                    scope.heatmapInstance = h337.create({
                        container: ele.find('div')[0]
                    });
                    scope.heatmapInstance.setData(scope.data);
                }
                //to ensure that the wrapping style is already applied
                $timeout(init,0);
            }

        };
    }])

The $timout is essential to ensure that the heatmap is initialized in the next digestcycle of AngularJs when the ng-styleis already applied.

CSS

And last the new CSS:

heat-map {
    position: relative;
    width: 100%;
    height: 100%;
}
heat-map div {
    height: 100%;
}
Discussion courtesy of: Ohmen

This recipe can be found in it's original form on Stack Over Flow.