Learn MVC Using Angular Flot Chart

Introduction

In this article, we will learn about working with MVC using the Angular Flot Chart with JSON data. With Flot Chart, we can create the following types of charts.

  • Area Chart
  • Bar Chart
  • Stacked Bar Chart

Area Chart

Output 1

MVC

Create MVC Project

Open Visual Studio 2015.
MVC

Go to New >> Project. Now it will open “New Project” window.
MVC

Select ASP.NET Web Application on Framework 4.6. Enter the name of the project in the “Solution name” textbox and click OK.
MVC

One more window should appear. Select MVC Template in this popup and click the OK button.

Configure the jQuery Flot Chart

We will download the Flot plugin from jQuery Flot.

Open the _Layout.cshtml and refer to the jqery.flot.js file below:

<script src="~/Plugin/flot/jquery.flot.js"></script>
 
        <script src="~/Plugin/flot/jquery.flot.resize.js"></script>
 
        <script src="~/Plugin/flot/jquery.flot.pie.js"></script>
 
        <script src="~/Plugin/flot/jquery.flot.time.js"></script>
 
<script src="~/Plugin/flot/jquery.flot.categories.js"></script>

Open the HTML page and design it using flot elements and attributes.

<flot datalist="'server/area.json'" options="chartAreaFlotChart" series="{'lines': areaSeries}"></flot>

Here, we can show and change the visual view of data on a per year basis.

<input type="checkbox" id="input10" ng-model="areaSeries[0]" />
<label for="input10">
    <strong>2017</strong>
</label>

<input type="checkbox" id="input11" ng-model="areaSeries[1]" />
<label for="input11">
    <strong>2016</strong>
</label>

<input type="checkbox" id="input12" ng-model="areaSeries[2]" />
<label for="input12">
    <strong>2015</strong>
</label>

You have the option to change the Flot Chart UI using “Angular Service.”

var vm = this;

        vm['default'] = {
            grid: {
                hoverable: true,
                clickable: true,
                borderWidth: 0,
                color: '#8394a9'
            },
            tooltip: true,
            tooltipOpts: {
                content: '%x : %y'
            },
            xaxis: {
                tickColor: '#f1f2f3',
                mode: 'categories'
            },
            yaxis: {
                tickColor: '#f1f2f3'
            },
            legend: {
                backgroundColor: 'rgba(0,0,0,0)'
            },
            shadowSize: 0
        };

        vm['area'] = angular.extend({}, vm['default'], {
            series: {
                lines: {
                    show: true,
                    fill: 1
                }
            }
        });

Set vm[‘default’] as a common declaration, because we are going to use bar charts and stacked bar charts also.

Inject the Angular service function into the Angular controllers, as shown below:

function ChartController($scope, $http, $timeout, flotService)

Set the values for the attribute. Open the “angular controller” files and hard code an input or you may get and bind the values from the server side.

$scope.chartAreaFlotChart = flotService['area'];

I have used JSON data for this flot chart and the files are given below.

[
  {
    "label": "2017",
    "color": "#2196f3",
    "data": [
      [ "1", 530 ],
      [ "2", 720 ],
      [ "3", 580 ],
      [ "4", 920 ],
      [ "5", 510 ]
    ]
  },
  {
    "label": "2016",
    "color": "#03a9f4",
    "data": [
      [ "1", 370 ],
      [ "2", 310 ],
      [ "3", 420 ],
      [ "4", 590 ],
      [ "5", 240 ]
    ]
  },
  {
    "label": "2015",
    "color": "#00bcd4",
    "data": [
      [ "1", 230 ],
      [ "2", 170 ],
      [ "3", 280 ],
      [ "4", 450],
      [ "5", 100 ]
    ]
  }
]

Now, we must link this file to the HTML attribute values.

datalist="'server/area.json'" 

