Made it work
This commit is contained in:
		@@ -4,7 +4,7 @@ root = true
 | 
			
		||||
[*]
 | 
			
		||||
charset = utf-8
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 2
 | 
			
		||||
indent_size = 4
 | 
			
		||||
insert_final_newline = true
 | 
			
		||||
trim_trailing_whitespace = true
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,19 @@
 | 
			
		||||
<!--The content below is only a placeholder and can be replaced.-->
 | 
			
		||||
<div style="text-align:center">
 | 
			
		||||
  <h1>
 | 
			
		||||
    Welcome to {{ title }}!
 | 
			
		||||
  </h1>
 | 
			
		||||
  <img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
 | 
			
		||||
<mat-toolbar>
 | 
			
		||||
    <span>ETF Demo</span>
 | 
			
		||||
    <span class="mx-auto"><!-- Spacer --></span>
 | 
			
		||||
    <button mat-button (click)="fileUploader.click()">
 | 
			
		||||
        <mat-icon>add</mat-icon>
 | 
			
		||||
        Upload
 | 
			
		||||
    </button>
 | 
			
		||||
</mat-toolbar>
 | 
			
		||||
<div *ngIf="chartResults" class="w-100" [style.height]="chartHeight">
 | 
			
		||||
    <ngx-charts-bar-horizontal-2d #chart
 | 
			
		||||
                                [results]="chartResults"
 | 
			
		||||
                                [xAxis]="true"
 | 
			
		||||
                                [yAxis]="true"
 | 
			
		||||
                                [yAxisTickFormatting]="format">
 | 
			
		||||
    </ngx-charts-bar-horizontal-2d>
 | 
			
		||||
</div>
 | 
			
		||||
<h2>Here are some links to help you start: </h2>
 | 
			
		||||
<ul>
 | 
			
		||||
  <li>
 | 
			
		||||
    <h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
 | 
			
		||||
  </li>
 | 
			
		||||
  <li>
 | 
			
		||||
    <h2><a target="_blank" rel="noopener" href="https://angular.io/cli">CLI Documentation</a></h2>
 | 
			
		||||
  </li>
 | 
			
		||||
  <li>
 | 
			
		||||
    <h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
 | 
			
		||||
  </li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
<input #fileUploader type="file" accept="text/csv" multiple hidden (change)="upload(fileUploader.files)">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
import { TestBed, async } from '@angular/core/testing';
 | 
			
		||||
import { AppComponent } from './app.component';
 | 
			
		||||
 | 
			
		||||
