Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Angular directive for jQuery sparkline
// Requires jQuery from http://jquery.com/
// and jQuerySparklines from http://omnipotent.net/jquery.sparkline
// AngularJS directives for jquery sparkline
angular.module('sparkline', []);
angular.module('sparkline')
.directive('jqSparkline', [function () {
'use strict';
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elem, attrs, ngModel) {
var opts={};
//TODO: Use $eval to get the object
opts.type = attrs.type || 'line';
scope.$watch(attrs.ngModel, function () {
render();
});
scope.$watch(attrs.opts, function(){
render();
}
);
var render = function () {
var model;
if(attrs.opts) angular.extend(opts, angular.fromJson(attrs.opts));
console.log(opts);
// Trim trailing comma if we are a string
angular.isString(ngModel.$viewValue) ? model = ngModel.$viewValue.replace(/(^,)|(,$)/g, "") : model = ngModel.$viewValue;
var data;
// Make sure we have an array of numbers
angular.isArray(model) ? data = model : data = model.split(',');
$(elem).sparkline(data, opts);
};
}
}
}]);
@itrond

This comment has been minimized.

Copy link

commented Nov 29, 2013

Thank you Peter! :-) works very nice:
remember to use {{ around you opts, like:
.... jq-sparkline ng-model="yourData" opts="{{ {type:'line', width:'200px', height:'45px'} }}" ....

@wimvanleuven

This comment has been minimized.

Copy link

commented Jan 28, 2014

Hmmm ... can't seem to get it work. I notice the module/directive to get loaded, but the rendering never gets triggered.

In my HTML code, I've set this up as a

Any ideas? Thanks already!
-wim

@Ercenk

This comment has been minimized.

Copy link

commented Apr 7, 2014

wim, try setting the objectEquality flag of $watch for the ngModel to true, if your ngModel is an array, and you are changing it programmatically.

e.g. if you are adding elements to the model array pointed to by the ng-model attribute, change the code to:

scope.$watch(attrs.ngModel, function () {
render();
}, true);

@DaveCollinsJr

This comment has been minimized.

Copy link

commented Jul 22, 2014

I don't suppose anyone has a JSFiddle of this working, do they?

@DaveCollinsJr

This comment has been minimized.

Copy link

commented Jul 22, 2014

If it helps anyone who uses coffeescript... Here is a version of the above that is working for me in a project:

  .directive "mySpark", ->
    restrict: "A"
    require: "ngModel"
    link: (scope, elem, attrs, ngModel) ->
      opts = {}

      opts.type = attrs.type || 'bar'
      opts.barColor = attrs.barColor || '#ffffff'
      opts.height = attrs.height || '35px'
      opts.barWidth = attrs.barWidth || '5px'
      opts.barSpacing = attrs.barSpacing || '2px'
      opts.zeroAxis = attrs.zeroAxis || 'false'

      scope.$watch attrs.ngModel, ((value) ->
        render()
      ), true

      scope.$watch attrs.opts, ((value) ->
        render()
      ), true

      render = () ->
        angular.extend opts, angular.fromJson(attrs.opts) if attrs.opts

        model = ngModel.$viewValue

        if angular.isArray(model)
          data = model
        else
          if model?
            data = model.split(",")
          else
            data = []

        $(elem).sparkline data, opts

Using it:

<div my-spark ng-model="daily_meter_uptime.scaled_historical_values"/>

used a deep watch on the values and it is working great. Thanks for taking the time to write this up!!

@nozelrosario

This comment has been minimized.

Copy link

commented Dec 16, 2014

Thanks !! works like charm :)

@anilsingh581

This comment has been minimized.

Copy link

commented Feb 14, 2015

@darkbluesun

This comment has been minimized.

Copy link

commented Feb 15, 2016

Wrapping the jquery bit in $timeout() helped me.

@dylannnn

This comment has been minimized.

Copy link

commented Apr 17, 2016

This is great! But how can I use this directive to create a Composite inline graph? For example two line in one graph. I tried many way but failed. Thanks

Sample image:
download 1

@adanylov

This comment has been minimized.

Copy link

commented Jun 7, 2016

In case of composite sparkline:

function compositeSparkline(): ng.IDirective {

    function link(scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes) {
        var getOptions = () => {
            var options = {
                chart1: angular.extend({ type: 'line', data: [] }, scope.$eval(attrs['chart1'])),
                chart2: angular.extend({ type: 'line', data: [] }, scope.$eval(attrs['chart2']))
            }

            return options;
        };

        var render = () => {
            var opts = getOptions();

            // draw chart1
            (<any>jQuery(element)).sparkline(opts.chart1.data, opts.chart1);

            // draw chart2
            (<any>jQuery(element)).sparkline(opts.chart2.data, opts.chart2);
        };

        // Watch for changes to the directives options
        scope.$watch(getOptions, render, true);

        render();
    }

    return {
        restrict: 'A',
        scope: {},
        link: link
    };
}

angular.module('sparkline').directive('ngCompositeSparkline', compositeSparkline);

It is less flexible because you need to pass arrays of integer for chart1 and chart2 options into the directive... But it is just a starting point for the extensions

@roelzkie15

This comment has been minimized.

Copy link

commented Mar 2, 2017

May i know where can i find the implementation code? Its a big help.

@Hnasante

This comment has been minimized.

Copy link

commented May 31, 2018

+1

May I know how to make this work for angular 4, thanks in advance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.