Адаптивная панель инструментов диаграммы с viewBox и preserveAspectRatio - PullRequest
0 голосов
/ 19 декабря 2018

Я пытаюсь создать панель с несколькими графиками, созданными с помощью 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.

У меня есть разные типы диаграмм на моей панели, такие как линейные диаграммы и диаграммы, поэтому каждый тип диаграмм является угловым компонентом, которому вы передаете данные, и он отображает<div> с svg внутри диаграммы.

Поскольку я хочу, чтобы это было отзывчивым, мои диаграммы d3 были сделаны с использованием viewBox и preserveAspectRatio, а компоненты имеют xWIDTHи xHEIGHT приписывают себя при создании svg, что поможет установить соотношение между шириной и высотой (например, не каждая линейная диаграмма должна иметь одинаковую ширину).

Некоторые ссылки на моикомпоненты диаграммы:

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>

Моя проблема в том, что мои SVG элементы сохраняют соотношение сторон,но элемент <g> внутри не учитывает размер родительского элемента SVG, когда я даю компоненту небольшие значения для xWIDTH и xHEIGHT, g элемент si массив, а затем значения для xWIDTH и xHEIGHT большие, это путьменьше, чем SVG элемент.Как я могу это исправить?Как я могу настроить элемент SVG и g на родительский контейнер?

Кроме того, SVG и g, кажется, игнорируют max-height: 450px !important; своих родителей, а иногдаони просто растут вне своего контейнера.

Два изображения, которые могут помочь понять, что происходит: https://i.imgur.com/yq9BJWX.png https://i.imgur.com/fbGqDXM.png

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...