woals
08-20
240820 권민수 학부모 대시보드 문제 카테고리별 점수 시각화 적용
@ee4a222fc455c758c4fec01de68c2e4ca966cd42
--- client/views/pages/parents/Bubblechart.vue
+++ client/views/pages/parents/Bubblechart.vue
... | ... | @@ -1,6 +1,8 @@ |
1 |
+<!-- 이 차트 컴포넌트는 유기되었습니다. --> |
|
2 |
+ |
|
1 | 3 |
<template> |
2 |
- <div ref="Bubblechart" style="width: 500px; height: 500px;"></div> |
|
3 |
- </template> |
|
4 |
+ <div ref="Bubblechart" style="width: 500px; height: 500px;"></div> |
|
5 |
+</template> |
|
4 | 6 |
|
5 | 7 |
<script> |
6 | 8 |
import * as am5 from "@amcharts/amcharts5"; |
+++ client/views/pages/parents/CategoryBarChart.vue
... | ... | @@ -0,0 +1,124 @@ |
1 | +<template> | |
2 | + <div ref="CategoryBarChart" style="width: 500px; height: 500px;"></div> | |
3 | + </template> | |
4 | + | |
5 | + <script> | |
6 | + import * as am5 from "@amcharts/amcharts5"; | |
7 | + import * as am5xy from "@amcharts/amcharts5/xy"; | |
8 | + import am5themes_Animated from "@amcharts/amcharts5/themes/Animated"; | |
9 | + import axios from "axios"; | |
10 | + | |
11 | + export default { | |
12 | + name: "CategoryBarChart", | |
13 | + | |
14 | + data() { | |
15 | + return { | |
16 | + chartData: [], | |
17 | + currentStdId: "1" | |
18 | + }; | |
19 | + }, | |
20 | + | |
21 | + mounted() { | |
22 | + this.getCategoryScoreData(); | |
23 | + }, | |
24 | + | |
25 | + methods: { | |
26 | + // 카테고리별 점수 데이터 가져오기 | |
27 | + getCategoryScoreData() { | |
28 | + const vm = this; | |
29 | + axios.post('/dashboard/categoryScoreData.json', { | |
30 | + std_id: vm.currentStdId | |
31 | + }) | |
32 | + .then(response => { | |
33 | + vm.chartData = response.data.map(item => ({ | |
34 | + ...item, | |
35 | + combinedCategory: `${item.categoryNm}\n(${item.categoryCls})` | |
36 | + })); | |
37 | + vm.createChart(); | |
38 | + }) | |
39 | + .catch(error => { | |
40 | + console.error('카테고리 점수 데이터를 가져오는 중 오류 발생:', error); | |
41 | + }) | |
42 | + }, | |
43 | + | |
44 | + createChart() { | |
45 | + // Initialize root | |
46 | + const root = am5.Root.new(this.$refs.CategoryBarChart); | |
47 | + | |
48 | + // Apply themes | |
49 | + root.setThemes([ | |
50 | + am5themes_Animated.new(root) | |
51 | + ]); | |
52 | + | |
53 | + // Create chart | |
54 | + const chart = root.container.children.push(am5xy.XYChart.new(root, { | |
55 | + panX: false, | |
56 | + panY: false, | |
57 | + wheelX: "panX", | |
58 | + wheelY: "zoomX", | |
59 | + layout: root.verticalLayout | |
60 | + })); | |
61 | + | |
62 | + // Create axes | |
63 | + const yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, { | |
64 | + renderer: am5xy.AxisRendererY.new(root, {}), | |
65 | + min: 0 | |
66 | + })); | |
67 | + | |
68 | + const xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, { | |
69 | + categoryField: "combinedCategory", | |
70 | + renderer: am5xy.AxisRendererX.new(root, {}), | |
71 | + tooltip: am5.Tooltip.new(root, { themeTags: ["axis"] }) | |
72 | + })); | |
73 | + | |
74 | + xAxis.get("renderer").labels.template.setAll({ | |
75 | + textAlign: "center", | |
76 | + centerX: am5.p50 | |
77 | + }); | |
78 | + | |
79 | + xAxis.data.setAll(this.chartData); | |
80 | + | |
81 | + // Create series | |
82 | + const series = chart.series.push(am5xy.ColumnSeries.new(root, { | |
83 | + name: "Category Scores", | |
84 | + xAxis: xAxis, | |
85 | + yAxis: yAxis, | |
86 | + valueYField: "totalScore", | |
87 | + categoryXField: "combinedCategory", | |
88 | + tooltip: am5.Tooltip.new(root, { | |
89 | + labelText: "{categoryX}: {valueY}" | |
90 | + }) | |
91 | + })); | |
92 | + | |
93 | + // Set color manually for each bar (simplified for clarity) | |
94 | + series.columns.template.setAll({ | |
95 | + fill: am5.color("#67b7dc"), | |
96 | + stroke: am5.color("#67b7dc"), | |
97 | + fillOpacity: 0.8, // Adjust opacity if needed | |
98 | + strokeWidth: 0, | |
99 | + cornerRadiusTL: 5, | |
100 | + cornerRadiusTR: 5 | |
101 | + }); | |
102 | + | |
103 | + // Assign data | |
104 | + series.data.setAll(this.chartData); | |
105 | + | |
106 | + // Add legend | |
107 | + chart.children.push(am5.Legend.new(root, { | |
108 | + centerX: am5.p50, | |
109 | + x: am5.p50, | |
110 | + marginTop: 15, | |
111 | + marginBottom: 15 | |
112 | + })); | |
113 | + | |
114 | + // Play initial series animation | |
115 | + series.appear(1000, 100); | |
116 | + } | |
117 | + } | |
118 | + }; | |
119 | + </script> | |
120 | + | |
121 | + <style scoped> | |
122 | + /* 스타일은 필요에 따라 추가 */ | |
123 | + </style> | |
124 | + (파일 끝에 줄바꿈 문자 없음) |
--- client/views/pages/parents/Main_p.vue
+++ client/views/pages/parents/Main_p.vue
... | ... | @@ -164,8 +164,8 @@ |
164 | 164 |
</div> |
165 | 165 |
|
166 | 166 |
<div class="wrap"> |
167 |
- <p class="name">LC/RC 세부 점수</p> |
|
168 |
- <div class="flex justify-center"><Bubblechart /></div> |
|
167 |
+ <p class="name">문제 카테고리별 세부 점수</p> |
|
168 |
+ <div class="flex justify-center"><CategoryBarChart /></div> |
|
169 | 169 |
</div> |
170 | 170 |
|
171 | 171 |
</div> |
... | ... | @@ -185,7 +185,8 @@ |
185 | 185 |
import ProgressBar from '../../component/ProgressBar.vue'; |
186 | 186 |
import StackedBarChart from './StackedBarChart.vue'; |
187 | 187 |
import Barchart from './Barchart.vue'; |
188 |
-import Bubblechart from './Bubblechart.vue'; |
|
188 |
+// import Bubblechart from './Bubblechart.vue'; |
|
189 |
+import CategoryBarChart from './CategoryBarChart.vue'; |
|
189 | 190 |
import Dounutchart from './Dounutchart.vue'; |
190 | 191 |
import ColumnLineChart from './ColumnLineChart.vue'; |
191 | 192 |
import axios from "axios"; |
... | ... | @@ -257,7 +258,8 @@ |
257 | 258 |
ProgressBar, |
258 | 259 |
StackedBarChart: StackedBarChart, |
259 | 260 |
Barchart: Barchart, |
260 |
- Bubblechart: Bubblechart, |
|
261 |
+ // Bubblechart: Bubblechart, |
|
262 |
+ CategoryBarChart, |
|
261 | 263 |
Dounutchart: Dounutchart, |
262 | 264 |
ColumnLineChart: ColumnLineChart, |
263 | 265 |
|
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?