├── .angular-cli.json
├── .editorconfig
├── .gitignore
├── README.md
├── package.json
├── src
├── app
│ ├── app.component.css
│ ├── app.component.html
│ ├── app.component.ts
│ ├── app.config.ts
│ ├── app.module.ts
│ ├── d3
│ │ ├── d3.service.ts
│ │ ├── directives
│ │ │ ├── draggable.directive.ts
│ │ │ ├── index.ts
│ │ │ └── zoomable.directive.ts
│ │ ├── index.ts
│ │ └── models
│ │ │ ├── force-directed-graph.ts
│ │ │ ├── index.ts
│ │ │ ├── link.ts
│ │ │ └── node.ts
│ └── visuals
│ │ ├── graph
│ │ ├── graph.component.css
│ │ └── graph.component.ts
│ │ └── shared
│ │ ├── index.ts
│ │ ├── link-visual
│ │ ├── link-visual.component.css
│ │ └── link-visual.component.ts
│ │ └── node-visual
│ │ ├── node-visual.component.css
│ │ └── node-visual.component.ts
├── assets
│ └── .gitkeep
├── environments
│ ├── environment.prod.ts
│ └── environment.ts
├── favicon.ico
├── index.html
├── main.ts
├── polyfills.ts
├── styles.css
└── tsconfig.json
└── tslint.json
/.angular-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "project": {
3 | "version": "1.0.0-beta.26",
4 | "name": "angular-d3-graph-example"
5 | },
6 | "apps": [
7 | {
8 | "root": "src",
9 | "outDir": "dist",
10 | "assets": [
11 | "assets",
12 | "favicon.ico"
13 | ],
14 | "index": "index.html",
15 | "main": "main.ts",
16 | "polyfills": "polyfills.ts",
17 | "tsconfig": "tsconfig.json",
18 | "prefix": "app",
19 | "mobile": false,
20 | "styles": [
21 | "styles.css"
22 | ],
23 | "scripts": [],
24 | "environmentSource": "environments/environment.ts",
25 | "environments": {
26 | "dev": "environments/environment.ts",
27 | "prod": "environments/environment.prod.ts"
28 | }
29 | }
30 | ],
31 | "e2e": {
32 | "protractor": {
33 | "config": "./protractor.conf.js"
34 | }
35 | },
36 | "test": {
37 | "karma": {
38 | "config": "./karma.conf.js"
39 | }
40 | },
41 | "defaults": {
42 | "styleExt": "css",
43 | "prefixInterfaces": false,
44 | "inline": {
45 | "style": false,
46 | "template": true
47 | },
48 | "spec": {
49 | "class": false,
50 | "component": false,
51 | "directive": false,
52 | "module": false,
53 | "pipe": false,
54 | "service": false
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 |
7 | # dependencies
8 | /node_modules
9 |
10 | # IDEs and editors
11 | /.idea
12 | .project
13 | .classpath
14 | .c9/
15 | *.launch
16 | .settings/
17 |
18 | # IDE - VSCode
19 | .vscode/*
20 | !.vscode/settings.json
21 | !.vscode/tasks.json
22 | !.vscode/launch.json
23 | !.vscode/extensions.json
24 |
25 | # misc
26 | /.sass-cache
27 | /connect.lock
28 | /coverage/*
29 | /libpeerconnection.log
30 | npm-debug.log
31 | testem.log
32 | /typings
33 |
34 | # e2e
35 | /e2e/*.js
36 | /e2e/*.map
37 |
38 | #System Files
39 | .DS_Store
40 | Thumbs.db
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Angular D3 Graph Example
2 |
3 | This is the code of a short tutorial [published on medium](https://medium.com/@lsharir/visualizing-data-with-angular-and-d3-209dde784aeb)
4 |
5 | This project was generated with [angular-cli](https://github.com/angular/angular-cli) version 1.0.0-beta.26.
6 |
7 | ## Development server
8 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
9 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-d3-graph-example",
3 | "version": "0.0.1",
4 | "license": "MIT",
5 | "angular-cli": {},
6 | "scripts": {
7 | "ng": "ng",
8 | "start": "ng serve",
9 | "lint": "ng lint"
10 | },
11 | "private": true,
12 | "dependencies": {
13 | "@angular/common": "^5.0.1",
14 | "@angular/compiler": "^5.0.1",
15 | "@angular/core": "^5.0.1",
16 | "@angular/forms": "^5.0.1",
17 | "@angular/http": "^5.0.1",
18 | "@angular/platform-browser": "^5.0.1",
19 | "@angular/platform-browser-dynamic": "^5.0.1",
20 | "@angular/router": "^5.0.1",
21 | "core-js": "^2.4.1",
22 | "d3": "^4.11.0",
23 | "rxjs": "^5.5.2",
24 | "ts-helpers": "^1.1.2",
25 | "zone.js": "^0.8.14"
26 | },
27 | "devDependencies": {
28 | "@angular/cli": "1.5.0",
29 | "@angular/compiler-cli": "^5.0.1",
30 | "@types/d3": "^4.4.1",
31 | "@types/node": "^6.0.60",
32 | "codelyzer": "~4.0.0",
33 | "ts-node": "~3.2.0",
34 | "tslint": "^5.7.0",
35 | "typescript": "2.4.2"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/app/app.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lsharir/angular-d3-graph-example/57b88e1fbaef6dd565c6a0a2ddaa05b44155215d/src/app/app.component.css
--------------------------------------------------------------------------------
/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import APP_CONFIG from './app.config';
3 | import { Node, Link } from './d3';
4 |
5 | @Component({
6 | selector: 'app-root',
7 | templateUrl: './app.component.html',
8 | styleUrls: ['./app.component.css']
9 | })
10 |
11 | export class AppComponent {
12 | nodes: Node[] = [];
13 | links: Link[] = [];
14 |
15 | constructor() {
16 | const N = APP_CONFIG.N,
17 | getIndex = number => number - 1;
18 |
19 | /** constructing the nodes array */
20 | for (let i = 1; i <= N; i++) {
21 | this.nodes.push(new Node(i));
22 | }
23 |
24 | for (let i = 1; i <= N; i++) {
25 | for (let m = 2; i * m <= N; m++) {
26 | /** increasing connections toll on connecting nodes */
27 | this.nodes[getIndex(i)].linkCount++;
28 | this.nodes[getIndex(i * m)].linkCount++;
29 |
30 | /** connecting the nodes before starting the simulation */
31 | this.links.push(new Link(i, i * m));
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/app/app.config.ts:
--------------------------------------------------------------------------------
1 | const CONFIG = {
2 | N : 100,
3 | SPECTRUM: [
4 | // "rgb(222,237,250)"
5 | "rgb(176,212,243)",
6 | "rgb(128,186,236)",
7 | "rgb(77,158,228)",
8 | "rgb(38,137,223)",
9 | "rgb(0,116,217)",
10 | "rgb(0,106,197)"
11 | // "rgb(0,94,176)"
12 | // "rgb(0,82,154)"
13 | // "rgb(0,60,113)"
14 | ]
15 | }
16 |
17 | export default CONFIG;
18 |
--------------------------------------------------------------------------------
/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { BrowserModule } from '@angular/platform-browser';
2 | import { NgModule } from '@angular/core';
3 | import { FormsModule } from '@angular/forms';
4 | import { HttpModule } from '@angular/http';
5 |
6 | import { D3Service, D3_DIRECTIVES } from './d3';
7 |
8 | import { AppComponent } from './app.component';
9 |
10 | import { GraphComponent } from './visuals/graph/graph.component';
11 | import { SHARED_VISUALS } from './visuals/shared';
12 |
13 | @NgModule({
14 | declarations: [
15 | AppComponent,
16 | GraphComponent,
17 | ...SHARED_VISUALS,
18 | ...D3_DIRECTIVES
19 | ],
20 | imports: [
21 | BrowserModule,
22 | FormsModule,
23 | HttpModule
24 | ],
25 | providers: [D3Service],
26 | bootstrap: [AppComponent]
27 | })
28 | export class AppModule { }
29 |
--------------------------------------------------------------------------------
/src/app/d3/d3.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable, EventEmitter } from '@angular/core';
2 | import { Node, Link, ForceDirectedGraph } from './models';
3 | import * as d3 from 'd3';
4 |
5 | @Injectable()
6 | export class D3Service {
7 | /** This service will provide methods to enable user interaction with elements
8 | * while maintaining the d3 simulations physics
9 | */
10 | constructor() { }
11 |
12 | /** A method to bind a pan and zoom behaviour to an svg element */
13 | applyZoomableBehaviour(svgElement, containerElement) {
14 | let svg, container, zoomed, zoom;
15 |
16 | svg = d3.select(svgElement);
17 | container = d3.select(containerElement);
18 |
19 | zoomed = () => {
20 | const transform = d3.event.transform;
21 | container.attr('transform', 'translate(' + transform.x + ',' + transform.y + ') scale(' + transform.k + ')');
22 | }
23 |
24 | zoom = d3.zoom().on('zoom', zoomed);
25 | svg.call(zoom);
26 | }
27 |
28 | /** A method to bind a draggable behaviour to an svg element */
29 | applyDraggableBehaviour(element, node: Node, graph: ForceDirectedGraph) {
30 | const d3element = d3.select(element);
31 |
32 | function started() {
33 | /** Preventing propagation of dragstart to parent elements */
34 | d3.event.sourceEvent.stopPropagation();
35 |
36 | if (!d3.event.active) {
37 | graph.simulation.alphaTarget(0.3).restart();
38 | }
39 |
40 | d3.event.on('drag', dragged).on('end', ended);
41 |
42 | function dragged() {
43 | node.fx = d3.event.x;
44 | node.fy = d3.event.y;
45 | }
46 |
47 | function ended() {
48 | if (!d3.event.active) {
49 | graph.simulation.alphaTarget(0);
50 | }
51 |
52 | node.fx = null;
53 | node.fy = null;
54 | }
55 | }
56 |
57 | d3element.call(d3.drag()
58 | .on('start', started));
59 | }
60 |
61 | /** The interactable graph we will simulate in this article
62 | * This method does not interact with the document, purely physical calculations with d3
63 | */
64 | getForceDirectedGraph(nodes: Node[], links: Link[], options: { width, height }) {
65 | const sg = new ForceDirectedGraph(nodes, links, options);
66 | return sg;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/app/d3/directives/draggable.directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, ElementRef, OnInit } from '@angular/core';
2 | import { Node, ForceDirectedGraph } from '../models';
3 | import { D3Service } from '../d3.service';
4 |
5 | @Directive({
6 | selector: '[draggableNode]'
7 | })
8 | export class DraggableDirective implements OnInit {
9 | @Input('draggableNode') draggableNode: Node;
10 | @Input('draggableInGraph') draggableInGraph: ForceDirectedGraph;
11 |
12 | constructor(private d3Service: D3Service, private _element: ElementRef) { }
13 |
14 | ngOnInit() {
15 | this.d3Service.applyDraggableBehaviour(this._element.nativeElement, this.draggableNode, this.draggableInGraph);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/app/d3/directives/index.ts:
--------------------------------------------------------------------------------
1 | import { ZoomableDirective } from './zoomable.directive';
2 | import { DraggableDirective } from './draggable.directive';
3 |
4 | export * from './zoomable.directive';
5 | export * from './draggable.directive';
6 |
7 | export const D3_DIRECTIVES = [
8 | ZoomableDirective,
9 | DraggableDirective
10 | ];
--------------------------------------------------------------------------------
/src/app/d3/directives/zoomable.directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, ElementRef, OnInit } from '@angular/core';
2 | import { D3Service } from '../d3.service';
3 |
4 | @Directive({
5 | selector: '[zoomableOf]'
6 | })
7 | export class ZoomableDirective implements OnInit {
8 | @Input('zoomableOf') zoomableOf: ElementRef;
9 |
10 | constructor(private d3Service: D3Service, private _element: ElementRef) {}
11 |
12 | ngOnInit() {
13 | this.d3Service.applyZoomableBehaviour(this.zoomableOf, this._element.nativeElement);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/app/d3/index.ts:
--------------------------------------------------------------------------------
1 | export * from './d3.service';
2 | export * from './models';
3 | export * from './directives';
4 |
--------------------------------------------------------------------------------
/src/app/d3/models/force-directed-graph.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from '@angular/core';
2 | import { Link } from './link';
3 | import { Node } from './node';
4 | import * as d3 from 'd3';
5 |
6 | const FORCES = {
7 | LINKS: 1 / 50,
8 | COLLISION: 1,
9 | CHARGE: -1
10 | }
11 |
12 | export class ForceDirectedGraph {
13 | public ticker: EventEmitter> = new EventEmitter();
14 | public simulation: d3.Simulation;
15 |
16 | public nodes: Node[] = [];
17 | public links: Link[] = [];
18 |
19 | constructor(nodes, links, options: { width, height }) {
20 | this.nodes = nodes;
21 | this.links = links;
22 |
23 | this.initSimulation(options);
24 | }
25 |
26 | connectNodes(source, target) {
27 | let link;
28 |
29 | if (!this.nodes[source] || !this.nodes[target]) {
30 | throw new Error('One of the nodes does not exist');
31 | }
32 |
33 | link = new Link(source, target);
34 | this.simulation.stop();
35 | this.links.push(link);
36 | this.simulation.alphaTarget(0.3).restart();
37 |
38 | this.initLinks();
39 | }
40 |
41 | initNodes() {
42 | if (!this.simulation) {
43 | throw new Error('simulation was not initialized yet');
44 | }
45 |
46 | this.simulation.nodes(this.nodes);
47 | }
48 |
49 | initLinks() {
50 | if (!this.simulation) {
51 | throw new Error('simulation was not initialized yet');
52 | }
53 |
54 | this.simulation.force('links',
55 | d3.forceLink(this.links)
56 | .id(d => d['id'])
57 | .strength(FORCES.LINKS)
58 | );
59 | }
60 |
61 | initSimulation(options) {
62 | if (!options || !options.width || !options.height) {
63 | throw new Error('missing options when initializing simulation');
64 | }
65 |
66 | /** Creating the simulation */
67 | if (!this.simulation) {
68 | const ticker = this.ticker;
69 |
70 | this.simulation = d3.forceSimulation()
71 | .force('charge',
72 | d3.forceManyBody()
73 | .strength(d => FORCES.CHARGE * d['r'])
74 | )
75 | .force('collide',
76 | d3.forceCollide()
77 | .strength(FORCES.COLLISION)
78 | .radius(d => d['r'] + 5).iterations(2)
79 | );
80 |
81 | // Connecting the d3 ticker to an angular event emitter
82 | this.simulation.on('tick', function () {
83 | ticker.emit(this);
84 | });
85 |
86 | this.initNodes();
87 | this.initLinks();
88 | }
89 |
90 | /** Updating the central force of the simulation */
91 | this.simulation.force('centers', d3.forceCenter(options.width / 2, options.height / 2));
92 |
93 | /** Restarting the simulation internal timer */
94 | this.simulation.restart();
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/app/d3/models/index.ts:
--------------------------------------------------------------------------------
1 | export * from './node';
2 | export * from './link';
3 | export * from './force-directed-graph';
4 |
--------------------------------------------------------------------------------
/src/app/d3/models/link.ts:
--------------------------------------------------------------------------------
1 | import { Node } from './';
2 |
3 | export class Link implements d3.SimulationLinkDatum {
4 | // optional - defining optional implementation properties - required for relevant typing assistance
5 | index?: number;
6 |
7 | // must - defining enforced implementation properties
8 | source: Node | string | number;
9 | target: Node | string | number;
10 |
11 | constructor(source, target) {
12 | this.source = source;
13 | this.target = target;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/app/d3/models/node.ts:
--------------------------------------------------------------------------------
1 | import APP_CONFIG from '../../app.config';
2 |
3 | export class Node implements d3.SimulationNodeDatum {
4 | // optional - defining optional implementation properties - required for relevant typing assistance
5 | index?: number;
6 | x?: number;
7 | y?: number;
8 | vx?: number;
9 | vy?: number;
10 | fx?: number | null;
11 | fy?: number | null;
12 |
13 | id: string;
14 | linkCount: number = 0;
15 |
16 | constructor(id) {
17 | this.id = id;
18 | }
19 |
20 | normal = () => {
21 | return Math.sqrt(this.linkCount / APP_CONFIG.N);
22 | }
23 |
24 | get r() {
25 | return 50 * this.normal() + 10;
26 | }
27 |
28 | get fontSize() {
29 | return (30 * this.normal() + 10) + 'px';
30 | }
31 |
32 | get color() {
33 | let index = Math.floor(APP_CONFIG.SPECTRUM.length * this.normal());
34 | return APP_CONFIG.SPECTRUM[index];
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/app/visuals/graph/graph.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lsharir/angular-d3-graph-example/57b88e1fbaef6dd565c6a0a2ddaa05b44155215d/src/app/visuals/graph/graph.component.css
--------------------------------------------------------------------------------
/src/app/visuals/graph/graph.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, ChangeDetectorRef, HostListener, ChangeDetectionStrategy, OnInit, AfterViewInit } from '@angular/core';
2 | import { D3Service, ForceDirectedGraph, Node } from '../../d3';
3 |
4 | @Component({
5 | selector: 'graph',
6 | changeDetection: ChangeDetectionStrategy.OnPush,
7 | template: `
8 |
15 | `,
16 | styleUrls: ['./graph.component.css']
17 | })
18 | export class GraphComponent implements OnInit, AfterViewInit {
19 | @Input('nodes') nodes;
20 | @Input('links') links;
21 | graph: ForceDirectedGraph;
22 | private _options: { width, height } = { width: 800, height: 600 };
23 |
24 | @HostListener('window:resize', ['$event'])
25 | onResize(event) {
26 | this.graph.initSimulation(this.options);
27 | }
28 |
29 |
30 | constructor(private d3Service: D3Service, private ref: ChangeDetectorRef) {}
31 |
32 | ngOnInit() {
33 | /** Receiving an initialized simulated graph from our custom d3 service */
34 | this.graph = this.d3Service.getForceDirectedGraph(this.nodes, this.links, this.options);
35 |
36 | /** Binding change detection check on each tick
37 | * This along with an onPush change detection strategy should enforce checking only when relevant!
38 | * This improves scripting computation duration in a couple of tests I've made, consistently.
39 | * Also, it makes sense to avoid unnecessary checks when we are dealing only with simulations data binding.
40 | */
41 | this.graph.ticker.subscribe((d) => {
42 | this.ref.markForCheck();
43 | });
44 | }
45 |
46 | ngAfterViewInit() {
47 | this.graph.initSimulation(this.options);
48 | }
49 |
50 | get options() {
51 | return this._options = {
52 | width: window.innerWidth,
53 | height: window.innerHeight
54 | };
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/app/visuals/shared/index.ts:
--------------------------------------------------------------------------------
1 | export * from './node-visual/node-visual.component';
2 | export * from './link-visual/link-visual.component';
3 |
4 | import { NodeVisualComponent } from './node-visual/node-visual.component';
5 | import { LinkVisualComponent } from './link-visual/link-visual.component';
6 |
7 | export const SHARED_VISUALS = [
8 | NodeVisualComponent,
9 | LinkVisualComponent
10 | ];
11 |
--------------------------------------------------------------------------------
/src/app/visuals/shared/link-visual/link-visual.component.css:
--------------------------------------------------------------------------------
1 | .link {
2 | stroke-width: 0.25;
3 | stroke: rgb(222,237,250);
4 | }
5 |
--------------------------------------------------------------------------------
/src/app/visuals/shared/link-visual/link-visual.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 | import { Link } from '../../../d3';
3 |
4 | @Component({
5 | selector: '[linkVisual]',
6 | template: `
7 |
14 | `,
15 | styleUrls: ['./link-visual.component.css']
16 | })
17 | export class LinkVisualComponent {
18 | @Input('linkVisual') link: Link;
19 | }
20 |
--------------------------------------------------------------------------------
/src/app/visuals/shared/node-visual/node-visual.component.css:
--------------------------------------------------------------------------------
1 | .node {
2 | cursor: pointer;
3 | transition: stroke-width 0.1s ease-out,
4 | fill 0.1s ease-out,
5 | stroke 0.1s ease-out;
6 |
7 | stroke: white;
8 | stroke-width: 0.25;
9 | }
10 |
11 | .node-name {
12 | font-family: 'Lato';
13 | text-anchor: middle;
14 | alignment-baseline: central;
15 | font-weight: 300;
16 | fill: white;
17 | }
18 |
--------------------------------------------------------------------------------
/src/app/visuals/shared/node-visual/node-visual.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 | import { Node } from '../../../d3';
3 |
4 | @Component({
5 | selector: '[nodeVisual]',
6 | template: `
7 |
8 |
14 |
15 |
18 | {{node.id}}
19 |
20 |
21 | `,
22 | styleUrls: ['./node-visual.component.css']
23 | })
24 | export class NodeVisualComponent {
25 | @Input('nodeVisual') node: Node;
26 | }
27 |
--------------------------------------------------------------------------------
/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lsharir/angular-d3-graph-example/57b88e1fbaef6dd565c6a0a2ddaa05b44155215d/src/assets/.gitkeep
--------------------------------------------------------------------------------
/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // The file contents for the current environment will overwrite these during build.
2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do
3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead.
4 | // The list of which env maps to which file can be found in `angular-cli.json`.
5 |
6 | export const environment = {
7 | production: false
8 | };
9 |
--------------------------------------------------------------------------------
/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lsharir/angular-d3-graph-example/57b88e1fbaef6dd565c6a0a2ddaa05b44155215d/src/favicon.ico
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AngularD3GraphExample
6 |
7 |
8 |
9 |
10 |
11 |
12 | Loading...
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 | import { enableProdMode } from '@angular/core';
3 | import { environment } from './environments/environment';
4 | import { AppModule } from './app/app.module';
5 |
6 | if (environment.production) {
7 | enableProdMode();
8 | }
9 |
10 | platformBrowserDynamic().bootstrapModule(AppModule);
11 |
--------------------------------------------------------------------------------
/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | // This file includes polyfills needed by Angular and is loaded before
2 | // the app. You can add your own extra polyfills to this file.
3 | import 'core-js/es6/symbol';
4 | import 'core-js/es6/object';
5 | import 'core-js/es6/function';
6 | import 'core-js/es6/parse-int';
7 | import 'core-js/es6/parse-float';
8 | import 'core-js/es6/number';
9 | import 'core-js/es6/math';
10 | import 'core-js/es6/string';
11 | import 'core-js/es6/date';
12 | import 'core-js/es6/array';
13 | import 'core-js/es6/regexp';
14 | import 'core-js/es6/map';
15 | import 'core-js/es6/set';
16 | import 'core-js/es6/reflect';
17 |
18 | import 'core-js/es7/reflect';
19 | import 'zone.js/dist/zone';
20 |
--------------------------------------------------------------------------------
/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 | body, html {
3 | margin: 0;
4 | padding: 0;
5 | background: white;
6 | }
7 |
--------------------------------------------------------------------------------
/src/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "",
4 | "declaration": false,
5 | "emitDecoratorMetadata": true,
6 | "experimentalDecorators": true,
7 | "lib": ["es6", "dom"],
8 | "mapRoot": "./",
9 | "module": "es6",
10 | "moduleResolution": "node",
11 | "outDir": "../dist/out-tsc",
12 | "sourceMap": true,
13 | "target": "es5",
14 | "typeRoots": [
15 | "../node_modules/@types"
16 | ]
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "callable-types": true,
7 | "class-name": true,
8 | "comment-format": [
9 | true,
10 | "check-space"
11 | ],
12 | "curly": true,
13 | "eofline": true,
14 | "forin": true,
15 | "import-blacklist": [true, "rxjs"],
16 | "import-spacing": true,
17 | "indent": [
18 | true,
19 | "spaces"
20 | ],
21 | "interface-over-type-literal": true,
22 | "label-position": true,
23 | "max-line-length": [
24 | true,
25 | 140
26 | ],
27 | "member-access": false,
28 | "member-ordering": [
29 | true,
30 | "static-before-instance",
31 | "variables-before-functions"
32 | ],
33 | "no-arg": true,
34 | "no-bitwise": true,
35 | "no-console": [
36 | true,
37 | "debug",
38 | "info",
39 | "time",
40 | "timeEnd",
41 | "trace"
42 | ],
43 | "no-construct": true,
44 | "no-debugger": true,
45 | "no-duplicate-variable": true,
46 | "no-empty": false,
47 | "no-empty-interface": true,
48 | "no-eval": true,
49 | "no-inferrable-types": true,
50 | "no-shadowed-variable": true,
51 | "no-string-literal": false,
52 | "no-string-throw": true,
53 | "no-switch-case-fall-through": true,
54 | "no-trailing-whitespace": true,
55 | "no-unused-expression": true,
56 | "no-use-before-declare": true,
57 | "no-var-keyword": true,
58 | "object-literal-sort-keys": false,
59 | "one-line": [
60 | true,
61 | "check-open-brace",
62 | "check-catch",
63 | "check-else",
64 | "check-whitespace"
65 | ],
66 | "prefer-const": true,
67 | "quotemark": [
68 | true,
69 | "single"
70 | ],
71 | "radix": true,
72 | "semicolon": [
73 | "always"
74 | ],
75 | "triple-equals": [
76 | true,
77 | "allow-null-check"
78 | ],
79 | "typedef-whitespace": [
80 | true,
81 | {
82 | "call-signature": "nospace",
83 | "index-signature": "nospace",
84 | "parameter": "nospace",
85 | "property-declaration": "nospace",
86 | "variable-declaration": "nospace"
87 | }
88 | ],
89 | "typeof-compare": true,
90 | "unified-signatures": true,
91 | "variable-name": false,
92 | "whitespace": [
93 | true,
94 | "check-branch",
95 | "check-decl",
96 | "check-operator",
97 | "check-separator",
98 | "check-type"
99 | ],
100 |
101 | "directive-selector": [true, "attribute", "app", "camelCase"],
102 | "component-selector": [true, "element", "app", "kebab-case"],
103 | "use-input-property-decorator": true,
104 | "use-output-property-decorator": true,
105 | "use-host-property-decorator": true,
106 | "no-input-rename": true,
107 | "no-output-rename": true,
108 | "use-life-cycle-interface": true,
109 | "use-pipe-transform-interface": true,
110 | "component-class-suffix": true,
111 | "directive-class-suffix": true,
112 | "no-access-missing-member": true,
113 | "templates-use-public": true,
114 | "invoke-injectable": true
115 | }
116 | }
117 |
--------------------------------------------------------------------------------