# 데이터 레이블

## Content

데이터 레이블은 데이터 포인트에 대한 추가 정보를 **차트 위에 직접 표시**합니다. 사용자의 특정 요구 사항을 충족하도록 데이터 레이블을 추가하고, 서식을 지정하며, 커스터마이징할 수 있습니다.
`GC.Spread.Sheets.DataCharts` 네임스페이스의 `IPlotConfigTextOption` 인터페이스를 사용하여 데이터 차트의 데이터 레이블을 구성하고 관리할 수 있습니다. 이 인터페이스는 템플릿, 텍스트 스타일, 오프셋, 연결선 스타일 등 레이블의 외형 및 동작을 사용자 정의할 수 있는 다양한 속성을 제공합니다. 또한, `OverlappingLabels` 및 `TextPosition` 열거형을 사용하여 겹치는 레이블의 표시 여부와 레이블 텍스트의 위치를 각각 제어할 수 있습니다.

![image](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/9c3d6948-546a-4e49-bd0d-d1a9991a1a68/image.ec446d.png)

## **데이터 레이블 속성**

다음은 `IPlotConfigTextOption` 인터페이스의 주요 속성 목록입니다:

| 속성 | 설명 |
| --- | --- |
| `template` | 데이터 레이블의 구조를 사용자 정의합니다. |
| `format` | 데이터 레이블 값의 형식을 사용자 정의합니다. |
| `style` | `fill`, `fillOpacity`, `stroke`, `strokeWidth`, `strokeDasharray`, `strokeOpacity` 등의 속성을 통해 레이블의 외형과 스타일을 사용자 정의합니다. |
| `textStyle` | `fontSize`, `fontWeight`, `fontFamily`, `color`, `fontStyle`, `overflow` 등의 속성을 통해 레이블 내 텍스트 스타일을 사용자 정의합니다. |
| `maxWidth` | 데이터 레이블의 최대 너비를 설정합니다.<br>텍스트가 최대 너비를 초과하는 경우, `textStyle.overflow` 설정에 따라 표시됩니다. |
| `offset` | 기본 위치에서의 데이터 레이블 오프셋을 조정합니다. |
| `overlappingLabels` | 레이블이 겹치는 경우의 표시 여부를 제어합니다. |
| `position` | 데이터 포인트에 대한 레이블의 위치를 지정합니다. |
| `connectingLineStyle` | 데이터 포인트와 레이블 사이의 연결선 스타일을 사용자 정의합니다. <br>예: `stroke`, `strokeWidth`, `strokeDasharray` 등.<br>연결선 스타일 설정 시 주의사항:<ul><li>연결선을 보이게 하려면 `strokeWidth` 값이 0보다 커야 합니다.</li><li>파이 차트(pie chart)의 경우 `firstLineLength`와 `secondLineLength`를 사용해 레이블 연결선을 조정할 수 있습니다.</li></ul> |

## **코드 사용 예시**

아래 샘플 코드는 데이터 차트에서 데이터 레이블을 구성하고 커스터마이징하는 방법을 보여줍니다.

이 샘플은 “[데이터 차트 생성하기](/spreadjs/docs/features/data-charts/create-data-charts)” 페이지에서 설명된 `salesTable` 데이터를 사용합니다. 따라서, 해당 페이지에 안내된 **기본 설정 단계를 먼저 완료**해야 합니다. 설정이 완료된 후 아래의 코드를 사용하여 데이터 레이블을 구성할 수 있습니다. 또한, 필요에 따라 데이터 소스를 사용자 정의하는 것도 가능합니다.

