OJS 셀

OJS 코드 셀 {ojs}는 전통적인 노트북의 셀과는 조금 다르게 동작하며, 표시와 레이아웃을 제어할 수 있는 다양한 옵션이 있습니다.

셀 실행

OJS 셀 실행과 전통적인 노트북의 중요한 차이점은 OJS 셀이 특정한 순서로 정의될 필요가 없다는 점입니다.

실행이 완전히 반응형이므로 런타임은 셀 간의 참조 관계에 따라 올바른 순서로 자동 실행합니다. 이는 셀이 선형으로 실행되는 전통적인 노트북보다 스프레드시트에 더 가깝습니다.

예를 들어, 이 셀에서는 아직 정의되지 않은 변수를 참조합니다(바로 아래에서 정의됩니다).

```{ojs}
x + 5
```
```{ojs}
x = 10
```

이 코드는 Observable 런타임이 셀의 올바른 실행 순서를 자동으로 결정하기 때문에 동작합니다.

셀 출력

기본적으로 OJS 셀은 렌더링된 문서에서 전체 소스 코드와 출력을 표시합니다. 만들고 있는 문서 유형에 따라 이 동작을 전역 또는 개별 셀 단위로 변경하고 싶을 수도 있습니다.

코드 표시

echo 옵션은 셀이 소스 코드를 표시할지 여부를 제어합니다. 문서 전체에서 코드를 표시하지 않으려면 YAML 메타데이터에 echo: false 옵션을 설정합니다.

---
title: "My Document"
execute:
  echo: false
---

이 옵션은 셀 단위로도 지정할 수 있습니다. 예를 들면 다음과 같습니다.

```{ojs}
//| echo: false
data = FileAttachment("palmer-penguins.csv").csv({ typed: true })
```

출력 표시

OJS 셀 출력도 기본으로 표시됩니다. output 옵션을 사용해 전역 또는(더 흔하게는) 셀 단위로 이를 변경할 수 있습니다. 예를 들어 다음처럼 셀 출력을 끌 수 있습니다.

```{ojs}
//| output: false
data
```

할당만 포함한 셀은 기본적으로 출력을 표시하지 않습니다. 예를 들어 다음 할당은 아무것도 출력하지 않습니다.

```{ojs}
//| echo: fenced
dummy1 = "aHiddenAssignment"
```

할당 결과까지 출력하려면 output: all 옵션을 지정하면 됩니다. 예를 들면 다음과 같습니다.

```{ojs}
//| echo: fenced
//| output: all
dummy2 = [{key: 1, value: [1, 2, [3, 4], dummy1]}]
```

검사기를 클릭하면 JSON 형태로 데이터가 펼쳐져 보입니다.

코드 표시 방식

위에서 소스 코드를 표시하거나 숨기는 방법을 살펴봤는데, 표시 방식을 구체적으로 제어하는 방법은 어떨까요?

코드 블록의 모양(하이라이팅, 배경, 테두리 등)과 가로 오버플로 처리 방식까지 커스터마이즈할 수 있는 옵션이 있습니다. 자세한 내용은 HTML 코드 블록 문서를 참고하세요.

여기서 특별히 강조하고 싶은 옵션은 코드 접기입니다. 코드를 접어두되 사용자가 볼 수 있는 선택지를 제공할 수 있습니다. 맞춤형 JavaScript 시각화는 코드가 수십 줄에 이르는 경우가 많아 특히 유용합니다.

코드 셀에 code-fold: true 옵션을 추가하면 코드 접기를 활성화할 수 있습니다(전역으로도 설정 가능). 예를 들어 “코드” 버튼을 클릭하면 코드 블록이 표시됩니다(code-fold: true 옵션이 지정되어 있습니다).

Code
```{ojs}
//| code-fold: true
pdata = FileAttachment("palmer-penguins.csv").csv({typed: true})

Plot.plot({
  facet: {
    data: pdata,
    x: "sex",
    y: "species",
    marginRight: 80
  },
  marks: [
    Plot.frame(),
    Plot.rectY(pdata, 
      Plot.binX(
        {y: "count"}, 
        {x: "body_mass_g", thresholds: 20, fill: "species"}
      )
    ),
    Plot.tickX(pdata, 
      Plot.groupZ(
        {x: "median"}, 
        {x: "body_mass_g",
         z: d => d.sex + d.species,
         stroke: "#333",
         strokeWidth: 2
        }
      )
    )
  ]
})
```

셀 레이아웃

OJS 셀에는 출력 표시 방식을 커스터마이즈할 수 있는 panel, layout 옵션이 더 있습니다. 다음은 이전 예제 일부를 사이드바와 탭셋으로 구성한 버전입니다.

이 레이아웃은 먼저 입력을 담은 셀에 panel: sidebar 옵션을 추가해 만들었습니다.

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

viewof bill_length_min = Inputs.range(
  [32, 50], 
  {value: 35, step: 1, label: "부리 길이(최소):"}
)
viewof islands = Inputs.checkbox(
  ["Torgersen", "Biscoe", "Dream"], 
  { value: ["Torgersen", "Biscoe"], 
    label: "섬:"
  }
)
```

그 다음 그래프데이터 탭을 가진 탭셋(클래스가 .panel-tabset인 div)을 추가했습니다(div 안의 제목이 탭을 정의합니다).

::: {.panel-tabset}

## 그래프

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

## 데이터

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

:::

레이아웃 예제에서 전체 소스 코드를 확인할 수 있습니다.

인터랙티브 문서의 레이아웃 문서에서 더 자세히 알아보세요.

셀 그림

OJS 셀은 번호가 매겨지고 상호 참조 가능한 그림으로도 렌더링할 수 있습니다. 이를 위해 셀에 labelfig-cap 옵션을 추가합니다. 예를 들면 다음과 같습니다.

```{ojs}
//| echo: fenced
//| label: fig-penguin-body-mass
//| fig-cap: "성별과 종에 따른 펭귄 체중"
Plot.rectY(filtered, 
  Plot.binX(
    {y: "count"}, 
    {x: "body_mass_g", fill: "species", thresholds: 20}
  ))
  .plot({
    facet: {
      data: filtered,
      x: "sex",
      y: "species",
      marginRight: 80
    },
    marks: [
      Plot.frame(),
    ]
  }
)
```
Figure 1: 성별과 종에 따른 펭귄 체중

자세한 내용은 Figure 1 를 참고하세요.

그림을 참조하려면 마크다운 상호 참조에서 해당 레이블을 사용하세요:

자세한 내용은 @fig-penguin-body-mass 를 참고하세요.