import {Component, Input, OnInit, OnChanges, SimpleChanges} from '@angular/core'; import * as d3 from "d3"; import {ChartBase} from "../base-classes/chart-base"; import {Http} from "@angular/http"; import {forEach, every} from "lodash"; import {ChartHelpers, IPadding, YAxisSide} from "../utilities/chart-helpers"; export interface ILineData { yData?: Array; color: string; shown: boolean; data: object; name: string; } @Component({ selector: 'multi-line-chart', templateUrl: './multi-line-chart.component.html', styleUrls: ['./multi-line-chart.component.scss'] }) export class MultiLineChartComponent extends ChartBase implements OnInit, OnChanges { @Input() public lineDataObjects: Array; @Input() public hideLegend: boolean = false; @Input() public hideAxies: boolean = false; @Input() public yAxisName: string = 'Intensity'; @Input() public xAxisName: string = 'Wavelength (um)'; @Input() public yMin: number = 0; @Input() public yMax: number = 65000; @Input() public innerPadding: IPadding = { top: 10, right: 70, bottom: 40, left: 20 }; public lines = []; protected xScale: d3.ScaleTime; protected dataSets = []; protected xData: Array; private xEndpoint: string = "./data/wavelengths.json"; constructor(protected http: Http) { super(); } ngOnChanges(changes: SimpleChanges) { if(changes.lineDataObjects && changes.lineDataObjects.previousValue) { forEach(changes.lineDataObjects.currentValue, (lineDataObject: ILineData, i: number) => { if(lineDataObject.shown == true){ this.lines[i].style("opacity", 1); } else { this.lines[i].style("opacity", 0); } }); } if(changes.isActive && changes.isActive.previousValue) { console.log(changes); } if(changes.width && changes.width.previousValue) { this._width = changes.width.currentValue; this.redrawChart(); } if(changes.height && changes.height.previousValue) { this._height = changes.height.currentValue; this.redrawChart(); } } ngOnInit() { this.getXData().subscribe((xData: Array) => { this.xData = xData; this.buildXScale(); forEach(this.lineDataObjects, (lineDataObject: ILineData) => { if(!lineDataObject.yData) { lineDataObject.yData = []; for(let j = 0; j < this.xData.length; j++) { lineDataObject.yData[j] = 0; } } }); super.onInitBase(this.yMin, this.yMax); this.buildDataSets(); this.drawChart(); }); } public setLineToCurrentValue (lineName) { let matchingLineIndex = -1; this.lineDataObjects.filter((line, i) => { if (line.name == lineName) { matchingLineIndex = i; return true; } else { return false; } }); if (matchingLineIndex != -1) { this.dataSets[matchingLineIndex] = this.dataSets[0]; ChartHelpers.updateLineGraph(this.lines[matchingLineIndex], this.xScale, this.yScale, this.dataSets[matchingLineIndex]); return this.dataSets[0]; } return []; } public setLineData (data, lineName) { let matchingLineIndex = -1; this.lineDataObjects.filter((line, i) => { if (line.name == lineName) { matchingLineIndex = i; return true; } else { return false; } }); if (matchingLineIndex != -1) { this.dataSets[matchingLineIndex] = []; for(let j = 0; j < this.xData.length; j++) { this.dataSets[matchingLineIndex].push([ this.xData[j], data[j] ]); } ChartHelpers.updateLineGraph(this.lines[matchingLineIndex], this.xScale, this.yScale, this.dataSets[matchingLineIndex]); } } protected buildXScale() { this.xScale = d3.scaleTime() .domain([ d3.min(this.xData), d3.max(this.xData) ]) .range([this.innerPadding.left, this._width - this.innerPadding.right]); } protected buildDataSets() { forEach(this.lineDataObjects,(lineDataObject, i) => { this.dataSets[i] = []; for(let j = 0; j < this.xData.length; j++) { this.dataSets[i].push([ this.xData[j], lineDataObject.yData[j] ]); } }); } protected getXData() { return this.http.get(this.xEndpoint) .map(response => response.json().wavelengths); } public lineToggled (index: number) { this.lineDataObjects[index].shown = !this.lineDataObjects[index].shown; if(this.lineDataObjects[index].shown == true){ this.lines[index].style("opacity", 1); } else { this.lines[index].style("opacity", 0); } } private drawChart() { if(!this.hideAxies) { this.xAxis = ChartHelpers.buildXAxis(this.svg, this.xScale, this._width, this._height, this.innerPadding, this.xAxisSide, this.xAxisName); this.yAxis = ChartHelpers.buildYAxis(this.svg, this.yScale, this._width, this._height, this.innerPadding, YAxisSide.Right, this.yAxisName, true) } ChartHelpers.drawGrid(this.svg, this._width, this._height, this.xAxisSide, YAxisSide.Right); forEach(this.dataSets, (dataSet, i) => { this.lines.push(ChartHelpers.buildLineGraph(this.svg, this.xScale, this.yScale, dataSet, this.lineDataObjects[i].color)); }); } private redrawChart() { this.buildXScale(); this.buildYScale(); if(!this.hideAxies) { ChartHelpers.removeXAxis(this.svg); ChartHelpers.removeYAxis(this.svg); this.xAxis = ChartHelpers.buildXAxis(this.svg, this.xScale, this._width, this._height, this.innerPadding, this.xAxisSide, "Wavelength"); this.yAxis = ChartHelpers.buildYAxis(this.svg, this.yScale, this._width, this._height, this.innerPadding, YAxisSide.Right, this.yAxisName, true) } forEach(this.dataSets, (dataSet, i) => { ChartHelpers.updateLineGraph(this.lines[i], this.xScale, this.yScale, dataSet) }); ChartHelpers.drawGrid(this.svg, this._width, this._height, this.xAxisSide, YAxisSide.Right); } }