Abhirath Mahipal Abhirath Mahipal - 10 months ago 53
JSON Question

Optimal way to use Angular Directives and JSON

I want an efficient way to factor an Angular Directive that is written to display a chart.

After reading other answers here, I found a nice way to create a directive that displays a single chart without any problem.

How do I reuse the same directive to display different charts? Each chart needs a JSON object that has settings and data in order to render.

I don't want to pollute my Angular View by typing 100-150 lines of JSON and passing it in via the directive.


  • Each chart has some common key/value pairs that I can leave in the directive.

  • How do I infuse chart specific key & value pairs in each directive?

Eg:- Say I want one chart to have green bars and the other chart to have red lines.

Angular Directive

(function () {

'use strict';

.directive("angularDirectiveAmcharts", angularDirectiveAmcharts);

function angularDirectiveAmcharts() {

var directive = {
link: link,
restrict: 'A',
replace: true,
scope: {
chartdata: '=',
type: '=',
customstyle: '@',
chartsettings: '=',
chartid: '@'
template: '<div id="{{ chartid }}" style="{{ customstyle }}"></div>'

return directive;

function link(scope, elem, attrs) {
AmCharts.makeChart(scope.chartid, {
"type": "serial",
"categoryField": "date",
"autoMarginOffset": 10,
"marginRight": 20,
"marginTop": 20,

//I've deleted lots of keys and values for the sake of brevity

"dataProvider": scope.chartdata



<div class="chartarea" ng-controller="pcController as vm">

<div angular-directive-amcharts chartid="chartdiv" chartdata="vm.chart_data"></div>


I am particular about maintainability because a lot of changes are going to made after I'm done with my internship.


Parts of the given code in this answer are based on another answer

You could use a service to provide a standard configuration to all of your chart directives. In this service you can define this standard configuration once and merge it with a specific configuration each time, a directive is created. This way you only have to declare minor changes in your controller.

Nonrequired but possible config binding into directive:

<div ng-controller="myCtrl">
    <my-chart config="conf"></my-chart>

Specific configuration in controller:

myapp.controller('myCtrl', function ($scope) {
    $scope.conf = {
        graphs: [{ type: 'column' }]

Service for default configuration (using jQuerys way to deep merge objects):

myapp.service('chartService', function () {
    this.defaultConfig = {
        "type": "serial",
        // reduced object for readabilty
    this.getConfig = function (mergeObj) {
        return $.extend(true, {}, this.defaultConfig, mergeObj);

The data is get through another service, and added to the configuration after the merge:

var config = chartService.getConfig(scope.config || {});
config.dataProvider = dataProvider.getData();
chart = AmCharts.makeChart(element[0], config);

I've prepared a fiddle, so you can take a look into an example.