Here I want to bind JSON data into the flot chart. Therefore, I wrote the “angular directive” as an intermediate.

    angular
        .module('chart')
        .directive('flot', flot);

    function flot($http, $timeout) {

        return {
            restrict: 'EA',
            template: '<div></div>',
            scope: {
                dataset: '=?',
                options: '=',
                series: '=',
                callback: '=',
                datalist: '='
            },
            link: linkFunction
        };

        function linkFunction(scope, element, attributes) {
            var height, plot, plotArea, width;
            var heightDefault = 220;

            plot = null;

            width = attributes.width || '100%';
            height = attributes.height || heightDefault;

            plotArea = $(element.children()[0]);
            plotArea.css({
                width: width,
                height: height
            });

            function init() {
                var plotObj;
                if (!scope.dataset || !scope.options) return;
                plotObj = $.plot(plotArea, scope.dataset, scope.options);
                scope.$emit('plotReady', plotObj);
                if (scope.callback) {
                    scope.callback(plotObj, scope);
                }

                return plotObj;
            }

            function onDatasetChanged(dataset) {
                if (plot) {
                    plot.setData(dataset);
                    plot.setupGrid();
                    return plot.draw();
                } else {
                    plot = init();
                    onSerieToggled(scope.series);
                    return plot;
                }
            }
            scope.$watchCollection('dataset', onDatasetChanged, true);

            function onSerieToggled(series) {
                if (!plot || !series) return;
                var someData = plot.getData();
                /*jshint -W089 */
                for (var sName in series) {
                    angular.forEach(series[sName], toggleFor(sName));
                }

                plot.setData(someData);
                plot.draw();

                function toggleFor(sName) {
                    return function (s, i) {
                        if (someData[i] && someData[i][sName])
                            someData[i][sName].show = s;
                    };
                }
            }
            scope.$watch('series', onSerieToggled, true);

            function onDatalistChanged(datalist) {

                if (datalist) {

                    $http.get(datalist)
                      .success(function (data) {

                          $timeout(function () {
                              scope.dataset = data;
                          });

                      }).error(function () {
                          $.error('Flot chart: Bad request.');
                      });

                }
            }
            scope.$watch('datalist', onDatalistChanged);
        }

    }

After completing the entire configuration, add the reference file in the _Layout.CSHTML page

<script src="~/App/App.module.js"></script>
<script src="~/App/App.config.js"></script>
<script src="~/App/ChartDirective.js"></script>
<script src="~/App/ChartController.js"></script>
 <script src="~/App/ChartService.js"></script>

Output 2

MVC

Let us talk about bar charts. We will create our bar chart in a similar way to how we configured our area chart.

Load attribute values for the bar chart angular controller files

$scope.chartBarFlotChart = flotService['bar'];

Set the flot chart series as bars based on the configuration in the “angular service” file.

  vm['bar'] = angular.extend({}, vm['default'], {
            series: {
                bars: {
                    align: 'center',
                    lineWidth: 0,
                    show: true,
                    barWidth: 0.6,
                    fill: 1
                }
            }
        });

Call the function in an HTML element based on bar chart types

<flot datalist="'server/bar.json'" options="chartBarFlotChart"></flot>

My JSON Data is given below.

[
  {
    "label": "2017",
    "color": "#2196f3",
    "data": [
      [ "Jan", 17 ],
      [ "Feb", 82 ],
      [ "Mar", 56 ],
      [ "Apr", 24 ],
      [ "May", 28 ],
      [ "Jun", 37 ],
      [ "Jul", 23 ],
      [ "Aug", 49 ],
      [ "Sep", 51 ],
      [ "Oct", 40 ]
    ]
  }
]

Output 3

MVC

Load Attribute values for a stacked bar chart to the angular controller files.

$scope.chartBarStackedFlotChart = flotService['bar-stacked'];

Set the flot chart series as a stacked bar based on the configuration in the “angular service” file.

  vm['bar-stacked'] = angular.extend({}, vm['default'], {
            series: {
                bars: {
                    align: 'center',
                    lineWidth: 0,
                    show: true,
                    barWidth: 0.6,
                    fill: 1,
                    stacked: true
                }
            }
        });

Assign the function in an HTML element based on the stacked bar chart types.

<flot datalist="'server/barstacked.json'" options="chartBarStackedFlotChart"></flot>

My JSON Data is given below.

[
  {
    "label": "2017",
    "color": "#2196f3",
    "data": [
      [ "Jan", 80 ],
      [ "Feb", 40 ],
      [ "Mar", 97 ],
      [ "Apr", 44 ],
      [ "May", 24 ],
      [ "Jun", 85 ],
      [ "Jul", 94 ],
      [ "Aug", 78 ],
      [ "Sep", 52 ],
      [ "Oct", 17 ],
      [ "Nov", 90 ],
      [ "Dec", 62 ]
    ]
  },
  {
    "label": "2015",
    "color": "#00bcd4",
    "data": [
      [ "Jan", 20 ],
      [ "Feb", 20 ],
      [ "Mar", 14 ],
      [ "Apr", 80 ],
      [ "May", 90 ],
      [ "Jun", 62 ],
      [ "Jul", 15 ],
      [ "Aug", 22 ],
      [ "Sep", 10 ],
      [ "Oct", 13 ],
      [ "Nov", 72 ],
      [ "Dec", 61 ]
    ]
  }]

Now you can run the flot chart application in visual studio 2015. The output will appear in the browser.

Output 4

MVC

Note

If you click any year in the check box, you can see the actual data representation in this flot chart. Stacked bar charts represent the actual difference in each month.

You can download my source code here.

Conclusion

In this article, we have learned how to use MVC by using the Angular Flot Chart framework. If you have any queries, please tell me through the comments section. Your comments are very valuable.

Happy Coding!