基于 Highcharts 实现 Vue 中的答题统计柱状图组件

在现代 Web 开发中,数据可视化是一个重要的组成部分,而 Highcharts 是一个广泛使用的 JavaScript 图表库,可以帮助开发者在 Web 页面上轻松地绘制丰富的图表。在本文中,我们将基于 Highcharts 创建一个用于答题统计的柱状图,并在 Vue.js 中进行集成。我们的目标是通过一个 Vue 组件显示答题正确数和错误数的柱状图,图表会根据外部数据进行动态更新。

1. 项目结构与需求分析

首先,需求是实现一个显示答题统计的柱状图。这个图表将有两个数据系列------正确答案数和错误答案数。每个题型(如单选、多选、判断等)将作为 X 轴的分类,而 Y 轴将表示每个题型的答对和答错的数量。为了满足这些需求,我们将使用 Highcharts 来生成图表,并通过 Vue.js 作为容器,管理和渲染数据。

效果:

2. 创建 Vue 组件

我们将首先创建一个 Vue 组件,该组件通过 chartData 属性接收外部传入的数据。这些数据包含了每个题型的答对和答错的数量。组件的结构包括图表容器以及用于初始化图表的 JavaScript 逻辑。

2.1. template 部分

html 复制代码
    <template>
      <!-- 图表容器 -->
      <div id="questionAnsweringStatistics"></div>
    </template>

template 部分,我们创建了一个简单的容器 div,用来放置生成的图表。Highcharts 会将图表渲染到这个 div 中。

2.2. script 部分

base 复制代码
    import Highcharts from 'highcharts'

这行代码导入了 Highcharts 库,它是用来绘制图表的核心库。这里我们通过 import 语法导入 Highcharts,以便在组件中使用。

2.3. props 定义部分

js 复制代码
    props: {
      chartData: {
        type: Array,
        default: () => [ // 定义些一些假数据,展示使用
          {
            questionType: "1",
            rightNums: [1, 0, 0],
            nums: [3, 0, 0]
          },
          {
            questionType: "2",
            rightNums: [2, 0, 0],
            nums: [4, 0, 0]
          },
          {
            questionType: "3",
            rightNums: [0, 1, 0],
            nums: [0, 2, 0]
          },
          {
            questionType: "4",
            rightNums: [0, 2, 0],
            nums: [0, 2, 0]
          },
          {
            questionType: "5",
            rightNums: [0, 1, 0],
            nums: [0, 1, 0]
          },
          {
            questionType: "6",
            rightNums: [0, 0, 0],
            nums: [2, 0, 1]
          }
        ]
      }
    }
  • props 用来接收父组件传递的数据,这里的 chartData 是一个数组,包含题目类型的统计数据(rightNumsnums)。
  • chartData 是一个必须传递的数组,它包含了题目类型的统计信息。这样可以灵活地将不同的数据传递给图表组件进行动态渲染。
  • default 设置了默认值,以便便展示,一般设为空数组。如果父组件没有传递 chartData,则会使用这个默认数据来渲染图表。此数据格式与实际应用中的结构一致:rightNums 表示答对的题目数,nums 表示总题目数。

2.4. watch 监听 chartData 变化:

js 复制代码
    watch: {
      chartData: {
        handler(newVal) {
          newVal && this.initChart(newVal); // 数据变化时重新初始化图表
        },
        deep: true
      }
    }
  • watch 用来监听 chartData 的变化,确保当父组件传递的数据发生变化时,我们能及时更新图表。
  • handler(newVal) 是一个回调函数,每当 chartData 更新时,它会被调用并传入新值 newVal,然后重新调用 initChart 渲染图表。
  • deep: true 是为了确保能够检测到对象内部属性的变化,防止 chartData 中的嵌套数据发生改变时无法触发更新。

2.5. mounted 生命周期钩子:

js 复制代码
    mounted() {
      this.chartData && this.initChart(this.chartData); // 组件挂载时初始化图表
    }
  • mounted 中,我们检查是否存在 chartData(即数据是否已传递到组件),如果存在则调用 initChart 方法初始化图表。
  • initChart 方法会将 chartData 数据传递进去,渲染图表。

2.6. processData 数据处理方法:

js 复制代码
    processData(data) {
      let name = [], error = [], success = []; // 题目类型,错误数,正确数

      data.forEach(item => {
        const totalQuestions = item.nums.reduce((pre, cur) => pre + cur, 0); // 总问题数
        if (totalQuestions > 0) {
          name.push(this.questionTypeFilter(item.questionType));  // 转换题目类型
          error.push(totalQuestions - item.rightNums.reduce((pre, cur) => pre + cur, 0)); // 计算错误数
          success.push(item.rightNums.reduce((pre, cur) => pre + cur, 0)); // 计算正确数
        }
      });

      return { name, error, success }; // 返回处理后的数据
    }
  • processData 是数据预处理的核心函数。它对 chartData 中的每个数据项进行处理,提取出图表需要的数据。
  • name: 存储每个题型的名称(如"单选题"、"判断题"等)。这个名称来自 questionTypeFilter 方法的转换。
  • errorsuccess: 分别存储每个题型的错误数和正确数。通过对 rightNumsnums 数组的累加计算得出。
  • reduce 是用来对数组求和的常用方法,这里通过它来计算每个题型的总数和正确数量。
  • 最终返回一个对象,包含 name, error, success,这三项数据是后续 Highcharts 渲染的基础。

2.7. questionTypeFilter 方法:

