ソースを参照

build: echarts数据图表样式

chaooo 2 年 前
コミット
d003777308

+ 6 - 1
src/router/index.ts

@@ -5,6 +5,11 @@ export const Layout = () => import("@/layout/school.vue");
 // 静态路由
 export const constantRoutes: RouteRecordRaw[] = [
   {
+    path: "/:pathMatch(.*)*", // 解决路由爆[Vue Router warn]: No match found for location with path
+    meta: { title: "找不到此页面", hidden: true },
+    component: () => import("@/views/error/404.vue"),
+  },
+  {
     path: "/redirect",
     component: Layout,
     meta: { hidden: true },
@@ -18,7 +23,7 @@ export const constantRoutes: RouteRecordRaw[] = [
   {
     path: "/login",
     component: () => import("@/views/login/index.vue"),
-    meta: { hidden: true },
+    meta: { title: "登录", hidden: true },
   },
 ];
 

+ 22 - 27
src/views/dashboard/components/BarChart.vue → src/views/base-charts/BarChart.vue

@@ -10,6 +10,7 @@ const props = defineProps({
   id: {
     type: String,
     default: "barChart",
+    required: true,
   },
   className: {
     type: String,
@@ -18,12 +19,10 @@ const props = defineProps({
   width: {
     type: String,
     default: "400px",
-    required: true,
   },
   height: {
     type: String,
     default: "400px",
-    required: true,
   },
   title: {
     type: String,
@@ -32,17 +31,19 @@ const props = defineProps({
   percentData: {
     type: String,
     default: "0,0,0,0,0",
+    required: true,
   },
   numberData: {
     type: String,
     default: "0,0,0,0,0",
+    required: true,
   },
 });
-function showText(index) {
+function showText(index): String {
   return (
-    props.numberData.split(",")[index] +
+    props.numberData?.split(",")[index] +
     "人 (" +
-    props.percentData.split(",")[index] +
+    props.percentData?.split(",")[index] +
     "%)"
   );
 }
@@ -90,16 +91,13 @@ const options = {
   ],
   series: [
     {
-      data: props.percentData.split(","),
+      data: props.percentData?.split(","),
       type: "bar",
-      //barWidth: 36,
       label: {
-        normal: {
-          show: true,
-          position: "right",
-          formatter(params) {
-            return params.value == 0 ? "" : showText(params.dataIndex);
-          },
+        show: true,
+        position: "right",
+        formatter(params) {
+          return params.value == 0 ? "" : showText(params.dataIndex);
         },
       },
       showBackground: true,
@@ -107,19 +105,16 @@ const options = {
         color: "#f2f2fb",
       },
       itemStyle: {
-        //通常情况下:
-        normal: {
-          //每个柱子的颜色即为colorList数组里的每一项,如果柱子数目多于colorList的长度,则柱子颜色循环使用该数组
-          color: function (params) {
-            const colorList = [
-              "#68cfff",
-              "#688fff",
-              "#b890ef",
-              "#ee7a66",
-              "#f6c04c",
-            ];
-            return colorList[params.dataIndex];
-          },
+        //每个柱子的颜色即为colorList数组里的每一项,如果柱子数目多于colorList的长度,则柱子颜色循环使用该数组
+        color: function (params) {
+          const colorList = [
+            "#68cfff",
+            "#688fff",
+            "#b890ef",
+            "#ee7a66",
+            "#f6c04c",
+          ];
+          return colorList[params.dataIndex];
         },
       },
       barCategoryGap: "50%",
@@ -130,7 +125,7 @@ const options = {
 onMounted(() => {
   // 图表初始化
   const chart = echarts.init(
-    document.getElementById(props.id) as HTMLDivElement
+    document.getElementById(<string>props.id) as HTMLDivElement
   );
   chart.setOption(options);
   // 大小自适应

+ 38 - 40
src/views/dashboard/components/CircleChart.vue → src/views/base-charts/CircleChart.vue

@@ -10,33 +10,51 @@ const props = defineProps({
   id: {
     type: String,
     default: "circleChart",
-  },
-  data: {
-    type: Number,
-    default: 0,
+    required: true,
   },
   className: {
     type: String,
-    default: "",
+    default: "chart",
   },
   width: {
     type: String,
-    default: "160px",
-    required: true,
+    default: "200px",
   },
   height: {
     type: String,
-    default: "160px",
-    required: true,
+    default: "200px",
   },
   color: {
     type: String,
     default: "#2f539b",
-    required: true,
   },
   bgColor: {
     type: String,
     default: "#e6e8f9",
+  },
+  fontColor: {
+    type: String,
+    default: "#2f539b",
+  },
+  fontSize: {
+    type: Number,
+    default: 18,
+  },
+  fontWeight: {
+    type: String,
+    default: "bold",
+  },
+  roundCap: {
+    type: Boolean,
+    default: false,
+  },
+  lineWidth: {
+    type: Number,
+    default: 20,
+  },
+  data: {
+    type: Number,
+    default: 0,
     required: true,
   },
 });
@@ -45,13 +63,13 @@ const options = {
   animation: true,
   title: {
     show: true,
-    text: props.data,
+    text: props.data + "%",
     x: "center",
     y: "center",
     textStyle: {
-      fontSize: "30",
-      // fontWeight: 'normal',
-      color: props.color,
+      fontSize: props.fontSize,
+      fontWeight: props.fontWeight,
+      color: props.fontColor,
     },
   },
   series: [
@@ -65,27 +83,18 @@ const options = {
       center: ["50%", "50%"],
       progress: {
         // 进度环
-        roundCap: "true",
+        roundCap: props.roundCap,
         show: true,
-        width: 20,
+        width: props.lineWidth,
         itemStyle: {
           color: props.color,
-          // color: {
-          // 	type: 'linear',
-          // 	x:0, y: 0, x2: 0, y2: 1,
-          // 	colorStops: [{ //进度环的渐变色
-          // 		offset: 0, color: '#2ce385' // 0% 处的颜色
-          // 	}, {
-          // 		offset: 1, color: '#00b056' // 100% 处的颜色
-          // 	}]
-          // }
         },
       },
       axisLine: {
         // 背景环
-        roundCap: "true",
+        roundCap: false,
         lineStyle: {
-          width: 20,
+          width: props.lineWidth,
           color: [
             [0, props.bgColor],
             [1, props.bgColor],
@@ -93,20 +102,9 @@ const options = {
         },
       },
       avoidLabelOverlap: true,
-      hoverAnimation: false,
-      label: {
-        normal: {
-          show: false,
-          position: "center",
-        },
-        emphasis: {
-          show: false,
-        },
-      },
+      label: { show: false },
       labelLine: {
-        normal: {
-          show: false,
-        },
+        show: false,
       },
       pointer: { show: false },
       axisTick: { show: false },

+ 102 - 0
src/views/base-charts/DoubleChart.vue

@@ -0,0 +1,102 @@
+<!-- 双圈图 -->
+<template>
+  <div :id="id" :class="className" :style="{ height, width }" />
+</template>
+
+<script setup lang="ts">
+import * as echarts from "echarts";
+
+const props = defineProps({
+  id: {
+    type: String,
+    default: "doubleChart",
+    required: true,
+  },
+  className: {
+    type: String,
+    default: "chart",
+  },
+  width: {
+    type: String,
+    default: "200px",
+  },
+  height: {
+    type: String,
+    default: "200px",
+  },
+  color: {
+    type: String,
+    default: "#2f539b",
+  },
+  bgColor: {
+    type: String,
+    default: "#e6e8f9",
+  },
+  data: {
+    type: Number,
+    default: 0,
+    required: true,
+  },
+});
+
+const options = {
+  animation: true,
+  title: {
+    show: true,
+    text: props.data,
+    x: "center",
+    y: "center",
+    textStyle: {
+      fontSize: 18,
+      fontWeight: "normal",
+      color: "#09132e",
+    },
+  },
+  series: [
+    {
+      name: "Double Chart",
+      type: "pie",
+      radius: ["74%", "94%"],
+      avoidLabelOverlap: false,
+      colorBy: "series",
+      itemStyle: {
+        color: props.color,
+        borderColor: "#fff",
+        borderWidth: 10,
+      },
+      label: { show: false },
+      emphasis: { label: { show: false } },
+      labelLine: { show: false },
+      data: [25, 25, 25, 25],
+    },
+    {
+      name: "Double Chart BG",
+      type: "pie",
+      radius: ["48%", "68%"],
+      startAngle: 45,
+      avoidLabelOverlap: false,
+      colorBy: "series",
+      itemStyle: {
+        color: props.bgColor,
+        borderColor: "#fff",
+        borderWidth: 10,
+      },
+      label: { show: false },
+      emphasis: { label: { show: false } },
+      labelLine: { show: false },
+      data: [25, 25, 25, 25],
+    },
+  ],
+};
+
+onMounted(() => {
+  const chart = echarts.init(
+    document.getElementById(<string>props.id) as HTMLDivElement
+  );
+  chart.setOption(options);
+
+  window.addEventListener("resize", () => {
+    chart.resize();
+  });
+});
+</script>

+ 9 - 20
src/views/dashboard/components/LiquidChart.vue → src/views/base-charts/LiquidChart.vue

@@ -11,10 +11,7 @@ const props = defineProps({
   id: {
     type: String,
     default: "liquidChart",
-  },
-  data: {
-    type: Number,
-    default: 0,
+    required: true,
   },
   className: {
     type: String,
@@ -23,33 +20,29 @@ const props = defineProps({
   width: {
     type: String,
     default: "160px",
-    required: true,
   },
   height: {
     type: String,
     default: "160px",
-    required: true,
   },
   color: {
     type: String,
     default: "#2f539b",
-    required: true,
   },
   bgColor: {
     type: String,
     default: "#e6e8f9",
+  },
+  data: {
+    type: Number,
+    default: 0,
     required: true,
   },
 });
 
 const options = {
-  // backgroundColor: '#ffffff',
-  // tooltip: {
-  // 	show: true
-  // },
   series: [
     {
-      // name: '全体学员初期专注力评估均值',
       type: "liquidFill", // 水球图样式
       radius: "90%",
       center: ["50%", "50%"], // 水球图位置
@@ -74,14 +67,10 @@ const options = {
         },
       },
       label: {
-        normal: {
-          formatter: "60", // 内部文字内容
-          textStyle: {
-            color: props.color, // 在波浪上方时的文字颜色
-            insideColor: "#ffffff", // 在波浪下方时的文字颜色
-            fontSize: 30, // 文字大小
-          },
-        },
+        formatter: props.data,
+        color: props.color, // 在波浪上方时的文字颜色
+        insideColor: "#ffffff", // 在波浪下方时的文字颜色
+        fontSize: 30, // 文字大小
       },
       data: [props.data / 100], // 水球的注满度 60%
     },

+ 33 - 51
src/views/student/components/PieChart.vue → src/views/base-charts/PieChart.vue

@@ -1,4 +1,4 @@
-<!--  柱状图 -->
+<!-- 圆饼图 -->
 <template>
   <div :id="id" :class="className" :style="{ height, width }" />
 </template>
@@ -10,87 +10,69 @@ const props = defineProps({
   id: {
     type: String,
     default: "pieChart",
+    required: true,
   },
   className: {
     type: String,
-    default: "",
+    default: "chart",
   },
   width: {
     type: String,
     default: "400px",
-    required: true,
   },
   height: {
     type: String,
     default: "400px",
-    required: true,
   },
   title: {
     type: String,
     default: "",
   },
-  percentData: {
-    type: String,
-    default: "0,0,0,0,0",
-  },
-  numberData: {
+  data: {
     type: String,
-    default: "0,0,0,0,0",
+    default: "1,0,0,0,0",
+    required: true,
   },
 });
+function getDataValue(i): number {
+  return props.data?.split(",")[i];
+}
 const options = {
-  tooltip: {
-    trigger: "item",
-    formatter: "{a} \r\n {b}: {c} ({d}%)",
+  title: {
+    text: props.title,
+    left: "39%",
+    top: "52%",
+    textStyle: {
+      fontSize: 16,
+      fontWeight: "normal",
+      color: "#09132e",
+    },
   },
   legend: {
-    orient: "vertical",
-    right: "10%",
-    top: "5%",
+    right: "6%",
+    top: "6%",
+    padding: 0,
+    itemGap: 5,
+    icon: "roundRect",
     data: ["0-20", "21-40", "41-60", "61-80", "81-100"],
   },
   series: [
     {
-      name: "访问来源",
+      name: props.title,
       type: "pie",
-      radius: ["40%", "70%"],
+      radius: ["40%", "60%"],
       avoidLabelOverlap: false,
       label: {
-        show: false,
-        position: "center",
-      },
-      right: "40%",
-      emphasis: {
-        label: {
-          show: true,
-          fontSize: "30",
-          fontWeight: "bold",
-        },
-      },
-      labelLine: {
         show: true,
+        formatter: "{c}%",
       },
+      center: ["50%", "55%"],
       data: [
-        {
-          value: 20,
-          name: "A",
-        },
-        {
-          value: 12,
-          name: "B",
-        },
-        {
-          value: 18,
-          name: "C",
-        },
-        {
-          value: 20,
-          name: "D",
-        },
-        {
-          value: 20,
-          name: "E",
-        },
+        { value: getDataValue(0), name: "0-20" },
+        { value: getDataValue(1), name: "21-40" },
+        { value: getDataValue(2), name: "41-60" },
+        { value: getDataValue(3), name: "61-80" },
+        { value: getDataValue(4), name: "81-100" },
       ],
     },
   ],
@@ -99,7 +81,7 @@ const options = {
 onMounted(() => {
   // 图表初始化
   const chart = echarts.init(
-    document.getElementById(props.id) as HTMLDivElement
+    document.getElementById(<string>props.id) as HTMLDivElement
   );
   chart.setOption(options);
   // 大小自适应

+ 138 - 0
src/views/base-charts/RadarChart.vue

@@ -0,0 +1,138 @@
+<!-- 五维雷达图 -->
+<template>
+  <div :id="id" :class="className" :style="{ height, width }" />
+</template>
+
+<script setup lang="ts">
+import * as echarts from "echarts";
+
+const props = defineProps({
+  id: {
+    type: String,
+    default: "radarChart",
+    required: true,
+  },
+  className: {
+    type: String,
+    default: "",
+  },
+  width: {
+    type: String,
+    default: "160px",
+  },
+  height: {
+    type: String,
+    default: "160px",
+  },
+  color: {
+    type: String,
+    default: "#2f539b",
+  },
+  bgColor: {
+    type: String,
+    default: "#e6e8f9",
+  },
+  beforeData: {
+    type: String,
+    default: "0,0,0,0,0",
+    required: true,
+  },
+  afterData: {
+    type: String,
+    default: "0,0,0,0,0",
+    required: true,
+  },
+});
+
+const options = {
+  title: {
+    text: "5D脑电数据模型",
+    left: "5%",
+    top: "5%",
+    textStyle: {
+      fontSize: 18,
+      fontWeight: "normal",
+      color: "#09132e",
+    },
+  },
+  color: ["#937dff", "#ffb72d"],
+  legend: {
+    right: "5%",
+    top: "5%",
+    data: [
+      { name: "训练前", icon: "circle" },
+      { name: "训练后", icon: "circle" },
+    ],
+    textStyle: {
+      fontSize: 15,
+    },
+  },
+  radar: {
+    radius: "55%",
+    center: ["50%", "56%"],
+    indicator: [
+      { name: "专注力平均值", max: 100 },
+      { name: "高专注占比", max: 100 },
+      { name: "专注唤醒效率", max: 100 },
+      { name: "整体和谐度", max: 100 },
+      { name: "专注力稳定度", max: 100 },
+    ],
+    axisName: {
+      color: "#4284f2",
+      fontSize: 15,
+    },
+  },
+  series: [
+    {
+      name: "训练前 vs 训练后",
+      type: "radar",
+      symbolSize: 8,
+      data: [
+        {
+          value: props.beforeData?.split(","),
+          name: "训练前",
+          label: {
+            show: true,
+            position: "right",
+            color: "#937dff",
+            fontSize: 12,
+            formatter: function (params) {
+              return params.value;
+            },
+          },
+          areaStyle: {
+            color: "rgba(147, 125, 255, .8)",
+          },
+        },
+        {
+          value: props.afterData?.split(","),
+          name: "训练后",
+          label: {
+            show: true,
+            position: "right",
+            color: "#ffb72d",
+            fontSize: 15,
+            formatter: function (params) {
+              return params.value;
+            },
+          },
+          areaStyle: {
+            color: "rgba(255, 183, 45, .5)",
+          },
+        },
+      ],
+    },
+  ],
+};
+
+onMounted(() => {
+  const chart = echarts.init(
+    document.getElementById(<string>props.id) as HTMLDivElement
+  );
+  chart.setOption(options);
+
+  window.addEventListener("resize", () => {
+    chart.resize();
+  });
+});
+</script>

+ 10 - 5
src/views/dashboard/index.vue

@@ -1,8 +1,8 @@
 <script setup lang="ts">
 import DataCard from "@/views/dashboard/components/DataCard.vue";
-import LiquidChart from "@/views/dashboard/components/LiquidChart.vue";
-import CircleChart from "@/views/dashboard/components/CircleChart.vue";
-import BarChart from "@/views/dashboard/components/BarChart.vue";
+import LiquidChart from "@/views/base-charts/LiquidChart.vue";
+import CircleChart from "@/views/base-charts/CircleChart.vue";
+import BarChart from "@/views/base-charts/BarChart.vue";
 defineOptions({
   // eslint-disable-next-line vue/no-reserved-component-names
   name: "DashboardIndex",
@@ -141,7 +141,9 @@ onMounted(() => {
                   width="200px"
                   color="#3a7fc2"
                   bg-color="#e4e7f4"
-                  class="chart"
+                  font-color="#3a7fc2"
+                  font-size="30"
+                  round-cap="true"
                 />
                 <p>初期训练</p>
                 <p>专注力50以上人数比例</p>
@@ -156,7 +158,9 @@ onMounted(() => {
                   width="200px"
                   color="#5563ac"
                   bg-color="#e4e7f4"
-                  class="chart"
+                  font-color="#5563ac"
+                  font-size="30"
+                  round-cap="true"
                 />
                 <p>近期训练</p>
                 <p>专注力50以上人数比例</p>
@@ -281,6 +285,7 @@ onMounted(() => {
   border: 1px solid #e8eaec;
   border-radius: 24px;
   text-align: center;
+  position: relative;
   .title {
     margin: 0;
     height: 78px;

+ 2 - 1
src/views/error-page/401.vue → src/views/error/401.vue

@@ -11,7 +11,8 @@ import { useRouter } from "vue-router";
 
 const state = reactive({
   errGif: new URL(`../../assets/401_images/401.gif`, import.meta.url).href,
-  ewizardClap: "https://wpimg.wallstcn.com/007ef517-bafd-4066-aae4-6883632d9646",
+  ewizardClap:
+    "https://wpimg.wallstcn.com/007ef517-bafd-4066-aae4-6883632d9646",
   dialogVisible: false,
 });
 

+ 0 - 0
src/views/error-page/404.vue → src/views/error/404.vue


+ 0 - 141
src/views/student/components/RadarChart.vue

@@ -1,141 +0,0 @@
-<!-- 圆形进度图 -->
-<template>
-  <div :id="id" :class="className" :style="{ height, width }" />
-</template>
-
-<script setup lang="ts">
-import * as echarts from "echarts";
-
-const props = defineProps({
-  id: {
-    type: String,
-    default: "radarChart",
-  },
-  data: {
-    type: Number,
-    default: 0,
-  },
-  className: {
-    type: String,
-    default: "",
-  },
-  width: {
-    type: String,
-    default: "160px",
-    required: true,
-  },
-  height: {
-    type: String,
-    default: "160px",
-    required: true,
-  },
-  color: {
-    type: String,
-    default: "#2f539b",
-    required: true,
-  },
-  bgColor: {
-    type: String,
-    default: "#e6e8f9",
-    required: true,
-  },
-});
-
-const options = {
-  title: {
-    text: "5D脑电数据模型",
-  },
-  color: "#ffb72d",
-  legend: {
-    right: 0,
-    data: ["训练前", "训练后"],
-  },
-  radar: {
-    radius: "65%",
-    indicator: [
-      {
-        name: "专注力平均值",
-        max: 100,
-      },
-      {
-        name: "高专注占比",
-        max: 100,
-      },
-      {
-        name: "专注唤醒效率",
-        max: 100,
-      },
-      {
-        name: "整体和谐度",
-        max: 100,
-      },
-      {
-        name: "专注力稳定度",
-        max: 100,
-      },
-    ],
-    // 点击事件
-    triggerEvent: true,
-    splitArea: {
-      show: true,
-      areaStyle: {
-        color: ["#FFFFFF", "#E6E6E6", "#FFFFFF", "#E6E6E6", "#FFFFFF"],
-        // 图表背景网格的颜色
-      },
-    },
-    axisLine: {
-      lineStyle: {
-        color: "#E6E6E6",
-      },
-    },
-    name: {
-      rich: {
-        a: {
-          color: "#333333",
-          fontSize: 10,
-          fontWeight: "400",
-          fontFamily: "Microsoft YaHei",
-        },
-        b: {
-          color: "#333333",
-          align: "center",
-          padding: 5,
-          fontSize: 10,
-        },
-      },
-      formatter: (a, b) => {
-        return `{a|${a}}\n{b}`;
-      },
-    },
-  },
-  series: [
-    {
-      name: "Budget vs spending",
-      type: "radar",
-      color: "#5470c6",
-      symbolSize: 3,
-      data: [
-        {
-          value: [20, 30, 15, 5, 10],
-          name: "训练前",
-        },
-        {
-          value: [78, 98, 56, 86, 65],
-          name: "训练后",
-        },
-      ],
-    },
-  ],
-};
-
-onMounted(() => {
-  const chart = echarts.init(
-    document.getElementById(<string>props.id) as HTMLDivElement
-  );
-  chart.setOption(options);
-
-  window.addEventListener("resize", () => {
-    chart.resize();
-  });
-});
-</script>

+ 79 - 7
src/views/student/result.vue

@@ -1,11 +1,15 @@
 <script setup lang="ts">
+import PieChart from "@/views/base-charts/PieChart.vue";
+
 defineOptions({
   name: "StudentResult",
   inheritAttrs: false,
 });
 import { watch } from "vue";
 import { useUserStore } from "@/store/modules/user";
-import RadarChart from "@/views/student/components/RadarChart.vue";
+import RadarChart from "@/views/base-charts/RadarChart.vue";
+import CircleChart from "@/views/base-charts/CircleChart.vue";
+import DoubleChart from "@/views/base-charts/DoubleChart.vue";
 const userStore = useUserStore();
 watch(
   () => userStore.schoolId,
@@ -42,17 +46,63 @@ watch(
       <el-col :xs="24" :sm="7" :md="7">
         <div class="box-card">
           <RadarChart
-            id="pieChart"
-            height="400px"
-            width="400px"
+            id="radarChart"
+            before-data="15,5,25,36,45"
+            after-data="78,88,65,82,65"
+            width="450px"
+            height="350px"
             class="chart"
-            bg-color=""
-            color=""
           />
         </div>
       </el-col>
       <el-col :xs="24" :sm="17" :md="17">
-        <div class="box-card"></div>
+        <div class="box-card">
+          <div class="chart-title">专注力脑电维度数据分析</div>
+          <el-row>
+            <el-col :xs="24" :sm="7" :md="7">
+              <div class="charts">
+                <CircleChart
+                  id="resultChart1"
+                  data="75"
+                  height="220px"
+                  width="220px"
+                  color="#4284f2"
+                  bg-color="#dadff0"
+                  font-color="#09132e"
+                  font-weight="normal"
+                  font-size="18"
+                  line-width="30"
+                />
+                <p>高专注力状态数据占比</p>
+              </div>
+            </el-col>
+            <el-col :xs="24" :sm="7" :md="7">
+              <div class="charts">
+                <DoubleChart
+                  id="doubleChart1"
+                  data="258"
+                  height="220px"
+                  width="220px"
+                  color="#4e68b0"
+                  bg-color="#d6daed"
+                />
+                <p>整体高专注力状态数据累计条数</p>
+              </div>
+            </el-col>
+            <el-col :xs="24" :sm="10" :md="10">
+              <div class="charts last">
+                <PieChart
+                  id="pieChart"
+                  data="12,18,20,28,22"
+                  width="400px"
+                  height="350px"
+                  class="chart"
+                  title="专注力分布"
+                />
+              </div>
+            </el-col>
+          </el-row>
+        </div>
       </el-col>
     </el-row>
   </div>
@@ -66,6 +116,7 @@ watch(
     background: #ffffff;
     border-radius: 30px;
     border: 1px solid #e6e8eb;
+    position: relative;
   }
   .result-title {
     width: 950px;
@@ -89,5 +140,26 @@ watch(
 }
 .result-chart {
   margin-top: 12px;
+  .chart-title {
+    position: absolute;
+    top: 20px;
+    left: 30px;
+    font-size: 18px;
+    color: #09132e;
+  }
+  .charts {
+    position: relative;
+    padding-top: 74px;
+    text-align: center;
+    &.last {
+      padding: 0;
+    }
+    .chart {
+      margin: 0 auto;
+    }
+    p {
+      margin: 5px 0 0 0;
+    }
+  }
 }
 </style>