@opsnow-mcp/opsnow-mcp-common-ui-server 1.0.22 → 1.0.24

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.
@@ -514,6 +514,59 @@ export const PieChartExamples = [
514
514
  chartCustomCategory={chartCustomCategory}
515
515
  />`
516
516
  },
517
+ {
518
+ title: '파이 차트 - 다운로드',
519
+ description: 'ref를 사용하여 파이 차트를 다양한 형식으로 다운로드하는 예제입니다. 다운로드 시에는 chartRef가 아닌 React ref를 사용해야 합니다. downloadFile(fileName, fileType, fileOption?)을 호출합니다.',
520
+ code_props_usage: `
521
+ const chartId = 'pie-chart-download-${generateUniqueGeneralId()}'
522
+ const chartRef = useRef(null)
523
+ const [chartProps] = useState({
524
+ series: {
525
+ categoryField: 'service',
526
+ valueField: 'cost',
527
+ tooltip: {
528
+ type: 'CI',
529
+ body: {
530
+ name: '{category}',
531
+ value: '\${value.formatNumber("0,0.00")}',
532
+ useMarker: true
533
+ }
534
+ }
535
+ },
536
+ legend: {}
537
+ })
538
+ const [chartData] = useState([
539
+ { service: 'EC2', cost: 15600 },
540
+ { service: 'RDS', cost: 8200 },
541
+ { service: 'S3', cost: 4300 }
542
+ ])
543
+ const [chartCategory] = useState(['EC2', 'RDS', 'S3'])
544
+
545
+ // 다운로드 핸들러
546
+ const handleDownload = () => {
547
+ chartRef.current.downloadFile('파일명', 'xlsx')
548
+ }
549
+
550
+ // 커스텀 데이터 소스로 다운로드
551
+ const handleCustomDownload = () => {
552
+ chartRef.current.downloadFile('파일명', 'xlsx', {
553
+ dataSource: [
554
+ { Category: 'Custom Row 1', Value: 100 },
555
+ { Category: 'Custom Row 2', Value: 200 }
556
+ ]
557
+ })
558
+ }
559
+
560
+ // 지원 형식: xlsx, csv, png, jpg, pdf, json, html, canvas, pdfdata, print
561
+ `,
562
+ code: `<OpsnowCommonPieChart
563
+ ref={chartRef}
564
+ chartId={chartId}
565
+ chartProps={chartProps}
566
+ chartCategory={chartCategory}
567
+ chartData={chartData}
568
+ />`
569
+ },
517
570
  ];
518
571
  export const BarChartExamples = [
519
572
  {
@@ -1275,6 +1328,97 @@ export const BarChartExamples = [
1275
1328
  chartCategory={chartCategory}
1276
1329
  />`
1277
1330
  },
1331
+ {
1332
+ title: '바 차트 - 다운로드 (기본)',
1333
+ description: 'ref를 사용하여 바 차트를 다양한 형식으로 다운로드하는 예제입니다. 다운로드 시에는 chartRef가 아닌 React ref를 사용해야 합니다. downloadFile(fileName, fileType, fileOption?)을 호출합니다.',
1334
+ code_props_usage: `
1335
+ const chartId = 'bar-chart-download-${generateUniqueGeneralId()}'
1336
+ const chartRef = useRef(null)
1337
+ const [chartProps] = useState({
1338
+ xAxis: { type: 'category', valueField: 'month' },
1339
+ yAxis: { type: 'value' },
1340
+ series: {
1341
+ valueXField: 'month',
1342
+ columns: { width: 'p60' },
1343
+ tooltip: {
1344
+ type: 'CG',
1345
+ body: {
1346
+ name: '{name}',
1347
+ value: '\${valueY.formatNumber("0,0.00")}',
1348
+ useMarker: true
1349
+ }
1350
+ }
1351
+ },
1352
+ legend: {}
1353
+ })
1354
+ const [chartData] = useState([
1355
+ { month: 'Jan', AWS: 12500, Azure: 8300 },
1356
+ { month: 'Feb', AWS: 13100, Azure: 8700 }
1357
+ ])
1358
+ const [chartCategory] = useState(['AWS', 'Azure'])
1359
+
1360
+ // 다운로드 핸들러
1361
+ const handleDownload = () => {
1362
+ chartRef.current.downloadFile('파일명', 'xlsx')
1363
+ }
1364
+ `,
1365
+ code: `<OpsnowCommonBarChart
1366
+ ref={chartRef}
1367
+ chartId={chartId}
1368
+ chartProps={chartProps}
1369
+ chartCategory={chartCategory}
1370
+ chartData={chartData}
1371
+ />`
1372
+ },
1373
+ {
1374
+ title: '바 차트 - 다운로드 (커스텀 데이터 소스)',
1375
+ description: '커스텀 데이터 소스를 지정하여 차트 데이터를 다운로드하는 예제입니다. downloadFile의 세 번째 인자로 dataSource를 전달하면 차트 데이터 대신 지정한 데이터로 다운로드됩니다.',
1376
+ code_props_usage: `
1377
+ const chartId = 'bar-chart-custom-download-${generateUniqueGeneralId()}'
1378
+ const chartRef = useRef(null)
1379
+ const [chartProps] = useState({
1380
+ xAxis: { type: 'category', valueField: 'month' },
1381
+ yAxis: { type: 'value' },
1382
+ series: {
1383
+ valueXField: 'month',
1384
+ columns: { width: 'p60' },
1385
+ tooltip: {
1386
+ type: 'CG',
1387
+ body: {
1388
+ name: '{name}',
1389
+ value: '\${valueY.formatNumber("0,0.00")}',
1390
+ useMarker: true
1391
+ }
1392
+ }
1393
+ },
1394
+ legend: {}
1395
+ })
1396
+ const [chartData] = useState([
1397
+ { month: 'Jan', AWS: 12500, Azure: 8300 },
1398
+ { month: 'Feb', AWS: 13100, Azure: 8700 }
1399
+ ])
1400
+ const [chartCategory] = useState(['AWS', 'Azure'])
1401
+
1402
+ // 커스텀 데이터 소스로 다운로드
1403
+ const handleCustomDownload = () => {
1404
+ chartRef.current.downloadFile('파일명', 'xlsx', {
1405
+ dataSource: [
1406
+ { Category: 'Custom Row 1', Value: 100 },
1407
+ { Category: 'Custom Row 2', Value: 200 }
1408
+ ]
1409
+ })
1410
+ }
1411
+
1412
+ // 지원 형식: xlsx, csv, png, jpg, pdf, json, html, canvas, pdfdata, print
1413
+ `,
1414
+ code: `<OpsnowCommonBarChart
1415
+ ref={chartRef}
1416
+ chartId={chartId}
1417
+ chartProps={chartProps}
1418
+ chartCategory={chartCategory}
1419
+ chartData={chartData}
1420
+ />`
1421
+ },
1278
1422
  ];