js 复制代码
questionTypeFilter(num) {
  const typeMap = {
    '1': '单选',
    '2': '多选',
    '3': '判断',
    '4': '阅文解答',
    '5': '问答题',
    '6': '填空题',
  };

  return typeMap[String(num)] || '未知类型'; // 默认为未知类型
}
  • questionTypeFilter 方法用于将题型编号转换为题型名称(例如,"1" 转换为 "单选")。
  • typeMap 是一个映射对象,将题型编号与其对应的名称进行映射。
  • String(num) 将传入的 num 转为字符串类型,因为 typeMap 的键是字符串类型的。
  • 如果传入的题型编号没有匹配到 typeMap 中的任何键,则返回 '未知类型'

2.8. initChart 图表初始化:

js 复制代码
initChart(data) {
  const { name, error, success } = this.processData(data); // 获取处理后的数据

  if (this.chart) {
    this.chart.destroy(); // 销毁旧的图表实例
  }

  const chartOptions = {
    chart: {
      type: 'column', // 设置柱状图类型
      backgroundColor: 'transparent', // 背景透明
      height: 380, // 图表高度
    },
    title: {
      text: '答题正确数', // 图表标题
      align: 'left',
      y: this.fontSize * 0.8, // 微调标题位置
      style: {
        fontSize: `${this.fontSize * 0.8}px`,
        fontWeight: 'bold', // 标题加粗
      },
    },
    xAxis: {
      categories: name, // X轴显示题目类型
      tickWidth: 0,
      lineColor: '#999', // 设置X轴线条颜色
      labels: {
        style: {
          fontSize: `${this.fontSize * 0.6}px`, // 设置X轴标签字体大小
        },
      },
    },
    yAxis: {
      min: 0, // Y轴从0开始
      title: { enabled: false }, // 关闭Y轴标题
      gridLineColor: '#999', // 设置网格线颜色
    },
    legend: {
      align: 'right',
      verticalAlign: 'top',
      floating: true, // 图例浮动
      itemStyle: {
        fontSize: `${this.fontSize * 0.6}px`, // 设置图例字体大小
      },
    },
    plotOptions: {
      column: {
        cursor: 'pointer', // 鼠标悬浮显示小手
        stacking: 'normal', // 堆叠柱状图
        dataLabels: {
          enabled: true, // 启用数据标签
          style: {
            textOutline: 'none', // 去掉文字外框
            fontSize: `${this.fontSize * 0.6}px`, // 设置数据标签字体大小
          },
        },
      },
    },
    series: [
      {
        name: '错误',
        color: 'rgb(247, 163, 92)', // 错误答案的颜色
        data: error, // 错误数据
      },
      {
        name: '正确',
        color: 'rgb(124, 181, 236)', // 正确答案的颜色
        data: success, // 正确数据
      },
    ],
    credits: { enabled: false }, // 禁用版权信息
    exporting: { enabled: false }, // 禁用导出功能
  };

  this.chart = Highcharts.chart('questionAnsweringStatistics', chartOptions); // 渲染图表
}
  • initChart 方法用于初始化并渲染 Highcharts 图表。图表的配置项被详细定义在 chartOptions 中。

  • 首先,通过 this.processData(data) 获取处理后的数据,包括题目类型名称、正确数和错误数。

  • 如果已有图表实例(this.chart)存在,先销毁旧的图表实例,避免在页面中存在多个图表实例。

  • 图表配置项(chartOptions)包括了:

    • type: 'column':指定图表类型为柱状图。
    • title:设置图表标题及样式。
    • xAxis:设置 X 轴,显示题型名称(name)。
    • yAxis:设置 Y 轴,显示正确数和错误数。
    • legend:设置图例(正确、错误),以及图例样式。
    • series:设置数据系列,这里定义了两组数据:错误正确,分别对应 errorsuccess 数组。
  • 最后,通过 Highcharts.chart() 方法将配置项应用到图表,并渲染到页面中的 #questionAnsweringStatistics 容器中。

3. 总结:

代码的核心是通过 Highcharts 渲染动态柱状图,关键部分包括:

  • 数据预处理processData)和 题型转换questionTypeFilter),确保传递给图表的数据格式正确。
  • 图表初始化initChart),通过 Highcharts 配置项精细控制图表样式和显示效果。
  • 数据更新处理watchmounted),确保当数据发生变化时,图表能及时更新。
相关推荐
一路向前的月光8 分钟前
react(9)-redux
前端·javascript·react.js
大数据追光猿35 分钟前
Python中的Flask深入认知&搭建前端页面?
前端·css·python·前端框架·flask·html5
莫忘初心丶37 分钟前
python flask 使用教程 快速搭建一个 Web 应用
前端·python·flask
xw51 小时前
Trae初体验
前端·trae
横冲直撞de1 小时前
前端接收后端19位数字参数,精度丢失的问题
前端
我是哈哈hh1 小时前
【JavaScript进阶】作用域&解构&箭头函数
开发语言·前端·javascript·html
摸鱼大侠想挣钱1 小时前
ActiveX控件
前端
谢尔登1 小时前
Vue 和 React 响应式的区别
前端·vue.js·react.js
后端小肥肠1 小时前
【AI编程】Java程序员如何用Cursor 3小时搞定CAS单点登录前端集成
前端·后端·cursor
酷酷的阿云1 小时前
Vue3性能优化必杀技:useDebounce+useThrottle+useLazyLoad深度剖析
前端·javascript·vue.js