Расположите некоторые элементы в последнем ряду, используя сетку вместо flex - PullRequest
4 голосов
/ 22 марта 2019

Ранее я задавал этот вопрос . Я пробую решение, связанное с аналогичным вопросом, уже сделанным (используя grid вместо flex), но у меня есть некоторые проблемы.

Мне нужно построить сетку графиков (гистограммы). Мой набор данных может быть агрегирован по дням или месяцам. Очевидно, что если данные агрегируются по месяцам, количество баров намного меньше, чем количество баров, если данные агрегированы по дням. Ширина графика пропорциональна количеству баров.

Чтобы показать мою проблему, я создал эти простые изображения: каждый прямоугольник представляет гистограмму (как заполнитель). Большие прямоугольники представляют гистограммы в случае агрегирования данных по дням, а более узкие гистограммы представляют гистограммы при агрегировании данных по месяцам.

В этом примере я предполагаю, что мой набор данных состоит из 6 диаграмм. Я знаю ширину графика, потому что это просто количество баров для ширины бара. Я хотел бы, чтобы данные располагались автоматически.

В каждой строке не может быть более двух графиков, между графиком и другим должен быть некоторый пробел, и в последней строке (если она не завершена) диаграммы должны быть выровнены влево. Последний запрос является причиной неправильного использования Flex, поэтому я перешел на Grid.

Итак, я хочу, чтобы, если данные агрегировались по дням, графики должны выглядеть так:

enter image description here

Если данные агрегированы по месяцам, диаграммы должны выглядеть так:

enter image description here

Я пробую сетку CSS, используя этот код:

<div
  className="relative ba b--black"
  style={{
    display: 'grid',
    gridTemplateColumns: `repeat(auto-fit, minmax(45%, 1fr))`,
    gridAutoRows: SVG_HEIGHT,
    gridGap: '10px 5px', // space h, space v
  }}
>
  {
    data.map((plot, plotIdx) => {
      return (
        <div
          key={plotIdx}
          className="ba b--black overflow-x-auto"
          onScroll={this.handleHorizontalScroll(plotIdx)}
        >
          <svg
            width={SVG_WIDTH}
            height={CHART_HEIGHT + MARGINS.bottom + MARGINS.top}
          >
            // other code...
          </svg>
        </div>
      )
    })
  }
</div>

(каждая диаграмма может иметь большую ширину, поэтому имеется горизонтальная прокрутка).

Проблема теперь в том, что ячейка каждого графика всегда одинакова, даже если реальное измерение, если диаграмма меньше контейнера.

Данные агрегированы по дням:

enter image description here

Данные агрегированы по месяцам:

enter image description here


Если я использую SVG_WIDTH вместо 45% в выражении minmax, я получу:

enter image description here

в случае, если данные агрегированы по дням, и этот в случае, если данные агрегированы в мой месяц:

enter image description here


Я не использовал px, спасибо! Теперь он работает в случае агрегирования по месяцам, но не в случае агрегирования по дням.

днем ​​(не работает):

enter image description here

по месяцам (работ):

enter image description here

Проблема в том, что на каждом графике должна быть горизонтальная прокрутка, на самом деле, если SVG_WIDTH больше, чем размер отца div, тогда мне нужно добавить прокрутку.

Вот код, который я использовал:

<div
  className="relative ba b--black"
  style={{
    display: 'grid',
    gridTemplateColumns: `repeat(auto-fit, minmax(${SVG_WIDTH}px, 1fr))`,
    gridAutoRows: PLOT_HEIGHT,
    gridGap: '10px 5px', // space h, space v
  }}
>
  {data.map((plot, plotIdx) => {
    const yScale = this.yScale(plot)
    const yAxisTicks = yScale.ticks(4)

    return (
      <div
        key={plotIdx}
        ref={plotElem => (this.plots[plotIdx] = plotElem)}
        className="ba b--black overflow-x-auto"
        onScroll={this.handleHorizontalScroll(plotIdx)}
      >
      // ...
      </div>
    )}
  )}
</div>

1 Ответ

1 голос
/ 26 марта 2019

Используйте SVG_WIDTH вместо 45% в операторе minmax.

Что касается проблемы переполнения, которая обнаруживается при больших значениях, здесь есть обходной путь, описанный здесь , хотя это немного хакерский.Адаптировано к вашему случаю, минимум два столбца:

@media (max-width: ${SVG_WIDTH * 2 + 10}px) {
  .container { grid-template-columns: repeat(2, 1fr); }
}

Где 10 - ваш grid-gap.container принимает всю ширину страницы с полем тела, сбрасываемым в 0. В противном случае также добавьте поле по умолчанию для тега тела (8px слева и справа) и ширину боковой панели, если она у вас есть.Вы также можете использовать CSS calc (), если ваша боковая панель или макет адаптивны, но поддержка calc () в медиазапросах ограничена только для самых последних браузеров.

...