我正在尝试使用D3制作的具有多个图表的仪表板。我的问题是,我似乎无法使图表响应并调整容器大小。
首先,仪表板的基本结构:
dashboard.html
:
<div id="graphs-container">
<div class="widget-container">
<div class="widget-container-header">
Some text
</div>
<div class="widget-container-body big">
<div class="spinner-container" *ngIf="!loopsByTruckAndHour">
<mat-spinner></mat-spinner>
</div>
<div *ngIf="loopsByTruckAndHour">
<app-linechart [data]="loopsByTruckAndHourData"
xWIDTH="1100" xHEIGHT="450"></app-linechart>
</div>
</div>
</div>
<div class="widget-container grow1">
<div class="widget-container-header">
Some other text
</div>
<div class="widget-container-body medium">
<div class="spinner-container" *ngIf="!productionByTruckAndHour">
<mat-spinner></mat-spinner>
</div>
<div *ngIf="productionByTruckAndHour">
<app-barchart [data]="productionByTruckAndHourData"></app-barchart>
</div>
</div>
</div>
{...}
</div>
dashboard.css
:
#graphs-container {
background-color: #ffffff;
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
}
.small {
max-width: 400px;
}
.medium {
max-width: 450px;
}
.medium-table {
max-width: 500px;
}
.medium-big {
min-width: 500px;
max-width: 1000px;
}
.big {
min-width: 700px;
max-width: 1100px;
}
.widget-container {
margin: 10px;
flex-grow: 1;
-webkit-box-shadow: 0px 2px 10px 4px rgba(230,230,230,1);
-moz-box-shadow: 0px 2px 10px 4px rgba(230,230,230,1);
box-shadow: 0px 2px 10px 4px rgba(230,230,230,1);
border-radius: 0px 0px 8px 8px;
border: 1px solid #e6e6e6;
}
.widget-container-header {
background-color: #E6E6E6;
color: #3F3F3F;
font-family: 'Open Sans';
font-size: 1.08vw;
padding: 0.2rem 0rem 0.2rem 1rem;
}
.widget-container-body {
padding: 10px;
font-family: 'Open Sans';
max-height: 450px !important;
}
在这里,我试图使用Flexbox显示所有不同的小部件或图表,以便它们在屏幕中进行组织。每个小部件的最大高度为450像素,我根据每个小部件应具有的大小为它们设置了max-width
,并为每个小部件设置了flex-grow: 1
,以便它们很好地填充屏幕,而不要不要在两者之间留出空白。
现在,到现在为止,一切正常。问题来自图表和SVG。
我的仪表板中有不同类型的图表,例如折线图和条形图,因此每种图表都是一个Angular组件,您将数据传递给该Angular组件,并且它会用{{1}呈现一个<div>
}放在图表中。
由于我希望这是响应性的,因此我的d3图表是使用svg
和viewBox
制作的,并且组件具有preserveAspectRatio
和xWIDTH
属性以在构建svg,这将有助于设置宽度和高度之间的比率(例如,并非每个折线图都必须具有相同的宽度)。
对我的图表组件的一些引用:
xHEIGHT
:
linechart.component.ts
div_id = '_' + Math.random().toString(36).substr(2, 9);
@Input() data;
@Input() xWIDTH: number = 800; // default value
@Input() xHEIGHT: number = 300;
margin = {
left: this.xWIDTH / 16,
top: this.xHEIGHT / 8,
bottom: this.xHEIGHT / 8,
right: this.xWIDTH / 80
}
width = this.xWIDTH - this.margin.left - this.margin.right;
height = this.xHEIGHT - this.margin.top - this.margin.bottom;
drawChart() {
const svg = d3.select(`#${this.div_id}`)
.append('svg')
.attr("width", '100%')
.attr("height", '100%')
.attr('viewBox', `0 0 ${this.xWIDTH} ${this.xHEIGHT}`)
.attr('preserveAspectRatio', 'xMinYMin meet')
.append('g')
.attr('transform', `translate(${this.margin.left},${this.margin.top})`);
// make the rest of the chart
}
:
linechart.component.html
我的问题是:我的<div [attr.id]="div_id">
</div>
元素保持宽高比,但是当我给组件提供{{1}的较小值时,内部的SVG
元素并没有尊重其父SVG元素的大小。 }和<g>
,xWIDTH
元素非常大,然后xHEIGHT
和g
的值很大,比xWIDTH
元素小得多。我怎样才能解决这个问题?如何使xHEIGHT
和SVG
元素适应其父容器?
此外,SVG
和g
似乎无视其父母的SVG
,有时他们只是在容器外生长。
两张图像可能有助于了解正在发生的事情: https://i.imgur.com/yq9BJWX.png https://i.imgur.com/fbGqDXM.png