Using Google Charts in Angular 4 project, part 1

Introducing Google Charts

Google Charts is an HTML5/SVG thats provides many kind of charts.
The most common way to use Google Charts is with simple JavaScript that you embed in your web page. You load some Google Chart libraries, list the data to be charted, select options to customize your chart, and finally create a chart object with an id that you choose. Then, later in the web page, you create a with that id to display the Google Chart.

All chart types are populated with data using the DataTable class, making it easy to switch between chart types as you experiment to find the ideal appearance. The DataTable provides methods for sorting, modifying, and filtering data, and can be populated directly from your web page, a database.

In this article we will use Pie Chart (Donut Chart exactly) as sample.

Let’s get started with Google’s documentation :

<html>
  <head>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  </head>
  <body>
     <script type="text/javascript">       
        google.charts.load("current", {packages:["corechart"]});    
        function drawChart() {         
           var data = google.visualization.arrayToDataTable([['Task', 'Hours per Day'], ['Work', 11], ['Eat', 2], ['Commute',  2], ['Watch TV', 2], ['Sleep', 7] ]);         
           var options = { title: 'My Daily Activities', pieHole: 0.4 };         
           var chart = new google.visualization.PieChart(document.getElementById('donutchart'));         
           chart.draw(data, options);       
         }
         google.charts.setOnLoadCallback(drawChart);        
       </script>
       <div id="donutchart" style="width: 900px; height: 500px;"></div>
  </body>
</html>

Here is the display result (in picture) :

 

Sexy isn’t it ? 🙂

How does it work ?

Step 1 :

Add the library js file within <head> tag of your page :

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

Step 2 :

Load the library :

google.charts.load("current", {packages:["corechart"]});

Step 3 :

Write the proper callback to create the chart, this callback, must contain data, options to parameterize your chart, the proper method to display the type of chart you want to draw and then execute the draw method. Don’t forget to set the right id of the div you want to fill with the chart.

function drawChart() {          
   var data = google.visualization.arrayToDataTable([['Task', 'Hours per Day'], ['Work', 11], ['Eat', 2], ['Commute',  2], ['Watch TV', 2], ['Sleep', 7] ]);          
   var options = { title: 'My Daily Activities', pieHole: 0.4 };          
   var chart = new google.visualization.PieChart(document.getElementById('donutchart'));         
   chart.draw(data, options);
}

Important : It’s mandatory to use a callback, because object google.visualization is not set by the framework yet, it’s set during the page load.

Step 4 :

Setup the Google Chart call back named setOnLoadCallback like this :

google.charts.setOnLoadCallback(drawChart);

Step 6 :

Add a div container to be filled by the chart :

<div id="donutchart" style="width: 900px; height: 500px;"></div>

Then…..

I just showed you how to use Google Charts in classical web page in HTML / Javascript, now let’s go the next article to see :

1- How we can make it work in an Angular 4  project,

2- How we can abstract Google Charts from it if we want to change chart Library

3- How can make this kind of charts reusable by using Angular 4 components.

Click here to go to Part 2

Angular 2, 4 and 5 must have extensions for Visual Studio Code

 

You decided to develop with Angular 4 with TypeScript in Visual Studio Code ?

Good Choice ! 🙂

Here are the must have extensions !

For any installation : Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.

1- Angular v4 TypeScript Snippets

Installation : 
ext install Angular v4 TypeScript Snippets

Usage :

  • TypeScript Angular Snippets
