实现的最终效果:
三个要求:
- 显示每道题总的答题人数
- 显示每道题每个选项的答题人数
- 显示每道题每个选项答题人数所占比例,并反映到柱子长度和颜色上
完整代码示例:
<template>
<div
:id="topicIndexS"
:style="{ width: '480px', height: '400px' }"
></div>
</template>
<script setup>
import * as echarts from "echarts";
import { reactive, ref, onMounted } from "vue";
onst topicIndexS = 1; // 任意值即可
const topicJsonS = topicJson; // topicJson指的是自己的要渲染的数据
// 我的数据为(topicJsonS ):
// {
// data: {id: 13, title: "投票4投票4", warning: "这是一个warning",…}
// active: true
// appid: "1"
// created_at: "2022-05-01T09:01:27.000Z"
// description: "<p><b>投票4投票4票</b>4投票<u>4投票4票4投票</u>4投票</p>"
// endDate: null
// id: 13
// image: "https://cdn.mededutv.com/res/runyi/case/2022/05/01/cb1ec2ea-480c-406c-9471-4b48db8e1690.jpg"
// number_of_participants: 20
// question: [{id: 24, vote_id: 13, question_type: 2,…},…]
// 0: {id: 24, vote_id: 13, question_type: 2,…}
// appid: "1"
// created_at: "2022-05-01T09:01:59.000Z"
// id: 24
// num: 43
// options: [{id: 40, question_id: 24, title: "热热热热热若若若11111", appid: "1", sort_no: 1, num: 20,…},…]
// question_type: 2
// sort_no: 1
// title: "嗯嗯呃呃呃呃呃嗯嗯呃呃呃呃呃嗯嗯呃呃呃呃呃嗯嗯呃呃呃呃呃嗯嗯呃呃呃呃呃嗯嗯呃呃呃呃呃嗯嗯呃呃呃呃呃嗯嗯呃呃呃呃呃"
// updated_at: "2022-05-01T09:01:59.000Z"
// vote_id: 13
// 1: {id: 23, vote_id: 13, question_type: 1, title: "投票4投票4投票4票4投票4投票222222票4投票4投票33333票4投票4投票", sort_no: 2,…}
// appid: "1"
// created_at: "2022-05-01T09:01:47.000Z"
// id: 23
// num: 23
// options: [{id: 37, question_id: 23, title: "请求请求群群群群22222222", appid: null, sort_no: 1, num: 16,…},…]
// question_type: 1
// sort_no: 2
// title: "投票4投票4投票4票4投票4投票222222票4投票4投票33333票4投票4投票"
// updated_at: "2022-05-01T09:01:47.000Z"
// vote_id: 13
// result: 2
// startDate: null
// timeSetting: false
// title: "投票4投票4"
// updated_at: "2022-05-11T09:49:37.000Z"
// user_id: 1
// voterule: 2
// warning: "这是一个warning"
// err: 0
// msg: "ok"
// }
const filterLetters = (i) => {
if (i >= 0 && i <= 25) {
return String.fromCharCode(65 + i);
} else {
return undefined;
}
};
const getPercent = (num, total) => {
num = parseFloat(num);
total = parseFloat(total);
if (isNaN(num) || isNaN(total)) {
return "";
}
return total <= 0 ? "0%" : Math.round((num / total) * 100) / 1 + "%";
};
onMounted(() => {
let TwoMatrix = [["amount", "product", "Percent"]];
let numList = [];
let total_num = 0;
// 每个选项用户的选择
for (let i = 0; i < topicJsonS.options.length; i++) {
total_num = total_num + topicJsonS.options[i].num;
}
if(total_num==0){
return false
}
// 判断没有itemList用户没有答题
for (let i = 0; i < topicJsonS.options.length; i++) {
topicJsonS.options[i]["englishOrder"] = filterLetters(i);
let aList = [
topicJsonS.options[i].num,
filterLetters(i),
getPercent(topicJsonS.options[i].num, total_num),
];
numList.push(topicJsonS.options[i].num);
TwoMatrix.push(aList);
}
console.log("得到二维矩阵为:", TwoMatrix);
let myChart = echarts.init(document.getElementById(topicIndexS));
// 绘制图表
let optionDIY = {
title: { text: " 投票人数: " + topicJsonS.num },
dataset: {
source: TwoMatrix,
},
legend: {
height: 10,
},
grid: { containLabel: true },
xAxis: { name: "" },
yAxis: { type: "category" },
visualMap: {
orient: "horizontal",
left: "center",
min: Math.min.apply(0, numList),
max: Math.max.apply(0, numList),
text: ["High ticket ", "Low ticket "],
// Map the score column to color
dimension: 0,
inRange: {
color: ["#65B581", "#FFCE34", "#FD665F"],
},
},
series: [
{
type: "bar",
barWidth: 43,
label: {
fontSize: 15,
fontWeight: "bold",
stack: "samestack",
position: "insideLeft",
formatter: (params) => {
return " " + params.value[params.encode.x[0]] + "人" + " " + params.value.pop();
},
show: true,
},
encode: {
// Map the "amount" column to X axis.
x: "amount",
// Map the "product" column to Y axis
y: "product",
},
},
],
};
myChart.setOption(optionDIY);
window.onresize = function () {
//自适应大小
myChart.resize();
};
});
</script>