import { Component } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import { NodeDataService } from './tree.service';
declare var d3: any;
export class Hero {
id: number;
name: string;
}
@Component({
selector: 'my-app',
template: `
<div id="body">
<h1>Hello {{name}}</h1>
<!--<router-outlet></router-outlet>-->
</div>
`,
providers: [NodeDataService]
})
export class AppComponent {
name = 'D3!';
public margin = {
top: 20,
right: 120,
bottom: 20,
left: 120
};
width = 1400 - this.margin.right - this.margin.left;
height = 800 - this.margin.top - this.margin.bottom;
public inst: number = 1;
public duration: number = 750;
public rectW: number = 60;
public rectH: number = 30;
public zm: any;
public collapse: Function;
public d: any;
public error: any;
public view: any;
public parent: any;
public visitFn: any;
public childrenFn: any;
public links: any;
public tree: any;
public maxLabelLength: any;
public svg: any;
public drag: any;
public dragmove: any;
// how much horz space to give a flaring of branches (menus, day/night behaviour)
public BRANCH_SPACE = 80;
constructor(private _nodeDataService: NodeDataService) {
}
ngOnInit() {
this.tree = d3.layout.tree().size([this.height, this.width]);
this.drag = d3.behavior.drag()
.on("drag", this.dragmove);
this.dragmove = (d) => {
var x = d3.event.x;
var y = d3.event.y;
d3.select(this).attr("transform", "translate(" + x + "," + y + ")");
};
this.svg = d3.select("#body").append("svg")
.attr("width", this.width + this.margin.right + this.margin.left)
.attr("height", this.height + this.margin.top + this.margin.bottom)
.append("g")
.call(this.drag)
.attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")");
this.getNodes();
//this.zm.translate([350, 20]);
}
diagonal = d3.svg.diagonal().projection((d: any) => {
// return [d.x + this.rectW / 2, d.y + this.rectH / 2];
return [d.y, d.x];
});
// our own connector flavour, where we take long to flare, but flare steeper than
// the original, staying straight out of the source node longer
// diagonal = (d) => {
// // y is x, somehow...
// var y2, delta, dir;
// // var dir = d.source.x < d.target.x ?
// // 1 :
// // -1;
// var line = 'M' + p(d.source); // start at source
// function p(o) {
// return o.y + ',' + o.x;
// }
// if (d.source.x === d.target.x) {
// // STRAIGHT LINE, just do that
// line += 'L' + p(d.target);
// } else {
// // CURVE, get to the start
// y2 = d.target.y - this.BRANCH_SPACE;
// line += 'L' + p({
// y: y2,
// x: d.source.x
// });
// // the bigger the vert diff, the farther the control point
// delta = (Math.abs(d.target.x) - Math.abs(d.source.x)) * 0.15;
// dir = d.source.x > d.target.x ? 1 : -1;
// // start control point: gentle
// line += 'C' + p({
// y: y2 + this.BRANCH_SPACE / 2,
// x: d.source.x
// });
// // end control point: steep
// line += ' ' + p({
// y: y2,
// x: d.target.x - (delta * dir)
// });
// // go to the end
// line += ' ' + p(d.target);
// }
// return line;
// }
// A recursive helper function for performing some setup by walking through all nodes
public visit = (parent: any, visitFn: any, childrenFn: any): void => {
if (typeof childrenFn !== 'function') {
//default childrenFn =
childrenFn = function (node) {
return node.children || null;
};
}
if (!parent) {
return;
}
visitFn(parent);
var children = childrenFn(parent);
if (children) {
for (var i = 0, count = children.length; i < count; i++) {
this.visit(children[i], visitFn, childrenFn);
}
}
}
// this.visit(this._nodeDataService.root, function (d: any) {
// this.totalNodes++;
// this.maxLabelLength = Math.max(d.name.length, this.maxLabelLength);
// }, function (d: any) {
// return d.children && d.children.length > 0 ? d.children : null;
// });
ngAfterViewInit() {
}
// zm.translate([350,20]);
getNodes() {
this._nodeDataService.getNodes().subscribe(
// the first argument is a function which runs on success
data => {
this._nodeDataService.root = data;
debugger;
this._nodeDataService.root.x0 = 0;
this._nodeDataService.root.y0 = this.height / 2;
console.log("height", this.height);
this.collapse = (d: any) => {
if (d.children) {
d._children = d.children;
d._children.forEach(this.collapse);
d.children = null;
}
};
this._nodeDataService.root.children.forEach(this.collapse);
this.update(this._nodeDataService.root);
// Call visit function to establish maxLabelLength
this.visit(this._nodeDataService.root, (d: any) => {
let totalNodes: number = 0;
totalNodes++;
this.maxLabelLength = Math.max(d.name.length, this.maxLabelLength);
}, (d: any) => {
return d.children && d.children.length > 0 ? d.children : null;
});
},
// the second argument is a function which runs on error
err => console.error(err),
// the third argument is a function which runs on completion
// () => console.log('done loading Nodes', this._nodeDataService.root)
)
};
//necessary so that zoom knows where to zoom and unzoom from
// zm.translate([350, 20]);
selectFrame = d3.select(self.frameElement).style("height", "800px");
update = (source: any) => {
let i: number = 0;
// Compute the new tree layout.
let nodes = this.tree.nodes(this._nodeDataService.root).reverse(),
links = this.tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach((n: any) => {
n.y = n.depth * 180;
});
// Update the nodes…
let node = this.svg.selectAll("g.node")
.data(nodes, function (n: any) {
return n.size || (n.id = ++i);
}
);
// Enter any new nodes at the parent's previous position.
let nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", (n: any) => {
return "translate(" + source.y0 + "," + source.x0 + ")";
})
.on("click", this.click);
nodeEnter.append("rect")
.attr("width", this.rectW)
.attr("height", this.rectH)
.attr("stroke", "black")
.attr("stroke-width", 1)
.style("fill", (d) => {
return d._children ? "lightsteelblue" : "#fff";
});
nodeEnter.append("text")
.attr("x", this.rectW / 2)
.attr("y", this.rectH / 2)
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text((d: any) => {
return d.name;
});
// Transition nodes to their new position.
let nodeUpdate = node.transition()
.duration(this.duration)
.attr("transform", (d: any) => {
return "translate(" + d.y + "," + d.x + ")";
});
nodeUpdate.select("rect")
.attr("width", this.rectW)
.attr("height", this.rectH)
.attr("stroke", "black")
.attr("stroke-width", 1)
.style("fill", (d: any) => {
return d._children ? "lightsteelblue" : "#fff";
});
nodeUpdate.select("text")
.style("fill-opacity", 1);
// Transition exiting nodes to the parent's new position.
let nodeExit = node.exit().transition()
.duration(this.duration)
.attr("transform", (n: any) => {
return "translate(" + source.y + "," + source.x + ")";
})
.remove();
nodeExit.select("rect")
.attr("width", this.rectW)
.attr("height", this.rectH)
//.attr("width", bbox.getBBox().width)""
//.attr("height", bbox.getBBox().height)
.attr("stroke", "black")
.attr("stroke-width", 1);
nodeExit.select("text");
// Update the links…
var link = this.svg.selectAll("path.link")
.data(links, function (n: any) {
return n.target.id;
});
// Enter any new links at the parent's previous position.
// Enter any new links at the parent's previous position.
link.enter().insert("path", "g")
.attr("class", "link")
.attr("x", this.rectW / 2)
.attr("y", this.rectH / 2)
.attr("d", (d) => {
var o = {
x: source.x0,
y: source.y0
};
return this.diagonal({
source: o,
target: o
});
});
// Transition links to their new position.
link.transition()
.duration(this.duration)
.attr("d", this.diagonal);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(this.duration)
.attr("d", (n: any) => {
var o = {
x: source.x,
y: source.y
}
return this.diagonal({
source: o,
target: o
});
})
// Stash the old positions for transition.
nodes.forEach((n: any) => {
n.x0 = n.x;
n.y0 = n.y;
});
};
click = (d): void => {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
this.update(d);
};
redraw = (d) => {
this.svg.attr("transform",
"translate(" + d3.event.translate + ")"
+ " scale(" + d3.event.scale + ")");
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { HttpModule } from '@angular/http';
@NgModule({
imports: [
BrowserModule,
FormsModule,
HttpModule
],
declarations: [
AppComponent
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/
import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from "@angular/http";
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
@Injectable()
export class NodeDataService {
public root: any
constructor(private http: Http) {
}
getNodes(): Observable<any> {
return this.http.get('app/flare.json')
.map(this.extractData);
}
private extractData(res: Response) {
let body = res.json();
return body || {};
}
}
{
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{
"name": "AgglomerativeCluster",
"size": 3938
},
{
"name": "CommunityStructure",
"size": 3812
},
{
"name": "HierarchicalCluster",
"size": 6714
},
{
"name": "MergeEdge",
"size": 743
}
]
},
{
"name": "graph",
"children": [
{
"name": "BetweennessCentrality",
"size": 3534
},
{
"name": "LinkDistance",
"size": 5731
},
{
"name": "MaxFlowMinCut",
"size": 7840
},
{
"name": "ShortestPaths",
"size": 5914
},
{
"name": "SpanningTree",
"size": 3416
}
]
},
{
"name": "optimization",
"children": [
{
"name": "AspectRatioBanker",
"size": 7074
}
]
}
]
},
{
"name": "animate",
"children": [
{
"name": "Easing",
"size": 17010
},
{
"name": "FunctionSequence",
"size": 5842
},
{
"name": "interpolate",
"children": [
{
"name": "ArrayInterpolator",
"size": 1983
},
{
"name": "ColorInterpolator",
"size": 2047
},
{
"name": "DateInterpolator",
"size": 1375
},
{
"name": "Interpolator",
"size": 8746
},
{
"name": "MatrixInterpolator",
"size": 2202
},
{
"name": "NumberInterpolator",
"size": 1382
},
{
"name": "ObjectInterpolator",
"size": 1629
},
{
"name": "PointInterpolator",
"size": 1675
},
{
"name": "RectangleInterpolator",
"size": 2042
}
]
},
{
"name": "ISchedulable",
"size": 1041
},
{
"name": "Parallel",
"size": 5176
},
{
"name": "Pause",
"size": 449
},
{
"name": "Scheduler",
"size": 5593
},
{
"name": "Sequence",
"size": 5534
},
{
"name": "Transition",
"size": 9201
},
{
"name": "Transitioner",
"size": 19975
},
{
"name": "TransitionEvent",
"size": 1116
},
{
"name": "Tween",
"size": 6006
}
]
},
{
"name": "data",
"children": [
{
"name": "converters",
"children": [
{
"name": "Converters",
"size": 721
},
{
"name": "DelimitedTextConverter",
"size": 4294
},
{
"name": "GraphMLConverter",
"size": 9800
},
{
"name": "IDataConverter",
"size": 1314
},
{
"name": "JSONConverter",
"size": 2220
}
]
},
{
"name": "DataField",
"size": 1759
},
{
"name": "DataSchema",
"size": 2165
},
{
"name": "DataSet",
"size": 586
},
{
"name": "DataSource",
"size": 3331
},
{
"name": "DataTable",
"size": 772
},
{
"name": "DataUtil",
"size": 3322
}
]
},
{
"name": "display",
"children": [
{
"name": "DirtySprite",
"size": 8833
},
{
"name": "LineSprite",
"size": 1732
},
{
"name": "RectSprite",
"size": 3623
},
{
"name": "TextSprite",
"size": 10066
}
]
},
{
"name": "flex",
"children": [
{
"name": "FlareVis",
"size": 4116
}
]
},
{
"name": "physics",
"children": [
{
"name": "DragForce",
"size": 1082
},
{
"name": "GravityForce",
"size": 1336
},
{
"name": "IForce",
"size": 319
},
{
"name": "NBodyForce",
"size": 10498
},
{
"name": "Particle",
"size": 2822
},
{
"name": "Simulation",
"size": 9983
},
{
"name": "Spring",
"size": 2213
},
{
"name": "SpringForce",
"size": 1681
}
]
},
{
"name": "query",
"children": [
{
"name": "AggregateExpression",
"size": 1616
},
{
"name": "And",
"size": 1027
},
{
"name": "Arithmetic",
"size": 3891
},
{
"name": "Average",
"size": 891
},
{
"name": "BinaryExpression",
"size": 2893
},
{
"name": "Comparison",
"size": 5103
},
{
"name": "CompositeExpression",
"size": 3677
},
{
"name": "Count",
"size": 781
},
{
"name": "DateUtil",
"size": 4141
},
{
"name": "Distinct",
"size": 933
},
{
"name": "Expression",
"size": 5130
},
{
"name": "ExpressionIterator",
"size": 3617
},
{
"name": "Fn",
"size": 3240
},
{
"name": "If",
"size": 2732
},
{
"name": "IsA",
"size": 2039
},
{
"name": "Literal",
"size": 1214
},
{
"name": "Match",
"size": 3748
},
{
"name": "Maximum",
"size": 843
},
{
"name": "methods",
"children": [
{
"name": "add",
"size": 593
},
{
"name": "and",
"size": 330
},
{
"name": "average",
"size": 287
},
{
"name": "count",
"size": 277
},
{
"name": "distinct",
"size": 292
},
{
"name": "div",
"size": 595
},
{
"name": "eq",
"size": 594
},
{
"name": "fn",
"size": 460
},
{
"name": "gt",
"size": 603
},
{
"name": "gte",
"size": 625
},
{
"name": "iff",
"size": 748
},
{
"name": "isa",
"size": 461
},
{
"name": "lt",
"size": 597
},
{
"name": "lte",
"size": 619
},
{
"name": "max",
"size": 283
},
{
"name": "min",
"size": 283
},
{
"name": "mod",
"size": 591
},
{
"name": "mul",
"size": 603
},
{
"name": "neq",
"size": 599
},
{
"name": "not",
"size": 386
},
{
"name": "or",
"size": 323
},
{
"name": "orderby",
"size": 307
},
{
"name": "range",
"size": 772
},
{
"name": "select",
"size": 296
},
{
"name": "stddev",
"size": 363
},
{
"name": "sub",
"size": 600
},
{
"name": "sum",
"size": 280
},
{
"name": "update",
"size": 307
},
{
"name": "variance",
"size": 335
},
{
"name": "where",
"size": 299
},
{
"name": "xor",
"size": 354
},
{
"name": "_",
"size": 264
}
]
},
{
"name": "Minimum",
"size": 843
},
{
"name": "Not",
"size": 1554
},
{
"name": "Or",
"size": 970
},
{
"name": "Query",
"size": 13896
},
{
"name": "Range",
"size": 1594
},
{
"name": "StringUtil",
"size": 4130
},
{
"name": "Sum",
"size": 791
},
{
"name": "Variable",
"size": 1124
},
{
"name": "Variance",
"size": 1876
},
{
"name": "Xor",
"size": 1101
}
]
},
{
"name": "scale",
"children": [
{
"name": "IScaleMap",
"size": 2105
},
{
"name": "LinearScale",
"size": 1316
},
{
"name": "LogScale",
"size": 3151
},
{
"name": "OrdinalScale",
"size": 3770
},
{
"name": "QuantileScale",
"size": 2435
},
{
"name": "QuantitativeScale",
"size": 4839
},
{
"name": "RootScale",
"size": 1756
},
{
"name": "Scale",
"size": 4268
},
{
"name": "ScaleType",
"size": 1821
},
{
"name": "TimeScale",
"size": 5833
}
]
},
{
"name": "util",
"children": [
{
"name": "Arrays",
"size": 8258
},
{
"name": "Colors",
"size": 10001
},
{
"name": "Dates",
"size": 8217
},
{
"name": "Displays",
"size": 12555
},
{
"name": "Filter",
"size": 2324
},
{
"name": "Geometry",
"size": 10993
},
{
"name": "heap",
"children": [
{
"name": "FibonacciHeap",
"size": 9354
},
{
"name": "HeapNode",
"size": 1233
}
]
},
{
"name": "IEvaluable",
"size": 335
},
{
"name": "IPredicate",
"size": 383
},
{
"name": "IValueProxy",
"size": 874
},
{
"name": "math",
"children": [
{
"name": "DenseMatrix",
"size": 3165
},
{
"name": "IMatrix",
"size": 2815
},
{
"name": "SparseMatrix",
"size": 3366
}
]
},
{
"name": "Maths",
"size": 17705
},
{
"name": "Orientation",
"size": 1486
},
{
"name": "palette",
"children": [
{
"name": "ColorPalette",
"size": 6367
},
{
"name": "Palette",
"size": 1229
},
{
"name": "ShapePalette",
"size": 2059
},
{
"name": "SizePalette",
"size": 2291
}
]
},
{
"name": "Property",
"size": 5559
},
{
"name": "Shapes",
"size": 19118
},
{
"name": "Sort",
"size": 6887
},
{
"name": "Stats",
"size": 6557
},
{
"name": "Strings",
"size": 22026
}
]
},
{
"name": "vis",
"children": [
{
"name": "axis",
"children": [
{
"name": "Axes",
"size": 1302
},
{
"name": "Axis",
"size": 24593
},
{
"name": "AxisGridLine",
"size": 652
},
{
"name": "AxisLabel",
"size": 636
},
{
"name": "CartesianAxes",
"size": 6703
}
]
},
{
"name": "controls",
"children": [
{
"name": "AnchorControl",
"size": 2138
},
{
"name": "ClickControl",
"size": 3824
},
{
"name": "Control",
"size": 1353
},
{
"name": "ControlList",
"size": 4665
},
{
"name": "DragControl",
"size": 2649
},
{
"name": "ExpandControl",
"size": 2832
},
{
"name": "HoverControl",
"size": 4896
},
{
"name": "IControl",
"size": 763
},
{
"name": "PanZoomControl",
"size": 5222
},
{
"name": "SelectionControl",
"size": 7862
},
{
"name": "TooltipControl",
"size": 8435
}
]
},
{
"name": "data",
"children": [
{
"name": "Data",
"size": 20544
},
{
"name": "DataList",
"size": 19788
},
{
"name": "DataSprite",
"size": 10349
},
{
"name": "EdgeSprite",
"size": 3301
},
{
"name": "NodeSprite",
"size": 19382
},
{
"name": "render",
"children": [
{
"name": "ArrowType",
"size": 698
},
{
"name": "EdgeRenderer",
"size": 5569
},
{
"name": "IRenderer",
"size": 353
},
{
"name": "ShapeRenderer",
"size": 2247
}
]
},
{
"name": "ScaleBinding",
"size": 11275
},
{
"name": "Tree",
"size": 7147
},
{
"name": "TreeBuilder",
"size": 9930
}
]
},
{
"name": "events",
"children": [
{
"name": "DataEvent",
"size": 2313
},
{
"name": "SelectionEvent",
"size": 1880
},
{
"name": "TooltipEvent",
"size": 1701
},
{
"name": "VisualizationEvent",
"size": 1117
}
]
},
{
"name": "legend",
"children": [
{
"name": "Legend",
"size": 20859
},
{
"name": "LegendItem",
"size": 4614
},
{
"name": "LegendRange",
"size": 10530
}
]
},
{
"name": "operator",
"children": [
{
"name": "distortion",
"children": [
{
"name": "BifocalDistortion",
"size": 4461
},
{
"name": "Distortion",
"size": 6314
},
{
"name": "FisheyeDistortion",
"size": 3444
}
]
},
{
"name": "encoder",
"children": [
{
"name": "ColorEncoder",
"size": 3179
},
{
"name": "Encoder",
"size": 4060
},
{
"name": "PropertyEncoder",
"size": 4138
},
{
"name": "ShapeEncoder",
"size": 1690
},
{
"name": "SizeEncoder",
"size": 1830
}
]
},
{
"name": "filter",
"children": [
{
"name": "FisheyeTreeFilter",
"size": 5219
},
{
"name": "GraphDistanceFilter",
"size": 3165
},
{
"name": "VisibilityFilter",
"size": 3509
}
]
},
{
"name": "IOperator",
"size": 1286
},
{
"name": "label",
"children": [
{
"name": "Labeler",
"size": 9956
},
{
"name": "RadialLabeler",
"size": 3899
},
{
"name": "StackedAreaLabeler",
"size": 3202
}
]
},
{
"name": "layout",
"children": [
{
"name": "AxisLayout",
"size": 6725
},
{
"name": "BundledEdgeRouter",
"size": 3727
},
{
"name": "CircleLayout",
"size": 9317
},
{
"name": "CirclePackingLayout",
"size": 12003
},
{
"name": "DendrogramLayout",
"size": 4853
},
{
"name": "ForceDirectedLayout",
"size": 8411
},
{
"name": "IcicleTreeLayout",
"size": 4864
},
{
"name": "IndentedTreeLayout",
"size": 3174
},
{
"name": "Layout",
"size": 7881
},
{
"name": "NodeLinkTreeLayout",
"size": 12870
},
{
"name": "PieLayout",
"size": 2728
},
{
"name": "RadialTreeLayout",
"size": 12348
},
{
"name": "RandomLayout",
"size": 870
},
{
"name": "StackedAreaLayout",
"size": 9121
},
{
"name": "TreeMapLayout",
"size": 9191
}
]
},
{
"name": "Operator",
"size": 2490
},
{
"name": "OperatorList",
"size": 5248
},
{
"name": "OperatorSequence",
"size": 4190
},
{
"name": "OperatorSwitch",
"size": 2581
},
{
"name": "SortOperator",
"size": 2023
}
]
},
{
"name": "Visualization",
"size": 16540
}
]
}
]
}
/* Master Styles */
h1 {
color: #369;
font-family: Arial, Helvetica, sans-serif;
font-size: 250%;
}
h2, h3 {
color: #444;
font-family: Arial, Helvetica, sans-serif;
font-weight: lighter;
}
body {
margin: 2em;
}
body, input[text], button {
color: #888;
font-family: Cambria, Georgia;
}
a {
cursor: pointer;
cursor: hand;
}
button {
font-family: Arial;
background-color: #eee;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
cursor: hand;
}
button:hover {
background-color: #cfd8dc;
}
button:disabled {
background-color: #eee;
color: #aaa;
cursor: auto;
}
/* Navigation link styles */
nav a {
padding: 5px 10px;
text-decoration: none;
margin-right: 10px;
margin-top: 10px;
display: inline-block;
background-color: #eee;
border-radius: 4px;
}
nav a:visited, a:link {
color: #607D8B;
}
nav a:hover {
color: #039be5;
background-color: #CFD8DC;
}
nav a.active {
color: #039be5;
}
/* items class */
.items {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 24em;
}
.items li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
.items li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.items li.selected {
background-color: #CFD8DC;
color: white;
}
.items li.selected:hover {
background-color: #BBD8DC;
}
.items .text {
position: relative;
top: -3px;
}
.items .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color: #607D8B;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
/* everywhere else */
* {
font-family: Arial, Helvetica, sans-serif;
}
.node {
cursor: pointer;
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node text {
font: 10px sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/
<!DOCTYPE html>
<html>
<head>
<title>Angular Tour of Heroes</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<!-- Polyfills for older browsers -->
<script src="https://unpkg.com/core-js/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js@0.7.4?main=browser"></script>
<script src="https://unpkg.com/reflect-metadata@0.1.8"></script>
<script src="https://unpkg.com/systemjs@0.19.39/dist/system.src.js"></script>
<script src="https://cdn.rawgit.com/angular/angular.io/b3c65a9/public/docs/_examples/_boilerplate/systemjs.config.web.js"></script>
<!-- Including D3 JS -->
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>
<!--
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->