csat-chart.js 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,914 @@
1
+ interface EnsureFontsOptions {
2
+ /**
3
+ * 글꼴 CSS 주소. 기본은 Google Fonts. 사내망·오프라인이면 바꾼다.
4
+ *
5
+ * `families` 와 짝이다. 한쪽만 바꾸면 어긋난다 — 예컨대 `families` 만
6
+ * 바꾸면 기본 구글 스타일시트가 그 글꼴을 제공하지 않는데도 `true` 가
7
+ * 나온다(아래 반환값 설명 참고).
8
+ */
9
+ href?: string;
10
+ /** 확인할 글꼴 이름. 기본은 Noto Serif KR, Noto Sans KR. `href` 와 함께 바꾼다. */
11
+ families?: string[];
12
+ /** 이 시간(ms) 안에 준비되지 않으면 false 를 돌려주고 넘어간다. 기본 5000 */
13
+ timeoutMs?: number;
14
+ }
15
+ /**
16
+ * 시험지 양식에 쓰이는 글꼴을 확보한다.
17
+ *
18
+ * 브라우저에서만 일한다. 준비되면 `true`, 시간 안에 못 받거나 Node 이거나
19
+ * 브라우저가 `document.fonts` 를 모르면 `false` 를 돌려준다. **던지지 않는다** —
20
+ * 글꼴이 없어도 그림은 대체 글꼴로 그려져야 하기 때문이다.
21
+ *
22
+ * ⚠️ `true` 가 «그 글꼴로 그려진다» 를 보장하지는 않는다. `document.fonts.load`
23
+ * 는 페이지에 `@font-face` 가 없는 이름에 대해 거부하지 않고 **빈 배열로
24
+ * 이행한다**. 그래서 `href` 없이 `families` 만 바꾸면 없는 글꼴에도 `true` 가
25
+ * 나온다. 둘은 함께 바꾼다.
26
+ *
27
+ * ⚠️ 여러 번 불러도 실제 작업은 한 번만 하는데, **나중 호출의 옵션은 조용히
28
+ * 버려진다.** 앞선 호출이 이미 시작했으면 그 약속을 그대로 돌려준다. 사내망
29
+ * 주소를 쓸 것이라면 **가장 먼저** 그 옵션으로 부른다.
30
+ *
31
+ * ⚠️ «한 번만» 은 이 모듈 한 벌 기준이다. 한 페이지에 ESM 판과 CDN 판이 함께
32
+ * 올라오면 각자 한 번씩 한다. `<link>` 는 id 로 걸러지므로 두 번 들어가지는
33
+ * 않는다.
34
+ */
35
+ declare function ensureFonts(options?: EnsureFontsOptions): Promise<boolean>;
36
+
37
+ type LegendPosition = 'bottom' | 'right';
38
+ /** 플롯 안쪽 범례를 놓을 모서리 */
39
+ type InsideLegendCorner = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
40
+ interface GraphOptions {
41
+ title: string;
42
+ source: string;
43
+ /**
44
+ * 출처 줄 **왼쪽**에 함께 적는 글 (예: 자료 연도 `(2024)`).
45
+ *
46
+ * 주면 출처 줄이 각주 **아래**로 내려가고 왼쪽·오른쪽에 나눠 적힌다.
47
+ * 미지정이면 기존대로 출처가 각주 위에 오른쪽 정렬로만 놓인다.
48
+ */
49
+ sourceLeft?: string;
50
+ /**
51
+ * 출처를 **마지막 각주와 같은 줄** 오른쪽 끝에 적는다 (각주는 왼쪽 끝).
52
+ *
53
+ * 시험지 관습이다 — 원본은 `* 1991~2020년의 평년값임.` 과 `(기상청)` 이
54
+ * 한 줄에 좌우로 놓인다. 미지정이면 기존대로 출처가 각주 **위** 줄에 놓인다.
55
+ * 각주가 없으면 아무 차이가 없다.
56
+ */
57
+ sourceInline?: boolean;
58
+ footnotes: string[];
59
+ fontFamily: 'serif' | 'sans' | 'custom';
60
+ customFont: string;
61
+ fontSize: {
62
+ title: number;
63
+ axisLabel: number;
64
+ tick: number;
65
+ dataLabel: number;
66
+ };
67
+ showDataLabels: boolean;
68
+ showLegend: boolean;
69
+ legendPosition: LegendPosition;
70
+ legendLabel1: string;
71
+ legendLabel2: string;
72
+ }
73
+ declare function createDefaultGraphOptions(): GraphOptions;
74
+
75
+ interface ClimateMonthData {
76
+ temp: number;
77
+ precip: number;
78
+ }
79
+ type MonthInterval = 12 | 4 | 2;
80
+ interface ClimateGraphData {
81
+ months: ClimateMonthData[];
82
+ monthInterval: MonthInterval;
83
+ tempLabel: string;
84
+ precipLabel: string;
85
+ tempRange: {
86
+ min: number;
87
+ max: number;
88
+ auto: boolean;
89
+ step?: number;
90
+ };
91
+ precipRange: {
92
+ min: number;
93
+ max: number;
94
+ auto: boolean;
95
+ step?: number;
96
+ };
97
+ }
98
+ type ClimateMode = 'normal' | 'deviationA' | 'deviationB';
99
+ interface DeviationAData {
100
+ baseMonths: ClimateMonthData[];
101
+ months: ClimateMonthData[];
102
+ monthInterval: MonthInterval;
103
+ tempLabel: string;
104
+ precipLabel: string;
105
+ /** step 을 주면 눈금 간격을 그 값으로 고정한다. 미지정이면 기존대로 자동 계산 */
106
+ tempRange: {
107
+ min: number;
108
+ max: number;
109
+ auto: boolean;
110
+ step?: number;
111
+ };
112
+ precipRange: {
113
+ min: number;
114
+ max: number;
115
+ auto: boolean;
116
+ step?: number;
117
+ };
118
+ /**
119
+ * 막대 채움을 하나로 고정한다. 미지정이면 기존대로 양수는 진회색,
120
+ * 음수는 연회색으로 나뉜다. 시험지는 부호와 무관하게 한 색이다.
121
+ */
122
+ barFill?: string;
123
+ /** 막대 테두리색 — 미지정이면 `#444` */
124
+ barStroke?: string;
125
+ /** 꺾은선의 점 모양 — 미지정이면 원. 시험지는 검은 정사각형을 쓴다. */
126
+ markerShape?: 'circle' | 'square';
127
+ /**
128
+ * 좌·우 축 이름. 주면 눈금 숫자 바깥에 **한 글자씩 세로로** 쌓아 그린다.
129
+ * 미지정이면 단위 표기(tempLabel·precipLabel)만 축 위에 놓는다.
130
+ */
131
+ tempAxisName?: string;
132
+ precipAxisName?: string;
133
+ /** 범례를 플롯 안쪽 모서리 상자에 둔다. 자료를 덮는 모서리는 피한다. */
134
+ insideLegend?: InsideLegendCorner;
135
+ /** 위·오른쪽까지 이어 사각 테두리로 감싼다. 미지정이면 ㄷ자 축선만 그린다. */
136
+ showFrame?: boolean;
137
+ }
138
+ interface DeviationBRegion {
139
+ label: string;
140
+ precip: number;
141
+ temp: number;
142
+ }
143
+ interface DeviationBData {
144
+ baseTemp: number;
145
+ basePrecip: number;
146
+ regions: DeviationBRegion[];
147
+ precipDiffLabel: string;
148
+ tempDiffLabel: string;
149
+ precipUnit: string;
150
+ tempUnit: string;
151
+ precipRange: {
152
+ min: number;
153
+ max: number;
154
+ auto: boolean;
155
+ };
156
+ tempRange: {
157
+ min: number;
158
+ max: number;
159
+ auto: boolean;
160
+ };
161
+ }
162
+ declare function createDefaultDeviationAData(): DeviationAData;
163
+ declare function createDefaultDeviationBData(): DeviationBData;
164
+ declare function createDefaultClimateData(): ClimateGraphData;
165
+
166
+ interface PyramidAgeData {
167
+ male: number;
168
+ female: number;
169
+ }
170
+ type PyramidUnit = 'count' | 'percent';
171
+ type AgeLabelSide = 'left' | 'right' | 'center';
172
+ interface PyramidGraphData {
173
+ ages: PyramidAgeData[];
174
+ unit: PyramidUnit;
175
+ maleLabel: string;
176
+ femaleLabel: string;
177
+ axisLabel: string;
178
+ range: {
179
+ max: number;
180
+ auto: boolean;
181
+ };
182
+ ageLabelSide: AgeLabelSide;
183
+ /**
184
+ * 세로축을 연령대 이름(0-4, 5-9…) 대신 **나이 수치 눈금**으로 그린다.
185
+ * 시험지 피라미드가 이 방식이다 — 왼쪽에 (세) 0/20/40/60/80.
186
+ * 미지정이면 기존대로 연령대 이름을 쓴다.
187
+ */
188
+ numericAgeAxis?: boolean;
189
+ /** 나이 축 단위 표기 (numericAgeAxis 일 때만). 예: '(세)' */
190
+ ageUnit?: string;
191
+ /**
192
+ * 가로축 단위 표기를 눈금 **숫자와 같은 줄** 오른쪽 끝에 둔다.
193
+ * 시험지 피라미드가 이 배치다. 미지정이면 기존대로 숫자 아랫줄에 적는다.
194
+ */
195
+ axisLabelInline?: boolean;
196
+ /**
197
+ * 남·여 막대 채움색 [남, 여]. 미지정이면 기존 색(진회색/연회색).
198
+ * 시험지는 둘 다 같은 연회색에 검정 테두리다.
199
+ */
200
+ sexFills?: [string, string];
201
+ }
202
+ declare function createDefaultPyramidData(): PyramidGraphData;
203
+
204
+ interface TernaryPoint {
205
+ a: number;
206
+ b: number;
207
+ c: number;
208
+ label: string;
209
+ }
210
+ type TernaryGridInterval = 10 | 20 | 25;
211
+ interface TernaryGraphData {
212
+ points: TernaryPoint[];
213
+ axisLabels: [string, string, string];
214
+ gridInterval: TernaryGridInterval;
215
+ }
216
+ declare function createDefaultTernaryData(): TernaryGraphData;
217
+
218
+ type StackedDisplayMode = 'bar' | 'pie';
219
+ type StackedBarDirection = 'vertical' | 'horizontal';
220
+ interface StackedCategory {
221
+ label: string;
222
+ values: number[];
223
+ /**
224
+ * 이 막대에서 세그먼트를 쌓을 순서 (아래→위). 계열 번호를 늘어놓는다.
225
+ *
226
+ * 시험지 누적 막대는 막대마다 **자기 값 순서로** 쌓는다(큰 값이 아래,
227
+ * '기타'가 맨 위). 계열 순서는 모든 막대가 공유하므로 그것만으로는
228
+ * 재현할 수 없다. 미지정이면 기존대로 계열 번호 순으로 쌓는다.
229
+ */
230
+ segmentOrder?: number[];
231
+ }
232
+ interface StackedGraphData {
233
+ displayMode: StackedDisplayMode;
234
+ barDirection: StackedBarDirection;
235
+ categories: StackedCategory[];
236
+ seriesLabels: string[];
237
+ unit: string;
238
+ /**
239
+ * 계열별 채움 직접 지정. `'pattern:diagonal'` 처럼 적으면 패턴을 쓴다.
240
+ * 미지정이면 기존 팔레트(getStackedFill).
241
+ */
242
+ seriesFills?: string[];
243
+ /**
244
+ * 값 대신 **계열 이름**을 세그먼트 안에 적는다.
245
+ *
246
+ * 시험지 누적 막대는 범례 없이 칸마다 이름을 적는 경우가 많다.
247
+ * 패턴 위에서도 읽히도록 글자에 흰 테두리를 두르고, 어두운 채움 위에서는
248
+ * 흰 글자로 쓴다. 미지정이면 기존대로 `showDataLabels` 에 따라 값을 적는다.
249
+ */
250
+ labelInSegment?: boolean;
251
+ /**
252
+ * 계열 이름이 기호(A·B)인지 실제 이름인지. 시험지는 기호를 명조,
253
+ * 지명을 고딕으로 쓴다. 미지정이면 전부 본문 글꼴.
254
+ */
255
+ seriesIsSymbol?: boolean[];
256
+ /** 가로 격자선 색 — 미지정이면 `#ddd`. 시험지는 더 진하다. */
257
+ gridColor?: string;
258
+ pieRotation?: number;
259
+ pieScale?: number;
260
+ axisStep?: number;
261
+ }
262
+ declare function createDefaultStackedData(): StackedGraphData;
263
+
264
+ type AbsBarDirection = 'vertical' | 'horizontal';
265
+ interface AbsBarCategory {
266
+ label: string;
267
+ values: number[];
268
+ }
269
+ interface AbsBarGraphData {
270
+ barDirection: AbsBarDirection;
271
+ stacked: boolean;
272
+ categories: AbsBarCategory[];
273
+ seriesLabels: string[];
274
+ unit: string;
275
+ yRange: {
276
+ min: number;
277
+ max: number;
278
+ auto: boolean;
279
+ step?: number;
280
+ };
281
+ fitMax?: boolean;
282
+ /**
283
+ * 계열별 채움색 직접 지정. 미지정이면 기존 팔레트(getStackedFill)를 쓴다.
284
+ * 원본 시험지를 재현할 때 기본 팔레트와 색이 다른 경우에 쓴다.
285
+ */
286
+ seriesFills?: string[];
287
+ /**
288
+ * 0을 기준으로 막대를 그린다. 음수는 0에서 아래로 내려가고 0 위치에 실선을 긋는다.
289
+ *
290
+ * 미지정이면 기존대로 축 바닥에서 막대가 자란다. 축이 음수까지 내려가는
291
+ * 편차 그래프에서는 그 방식이 막대를 허공에 띄운 것처럼 보이게 한다.
292
+ */
293
+ zeroBaseline?: boolean;
294
+ /**
295
+ * 범주 라벨을 0선 바로 아래에 놓는다. 미지정이면 플롯 아래(축 바깥)에 놓는다.
296
+ *
297
+ * 시험지마다 다르다 — 2026 수능 한국지리 6번은 0선 아래, 2025 수능
298
+ * 세계지리 19번은 플롯 아래다. 그래서 zeroBaseline 과 따로 둔다.
299
+ */
300
+ categoryLabelAtBaseline?: boolean;
301
+ /**
302
+ * 범주를 묶어 2단 라벨로 만든다 (가로 막대 전용).
303
+ *
304
+ * 시험지에서 흔한 형태다 — 바깥 라벨이 A·B·C, 안쪽 라벨이 1990년·2020년.
305
+ * `span` 은 그 그룹에 속한 범주 개수이고, 합이 categories 길이와 같아야 한다.
306
+ * 그룹 안 막대는 서로 붙고 그룹 사이는 벌어진다.
307
+ *
308
+ * 미지정이면 기존대로 범주마다 라벨 하나를 고르게 배치한다.
309
+ */
310
+ groups?: {
311
+ label: string;
312
+ span: number;
313
+ }[];
314
+ /**
315
+ * 범례를 플롯 안쪽 모서리에 작은 상자로 둔다.
316
+ *
317
+ * 미지정이면 기존대로 options.legendPosition 을 따라 플롯 바깥에 그린다.
318
+ */
319
+ insideLegend?: 'top-right' | 'top-left';
320
+ /**
321
+ * 단위를 마지막 눈금 숫자 바로 옆에 붙인다 (가로 막대 전용).
322
+ *
323
+ * 원본 시험지는 축 끝이 `100(EJ)` 처럼 붙어 있다.
324
+ * 미지정이면 기존대로 축 오른쪽에 조금 떨어뜨려 그린다.
325
+ */
326
+ unitAdjacent?: boolean;
327
+ }
328
+ declare function createDefaultAbsBarData(): AbsBarGraphData;
329
+
330
+ type ScatterMode = 'normal' | 'deviation';
331
+ interface ScatterPoint {
332
+ x: number;
333
+ y: number;
334
+ size: number;
335
+ label: string;
336
+ /**
337
+ * 이 점(버블)의 채움색. 미지정이면 기존 회색을 쓴다.
338
+ * 크기와 별개인 두 번째 값(예: 1인당 GDP 구간)을 색으로 나타낼 때 쓴다.
339
+ */
340
+ fill?: string;
341
+ }
342
+ /**
343
+ * 버블 범례 자리.
344
+ *
345
+ * `outside-right` 는 플롯 **바깥** 오른쪽 여백에 세로로 쌓는다. 자료를 아예
346
+ * 덮지 않으므로 점이 많을 때 가장 안전하다. 나머지는 플롯 안쪽 모서리이고,
347
+ * 버블을 덜 덮는 쪽으로 알아서 옮겨 간다.
348
+ */
349
+ type BubbleLegendPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'outside-right';
350
+ interface ScatterGraphData {
351
+ mode: ScatterMode;
352
+ points: ScatterPoint[];
353
+ bubbleLegendPosition: BubbleLegendPosition;
354
+ xLabel: string;
355
+ yLabel: string;
356
+ xUnit: string;
357
+ yUnit: string;
358
+ /** step 을 주면 눈금 간격을 그 값으로 고정한다. 미지정이면 기존대로 자동 계산 */
359
+ xRange: {
360
+ min: number;
361
+ max: number;
362
+ auto: boolean;
363
+ step?: number;
364
+ };
365
+ yRange: {
366
+ min: number;
367
+ max: number;
368
+ auto: boolean;
369
+ step?: number;
370
+ };
371
+ showBubble: boolean;
372
+ bubbleScale: number;
373
+ /**
374
+ * 바깥 사각 테두리를 그린다. 미지정이면 그린다(기존 동작).
375
+ * 시험지 편차 그래프는 테두리 없이 교차하는 두 축만 둔다.
376
+ *
377
+ * **편차 모드 전용이다.** 일반 모드의 틀은 `examFrame` 이 정한다.
378
+ */
379
+ showFrame?: boolean;
380
+ /**
381
+ * 일반 모드의 틀을 시험지 모양으로 바꾼다. 세 가지가 함께 간다 —
382
+ * 시험지 산점도에서 늘 같이 나타나므로 하나로 묶었다.
383
+ *
384
+ * 1. 플롯을 사각 테두리로 감싼다 (기본은 왼쪽·아래 축선만)
385
+ * 2. 격자를 진한 점선으로 (기본은 아주 연한 회색)
386
+ * 3. x축 단위를 **마지막 눈금 옆**에 둔다 — 원본은 `4(℃)` 꼴이다
387
+ * (기본은 축 이름과 같은 줄 오른쪽 끝)
388
+ *
389
+ * 미지정이면 기존 동작 그대로다.
390
+ */
391
+ examFrame?: boolean;
392
+ /**
393
+ * 축 이름을 상자에 넣어 y는 그래프 위, x는 그래프 오른쪽에 세운다.
394
+ * 시험지 편차 그래프 관습이다. 미지정이면 기존대로 축 옆에 쓴다.
395
+ * 편차 모드에서만 쓴다.
396
+ */
397
+ boxedAxisLabels?: boolean;
398
+ /**
399
+ * 눈금과 눈금 숫자를 가운데 십자선 축에 붙인다. 미지정이면 플롯 가장자리에 붙인다.
400
+ * 테두리를 끄면(showFrame: false) 가장자리에 붙은 눈금이 허공에 뜨므로 함께 쓴다.
401
+ * 편차 모드에서만 쓴다.
402
+ */
403
+ ticksOnAxis?: boolean;
404
+ /**
405
+ * 채움색이 무엇을 뜻하는지 알려주는 범례. 버블 크기 범례 아래에 놓인다.
406
+ * 미지정이면 그리지 않는다.
407
+ */
408
+ fillLegend?: {
409
+ title: string;
410
+ items: {
411
+ label: string;
412
+ fill: string;
413
+ }[];
414
+ };
415
+ /**
416
+ * 버블 크기 범례에 쓸 항목을 직접 지정한다.
417
+ * 미지정이면 최댓값에서 자동으로 세 단계를 잡고 숫자를 그대로 쓴다 —
418
+ * 인구처럼 자릿수가 큰 값은 그대로 두면 읽을 수 없으므로 여기서 정해 준다.
419
+ */
420
+ bubbleLegendItems?: {
421
+ size: number;
422
+ label: string;
423
+ }[];
424
+ quadrantLabels: [string, string, string, string];
425
+ }
426
+ declare function createDefaultScatterData(): ScatterGraphData;
427
+
428
+ type HythergraphMode = 'loop' | 'points' | 'both';
429
+ type MonthLabelStyle = 'number' | 'english';
430
+ interface HythergraphSeries {
431
+ label: string;
432
+ months: ClimateMonthData[];
433
+ }
434
+ interface HythergraphData {
435
+ series: HythergraphSeries[];
436
+ mode: HythergraphMode;
437
+ monthLabelStyle: MonthLabelStyle;
438
+ xUnit: string;
439
+ yUnit: string;
440
+ xRange: {
441
+ min: number;
442
+ max: number;
443
+ auto: boolean;
444
+ };
445
+ yRange: {
446
+ min: number;
447
+ max: number;
448
+ auto: boolean;
449
+ };
450
+ }
451
+ declare function createDefaultHythergraphData(): HythergraphData;
452
+
453
+ interface CubePoint {
454
+ x: number;
455
+ y: number;
456
+ z: number;
457
+ label: string;
458
+ labelDx: number;
459
+ labelDy: number;
460
+ }
461
+ interface LabelOffset {
462
+ x: number;
463
+ y: number;
464
+ }
465
+ interface CubeAxisConfig {
466
+ name: string;
467
+ lowLabel: string;
468
+ highLabel: string;
469
+ lowOffset: LabelOffset;
470
+ highOffset: LabelOffset;
471
+ }
472
+ interface CubeGraphData {
473
+ points: CubePoint[];
474
+ xAxis: CubeAxisConfig;
475
+ yAxis: CubeAxisConfig;
476
+ zAxis: CubeAxisConfig;
477
+ }
478
+ declare function createDefaultCubeData(): CubeGraphData;
479
+
480
+ interface RadarSeries {
481
+ label: string;
482
+ values: number[];
483
+ }
484
+ interface RadarGraphData {
485
+ axisLabels: string[];
486
+ series: RadarSeries[];
487
+ maxValue: number;
488
+ autoMax: boolean;
489
+ gridSteps: number;
490
+ showFill: boolean;
491
+ }
492
+ declare function createDefaultRadarData(): RadarGraphData;
493
+
494
+ /** 계열 구분은 색이 아니라 기호 모양으로 한다 (흑백 인쇄 관습) */
495
+ type DotMarker = 'circle' | 'square' | 'triangle' | 'diamond';
496
+ interface CategoryDotCategory {
497
+ label: string;
498
+ /** 계열별 값. 계열이 하나면 길이 1. */
499
+ values: number[];
500
+ }
501
+ interface CategoryDotGraphData {
502
+ categories: CategoryDotCategory[];
503
+ seriesLabels: string[];
504
+ /** 계열별 기호. 미지정이면 DOT_MARKER_ORDER 순서를 쓴다. */
505
+ seriesMarkers?: DotMarker[];
506
+ /** y축 단위 — 축 위쪽에 붙는다 (예: '(°C)') */
507
+ unit: string;
508
+ /** 점 반지름(px) */
509
+ dotRadius: number;
510
+ yRange: {
511
+ min: number;
512
+ max: number;
513
+ auto: boolean;
514
+ step?: number;
515
+ };
516
+ /**
517
+ * 0 위치에 실선을 긋는다. 편차 그래프에서 기준선을 보이게 하려고 쓴다.
518
+ * 점 자체는 값 위치에 찍히므로 막대와 달리 기준선이 그리기에 영향을 주지 않는다.
519
+ */
520
+ zeroBaseline?: boolean;
521
+ }
522
+ declare function createDefaultCategoryDotData(): CategoryDotGraphData;
523
+
524
+ /** 선 종류 — 흑백 인쇄에서 계열을 구분하는 수단 */
525
+ type LineStyle = 'solid' | 'dashed' | 'dotted' | 'dashdot';
526
+ /** 꼭짓점 기호 — 선 종류만으로 부족할 때 함께 쓴다 */
527
+ type LineMarker = 'circle' | 'square' | 'triangle' | 'diamond';
528
+ interface LineSeries {
529
+ label: string;
530
+ /** xLabels 와 같은 길이. 빠진 값은 null 로 둔다 (선이 끊긴다). */
531
+ values: (number | null)[];
532
+ lineStyle?: LineStyle;
533
+ marker?: LineMarker;
534
+ /** 기호 속을 비운다 (흰색 채움 + 검정 테두리) */
535
+ hollowMarker?: boolean;
536
+ /**
537
+ * 면적 채움색. 주면 이 계열의 선 아래를 채운다.
538
+ * `stacked` 와 함께 쓰면 아래 계열의 경계까지만 채워 누적 면적이 된다.
539
+ */
540
+ areaFill?: string;
541
+ }
542
+ /** 계열 이름을 어디에 쓸지 */
543
+ type LineLabelPlacement = 'lineEnd' | 'legend';
544
+ interface LineGraphData {
545
+ series: LineSeries[];
546
+ /** x축 눈금 이름 (예: 1~12월) */
547
+ xLabels: string[];
548
+ /** x축 끝에 붙는 단위 (예: '(월)') */
549
+ xUnit: string;
550
+ /** y축 위에 붙는 단위 (예: '(°C)') */
551
+ yUnit: string;
552
+ yRange: {
553
+ min: number;
554
+ max: number;
555
+ auto: boolean;
556
+ step?: number;
557
+ };
558
+ /** 기본은 시험지 관습대로 선 끝 */
559
+ labelPlacement: LineLabelPlacement;
560
+ showMarkers: boolean;
561
+ /** 0 위치에 점선 기준선을 긋는다 (편차 그래프) */
562
+ zeroBaseline?: boolean;
563
+ /**
564
+ * 계열을 아래에서부터 쌓아 올린다 (누적 면적 그래프).
565
+ * 각 계열의 선은 "그때까지의 합"을 나타낸다.
566
+ */
567
+ stacked?: boolean;
568
+ /**
569
+ * 범례를 플롯 안쪽 왼쪽 위에 작은 상자로 둔다.
570
+ * 시험지 누적 면적 그래프가 이 방식이다. `labelPlacement:'legend'` 와 함께 쓴다.
571
+ */
572
+ insideLegend?: boolean;
573
+ }
574
+ declare function createDefaultLineData(): LineGraphData;
575
+
576
+ interface MatrixTableData {
577
+ /**
578
+ * 대각선 칸에 들어갈 이름. 문제에서 가릴 이름은 이미 (가)·(나)로
579
+ * 바꿔서 넘긴다 — 렌더러는 무엇을 가렸는지 모른다.
580
+ */
581
+ names: string[];
582
+ /**
583
+ * 짝별 값. `values[i][j]`(j < i)만 쓴다 — 위 삼각형과 대각선은 무시한다.
584
+ * 정사각 행렬을 그대로 넘겨도 된다.
585
+ */
586
+ values: number[][];
587
+ /**
588
+ * 이름이 기호인지((가)·A) 실제 지명인지.
589
+ *
590
+ * 시험지는 **기호를 명조, 지명을 고딕**으로 쓴다. 미지정이면 전부
591
+ * 본문 글꼴(`options.fontFamily`)을 쓴다.
592
+ */
593
+ nameIsSymbol?: boolean[];
594
+ /** 오른쪽 위에 붙는 단위 표기. 예: `'(단위 : km)'` */
595
+ unit: string;
596
+ /** 이름 칸 채움색 — 미지정이면 연회색 */
597
+ nameFill?: string;
598
+ /** 천 단위 쉼표 — 미지정이면 붙인다 (원본이 `2,648` 꼴이다) */
599
+ groupThousands?: boolean;
600
+ }
601
+ declare function createDefaultMatrixTableData(): MatrixTableData;
602
+
603
+ interface DataTableRow {
604
+ /** 항목 이름. 예: `'기온의 연교차'` */
605
+ label: string;
606
+ /** 이름 뒤에 붙는 괄호 단위. 원본은 이름보다 조금 작게 쓴다. 예: `'(℃)'` */
607
+ unit?: string;
608
+ /** 머리글 순서대로 놓이는 값 */
609
+ values: number[];
610
+ /** 소수점 자릿수. 미지정이면 1자리 — 시험지 표는 대개 소수 한 자리다. */
611
+ decimals?: number;
612
+ }
613
+ interface DataTableData {
614
+ /** 왼쪽 위 모서리 칸. 원본은 `'구분'` */
615
+ cornerLabel: string;
616
+ /**
617
+ * 머리글. 시험지는 지역을 (가)~(라) 처럼 기호로 가린다.
618
+ * 문제에서 가릴 이름은 이미 바꿔서 넘긴다 — 렌더러는 무엇을 가렸는지 모른다.
619
+ */
620
+ columns: string[];
621
+ rows: DataTableRow[];
622
+ /**
623
+ * 머리글이 기호인지((가)·A) 실제 지명인지.
624
+ *
625
+ * 시험지는 **기호를 명조, 지명을 고딕**으로 쓴다. 미지정이면 전부
626
+ * 본문 글꼴(`options.fontFamily`)을 쓴다.
627
+ */
628
+ columnIsSymbol?: boolean[];
629
+ /** 머리글 행 채움색 — 미지정이면 연회색 */
630
+ headerFill?: string;
631
+ /** 천 단위 쉼표 — 미지정이면 붙인다 */
632
+ groupThousands?: boolean;
633
+ }
634
+ declare function createDefaultDataTableData(): DataTableData;
635
+
636
+ interface TreemapCell {
637
+ label: string;
638
+ /** 넓이의 근거가 되는 값. 렌더러가 합으로 나눠 비율을 낸다. */
639
+ value: number;
640
+ }
641
+ interface TreemapGraphData {
642
+ /**
643
+ * 순서는 배치 결과에만 영향을 준다 — 넓이는 값 비율대로 나뉘므로 어느
644
+ * 순서든 정확하다. 다만 내림차순이라야 칸이 정사각형에 가깝게 나온다.
645
+ * '기타'는 값이 더 크더라도 시험지 관행대로 맨 뒤에 둔다.
646
+ */
647
+ cells: TreemapCell[];
648
+ /** 칸 라벨 글자 크기. 미지정이면 options.fontSize.tick 을 쓴다. */
649
+ labelFontSize?: number;
650
+ /**
651
+ * 라벨을 적을 최소 칸 너비(px). 이보다 좁으면 글자를 생략한다.
652
+ * 좁은 칸에 억지로 넣으면 글자가 테두리를 넘어 옆 칸을 밟는다.
653
+ */
654
+ minLabelWidth?: number;
655
+ /**
656
+ * 출처가 없어도 출처 한 줄만큼 아래를 비워 둔다.
657
+ *
658
+ * 패널을 여러 장 나란히 놓을 때 쓴다 — 출처를 마지막 패널에만 적으면
659
+ * 그 패널만 상자가 짧아져 줄이 안 맞는다. 모두 같은 자리를 비우면
660
+ * 상자 높이가 같아지고 출처는 상자 **아래**에 놓인다.
661
+ */
662
+ reserveSourceSpace?: boolean;
663
+ }
664
+ declare function createDefaultTreemapData(): TreemapGraphData;
665
+
666
+ declare function renderAbsBarGraph(ctx: CanvasRenderingContext2D, w: number, h: number, data: AbsBarGraphData, options: GraphOptions): void;
667
+
668
+ declare function renderCategoryDotGraph(ctx: CanvasRenderingContext2D, w: number, h: number, data: CategoryDotGraphData, options: GraphOptions): void;
669
+
670
+ declare function renderLineGraph(ctx: CanvasRenderingContext2D, w: number, h: number, data: LineGraphData, options: GraphOptions): void;
671
+
672
+ declare function renderMatrixTable(ctx: CanvasRenderingContext2D, w: number, h: number, data: MatrixTableData, options: GraphOptions): void;
673
+
674
+ declare function renderDataTable(ctx: CanvasRenderingContext2D, w: number, h: number, data: DataTableData, options: GraphOptions): void;
675
+
676
+ declare function renderTreemapGraph(ctx: CanvasRenderingContext2D, w: number, h: number, data: TreemapGraphData, options: GraphOptions): void;
677
+
678
+ declare function renderClimateGraph(ctx: CanvasRenderingContext2D, w: number, h: number, data: ClimateGraphData, options: GraphOptions): void;
679
+
680
+ declare function renderCubeGraph(ctx: CanvasRenderingContext2D, w: number, h: number, data: CubeGraphData, options: GraphOptions): void;
681
+
682
+ declare function renderDeviationAGraph(ctx: CanvasRenderingContext2D, w: number, h: number, data: DeviationAData, options: GraphOptions): void;
683
+
684
+ declare function renderDeviationBGraph(ctx: CanvasRenderingContext2D, w: number, h: number, data: DeviationBData, options: GraphOptions): void;
685
+
686
+ declare function renderHythergraph(ctx: CanvasRenderingContext2D, w: number, h: number, data: HythergraphData, options: GraphOptions): void;
687
+
688
+ declare function renderPyramidGraph(ctx: CanvasRenderingContext2D, w: number, h: number, data: PyramidGraphData, options: GraphOptions): void;
689
+
690
+ declare function renderRadarChart(ctx: CanvasRenderingContext2D, w: number, h: number, data: RadarGraphData, options: GraphOptions): void;
691
+
692
+ declare function renderScatterGraph(ctx: CanvasRenderingContext2D, w: number, h: number, data: ScatterGraphData, options: GraphOptions): void;
693
+
694
+ declare function renderStackedGraph(ctx: CanvasRenderingContext2D, w: number, h: number, data: StackedGraphData, options: GraphOptions): void;
695
+
696
+ declare function renderTernaryGraph(ctx: CanvasRenderingContext2D, w: number, h: number, data: TernaryGraphData, options: GraphOptions): void;
697
+
698
+ /** 적절한 눈금 간격을 자동 계산 */
699
+ declare function niceStep(range: number, maxTicks?: number): number;
700
+ /** 자동 축 범위 계산 (min, max, step) */
701
+ declare function autoRange(values: number[], maxTicks?: number): {
702
+ min: number;
703
+ max: number;
704
+ step: number;
705
+ };
706
+
707
+ interface ChartDataMap {
708
+ absbar: AbsBarGraphData;
709
+ 'category-dot': CategoryDotGraphData;
710
+ climate: ClimateGraphData;
711
+ cube: CubeGraphData;
712
+ 'data-table': DataTableData;
713
+ 'deviation-a': DeviationAData;
714
+ 'deviation-b': DeviationBData;
715
+ hythergraph: HythergraphData;
716
+ line: LineGraphData;
717
+ 'matrix-table': MatrixTableData;
718
+ pyramid: PyramidGraphData;
719
+ radar: RadarGraphData;
720
+ scatter: ScatterGraphData;
721
+ stacked: StackedGraphData;
722
+ ternary: TernaryGraphData;
723
+ treemap: TreemapGraphData;
724
+ }
725
+ /** 그릴 수 있는 그래프 종류. 여러 낱말은 kebab-case, 한 낱말은 그대로. */
726
+ type CsatChartType = keyof ChartDataMap;
727
+ /**
728
+ * 부분 지정을 허용하는 옵션.
729
+ *
730
+ * `Partial` 은 맨 위 칸만 선택으로 만든다. 그래서 `fontSize` 는 넷을 다 적어야
731
+ * 했다 — 런타임은 하나만 줘도 받는데 타입이 막는, 거꾸로 된 어긋남이다.
732
+ * 한 겹 더 풀어 준다.
733
+ */
734
+ type PartialGraphOptions = Omit<Partial<GraphOptions>, 'fontSize'> & {
735
+ fontSize?: Partial<GraphOptions['fontSize']>;
736
+ };
737
+ /** 한 종류의 설정. `type` 을 적으면 `data` 가 그 종류로 좁혀진다. */
738
+ interface ConfigFor<T extends CsatChartType> {
739
+ type: T;
740
+ data: ChartDataMap[T];
741
+ options?: PartialGraphOptions;
742
+ }
743
+ /** 16종을 모은 판별 유니온. */
744
+ type CsatChartConfig = {
745
+ [K in CsatChartType]: ConfigFor<K>;
746
+ }[CsatChartType];
747
+ /** 한 종류의 부분 갱신. 준 것만 덮는다. */
748
+ interface UpdateFor<T extends CsatChartType> {
749
+ data?: ChartDataMap[T];
750
+ options?: PartialGraphOptions;
751
+ }
752
+
753
+ /**
754
+ * 브라우저의 `HTMLCanvasElement` 와 Node 캔버스 구현체가 함께 만족하는 최소 모양.
755
+ * 라이브러리는 이 이상을 요구하지 않는다.
756
+ */
757
+ interface CanvasLike {
758
+ width: number;
759
+ height: number;
760
+ getContext(id: '2d'): unknown;
761
+ toDataURL?(type?: string): string;
762
+ }
763
+ /**
764
+ * 종류 하나를 붙들고 사는 차트.
765
+ *
766
+ * `T` 는 생성자의 `config.type` 에서 추론된다. 그래서 `update()` 의 `data` 도
767
+ * 같은 종류로 좁혀지고, 다른 종류의 데이터를 넣으면 컴파일 시점에 걸린다.
768
+ */
769
+ declare class CsatChart<T extends CsatChartType = CsatChartType> {
770
+ /**
771
+ * 시험지 글꼴을 확보한다. 자세한 것은 `ensureFonts` 참고.
772
+ *
773
+ * 필드가 아니라 **메서드**로 둔다. `static readonly ensureFonts = ensureFonts`
774
+ * 로 적으면 ES2020 로 낮출 때 클래스 «뒤» 의 대입문이 되는데, 그것은 지울 수
775
+ * 없는 부수효과라 이 클래스와 레지스트리와 렌더러 16종이 모든 번들에 박힌다.
776
+ * 메서드는 클래스 본문의 일부라 어느 목표에서도 그런 일이 없다 — 실제로
777
+ * 겪은 문제이고, `test/bundle.test.ts` 가 이걸 회귀로 잡지는 않으니 여기
778
+ * 적어 둔다.
779
+ */
780
+ static ensureFonts(options?: EnsureFontsOptions): Promise<boolean>;
781
+ readonly canvas: CanvasLike;
782
+ private readonly ctx;
783
+ private readonly type;
784
+ private data;
785
+ private options;
786
+ private destroyed;
787
+ constructor(target: CanvasLike | string, config: ConfigFor<T>);
788
+ /** `data`·`options` 중 준 것만 덮고 다시 그린다. 어긋나면 던지고 이전 상태를 지킨다. */
789
+ update(next: UpdateFor<T>): this;
790
+ resize(width: number, height: number): this;
791
+ /**
792
+ * PNG data URL 을 돌려준다.
793
+ *
794
+ * `scale` 은 **글자·선까지 함께 키우는** 배율이다. 캔버스만 키우는
795
+ * `resize(1600, 1200)` 과 다르다 — 이 라이브러리의 글꼴 크기와 여백은 절대
796
+ * 픽셀이라, 캔버스를 두 배로 하면 «두 배로 선명한 같은 그림» 이 아니라
797
+ * «글자가 절반으로 작아진 다른 그림» 이 나온다. 인쇄용으로 뽑으려면 이쪽을 쓴다.
798
+ */
799
+ toDataURL(options?: {
800
+ scale?: number;
801
+ }): string;
802
+ /** 브라우저 전용. Node 에서는 `toDataURL()` 이나 캔버스의 버퍼를 쓴다. */
803
+ download(filename?: string, options?: {
804
+ scale?: number;
805
+ }): void;
806
+ destroy(): void;
807
+ /**
808
+ * 글꼴이 늦게 도착하면 한 번 다시 그린다.
809
+ *
810
+ * `await CsatChart.ensureFonts()` 를 빠뜨리는 실수가 이 라이브러리에서 가장
811
+ * 흔할 실패다. 그런데 증상이 조용하고 영구적이다 — 대체 글꼴로 «멀쩡히»
812
+ * 그려지고, 잠시 뒤 글꼴이 도착해도 아무도 다시 그리지 않는다. 시험지 서체를
813
+ * 모르는 사람은 무엇이 잘못됐는지조차 알 수 없다. 빌드 도구도 타입 검사도
814
+ * 없는 사용자에게 그 책임을 문서로만 지울 수는 없다.
815
+ *
816
+ * ⚠️ 만능이 아니다. `document.fonts.ready` 는 **부르는 시점에** 로딩 중인
817
+ * 것이 끝나면 이행한다. 그래서 차트를 먼저 만들고 `ensureFonts()` 를 나중에
818
+ * 부르면 이 약속은 이미 이행된 뒤라 도움이 안 된다. 순서를 지켜 부르거나,
819
+ * 그냥 `await` 하는 것이 여전히 옳다.
820
+ */
821
+ private redrawWhenFontsArrive;
822
+ private draw;
823
+ /**
824
+ * 논리 크기는 `width`×`height` 로 두고 픽셀만 `scale` 배로 그린다.
825
+ *
826
+ * 렌더러들은 변환 행렬을 전혀 건드리지 않으므로(`grep setTransform src/core` →
827
+ * 없음) 여기서 한 번 걸어 두면 그림 전체가 그대로 확대된다.
828
+ */
829
+ private drawScaled;
830
+ private assertAlive;
831
+ }
832
+
833
+ /**
834
+ * 사전순으로 정렬된 전체 종류 목록. 오류 메시지와 데모가 이 순서를 쓴다.
835
+ *
836
+ * `Object.freeze` 를 쓰는 까닭: `readonly` 는 타입에만 있고 런타임에는 없다.
837
+ * 이 패키지는 타입 검사를 받지 않는 CDN 사용자를 겨냥하므로, 얼려 두지 않으면
838
+ * `CsatChart.CHART_TYPES.reverse()` 한 번에 오류 메시지가 조용히 망가진다.
839
+ *
840
+ * 인자 없는 `sort()` 는 로캘을 보지 않고 UTF-16 코드 단위로 비교한다(명세).
841
+ * 리눅스 CI 의 small-icu 빌드에서도 같은 순서가 나온다.
842
+ *
843
+ * 아래 세 PURE 주석을 지우지 말 것. `Object.freeze`·`.sort()`·`Object.keys`
844
+ * 모두 이 모듈 맨 위에서 실행되는 함수 호출이다 — 번들러는 함수 호출에
845
+ * 부작용이 있을 수 있다고 보수적으로 가정하므로, 표시가 없으면 `CHART_TYPES`
846
+ * 를 아무도 안 써도 이 문장을 지우지 못하고, 그 문장이 붙들고 있는
847
+ * `REGISTRY`(=16종 렌더러 전부)까지 함께 남는다. **셋 중 하나라도 빠지면**
848
+ * 나머지 호출이 여전히 `REGISTRY` 를 읽으므로 소용이 없다 — 실제로 겪은
849
+ * 문제다(`Object.freeze` 하나만 표시했을 때는 번들이 전혀 줄지 않았다).
850
+ * 표시를 지우면 저수준 렌더러 하나만 가져와도 번들이 줄지 않는 문제가
851
+ * 조용히 되돌아온다.
852
+ */
853
+ declare const CHART_TYPES: readonly CsatChartType[];
854
+ /**
855
+ * 아는 키인지 본다.
856
+ *
857
+ * **`v in REGISTRY` 로 바꾸지 말 것.** REGISTRY 는 객체 리터럴이라 프로토타입을
858
+ * 물고 있어서 `'constructor'`·`'__proto__'`·`'toString'` 이 전부 통과하고,
859
+ * 곧이어 `REGISTRY['constructor'].render` 에서 터진다.
860
+ */
861
+ declare function isCsatChartType(v: unknown): v is CsatChartType;
862
+
863
+ declare class CsatChartError extends Error {
864
+ constructor(message: string);
865
+ }
866
+
867
+ /**
868
+ * `CanvasRenderingContext2D.prototype.roundRect` 가 없으면 심는다.
869
+ *
870
+ * - 브라우저가 아닌 곳(Node 등)에서는 아무 일도 하지 않는다 —
871
+ * `typeof CanvasRenderingContext2D === 'undefined'` 로 가려낸다.
872
+ * - 이미 있으면(Chrome 99·Firefox 112·Safari 16.4 이상, 또는 이미 폴리필이
873
+ * 설치된 두 번째 호출) 아무 일도 하지 않는다 — 네이티브 구현을 밀어내지 않는다.
874
+ * - 그 아래에서만 심는다.
875
+ *
876
+ * `CsatChart` 생성자가 첫 렌더 전에 이 함수를 부르므로 파사드 사용자는 따로
877
+ * 부를 필요가 없다. 저수준 렌더러(`renderClimateGraph` 등)를 파사드 없이 직접
878
+ * 부르는 사람은 그리기 전에 `installRoundRectPolyfill()` 을 한 번 불러야
879
+ * 한다 — 파사드를 거치지 않으므로 이 라이브러리가 대신 불러 줄 자리가 없다.
880
+ *
881
+ * @returns 실제로 심었으면 `true`. 심을 필요가 없었으면(Node 이거나 이미
882
+ * 있음) `false`.
883
+ */
884
+ declare function installRoundRectPolyfill(): boolean;
885
+
886
+ /**
887
+ * 상수는 얼려서 내보낸다.
888
+ *
889
+ * 여기서 내보내는 것은 렌더러가 기본값으로 읽는 **바로 그 객체**다. 얼리지 않으면
890
+ * `CsatChart.DOT_MARKER_ORDER.reverse()` 한 번에 이후 모든 그림의 기호 배정이
891
+ * 조용히 어긋난다. 타입 검사를 받지 않는 CDN 사용자를 겨냥한 패키지라 특히 그렇다.
892
+ * `CHART_TYPES` 를 얼린 것과 같은 이유다.
893
+ *
894
+ * 각 `Object.freeze` 앞의 PURE 주석을 지우지 말 것. 함수 호출은 번들러가
895
+ * 부작용이 있을 수 있다고 보수적으로 가정하는 대상이라, 표시가 없으면 이
896
+ * 상수들을 아무도 안 써도 문장 자체가 안 지워진다 — 여기서는 값이 각각
897
+ * `core` 배열 하나씩만 가리키므로 결과가 이 파일 안에서 끝나 심각하지 않지만,
898
+ * `registry.ts` 의 `CHART_TYPES` 는 같은 문제가 16종 렌더러 전체를 붙드는
899
+ * 문제로 번진다. 그 사례를 따라 여기도 표시해 둔다.
900
+ */
901
+ declare const AGE_GROUPS: readonly string[];
902
+ declare const DOT_MARKER_ORDER: readonly DotMarker[];
903
+ declare const LINE_MARKER_ORDER: readonly LineMarker[];
904
+ declare const LINE_STYLE_ORDER: readonly LineStyle[];
905
+ declare const MONTH_LABELS_EN: readonly string[];
906
+ declare const MONTH_LABELS_NUM: readonly string[];
907
+ declare const LINE_DASH: Readonly<{
908
+ solid: readonly number[];
909
+ dashed: readonly number[];
910
+ dotted: readonly number[];
911
+ dashdot: readonly number[];
912
+ }>;
913
+
914
+ export { AGE_GROUPS, type AbsBarCategory, type AbsBarDirection, type AbsBarGraphData, type AgeLabelSide, type BubbleLegendPosition, CHART_TYPES, type CanvasLike, type CategoryDotCategory, type CategoryDotGraphData, type ChartDataMap, type ClimateGraphData, type ClimateMode, type ClimateMonthData, type ConfigFor, CsatChart, type CsatChartConfig, CsatChartError, type CsatChartType, type CubeAxisConfig, type CubeGraphData, type CubePoint, DOT_MARKER_ORDER, type DataTableData, type DataTableRow, type DeviationAData, type DeviationBData, type DeviationBRegion, type DotMarker, type EnsureFontsOptions, type GraphOptions, type HythergraphData, type HythergraphMode, type HythergraphSeries, type InsideLegendCorner, LINE_DASH, LINE_MARKER_ORDER, LINE_STYLE_ORDER, type LabelOffset, type LegendPosition, type LineGraphData, type LineLabelPlacement, type LineMarker, type LineSeries, type LineStyle, MONTH_LABELS_EN, MONTH_LABELS_NUM, type MatrixTableData, type MonthInterval, type MonthLabelStyle, type PartialGraphOptions, type PyramidAgeData, type PyramidGraphData, type PyramidUnit, type RadarGraphData, type RadarSeries, type ScatterGraphData, type ScatterMode, type ScatterPoint, type StackedBarDirection, type StackedCategory, type StackedDisplayMode, type StackedGraphData, type TernaryGraphData, type TernaryGridInterval, type TernaryPoint, type TreemapCell, type TreemapGraphData, type UpdateFor, autoRange, createDefaultAbsBarData, createDefaultCategoryDotData, createDefaultClimateData, createDefaultCubeData, createDefaultDataTableData, createDefaultDeviationAData, createDefaultDeviationBData, createDefaultGraphOptions, createDefaultHythergraphData, createDefaultLineData, createDefaultMatrixTableData, createDefaultPyramidData, createDefaultRadarData, createDefaultScatterData, createDefaultStackedData, createDefaultTernaryData, createDefaultTreemapData, ensureFonts, installRoundRectPolyfill, isCsatChartType, niceStep, renderAbsBarGraph, renderCategoryDotGraph, renderClimateGraph, renderCubeGraph, renderDataTable, renderDeviationAGraph, renderDeviationBGraph, renderHythergraph, renderLineGraph, renderMatrixTable, renderPyramidGraph, renderRadarChart, renderScatterGraph, renderStackedGraph, renderTernaryGraph, renderTreemapGraph };