Simple charts can be rendered using an <svg>
element.
The following example shows a basic SVG chart within an Angular context.
While the markup can be written and manipulated directly, this example makes use of a third-party library, SVG.js, to demonstrate how the bars could be animated when the page loads.
When you need a more complex interactivity with a chart, we recommend using the third-party charting tool called NGX-Charts.
<!DOCTYPE html>
<html>
<head>
<base href="." />
<title>SVG Chart Example</title>
{% stylesheet_link_tag application %}
<script src="//unpkg.com/zone.js/dist/zone.js"></script>
<script src="//unpkg.com/zone.js/dist/long-stack-trace-zone.js"></script>
<script src="//unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
<script src="//unpkg.com/systemjs@0.19.31/dist/system.js"></script>
<script src="config.js"></script>
<script src="//cdn.jsdelivr.net/npm/svg.js@2.6.3/dist/svg.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/svg.pathmorphing.js@0.1.1/dist/svg.pathmorphing.min.js"></script>
<script>
System.import('app')
.catch(console.error.bind(console));
</script>
<script src="https://use.typekit.net/ccb3vpa.js"></script>
<script>
try {
Typekit.load({
async: true
});
} catch (e) {}
</script>
<script src="/examples/shared/theme_toggler.js"></script>
</head>
<body>
<style>
@keyframes rotateInitLoadingSpinner {
100% {
transform: rotate(360deg);
}
}
.preloader {
position: absolute;
display: block;
top: 48px;
left: calc(50% - 37.5px);
width: 75px;
height: 75px;
margin: 0 auto;
background: transparent;
animation: rotateInitLoadingSpinner 700ms linear infinite;
}
.preloader-wrapper {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
<my-app>
<div class="preloader-wrapper">
<svg viewBox="0 0 102 101" class="preloader">
<g fill="none" fill-rule="evenodd">
<g transform="translate(1 1)" stroke-width="2">
<ellipse stroke="#eee" cx="50" cy="49.421" rx="50" ry="49.421"></ellipse>
<path d="M50 98.842c27.614 0 50-22.127 50-49.42C100 22.125 77.614 0 50 0" stroke-opacity=".631" stroke="#3B6E8F"></path>
</g>
</g>
</svg>
</div>
</my-app>
</body>
</html>
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ChartComponent } from './chart.component';
@NgModule({
imports: [
BrowserModule
],
declarations: [
AppComponent,
ChartComponent
],
bootstrap: [
AppComponent
]
})
export class AppModule {}
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html'
})
export class AppComponent {
constructor() {}
}
<div class="container soft-ends">
<div class="row">
<svg-chart></svg-chart>
</div>
</div>
import { Component, OnInit } from '@angular/core';
declare const SVG;
@Component({
selector: 'svg-chart',
templateUrl: './chart.component.html'
})
export class ChartComponent implements OnInit {
bars = {
thing1: {
value: 2.7,
top: 228
},
thing2: {
value: 2.4,
top: 171
},
thing3: {
value: 1.8,
top: 114
},
thing4: {
value: 1.2,
top: 57
},
thing5: {
value: 0.6,
top: 0
}
};
svg: any;
constructor() {}
ngOnInit() {
this.svg = SVG.get('my-chart');
this.initBarPaths();
}
private initBarPaths() {
for (let name in this.bars) {
if (name) {
const bar = this.bars[name];
const svgBar = this.getBar(name);
svgBar.attr({ d: this.getPathArray(bar, 0) });
svgBar.animate(750, '<>', 0).plot(this.getPathArray(bar));
}
}
}
private getPathArray(bar, value = bar.value) {
const right = (value * 206) - 4;
const top = bar.top;
return new SVG.PathArray([
['M', 0, top],
['L', right, top],
['C', right + 2, top, right + 4, top + 2, right + 4, top + 4],
['L', right + 4, top + 45],
['C', right + 4, top + 47, right + 2, top + 49, right, top + 49],
['L', 0, top + 49],
['L', 0, 0]
]);
}
private getBar(name) {
return this.svg.select(`#${name}-path`);
}
}
<svg id="my-chart" viewBox="0 0 750 313" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<!-- Grid Lines -->
<g transform="translate(81.5, 0.5)" stroke="#E7E7E7" stroke-linecap="square">
<path d="M0,0 L0,276.6"></path>
<path d="M206,0 L206,276.6"></path>
<path d="M412,0 L412,276.6"></path>
<path d="M618,0 L618,276.6"></path>
</g>
<!-- Y-Axis Labels -->
<g transform="translate(64, 0)" font-size="14" fill="#737373" font-weight="300" text-anchor="end">
<text y="257">Thing #1</text>
<text y="200">Thing #2</text>
<text y="143">Thing #3</text>
<text y="86">Thing #4</text>
<text y="29">Thing #5</text>
</g>
<!-- Bars -->
<g id="bar-group" fill="#57AFA9" transform="translate(82, 0)">
<path id="thing1-path"></path>
<path id="thing2-path"></path>
<path id="thing3-path"></path>
<path id="thing4-path"></path>
<path id="thing5-path"></path>
</g>
<!-- X-Axis Labels -->
<g transform="translate(81.5, 310)" fill="#737373" font-size="14" font-weight="300" text-anchor="middle">
<text x="0">0</text>
<text x="206">1</text>
<text x="412">2</text>
<text x="618">3</text>
</g>
</g>
</svg>