describe('AppComponent', () => {
 | 
			
		||||
  beforeEach(async(() => {
 | 
			
		||||
    TestBed.configureTestingModule({
 | 
			
		||||
      declarations: [
 | 
			
		||||
        AppComponent
 | 
			
		||||
      ],
 | 
			
		||||
    }).compileComponents();
 | 
			
		||||
  }));
 | 
			
		||||
 | 
			
		||||
  it('should create the app', () => {
 | 
			
		||||
    const fixture = TestBed.createComponent(AppComponent);
 | 
			
		||||
    const app = fixture.debugElement.componentInstance;
 | 
			
		||||
    expect(app).toBeTruthy();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it(`should have as title 'ETFDemo'`, () => {
 | 
			
		||||
    const fixture = TestBed.createComponent(AppComponent);
 | 
			
		||||
    const app = fixture.debugElement.componentInstance;
 | 
			
		||||
    expect(app.title).toEqual('ETFDemo');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render title in a h1 tag', () => {
 | 
			
		||||
    const fixture = TestBed.createComponent(AppComponent);
 | 
			
		||||
    fixture.detectChanges();
 | 
			
		||||
    const compiled = fixture.debugElement.nativeElement;
 | 
			
		||||
    expect(compiled.querySelector('h1').textContent).toContain('Welcome to ETFDemo!');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -1,10 +1,52 @@
 | 
			
		||||
import { Component } from '@angular/core';
 | 
			
		||||
import {Component} from '@angular/core';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-root',
 | 
			
		||||
  templateUrl: './app.component.html',
 | 
			
		||||
  styleUrls: ['./app.component.scss']
 | 
			
		||||
    selector: 'app-root',
 | 
			
		||||
    templateUrl: './app.component.html'
 | 
			
		||||
})
 | 
			
		||||
export class AppComponent {
 | 
			
		||||
  title = 'ETFDemo';
 | 
			
		||||
    chartResults; // This is where the chart reads the data from
 | 
			
		||||
    chartHeight = '100%';
 | 
			
		||||
 | 
			
		||||
    // ngx-charts requires a different data structure than the hash map we built so I will use a setter to handle converting it when we go to save the processed data.
 | 
			
		||||
    private _data;
 | 
			
		||||
    get data() { return this._data; }
 | 
			
		||||
    set data(data) {
 | 
			
		||||
        this._data = data;
 | 
			
		||||
        this.chartHeight = `${Object.keys(data).length * 100}px`;
 | 
			
		||||
        this.chartResults = Object.keys(data).map(key => ({name: key, series: data[key].map((val, i) => ({name: i, value: val}))}));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    constructor() { }
 | 
			
		||||
 | 
			
		||||
    upload(fileList: FileList) {
 | 
			
		||||
        // Because we enabled uploading multiple files at once we need to process each one individually
 | 
			
		||||
        const files: File[] = Array.from(fileList);
 | 
			
		||||
        files.forEach(file => {
 | 
			
		||||
            // Process CSV
 | 
			
		||||
            const reader = new FileReader();
 | 
			
		||||
            reader.onload = (e: ProgressEvent) => {
 | 
			
		||||
                // Split the file into lines
 | 
			
		||||
                const lines = ((<FileReader>e.target).result as string).split('\n');
 | 
			
		||||
 | 
			
		||||
                // Use regex to grab the holding name and its % market value
 | 
			
		||||
                this.data = lines.map(text => {
 | 
			
		||||
                    const parse = /^(.+),.+?(\d+\.\d+)%/gm.exec(text);
 | 
			
		||||
                    if(parse) return parse.slice(1);
 | 
			
		||||
                }).reduce((acc, line) => {
 | 
			
		||||
                    // The regex will turn lines that don't match into null values so lets filter those out here
 | 
			
		||||
                    if(!line) return acc;
 | 
			
		||||
 | 
			
		||||
                    // Add the parsed data into our data set
 | 
			
		||||
                    if(!acc[line[0]]) acc[line[0]] = [];
 | 
			
		||||
                    acc[line[0]].push(Number(line[1]));
 | 
			
		||||
 | 
			
		||||
                    return acc;
 | 
			
		||||
                }, this.data || {});
 | 
			
		||||
            };
 | 
			
		||||
            reader.readAsText(file);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    format(text) { return `${text} %`}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +1,24 @@
 | 
			
		||||
import { BrowserModule } from '@angular/platform-browser';
 | 
			
		||||
import { NgModule } from '@angular/core';
 | 
			
		||||
 | 
			
		||||
import { AppComponent } from './app.component';
 | 
			
		||||
import {BrowserModule} from '@angular/platform-browser';
 | 
			
		||||
import {NgModule} from '@angular/core';
 | 
			
		||||
import {AppComponent} from './app.component';
 | 
			
		||||
import {MatButtonModule, MatIconModule, MatToolbarModule} from '@angular/material';
 | 
			
		||||
import {NgxChartsModule} from '@swimlane/ngx-charts';
 | 
			
		||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
  declarations: [
 | 
			
		||||
    AppComponent
 | 
			
		||||
  ],
 | 
			
		||||
  imports: [
 | 
			
		||||
    BrowserModule
 | 
			
		||||
  ],
 | 
			
		||||
  providers: [],
 | 
			
		||||
  bootstrap: [AppComponent]
 | 
			
		||||
    declarations: [
 | 
			
		||||
        AppComponent
 | 
			
		||||
    ],
 | 
			
		||||
    imports: [
 | 
			
		||||
        BrowserAnimationsModule,
 | 
			
		||||
        BrowserModule,
 | 
			
		||||
        MatButtonModule,
 | 
			
		||||
        MatIconModule,
 | 
			
		||||
        MatToolbarModule,
 | 
			
		||||
        NgxChartsModule,
 | 
			
		||||
    ],
 | 
			
		||||
    providers: [],
 | 
			
		||||
    bootstrap: [AppComponent]
 | 
			
		||||
})
 | 
			
		||||
export class AppModule { }
 | 
			
		||||
export class AppModule {
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,15 @@
 | 
			
		||||
<!doctype html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="utf-8">
 | 
			
		||||
  <title>ETFDemo</title>
 | 
			
		||||
  <base href="/">
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <title>ETFDemo</title>
 | 
			
		||||
    <base href="/">
 | 
			
		||||
 | 
			
		||||
  <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
  <link rel="icon" type="image/x-icon" href="favicon.ico">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
    <link rel="icon" type="image/x-icon" href="favicon.ico">
 | 
			
		||||
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet">
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
  <app-root></app-root>
 | 
			
		||||
<app-root></app-root>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +1,11 @@
 | 
			
		||||
/* You can add global styles to this file, and also import other style files */
 | 
			
		||||
@import url('https://fonts.googleapis.com/css?family=Archivo|Material+Icons');
 | 
			
		||||
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
 | 
			
		||||
 | 
			
		||||
html, body {
 | 
			
		||||
    padding: 0;
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
 | 
			
		||||
    font-family: 'Archivo', sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user