I have several Angular components that I would like to layout on the same webpage, so I am using Angular mat-grid-list and mat-grid-tiles to do this. However, I am running into a size problem. One of the components is a time series plot with a legend and whenever it renders in the mat-grid-tile, it overfills the box, and in another bar plot, the box is underfilled. Here is some example code:
time-series-component.ts
import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import * as d3 from 'd3';
import { ScaleOrdinal } from 'd3';
@Component({
selector: 'time-series-component',
templateUrl: './time-series-component.html',
styleUrls: ['./time-series-component.component.scss'],
})
export class TimeSeriesComponent implements OnInit {
private width = 1000;
private height = 620;
private svg: d3.Selection<SVGGElement, unknown, HTMLElement, any>;
private xAxis: d3.ScaleTime<number, number>;
private yAxis: d3.ScaleLinear<number, number>;
ngOnInit(): void {
this.createGroups();
this.createLinePlot();
}
createGroups(): void {
this.groupedData = d3.group(
this.timeSeriesData,
(d: TimeSeriesDatum) => d.id,
);
}
createLinePlot(): void {
this.createSVG();
this.createAxes();
this.addData();
this.addClickableLegend();
}
createSVG(): void {
this.svg = d3
.select('#time-series-component')
.append<SVGGElement>('svg')
.classed('svg-content', true)
.attr('viewBox', `0 0 ${this.width} ${this.height}`)
.attr('preserveAspectRatio', 'xMidYMid meet')
.append('g');
}
createAxes(): void {
this.createX();
this.createY();
this.attachAxes();
this.addAxisLabels();
}
createX(): void {
this.xAxis = d3
.scaleTime()
.domain(
d3.extent(this.timeSeriesData, (d: TimeSeriesDatum) =>
this.parseDate(d.date),
),
)
.range([0, this.width]);
}
createY(): void {
this.yAxis = d3
.scaleLinear()
.domain([
0,
d3.max(
this.timeSeriesData,
(d: TimeSeriesDatum) => d.yvalue,
),
])
.range([this.height, 0]);
}
attachAxes(): void {
this.svg
.append('g')
.attr('transform', `translate(30, ${this.height})`)
.call(d3.axisBottom(this.xAxis))
.style('font-size', '10px');
this.svg.append('g').call(d3.axisLeft(this.yAxis));
}
There is more, but this is the important stuff. I have 2 more of these components and I am putting them in a mat-grid-list for layout (first component spans two columns, and the next two are one row below the first and span 1 column each). The parent-component.ts simply gathers the data and then passes it to the components through the html.
parent.html
<div
class="container"
id="nlp-modeling"
fxFlexFill
fxLayout="column">
<h1>Modeling
<mat-icon class="info-icon" aria-hidden="false"
matTooltip=
"This analytic blah blah blah"
matTooltipPosition="below">help_outline
</mat-icon>
</h1>
<mat-grid-list cols="2">
<mat-grid-tile
[colspan]="2">
<div class="container">
<mat-grid-tile-header>
<h2>Time Series</h2>
</mat-grid-tile-header>
<time-series-component
*ngIf="timeSeriesData"
[timeSeriesData]="timeSeriesData">
</time-series-component>
</div>
</mat-grid-tile>
<mat-grid-tile
[colspan]="1">
<div class="container">
<mat-grid-tile-header>
<h3>First Bar Chart</h3>
</mat-grid-tile-header>
<bar-chart-one
*ngIf="barChartData1"
[barChartData1]="barChartData1">
</bar-chart-one>
</div>
</mat-grid-tile>
<mat-grid-tile
[colspan]="1">
<div class="container">
<mat-grid-tile-header>
<h3>Second Bar Chart</h3>
</mat-grid-tile-header>
<bar-chart-two
*ngIf="barChartData2"
[barChartData2]="barChartData2">
</bar-chart-two>
</div>
</mat-grid-tile>
</mat-grid-list>
</div>
I'm just not sure how to ensure that the content stays inside each of the mat-grid-tiles. In some cases, the plot extends beyond the width of the cell, the x- and/or y-axis is cut off. Each of the component html files are of the same structure: <div id="time-series-component" class="svg-container"></div>. I'm a little lost on how to embed these components in the Angular mat-grid-list/mat-grid-tile structure.