PageSourceSearch

https://kbr.go.kr/js/highcharts-11.2.0/chart.js;jsessionid=0165A086CBBAFE6FB3D9EB71315AE60C

js kbr.go.kr collected 2026-09-25 04:04:18 UTC 97,222 bytes, 3,858 lines download raw bytes

1function getChartInfo(chartId){
2	var chartInfo;
3	$.ajax({
4		url: '/chart/getChatInfo.do'
5		,async : false
6		,data : {
7			chartId : chartId
8		}
9		,success :  function(res){
10			var _r = JSON.parse(res);
11			if(_r.result == 'success'){
12				chartInfo = _r.chartInfo;
13				console.log(chartInfo);
14			}else {
15				alert("관리자에게 문의하여 주시기 바랍니다.");
16			}
17		}
18		,error : function(res){
19			console.log('ERROR : ' + res);
20		}
21	});
22	return chartInfo;
23}
24
25function setChart(chartInfo){
26	const c_type = chartInfo.chartType;
27
28	const c_target = chartInfo.chartTarget;
29	const c_height = chartInfo.chartHeight;
30	const c_width = chartInfo.chartWidth;
31	const c_title = chartInfo.chartTitle;
32	const c_subTitle = chartInfo.chartSubTitle;
33	const c_id = chartInfo.chartId;
34
35	// 천단위 콤마 설정
36	Highcharts.setOptions({
37		lang: {
38			thousandsSep: ','
39		}
40	});
41	if(c_type == 'LINE'){
42		lineChart(chartInfo, c_target, c_height, c_width, c_title, c_subTitle);
43	}else if(c_type == 'AREA'){
44		areaChart(chartInfo, c_target, c_height, c_width, c_title, c_subTitle);
45	}else if(c_type == 'COLUMN'){
46		columnChart(chartInfo, c_target, c_height, c_width, c_title, c_subTitle);
47	}else if(c_type == 'HALFPIE'){
48		halfPieChart(chartInfo, c_target, c_height, c_width, c_title, c_subTitle);
49	}else if(c_type == 'PIE'){
50		pieChart(chartInfo, c_target, c_height, c_width, c_title, c_subTitle);
51	}else if(c_type == 'COLUMN-STACK'){
52		columnStakChart(chartInfo, c_target, c_height, c_width, c_title, c_subTitle);
53	}else if(c_type == 'BAR'){
54		barStakChart(chartInfo, c_target, c_height, c_width, c_title, c_subTitle);
55	}else if(c_type == 'MAP'){
56		if(c_id == 'I501') provinceMapChart(chartInfo, c_target, c_height, c_width, c_title, c_subTitle);
57		else mapBubbleChart(chartInfo, c_target, c_height, c_width, c_title, c_subTitle);
58	}
59
60}
61
62// 천단위 콤마 처리 함수
63function numberWithCommas(x) {
64	return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
65}
66
67// Line
68function lineChart(cObj, target, height , width, title, subTitle){
69	$('#' + target).css('height',height).css('width',width);
70	const labelList = cObj.dataGrpList[0].labelList;
71	let series = []
72	let maxVal = 0;
73	let chartId = "";
74	let legend = "";
75	for(var i=0; i < cObj.dataGrpList.length;i++){
76		const dataGrp = cObj.dataGrpList[i];
77		//console.log(dataGrp);
78		if(i == 0) { chartId =  dataGrp.chartId; }
79		const data = {
80			name : dataGrp.chartDataTitle
81			,data : dataGrp.dataList
82		};
83		series.push(data)
84
85		for(dt of dataGrp.dataList){
86			if(maxVal < dt){
87				maxVal = dt;
88			}
89		}
90	}
91
92	let plotOptions = {
93		line: {
94			dataLabels: {
95				enabled: true
96			},
97		}
98	};
99
100	if (chartId === 'I104' || chartId === 'II40' || chartId === 'II50') {
101		plotOptions = {
102			series: {
103				states: {
104					hover: {
105						enabled: false // hover 비활성화
106					},
107					inactive: {
108						enabled: false // 비활성화 상태 비활성화
109					}
110				},
111				point: {
112					events: {
113						mouseOver: function() {
114							return false; // 마우스 오버 이벤트 비활성화
115						},
116						click: function() {
117							return false; // 클릭 이벤트 비활성화
118						}
119					}
120				}
121			},
122			line: {
123				dataLabels: {
124					enabled: true
125				},
126			}
127		};
128
129	}
130	
131	// legend 위치 변경
132	if (chartId === 'II40' || chartId === 'II50') {
133		legend = {
134			layout: 'horizontal',
135			align: 'center',
136			verticalAlign: 'bottom'
137		}
138	} else {
139		legend = {
140			layout: 'vertical',
141			align: 'right',
142			verticalAlign: 'middle'
143		}
144	}
145
146
147	Highcharts.chart(target, {
148		title: {
149			text: title,
150			align: 'left'
151		},
152		subtitle: {
153			text: subTitle,
154			align: 'right'
155		},
156		legend: legend,
157		xAxis: {
158			categories: labelList
159			,accessibility: {
160				description: 'subTitle'
161			}
162		},
163		yAxis: {
164			title : {
165				text : subTitle
166			}
167		},
168		plotOptions: plotOptions,
169		series:series
170	});
171}
172
173// AREA
174function areaChart(cObj, target, height , width, title, subTitle){
175	$('#' + target).css('height',height).css('width',width);
176	const labelList = cObj.dataGrpList[0].labelList;
177	let series = []
178	for(var i=0; i < cObj.dataGrpList.length;i++){
179		const dataGrp = cObj.dataGrpList[i];
180		//console.log(dataGrp);
181		const data = {
182			name : dataGrp.chartDataTitle
183			,data : dataGrp.dataList
184		};
185		series.push(data)
186	}
187
188	Highcharts.chart(target, {
189		chart: {
190			type: 'area'
191		},
192		title: {
193			text: title,
194			align: 'left'
195		},
196		subtitle: {
197			text: subTitle,
198			align: 'center'
199		},
200		legend: {
201			layout: 'vertical',
202			align: 'right',
203			verticalAlign: 'middle'
204		},
205		xAxis: {
206			categories: labelList
207			,accessibility: {
208				description: 'subTitle'
209			}
210		},
211		yAxis: {
212			title : {
213				text : subTitle
214			}
215		},
216		series:series
217	});
218}
219
220// COLUMN
221function columnChart(cObj, target, height , width, title, subTitle){
222	$('#' + target).css('height',height).css('width',width);
223	const labelList = cObj.dataGrpList[0].labelList;
224	let series = [];
225	let maxVal = 0;
226	let legend = {};
227	let dataGrpLength = cObj.dataGrpList.length;
228	let chartId = "";
229
230	for(var i=0; i < cObj.dataGrpList.length;i++){
231		const dataGrp = cObj.dataGrpList[i];
232		//console.log(dataGrp);
233		if(i == 0) { chartId =  dataGrp.chartId; }
234		const data = {
235			name : dataGrp.chartDataTitle
236			,data : dataGrp.chartDataList
237			,showInLegend : dataGrpLength > 1
238			,dataLabels: {
239				enabled: true,
240				format: '{point.y:,.0f}'
241			}
242			,color : dataGrp.chartDataList[0].chartColor
243		};
244		series.push(data)
245	}
246
247	if(cObj.dataGrpList.length > 4){
248		legend = {
249			layout: 'vertical',
250			align: 'right',
251			verticalAlign: 'middle'
252		}
253	}
254
255	let plotOptions = {};
256	if (chartId === 'II60') {
257		plotOptions = {
258			series: {
259				states: {
260					hover: {
261						enabled: false // hover 비활성화
262					},
263					inactive: {
264						enabled: false // 비활성화 상태 비활성화
265					}
266				},
267				point: {
268					events: {
269						mouseOver: function() {
270							return false; // 마우스 오버 이벤트 비활성화
271						},
272						click: function() {
273							return false; // 클릭 이벤트 비활성화
274						}
275					}
276				}
277			}
278		};
279	}
280
281	Highcharts.chart(target, {
282		chart: {
283			type: 'column'
284		},
285		title: {
286			text: title,
287			align: 'left'
288		},
289		subtitle: {
290			text: subTitle,
291			align: 'right'
292		},
293		legend: legend,
294		xAxis: {
295			categories: labelList
296			,accessibility: {
297				description: 'subTitle'
298			}
299		},
300		yAxis: {
301			type: 'logarithmic',
302			title : {
303				text : subTitle
304			},
305			visible: false
306		},
307		plotOptions: plotOptions,
308		series:series
309	});
310}
311
312//PIE
313function pieChart(cObj, target, height , width, title, subTitle){
314	$('#' + target).css('height',height).css('width',width);
315	const labelList = cObj.dataGrpList[0].labelList;
316	let series = []
317	let chartId = "";
318	for(var i=0; i < cObj.dataGrpList.length;i++){
319		const dataGrp = cObj.dataGrpList[i];
320		//console.log(dataGrp);
321		if(i == 0) { chartId =  dataGrp.chartId; }
322		const data = {
323			name : dataGrp.chartDataTitle
324			,type: 'pie'
325			,data : dataGrp.chartDataList
326			,dataLabels: {
327				enabled: true,
328				format: '<b>{point.name}</b><br>{point.y:,.0f}',
329				distance: -70,
330				style: {
331					fontWeight: 'bold',
332					color: 'white'
333				}
334			}
335		};
336		series.push(data)
337	}
338
339	let plotOptions = {
340		pie: {
341			dataLabels: {
342				enabled: true,
343				distance: -80,
344				style: {
345					fontWeight: 'bold',
346					color: 'white'
347				}
348			}
349		}
350	};
351
352	if (chartId === 'II20') {
353		plotOptions = {
354			series: {
355				states: {
356					hover: {
357						enabled: false // hover 비활성화
358					},
359					inactive: {
360						enabled: false // 비활성화 상태 비활성화
361					}
362				},
363				point: {
364					events: {
365						mouseOver: function() {
366							return false; // 마우스 오버 이벤트 비활성화
367						},
368						click: function() {
369							return false; // 클릭 이벤트 비활성화
370						}
371					}
372				}
373			},
374			pie: {
375				dataLabels: {
376					enabled: true,
377					distance: -80,
378					style: {
379						fontWeight: 'bold',
380						color: 'white'
381					}
382				}
383			}
384		};
385	}
386
387	Highcharts.chart(target, {
388		credits: {enabled: false}
389		,title: {
390			text: title,
391			align: 'left'
392		}
393		,subtitle: {
394			text: subTitle,
395			align: 'right'
396		}
397		,legend: {
398			enabled: false
399		}
400		,plotOptions: plotOptions
401		,yAxis: {
402			title: {
403				text:'',
404				layout: 'vertical'
405			}
406		}
407		,xAxis: {
408			categories: labelList
409		}
410		,series: series
411	});
412}
413
414// half-PIE
415function halfPieChart(cObj, target, height , width, title, subTitle){
416	$('#' + target).css('height',height).css('width',width);
417	const labelList = cObj.dataGrpList[0].labelList;
418	let series = []
419	for(var i=0; i < cObj.dataGrpList.length;i++){
420		const dataGrp = cObj.dataGrpList[i];
421		//console.log(dataGrp);
422		const data = {
423			name : dataGrp.chartDataTitle
424			,type: 'pie'
425			,innerSize: '50%'
426			,data : dataGrp.chartDataList
427			,dataLabels: {
428				enabled: true,
429				format: '<b>{point.name}</b><br>{point.y:,.0f}',
430				distance: -70,
431				style: {
432					fontWeight: 'bold',
433					color: 'white'
434				}
435			}
436		};
437		series.push(data)
438	}
439	const plotOptions = {
440		pie: {
441			dataLabels: {
442				enabled: true,
443				distance: -80,
444				style: {
445					fontWeight: 'bold',
446					color: 'white'
447				},
448				format: '<b>{point.name}</b><br>{point.y:,.0f}',
449			}
450			,startAngle: -90
451			,endAngle: 90
452			,center: ['50%', '100%']
453			,size: '200%'
454		}
455	};
456
457	Highcharts.chart(target, {
458		credits: {enabled: false}
459		,title: {
460			text: title,
461			align: 'left'
462		}
463		,subtitle: {
464			text: subTitle,
465			align: 'right'
466		}
467		,legend: {
468			enabled: false
469		}
470		,plotOptions: plotOptions
471		,yAxis: {
472			title: {
473				text:'',
474				layout: 'vertical'
475			}
476		}
477		,xAxis: {
478			categories: labelList
479		}
480		,series: series
481	});
482}
483
484// bar-Stack
485function barStakChart(cObj, target, height , width, title, subTitle){
486	$('#' + target).css('height',height).css('width',width);
487	const labelList = cObj.dataGrpList[0].labelList;
488	let series = []
489	for(var i=0; i < cObj.dataGrpList.length;i++){
490		const dataGrp = cObj.dataGrpList[i];
491		//console.log(dataGrp);
492		const data = {
493			name : dataGrp.chartDataTitle
494			,data : dataGrp.chartDataList
495		};
496		series.push(data)
497	}
498	Highcharts.chart(target, {
499		credits: {enabled: false},
500		chart: {
501			type: 'bar'
502		},
503		title: {
504			text: title,
505			align: 'left'
506		},
507		subtitle: {
508			text: subTitle,
509			align: 'right'
510		},
511		xAxis: {
512			categories: labelList
513			,reversedStacks: true
514		},
515		yAxis:{
516			visible:false
517		},
518		legend:{
519			enabled:true
520		},
521		plotOptions: {
522			series: {
523				stacking: 'normal',
524				dataLabels: {
525					enabled: true
526				}
527			}
528		},
529		series:series
530	});
531}
532
533// column-Stack
534function columnStakChart(cObj, target, height , width, title, subTitle){
535	$('#' + target).css('height',height).css('width',width);
536	const labelList = cObj.dataGrpList[0].labelList;
537	let series = []
538
539	for(dataGrp of cObj.dataGrpList){
540		//console.log(dataGrp);
541		const data = {
542			name : dataGrp.chartDataTitle
543			,data : dataGrp.chartDataList
544			,color : dataGrp.chartDataList[0].chartColor
545		};
546		series.push(data)
547	}
548
549	Highcharts.chart(target, {
550		credits: {enabled: false},
551		chart: {
552			type: 'column'
553		},
554		title: {
555			text: title,
556			align: 'left'
557		},
558		subtitle: {
559			text: subTitle,
560			align: 'right'
561		},
562		xAxis: {
563			categories: labelList
564			,reversedStacks: true
565			// ,labels: {
566			// 	style: {
567			// 		lineHeight: '15px', // 카테고리 레이블의 높이
568			// 		padding: '5px', // 레이블 간의 여백
569			// 		overflow: 'justify', // 레이블이 차트 영역을 넘어갈 경우 잘림
570			// 		rotation: -45 // 레이블 회전
571			// 	}
572			// },
573			// ,labels: {
574			// 	style: {
575			// 		rotation: 0, // 레이블 회전 각도
576			// 		staggerLines: 2, // 줄 수 조정
577			// 		// height: '50px', // 고정 높이 설정
578			// 		// lineHeight: '50px', // 레이블의 높이
579			// 		padding: '5px',     // 레이블 간 여백
580			// 		fontSize: '12px'    // 레이블 글자 크기
581			// 	},
582			// 	useHTML: true, // HTML로 스타일을 적용 가능
583			// },
584		},
585		yAxis:{
586			type: 'logarithmic', // 로그 스케일 적용
587			title : {
588				text : subTitle
589			},
590			visible:false
591		},
592		/*legend:{
593            enabled:false
594        },*/
595		plotOptions: {
596			series: {
597				stacking: null,
598				dataLabels: {
599					enabled: true
600				}
601			}
602		},
603		series:series
604	});
605}
606
607
608
609/*
610function mapBubbleChart(cObj, target, height, width, title, subTitle) {
611    $('#' + target).css('height', height).css('width', width);
612
613    const dataGrp = cObj.dataGrpList[0];
614    const labelList = dataGrp.labelList;
615    const chartDataList = dataGrp.chartDataList;
616
617    // 국립공원 좌표 + 색상 테이블
618    const parkCoords = {
619        "지리산": { lat: 35.330, lon: 127.730, color: '#a69bd3' },
620        "경주": { lat: 35.856, lon: 129.224, color: '#a69bd3' },
621        "계룡산": { lat: 36.346, lon: 127.240, color: '#e8c164' },
622        "한려해상": { lat: 34.738, lon: 128.015, color: '#8a7ab9' },
623        "설악산": { lat: 38.176, lon: 128.160, color: '#d28b86' },
624        "속리산": { lat: 36.578, lon: 127.990, color: '#e8c164' },
625        "한라산": { lat: 33.441, lon: 126.829, color: '#87b976' },
626        "내장산": { lat: 35.428, lon: 126.880, color: '#6d9ed1' },
627        "가야산": { lat: 35.802, lon: 127.985, color: '#87a2d5' },
628        "덕유산": { lat: 35.906, lon: 127.70, color: '#6d9ed1' },
629        "오대산": { lat: 37.789, lon: 128.567, color: '#d28b86' },
630        "주왕산": { lat: 36.363, lon: 129.160, color: '#a69bd3' },
631        "태안해안": { lat: 36.700, lon: 126.300, color: '#e8c164' },
632        "다도해해상": { lat: 34.431, lon: 126.024, color: '#6d9ed1' },
633        "치악산": { lat: 37.408, lon: 128.027, color: '#d28b86' },
634        "월악산": { lat: 36.833, lon: 128.083, color: '#e8c164' },
635        "소백산": { lat: 36.899, lon: 128.469, color: '#8a7ab9' },
636        "월출산": { lat: 34.746, lon: 126.744, color: '#6d9ed1' },
637        "변산반도": { lat: 35.654, lon: 126.582, color: '#87a2d5' },
638        "무등산": { lat: 35.139, lon: 126.987, color: '#6d9ed1' },
639        "북한산": { lat: 37.658, lon: 126.999, color: '#87a2d5' },
640        "태백산": { lat: 37.090, lon: 128.991, color: '#d28b86' }
641    };
642
643    // 버블 데이터 변환
644    const bubbles = [];
645
646    labelList.forEach((label, idx) => {
647        const nm = typeof label === "object" ? (label.label || label.name) : label;
648
649        let v = chartDataList[idx].chartData;
650        if (typeof v === "object") v = v.value || v.data || v.label || 0;
651
652        const coord = parkCoords[nm];
653        if (!coord) return;
654
655        bubbles.push({
656            name: nm,
657            lat: coord.lat,
658            lon: coord.lon,
659            value: v,
660            z: v,
661            color: coord.color
662        });
663    });
664
665    // Highcharts 지도 생성
666    Highcharts.mapChart(target, {
667        credits: { enabled: false },
668
669        chart: {
670            map: 'countries/kr/kr-all'
671        },
672
673		title: {
674			text: title,
675			align: 'left'
676		},
677		subtitle: {
678			text: subTitle,
679			align: 'right'
680		},
681
682        tooltip: { enabled: false },
683        legend: { enabled: false },
684
685        plotOptions: {
686            map: {
687                dataLabels: { enabled: false },
688                states: {
689                    inactive: { enabled: false }
690                }
691            },
692
693            mapbubble: {
694                enableMouseTracking: false,   // ← 마우스 이벤트 제거
695                states: {
696                    hover: {
697                        enabled: false,       // ← hover 비활성화
698                        brightness: 0,
699                        halo: { size: 0 }
700                    }
701                },
702                dataLabels: {
703                    enabled: true,
704                    useHTML: false,
705                    align: 'center',
706                    verticalAlign: 'middle',
707                    y: 0,
708                    formatter: function () {
709                        return (
710                            this.point.name +
711                            '<tspan x="7" dy="20">' + this.point.value.toLocaleString() + '</tspan>'
712                        );
713                    },
714                    style: {
715                        fontWeight: '600',
716                        fontSize: '14px',
717                        lineHeight: '20px',
718                        textOutline: 'none',
719                        color: '#fff'
720                    }
721                }
722            },
723
724            mappoint: {
725                enableMouseTracking: false,
726                states: {
727                    inactive: { enabled: false },
728                    hover: { enabled: false }  // ← 독도 hover도 제거
729                }
730            }
731        },
732
733        series: [
734            {
735                mapData: Highcharts.maps['countries/kr/kr-all'],
736                nullColor: '#e8eef7',
737                borderColor: '#aac1d7',
738                enableMouseTracking: false
739            },
740
741            {
742                type: 'mapbubble',
743                data: bubbles,
744                minSize: 30,
745                maxSize: 100,
746                colorByPoint: true
747            },
748
749            {
750                name: '',
751                type: 'mappoint',
752                data: [{
753                    lat: 37.241086,
754                    lon: 131.864716,
755                    marker: {
756                        radius: 2,
757                        fillColor: '#DFEAF8'
758                    }
759                }],
760                enableMouseTracking: false,
761                showInLegend: false
762            }
763        ]
764    });
765}
766
767*/
768
769function mapBubbleChart(cObj, target, height, width, title, subTitle) {
770
771    $('#' + target).css('height', height).css('width', "100%");
772
773    const dataGrp = cObj.dataGrpList[0];
774    const labelList = dataGrp.labelList;
775    const chartDataList = dataGrp.chartDataList;
776	//console.log("target : " + target);
777
778
779    // 국립공원 좌표 + 색상 테이블
780    const parkCoords = {
781        "지리산": { lat: 35.330, lon: 127.730, color: '#a69bd3' },
782        "경주": { lat: 35.856, lon: 129.224, color: '#a69bd3' },
783        "계룡산": { lat: 36.346, lon: 127.240, color: '#e8c164' },
784        "한려해상": { lat: 34.738, lon: 128.015, color: '#8a7ab9' },
785        "설악산": { lat: 38.176, lon: 128.160, color: '#d28b86' },
786        "속리산": { lat: 36.578, lon: 127.990, color: '#e8c164' },
787        "한라산": { lat: 33.441, lon: 126.829, color: '#87b976' },
788        "내장산": { lat: 35.428, lon: 126.880, color: '#6d9ed1' },
789        "가야산": { lat: 35.802, lon: 127.985, color: '#a69bd3' },
790        "덕유산": { lat: 35.906, lon: 127.620, color: '#6d9ed1' },
791        "오대산": { lat: 37.789, lon: 128.567, color: '#d28b86' },
792        "주왕산": { lat: 36.363, lon: 129.160, color: '#a69bd3' },
793        "태안해안": { lat: 36.700, lon: 126.300, color: '#e8c164' },
794        "다도해해상": { lat: 34.431, lon: 126.024, color: '#6d9ed1' },
795        "치악산": { lat: 37.408, lon: 128.027, color: '#d28b86' },
796        "월악산": { lat: 36.833, lon: 128.083, color: '#e8c164' },
797        "소백산": { lat: 36.899, lon: 128.469, color: '#8a7ab9' },
798        "월출산": { lat: 34.746, lon: 126.744, color: '#6d9ed1' },
799        "변산반도": { lat: 35.654, lon: 126.402, color: '#87a2d5' },
800        "무등산": { lat: 35.139, lon: 126.987, color: '#6d9ed1' },
801        "북한산": { lat: 37.658, lon: 126.999, color: '#87a2d5' },
802        "태백산": { lat: 37.090, lon: 128.991, color: '#d28b86' },
803		"팔공산": { lat: 35.985, lon: 128.713, color: '#a69bd3' }
804    };
805
806	// 데이터 변환
807	const bubbles = [];
808	labelList.forEach((label, idx) => {
809		const nm = typeof label === "object" ? (label.label || label.name) : label;
810		let v = chartDataList[idx].chartData;
811		if (typeof v === "object") v = v.value || v.data || v.label || 0;
812
813		const coord = parkCoords[nm];
814		if (!coord) return;
815
816		bubbles.push({
817			name: nm,
818			lat: coord.lat,
819			lon: coord.lon,
820			value: v,
821			z: v,
822			// chartColor가 있으면 chartColor 사용, 없으면 기존 색상 사용
823			color: chartDataList[idx].chartColor || coord.color
824		});
825	});
826
827    Highcharts.mapChart(target, {
828        credits: { enabled: false },
829
830        chart: {
831            map: 'countries/kr/kr-all'
832        },
833
834        // 지도 축소 효과
835        mapView: {
836            padding: [10, 110, 10, 10]
837        },
838
839        title: {
840            text: title,
841            align: 'left'
842        },
843        subtitle: {
844            text: subTitle,
845            align: 'right'
846        },
847
848        tooltip: { enabled: false },
849        legend: { enabled: false },
850
851        plotOptions: {
852            map: {
853                dataLabels: { enabled: false },
854                states: { inactive: { enabled: false } }
855            },
856            mapbubble: {
857                enableMouseTracking: false,
858                states: {
859                    hover: { enabled: false, brightness: 0, halo: { size: 0 } }
860                },
861                dataLabels: {
862                    enabled: true,
863                    align: 'center',
864                    verticalAlign: 'middle',
865					formatter: function () {
866						const name = this.point.name;
867						const val = this.point.value;
868						const xVal = val > 100 ? 7 : 15;   // ★ 조건에 따라 x 값 변경
869
870						return name + `<tspan x="${xVal}" dy="13">
870${val.toLocaleString()}</tspan>`;
871					},
872					style: {
873                        fontWeight: '600',
874                        fontSize: '13px',
875                        color: '#fff',
876                        textOutline: 'none'
877                    }
878                }
879            },
880            mappoint: {
881                enableMouseTracking: false,
882                states: {
883                    inactive: { enabled: false },
884                    hover: { enabled: false }
885                }
886            }
887        },
888
889        series: [
890            {
891                mapData: Highcharts.maps['countries/kr/kr-all'],
892                nullColor: '#e8eef7',
893                borderColor: '#aac1d7',
894                enableMouseTracking: false
895            },
896            {
897                type: 'mapbubble',
898                data: bubbles,
899                minSize: 30,
900                maxSize: '10%',
901                colorByPoint: true
902            },
903            {
904                name: '',
905                type: 'mappoint',
906                data: [{
907                    lat: 37.241086,
908                    lon: 131.864716,
909                    marker: {
910                        radius: 2,
911                        fillColor: '#DFEAF8'
912                    }
913                }],
914                enableMouseTracking: false,
915                showInLegend: false
916            }
917        ],
918
919        // 반응형 설정 시작
920        responsive: {
921            rules: [
922                // 모바일 (화면 500px 이하)
923                {
924                    condition: { maxWidth: 500 },
925                    chartOptions: {
926						// 지도 축소 효과
927						mapView: {
928							padding: [0, 0, 0, 0]
929						},
930                        plotOptions: {
931                            mapbubble: {
932                                minSize: 10,
933                                maxSize: "6%",
934                                dataLabels: {
935                                    style: { fontSize: "8px" }
936                                }
937                            }
938                        }
939                    }
940                },
941                // 태블릿 (500~900px)
942                {
943                    condition: { maxWidth: 600 },
944                    chartOptions: {
945                        plotOptions: {
946                            mapbubble: {
947                                minSize: 15,
948                                maxSize: "8%",
949                                dataLabels: {
950                                    style: { fontSize: "9px" }
951                                }
952                            }
953                        }
954                    }
955                },
956                // PC (900px 이상)
957                {
958                    condition: { minWidth: 901 },
959                    chartOptions: {
960                        plotOptions: {
961                            mapbubble: {
962                                minSize: 20,
963                                maxSize: "10%",
964                                dataLabels: {
965                                    style: { fontSize: "10px" }
966                                }
967                            }
968                        }
969                    }
970                }
971            ]
972        }
973        // 반응형 설정 끝
974
975    });
976}
977
978
979/*
980
981function provinceMapChart(cObj, target, height, width, title, subTitle) {
982
983    $('#' + target).css('height', height).css('width', width || "100%");
984
985    const dataGrp = cObj.dataGrpList[0];
986    const dataList = dataGrp.chartDataList;
987
988    const NAME_KR = {
989        'kr-so': '서울특별시','kr-pu': '부산광역시','kr-tg': '대구광역시','kr-in': '인천광역시',
990        'kr-kj': '광주광역시','kr-tj': '대전광역시','kr-ul': '울산광역시','kr-sj': '세종특별자치시',
991        'kr-kg': '경기도','kr-kw': '강원특별자치도','kr-gb': '충청북도','kr-gn': '충청남도',
992        'kr-2688': '경상북도','kr-kn': '경상남도','kr-cb': '전북특별자치도','kr-2685': '전라남도',
993        'kr-cj': '제주특별자치도'
994    };
995
996    const PROV_COLORS = {
997		"서울특별시": "#E9F1D8",
998		"경기도": "#E9F1D8",
999		"인천광역시": "#E9F1D8",
1000		"강원특별자치도": "#F5D3D0",
1001		"세종특별자치시": "#F8E6B8",
1002		"충청북도": "#F8E6B8",
1003		"충청남도": "#F8E6B8",
1004		"대전광역시": "#F8E6B8",
1005		"경상북도": "#E0DAED",
1006		"경상남도": "#E0DAED",
1007		"부산광역시": "#E0DAED",
1008		"울산광역시": "#E0DAED",
1009		"대구광역시": "#E0DAED",
1010		"전북특별자치도": "#CFE2F5",
1011		"전라남도": "#CFE2F5",
1012		"광주광역시": "#CFE2F5",
1013		"제주특별자치도": "#DDECCD"
1014    };
1015
1016    const PROV_CENTER = {
1017        "강원특별자치도": [37.9, 128.3],"충청북도": [36.8, 127.8],
1018        "경상북도": [36.4, 128.8],"경상남도": [35.3, 128.3],"전북특별자치도": [35.8, 127.1],
1019        "전라남도": [34.8, 126.7],
1020    };
1021
1022    const inputData = {};
1023    const colorData = {};
1024    dataList.forEach(item => {
1025        inputData[item.chartDataLabel] = item.chartData;
1026        colorData[item.chartDataLabel] = item.chartColor;
1027    });
1028
1029    $.getJSON('https://code.highcharts.com/mapdata/countries/kr/kr-all.topo.json', function (topology) {
1030
1031        const areaData = topology.objects.default.geometries.map(g => {
1032            const key = g.properties['hc-key'];
1033            const name = NAME_KR[key];
1034
1035            return {
1036                'hc-key': key,
1037                name: name,
1038                value: inputData[name] || null,
1039                color: PROV_COLORS[name] || '#f0f0f0'
1040            };
1041        });
1042
1043        const bubbleData = Object.keys(PROV_CENTER).map(name => {
1044            const [lat, lon] = PROV_CENTER[name];
1045            const chartColor = colorData[name] || '#000';
1046
1047            return {
1048                name,
1049                lat,
1050                lon,
1051                z: inputData[name] || 0,
1052                color: chartColor,
1053                borderColor: chartColor,
1054                marker: {
1055                    radius: 40,
1056                    fillColor: '#ffffff',
1057                    lineColor: chartColor,
1058                    lineWidth: 4
1059                },
1060				dataLabels: {
1061					enabled: true,
1062					useHTML: true,
1063					y: 45,          // ★ 버블 정중앙으로 이동하는 핵심 값
1064					formatter: function () {
1065						const chartColor = this.point.color;
1066						return `
1067							<div style="
1068								text-align:center;
1069								font-size:11px;
1070								font-weight:700;
1071								color:${chartColor};
1072								line-height:16px;
1073							">
1074								${this.point.z}km<sup>2</sup><br>
1075								<span style="font-size:12px;">${this.point.name}</span>
1076							</div>
1077						`;
1078					}
1079				}
1080
1081
1082            };
1083        });
1084
1085        Highcharts.mapChart(target, {
1086            chart: { map: topology },
1087            credits: { enabled: false },
1088			// 지도 축소 효과
1089			mapView: {
1090				padding: [10, 95, 10, 10]
1091			},
1092
1093			title: {
1094				text: title,
1095				align: 'left'
1096			},
1097			subtitle: {
1098				text: subTitle,
1099				align: 'right'
1100			},
1101            legend: { enabled: false },
1102
1103			plotOptions: {
1104				mappoint: {
1105					enableMouseTracking: false,
1106					states: {
1107						inactive: { enabled: false },
1108						hover: { enabled: false }
1109					}
1110				}
1111			},
1112
1113            series: [
1114				{
1115					type: 'map',
1116					mapData: topology,
1117					data: areaData,
1118					joinBy: 'hc-key',
1119					borderColor: '#ffffff',
1120					borderWidth: 1.5,
1121
1122					enableMouseTracking: false,   // ★ 지도 위 마우스 이벤트 차단
1123					states: {
1124						hover: { enabled: false },    // ★ hover 비활성화
1125						inactive: { enabled: false }
1126					}
1127				},
1128				{
1129					type: 'mappoint',
1130					data: bubbleData,
1131
1132					enableMouseTracking: false,   // ★ 마우스 반응 완전 차단
1133					states: {
1134						hover: { enabled: false },    // ★ hover 비활성화
1135						inactive: { enabled: false }
1136					}
1137				},
1138				{
1139					name: '',
1140					type: 'mappoint',
1141					data: [{
1142						lat: 37.241086,
1143						lon: 131.864716,
1144						marker: {
1145							radius: 2,
1146							fillColor: '#DFEAF8'
1147						}
1148					}],
1149					enableMouseTracking: false,
1150					showInLegend: false
1151				}
1152            ],
1153
1154			responsive: {
1155				rules: [
1156					{
1157						condition: { maxWidth: 499 },
1158						chartOptions: {
1159							chart: {
1160								events: {
1161									load: function () {
1162										console.log("Applied: maxWidth 500");
1163									}
1164								}
1165							},
1166							series: [
1167								{}, // series[0] (지도) 수정 없음
1168								{   // series[1] (버블)
1169									marker: { radius: 14, lineWidth: 2 },
1170									dataLabels: {
1171										y: 30,
1172										style: { fontSize: "9px" }
1173									}
1174								},
1175								{} // series[2] (지도) 수정 없음
1176
1177							]
1178						}
1179					},
1180					{
1181						condition: { maxWidth: 900 },
1182						chartOptions: {
1183							series: [
1184								{}, 
1185								{
1186									marker: { radius: 32, lineWidth: 3 },
1187									dataLabels: {
1188										y: 42,
1189										style: { fontSize: "10px" }
1190									}
1191								},
1192								{} // series[2] (지도) 수정 없음
1193							]
1194						}
1195					},
1196					{
1197						condition: { minWidth: 901 },
1198						chartOptions: {
1199							series: [
1200								{},
1201								{
1202									marker: { radius: 40, lineWidth: 4 },
1203									dataLabels: {
1204										y: 53,
1205										style: { fontSize: "11px" }
1206									}
1207								},
1208								{} // series[2] (지도) 수정 없음
1209							]
1210						}
1211					}
1212				]
1213			}
1214
1215
1216        });
1217    });
1218}
1219
1220
1221*/
1222
1223function provinceMapChart(cObj, target, height, width, title, subTitle) {
1224
1225    $('#' + target).css('height', height).css('width', width || "100%");
1226
1227    const $container = $('#' + target);
1228    const containerWidth = $container.width();   // ★ 컨테이너 실제 너비
1229
1230    // ★ 너비에 따른 버블/폰트 사이즈 결정
1231    let bubbleRadius = 41;
1232    let bubbleLineWidth = 4;
1233    let labelY = 50;
1234    let fontSizeValue = 11;  // 숫자 km²
1235    let fontSizeName  = 12;  // 도 이름
1236
1237
1238    if (containerWidth <= 400) {
1239        bubbleRadius = 18;
1240        bubbleLineWidth = 2;
1241        labelY = 28;
1242        fontSizeValue = 9;
1243        fontSizeName  = 10;
1244    } else if (containerWidth <= 600) {
1245        bubbleRadius = 30;
1246        bubbleLineWidth = 3;
1247        labelY = 38;
1248        fontSizeValue = 10;
1249        fontSizeName  = 11;
1250    }
1251
1252    // 그 외(PC)는 초기 값(40, 4, 45, 11, 12) 유지
1253
1254    const dataGrp = cObj.dataGrpList[0];
1255    const dataList = dataGrp.chartDataList;
1256
1257    const NAME_KR = {
1258        'kr-so': '서울특별시','kr-pu': '부산광역시','kr-tg': '대구광역시','kr-in': '인천광역시',
1259        'kr-kj': '광주광역시','kr-tj': '대전광역시','kr-ul': '울산광역시','kr-sj': '세종특별자치시',
1260        'kr-kg': '경기도','kr-kw': '강원특별자치도','kr-gb': '충청북도','kr-gn': '충청남도',
1261        'kr-2688': '경상북도','kr-kn': '경상남도','kr-cb': '전북특별자치도','kr-2685': '전라남도',
1262        'kr-cj': '제주특별자치도'
1263    };
1264
1265    const PROV_COLORS = {
1266        "서울특별시": "#E9F1D8",
1267        "경기도": "#E9F1D8",
1268        "인천광역시": "#E9F1D8",
1269        "강원특별자치도": "#F5D3D0",
1270        "세종특별자치시": "#F8E6B8",
1271        "충청북도": "#F8E6B8",
1272        "충청남도": "#F8E6B8",
1273        "대전광역시": "#F8E6B8",
1274        "경상북도": "#E0DAED",
1275        "경상남도": "#E0DAED",
1276        "부산광역시": "#E0DAED",
1277        "울산광역시": "#E0DAED",
1278        "대구광역시": "#E0DAED",
1279        "전북특별자치도": "#CFE2F5",
1280        "전라남도": "#CFE2F5",
1281        "광주광역시": "#CFE2F5",
1282        "제주특별자치도": "#DDECCD"
1283    };
1284
1285    const PROV_CENTER = {
1286        "강원특별자치도": [37.9, 128.3],
1287        "충청북도": [36.8, 127.8],
1288        "경상북도": [36.4, 128.8],
1289        "경상남도": [35.3, 128.3],
1290        "전북특별자치도": [35.8, 127.1],
1291        "전라남도": [34.8, 126.7],
1292    };
1293
1294    const inputData = {};
1295    const colorData = {};
1296    dataList.forEach(item => {
1297        inputData[item.chartDataLabel] = item.chartData;
1298        colorData[item.chartDataLabel] = item.chartColor;
1299    });
1300
1301    $.getJSON('https://code.highcharts.com/mapdata/countries/kr/kr-all.topo.json', function (topology) {
1302
1303        const areaData = topology.objects.default.geometries.map(g => {
1304            const key = g.properties['hc-key'];
1305            const name = NAME_KR[key];
1306
1307            return {
1308                'hc-key': key,
1309                name: name,
1310                value: inputData[name] || null,
1311                color: PROV_COLORS[name] || '#f0f0f0'
1312            };
1313        });
1314
1315        const bubbleData = Object.keys(PROV_CENTER).map(name => {
1316            const [lat, lon] = PROV_CENTER[name];
1317            const chartColor = colorData[name] || '#000';
1318
1319            return {
1320                name,
1321                lat,
1322                lon,
1323                z: inputData[name] || 0,
1324                color: chartColor,
1325                borderColor: chartColor,
1326                marker: {
1327                    radius: bubbleRadius,          // ★ 너비에 따라 계산된 값
1328                    fillColor: '#ffffff',
1329                    lineColor: chartColor,
1330                    lineWidth: bubbleLineWidth     // ★ 너비에 따라 계산된 값
1331                },
1332                dataLabels: {
1333                    enabled: true,
1334                    useHTML: true,
1335                    y: labelY,                     // ★ 너비에 따라 계산된 값
1336                    formatter: function () {
1337                        const chartColor = this.point.color;
1338                        return `
1339                            <div style="
1340                                text-align:center;
1341                                font-size:${fontSizeValue}px;
1342                                font-weight:700;
1343                                color:${chartColor};
1344                                line-height:16px;
1345                            ">
1346                                ${this.point.z}km<sup>2</sup><br>
1347                                <span style="font-size:${fontSizeName}px;">
1348                                    ${this.point.name}
1349                                </span>
1350                            </div>
1351                        `;
1352                    }
1353                }
1354            };
1355        });
1356
1357        Highcharts.mapChart(target, {
1358            chart: { map: topology },
1359            credits: { enabled: false },
1360			
1361            // 지도 축소 효과
1362            mapView: {
1363                padding: [0, 83, 0, 0]
1364            },
1365
1366            title: {
1367                text: title,
1368                align: 'left'
1369            },
1370            subtitle: {
1371                text: subTitle,
1372                align: 'right'
1373            },
1374            legend: { enabled: false },
1375
1376            plotOptions: {
1377                mappoint: {
1378                    enableMouseTracking: false,
1379                    states: {
1380                        inactive: { enabled: false },
1381                        hover: { enabled: false }
1382                    }
1383                }
1384            },
1385
1386            series: [
1387                {
1388                    type: 'map',
1389                    mapData: topology,
1390                    data: areaData,
1391                    joinBy: 'hc-key',
1392                    borderColor: '#ffffff',
1393                    borderWidth: 1.5,
1394                    enableMouseTracking: false,
1395                    states: {
1396                        hover: { enabled: false },
1397                        inactive: { enabled: false }
1398                    }
1399                },
1400                {
1401                    type: 'mappoint',
1402                    data: bubbleData,
1403                    enableMouseTracking: false,
1404                    states: {
1405                        hover: { enabled: false },
1406                        inactive: { enabled: false }
1407                    }
1408                },
1409                {
1410                    name: '',
1411                    type: 'mappoint',
1412                    data: [{
1413                        lat: 37.241086,
1414                        lon: 131.864716,
1415                        marker: {
1416                            radius: 2,
1417                            fillColor: '#DFEAF8'
1418                        }
1419                    }],
1420                    enableMouseTracking: false,
1421                    showInLegend: false
1422                }
1423            ]
1424        });
1425    });
1426}
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437// 1page chart
1438function statIdx1Chart(){
1439	//chartStat0();
1440	chartStat1();
1441	//chartStat2();
1442	//chartStat3();
1443	//chartStat4();
1444	//chartStat5();
1445	//chartStat6();
1446}
1447
1448function chart_test() {
1449	const target = 'testChart';
1450	$('#'+ target).css('height','100%').css('width','100%');
1451	const title = '계(Kingdom) 분류체계에 따른 생물 종 수';
1452
1453	// 기존 데이터
1454	const bird1Grade = [2, 5, 3, 6, 4]; // 조류 1급 데이터
1455	const mammal1Grade = [4, 3, 2, 4, 3]; // 포유류 1급 데이터
1456	const bird2Grade = [3, 4, 5, 3, 2]; // 조류 2급 데이터
1457	const mammal2Grade = [5, 7, 6, 2, 4]; // 포유류 2급 데이터
1458
1459	// 합계 데이터 동적 생성
1460	const firstGradeSum = bird1Grade.map((val, idx) => val + mammal1Grade[idx]); // 1급 합계
1461	const secondGradeSum = bird2Grade.map((val, idx) => val + mammal2Grade[idx]); // 2급 합계
1462	let series = [{
1463		name: '조류 1급',
1464		data: bird1Grade,
1465		color: '#ff9999', // 조류 1급 색상
1466		group: '조류',
1467		showInLegend: true // 범례에 표시
1468	}, {
1469		name: '포유류 1급',
1470		data: mammal1Grade,
1471		color: '#66ccff', // 포유류 1급 색상
1472		group: '포유류',
1473		showInLegend: true // 범례에 표시
1474	}, {
1475		name: '조류 2급',
1476		data: bird2Grade,
1477		color: '#ffcc99', // 조류 2급 색상
1478		group: '조류',
1479		showInLegend: false // 범례에 표시하지 않음
1480	}, {
1481		name: '포유류 2급',
1482		data: mammal2Grade,
1483		color: '#a4d8ff', // 포유류 2급 색상
1484		group: '포유류',
1485		showInLegend: false // 범례에 표시하지 않음
1486	}, {
1487		name: '1급 합계',
1488		data: firstGradeSum, // 동적으로 생성된 1급 합계 데이터
1489		stack: '합계',
1490		group: '합계',
1491		showInLegend: false // 범례에 표시
1492	}, {
1493		name: '2급 합계',
1494		data: secondGradeSum, // 동적으로 생성된 2급 합계 데이터
1495		stack: '합계',
1496		group: '합계',
1497		showInLegend: false // 범례에 표시
1498	}];
1499
1500	Highcharts.chart('container', {
1501		chart: {
1502			type: 'bar'
1503		},
1504		title: {
1505			text: '조류 및 포유류 데이터'
1506		},
1507		xAxis: {
1508			categories: ['서울특별시', '부산광역시', '대구광역시', '인천광역시', '경상남도']
1509		},
1510		yAxis: {
1511			min: 0,
1512			title: {
1513				text: '종수'
1514			}
1515		},
1516		legend: {
1517			labelFormatter: function () {
1518				// 범례에 '조류', '포유류'만 표시
1519				if (this.options.group === '조류') {
1520					return '조류';
1521				} else if (this.options.group === '포유류') {
1522					return '포유류';
1523				} else if (this.options.group === '합계') {
1524					return '합계';
1525				}
1526				return this.name;
1527			},
1528		},
1529		plotOptions: {
1530			series: {
1531				stacking: 'normal',
1532				events: {
1533					legendItemClick: function (event) {
1534						var visible = this.visible;
1535						this.chart.series.forEach(function (s) {
1536							// 동일한 그룹의 데이터 시리즈를 함께 표시/숨김 처리
1537							if (s.options.group === event.target.options.group) {
1538								s.setVisible(!visible, false);
1539							}
1540						});
1541						this.chart.redraw();
1542						return false;
1543					}
1544				}
1545			}
1546		},
1547		series: [{
1548			name: '조류 1급',
1549			data: bird1Grade,
1550			color: '#ff9999', // 조류 1급 색상
1551			group: '조류',
1552			showInLegend: true // 범례에 표시
1553		}, {
1554			name: '포유류 1급',
1555			data: mammal1Grade,
1556			color: '#66ccff', // 포유류 1급 색상
1557			group: '포유류',
1558			showInLegend: true // 범례에 표시
1559		}, {
1560			name: '조류 2급',
1561			data: bird2Grade,
1562			color: '#ffcc99', // 조류 2급 색상
1563			group: '조류',
1564			showInLegend: false // 범례에 표시하지 않음
1565		}, {
1566			name: '포유류 2급',
1567			data: mammal2Grade,
1568			color: '#a4d8ff', // 포유류 2급 색상
1569			group: '포유류',
1570			showInLegend: false // 범례에 표시하지 않음
1571		}, {
1572			name: '1급 합계',
1573			data: firstGradeSum, // 동적으로 생성된 1급 합계 데이터
1574			stack: '합계',
1575			group: '합계',
1576			showInLegend: false // 범례에 표시
1577		}, {
1578			name: '2급 합계',
1579			data: secondGradeSum, // 동적으로 생성된 2급 합계 데이터
1580			stack: '합계',
1581			group: '합계',
1582			showInLegend: false // 범례에 표시
1583		}]
1584	});
1585}
1586
1587function preprocessData(data) {
1588	return data.map(value => (value === 0 ? null : value)); // 0을 null로 변경
1589}
1590
1591function chart2StatMix(chartId) {
1592	const chartInfo = getChartInfo(chartId);
1593	const target = chartId;
1594	const subTitle = '(단위: 종)';
1595
1596	$('#' + target).css('height', '100%').css('width', '100%');
1597	const title = chartInfo.chartTitle;
1598
1599	let categories = [];
1600	let series = [];
1601	let firstGradeSum = [];
1602	let secondGradeSum = [];
1603
1604	// chartInfo에서 카테고리와 시리즈 데이터 수집
1605	for (dataGrp of chartInfo.dataGrpList) {
1606		if (categories.length === 0) {
1607			categories = dataGrp.labelList;
1608		}
1609		if (dataGrp.chartDataTitle.includes('II급')) {
1610			dataGrp.dataList.forEach((value, idx) => {
1611				if (secondGradeSum[idx] === undefined) {
1612					secondGradeSum[idx] = 0;
1613				}
1614				secondGradeSum[idx] += value;
1615			});
1616		} else if (dataGrp.chartDataTitle.includes('I급')) {
1617			dataGrp.dataList.forEach((value, idx) => {
1618				if (firstGradeSum[idx] === undefined) {
1619					firstGradeSum[idx] = 0;
1620				}
1621				firstGradeSum[idx] += value;
1622			});
1623		}
1624		let data = {
1625			name: dataGrp.chartDataTitle,
1626			data: preprocessData(dataGrp.dataList),
1627			group: dataGrp.chartDataTitle.replace(/II급/g, '').replace(/I급/g, '').replace(/\(/g, '').replace(/\)/g, ''),
1628			color: dataGrp.chartDataList[0].chartColor,
1629			showInLegend: dataGrp.chartDataTitle.includes('II급') ? false : true,
1630		};
1631		series.push(data);
1632	}
1633	series.reverse();
1634
1635	// 1,2급 합계 시리즈 생성
1636	let firstGradeSumSeries = {
1637		name: 'I급 합계',
1638		data: firstGradeSum,
1639		stack: '합계',
1640		group: '합계',
1641		color: '#8AC193',
1642		showInLegend: false
1643	};
1644
1645	let secondGradeSumSeries = {
1646		name: 'II급 합계',
1647		data: secondGradeSum,
1648		stack: '합계',
1649		group: '합계',
1650		color: '#5B96BD',
1651		showInLegend: false
1652	};
1653
1654	series.push(secondGradeSumSeries);
1655	series.push(firstGradeSumSeries);
1656
1657	const legend = {
1658		labelFormatter: function () {
1659			if (this.options.group === '포유류') {
1660				return '포유류';
1661			} else if (this.options.group === '조류') {
1662				return '조류';
1663			} else if (this.options.group === '양서류') {
1664				return '양서류';
1665			} else if (this.options.group === '파충류') {
1666				return '파충류';
1667			} else if (this.options.group === '어류') {
1668				return '어류';
1669			} else if (this.options.group === '무척추동물류') {
1670				return '무척추동물류';
1671			} else if (this.options.group === '곤충류') {
1672				return '곤충류';
1673			} else if (this.options.group === '육상식물') {
1674				return '육상식물';
1675			} else if (this.options.group === '해조류') {
1676				return '해조류';
1677			} else if (this.options.group === '고등균류') {
1678				return '고등균류';
1679			} else if (this.options.group === '합계') {
1680				return '합계';
1681			}
1682			return this.name;
1683		},
1684		reversed: true
1685	};
1686
1687	const plotOptions = {
1688		series: {
1689			stacking: 'normal',
1690			events: {
1691				legendItemClick: function (event) {
1692					var visible = this.visible;
1693					const chart = this.chart;
1694
1695					// 범례 그룹 처리
1696					this.chart.series.forEach(function (s) {
1697						if (s.options.group === event.target.options.group) {
1698							s.setVisible(!visible, false);
1699						}
1700					});
1701					this.chart.redraw();
1702
1703					// 범례 클릭 시 1급, 2급 합계 배열 초기화
1704					const firstGradeSum = Array(categories.length).fill(0);
1705					const secondGradeSum = Array(categories.length).fill(0);
1706
1707					// 클릭된 범례의 그룹을 기준으로 합계 계산 (단, "I급 합계" 및 "II급 합계" 시리즈는 제외)
1708					chart.series.forEach(function (s) {
1709						if (s.options.group !== '합계' && s.visible) {
1710							if (s.options.name.includes('II급')) {
1711								s.data.forEach((point, idx) => {
1712									secondGradeSum[idx] += point.y;
1713								});
1714							}else if(s.options.name.includes('I급')) {
1715								s.data.forEach((point, idx) => {
1716									firstGradeSum[idx] += point.y;
1717								});
1718							}
1719						}
1720					});
1721
1722					// 합계 시리즈 데이터 업데이트
1723					const firstGradeSeries = chart.series.find(s => s.options.name === 'I급 합계');
1724					const secondGradeSeries = chart.series.find(s => s.options.name === 'II급 합계');
1725
1726					firstGradeSeries.setData(firstGradeSum);
1727					secondGradeSeries.setData(secondGradeSum);
1728
1729					return false;
1730				}
1731			},
1732			dataLabels: {
1733				enabled: true
1734			}
1735		}
1736	};
1737	Highcharts.chart(target, {
1738		chart: {
1739			type: 'bar',
1740		},
1741		title: {
1742			text: title,
1743			align: 'left'
1744		},
1745		subtitle: {
1746			text: subTitle,
1747			align: 'right'
1748		},
1749		legend: legend,
1750		plotOptions: plotOptions,
1751		yAxis: {
1752			min: 0,
1753			title: {
1754				text: '종수'
1755			}
1756		},
1757		xAxis: {
1758			categories: categories
1759		},
1760		series: series
1761	});
1762}
1763
1764function chartStat0(){
1765	const target = 'chart0';
1766	$('#'+ target).css('height','100%').css('width','100%');
1767	const title = '세부분류군별 종현황';
1768	const subTitle = '';
1769	const categories = ['동물계','식물계','유색조식물계','균계','원생동물계','세균계','고세균계'];
1770	const plotOptions = [];
1771	const data = [
1772		{ id: '0.0', parent: '', name: '', color: '#FFFFFF', visible: false },
1773		{ id: '1.1', parent: '0.0', name: '동물계' , color: '#00431c'},
1774		{ id: '2.1', parent: '1.1', name: '포유류', value: 125 , color: '#177540'},
1775		{ id: '2.2', parent: '1.1', name: '조류', value: 552 , color: '#42a86e'},
1776		{ id: '2.3', parent: '1.1', name: '파충류', value: 36 , color: '#ccffe0'},
1777		{ id: '2.4', parent: '1.1', name: '양서류', value: 28 , color: '#ccffe0'},
1778		{ id: '2.5', parent: '1.1', name: '어류', value: 1349 , color: '#00431c'},
1779		{ id: '2.6', parent: '1.1', name: '미삭동물류', value: 139 , color: '#00c252'},
1780		{ id: '2.7', parent: '1.1', name: '무척추동물류(곤충류 제외)', value: 10754 , color: '#009940'},
1781		{ id: '2.8', parent: '1.1', name: '곤충류', value: 20710 , color: '#00702e'},
1782		{ id: '1.2', parent: '0.0', name: '식물계' },
1783		{ id: '2.21', parent: '1.2', name: '관속식물류', value: 4641 , color: '#edb000'},
1784		{ id: '2.22', parent: '1.2', name: '선태류', value: 1118 , color: '#d69900'},
1785		{ id: '2.23', parent: '1.2', name: '윤조류', value: 1001 , color: '#ad7d00'},
1786		{ id: '2.24', parent: '1.2', name: '녹조류', value: 854 , color: '#855e00'},
1787		{ id: '2.25', parent: '1.2', name: '홍조류', value: 670 , color: '#5c4200'},
1788		{ id: '1.3', parent: '0.0', name: '유색조식물계' , color: '#82ad6b'},
1789		{ id: '2.31', parent: '1.3', name: '돌말류', value: 2323 , color: '#a3db87'},
1790		{ id: '2.32', parent: '1.3', name: '와편모조류', value: 544 , color: '#47613d'},
1791		{ id: '2.33', parent: '1.3', name: '대롱편모조류', value: 417 , color: '#668a54'},
1792		{ id: '2.34', parent: '1.3', name: '은편모조류', value: 17 , color: '#293824'},
1793		{ id: '2.35', parent: '1.3', name: '착편모조류', value: 13 , color: '#293824'},
1794		{ id: '2.36', parent: '1.3', name: '황적조류', value: 2 , color: '#293824'},
1795		{ id: '1.4', parent: '0.0', name: '균계' , color: '#7d9199'},
1796		{ id: '2.41', parent: '1.4', name: '균류', value: 5054 , color: '#a3bdc7'},
1797		{ id: '2.42', parent: '1.4', name: '지의류', value: 1237 , color: '#617075'},
1798		{ id: '1.5', parent: '0.0', name: '원생동물계' , color: '#c28014'},
1799		{ id: '2.51', parent: '1.5', name: '원생동물류', value: 2575 , color: '#f79e
179900'},
1800		{ id: '2.52', parent: '1.5', name: '유글레나조류', value: 398 , color: '#7d4f00'},
1801		{ id: '1.6', parent: '0.0', name: '세균계' , color: '#e8400a'},
1802		{ id: '2.61', parent: '1.6', name: '남조류', value: 414 , color: '#db3000'},
1803		{ id: '2.62', parent: '1.6', name: '세균류', value: 4989 , color: '#b22600'},
1804		{ id: '1.7', parent: '0.0', name: '고세균계', color: '#520314'},
1805		{ id: '2.71', parent: '1.7', name: '고세균류', value: 50 , color: '#520314'}
1806	];
1807
1808	Highcharts.chart(target, {
1809		credits: {enabled: false}
1810		,title: {
1811			text: title,
1812			align: 'left'
1813		}
1814		,subtitle: {
1815			text: subTitle,
1816			align: 'right'
1817		}
1818		,series: [{
1819			type: 'sunburst',
1820			data: data,
1821			name: '',
1822			allowTraversingTree: true,
1823			borderRadius: 3,
1824			cursor: 'pointer',
1825			legendSymbol: 'lineMarker',
1826			dataLabels: {
1827				format: '{point.name}',
1828				filter: {
1829					property: 'innerArcLength',
1830					operator: '>',
1831					value: 16
1832				}
1833			},
1834			levels: [{
1835				level: 1,
1836				levelIsConstant: true,
1837				dataLabels: {
1838					filter: {
1839						property: 'outerArcLength',
1840						operator: '>',
1841						value: 64
1842					}
1843				}
1844			}, {
1845				level: 2,
1846				colorByPoint: true
1847			},
1848				{
1849					level: 3,
1850					colorVariation: {
1851						key: 'brightness',
1852						to: -0.5
1853					}
1854				}]
1855		}]
1856	});
1857
1858
1859}
1860
1861function chartStat1(){
1862	const target = 'chart1';
1863	$('#'+ target).css('height','100%').css('width','100%');
1864
1865
1866
1867	const title = '계(Kingdom) 분류체계에 따른 생물 종 수';
1868	const subTitle = '';
1869	const categories = ['동물계','식물계','유색조식물계','균계','원생동물계','세균계','고세균계'];
1870
1871	Highcharts.chart(target, {
1872	  chart: {
1873		type: 'pie',
1874		backgroundColor: 'transparent'
1875	  },
1876	  title: {
1877		useHTML: true,
1878		text: '<span style="font-size:22px; font-weight:600;">61,230</span><br><span style="font-size:16px; color:#555;">종</span>',
1879		align: 'center',
1880		verticalAlign: 'middle',
1881		y: 10
1882	  },
1883	  subtitle: {
1884		text: title,
1885		style: { fontSize: '15px', color: '#555' },
1886		y: -250
1887	  },
1888	  tooltip: {
1889		pointFormat: '<b>{point.y:,0f}</b> 종<br>{point.percentage:.2f}%'
1890	  },
1891	  plotOptions: {
1892		pie: {
1893		  dataLabels: {
1894			enabled: true,
1895			format: '{point.percentage:.2f}%',
1896			distance: -40,
1897			style: {
1898			  color: 'white',
1899			  textOutline: 'none',
1900			  fontWeight: 'bold',
1901			  fontSize: '13px'
1902			}
1903		  },
1904		  startAngle: 0,
1905		  endAngle: 360,
1906		  center: ['50%', '50%'],
1907		  size: '90%',
1908		  innerSize: '60%'
1909		}
1910	  },
1911	  series: [{
1912		name: '생물 종 수',
1913		colorByPoint: true,
1914		colors: [
1915		  '#4F7E9D', // 동물계
1916		  '#7DBA58', // 식물계
1917		  '#79C1AF', // 유색조식물계
1918		  '#8EA5CD', // 균계
1919		  '#C78CC2', // 원생동물계
1920		  '#E58283', // 세균계
1921		  '#E8A36C'  // 고세균계
1922		],
1923		data: [
1924		  { name: '동물계', y: 34245 },
1925		  { name: '식물계', y: 8306 },
1926		  { name: '유색조식물계', y: 3366 },
1927		  { name: '균계', y: 6402 },
1928		  { name: '원생동물계', y: 2988 },
1929		  { name: '세균계', y: 5873 },
1930		  { name: '고세균계', y: 50 }
1931		]
1932	  }],
1933	  legend: {
1934		layout: 'vertical',
1935		align: 'right',
1936		verticalAlign: 'middle',
1937		itemStyle: {
1938		  fontSize: '14px',
1939		  fontWeight: '500'
1940		},
1941		labelFormatter: function() {
1942		  return this.name + ' <span style="color:#888;">' + Highcharts.numberFormat(this.y, 0) + '</span>';
1943		}
1944	  },
1945	  credits: { enabled: false }
1946	});
1947/*
1948
1949	const title = '계(Kingdom) 분류체계에 따른 생물 종 수';
1950	const subTitle = '';
1951	const categories = ['동물계','식물계','유색조식물계','균계','원생동물계','세균계','고세균계'];
1952	const color = ['#00431c', '#edb000', '#82ad6b', '#7d9199', '#c28014', '#e8400a', '#520314'];
1953	const plotOptions = {
1954		pie: {
1955			dataLabels: {
1956				enabled: true,
1957				distance: -80,
1958				style: {
1959					fontWeight: 'bold',
1960					color: 'white'
1961				}
1962			}
1963			,startAngle: -90
1964			,endAngle: 90
1965			,center: ['50%', '75%']
1966			,size: '110%'
1967		}
1968	};
1969	const series = [
1970		{
1971			name: '종수'
1972			,type: 'pie'
1973			,innerSize: '50%'
1974			,data: [
1975				{y: 50,name:'고세균계',color: '#520314'}
1976				,{y: 5403,name:'세균계',color: '#e8400a'}
1977				,{y: 2973,name:'원생동물계',color: '#c28014'}
1978				,{y: 6291,name:'균계',color: '#7d9199'}
1979				,{y: 3316,name:'유색조식물계',color: '#82ad6b'}
1980				,{y: 8284,name:'식물계',color: '#edb000'}
1981				,{y: 33693,name:'동물계',color: '#00431c'}
1982			]
1983			,dataLabels: {
1984				enabled: true,
1985				distance: -70,
1986				style: {
1987					fontWeight: 'bold',
1988					color: 'white'
1989				}
1990			},
1991		}
1992		,
1993		{
1994			name: '계분류'
1995			,type: 'pie'
1996			,innerSize: '75%'
1997			,data: [
1998				{y: 50,name:'고세균역',color: '#520314'},
1999				{y: 5403,name:'세균역',color: '#e8400a'},
2000				{y: 54557,name:'진핵생물역',color: '#82ad6b'}
2001			]
2002			,dataLabels: {
2003				enabled: true,
2004				distance: -30,
2005				style: {
2006					fontWeight: 'bold',
2007					color: 'white'
2008				}
2009			}
2010		}
2011	];
2012
2013	console.log('series',series)
2014	Highcharts.chart(target, {
2015		credits: {enabled: false}
2016		,title: {
2017			text: title,
2018			align: 'left'
2019		}
2020		,subtitle: {
2021			text: subTitle,
2022			align: 'right'
2023		}
2024		,legend: {
2025			enabled: false
2026		}
2027		,plotOptions: plotOptions
2028		,yAxis: {
2029			title: {
2030				text:'',
2031				layout: 'vertical'
2032			}
2033		}
2034		,xAxis: {
2035			categories: categories
2036		}
2037		,series: series
2038	});
2039*/
2040
2041}
2042function chartStat2(){
2043	const target = 'chart2';
2044	$('#'+ target).css('height','100%').css('width','100%');
2045	const title = '연도별 생물종 수 추이';
2046	const subTitle = '';
2047	const categories = ['2013','2014','2015','2016','2017','2018','2019','2020','2021','2022','2023'];
2048	const actualData = [0, 3.07, 5.94, 3.77, 4.31, 3.67, 3.54, 3.42, 3.34, 3.20, 3.38];
2049
2050	let cumulativeData = [];
2051	let cumulativeSum = 0;
2052	for (let i = 0; i < actualData.length; i++) {
2053		cumulativeSum += actualData[i];
2054		cumulativeData.push(cumulativeSum);
2055	}
2056
2057	const series = [
2058		{
2059			name: '계'
2060			,type: 'column'
2061			,color: '#E2E2E2'
2062			,yAxis: 1
2063			,data: [41483, 42756, 45295, 47003, 49027, 50827, 52628, 54428, 56248, 58050, 60010]
2064		},
2065		{
2066			name: '전년대비 증가율(%)'
2067			,type: 'spline'
2068			,color: '#00431c'
2069			,align: 'left'
2070			,data: cumulativeData
2071			,tooltip: {
2072				pointFormatter: function() {
2073					return '<span style="color:' + this.color + '">\u25CF</span> ' + this.series.name + ': <b>' + actualData[this.index] + '%</b><br/>';
2074				}
2075			}
2076		},
2077	];
2078	const plotOptions = {
2079		spline: {
2080			label: {
2081				// boxesToAvoid: ['bottom'],
2082				onArea: false
2083			}
2084		}
2085	};
2086
2087	Highcharts.chart(target, {
2088		credits: {enabled: false},
2089		/* chart: {
2090			zoomType: 'x'
2091		}, */
2092		title: {
2093			text: title,
2094			align: 'left'
2095		},
2096		subtitle: {
2097			text: subTitle,
2098			align: 'right'
2099		},
2100		legend: {
2101			enabled: false
2102			// align: 'left'
2103			// ,
2104			// verticalAlign: 'bottom'
2105		},
2106		plotOptions: plotOptions,
2107		yAxis: [{
2108			title: {
2109				text:'',
2110				layout: 'vertical'
2111			},
2112			max: 40
2113		},
2114			{
2115				title: {
2116					text:'',
2117					layout: 'vertical'
2118				},
2119				//max: 58100
2120			}],
2121		xAxis: {
2122			categories: categories
2123		},
2124		series:series
2125	});
2126}
2127
2128function chartStat3(){
2129	const target = 'chart3';
2130	$('#'+ target).css('height','100%').css('width','100%');
2131	const title = '계(Kingdom) 분류체계에 따른 연도별 생물종 수 추이';
2132	const subTitle = '';
2133	const categories = ['2013','2014','2015','2016','2017','2018','2019','2020','2021','2022','2023'];
2134	const color = ['#808080','#00431c','#edb000','#82ad6b','#7d9199','#c28014','#e8400a'];
2135	const series = [
2136		// {
2137		// 	name: '계'
2138		// 	,type: 'column'
2139		// 	,color: '#E2E2E2'
2140		// 	,yAxis: 1
2141		// 	,data: [41483,42756,45295,47003,49027,50827,52628,54328,56248,58050,60010]
2142		// },
2143		{
2144			name: '동물계'
2145			,type: 'spline'
2146			,color: '#00431c'
2147			,align: 'left'
2148			,data: [24511,25453,26575,27468,28639,29678,30675,31367,32273,32941,33693]
2149		},
2150		{
2151			name: '식물계'
2152			,type: 'spline'
2153			,color: '#edb000'
2154			,data: [7331,7359,7616,7688,7782,7833,7926,8006,8156,8193,8284]
2155		},
2156		{
2157			name: '유색조식물계'
2158			,type: 'spline'
2159			,color: '#82ad6b'
2160			,data: [2391,2391,2788,2852,2879,2951,3018,3092,3156,3211,3316]
2161		},
2162		{
2163			name: '균계'
2164			,type: 'spline'
2165			,color: '#7d9199'
2166			,data: [4153,4346,4686,4840,5056,5226,5421,5616,5816,6116,6291]
2167		},
2168		{
2169			name: '원생동물계'
2170			,type: 'spline'
2171			,color: '#c28014'
2172			,data: [1799,1799,1918,2098,2243,2337,2372,2630,2845,2883,2973]
2173		},
2174		{
2175			name: '세균계'
2176			,type: 'spline'
2177			,color: '#e8400a'
2178			,data: [1293,1401,1702,2046,2417,2785,3198,3595,3979,4682,5403]
2179		},
2180		{
2181			name: '고세균계'
2182			,type: 'line'
2183			,color: '#520314'
2184			,dataLabels: {
2185				// position: 'left'
2186				align: 'left'
2187				,varticalAlign: 'bottom'
2188				,x:-100
2189			}
2190			,data: [5,7,10,11,11,17,18,22,23,24,50]
2191		}
2192	];
2193	const plotOptions = {
2194		spline: {
2195			label: {
2196				// boxesToAvoid: ['bottom'],
2197				onArea: false
2198			}
2199		}
2200	};
2201
2202	Highcharts.chart(target, {
2203		credits: {enabled: false},
2204		/* chart: {
2205			zoomType: 'x'
2206		}, */
2207		title: {
2208			text: title,
2209			align: 'left'
2210		},
2211		subtitle: {
2212			text: subTitle,
2213			align: 'right'
2214		},
2215		legend: {
2216			enabled: false
2217			// align: 'left'
2218			// ,
2219			// verticalAlign: 'bottom'
2220		},
2221		plotOptions: plotOptions,
2222		yAxis: [{
2223			title: {
2224				text:'',
2225				layout: 'vertical'
2226			},
2227			max: 35000
2228		},
2229			{
2230				title: {
2231					text:'',
2232					layout: 'vertical'
2233				},
2234				max: 58100
2235			}],
2236		xAxis: {
2237			categories: categories
2238		},
2239		series:series
2240	});
2241}
2242function chartStat4(){
2243	const target = 'chart4';
2244	$('#'+ target).css('height','100%').css('width','100%');
2245	const title = '분류계급별 분류군 수';
2246	const subTitle = '';
2247	const categories = ['동물계','식물계','유색조식물계','균계','원생동물계','세균계','고세균계'];
2248	// const color = ['#00431c','#edb000','#82ad6b','#7d9199','#c28014','#e8400a','#520314'];
2249	const color = [];
2250	const series = [
2251		{
2252			name: '문'
2253			,type: 'column'
2254			,color: '#00431c'
2255			,data: [
2256				{y: 30,name:'동물계'}
2257				,{y: 10,name:'식물계'}
2258				,{y: 6,name:'유색조식물계'}
2259				,{y: 10,name:'균계'}
2260				,{y: 20,name:'원생동물계'}
2261				,{y: 15,name:'세균계'}
2262				,{y: 2,name:'고세균계'}
2263			]
2264		},
2265		{
2266			name: '문합계'
2267			,type: 'pie'
2268			,data: [
2269				{y: 82,name:'문',color: '#e0e9e5'
2270					, dataLabels:{
2271						enabled: true,
2272						format: '{point.total}문',
2273						distance: -30,
2274					}
2275				}
2276			],
2277			center : ["20%", "5%"],
2278			size: 60,
2279			showInLegend: false,
2280			dataLabels: {
2281				enabled: false
2282			}
2283
2284		},
2285		{
2286			name: '강'
2287			,type: 'column'
2288			,color: '#e8400a'
2289			,data: [
2290				{y: 77,name:'동물계'}
2291				,{y: 34,name:'식물계'}
2292				,{y: 16,name:'유색조식물계'}
2293				,{y: 37,name:'균계'}
2294				,{y: 63,name:'원생동물계'}
2295				,{y: 34,name:'세균계'}
2296				,{y: 5,name:'고세균계'}
2297			]
2298		},
2299		{
2300			name: '강합계'
2301			,type: 'pie'
2302			,data: [
2303				{y: 259,name:'강',color: '#e0e9e5'
2304					, dataLabels:{
2305						enabled: true,
2306						format: '{point.total}강',
2307						distance: -30,
2308					}
2309				}
2310			],
2311			center : ["95%", "5%"],
2312			size: 60,
2313			showInLegend: false,
2314			dataLabels: {
2315				enabled: false
2316			}
2317		}
2318	];
2319	const plotOptions = {
2320		spline: {
2321			label: {
2322				// boxesToAvoid: ['bottom'],
2323				onArea: false
2324			}
2325		}
2326	};
2327
2328	Highcharts.chart(target, {
2329		credits: {enabled: false},
2330		/* chart: {
2331			zoomType: 'x'
2332		}, */
2333		title: {
2334			text: title,
2335			align: 'left'
2336		},
2337		subtitle: {
2338			text: subTitle,
2339			align: 'right'
2340		},
2341		plotOptions: plotOptions,
2342		yAxis: {
2343			title: {
2344				text:'',
2345				layout: 'vertical'
2346			},
2347			max:80,
2348			min:2
2349		},
2350		xAxis: {
2351			categories: categories
2352			//,angle: 45
2353		},
2354		series:series
2355	});
2356}
2357function chartStat5(){
2358	const target = 'chart5';
2359	$('#'+ target).css('height','100%').css('width','100%');
2360	const title = '계(Kingdom)별 고유종 수';
2361	const subTitle = '';
2362	const series = [
2363		{
2364			name: '자생생물 종 수'
2365			,data:[
2366				{y: 33693,name:'동물계',color: '#00431c'}
2367				,{y: 8284,name:'식물계',color: '#edb000'}
2368				,{y: 3316,name:'유색조식물계',color: '#82ad6b'}
2369				,{y: 6291,name:'균계',color: '#7d9199'}
2370				,{y: 2973,name:'원생동물계',color: '#c28014'}
2371				,{y: 5403,name:'세균계',color: '#e8400a'}
2372				,{y: 50,name:'고세균계',color: '#520314'}
2373				,{y: 60010,name:'전체',color: '#000000'}
2374			],
2375			index:1
2376		},
2377		{
2378			name: '고유종 수'
2379			,data:[
2380				{y: 1888,name:'동물계',color: '#00431c', dataLabels:{borderColor:'#00431c'}}
2381				,{y: 406,name:'식물계',color: '#edb000', dataLabels:{borderColor:'#edb000'}}
2382				,{y: 3,name:'유색조식물계',color: '#82ad6b', dataLabels:{borderColor:'#82ad6b'}}
2383				,{y: 52,name:'균계',color: '#7d9199', dataLabels:{borderColor:'#7d9199'}}
2384				,{y: 6,name:'원생동물계',color: '#c28014', dataLabels:{borderColor:'#c28014'}}
2385				,{y: 0,name:'세균계',color: '#e8400a', dataLabels:{borderColor:'#e8400a'}}
2386				,{y: 0,name:'고세균계',color: '#520314', dataLabels:{borderColor:'#520314'}}
2387				,{y: 2355,name:'전체',color: '#000000', dataLabels:{borderColor:'#000000'}}
2388			],
2389			dataLabels:{
2390				backgroundColor: '#FFFFFF'
2391			},
2392			index:2
2393		}
2394		,{
2395			name: '고유종 비율(%)'
2396			,data:[
2397				{y: 5.60,name:'동물계',color: '#00431c'}
2398				,{y: 4.90,name:'식물계',color: '#edb000'}
2399				,{y: 0.09,name:'유색조식물계',color: '#82ad6b'}
2400				,{y: 0.83,name:'균계',color: '#7d9199'}
2401				,{y: 0.20,name:'원생동물계',color: '#c28014'}
2402				,{y: 0,name:'세균계',color: '#e8400a'}
2403				,{y: 0,name:'고세균계',color: '#520314'}
2404				,{y: 3.92,name:'전체',color: '#000000'}
2405			],
2406			dataLabels:{
2407				align:'right',
2408				x:0,
2409				format: '{point.y}%'
2410			},
2411			index:3
2412		},
2413	];
2414
2415	Highcharts.chart(target, {
2416		credits: {enabled: false},
2417		chart: {
2418			type: 'bar'
2419		},
2420		title: {
2421			text: title,
2422			align: 'left'
2423		},
2424		subtitle: {
2425			text: subTitle,
2426			align: 'right'
2427		},
2428		xAxis: {
2429			categories: ['동물계', '식물계', '유색조식물계', '균계', '원생동물계', '세균계', '고세균계', '전체']
2430			,reversedStacks: true
2431		},
2432		yAxis:{
2433			visible:false
2434		},
2435		legend:{
2436			enabled:false
2437		},
2438		plotOptions: {
2439			series: {
2440				stacking: 'normal',
2441				dataLabels: {
2442					enabled: true
2443				}
2444			}
2445		},
2446		series:series
2447	});
2448}
2449
2450function chartStat6(){
2451	const target = 'chart6';
2452	$('#'+ target).css('height','100%').css('width','100%');
2453	const title = '세부분류군별 고유종 수';
2454	const subTitle = '';
2455	const series = [
2456		{
2457			name: '자생생물 종 수'
2458			,data:[
2459				{y: 125,name:'포유류',color: '#177540'},
2460				{y: 552,name:'조류',color: '#42a86e'},
2461				{y: 36,name:'파충류',color: '#ccffe0'},
2462				{y: 28,name:'양서류',color: '#ccffe0'},
2463				{y: 1349,name:'어류',color: '#00431c'},
2464				{y: 139,name:'미삭동물류',color: '#00c252'},
2465				{y: 10754,name:'무척추동물류(곤충류 제외)',color: '#009940'},
2466				{y: 20710,name:'곤충류',color: '#00702e'},
2467				{y: 4641,name:'관속식물류',color: '#edb000'},
2468				{y: 1118,name:'선태류',color: '#d69900'},
2469				{y: 1001,name:'윤조류',color: '#ad7d00'},
2470				{y: 854,name:'녹조류',color: '#855e00'},
2471				{y: 670,name:'홍조류',color: '#5c4200'},
2472				{y: 2323,name:'돌말류',color: '#a3db87'},
2473				{y: 544,name:'와편모조류',color: '#47613d'},
2474				{y: 417,name:'대롱편모조류',color: '#668a54'},
2475				{y: 17,name:'은편모조류',color: '#293824'},
2476				{y: 13,name:'착편모조류',color: '#293824'},
2477				{y: 2,name:'황적조류',color: '#293824'},
2478				{y: 5054,name:'균류',color: '#a3bdc7'},
2479				{y: 1237,name:'지의류',color: '#617075'},
2480				{y: 2575,name:'원생동물류',color: '#f79e00'},
2481				{y: 398,name:'유글레나조류',color: '#617075'},
2482				{y: 414,name:'남조류',color: '#db3000'},
2483				{y: 4989,name:'세균류',color: '#b22600'},
2484				{y: 50,name:'고세균류',color: '#520314'}
2485			],
2486			index:1
2487		},
2488		{
2489			name: '고유종 수'
2490			,data:[
2491				{y: 1,name:'포유류',color: '#177540'},
2492				{y: 1,name:'조류',color: '#42a86e'},
2493				{y: 0,name:'파충류',color: '#ccffe0'},
2494				{y: 7,name:'양서류',color: '#ccffe0'},
2495				{y: 68,name:'어류',color: '#00431c'},
2496				{y: 1,name:'미삭동물류',color: '#00c252'},
2497				{y: 639,name:'무척추동물류(곤충류 제외)',color: '#009940'},
2498				{y: 1171,name:'곤충류',color: '#00702e'},
2499				{y: 376,name:'관속식물류',color: '#edb000'},
2500				{y: 0,name:'선태류',color: '#d69900'},
2501				{y: 0,name:'윤조류',color: '#ad7d00'},
2502				{y: 3,name:'녹조류',color: '#855e00'},
2503				{y: 27,name:'홍조류',color: '#5c4200'},
2504				{y: 0,name:'돌말류',color: '#a3db87'},
2505				{y: 0,name:'와편모조류',color: '#47613d'},
2506				{y: 3,name:'대롱편모조류',color: '#668a54'},
2507				{y: 0,name:'은편모조류',color: '#293824'},
2508				{y: 0,name:'착편모조류',color: '#293824'},
2509				{y: 0,name:'황적조류',color: '#293824'},
2510				{y: 34,name:'균류',color: '#a3bdc7'},
2511				{y: 18,name:'지의류',color: '#617075'},
2512				{y: 6,name:'원생동물류',color: '#f79e00'},
2513				{y: 0,name:'유글레나조류',color: '#617075'},
2514				{y: 0,name:'남조류',color: '#db3000'},
2515				{y: 0,name:'세균류',color: '#b22600'},
2516				{y: 0,name:'고세균류',color: '#520314'}
2517			],
2518			dataLabels:{
2519				backgroundColor: '#FFFFFF'
2520			},
2521			index:2
2522		}
2523		,{
2524			name: '고유종 비율(%)'
2525			,data:[
2526				{y: 0.80,name:'포유류',color: '#177540'},
2527				{y: 0.18,name:'조류',color: '#42a86e'},
2528				{y: 0,name:'파충류',color: '#ccffe0'},
2529				{y: 25.00,name:'양서류',color: '#ccffe0'},
2530				{y: 5.04,name:'어류',color: '#00431c'},
2531				{y: 0.72,name:'미삭동물류',color: '#00c252'},
2532				{y: 5.94,name:'무척추동물류(곤충류 제외)',color: '#009940'},
2533				{y: 5.65,name:'곤충류',color: '#00702e'},
2534				{y: 8.10,name:'관속식물류',color: '#edb000'},
2535				{y: 0,name:'선태류',color: '#d69900'},
2536				{y: 0,name:'윤조류',color: '#ad7d00'},
2537				{y: 0.35,name:'녹조류',color: '#855e00'},
2538				{y: 4.03,name:'홍조류',color: '#5c4200'},
2539				{y: 0,name:'돌말류',color: '#a3db87'},
2540				{y: 0,name:'와편모조류',color: '#47613d'},
2541				{y: 0.72,name:'대롱편모조류',color: '#668a54'},
2542				{y: 0,name:'은편모조류',color: '#293824'},
2543				{y: 0,name:'착편모조류',color: '#293824'},
2544				{y: 0,name:'황적조류',color: '#293824'},
2545				{y: 0.67,name:'균류',color: '#a3bdc7'},
2546				{y: 1.46,name:'지의류',color: '#617075'},
2547				{y: 0.23,name:'원생동물류',color: '#f79e00'},
2548				{y: 0,name:'유글레나조류',color: '#617075'},
2549				{y: 0,name:'남조류',color: '#db3000'},
2550				{y: 0,name:'세균류',color: '#b22600'},
2551				{y: 0,name:'고세균류',color: '#520314'}
2552			],
2553			dataLabels:{
2554				align:'right',
2555				x:0,
2556				format: '{point.y}%'
2557			},
2558			index:3
2559		},
2560	];
2561
2562	Highcharts.chart(target, {
2563		credits: {enabled: false},
2564		chart: {
2565			type: 'bar'
2566		},
2567		title: {
2568			text: title,
2569			align: 'left'
2570		},
2571		subtitle: {
2572			text: subTitle,
2573			align: 'right'
2574		},
2575		xAxis: {
2576			categories: ['포유류','조류','파충류','양서류','어류','미삭동물류','무척추동물류(곤충류 제외)','곤충류','관속식물류','선태류','윤조류','녹조류'
2577				,'홍조류','돌말류','와편모조류','대롱편모조류','은편모조류','착편모조류','황적조류','균류','지의류','원생동물류','유글레나조류','남조류','세균류','고세균류']
2578		},
2579		yAxis:{
2580			visible:false
2581		},
2582		legend:{
2583			enabled:false
2584		},
2585		plotOptions: {
2586			series: {
2587				stacking: 'normal',
2588				dataLabels: {
2589					enabled: true
2590				}
2591			}
2592		},
2593		series:series
2594	});
2595}
2596
2597function mergeDataWithColors(data, colors) {
2598	return data.map((value, index) => {
2599		return { y: value, color: colors[index % colors.length] };
2600	});
2601}
2602
2603// chart 1-1
2604function chart1_1StatMix(chartId){
2605	const chartInfo = getChartInfo(chartId);
2606	const target = chartId;
2607	$('#'+ target).css('height','100%').css('width','100%');
2608	const title = chartInfo.chartTitle;
2609	const subTitle = '';
2610	let maxVal = 0;
2611	let maxValSum = 0;
2612	let size = 0;
2613	let distance = 0;
2614
2615	let categories = [];
2616	let series = [];
2617	let colors = [];
2618	let center = [];
2619	let totalCnt = 0;
2620
2621	for(dataGrp of chartInfo.dataGrpList){
2622		//console.log(dataGrp);
2623		if(categories.length == 0){
2624			categories = dataGrp.labelList;
2625		}
2626		let data;
2627
2628		if(dataGrp.chartDataGrpId == 'I101-1'){
2629			for(var i=0; i < dataGrp.chartDataList.length; i++) {
2630				colors.push(dataGrp.chartDataList[i].chartColor);
2631				totalCnt += dataGrp.chartDataList[i].chartData;
2632			}
2633			// bar
2634			data = {
2635				name: dataGrp.chartDataTitle
2636				,type: 'bar'
2637				,data: dataGrp.dataList
2638			};
2639
2640			const originalData = data;
2641			const transformedData = {
2642				...originalData,
2643				data: mergeDataWithColors(originalData.data, colors),
2644				showInLegend: false
2645			};
2646			data = transformedData;
2647		}else if(dataGrp.chartDataGrpId == 'I101-2' || dataGrp.chartDataGrpId == 'I101-3' || dataGrp.chartDataGrpId == 'I101-4' || dataGrp.chartDataGrpId == 'I101-5' ||
2648				dataGrp.chartDataGrpId == 'I101-6' || dataGrp.chartDataGrpId == 'I101-7' || dataGrp.chartDataGrpId == 'I101-8'){
2649			// pie
2650			if(dataGrp.chartDataGrpId == 'I101-2') { center = ["90%","5%"]; size = 80; distance = -40; }
2651			else if(dataGrp.chartDataGrpId == 'I101-3') { center = ["90%","40%"]; size = 80; distance = -40; }
2652			else if(dataGrp.chartDataGrpId == 'I101-4') { center = ["90%","60%"]; size = 80; distance = -40; }
2653			else if(dataGrp.chartDataGrpId == 'I101-5') { center = ["90%","78%"]; size = 60; distance = -30; }
2654			else if(dataGrp.chartDataGrpId == 'I101-6') { center = ["90%","86%"]; size = 60; distance = -30; }
2655			else if(dataGrp.chartDataGrpId == 'I101-7') { center = ["90%","94%"]; size = 60; distance = -30; }
2656			else if(dataGrp.chartDataGrpId == 'I101-8') { center = ["90%","101%"]; size = 40; distance = -20; }
2657			
2658			data = {
2659				name: dataGrp.chartDataTitle
2660				,type: 'pie'
2661				,data: [
2662					{
2663						y: dataGrp.dataList[0],
2664						name: dataGrp.labelList[0],
2665						color: dataGrp.chartDataList[0].chartColor
2666					}
2667				]
2668				,center : center
2669				,size: size
2670				,showInLegend: false
2671				,dataLabels: {
2672					enabled: true,
2673					distance: distance,
2674					// formatter: function() {
2675					// 	const percentage = ((this.y / totalCnt) * 100).toFixed(2);
2676					// 	return `<div style="white-space: nowrap;text-align:center;margin-top:60px;">${this.series.name}<br/>${numberWithCommas(this.y)}종<br/>${percentage}%</div>`;
2677					// },
2678					formatter: function() {
2679						const percentage = ((this.y / totalCnt) * 100).toFixed(2);
2680						return `${this.series.name}<br/>${numberWithCommas(this.y)}종<br/>${percentage}%`;
2681					},
2682					align: 'center',
2683					verticalAlign: 'middle',
2684					style: {
2685						fontSize: '11px',
2686						fontWeight: 'bold'
2687					},
2688					// filter: {
2689					// 	property: 'percentage',
2690					// 	operator: '>',
2691					// 	value: 4
2692					// }
2693				}
2694			};
2695		}
2696		series.push(data);
2697	}
2698
2699	const plotOptions = {
2700		series: {
2701			states: {
2702				hover: {
2703					enabled: false // hover 비활성화
2704				},
2705				inactive: {
2706					enabled: false // 비활성화 상태 비활성화
2707				}
2708			},
2709			point: {
2710				events: {
2711					mouseOver: function() {
2712						return false; // 마우스 오버 이벤트 비활성화
2713					},
2714					click: function() {
2715						return false; // 클릭 이벤트 비활성화
2716					}
2717				}
2718			}
2719		},
2720		bar: {
2721			dataLabels: {
2722				enabled: true,
2723				formatter: function() {
2724					const percentage = ((this.y / totalCnt) * 100).toFixed(2);
2725					return `${numberWithCommas(this.y)} (${percentage}%)`; // 데이터 값 및 비율 표시
2726				},
2727				align: 'left',
2728				verticalAlign: 'middle',
2729				inside: true,
2730				x: 5,
2731				y: 0
2732			}
2733		}
2734	};
2735
2736	Highcharts.chart(target, {
2737		credits: {enabled: false},
2738		/* chart: {
2739			zoomType: 'x'
2740		}, */
2741		title: {
2742			text: title,
2743			align: 'left'
2744		},
2745		subtitle: {
2746			text: `<span style="font-size:1.3em;font-weight:bold;">${numberWithCommas(totalCnt)}</span><span style="font-size:0.9em;">종</span> (단위: 종) `,
2747			align: 'right',
2748			verticalAlign: 'top',
2749			y: 30
2750		},
2751		plotOptions: plotOptions,
2752		yAxis: {
2753			type: 'logarithmic',
2754			title: {
2755				text:'',
2756				layout: 'vertical'
2757			},
2758		},
2759		xAxis: {
2760			categories: categories,
2761			labels: {
2762				style: {
2763					textOverflow: 'ellipsis',
2764					whiteSpace: 'nowrap',
2765					overflow: 'hidden',
2766					width: '100px',
2767					display: 'block'
2768				}
2769			}
2770		},
2771		series:series
2772	});
2773}
2774
2775// chart 1-2
2776function chart1_2StatMix(chartId){
2777	const chartInfo = getChartInfo(chartId);
2778	const target = chartId;
2779
2780	$('#'+ target).css({ height:'100%', width:'100%' });
2781
2782	const title = chartInfo.chartTitle;
2783	let totalCnt = 0;
2784	let series = [];
2785
2786	for (const dataGrp of chartInfo.dataGrpList) {
2787		// pie1 (하나만 사용)
2788		if (dataGrp.chartDataGrpId === 'I102-1') {
2789			const data = dataGrp.chartDataList.map((_, i) => {
2790				totalCnt += dataGrp.dataList[i];
2791				return {
2792					y: dataGrp.dataList[i],
2793					name: dataGrp.labelList[i]
2794				};
2795			});
2796
2797			series.push({
2798				name: dataGrp.chartDataTitle,
2799				type: 'pie',
2800				colorByPoint: true,
2801				size: '80%',
2802				innerSize: '70%',
2803				data: data,
2804				colors: [
2805					'#E8A36C', // 고세균계
2806					'#E58283', // 세균계
2807					'#C78CC2', // 원생동물계
2808					'#8EA5CD', // 균계
2809					'#79C1AF', // 유색조식물계
2810					'#7DBA58', // 식물계
2811					'#4F7E9D'  // 동물계
2812				],
2813				dataLabels: {
2814					enabled: true,
2815					distance: -54,
2816					format: '{point.name}<br/>{point.y:,.0f}<br/>{point.percentage:.1f}%',
2817					style: {
2818						fontSize: '11px',
2819						fontWeight: 'bold'
2820					}
2821				}
2822			});
2823		}
2824	}
2825
2826	const plotOptions = {
2827		series: {
2828			states: {
2829				hover: { enabled: false },
2830				inactive: { enabled: false }
2831			},
2832			point: {
2833				events: {
2834					mouseOver: () => false,
2835					click: () => false
2836				}
2837			}
2838		},
2839		pie: {
2840			allowPointSelect: false,
2841			cursor: 'default',
2842			borderRadius: 8,
2843			showInLegend: true
2844		}
2845	};
2846
2847	Highcharts.chart(target, {
2848		chart: {
2849			type: 'pie',
2850			backgroundColor: 'transparent'
2851		},
2852		credits: { enabled: false },
2853		accessibility: { enabled: false },
2854		yAxis: { // "Values" 라벨 제거
2855			title: { text: null }
2856		},
2857		title: {
2858			text: title,
2859			align: 'left'
2860		},
2861		subtitle: {
2862			//useHTML: true,
2863			text: `<span style="font-size:2.6em;font-weight:bold;">${numberWithCommas(totalCnt)}</span><span style="font-size:1.8em;"> 종</span>`,
2864			align: 'center',
2865			verticalAlign: 'middle',
2866			x: 40,
2867			y: 110
2868		},
2869		plotOptions: plotOptions,
2870		legend: {
2871			enabled: false
2872		},
2873		series: series
2874	});
2875}
2876
2877// chart 1-3
2878function chart1_3StatMix(chartId){
2879	const chartInfo = getChartInfo(chartId);
2880	const target = chartId;
2881	$('#'+ target).css('height','100%').css('width','100%');
2882	const title = chartInfo.chartTitle;
2883	const subTitle = '(단위: 종)';
2884	let maxVal = 0;
2885	let maxValSum = 0;
2886
2887	let categories = [];
2888	let series = [];
2889
2890	for(dataGrp of chartInfo.dataGrpList){
2891		//console.log(dataGrp);
2892		if(categories.length == 0){
2893			categories = dataGrp.labelList;
2894		}
2895		let data;
2896		// column
2897		if(dataGrp.chartDataGrpId == 'I103-1'){
2898			data = {
2899				name: dataGrp.chartDataTitle
2900				,type: 'column'
2901				,color: '#E2E2E2'
2902				,data: dataGrp.dataList
2903				,yAxis: 1
2904			};
2905			for(dt of dataGrp.dataList){
2906				if(maxVal < dt){
2907					maxVal = dt;
2908				}
2909			}
2910		}else if(dataGrp.chartDataGrpId == 'I103-2'){
2911			// line
2912			data = {
2913				name: dataGrp.chartDataTitle
2914				,type: 'line'
2915				,color: '#00431c'
2916				,label:{
2917					enabled: false
2918				}
2919				,data: dataGrp.dataList
2920			};
2921			for(dt of dataGrp.dataList){
2922				if(maxValSum < dt){
2923					maxValSum = dt;
2924				}
2925			}
2926		}
2927		series.push(data);
2928	}
2929
2930	const plotOptions = {
2931		series: {
2932			states: {
2933				hover: {
2934					enabled: false // hover 비활성화
2935				},
2936				inactive: {
2937					enabled: false // 비활성화 상태 비활성화
2938				}
2939			},
2940			point: {
2941				events: {
2942					mouseOver: function() {
2943						return false; // 마우스 오버 이벤트 비활성화
2944					},
2945					click: function() {
2946						return false; // 클릭 이벤트 비활성화
2947					}
2948				}
2949			}
2950		},
2951		column: {
2952			dataLabels: {
2953				enabled: true
2954				,y: 150
2955			}
2956		},
2957		line: {
2958			dataLabels: {
2959				enabled: true
2960			},
2961		}
2962	};
2963	Highcharts.chart(target, {
2964		credits: {enabled: false}
2965		,title: {
2966			text: title,
2967			align: 'left'
2968		}
2969		,subtitle: {
2970			text: subTitle,
2971			align: 'right'
2972		}
2973		,plotOptions: plotOptions
2974		,yAxis: [{
2975			title: {
2976				text:'',
2977				layout: 'vertical',
2978				align: 'right'
2979			},
2980			max : maxValSum
2981		},
2982			{
2983				title: {
2984					text:'',
2985					layout: 'vertical'
2986				},
2987				max : maxVal
2988			}]
2989		,xAxis: {
2990			categories: categories
2991		}
2992		,series: series
2993	});
2994}
2995
2996// chart 1-5
2997function chart1_5StatMix(chartId){
2998	const chartInfo = getChartInfo(chartId);
2999	const target = chartId;
3000	$('#'+ target).css('height','100%').css('width','100%');
3001	const title = chartInfo.chartTitle;
3002	const subTitle = '';
3003	let maxVal = 0;
3004	let maxValSum = 0;
3005
3006	let categories = [];
3007	let series = [];
3008
3009	for(dataGrp of chartInfo.dataGrpList){
3010		//console.log(dataGrp);
3011		if(categories.length == 0){
3012			categories = dataGrp.labelList;
3013		}
3014		let data;
3015
3016		if(dataGrp.chartDataGrpId == 'I105-1' || dataGrp.chartDataGrpId == 'I105-3'){
3017			// column
3018			let color =  (dataGrp.chartDataGrpId === 'I105-1' ? "#00431c" : "#e8400a");
3019			data = {
3020				name: dataGrp.chartDataTitle
3021				,type: 'column'
3022				,color: color
3023				,data: dataGrp.dataList
3024			};
3025		}else if(dataGrp.chartDataGrpId == 'I105-2' || dataGrp.chartDataGrpId == 'I105-4'){
3026			// pie
3027			data = {
3028				name: dataGrp.chartDataTitle
3029				,type: 'pie'
3030				,data: [
3031					{
3032						y: dataGrp.dataList[0],
3033						name: dataGrp.chartDataGrpId == 'I105-2' ? "문" : "강",
3034						color: '#e0e9e5',
3035						dataLabels: {
3036							enabled: true,
3037							format: dataGrp.chartDataGrpId == 'I105-2' ? '{point.total}문' : '{point.total}강',
3038							distance: -30,
3039						}
3040					}
3041				]
3042				,center : dataGrp.chartDataGrpId == 'I105-2' ? ["20%", "5%"] : ["95%", "5%"]
3043				,size: 60
3044				,showInLegend: false
3045				,dataLabels: {
3046					enabled: false
3047				}
3048			};
3049		}
3050		series.push(data);
3051	}
3052
3053	const plotOptions = {
3054		column: {
3055			dataLabels: {
3056				enabled: true
3057				,y: 150
3058			}
3059		},
3060	};
3061
3062	Highcharts.chart(target, {
3063		credits: {enabled: false},
3064		/* chart: {
3065			zoomType: 'x'
3066		}, */
3067		title: {
3068			text: title,
3069			align: 'left'
3070		},
3071		subtitle: {
3072			text: subTitle,
3073			align: 'right'
3074		},
3075		plotOptions: plotOptions,
3076		yAxis: {
3077			title: {
3078				text:'',
3079				layout: 'vertical'
3080			},
3081			max:80,
3082			min:2
3083		},
3084		xAxis: {
3085			categories: categories,
3086			labels: {
3087				style: {
3088					whiteSpace: 'nowrap',
3089					textOverflow: 'ellipsis',
3090					overflow: 'hidden',
3091					width: '60px'
3092				},
3093			},
3094			//,angle: 45
3095		},
3096		series:series
3097	});
3098}
3099
3100//chart 4
3101function chart4StatMix(chartId){
3102	const chartInfo = getChartInfo(chartId);
3103	const target = chartId;
3104	$('#'+ target).css('height','100%').css('width','100%');
3105	const title = chartInfo.chartTitle;
3106	const subTitle = '';
3107	let maxVal = 0;
3108	let maxValSum = 0;
3109
3110	let categories = [];
3111	let series = [];
3112
3113	for(dataGrp of chartInfo.dataGrpList){
3114		//console.log(dataGrp);
3115		if(categories.size == 0){
3116			categories = dataGrp.labelList;
3117		}
3118		let data;
3119		// column
3120		if(dataGrp.chartDataGrpId == 'I511-1' || dataGrp.chartDataGrpId == 'I550-2'){
3121			data = {
3122				name: dataGrp.chartDataTitle
3123				,type: 'column'
3124				,color: '#E2E2E2'
3125				,data: dataGrp.dataList
3126				,yAxis: 1
3127			};
3128			for(dt of dataGrp.dataList){
3129				if(maxValSum < dt){
3130					maxValSum = dt;
3131				}
3132			}
3133		}else if(dataGrp.chartDataGrpId == 'I511-2' || dataGrp.chartDataGrpId == 'I550-1'){
3134			// line
3135			data = {
3136				name: dataGrp.chartDataTitle
3137				,type: 'line'
3138				,color: '#00431c'
3139				,label:{
3140					enabled: false
3141				}
3142				,data: dataGrp.dataList
3143			};
3144			for(dt of dataGrp.dataList){
3145				if(maxVal < dt){
3146					maxVal = dt;
3147				}
3148			}
3149		}
3150		series.push(data);
3151	}
3152
3153	const plotOptions = {
3154		column: {
3155			dataLabels: {
3156				enabled: true
3157				,y: 150
3158			}
3159		}
3160	};
3161	Highcharts.chart(target, {
3162		credits: {enabled: false}
3163		,title: {
3164			text: title,
3165			align: 'left'
3166		}
3167		,subtitle: {
3168			text: subTitle,
3169			align: 'right'
3170		}
3171		,plotOptions: plotOptions
3172		,yAxis: [{
3173			title: {
3174				text:'',
3175				layout: 'vertical',
3176				align: 'right'
3177			},
3178			max : maxVal
3179		},
3180			{
3181				title: {
3182					text:'',
3183					layout: 'vertical'
3184				},
3185				max : maxVal
3186			}]
3187		,xAxis: {
3188			categories: categories
3189		}
3190		,series: series
3191	});
3192}
3193
3194// chart 5
3195function chart5StatMix(chartId){
3196	const chartInfo = getChartInfo(chartId);
3197	const target = chartId;
3198	$('#'+ target).css('height','100%').css('width','100%');
3199	const title = chartInfo.chartTitle;
3200//	const subTitle = '(단위: 종)';
3201	const subTitle = '';
3202	let maxVal = 0;
3203	let maxValSum = 0;
3204
3205	let categories = [];
3206	let series = [];
3207
3208	for(dataGrp of chartInfo.dataGrpList){
3209		//console.log(dataGrp);
3210		if(categories.length == 0){
3211			categories = dataGrp.labelList;
3212		}
3213		let data;
3214		// column
3215		if(dataGrp.chartDataGrpId == 'I511-1' || dataGrp.chartDataGrpId == 'I550-2'){
3216			data = {
3217				name: dataGrp.chartDataTitle
3218				,type: 'column'
3219				//,color: '#E2E2E2'
3220				,color: dataGrp.chartDataList[0].chartColor
3221				,data: dataGrp.dataList
3222				,yAxis: 1
3223			};
3224			for(dt of dataGrp.dataList){
3225				if(maxVal < dt){
3226					maxVal = dt;
3227				}
3228			}
3229		}else if(dataGrp.chartDataGrpId == 'I511-2' || dataGrp.chartDataGrpId == 'I550-1'){
3230			// line
3231			data = {
3232				name: dataGrp.chartDataTitle
3233				,type: 'line'
3234				//,color: '#00431c'
3235				,color: dataGrp.chartDataList[0].chartColor
3236				,label:{
3237					enabled: false
3238				}
3239				,data: dataGrp.dataList
3240			};
3241			for(dt of dataGrp.dataList){
3242				if(maxValSum < dt){
3243					maxValSum = dt;
3244				}
3245			}
3246		}
3247		series.push(data);
3248	}
3249
3250	const plotOptions = {
3251		column: {
3252			dataLabels: {
3253				enabled: true
3254				,y: 150
3255			}
3256		},
3257		line: {
3258			dataLabels: {
3259				enabled: true
3260			},
3261		}
3262	};
3263	Highcharts.chart(target, {
3264		credits: {enabled: false}
3265		,title: {
3266			text: title,
3267			align: 'left'
3268		}
3269		,subtitle: {
3270			text: subTitle,
3271			align: 'right'
3272		}
3273		,plotOptions: plotOptions
3274		,yAxis: [{
3275			title: {
3276				text:'',
3277				layout: 'vertical',
3278				align: 'right'
3279			},
3280			max : maxValSum
3281		},
3282			{
3283				title: {
3284					text:'',
3285					layout: 'vertical'
3286				},
3287				max : maxVal
3288			}]
3289		,xAxis: {
3290			categories: categories
3291		}
3292		,series: series
3293	});
3294}
3295
3296// chart 6-1
3297function chart6_1StatMix(chartId){
3298	const chartInfo = getChartInfo(chartId);
3299	const target = chartId;
3300
3301	$('#'+ target).css({ height:'100%', width:'100%' });
3302
3303	const title = chartInfo.chartTitle;
3304	let totalCnt = 0;
3305	let series = [];
3306	for (const dataGrp of chartInfo.dataGrpList) {
3307
3308		// pie1 (하나만 사용)
3309		if (dataGrp.chartDataGrpId === 'II20') {
3310			const data = dataGrp.chartDataList.map((_, i) => {
3311				totalCnt += dataGrp.dataList[i];
3312				return {
3313					y: dataGrp.dataList[i],
3314					name: dataGrp.labelList[i]
3315				};
3316			});
3317
3318			series.push({
3319				name: dataGrp.chartDataTitle,
3320				type: 'pie',
3321				colorByPoint: true,
3322				size: '80%',
3323				innerSize: '70%',
3324				data: data,
3325				colors: [
3326					'#4F7E9D',  // 동물계
3327					'#7DBA58', // 식물계
3328					'#79C1AF', // 유색조식물계
3329					'#8EA5CD', // 균계
3330					'#C78CC2', // 원생동물계
3331					'#E58283', // 세균계
3332					'#E8A36C' // 고세균계
3333				],
3334				dataLabels: {
3335					enabled: true,
3336					//distance: -54,
3337					format: '{point.name}<br/>{point.y:,.0f}<br/>{point.percentage:.1f}%',
3338					style: {
3339						fontSize: '11px',
3340						fontWeight: 'bold'
3341					}
3342				}
3343			});
3344		}
3345	}
3346
3347	const plotOptions = {
3348		series: {
3349			states: {
3350				hover: { enabled: false },
3351				inactive: { enabled: false }
3352			},
3353			point: {
3354				events: {
3355					mouseOver: () => false,
3356					click: () => false
3357				}
3358			}
3359		},
3360		pie: {
3361			allowPointSelect: false,
3362			cursor: 'default',
3363			borderRadius: 9,
3364			showInLegend: true
3365		}
3366	};
3367
3368	Highcharts.chart(target, {
3369		chart: {
3370			type: 'pie',
3371			backgroundColor: 'transparent'
3372		},
3373		credits: { enabled: false },
3374		accessibility: { enabled: false },
3375		yAxis: { // "Values" 라벨 제거
3376			title: { text: null }
3377		},
3378		title: {
3379			text: title,
3380			align: 'left'
3381		},
3382		subtitle: {
3383			//useHTML: true,
3384			text: `<span style="font-size:2.6em;font-weight:bold;">${numberWithCommas(totalCnt)}</span><span style="font-size:1.8em;"> 종</span>`,
3385			align: 'center',
3386			verticalAlign: 'middle',
3387			x: 40,
3388			y: 110
3389		},
3390		plotOptions: plotOptions,
3391		legend: {
3392			enabled: false
3393		},
3394		series: series
3395	});
3396}
3397
3398
3399// chart 6-2
3400function chart6_2StatMix(chartId){
3401	const chartInfo = getChartInfo(chartId);
3402	const target = chartId;
3403	$('#'+ target).css('height','100%').css('width','100%');
3404
3405	const title = chartInfo.chartTitle;
3406	let totalCnt = 0;
3407
3408	let categories = [];
3409	let series = [];
3410	let colors = [];
3411
3412	// -----------------------------
3413	// ① 데이터 정리 (bar 차트만 사용)
3414	// -----------------------------
3415	for (dataGrp of chartInfo.dataGrpList) {
3416		if (dataGrp.chartDataGrpId !== 'II30-1') continue; // ★ bar만 남김
3417
3418		categories = dataGrp.labelList;
3419
3420		for (let i = 0; i < dataGrp.chartDataList.length; i++) {
3421			colors.push(dataGrp.chartDataList[i].chartColor);
3422			totalCnt += dataGrp.chartDataList[i].chartData;
3423		}
3424
3425		let data = {
3426			name: dataGrp.chartDataTitle,
3427			type: 'bar',
3428			data: mergeDataWithColors(dataGrp.dataList, colors),  // 색 적용
3429			showInLegend: false
3430		};
3431
3432		series.push(data);
3433	}
3434
3435	// -----------------------------
3436	// ② plotOptions (막대 바깥 라벨)
3437	// -----------------------------
3438	const plotOptions = {
3439		series: {
3440			states: {
3441				hover: { enabled: false },
3442				inactive: { enabled: false }
3443			},
3444			point: {
3445				events: {
3446					mouseOver: () => false,
3447					click: () => false
3448				}
3449			}
3450		},
3451		bar: {
3452			dataLabels: {
3453				enabled: true,
3454
3455				// ★★★ 바깥쪽으로 이동 ★★★
3456				inside: false,
3457				align: 'left',
3458				x: 10, // 막대 오른쪽 여백
3459
3460				formatter: function () {
3461					const percentage = ((this.y / totalCnt) * 100).toFixed(2);
3462					return `${numberWithCommas(this.y)} (${percentage}%)`;
3463				},
3464
3465				style: {
3466					fontSize: '11px',
3467					fontWeight: 'bold',
3468					textOutline: 'none'
3469				}
3470			}
3471		}
3472	};
3473
3474	// -----------------------------
3475	// ③ Highcharts 생성
3476	// -----------------------------
3477	Highcharts.chart(target, {
3478		credits: {enabled: false},
3479		title: {
3480			text: title,
3481			align: 'left'
3482		},
3483		subtitle: {
3484			text: `<span style="font-size:1.3em;font-weight:bold;">${numberWithCommas(totalCnt)}</span><span style="font-size:0.9em;">종</span> (단위: 종) `,
3485			align: 'right',
3486			verticalAlign: 'top',
3487			y: 30
3488		},
3489		plotOptions: plotOptions,
3490
3491		yAxis: {
3492			type: 'logarithmic',
3493			title: { text: '' }
3494		},
3495
3496		xAxis: {
3497			categories: categories,
3498			labels: {
3499				style: {
3500					textOverflow: 'ellipsis',
3501					whiteSpace: 'nowrap',
3502					overflow: 'hidden',
3503					width: '100px',
3504					display: 'block'
3505				}
3506			}
3507		},
3508		series: series
3509	});
3510}
3511
3512
3513
3514
3515// chart 6 II
3516function chart6StatMix(chartId){
3517	const chartInfo = getChartInfo(chartId);
3518	const target = chartId;
3519	$('#'+ target).css('height','100%').css('width','100%');
3520	const title = chartInfo.chartTitle;
3521	const subTitle = '';
3522	let maxVal = 0;
3523	let maxValSum = 0;
3524
3525	let categories = [];
3526	let series = [];
3527
3528	for(dataGrp of chartInfo.dataGrpList){
3529		//console.log(dataGrp);
3530		if(dataGrp.chartDataGrpId == 'II30-1'){
3531			categories = dataGrp.labelList;
3532		}
3533		let data;
3534		// column
3535		if(dataGrp.chartDataGrpId == 'II30-1' || dataGrp.chartDataGrpId == 'II30-2'){
3536			data = {
3537				name: dataGrp.chartDataTitle
3538				,type: 'column'
3539				,data: dataGrp.dataList
3540				,yAxis: 1
3541			};
3542			for(dt of dataGrp.dataList){
3543				if(maxVal < dt){
3544					maxVal = dt;
3545				}
3546			}
3547		}else if(dataGrp.chartDataGrpId == 'II30-3'){
3548			// line
3549			data = {
3550				name: dataGrp.chartDataTitle
3551				,type: 'line'
3552				,color: '#00431c'
3553				,data: dataGrp.dataList
3554			};
3555			for(dt of dataGrp.dataList){
3556				if(maxValSum < dt){
3557					maxValSum = dt;
3558				}
3559			}
3560		}
3561		series.push(data);
3562	}
3563	//console.log(maxVal)
3564	//console.log(maxValSum)
3565	const plotOptions = {
3566		series: {
3567			states: {
3568				hover: {
3569					enabled: false // hover 비활성화
3570				},
3571				inactive: {
3572					enabled: false // 비활성화 상태 비활성화
3573				}
3574			},
3575			point: {
3576				events: {
3577					mouseOver: function() {
3578						return false; // 마우스 오버 이벤트 비활성화
3579					},
3580					click: function() {
3581						return false; // 클릭 이벤트 비활성화
3582					}
3583				}
3584			}
3585		},
3586		column: {
3587			dataLabels: {
3588				enabled: true
3589				,y: 150
3590			}
3591		}
3592	};
3593	Highcharts.chart(target, {
3594		credits: {enabled: false}
3595		,title: {
3596			text: title,
3597			align: 'left'
3598		}
3599		,subtitle: {
3600			text: subTitle,
3601			align: 'right'
3602		}
3603		,plotOptions: plotOptions
3604		,yAxis: [{
3605				title: {
3606					text:'',
3607					layout: 'vertical',
3608					align: 'right'
3609				},
3610				max : maxValSum
3611			},
3612			{
3613				title: {
3614					text:'',
3615					layout: 'vertical'
3616				},
3617				max : maxVal
3618			}]
3619		,xAxis: {
3620			categories: categories
3621		}
3622		,series: series
3623	});
3624}
3625
3626
3627
3628
3629//chart 7 III-1
3630function chart7StatMix(chartId){
3631	const chartInfo = getChartInfo(chartId);
3632	const target = chartId;
3633	$('#'+ target).css('height','100%').css('width','100%');
3634	const title = chartInfo.chartTitle;
3635//	const subTitle = '';
3636	const subTitle = '(단위: 건)';
3637	let maxVal = 0;
3638
3639	let categories = [];
3640	let series = [];
3641
3642	for(dataGrp of chartInfo.dataGrpList){
3643		//console.log(dataGrp);
3644		if(dataGrp.chartDataGrpId == 'III12-1' || dataGrp.chartDataGrpId == 'III22-1'){
3645			categories = dataGrp.labelList;
3646		}
3647		let data;
3648
3649		if(dataGrp.chartDataGrpId == 'III12-4' || dataGrp.chartDataGrpId == 'III22-5'){
3650			// line
3651			data = {
3652				name: dataGrp.chartDataTitle
3653				,type: 'line'
3654				//,color: '#00431c'
3655				,color: dataGrp.chartDataList[0].chartColor
3656				,data: dataGrp.dataList
3657			};
3658		} else {
3659			// column
3660			data = {
3661				name: dataGrp.chartDataTitle
3662				,type: 'column'
3663				,data: dataGrp.dataList
3664				,index:Number(dataGrp.chartDataTitle.split('-')[1])
3665				,color: dataGrp.chartDataList[0].chartColor
3666			};
3667		}
3668		series.push(data);
3669		for(dt of dataGrp.dataList){
3670			if(maxVal < dt){
3671				maxVal = dt;
3672			}
3673		}
3674	}
3675	//console.log(maxVal);
3676	//console.log(categories);
3677
3678	const plotOptions = {
3679		column: {
3680			dataLabels: {
3681				enabled: true
3682				,y: 150
3683			}
3684		},
3685		line: {
3686			dataLabels: {
3687				enabled: true
3688			},
3689		}
3690	};
3691
3692	Highcharts.chart(target, {
3693		credits: {enabled: false}
3694		,title: {
3695			text: title,
3696			align: 'left'
3697		}
3698		,subtitle: {
3699			text: subTitle,
3700			align: 'right'
3701		}
3702		,plotOptions: plotOptions
3703		,yAxis: {
3704			title: {
3705				text:'',
3706				layout: 'vertical'
3707			},
3708			max : maxVal
3709		}
3710		,xAxis: {
3711			categories: categories
3712		}
3713		,series: series
3714	});
3715}
3716
3717
3718// chart 8
3719function chart8StatStack(chartId){
3720	const chartInfo = getChartInfo(chartId);
3721	const target = chartId;
3722	$('#'+ target).css('height','100%').css('width','100%');
3723	const title = chartInfo.chartTitle;
3724	const subTitle = '';
3725	let maxVal = 0;
3726
3727	let categories = [];
3728	let series = [];
3729
3730	for(dataGrp of chartInfo.dataGrpList){
3731		if(categories.length == 0){
3732			categories.push(dataGrp.chartDataTitle);
3733		}
3734		let data;
3735		for(dt of dataGrp.chartDataList){
3736			data = {
3737				name: dt.name
3738				,color: dt.color
3739				,data: [dt.y]
3740			};
3741			series.push(data);
3742		}
3743		for(dt of dataGrp.dataList){
3744			if(maxVal < dt){
3745				maxVal = dt;
3746			}
3747		}
3748	}
3749	const plotOptions = {
3750		column: {
3751			dataLabels: {
3752				enabled: true
3753				,y: 150
3754			}
3755		}
3756	};
3757	Highcharts.chart(target, {
3758		credits: {enabled: false},
3759		chart: {
3760			type: 'column'
3761		},
3762		title: {
3763			text: title,
3764			align: 'left'
3765		},
3766		subtitle: {
3767			text: subTitle,
3768			align: 'right'
3769		},
3770		xAxis: {
3771			categories: categories
3772			,reversedStacks: true
3773		},
3774		yAxis:{
3775			visible:false
3776		},
3777		plotOptions: {
3778			series: {
3779				stacking: 'normal',
3780				dataLabels: {
3781					enabled: true
3782				}
3783			}
3784		},
3785		series:series
3786	});
3787}
3788
3789
3790function chart8StatColumn(chartId){
3791	const chartInfo = getChartInfo(chartId);
3792	const target = chartId;
3793	$('#'+ target).css('height','100%').css('width','100%');
3794	const title = chartInfo.chartTitle;
3795	const subTitle = '';
3796	let maxVal = 0;
3797
3798	let categories = [];
3799	let series = [];
3800
3801	for(dataGrp of chartInfo.dataGrpList){
3802		if(categories.length == 0){
3803			categories.push(dataGrp.chartDataTitle);
3804		}
3805		let data;
3806		for(dt of dataGrp.chartDataList){
3807			data = {
3808				name: dt.name
3809				,color: dt.color
3810				,data: [dt.y]
3811			};
3812			series.push(data);
3813		}
3814		for(dt of dataGrp.dataList){
3815			if(maxVal < dt){
3816				maxVal = dt;
3817			}
3818		}
3819	}
3820	const plotOptions = {
3821		column: {
3822			dataLabels: {
3823				enabled: true
3824				,y: 150
3825			}
3826		}
3827	};
3828	Highcharts.chart(target, {
3829		credits: {enabled: false},
3830		chart: {
3831			type: 'column'
3832		},
3833		title: {
3834			text: title,
3835			align: 'left'
3836		},
3837		subtitle: {
3838			text: subTitle,
3839			align: 'right'
3840		},
3841		xAxis: {
3842			categories: categories
3843			,reversedStacks: true
3844		},
3845		yAxis:{
3846			visible:false
3847		},
3848		plotOptions: {
3849			series: {
3850				dataLabels: {
3851					enabled: true
3852				}
3853			}
3854		},
3855		series:series
3856	});
3857}
3858

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.