구성 요소 레이아웃

개요

문서에 인터랙티브 구성 요소를 도입하면 가독성과 탐색성을 최적화하는 방식으로 배치하는 것이 중요합니다.

인터랙티비티를 포함하는 방법은 긴 형식의 아티클 안에 시각화를 임베드하는 방식부터 애플리케이션/대시보드 스타일 레이아웃까지 매우 다양합니다. 아래에서 두 가지 레이아웃 시나리오를 모두 다룹니다.

Observable JSShiny 인터랙티브 문서의 예시를 모두 사용합니다. 특정 예시의 코드/문법에 익숙하지 않다면 애플리케이션 코드보다 이를 감싸는 레이아웃 마크업에 집중하세요.

입력 패널

입력이 여러 개라면 입력 패널(panel: input 옵션이 있는 코드 블록 또는 .panel-input 클래스 div) 안에 묶는 것이 좋습니다. 예시는 다음과 같습니다.

입력은 패널로 묶고 OJS 코드 셀에 panel: inputlayout-ncol: 3 옵션을 추가해 세 열로 배치합니다.

```{ojs}
//| panel: input
//| layout-ncol: 3

viewof ch = checkbox({
  title: "Passport color:",
  options: [
    { value: "red", label: "Red" },
    { value: "green", label: "Green" },
    { value: "blue", label: "Blue" },
    { value: "black", label: "Black" }
  ],
  value: ["red", "green", "blue", "black"],
  submit: false
})

viewof type = radio({
  title: "Representation:",
  options: [
    { label: 'Passports', value: 'p' },
    { label: 'Circles', value: 'c' }
  ],
  value: 'p'
})

viewof k = slider({
  title: "Symbol size:",
  min: 1,
  max: 10,
  value: 3,
  step: 1
})
```

탭셋 패널

여러 시각화를 토글할 수 있게 하려면 탭셋(.panel-tabset 클래스 div)을 사용하세요. 탭셋 안에서 각 탭에 해당하는 제목(예: ##)을 포함합니다.

예를 들어, 아래는 플롯과 데이터를 각각의 탭에 표시한 것입니다.

다음은 탭셋을 만드는 데 사용한 마크업과 코드입니다.

::: {.panel-tabset}

## Plot

```{ojs}
Plot.rectY(data, 
  Plot.stackY(
    Plot.binX( 
      {y: "count"}, 
      {x: "body_mass_g", fill: "species", thresholds: 20})
    )
  ).plot({
    facet: {
      data,
      x: "sex"
    },
    marks: [Plot.frame()]
  })
```

## Data

```{ojs}
Inputs.table(filtered)
```

:::

전체 페이지 레이아웃

기본적으로 Quarto 문서는 문서 뷰포트 가운데에 내용을 배치하고, 최대 너비를 약 900픽셀로 제한합니다. 이는 가독성을 위한 동작이지만, 애플리케이션 레이아웃에서는 일반적으로 페이지 전체를 사용하고 싶습니다.

이를 위해 page-layout: custom 옵션을 추가합니다. 예시는 다음과 같습니다.

format: 
  html:
    page-layout: custom

아래는 브라우저 전체 너비를 차지하는 Shiny 애플리케이션 예시입니다.

입력이 사이드바에 포함되어 있다는 점도 확인할 수 있습니다. 다음 섹션에서는 사이드바를 만드는 방법을 설명합니다.

사이드바 패널

사이드바는 .panel-sidebar 클래스 div로 만들 수 있습니다. 위에서 .panel-input에 대해 설명한 것처럼 마크다운 div 컨테이너를 사용할 수도 있고, 사이드바의 전체 내용이 하나의 코드 셀로 생성되는 경우에는 셀에 panel: sidebar 옵션을 추가할 수도 있습니다.

사이드바 패널은 항상 인접한 .panel-fill 또는 .panel-center 패널과 함께 있어야 합니다. 전자는 사용 가능한 공간을 모두 채우고, 후자는 콘텐츠 주변에 가로 여백을 남깁니다.

예를 들어 위에 표시된 Shiny 애플리케이션의 사용자 인터페이스 부분 소스 코드는 다음과 같습니다.

---
title: "Iris K-Means Clustering"
format: 
  html:
    page-layout: custom
server: shiny
---

```{r}
#| panel: sidebar
vars <- setdiff(names(iris), "Species")
selectInput('xcol', 'X Variable', vars)
selectInput('ycol', 'Y Variable', vars, selected = vars[[2]])
numericInput('clusters', 'Cluster count', 3, min = 1, max = 9)
```

```{r}
#| panel: fill
plotOutput('plot1')
```

panel: fill 옵션은 플롯 출력 청크에 추가되었습니다. 패널 내용 주변에 가로 여백을 남기고 싶다면 panel: center를 사용할 수도 있습니다.

코드 청크에 panel 옵션을 추가하는 것은 해당 청크를 감싸는 div에 CSS 클래스를 추가하는 축약 표현입니다(즉, 코드 청크를 panel-fill 같은 클래스를 가진 div로 감싸는 것과 동일합니다).

OJS 입력과 함께 사이드바를 사용하는 예시는 다음과 같습니다.

이를 위해 다음 코드를 사용합니다.

```{ojs}
//| panel: sidebar

viewof myage = {
  const myage = select({
    title: "Quelle classe d'âge voulez-vous cartographier ?",
    options: ages,
    value: "80etplus"
  });
  return myage;
}

viewof pctvax = slider({
  title: '<br/>Objectif de vaccination',
  description: '200% signifie 2 doses par personnes pour tout le monde',
  min: 50,
  max: 200,
  value: 200,
  step: 10,
  format: v => v + "%"
})

viewof overlay = radio({
  title: "Écarter les cercles",
  options: [{ label: 'Oui', value: 'Y' }, { label: 'Non', value: 'N' }],
  value: 'N'
})

viewof label = radio({
  title: "Numéros des départements",
  options: [{ label: 'Afficher', value: 'Y' }, { label: 'Masquer', value: 'N' }],
  value: 'N'
})
```

```{ojs}
//| panel: fill

(vaccine visualization code)

```

패널 레이아웃

컨테이너 div의 layout 속성을 사용해 여러 인터랙티브 구성 요소를 패널로 배치할 수 있습니다. 예를 들어 아래에서는 첫 번째 행에 주요 시각화를 두고, 두 번째 행에 보조 시각화 두 개를 배치했습니다.

그림 문서에서 설명하듯이 layout 속성을 사용하면 매우 유연하게 패널을 배치할 수 있습니다. 위 예시에서는 세 개의 시각화를 다음 div로 감쌌습니다.

::: {layout="[ [1], [1,1] ]"}

(outputs)

:::

이미 패널인 div(예: .panel-fill)에도 layout 속성을 적용해 사이드바 옆 콘텐츠 레이아웃을 지정할 수 있습니다. 따라서 아래 마크업도 유효합니다.

::: {.panel-sidebar}

(inputs)

:::

::: {.panel-fill layout="[ [1], [1,1] ]"}

(outputs)

:::

layout 속성은 배열의 배열이며, 각 배열이 레이아웃의 한 행을 정의합니다. 위에서는 첫 번째 행이 첫 번째 시각화를 포함하고, 두 번째 행에서 나머지 두 개를 동일하게 나누도록 지정했습니다.

행의 값은 합이 특정 값이 될 필요가 없습니다(각 행 내에서 상대값입니다). 따라서 데이터 표현에 더 적합하다면 두 번째 행의 상대 너비를 다르게 지정할 수도 있습니다.

::: {layout="[ [1], [3,2] ]"}

(outputs)

:::