a-component                 // component
a-component-root            // root app component
a-directive                 // directive
a-guard-can-activate        // CanActivate guard
a-guard-can-activate-child  // CanActivateChild guard
a-guard-can-deactivate      // CanDeactivate guard
a-guard-can-load            // CanLoad guard
a-http-get                  // http.get with Rx Observable
a-httpclient-get            // httpClient.get with Rx Observable
a-module                    // module
a-module-root               // root app module
a-module-routing            // routing module file (forChild)
a-output-event              // @Output event and emitter
a-pipe                      // pipe
a-route-path-404            // 404 route path
a-route-path-default        // default route path
a-route-path-eager          // eager route path
a-route-path-lazy           // lazy route path
a-service                   // service
a-service-http              // service with Http
a-service-httpclient        // service with HttpClient
a-ctor-skip-self            // angular ngmodule's skipself constructor
a-subscribe                 // Rx Observable subscription
  • TypeScript RxJS Snippets

rx-observable               // Rx Observable import
rx-subject                  // Rx Subject import
rx-replay-subject           // Rx ReplaySubject import
rx-behavior-subject         // Rx BehaviorSubject import
rx-add-operator             // Rx add operator import
rx-add-observable           // Rx add observable import
  • HTML Snippets

a-class                     // [class] binding
a-select                    // <select> control
a-style                     // [style] binding
a-ngClass                   // ngClass
a-ngFor                     // *ngFor
a-ngForAsync                // *ngFor with async
a-ngIf                      // *ngIf
a-ngIfElse                  // *ngIf with else
a-ngModel                   // ngModel
a-routerLink                // routerLink
a-routerLink-param          // routerLink with a route parameter
a-ngStyle                   // ngStyle
a-ngSwitch                  // ngSwitch
a-prej                      // <pre>{{model | json}}</pre>
a-preja                     // <pre>{{model | async | json}}</pre>
Demo :

2- Auto Import

Installation :

ext install auto import

Automatically finds, parses and provides code actions and code completion for all available imports. Works with Typescript and TSX.

Demo :

3- Debugger for Chrome

Installation :

ext install debugger-for-chrome

Supported features :

  • Setting breakpoints, including in source files when source maps are enabled
  • Stepping, including with the buttons on the Chrome page
  • The Locals pane
  • Debugging eval scripts, script tags, and scripts that are added dynamically
  • Watches
  • Console

Unsupported scenarios :

  • Debugging web workers
  • Any features that aren’t script debugging.

Demo :

4- Path Intellisense

A Visual Studio Code plugin that autocompletes filenames.

Installation :

ext install path-intellisense

Demo :

5- sort-imports

Sort ES6 imports for JavaScript and TypeScript automatically.

Installation :

ext install sort-imports

Demo :

6- Visual Studio Team Services

This extension allows you to connect to Team Services and Team Foundation Server and provides support for Team Foundation Version Control (TFVC). It allows you to monitor your builds and manage your pull requests and work items for your TFVC or Git source repositories. The extension uses your local repository information to connect to either Team Services or Team Foundation Server 2015 Update 2 (and later).

Installation :

ext install team

For configuration tutorial, please check my previous article here : http://anthonygiretti.com/2017/05/29/how-to-configure-visual-studio-code-with-visual-studio-team-services/

7- vsc-angular-cli

This extension allows to run angular-cli commands from command panel

Installation :

ext install vsc-angular-cli

Supported commands (by now):

  • ng new
  • ng doc
  • ng lint
  • ng serve
  • ng versio
  • ng format
  • ng e2e
  • ng completion
  • ng generate
  • ng test
  • ng help

8- VSCode simpler Icons with Angular

This extension is a simpler icon pack than the big pack of icons vscode-great-icons.
Personnal icon theme, to group javascript style (typescript, coffee…) into one only icon, css style (less, sass …) into on only icon etc …

Installation :

ext install vscode-great-icons

Demo :

 

Are you ready to ;ake your fiest Angular 4 app with Visual Studio Code ? 😉

 

Create HTML 5 charts export them to PDF for free

sample

During the course of their work, many developers have had to create charts in view of exporting them to a PDF report.
Developing these charts was quite onerous due to having to create an image for display in HTML code, then recreating it on the server side, and finally inserting it into a PDF document created on the fly.
Happily, this is a thing of the past. Thanks to HTML 5, it is now possible to create charts using the new Javascript API without having to create an image. All you need to do is use free library content that will convert an HTML page to PDF by interpreting the HTML, Javascript and CSS.