1279
1423
  export const LineChartExamples = [
1280
1424
  {
@@ -2239,6 +2383,59 @@ export const LineChartExamples = [
2239
2383
  chartCategoryLocaleMapping={chartCategoryLocaleMapping}
2240
2384
  />`
2241
2385
  },
2386
+ {
2387
+ title: '라인 차트 - 다운로드',
2388
+ description: 'ref를 사용하여 라인 차트를 다양한 형식으로 다운로드하는 예제입니다. 다운로드 시에는 chartRef가 아닌 React ref를 사용해야 합니다. downloadFile(fileName, fileType, fileOption?)을 호출합니다.',
2389
+ code_props_usage: `
2390
+ const chartId = 'line-chart-download-${generateUniqueGeneralId()}'
2391
+ const chartRef = useRef(null)
2392
+ const [chartProps] = useState({
2393
+ xAxis: { type: 'category', valueField: 'month' },
2394
+ yAxis: { type: 'value' },
2395
+ series: {
2396
+ valueXField: 'month',
2397
+ tooltip: {
2398
+ type: 'CG',
2399
+ body: {
2400
+ name: '{name}',
2401
+ value: '\${valueY.formatNumber("0,0.00")}',
2402
+ useMarker: true
2403
+ }
2404
+ }
2405
+ },
2406
+ legend: {}
2407
+ })
2408
+ const [chartData] = useState([
2409
+ { month: 'Jan', AWS: 12500, Azure: 8300 },
2410
+ { month: 'Feb', AWS: 13100, Azure: 8700 }
2411
+ ])
2412
+ const [chartCategory] = useState(['AWS', 'Azure'])
2413
+
2414
+ // 다운로드 핸들러
2415
+ const handleDownload = () => {
2416
+ chartRef.current.downloadFile('파일명', 'xlsx')
2417
+ }
2418
+
2419
+ // 커스텀 데이터 소스로 다운로드
2420
+ const handleCustomDownload = () => {
2421
+ chartRef.current.downloadFile('파일명', 'xlsx', {
2422
+ dataSource: [
2423
+ { Category: 'Custom Row 1', Value: 100 },
2424
+ { Category: 'Custom Row 2', Value: 200 }
2425
+ ]
2426
+ })
2427
+ }
2428
+
2429
+ // 지원 형식: xlsx, csv, png, jpg, pdf, json, html, canvas, pdfdata, print
2430
+ `,
2431
+ code: `<OpsnowCommonLineChart
2432
+ ref={chartRef}
2433
+ chartId={chartId}
2434
+ chartProps={chartProps}
2435
+ chartCategory={chartCategory}
2436
+ chartData={chartData}
2437
+ />`
2438
+ },
2242
2439
  ];
2243
2440
  export const StackChartExamples = [
2244
2441
  {
@@ -3618,6 +3815,60 @@ export const StackChartExamples = [
3618
3815
  chartCustomCategory={chartCustomCategory}
3619
3816
  />`
3620
3817
  },
3818
+ {
3819
+ title: '스택 차트 - 다운로드',
3820
+ description: 'ref를 사용하여 스택 차트를 다양한 형식으로 다운로드하는 예제입니다. 다운로드 시에는 chartRef가 아닌 React ref를 사용해야 합니다. downloadFile(fileName, fileType, fileOption?)을 호출합니다.',
3821
+ code_props_usage: `
3822
+ const chartId = 'stack-chart-download-${generateUniqueGeneralId()}'
3823
+ const chartRef = useRef(null)
3824
+ const [chartProps] = useState({
3825
+ xAxis: { type: 'category', valueField: 'month' },
3826
+ yAxis: { type: 'value' },
3827
+ series: {
3828
+ valueXField: 'month',
3829
+ columns: { width: 'p60' },
3830
+ tooltip: {
3831
+ type: 'CG',
3832
+ body: {
3833
+ name: '{name}',
3834
+ value: '\${valueY.formatNumber("0,0.00")}',
3835
+ useMarker: true
3836
+ }
3837
+ }
3838
+ },
3839
+ legend: {}
3840
+ })
3841
+ const [chartData] = useState([
3842
+ { month: 'Jan', AWS: 12500, Azure: 8300 },
3843
+ { month: 'Feb', AWS: 13100, Azure: 8700 }
3844
+ ])
3845
+ const [chartCategory] = useState(['AWS', 'Azure'])
3846
+
3847
+ // 다운로드 핸들러
3848
+ const handleDownload = () => {
3849
+ chartRef.current.downloadFile('파일명', 'xlsx')
3850
+ }
3851
+
3852
+ // 커스텀 데이터 소스로 다운로드
3853
+ const handleCustomDownload = () => {
3854
+ chartRef.current.downloadFile('파일명', 'xlsx', {
3855
+ dataSource: [
3856
+ { Category: 'Custom Row 1', Value: 100 },
3857
+ { Category: 'Custom Row 2', Value: 200 }
3858
+ ]
3859
+ })
3860
+ }
3861
+
3862
+ // 지원 형식: xlsx, csv, png, jpg, pdf, json, html, canvas, pdfdata, print
3863
+ `,
3864
+ code: `<OpsnowCommonStackChart
3865
+ ref={chartRef}
3866
+ chartId={chartId}
3867
+ chartProps={chartProps}
3868
+ chartCategory={chartCategory}
3869
+ chartData={chartData}
3870
+ />`
3871
+ },
3621
3872
  ];
3622
3873
  export const XyMultiChartExamples = [
3623
3874
  {
@@ -6588,3 +6839,428 @@ export const XyMultiChartExamples = [
6588
6839
  />`
6589
6840
  },
6590
6841
  ];
6842
+ // Heatmap Chart 컴포넌트 예제 데이터
6843
+ export const HeatmapChartExamples = [
6844
+ {
6845
+ title: '히트맵 차트 - 기본',
6846
+ description: '인시던트 발생 패턴(시간×요일) 히트맵 차트 기본 예제입니다. heatRule로 최소/최대 색상을 지정하고, 기본 그래디언트 범례를 표시합니다.',
6847
+ code_props_usage: `
6848
+ const chartId = 'heatmap-chart-${generateUniqueGeneralId()}'
6849
+ const chartRef = useRef(null)
6850
+ const [chartProps, setChartProps] = useState({
6851
+ chart: {
6852
+ paddingLeft: 0,
6853
+ paddingRight: 0,
6854
+ paddingBottom: 0,
6855
+ },
6856
+ xAxis: {
6857
+ type: 'category',
6858
+ valueField: 'hour',
6859
+ gridHidden: true,
6860
+ renderer: {
6861
+ opposite: true,
6862
+ minGridDistance: 20,
6863
+ },
6864
+ label: { fontSize: 11 },
6865
+ },
6866
+ yAxis: {
6867
+ type: 'category',
6868
+ valueField: 'day',
6869
+ gridHidden: true,
6870
+ renderer: {
6871
+ inversed: true,
6872
+ minGridDistance: 20,
6873
+ },
6874
+ label: { fontSize: 11, maxWidth: 70, fontWeight: 'bold' },
6875
+ },
6876
+ series: {
6877
+ categoryXField: 'hour',
6878
+ categoryYField: 'day',
6879
+ valueField: 'value',
6880
+ columns: {
6881
+ strokeWidth: 2,
6882
+ hover: { enabled: true },
6883
+ },
6884
+ tooltip: {
6885
+ type: 'CI',
6886
+ header: { name: '{day} {hour}h' },
6887
+ body: { value: '{value} {l.unit}' },
6888
+ },
6889
+ },
6890
+ heatRule: {
6891
+ key: 'fill',
6892
+ minColor: '#fce4ec',
6893
+ maxColor: '#c62828',
6894
+ },
6895
+ legend: {
6896
+ orientation: 'horizontal',
6897
+ legendWidth: 200,
6898
+ },
6899
+ })
6900
+ const [chartData, setChartData] = useState([
6901
+ { hour: '0', day: 'day_0', value: 0 }, { hour: '1', day: 'day_0', value: 2 },
6902
+ { hour: '2', day: 'day_0', value: 0 }, { hour: '3', day: 'day_0', value: 5 },
6903
+ { hour: '4', day: 'day_0', value: 0 }, { hour: '5', day: 'day_0', value: 0 },
6904
+ { hour: '6', day: 'day_0', value: 1 }, { hour: '7', day: 'day_0', value: 3 },
6905
+ { hour: '8', day: 'day_0', value: 0 }, { hour: '9', day: 'day_0', value: 0 },
6906
+ { hour: '10', day: 'day_0', value: 4 }, { hour: '11', day: 'day_0', value: 0 },
6907
+ { hour: '12', day: 'day_0', value: 0 }, { hour: '13', day: 'day_0', value: 2 },
6908
+ { hour: '14', day: 'day_0', value: 0 }, { hour: '15', day: 'day_0', value: 0 },
6909
+ { hour: '16', day: 'day_0', value: 6 }, { hour: '17', day: 'day_0', value: 0 },
6910
+ { hour: '18', day: 'day_0', value: 0 }, { hour: '19', day: 'day_0', value: 1 },
6911
+ { hour: '20', day: 'day_0', value: 0 }, { hour: '21', day: 'day_0', value: 0 },
6912
+ { hour: '22', day: 'day_0', value: 3 }, { hour: '23', day: 'day_0', value: 0 },
6913
+ { hour: '0', day: 'day_1', value: 0 }, { hour: '1', day: 'day_1', value: 0 },
6914
+ { hour: '2', day: 'day_1', value: 1 }, { hour: '3', day: 'day_1', value: 0 },
6915
+ { hour: '4', day: 'day_1', value: 0 }, { hour: '5', day: 'day_1', value: 3 },
6916
+ { hour: '6', day: 'day_1', value: 0 }, { hour: '7', day: 'day_1', value: 0 },
6917
+ { hour: '8', day: 'day_1', value: 7 }, { hour: '9', day: 'day_1', value: 0 },
6918
+ { hour: '10', day: 'day_1', value: 0 }, { hour: '11', day: 'day_1', value: 2 },
6919
+ { hour: '12', day: 'day_1', value: 0 }, { hour: '13', day: 'day_1', value: 0 },
6920
+ { hour: '14', day: 'day_1', value: 4 }, { hour: '15', day: 'day_1', value: 0 },
6921
+ { hour: '16', day: 'day_1', value: 0 }, { hour: '17', day: 'day_1', value: 1 },
6922
+ { hour: '18', day: 'day_1', value: 0 }, { hour: '19', day: 'day_1', value: 5 },
6923
+ { hour: '20', day: 'day_1', value: 0 }, { hour: '21', day: 'day_1', value: 0 },
6924
+ { hour: '22', day: 'day_1', value: 0 }, { hour: '23', day: 'day_1', value: 2 },
6925
+ { hour: '0', day: 'day_2', value: 1 }, { hour: '1', day: 'day_2', value: 0 },
6926
+ { hour: '2', day: 'day_2', value: 0 }, { hour: '3', day: 'day_2', value: 0 },
6927
+ { hour: '4', day: 'day_2', value: 3 }, { hour: '5', day: 'day_2', value: 0 },
6928
+ { hour: '6', day: 'day_2', value: 0 }, { hour: '7', day: 'day_2', value: 6 },
6929
+ { hour: '8', day: 'day_2', value: 0 }, { hour: '9', day: 'day_2', value: 2 },
6930
+ { hour: '10', day: 'day_2', value: 0 }, { hour: '11', day: 'day_2', value: 0 },
6931
+ { hour: '12', day: 'day_2', value: 4 }, { hour: '13', day: 'day_2', value: 0 },
6932
+ { hour: '14', day: 'day_2', value: 0 }, { hour: '15', day: 'day_2', value: 1 },
6933
+ { hour: '16', day: 'day_2', value: 0 }, { hour: '17', day: 'day_2', value: 0 },
6934
+ { hour: '18', day: 'day_2', value: 5 }, { hour: '19', day: 'day_2', value: 0 },
6935
+ { hour: '20', day: 'day_2', value: 0 }, { hour: '21', day: 'day_2', value: 3 },
6936
+ { hour: '22', day: 'day_2', value: 0 }, { hour: '23', day: 'day_2', value: 0 },
6937
+ ])
6938
+ const chartLocaleMessage = [
6939
+ { name: 'day_0', locale: 'Mon 4/14' },
6940
+ { name: 'day_1', locale: 'Tue 4/15' },
6941
+ { name: 'day_2', locale: 'Wed 4/16' },
6942
+ ]
6943
+ const chartLocaleProps = [
6944
+ { name: 'l.unit', locale: 'incidents' },
6945
+ ]
6946
+ `,
6947
+ code: `<OpsnowCommonHeatmapChart
6948
+ chartId={chartId}
6949
+ ref={chartRef}
6950
+ chartProps={chartProps}
6951
+ chartData={chartData}
6952
+ chartLocaleMessage={chartLocaleMessage}
6953
+ chartLocaleProps={chartLocaleProps}
6954
+ />`
6955
+ },
6956
+ {
6957
+ title: '히트맵 차트 - 레전드 라벨 및 스타일',
6958
+ description: '범례에 labelText와 스타일(폰트 크기, 바 높이)을 커스터마이징한 히트맵 차트 예제입니다.',
6959
+ code_props_usage: `
6960
+ const chartId = 'heatmap-chart-${generateUniqueGeneralId()}'
6961
+ const chartRef = useRef(null)
6962
+ const [chartProps, setChartProps] = useState({
6963
+ chart: {
6964
+ paddingLeft: 0,
6965
+ paddingRight: 0,
6966
+ paddingBottom: 0,
6967
+ },
6968
+ xAxis: {
6969
+ type: 'category',
6970
+ valueField: 'hour',
6971
+ gridHidden: true,
6972
+ renderer: {
6973
+ opposite: true,
6974
+ minGridDistance: 20,
6975
+ },
6976
+ label: { fontSize: 11 },
6977
+ },
6978
+ yAxis: {
6979
+ type: 'category',
6980
+ valueField: 'day',
6981
+ gridHidden: true,
6982
+ renderer: {
6983
+ inversed: true,
6984
+ minGridDistance: 20,
6985
+ },
6986
+ label: { fontSize: 11, maxWidth: 70, fontWeight: 'bold' },
6987
+ },
6988
+ series: {
6989
+ categoryXField: 'hour',
6990
+ categoryYField: 'day',
6991
+ valueField: 'value',
6992
+ columns: {
6993
+ strokeWidth: 2,
6994
+ hover: { enabled: true },
6995
+ },
6996
+ tooltip: {
6997
+ type: 'CI',
6998
+ header: { name: '{day} {hour}h' },
6999
+ body: { value: '{value} {l.unit}' },
7000
+ label: { fontSize: 11 },
7001
+ },
7002
+ },
7003
+ heatRule: {
7004
+ key: 'fill',
7005
+ minColor: '#fce4ec',
7006
+ maxColor: '#c62828',
7007
+ },
7008
+ legend: {
7009
+ orientation: 'horizontal',
7010
+ labelText: '{l.legendLabel}',
7011
+ labelFontSize: 12,
7012
+ legendWidth: 200,
7013
+ barHeight: 16,
7014
+ },
7015
+ })
7016
+ const [chartData, setChartData] = useState([
7017
+ { hour: '0', day: 'day_0', value: 0 }, { hour: '1', day: 'day_0', value: 2 },
7018
+ { hour: '2', day: 'day_0', value: 0 }, { hour: '3', day: 'day_0', value: 5 },
7019
+ { hour: '4', day: 'day_0', value: 0 }, { hour: '5', day: 'day_0', value: 0 },
7020
+ { hour: '6', day: 'day_0', value: 1 }, { hour: '7', day: 'day_0', value: 3 },
7021
+ { hour: '8', day: 'day_0', value: 0 }, { hour: '9', day: 'day_0', value: 0 },
7022
+ { hour: '10', day: 'day_0', value: 4 }, { hour: '11', day: 'day_0', value: 0 },
7023
+ { hour: '12', day: 'day_0', value: 0 }, { hour: '13', day: 'day_0', value: 2 },
7024
+ { hour: '14', day: 'day_0', value: 0 }, { hour: '15', day: 'day_0', value: 0 },
7025
+ { hour: '16', day: 'day_0', value: 6 }, { hour: '17', day: 'day_0', value: 0 },
7026
+ { hour: '18', day: 'day_0', value: 0 }, { hour: '19', day: 'day_0', value: 1 },
7027
+ { hour: '20', day: 'day_0', value: 0 }, { hour: '21', day: 'day_0', value: 0 },
7028
+ { hour: '22', day: 'day_0', value: 3 }, { hour: '23', day: 'day_0', value: 0 },
7029
+ { hour: '0', day: 'day_1', value: 0 }, { hour: '1', day: 'day_1', value: 0 },
7030
+ { hour: '2', day: 'day_1', value: 1 }, { hour: '3', day: 'day_1', value: 0 },
7031
+ { hour: '4', day: 'day_1', value: 0 }, { hour: '5', day: 'day_1', value: 3 },
7032
+ { hour: '6', day: 'day_1', value: 0 }, { hour: '7', day: 'day_1', value: 0 },
7033
+ { hour: '8', day: 'day_1', value: 7 }, { hour: '9', day: 'day_1', value: 0 },
7034
+ { hour: '10', day: 'day_1', value: 0 }, { hour: '11', day: 'day_1', value: 2 },
7035
+ { hour: '12', day: 'day_1', value: 0 }, { hour: '13', day: 'day_1', value: 0 },
7036
+ { hour: '14', day: 'day_1', value: 4 }, { hour: '15', day: 'day_1', value: 0 },
7037
+ { hour: '16', day: 'day_1', value: 0 }, { hour: '17', day: 'day_1', value: 1 },
7038
+ { hour: '18', day: 'day_1', value: 0 }, { hour: '19', day: 'day_1', value: 5 },
7039
+ { hour: '20', day: 'day_1', value: 0 }, { hour: '21', day: 'day_1', value: 0 },
7040
+ { hour: '22', day: 'day_1', value: 0 }, { hour: '23', day: 'day_1', value: 2 },
7041
+ ])
7042
+ const chartLocaleMessage = [
7043
+ { name: 'day_0', locale: 'Mon 4/14' },
7044
+ { name: 'day_1', locale: 'Tue 4/15' },
7045
+ ]
7046
+ const chartLocaleProps = [
7047
+ { name: 'l.unit', locale: 'incidents' },
7048
+ { name: 'l.legendLabel', locale: 'Incident Count' },
7049
+ ]
7050
+ `,
7051
+ code: `<OpsnowCommonHeatmapChart
7052
+ chartId={chartId}
7053
+ ref={chartRef}
7054
+ chartProps={chartProps}
7055
+ chartData={chartData}
7056
+ chartLocaleMessage={chartLocaleMessage}
7057
+ chartLocaleProps={chartLocaleProps}
7058
+ />`
7059
+ },
7060
+ {
7061
+ title: '히트맵 차트 - 커스텀 색상 및 클릭 이벤트',
7062
+ description: '커스텀 색상(보라 계열 그래디언트)과 셀 클릭 이벤트를 처리하는 히트맵 차트 예제입니다. onChartClick으로 클릭한 셀 정보를 받을 수 있습니다.',
7063
+ code_props_usage: `
7064
+ const chartId = 'heatmap-chart-${generateUniqueGeneralId()}'
7065
+ const chartRef = useRef(null)
7066
+ const [clickedCell, setClickedCell] = useState(null)
7067
+ const [chartProps, setChartProps] = useState({
7068
+ chart: {
7069
+ paddingLeft: 0,
7070
+ paddingRight: 0,
7071
+ paddingBottom: 0,
7072
+ },
7073
+ xAxis: {
7074
+ type: 'category',
7075
+ valueField: 'hour',
7076
+ gridHidden: true,
7077
+ renderer: {
7078
+ opposite: true,
7079
+ minGridDistance: 20,
7080
+ },
7081
+ label: { fontSize: 11 },
7082
+ },
7083
+ yAxis: {
7084
+ type: 'category',
7085
+ valueField: 'day',
7086
+ gridHidden: true,
7087
+ renderer: {
7088
+ inversed: true,
7089
+ minGridDistance: 20,
7090
+ },
7091
+ label: { fontSize: 11, maxWidth: 70, fontWeight: 'bold' },
7092
+ },
7093
+ series: {
7094
+ categoryXField: 'hour',
7095
+ categoryYField: 'day',
7096
+ valueField: 'value',
7097
+ columns: {
7098
+ strokeWidth: 2,
7099
+ hover: { enabled: true, color: '#d50000' },
7100
+ },
7101
+ tooltip: {
7102
+ type: 'CI',
7103
+ header: { name: '{day} {hour}h' },
7104
+ body: { value: '{value} {l.unit}' },
7105
+ },
7106
+ },
7107
+ heatRule: {
7108
+ key: 'fill',
7109
+ minColor: '#e8eaf6',
7110
+ maxColor: '#4a148c',
7111
+ },
7112
+ legend: {
7113
+ orientation: 'horizontal',
7114
+ labelText: '{l.legendLabel}',
7115
+ labelFontSize: 12,
7116
+ labelFontWeight: 'bold',
7117
+ legendWidth: 200,
7118
+ barHeight: 16,
7119
+ },
7120
+ })
7121
+ const [chartData, setChartData] = useState([
7122
+ { hour: '0', day: 'day_0', value: 0 }, { hour: '1', day: 'day_0', value: 2 },
7123
+ { hour: '2', day: 'day_0', value: 0 }, { hour: '3', day: 'day_0', value: 5 },
7124
+ { hour: '4', day: 'day_0', value: 0 }, { hour: '5', day: 'day_0', value: 0 },
7125
+ { hour: '6', day: 'day_0', value: 1 }, { hour: '7', day: 'day_0', value: 3 },
7126
+ { hour: '8', day: 'day_0', value: 0 }, { hour: '9', day: 'day_0', value: 0 },
7127
+ { hour: '10', day: 'day_0', value: 4 }, { hour: '11', day: 'day_0', value: 0 },
7128
+ { hour: '12', day: 'day_0', value: 0 }, { hour: '13', day: 'day_0', value: 2 },
7129
+ { hour: '14', day: 'day_0', value: 0 }, { hour: '15', day: 'day_0', value: 0 },
7130
+ { hour: '16', day: 'day_0', value: 6 }, { hour: '17', day: 'day_0', value: 0 },
7131
+ { hour: '18', day: 'day_0', value: 0 }, { hour: '19', day: 'day_0', value: 1 },
7132
+ { hour: '20', day: 'day_0', value: 0 }, { hour: '21', day: 'day_0', value: 0 },
7133
+ { hour: '22', day: 'day_0', value: 3 }, { hour: '23', day: 'day_0', value: 0 },
7134
+ { hour: '0', day: 'day_1', value: 0 }, { hour: '1', day: 'day_1', value: 0 },
7135
+ { hour: '2', day: 'day_1', value: 1 }, { hour: '3', day: 'day_1', value: 0 },
7136
+ { hour: '4', day: 'day_1', value: 0 }, { hour: '5', day: 'day_1', value: 3 },
7137
+ { hour: '6', day: 'day_1', value: 0 }, { hour: '7', day: 'day_1', value: 0 },
7138
+ { hour: '8', day: 'day_1', value: 7 }, { hour: '9', day: 'day_1', value: 0 },
7139
+ { hour: '10', day: 'day_1', value: 0 }, { hour: '11', day: 'day_1', value: 2 },
7140
+ { hour: '12', day: 'day_1', value: 0 }, { hour: '13', day: 'day_1', value: 0 },
7141
+ { hour: '14', day: 'day_1', value: 4 }, { hour: '15', day: 'day_1', value: 0 },
7142
+ { hour: '16', day: 'day_1', value: 0 }, { hour: '17', day: 'day_1', value: 1 },
7143
+ { hour: '18', day: 'day_1', value: 0 }, { hour: '19', day: 'day_1', value: 5 },
7144
+ { hour: '20', day: 'day_1', value: 0 }, { hour: '21', day: 'day_1', value: 0 },
7145
+ { hour: '22', day: 'day_1', value: 0 }, { hour: '23', day: 'day_1', value: 2 },
7146
+ ])
7147
+ const chartLocaleMessage = [
7148
+ { name: 'day_0', locale: 'Mon 4/14' },
7149
+ { name: 'day_1', locale: 'Tue 4/15' },
7150
+ ]
7151
+ const chartLocaleProps = [
7152
+ { name: 'l.unit', locale: 'incidents' },
7153
+ { name: 'l.legendLabel', locale: 'Incident Count' },
7154
+ ]
7155
+ const handleChartClick = (data) => {
7156
+ setClickedCell(data)
7157
+ console.log('Clicked cell:', data)
7158
+ }
7159
+ `,
7160
+ code: `<OpsnowCommonHeatmapChart
7161
+ chartId={chartId}
7162
+ ref={chartRef}
7163
+ chartProps={chartProps}
7164
+ chartData={chartData}
7165
+ chartLocaleMessage={chartLocaleMessage}
7166
+ chartLocaleProps={chartLocaleProps}
7167
+ onChartClick={handleChartClick}
7168
+ />`
7169
+ },
7170
+ {
7171
+ title: '히트맵 차트 - downloadFile (차트 다운로드)',
7172
+ description: 'ref를 통해 downloadFile 메서드를 호출하여 히트맵 차트를 이미지(png, jpg) 또는 PDF로 다운로드하는 예제입니다.',
7173
+ code_props_usage: `
7174
+ const chartId = 'heatmap-chart-${generateUniqueGeneralId()}'
7175
+ const chartRef = useRef(null)
7176
+ const [chartProps, setChartProps] = useState({
7177
+ chart: {
7178
+ paddingLeft: 0,
7179
+ paddingRight: 0,
7180
+ paddingBottom: 0,
7181
+ },
7182
+ xAxis: {
7183
+ type: 'category',
7184
+ valueField: 'hour',
7185
+ gridHidden: true,
7186
+ renderer: {
7187
+ opposite: true,
7188
+ minGridDistance: 20,
7189
+ },
7190
+ label: { fontSize: 11 },
7191
+ },
7192
+ yAxis: {
7193
+ type: 'category',
7194
+ valueField: 'day',
7195
+ gridHidden: true,
7196
+ renderer: {
7197
+ inversed: true,
7198
+ minGridDistance: 20,
7199
+ },
7200
+ label: { fontSize: 11, maxWidth: 70, fontWeight: 'bold' },
7201
+ },
7202
+ series: {
7203
+ categoryXField: 'hour',
7204
+ categoryYField: 'day',
7205
+ valueField: 'value',
7206
+ columns: {
7207
+ strokeWidth: 2,
7208
+ hover: { enabled: true },
7209
+ },
7210
+ tooltip: {
7211
+ type: 'CI',
7212
+ header: { name: '{day} {hour}h' },
7213
+ body: { value: '{value} {l.unit}' },
7214
+ },
7215
+ },
7216
+ heatRule: {
7217
+ key: 'fill',
7218
+ minColor: '#e0f2f1',
7219
+ maxColor: '#00695c',
7220
+ },
7221
+ legend: {
7222
+ orientation: 'horizontal',
7223
+ legendWidth: 200,
7224
+ },
7225
+ })
7226
+ const [chartData, setChartData] = useState([
7227
+ { hour: '0', day: 'day_0', value: 0 }, { hour: '1', day: 'day_0', value: 2 },
7228
+ { hour: '2', day: 'day_0', value: 0 }, { hour: '3', day: 'day_0', value: 5 },
7229
+ { hour: '4', day: 'day_0', value: 0 }, { hour: '5', day: 'day_0', value: 0 },
7230
+ { hour: '6', day: 'day_0', value: 1 }, { hour: '7', day: 'day_0', value: 3 },
7231
+ { hour: '8', day: 'day_0', value: 0 }, { hour: '9', day: 'day_0', value: 0 },
7232
+ { hour: '10', day: 'day_0', value: 4 }, { hour: '11', day: 'day_0', value: 0 },
7233
+ { hour: '12', day: 'day_0', value: 0 }, { hour: '13', day: 'day_0', value: 2 },
7234
+ { hour: '14', day: 'day_0', value: 0 }, { hour: '15', day: 'day_0', value: 0 },
7235
+ { hour: '16', day: 'day_0', value: 6 }, { hour: '17', day: 'day_0', value: 0 },
7236
+ { hour: '18', day: 'day_0', value: 0 }, { hour: '19', day: 'day_0', value: 1 },
7237
+ { hour: '20', day: 'day_0', value: 0 }, { hour: '21', day: 'day_0', value: 0 },
7238
+ { hour: '22', day: 'day_0', value: 3 }, { hour: '23', day: 'day_0', value: 0 },
7239
+ ])
7240
+ const chartLocaleProps = [
7241
+ { name: 'l.unit', locale: 'incidents' },
7242
+ ]
7243
+ const chartLocaleMessage = [
7244
+ { name: 'day_0', locale: 'Mon 4/14' },
7245
+ ]
7246
+
7247
+ // 다운로드 함수
7248
+ const handleDownload = (fileType) => {
7249
+ // fileType: 'png' | 'jpg' | 'pdf'
7250
+ // fileOption: { quality?: number } (jpg일 때 품질 0~1)
7251
+ chartRef.current?.downloadFile('heatmap-chart', fileType)
7252
+ }
7253
+ `,
7254
+ code: `<OpsnowCommonHeatmapChart
7255
+ chartId={chartId}
7256
+ ref={chartRef}
7257
+ chartProps={chartProps}
7258
+ chartData={chartData}
7259
+ chartLocaleMessage={chartLocaleMessage}
7260
+ chartLocaleProps={chartLocaleProps}
7261
+ />
7262
+ <button onClick={() => handleDownload('png')}>Download PNG</button>
7263
+ <button onClick={() => handleDownload('jpg')}>Download JPG</button>
7264
+ <button onClick={() => handleDownload('pdf')}>Download PDF</button>`
7265
+ },
7266
+ ];
@@ -49,6 +49,16 @@ export const SelectExamples = [
49
49
  title: 'filled, size=medium, disabled',
50
50
  code: `<OpsnowCommonSelect items={[{ label: 'Option 1', value: '1' }, { label: 'Option 2', value: '2' }]} size="medium" variant="filled" disabled value={value} onChange={e => setValue(e.target.value)} />`,
51
51
  description: 'filled variant, medium 사이즈, 비활성화 셀렉트 예제입니다.'
52
+ },
53
+ {
54
+ title: 'outlined, size=small, label + placeholder (단일 선택)',
55
+ code: `<OpsnowCommonSelect items={[{ value: '1', label: 'Option 1' }, { value: '2', label: 'Option 2' }, { value: '3', label: 'Option 3' }]} size="small" variant="outlined" label="옵션 선택" placeholder="옵션을 선택하세요" value={value} onChange={e => setValue(e.target.value)} />`,
56
+ description: 'outlined variant, small 사이즈, label과 placeholder를 함께 사용하는 단일 선택 셀렉트 예제입니다.'
57
+ },
58
+ {
59
+ title: 'outlined, size=small, label + placeholder, multiple (다중 선택)',
60
+ code: `<OpsnowCommonSelect items={[{ value: '1', label: 'Option 1' }, { value: '2', label: 'Option 2' }, { value: '3', label: 'Option 3' }]} size="small" variant="outlined" multiple label="항목" placeholder="항목을 선택하세요" value={value} onChange={e => setValue(e.target.value)} />`,
61
+ description: 'outlined variant, small 사이즈, label과 placeholder를 함께 사용하는 다중 선택 셀렉트 예제입니다.'
52
62
  }
53
63
  ];
54
64
  // Autocomplete(오토컴플리트) 컴포넌트 예제 데이터
@@ -1337,6 +1337,172 @@ export const GaugeChartSchema = z.object({
1337
1337
  `),
1338
1338
  chartValue: z.number().describe("차트 값"),
1339
1339
  });
1340
+ // opsnow-common-heatmap-chart
1341
+ export const HeatmapChartSchema = z.object({
1342
+ chartId: z.string().describe("차트의 고유 식별자"),
1343
+ chartProps: z.object({}).describe(`
1344
+ 다음 정의된 형식 예를 보고 차트 속성을 설정하세요.
1345
+ **유효한 JSON 형식이어야합니다.**
1346
+ {
1347
+ // 차트 기본 설정
1348
+ "chart": {
1349
+ "paddingTop": 0, // 차트 상단 패딩 (px)
1350
+ "paddingBottom": 0, // 차트 하단 패딩 (px)
1351
+ "paddingLeft": 0, // 차트 좌측 패딩 (px)
1352
+ "paddingRight": 0, // 차트 우측 패딩 (px)
1353
+ "panX": false, // X축 팬 가능 여부
1354
+ "panY": false, // Y축 팬 가능 여부
1355
+ "wheelStep": 0.25, // 줌 휠 단계
1356
+ "scrollbarX": { // X축 스크롤바 설정
1357
+ "height": 6, // 스크롤바 높이 (px)
1358
+ "gripScale": 0 // 그립 크기 비율
1359
+ },
1360
+ "scrollbarY": { // Y축 스크롤바 설정
1361
+ "gripScale": 0 // 그립 크기 비율
1362
+ },
1363
+ "zoomOutButtonHidden": true // 줌 아웃 버튼 숨김 여부
1364
+ },
1365
+
1366
+ // X축 설정
1367
+ "xAxis": {
1368
+ "type": "category", // 축 타입: 'category' (필수)
1369
+ "valueField": "hour", // X축 값 필드명 (chartData의 필드명과 일치해야 함)
1370
+ "categories": ["0", "1", "2"], // 카테고리 명시적 순서 지정 (선택사항, 생략 시 데이터에서 자동 추출)
1371
+ "gridHidden": true, // 격자선 숨김 여부
1372
+ "labelHidden": false, // 라벨 숨김 여부
1373
+ "label": {
1374
+ "fontSize": 11, // 라벨 폰트 크기
1375
+ "maxWidth": 60, // 라벨 최대 너비 (px)
1376
+ "paddingTop": 5, // 라벨 상단 패딩
1377
+ "fontWeight": "normal" // 라벨 폰트 두께
1378
+ },
1379
+ "renderer": {
1380
+ "opposite": true, // X축을 상단에 배치 (기본값: false)
1381
+ "minGridDistance": 20 // 격자선 최소 간격
1382
+ },
1383
+ "startLocation": 0, // 축 시작 위치 (0~1)
1384
+ "endLocation": 1 // 축 끝 위치 (0~1)
1385
+ },
1386
+
1387
+ // Y축 설정
1388
+ "yAxis": {
1389
+ "type": "category", // 축 타입: 'category' (필수)
1390
+ "valueField": "day", // Y축 값 필드명 (chartData의 필드명과 일치해야 함)
1391
+ "categories": ["day_0", "day_1"], // 카테고리 명시적 순서 지정 (선택사항)
1392
+ "gridHidden": true, // 격자선 숨김 여부
1393
+ "labelHidden": false, // 라벨 숨김 여부
1394
+ "label": {
1395
+ "fontSize": 11, // 라벨 폰트 크기
1396
+ "maxWidth": 70, // 라벨 최대 너비 (px)
1397
+ "fontWeight": "bold" // 라벨 폰트 두께
1398
+ },
1399
+ "renderer": {
1400
+ "inversed": true, // Y축 반전 (기본값: true, 위→아래 순서)
1401
+ "minGridDistance": 20 // 격자선 최소 간격
1402
+ },
1403
+ "startLocation": 0, // 축 시작 위치
1404
+ "endLocation": 1 // 축 끝 위치
1405
+ },
1406
+
1407
+ // 시리즈 설정 (단일 ColumnSeries)
1408
+ "series": {
1409
+ "categoryXField": "hour", // X축 카테고리 필드 (기본값: xAxis.valueField)
1410
+ "categoryYField": "day", // Y축 카테고리 필드 (기본값: yAxis.valueField)
1411
+ "valueField": "value", // 값 필드 (기본값: "value")
1412
+ "columns": {
1413
+ "strokeWidth": 2, // 셀 테두리 두께
1414
+ "cornerRadius": 0, // 셀 모서리 둥글기
1415
+ "hover": {
1416
+ "enabled": true, // 호버 효과 활성화
1417
+ "scale": 1, // 호버 시 확대 비율
1418
+ "color": "#d50000" // 호버 시 테두리 색상
1419
+ }
1420
+ },
1421
+ "tooltip": {
1422
+ "type": "CI", // 'CI' (Individual) 고정 — 각 셀별 툴팁
1423
+ "enabled": true, // 툴팁 활성화
1424
+ "header": { "name": "{day} {hour}h" }, // 헤더 텍스트 ({}로 필드 참조)
1425
+ "body": {
1426
+ "name": "", // 바디 이름 (선택사항)
1427
+ "value": "{value} {l.unit}" // 바디 값 ({l.xxx}로 locale 참조)
1428
+ },
1429
+ "label": { "fontSize": 11 } // 툴팁 폰트 크기
1430
+ },
1431
+ "animation": {
1432
+ "duration": 500, // 애니메이션 지속 시간 (ms)
1433
+ "delay": 100 // 애니메이션 지연 시간 (ms)
1434
+ }
1435
+ },
1436
+
1437
+ // 히트맵 색상 규칙 (필수)
1438
+ "heatRule": {
1439
+ "key": "fill", // 변경할 속성: 'fill' (색상)
1440
+ "dataField": "value", // 값 필드 (기본값: "value")
1441
+ "minColor": "#fce4ec", // 최소값 색상 (연한색)
1442
+ "maxColor": "#c62828", // 최대값 색상 (진한색)
1443
+ "minValue": 0, // 최소값 직접 지정 (선택사항, 생략 시 데이터에서 자동 계산)
1444
+ "maxValue": 10 // 최대값 직접 지정 (선택사항)
1445
+ },
1446
+
1447
+ // 범례 설정 (히트맵 그래디언트 범례)
1448
+ "legend": {
1449
+ "orientation": "horizontal", // 방향: 'horizontal' | 'vertical'
1450
+ "labelText": "{l.legendLabel}", // 범례 라벨 ({l.xxx}로 locale 참조)
1451
+ "labelFontSize": 12, // 라벨 폰트 크기
1452
+ "labelFontWeight": "normal", // 라벨 폰트 두께
1453
+ "valueLabelFontSize": 11, // 값 라벨 폰트 크기
1454
+ "legendWidth": 200, // 범례 너비 (px)
1455
+ "barHeight": 16, // 범례 바 높이 (px)
1456
+ "paddingTop": 10, // 상단 패딩
1457
+ "startText": "Low", // 시작 라벨 텍스트
1458
+ "endText": "High", // 끝 라벨 텍스트
1459
+ "stepCount": 5, // 범례 단계 수
1460
+ "reversed": false // 범례 방향 반전
1461
+ }
1462
+ }
1463
+ `),
1464
+ chartData: z.array(z.record(z.any())).optional().describe(`히트맵에 표시할 데이터 배열입니다. 각 항목은 X축 카테고리, Y축 카테고리, 값 필드를 포함해야 합니다.
1465
+ 예시)
1466
+ [
1467
+ { "hour": "0", "day": "day_0", "value": 3 },
1468
+ { "hour": "1", "day": "day_0", "value": 0 },
1469
+ { "hour": "2", "day": "day_0", "value": 5 },
1470
+ { "hour": "0", "day": "day_1", "value": 1 },
1471
+ { "hour": "1", "day": "day_1", "value": 7 }
1472
+ ]`),
1473
+ chartLocaleProps: z.array(z.object({
1474
+ name: z.string(),
1475
+ locale: z.string()
1476
+ })).optional().describe(`차트에 적용할 다국어 플레이스홀더 목록입니다. {l.xxx} 형태로 chartProps에서 참조합니다.
1477
+ 예시)
1478
+ [
1479
+ { "name": "l.unit", "locale": "건" },
1480
+ { "name": "l.legendLabel", "locale": "인시던트 수" }
1481
+ ]`),
1482
+ chartLocaleData: z.array(z.object({
1483
+ name: z.string().describe("chartData에 정의된 필드 이름"),
1484
+ value: z.string().describe("chartData에 정의된 필드 값 전체 또는 일부"),
1485
+ locale: z.string().describe("chartData에 정의된 필드 다국어 값으로 value에 다국어 값을 적용")
1486
+ })).optional().describe(`차트 데이터에 다국어를 적용합니다.
1487
+ 예시)
1488
+ [
1489
+ { "name": "day", "value": "day_0", "locale": "월요일" }
1490
+ ]`),
1491
+ chartLocaleMessage: z.array(z.object({
1492
+ name: z.string().describe("카테고리 키 (chartData의 카테고리 값과 일치)"),
1493
+ locale: z.string().describe("표시할 다국어 텍스트")
1494
+ })).optional().describe(`카테고리 라벨을 다국어 텍스트로 치환합니다. Y축 또는 X축 카테고리의 키를 표시 텍스트로 변환할 때 사용합니다.
1495
+ 예시)
1496
+ [
1497
+ { "name": "day_0", "locale": "월요일 4/14" },
1498
+ { "name": "day_1", "locale": "화요일 4/15" }
1499
+ ]`),
1500
+ chartTooltipDetailText: z.string().optional().describe("툴팁 하단에 표시할 상세 안내 텍스트"),
1501
+ chartNoRowsText: z.string().optional().describe("데이터 없을 때 표시할 텍스트"),
1502
+ langCd: z.enum(['ko', 'en', 'ja', 'zh', 'ar']).optional().describe("언어 코드"),
1503
+ isDarkMode: z.boolean().optional().describe("다크 모드 활성화 여부"),
1504
+ onChartClick: z.string().optional().describe('셀 클릭 시 호출되는 콜백 함수(stringified). 클릭 시 { xField, yField, valueField, from: "heatmap" } 객체를 전달합니다.')
1505
+ });
1340
1506
  // Chart 컴포넌트 함수 - 배열 반환
1341
1507
  export function createChartComponent() {
1342
1508
  return [
@@ -1639,5 +1805,58 @@ export function createChartComponent() {
1639
1805
  };
1640
1806
  }
1641
1807
  },
1808
+ {
1809
+ name: "createHeatmapChart",
1810
+ description: `히트맵 차트 컴포넌트 - 2차원 매트릭스 형태의 데이터 시각화 지원
1811
+
1812
+ **이 차트 컴포넌트는 amCharts5를 기반으로 구현되었습니다.**
1813
+
1814
+ 히트맵 차트는 X축과 Y축 모두 카테고리(category) 축을 사용하며,
1815
+ 각 셀의 값에 따라 minColor ~ maxColor 사이의 그래디언트로 색상이 결정됩니다.
1816
+ 인시던트 발생 패턴(시간×요일), 리소스 사용량 등 2차원 분포 시각화에 적합합니다.
1817
+
1818
+ **import:**
1819
+ \`\`\`javascript
1820
+ import { useCommonComponents } from '@opsnow-common/opsnow-finops-common-ui-loader';
1821
+ const { OpsnowCommonHeatmapChart } = useCommonComponents();
1822
+ \`\`\``,
1823
+ parameters: HeatmapChartSchema,
1824
+ handler: async (args) => {
1825
+ const props = [];
1826
+ if (args.chartId)
1827
+ props.push(`chartId="${args.chartId}"`);
1828
+ if (args.chartProps)
1829
+ props.push(`chartProps={${args.chartProps}}`);
1830
+ if (args.chartData)
1831
+ props.push(`chartData={${args.chartData}}`);
1832
+ else
1833
+ props.push(`chartData={[]}`);
1834
+ if (args.chartLocaleProps)
1835
+ props.push(`chartLocaleProps={${args.chartLocaleProps}}`);
1836
+ if (args.chartLocaleData)
1837
+ props.push(`chartLocaleData={${args.chartLocaleData}}`);
1838
+ if (args.chartLocaleMessage)
1839
+ props.push(`chartLocaleMessage={${args.chartLocaleMessage}}`);
1840
+ if (args.chartTooltipDetailText)
1841
+ props.push(`chartTooltipDetailText="${args.chartTooltipDetailText}"`);
1842
+ if (args.chartNoRowsText)
1843
+ props.push(`chartNoRowsText="${args.chartNoRowsText}"`);
1844
+ if (args.langCd)
1845
+ props.push(`langCd="${args.langCd}"`);
1846
+ if (args.isDarkMode !== undefined)
1847
+ props.push(`isDarkMode={${args.isDarkMode}}`);
1848
+ if (args.onChartClick)
1849
+ props.push(`onChartClick={${args.onChartClick}}`);
1850
+ const code = `<OpsnowCommonHeatmapChart ${props.join(' ')} />`;
1851
+ return {
1852
+ content: [
1853
+ {
1854
+ type: "text",
1855
+ text: `\`\`\`jsx\n${code}\n\`\`\``
1856
+ }
1857
+ ]
1858
+ };
1859
+ }
1860
+ },
1642
1861
  ];
1643
1862
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opsnow-mcp/opsnow-mcp-common-ui-server",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "bin": {