Tag Archives: javascript

Track Google Analytics on Angular2

Nowadays Single Page (Web) Application (SPA) is taking over traditional full post-back website. Google Analytics standard tracking code is though yet to support SPA website. We then have to manually implement to track route change.

Google Analytics , at the moment, provides this kind of tracking js code.

(function(i,s,o,g,r,a,m){i[‘GoogleAnalyticsObject’]=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,’script’,’https://www.google-analytics.com/analytics.js’,’ga’);

ga(‘create’, ‘UA-123456-1’, ‘auto’);
ga(‘send’, ‘pageview’);

Per my previous post – Passing javascript global variable to Angular2 (Typescript). We can archive by sending ga object to Angular2. You can choose either approach 1 or 2.

Then at the root component, AppComponent in my previous post, update constructor as follow.

constructor(private router: Router, @Inject(‘ga’) ga:any) {
router.subscribe((val) => {
ga(‘send’, ‘pageview’, { page: val });
});
}

We need to inject router to the constructor and inject ga variable from javascript also.

router has ability to subscribe route change event. We make use of it and call ga function to post tracking to Google Analytics. val parameter is path of target route.

Updated version of Angular2 probably also updated the router class. Please try following if you use a newer version of Angular2.

router.changes.subscribe((val) => {
ga(‘send’, ‘pageview’, { page: val });
});

Then you can use Live overview of Google Analytics to validate if it works properly. Enjoy 🙂

Tagged , , ,

Passing javascript global variable to Angular2 (Typescript)

This content refers to angular2 version 2.0.0-beta.8. If it does not work for you probably because of breaking change in the future updates.

There are a couple ways to do this but I would basically mention only 2 approach.

The first approach, simply add declare var in component that you need to use.

In javascript code, declare variable in global scope:

var func = function() { … }

In Angular2, in the component that need to refer to javascript variable simply declare the same variable with the same name.

declare var func:Function;

This is the easiest way to archive the need but not the most efficient way. It looks like to be a magic variable in the component and is a great enemy of unit testing.

Since dependency injection (DI) pattern is one of the core concept of the  Angular2 (and AngularJS) and we should comply that 🙂

The second approach, import and inject from javascript to Angular2.

In javascript code, declare variable in global scope:

var func = function() { … }

at import statement which normally in the main html page. Passing func variable to the main function of main module.

System.import(‘app/main’)
.then((module) => module.main(func));

Update main.ts TypeScript file. Wrap Angular2 bootstrap with a main function which accept a parameter from import statement above. Inject func variable using provide feature.

import {provide} from ‘angular2/core’;

…….

export function main(func) {
bootstrap(AppComponent, [
//…providers and services
provide(‘func’, { useValue: func})
]);
}

In AppComponent that bootstrap from main.ts, inject func variable to constructor and use as needed. For more information about @Inject decorator please refer to this screencast tutorial – https://egghead.io/lessons/angular-2-using-the-inject-decorator.

export class AppComponent {
constructor(@Inject(‘func’) func:Function) {
// use func variable as needed
}
}

Now you have access to javascript variable and retain dependency injection concept and of course no magic variable!

 

 

Tagged , ,

D3 Network (Force Directed) Render with Node Margin

I had to build the network (massive relation) diagram to (potentially) replace the regular javascript drawing module due to the data to render getting bigger everyday. Instead of enhance the existing library to support more data, I rather decided to find the replacement of drawing library for the long term solution. D3 seems to be the best candidate with a bunch of incredible examples.

This example http://bl.ocks.org/mbostock/4062045 was the good start to customize to cover all requirements that the old render library does. Although it had many features and customizations to add and one of them was adding margin between link line and node.

There are a couple of reasons you would need margin to add margin between endpoint of line and node.

    1. Display node with various shape using d3.svg.symbol(), margin would make the the node shape (diamond, rectangle, circle, etc.) not to be overlapped by the line.
    2. If you have many line link to a single node, especially if you add arrow to the end of line, margin would make its display much cleaner.

Give some free space for node’s label.

Below is a sample of render; without margin we wouldn’t be able to indicate it’s shape.

Image

In tick event of d3.layout.force(), I replace (if any) “link.attr(“d”, function(d) { });” with following:


link.attr("d", function(d) {
 // calculate new link endpoint for both source and target
 // with specified margin
 var sourceX = d.source.x,
     sourceY = d.source.y,
     targetX = d.target.x,
     targetY = d.target.y;

 var X = Math.abs(targetX - sourceX);
 var Y = Math.abs(targetY - sourceY);
 var R = Math.sqrt(X*X + Y*Y);
 var xMargin = X * nodeMargin / R;
 var yMargin = Y * nodeMargin / R;

 if (sourceX > targetX) {
 sourceX = sourceX - xMargin,
 targetX = targetX + xMargin;
 }
 else {
 sourceX = sourceX + xMargin,
 targetX = targetX - xMargin;
 }

 if (sourceY > targetY) {
 sourceY = sourceY - yMargin,
 targetY = targetY + yMargin;
 }
 else {
 sourceY = sourceY + yMargin,
 targetY = targetY - yMargin;
 }
 d.x1 = sourceX;
 d.y1 = sourceY;
 d.x2 = targetX;
 d.y2 = targetY;
})
.attr("x1", function(d) { return d.x1; })
.attr("y1", function(d) { return d.y1; })
.attr("x2", function(d) { return d.x2; })
.attr("y2", function(d) { return d.y2; });

See a sample here – http://jsfiddle.net/iamarther/gZG5x/2/ (extended from http://bl.ocks.org/mbostock/4062045)

d3_mess_sample

Tagged , ,