```javascript
// 1. 데이터 레이블 템플릿 
const sheet = spread.getSheet(0);
sheet.name("Template");
sheet.setValue(23, 0, "Template Applied: '{colorField.name}: {colorField.value}\n{valueField.name}: {valueField.value}'");

const dataChart = sheet.dataCharts.add('data-chart', 10, 10, 800, 400, GC.Spread.Sheets.DataCharts.DataChartType.column);
dataChart.setChartConfig({
     tableName: 'Sales',
     plots: [
         {
             type: GC.Spread.Sheets.DataCharts.DataChartType.column,
             config: {
                 text: [{
                     // 데이터 레이블에 템플릿 설정
                     template: '{colorField.name}: {colorField.value}\n{valueField.name}: {valueField.value}', // string
                     position: GC.Spread.Sheets.DataCharts.TextPosition.outside, // GC.Spread.Sheets.DataCharts.TextPosition
                 }]
             },
             encodings: {
                 values: [{ field: 'Sales', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }],
                 category: { field: 'Product' },
                 color: { field: 'Product' },
             }
         }
     ]
});

// 2. 서식
const sheet2 = spread.getSheet(1);
sheet2.name("Format");
sheet2.setValue(23, 0, "Template Applied: '{colorField.value}\n{valueField.value}'");
sheet2.setValue(24, 0, "Format Applied: '$0'");

const dataChart2 = sheet2.dataCharts.add('data-chart-2', 10, 10, 800, 400, GC.Spread.Sheets.DataCharts.DataChartType.column);
dataChart2.setChartConfig({
     tableName: 'Sales',
     plots: [
         {
             type: GC.Spread.Sheets.DataCharts.DataChartType.column,
             config: {
                 text: [{
                     template: '{colorField.value}\n{valueField.value}',
                     //  데이터 레이블에 서식 적용
                     format: { value: '$0' }, // 문자
                     position: GC.Spread.Sheets.DataCharts.TextPosition.outside,
                 }]
             },
             encodings: {
                 values: [{ field: 'Sales', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }],
                 category: { field: 'Product' },
                 color: { field: 'Product' },
             }
         }
     ]
});

// 3. 스타일
const sheet3 = spread.getSheet(2);
sheet3.name("Style");
sheet3.setValue(23, 0, "Template Applied: '{colorField.value}\n{valueField.value}'");
sheet3.setValue(24, 0, "Style has been applied to Data Label");

const dataChart3 = sheet3.dataCharts.add('data-chart-3', 10, 10, 800, 400, GC.Spread.Sheets.DataCharts.DataChartType.column);
dataChart3.setChartConfig({
     tableName: 'Sales',
     plots: [
         {
             type: GC.Spread.Sheets.DataCharts.DataChartType.column,
             config: {
                 text: [{
                     template: '{colorField.value}\n{valueField.value}',
                     position: GC.Spread.Sheets.DataCharts.TextPosition.outside,
                    // style 속성을 사용하면 사용자들이 데이터 레이블의 스타일을 커스터마이징할 수 있습니다.
                     style: {         // GC.Spread.Sheets.DataCharts.IStyleOption
                         fill: { type: 'CssColor', color: 'rgb(255, 255, 255)' },
                         fillOpacity: 0,
                         stroke: { type: 'CssColor', color: "red" },
                         strokeOpacity: 0.5,
                         strokeWidth: 2,
                         strokeDasharray: '5,5'
                     },
                 }]
             },
             encodings: {
                 values: [{ field: 'Sales', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }],
                 category: { field: 'Product' },
                 color: { field: 'Product' },
             }
         }
     ]
});

// 4. 텍스트 스타일
const sheet4 = spread.getSheet(3);
sheet4.name("Text Style");
sheet4.setValue(23, 0, "Template Applied: '{colorField.value}\n{valueField.value}'");
sheet4.setValue(24, 0, "Style has been applied to Data Label");

const dataChart4 = sheet4.dataCharts.add('data-chart-4', 10, 10, 800, 400, GC.Spread.Sheets.DataCharts.DataChartType.column);
dataChart4.setChartConfig({
     tableName: 'Sales',
     plots: [
         {
             type: GC.Spread.Sheets.DataCharts.DataChartType.column,
             config: {
                 text: [{
                     template: '{colorField.value}\n{valueField.value}',
                     position: GC.Spread.Sheets.DataCharts.TextPosition.outside,
                    // textStyle 속성을 사용하면 사용자들이 데이터 레이블의 텍스트 스타일을 커스터마이징할 수 있습니다.
                     textStyle: {       // GC.Spread.Sheets.DataCharts.ITextStyleOption
                         fontFamily: 'Calibri',
                         fontSize: 14,
                         fontWeight: 'Lighter',
                         fontStyle: GC.Spread.Sheets.DataCharts.FontStyle.italic,
                         color: 'rgba(51, 51, 51, 1)',
                         overflow: GC.Spread.Sheets.DataCharts.TextOverflow.ellipsis
                     },
                     maxWidth: 60,
                 }]
             },
             encodings: {
                 values: [{ field: 'Sales', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }],
                 category: { field: 'Product' },
                 color: { field: 'Product' },
             }
         }
     ]
 });

// 5. 최대 너비 
const sheet5 = spread.getSheet(4);
sheet5.name("Max Width");
sheet5.setValue(16, 0, "Max Width: 40");
sheet5.setValue(17, 0, "Text Style Overflow: Wrap");

const dataChart5 = sheet5.dataCharts.add('data-chart-5', 10, 10, 400, 300, GC.Spread.Sheets.DataCharts.DataChartType.column);
dataChart5.setChartConfig({
     tableName: 'Sales',
     plots: [
         {
             type: GC.Spread.Sheets.DataCharts.DataChartType.column,
             config: {
                 text: [{
                     template: '{colorField.value}\n{valueField.value}',
                     position: GC.Spread.Sheets.DataCharts.TextPosition.outside,
                   // maxWidth 속성을 사용하면 데이터 레이블의 최대 너비를 사용자 정의할 수 있습니다.
                    maxWidth: 40,  // 숫자
                    // 데이터 레이블 텍스트가 최대 너비를 초과하는 경우, 텍스트는 textStyle.overflow 설정에 따라 표시됩니다.
                     textStyle: {
                         overflow: GC.Spread.Sheets.DataCharts.TextOverflow.wrap
                     },
                 }]
             },
             encodings: {
                 values: [{ field: 'Sales', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }],
                 category: { field: 'Product' },
                 color: { field: 'Product' },
             }
         }
     ]
});

// 6. 연결선 스타일
const sheet6 = spread.getSheet(5);
sheet6.name("Connecting Line Style");
sheet6.setValue(19, 0, "Connecting Line Style- StrokeWidth: 1");
sheet6.setValue(20, 0, "Connecting Line Style- StrokeDashArray: 5,5");

sheet6.setValue(19, 10, "Connecting Line Style- StrokeWidth: 1");
sheet6.setValue(20, 10, "Connecting Line Style- StrokeDashArray: 5,5");
sheet6.setValue(21, 10, "Connecting Line Style- firstLineLength: 20");
sheet6.setValue(22, 10, "Connecting Line Style- secondLineLength: 20");

const dataChart6 = sheet6.dataCharts.add('data-chart-6', 10, 10, 500, 350, GC.Spread.Sheets.DataCharts.DataChartType.column);
dataChart6.setChartConfig({
     tableName: 'Sales',
     plots: [
         {
             type: GC.Spread.Sheets.DataCharts.DataChartType.column,
             config: {
                 text: [{
                     template: '{colorField.value}\n{valueField.value}',
                     position: GC.Spread.Sheets.DataCharts.TextPosition.outside,
                     offset: 20,
                     // connectingLineStyle 속성을 사용하면 데이터 레이블과 데이터 포인트 사이의 연결선 스타일을 커스터마이징할 수 있습니다.
                    connectingLineStyle: {
                        strokeWidth: 1, // 선의 두께를 설정합니다. 기본값은 0이며, 연결선을 표시하려면 이 값을 0보다 크게 설정해야 합니다.
                        strokeDasharray: '5,5', // 선의 점선 패턴을 정의합니다. 점선을 표시하려면 '5,5'와 같은 패턴을 설정합니다.
                     }
                 }]
             },
             encodings: {
                 values: [{ field: 'Sales', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }],
                 category: { field: 'Product' },
                 color: { field: 'Product' },
             }
         }
     ]
});

const dataChart7 = sheet6.dataCharts.add('data-chart-7', 600, 10, 600, 350, GC.Spread.Sheets.DataCharts.DataChartType.column);
dataChart7.setChartConfig({
     tableName: 'Sales',
     plots: [
         {
             type: GC.Spread.Sheets.DataCharts.DataChartType.pie,
             config: {
                 text: [{
                     template: '{colorField.value},{valueField.value}',
                     position: GC.Spread.Sheets.DataCharts.TextPosition.outside,
                 connectingLineStyle: {
                    strokeWidth: 1, // 선의 두께를 설정합니다. 기본값은 0이며, 연결선을 표시하려면 이 값을 0보다 크게 설정해야 합니다.
                    strokeDasharray: '5,5', // 선의 점선 패턴을 정의합니다. 점선을 표시하려면 '5,5'와 같은 값을 설정합니다.
                    firstLineLength: 20, // 연결선의 첫 번째 구간(데이터 포인트에 가장 가까운 구간)의 길이를 설정합니다. 이 속성은 파이 차트(pie chart) 유형에만 적용됩니다. 다른 차트 유형에서는 offset 속성을 사용하세요.
                    secondLineLength: 20, // 연결선의 두 번째 구간(데이터 레이블 텍스트에 가장 가까운 구간)의 길이를 설정합니다. 이 속성 역시 파이 차트 유형에만 적용됩니다. 다른 차트 유형에서는 offset 속성을 사용하세요.
                    }
                 }]
             },
             encodings: {
                 values: [{ field: 'Sales', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }],
                 color: { field: 'Product' },
             }
         }
     ]
});

// 7. 오프셋
const sheet7 = spread.getSheet(6);
sheet7.name("Offset");
sheet7.setValue(19, 0, "Offset 40 is applied to the Data Label");

const dataChart8 = sheet7.dataCharts.add('data-chart-8', 10, 10, 500, 350, GC.Spread.Sheets.DataCharts.DataChartType.column);
dataChart8.setChartConfig({
     tableName: 'Sales',
     plots: [
         {
             type: GC.Spread.Sheets.DataCharts.DataChartType.column,
             config: {
                 text: [{
                     template: '{colorField.value}\n{valueField.value}',
                     position: GC.Spread.Sheets.DataCharts.TextPosition.outside,
                    // offset 속성을 사용하면 데이터 레이블의 원래 위치를 기준으로 위치를 조정할 수 있습니다.
                     offset: 40, // number
                 }]
             },
             encodings: {
                 values: [{ field: 'Sales', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }],
                 category: { field: 'Product' },
                 color: { field: 'Product' },
             }
         }
     ]
});

// 8. 레이블 겹침 
const sheet8 = spread.getSheet(7);
sheet8.name("Overlapping Labels");
sheet8.setValue(8, 0, "Overlapping Labels: Show");
sheet8.setValue(24, 0, "Overlapping Labels: Hide");

const dataChart9 = sheet8.dataCharts.add('data-chart-9', 300, 10, 600, 300, GC.Spread.Sheets.DataCharts.DataChartType.column);
dataChart9.setChartConfig({
     tableName: 'Sales',
     plots: [
         {
             type: GC.Spread.Sheets.DataCharts.DataChartType.pie,
             config: {
                 text: [{
                     template: '{valueField.value}',
                     position: GC.Spread.Sheets.DataCharts.TextPosition.outside,
                    // overlappingLabels 속성을 사용하면 레이블이 겹칠 때의 표시 여부를 제어할 수 있습니다.
                     overlappingLabels: GC.Spread.Sheets.DataCharts.OverlappingLabels.show,
                 }]
             },
             encodings: {
                 values: [{ field: 'Sales', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }],
                 color: { field: 'Sales' },
             }
         }
     ]
});

const dataChart10 = sheet8.dataCharts.add('data-chart-10', 300, 330, 600, 300, GC.Spread.Sheets.DataCharts.DataChartType.column);
dataChart10.setChartConfig({
     tableName: 'Sales',
     plots: [
         {
             type: GC.Spread.Sheets.DataCharts.DataChartType.pie,
             config: {
                 text: [{
                     template: '{valueField.value}',
                     position: GC.Spread.Sheets.DataCharts.TextPosition.outside,
                     overlappingLabels: GC.Spread.Sheets.DataCharts.OverlappingLabels.hide,  // Hide 
                 }]
             },
             encodings: {
                 values: [{ field: 'Sales', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }],
                 color: { field: 'Sales' },
             }
         }
     ]
 });

// 9. 위치
const sheet9 = spread.getSheet(8);
sheet9.name("Position");
sheet9.setColumnCount(25);
sheet9.setValue(13, 0, "Position: Outside");
sheet9.setValue(13, 11, "Position: Inside");
sheet9.setValue(30, 0, "Position: Center");

const dataChart11 = sheet9.dataCharts.add('data-chart-11', 10, 10, 600, 250, GC.Spread.Sheets.DataCharts.DataChartType.column);
dataChart11.setChartConfig({
     tableName: 'Sales',
     plots: [
         {
             type: GC.Spread.Sheets.DataCharts.DataChartType.donut,
             config: {
                 text: [{
                     template: '{colorField.value}',
                     // position 속성을 사용하면 데이터 포인트에 대해 데이터 레이블의 위치를 정의할 수 있습니다.
                     position: GC.Spread.Sheets.DataCharts.TextPosition.outside,  // Outside
                 }]
             },
             encodings: {
                 values: [{ field: 'Sales', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }],
                 color: { field: 'Salesman' },
             }
         }
     ]
});

const dataChart12 = sheet9.dataCharts.add('data-chart-12', 650, 10, 600, 250, GC.Spread.Sheets.DataCharts.DataChartType.column);
dataChart12.setChartConfig({
     tableName: 'Sales',
     plots: [
         {
             type: GC.Spread.Sheets.DataCharts.DataChartType.donut,
             config: {
                 text: [{
                     template: '{colorField.value}',
                     position: GC.Spread.Sheets.DataCharts.TextPosition.inside, // Inside
                 }]
             },
             encodings: {
                 values: [{ field: 'Sales', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }],
                 color: { field: 'Salesman' },
             }
         }
     ]
});

const dataChart13 = sheet9.dataCharts.add('data-chart-13', 10, 350, 600, 250, GC.Spread.Sheets.DataCharts.DataChartType.column);
dataChart13.setChartConfig({
     tableName: 'Sales',
     plots: [
         {
             type: GC.Spread.Sheets.DataCharts.DataChartType.donut,
             config: {
                 text: [{
                     template: '{colorField.value}',
                     position: GC.Spread.Sheets.DataCharts.TextPosition.center, // Center
                 }]
             },
             encodings: {
                 values: [{ field: 'Sales', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }],
                 color: { field: 'Salesman' },
             }
         }
     ]
});
```