jichoi / lms_front star
woals 08-19
240819 권민수 학부모 대시보드 문제 지표 점수 시각화 적용
@75c53f5ef44616ed7c00201a267a1a290e620f3e
client/views/pages/parents/ColumnLineChart.vue
--- client/views/pages/parents/ColumnLineChart.vue
+++ client/views/pages/parents/ColumnLineChart.vue
@@ -1,206 +1,237 @@
 <template>
-    <div ref="ColumnLineChart" style="width: 500px; height: 500px;"></div>
-  </template>
-  
-  <script>
-  import * as am5 from "@amcharts/amcharts5";
-  import * as am5xy from "@amcharts/amcharts5/xy";
-  import am5themes_Animated from "@amcharts/amcharts5/themes/Animated";
-  
-  export default {
-    name: "ColumnLineChart",
-    mounted() {
-      this.createChart();
+  <div ref="ColumnLineChart" style="width: 500px; height: 500px;"></div>
+</template>
+
+<script>
+import * as am5 from "@amcharts/amcharts5";
+import * as am5xy from "@amcharts/amcharts5/xy";
+import am5themes_Animated from "@amcharts/amcharts5/themes/Animated";
+import axios from "axios";
+
+export default {
+  name: "ColumnLineChart",
+
+  data() {
+    return {
+      chartData: [],
+      currentStdId: "1"
+    };
+  },
+
+  mounted() {
+    this.getMtrScoreData();
+  },
+
+  methods: {
+    // 학생의 문제 지표 점수 데이터 가져오기
+    getMtrScoreData() {
+      const vm = this;
+      axios.post('/dashboard/mtrScoreData.json', {
+          std_id: vm.currentStdId
+      })
+      .then(response => {
+        if (response.data) {
+          // 데이터를 날짜순으로 정렬
+          vm.chartData = response.data.sort(
+            (a, b) => new Date(a.learnedDate) - new Date(b.learnedDate)
+          );
+          vm.createChart();
+        } else {
+          console.error("mtrScoreList가 응답 데이터에 없습니다.");
+        }
+      })
+      .catch(error => {
+          console.error('문제 지표 점수 데이터를 가져오는 중 오류 발생:', error);
+      });
     },
-    methods: {
-      createChart() {
-        // Initialize root
-        const root = am5.Root.new(this.$refs.ColumnLineChart);
-  
-        // Apply themes
-        const myTheme = am5.Theme.new(root);
-        myTheme.rule("Grid", ["base"]).setAll({
-          strokeOpacity: 0.1,
+
+    createChart() {
+      // Initialize root
+      const root = am5.Root.new(this.$refs.ColumnLineChart);
+
+      // Apply themes
+      root.setThemes([
+        am5themes_Animated.new(root),
+      ]);
+
+      // Create chart
+      const chart = root.container.children.push(
+        am5xy.XYChart.new(root, {
+          panX: false,
+          panY: false,
+          wheelX: "panX",
+          wheelY: "zoomX",
+          paddingLeft: 0,
+          layout: root.verticalLayout
+        })
+      );
+
+      // Create axes
+      const xRenderer = am5xy.AxisRendererX.new(root, {
+        minorGridEnabled: true,
+        minGridDistance: 60
+      });
+
+      const xAxis = chart.xAxes.push(
+        am5xy.CategoryAxis.new(root, {
+          categoryField: "learnedDate",
+          renderer: xRenderer,
+          tooltip: am5.Tooltip.new(root, {})
+        })
+      );
+
+      xRenderer.grid.template.setAll({
+        location: 1
+      });
+
+      xAxis.data.setAll(this.chartData);
+
+      let yAxis = chart.yAxes.push(
+        am5xy.ValueAxis.new(root, {
+          min: 0,
+          extraMax: 0.1,
+          renderer: am5xy.AxisRendererY.new(root, {
+            strokeOpacity: 0.1
+          })
+        })
+      );
+
+      // 이해 점수 막대 그래프
+      let series1 = chart.series.push(
+        am5xy.ColumnSeries.new(root, {
+          name: "이해 점수",
+          xAxis: xAxis,
+          yAxis: yAxis,
+          valueYField: "totalMtr01Score",
+          categoryXField: "learnedDate",
+          tooltip: am5.Tooltip.new(root, {
+            pointerOrientation: "horizontal",
+            labelText: "{name} in {categoryX}: {valueY}"
+          })
+        })
+      );
+
+      // 파스텔 블루
+      series1.columns.template.setAll({
+        fill: am5.color(0x87CEEB),
+        stroke: am5.color(0x87CEEB),
+        tooltipY: am5.percent(10),
+      });
+
+      series1.data.setAll(this.chartData);
+
+      // 표현 점수 막대 그래프
+      let series2 = chart.series.push(
+        am5xy.ColumnSeries.new(root, {
+          name: "표현 점수",
+          xAxis: xAxis,
+          yAxis: yAxis,
+          valueYField: "totalMtr02Score",
+          categoryXField: "learnedDate",
+          tooltip: am5.Tooltip.new(root, {
+            pointerOrientation: "horizontal",
+            labelText: "{name} in {categoryX}: {valueY}"
+          })
+        })
+      );
+
+      // 파스텔 핑크
+      series2.columns.template.setAll({
+        fill: am5.color(0xFFB6C1),
+        stroke: am5.color(0xFFB6C1),
+        tooltipY: am5.percent(10),
+      });
+
+      series2.data.setAll(this.chartData);
+
+      // 이해 점수 변화 꺾은선 그래프
+      const lineSeries1 = chart.series.push(
+        am5xy.LineSeries.new(root, {
+          name: "이해 점수 변화",
+          xAxis: xAxis,
+          yAxis: yAxis,
+          valueYField: "totalMtr01Score",
+          categoryXField: "learnedDate",
+          stroke: am5.color(0xADD8E6), // 라이트 블루로 설정
+          tooltip: am5.Tooltip.new(root, {
+            pointerOrientation: "horizontal",
+            labelText: "{name} on {categoryX}: {valueY}"
+          })
+        })
+      );
+
+      lineSeries1.strokes.template.setAll({
+        strokeWidth: 3,
+        stroke: am5.color(0xADD8E6), // 다시 명시적 설정
+      });
+
+      lineSeries1.bullets.push(function () {
+        return am5.Bullet.new(root, {
+          sprite: am5.Circle.new(root, {
+            radius: 5,
+            fill: am5.color(0xADD8E6), // 라이트 블루로 설정
+            strokeWidth: 3,
+            stroke: am5.color(0xADD8E6)
+          })
         });
-        root.setThemes([
-          am5themes_Animated.new(root),
-          myTheme,
-        ]);
-  
-        // Create chart
-        let chart = root.container.children.push(
-  am5xy.XYChart.new(root, {
-    panX: false,
-    panY: false,
-    wheelX: "panX",
-    wheelY: "zoomX",
-    paddingLeft: 0,
-    layout: root.verticalLayout
-  })
-);
+      });
 
-// Add scrollbar
-// https://www.amcharts.com/docs/v5/charts/xy-chart/scrollbars/
-// chart.set(
-//   "scrollbarX",
-//   am5.Scrollbar.new(root, {
-//     orientation: "horizontal"
-//   })
-// );
+      lineSeries1.data.setAll(this.chartData);
 
-let data = [
-  {
-    year: "2016",
-    income: 23.5,
-    expenses: 21.1
-  },
-  {
-    year: "2017",
-    income: 26.2,
-    expenses: 30.5
-  },
-  {
-    year: "2018",
-    income: 30.1,
-    expenses: 34.9
-  },
-  {
-    year: "2019",
-    income: 29.5,
-    expenses: 31.1
-  },
-  {
-    year: "2020",
-    income: 30.6,
-    expenses: 28.2,
-    strokeSettings: {
-      stroke: chart.get("colors").getIndex(1),
-      strokeWidth: 3,
-      strokeDasharray: [5, 5]
-    }
-  },
-  {
-    year: "2021",
-    income: 34.1,
-    expenses: 32.9,
-    columnSettings: {
-      strokeWidth: 1,
-      strokeDasharray: [5],
-      fillOpacity: 0.2
+      // 표현 점수 변화 꺾은선 그래프
+      const lineSeries2 = chart.series.push(
+        am5xy.LineSeries.new(root, {
+          name: "표현 점수 변화",
+          xAxis: xAxis,
+          yAxis: yAxis,
+          valueYField: "totalMtr02Score",
+          categoryXField: "learnedDate",
+          stroke: am5.color(0xFF69B4), // 핫 핑크로 설정
+          tooltip: am5.Tooltip.new(root, {
+            pointerOrientation: "horizontal",
+            labelText: "{name} on {categoryX}: {valueY}"
+          })
+        })
+      );
+
+      lineSeries2.strokes.template.setAll({
+        strokeWidth: 3,
+        stroke: am5.color(0xFF69B4), // 다시 명시적 설정
+      });
+
+      lineSeries2.bullets.push(function () {
+        return am5.Bullet.new(root, {
+          sprite: am5.Circle.new(root, {
+            radius: 5,
+            fill: am5.color(0xFF69B4), // 핫 핑크로 설정
+            strokeWidth: 3,
+            stroke: am5.color(0xFF69B4)
+          })
+        });
+      });
+
+      lineSeries2.data.setAll(this.chartData);
+
+      chart.set("cursor", am5xy.XYCursor.new(root, {}));
+
+      let legend = chart.children.push(
+        am5.Legend.new(root, {
+          centerX: am5.p50,
+          x: am5.p50
+        })
+      );
+      legend.data.setAll(chart.series.values);
+
+      chart.appear(1000, 100);
+      series1.appear();
+      series2.appear();
+      lineSeries1.appear();
+      lineSeries2.appear();
     },
-    info: "(projection)"
-  }
-];
+  },
+};
+</script>
 
-// Create axes
-// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
-let xRenderer = am5xy.AxisRendererX.new(root, {
-  minorGridEnabled: true,
-  minGridDistance: 60
-});
-let xAxis = chart.xAxes.push(
-  am5xy.CategoryAxis.new(root, {
-    categoryField: "year",
-    renderer: xRenderer,
-    tooltip: am5.Tooltip.new(root, {})
-  })
-);
-xRenderer.grid.template.setAll({
-  location: 1
-})
-
-xAxis.data.setAll(data);
-
-let yAxis = chart.yAxes.push(
-  am5xy.ValueAxis.new(root, {
-    min: 0,
-    extraMax: 0.1,
-    renderer: am5xy.AxisRendererY.new(root, {
-      strokeOpacity: 0.1
-    })
-  })
-);
-
-
-// Add series
-// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
-
-let series1 = chart.series.push(
-  am5xy.ColumnSeries.new(root, {
-    name: "Income",
-    xAxis: xAxis,
-    yAxis: yAxis,
-    valueYField: "income",
-    categoryXField: "year",
-    tooltip: am5.Tooltip.new(root, {
-      pointerOrientation: "horizontal",
-      labelText: "{name} in {categoryX}: {valueY} {info}"
-    })
-  })
-);
-
-series1.columns.template.setAll({
-  tooltipY: am5.percent(10),
-  templateField: "columnSettings"
-});
-
-series1.data.setAll(data);
-
-let series2 = chart.series.push(
-  am5xy.LineSeries.new(root, {
-    name: "Expenses",
-    xAxis: xAxis,
-    yAxis: yAxis,
-    valueYField: "expenses",
-    categoryXField: "year",
-    tooltip: am5.Tooltip.new(root, {
-      pointerOrientation: "horizontal",
-      labelText: "{name} in {categoryX}: {valueY} {info}"
-    })
-  })
-);
-
-series2.strokes.template.setAll({
-  strokeWidth: 3,
-  templateField: "strokeSettings"
-});
-
-
-series2.data.setAll(data);
-
-series2.bullets.push(function () {
-  return am5.Bullet.new(root, {
-    sprite: am5.Circle.new(root, {
-      strokeWidth: 3,
-      stroke: series2.get("stroke"),
-      radius: 5,
-      fill: root.interfaceColors.get("background")
-    })
-  });
-});
-
-chart.set("cursor", am5xy.XYCursor.new(root, {}));
-
-// Add legend
-// https://www.amcharts.com/docs/v5/charts/xy-chart/legend-xy-series/
-let legend = chart.children.push(
-  am5.Legend.new(root, {
-    centerX: am5.p50,
-    x: am5.p50
-  })
-);
-legend.data.setAll(chart.series.values);
-
-// Make stuff animate on load
-// https://www.amcharts.com/docs/v5/concepts/animations/
-chart.appear(1000, 100);
-series1.appear();
-      },
-    },
-  };
-  </script>
-  
-  <style scoped>
-  /* Add necessary styles here */
-  </style>
-  
(파일 끝에 줄바꿈 문자 없음)
+<style scoped>
+/* Add necessary styles here */
+</style>
client/views/pages/parents/Dounutchart.vue
--- client/views/pages/parents/Dounutchart.vue
+++ client/views/pages/parents/Dounutchart.vue
@@ -15,7 +15,9 @@
     return {
       chartData: {},
       currentDate: "2024-08-14",
-      currentStdId: "1"
+      currentStdId: "1",
+      root: null,
+      chart: null
     };
   },
 
@@ -42,6 +44,11 @@
     },
 
     createChart() {
+      // 차트 중복 생성 방지
+      if (this.root) {
+        this.root.dispose();
+      }
+
       // Initialize root
       const root = am5.Root.new(this.$refs.Dounutchart);
 
@@ -118,7 +125,7 @@
       series.appear(1000, 100);
     }
   }
-  
+
 };
 </script>
 
Add a comment
List