First, select a graphics library 

I personally chose Google charts, which can be found at https://developers.google.com/chart/.

I like Google charts because of the reliability of Google, it’s free, it offers a plethora of original charts and I’m a fan of Google’s Material Design.
Note that Google uses SVG charts, while other libraries use the canvas. To check browser compatibility, go to the caniuse.com website, which will tell you if the feature you want is compatible with a particular browser. Personally, I test SVG support on the most common browsers.

Following is a 5 step example.

Step 1 : Add a reference to Google Charts

<script type="text/javascript" src="https://www.google.com/jsapi"></script>

Step 2 : Load classes

google.load("visualization", "1", { packages: ["corechart"] });

Step 3 : Implement and define loading for each chart

    google.setOnLoadCallback(drawChatter);
    google.setOnLoadCallback(drawPie);
    google.setOnLoadCallback(drawDonut);
    google.setOnLoadCallback(drawLines);
    google.setOnLoadCallback(drawStacked);

    function drawChatter() {
        var data = google.visualization.arrayToDataTable([
            ['Age', 'Weight'],
            [8, -12],
            [-4, 5.5],
            [11, 14],
            [4, 5],
            [-3, -3.5],
            [6.5, -7]
        ]);

        var options = {
            title: 'Scatter chart',
            hAxis: { title: 'X', minValue: -20, maxValue: 20 },
            vAxis: { title: 'Y', minValue: -20, maxValue: 20 },
            legend: 'none'
        };

        var chart = new google.visualization.ScatterChart(document.getElementById('chartContainer5'));

        chart.draw(data, options);
    }
    
    function drawPie() {

        var data = google.visualization.arrayToDataTable([
            ['Task', 'Hours per Day'],
            ['Work', 11],
            ['Eat', 2],
            ['Commute', 2],
            ['Watch TV', 2],
            ['Sleep', 7]
        ]);

        var options = {
            title: 'Pie chart'
        };

        var chart = new google.visualization.PieChart(document.getElementById('chartContainer4'));

        chart.draw(data, options);
    }

    function drawDonut() {
        var data = google.visualization.arrayToDataTable([
          ['Task', 'Hours per Day'],
          ['Work', 11],
          ['Eat', 2],
          ['Commute', 2],
          ['Watch TV', 2],
          ['Sleep', 7]
        ]);

        var options = {
            title: 'Donut Chart',
            pieHole: 0.4,
        };

        var chart = new google.visualization.PieChart(document.getElementById('chartContainer3'));
        chart.draw(data, options);
    }

    function drawLines() {

        var data = new google.visualization.DataTable();
        data.addColumn('number', 'X');
        data.addColumn('number', 'Y');
        var y = 0;
        var x = 0;
        for (var i = 0; i < 1000; i += 1) {
            y += (Math.random() * 10 - 5);
            x = i - 1000 / 2;
            data.addRows([[x,y]]);
        }
       
        var options = {
            hAxis: {
                title: 'Y'
            },
            vAxis: {
                title: 'X'
            }
        };

        var chart = new google.visualization.LineChart(document.getElementById('chartContainer2'));

        chart.draw(data, options);
    }

    function drawStacked() {
        var data = new google.visualization.DataTable();
        data.addColumn('timeofday', 'X');
        data.addColumn('number', 'Motivation Level');
        data.addColumn('number', 'Energy Level');
        data.addColumn('number', 'Another');

        data.addRows([
          [{ v: [8, 0, 0], f: '8' }, 1, 1.25, 1.25],
        [{ v: [9, 0, 0], f: '9' }, 2, 1.5, 1.75],
        [{ v: [10, 0, 0], f: '10' }, 3, 2, 2.25],
        [{ v: [11, 0, 0], f: '11' }, 4, 3.25, 1.5],
        [{ v: [12, 0, 0], f: '12' }, 5, 3.25, 1.25],
        [{ v: [13, 0, 0], f: '13' }, 6, 4, 1.25],
        [{ v: [14, 0, 0], f: '14' }, 7, 5, 3.25],
        [{ v: [15, 0, 0], f: '15' }, 8, 6.25, 1.75],
        [{ v: [16, 0, 0], f: '16' }, 9, 8.5, 4.25],
        [{ v: [17, 0, 0], f: '17' }, 10, 11, 2.75],
        ]);

        var options = {
            title: 'Stacked Bar',
            isStacked: true,
            hAxis: {
                title: 'Y',
                viewWindow: {
                    min: [7, 30, 0],
                    max: [17, 30, 0]
                }
            },
            vAxis: {
                title: 'x'
            }
        };

        var chart = new google.visualization.ColumnChart(document.getElementById('chartContainer1'));
        chart.draw(data, options);

Step 4 : Create a html placeholder for each chart

<style> 
    .myblock { padding: 5px; text-align: center; vertical-align: middle; } 
</style> 
<body> 
<header><h1>Report</h1></header> 
    <div class="myblock"><div id="chartContainer1" style="height: 300px; width: 50%; margin: auto;"></div></div> 
    <div class="myblock"><div id="chartContainer2" style="height: 300px; width: 50%; margin: auto; "></div></div> 
    <div class="myblock"><div id="chartContainer3" style="height: 300px; width: 50%; margin: auto;"></div></div> 
    <div class="myblock"><div id="chartContainer4" style="height: 300px; width: 50%; margin: auto;"></div></div> 
    <div class="myblock"><div id="chartContainer5" style="height: 300px; width: 50%; margin: auto;" ></div></div> 
</body>

The result is available here : http://chartssample.azurewebsites.net/

Second, download a free NuGet Package here: Select.Pdf

The documentation is available here : http://selectpdf.com/

Server side sample (ASP.NET MVC C#) :

using System;
using System.Web.Mvc;
using SelectPdf;
using PdfPageOrientation = SelectPdf.PdfPageOrientation;
using PdfPageSize = SelectPdf.PdfPageSize;

namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Report()
        {
            SelectPdf.GlobalProperties.HtmlEngineFullPath = HttpContext.ApplicationInstance.Server.MapPath("~/App_Data/Select.Html.dep");
            try
            {
                string pdf_page_size = "A4";
                PdfPageSize pageSize = (PdfPageSize) Enum.Parse(typeof (PdfPageSize),
                    pdf_page_size, true);

                string pdf_orientation = "Portrait";
                PdfPageOrientation pdfOrientation =
                    (PdfPageOrientation) Enum.Parse(typeof (PdfPageOrientation),
                        pdf_orientation, true);

                int webPageWidth = 1600;

                int webPageHeight = 0;

                // instantiate a html to pdf converter object
                HtmlToPdf converter = new HtmlToPdf();

                // set converter options
                converter.Options.PdfPageSize = pageSize;
                converter.Options.PdfPageOrientation = pdfOrientation;
                converter.Options.WebPageWidth = webPageWidth;
                converter.Options.WebPageHeight = webPageHeight;

                // create a new pdf document converting an url
                PdfDocument doc =
                    converter.ConvertUrl(string.Format("http://{0}:{1}/Home/Index", HttpContext.Request.Url.Host,
                        HttpContext.Request.Url.Port));

                // save pdf document
                doc.Save(HttpContext.ApplicationInstance.Response, false, "Sample.pdf");

                // close pdf document
                doc.Close();

                return Content("");
            }
            catch(Exception e)
            {
                return Content(string.Format("{0}


{1}", e.Message, (null!=e.InnerException)?e.InnerException.Message:"")); } } } }

The pdf file produced is available here: sample.pdf

So what do you think? 🙂