vue3中,echarts使用(四)02——柱状图之堆叠条形图-定制化 & 封装切换tag标签组件 & 封装title组件
效果
代码
1、主页面
index.vue
<template> <div class="topTen-box"> <titleHeader :title="title"> <template #right> <PitChecked @handle-button="handleChangePit"></PitChecked> </template> </titleHeader> <div class="topTen-data"> <div class="topTen-chart"> <BarChartTen :series-list="dataList" :color-index="kindIndex" :colors="colors" :x-list="xList"></BarChartTen> </div> <div class="topTen-control"> <div class="item" v-for="(item, index) in kinds" :label="index" :key="index" @click="handleChangeKind(item, index)"> <b :style="{ background: item == kindName ? colorList[kindIndex] : '' }"></b> <span>{
{ item }}</span> </div> </div> </div> </div> </template> <script setup lang="ts" name="topTen"> import titleHeader from "@/components/header/titleHeader.vue"; import PitChecked from "../components/pitChecked.vue"; import { ref, onMounted } from "vue"; import BarChartTen from "../components/barChartTen.vue"; const title = ref("月度部门休假分析TOP101"); // 颜色列表 const colors = ref(["#adb9c766", "#adb9c766", "#adb9c766"]); // 选择查看的请假类型下标 const kindIndex = ref(0); // 选择查看的的请假类型 const kindName = ref("事假"); // 所有的类型list const kinds: any = ["事假", "年假", "其他", "丧假", "工伤", "探亲假", "计生假", "产假", "婚假", "休假"]; const colorList = ["#0075FF", "#00D1FF", "#FF5D5D", "#FFB443", "#FFF736", "#B1FF81", "#5AFF7F", "#00FFBB", "#A25EFF", "#FF8743"]; // 假设top队伍 x轴数据 const xList = ref([ "综合一队", "综合十队", "综合二队", "综合五队", "综合九队", "综合三队", "综合四队", "综合六队", "综合十二队", "综合十五队" ]); // console.log(xList); // 事假 年假 其他 丧假 工伤 探亲假 计生假 产假 婚假 休假 // 原始数据 === const data = [ { name: "综合一队", data: [1, 2, 3, 2, 3, 1, 3, 0, 0, 0] }, { name: "综合十队", data: [0, 0, 0, 2, 3, 1, 2, 1, 1, 2] }, { name: "综合二队", data: [2, 3, 0, 4, 0, 2, 0, 1, 2, 1] }, { name: "综合五队", data: [2, 1, 2, 0, 0, 0, 4, 2, 1, 2] }, { name: "综合九队", data: [1, 2, 0, 0, 0, 3, 4, 2, 3, 1] }, { name: "综合三队", data: [0, 2, 0, 0, 0, 3, 4, 2, 3, 1] }, { name: "综合四队", data: [0, 0, 0, 0, 0, 3, 4, 2, 3, 1] }, { name: "综合六队", data: [0, 0, 0, 0, 0, 3, 4, 2, 3, 1] }, { name: "综合十二队", data: [0, 0, 0, 0, 0, 3, 4, 2, 3, 1] }, { name: "综合十五队", data: [1, 0, 0, 0, 0, 3, 4, 2, 0, 1] } ]; // 数据图表中拥有几项 const chartsNum = ref(0); // 经过划分处理后的数据 const newData: any = ref([]); // 渲染图表所使用的数据 const dataList: any = ref([]); // 将数据整理为需要的格式 const disposeData = () => { // 清空渲染数据 dataList.value = []; // 判断当前选中请假类型 let kindIndex = kinds.indexOf(kindName.value); // console.log(kindName.value, kindIndex); // 整合其余假期数据 【目标,其他】 // A B C 三段 // 1、 A --> 1 , B , C --> 2 -- n // 2、A --> 1 -- n , B , C --> n // 3、 A --> 1 -- B , B --> B , C --> B -- n newData.value = data.map(item => { let a = 0, b = 0, c = 0; if (kindIndex == 0) { item.data.map((_num, _index) => { _index ? (c += _num) : (a = _num); }); } else if (kindIndex == kinds.length - 1) { item.data.map((_num, _index) => { _index < kinds.length - 1 ? (a += _num) : (c = _num); }); } else { item.data.map((_num, _index) => { if (_index < kindIndex) { a += _num; } else if (_index == kindIndex) { b = _num; } else if (_index > kindIndex) { c += _num; } }); } return { name: item.name, data: [a, b, c], a, b, c }; }); // 三段 chartsNum.value = 3; // 组合图表需要的数据 for (let i = 0; i < chartsNum.value; i++) { let arr: any[] = []; newData.value.map((item: { data: any }) => { arr.push(item.data[i]); }); // console.log(arr); let sName = ""; // let sRadius: any[] = []; i == 1 ? (sName = kindName.value) : (sName = "假期" + i); // sRadius = [ // [5, 0, 0, 5], // [0, 0, 0, 0], // [0, 5, 5, 0] // ]; dataList.value.push({ name: sName, type: "bar", stack: "total", label: { show: false }, itemStyle: { normal: { // barBorderRadius: sRadius[i] barBorderRadius: [0, 0, 0, 0] } }, data: arr }); } setColors(colorList[kindIndex]); }; // 设置图表渲染颜色 const setColors = (color: string) => { if (kindIndex.value == 0) { colors.value = [color, "#adb9c766", "#adb9c766"]; } else if (0 < kindIndex.value && kindIndex.value < kinds.length - 1) { colors.value = ["#adb9c766", color, "#adb9c766"]; } else { colors.value = ["#adb9c766", "#adb9c766", color]; } }; // 初始化表格 const initData = () => { kindName.value = "事假"; kindIndex.value = 0; disposeData(); }; // 点击改变选择查看的类型 const handleChangeKind = (item: string, index: number) => { kindName.value = item; kindIndex.value = index; disposeData(); }; // 井上井下选择 const handleChangePit = (value: any) => { console.log(value); }; onMounted(() => { initData(); }); </script> <style scoped lang="scss"> .topTen-data { height: calc(100% - 48px); display: flex; .topTen-chart { flex: 1; } .topTen-control { flex: 1; max-width: 80px; display: flex; flex-flow: column; padding: 10px 0 20px; .item { flex: 1; color: #ffffff; font-size: 12px; cursor: pointer; > b { display: inline-block; width: 12px; height: 12px; border-radius: 4px; background: rgba(173, 185, 199, 0.3); margin-right: 6px; } } } } </style>
2、引入的title组件
src\components\header\titleHeader.vue
<template> <div class="header-container"> <div class="title-img"> <!-- title文字 --> <span>{
{ props.title }}</span> <!-- title单选 --> <slot name="right"></slot> <!-- title图片 --> <img @click="isDialog" class="header" :src="props.src" v-show="props.src != ''" /> </div> <div class="mark"> <slot name="mark" /> </div> </div> </template> <script lang="ts" setup> const props = defineProps({ src: { type: String, required: false, default: "" }, title: { type: String, required: true, default: "" } }); // 展示弹框 const emit = defineEmits(["is-dialog"]); const isDialog = () => { emit("is-dialog", ""); }; </script> <style lang="scss" scoped> .header-container { padding: 24px 24px 6px; .title-img { display: flex; font-family: "PingFang SC"; font-size: 22px; color: rgb(255 255 255 / 100%); align-items: center; > span { margin-right: auto; } > img { cursor: pointer; margin-left: 24px; height: 20px; } } } </style>
3、切换tag标签组件
src\views\attendance\components\pitChecked.vue
<template> <div class="pitChecked-box"> <span v-for="item in buttonList" :class="typeIndex == item.value ? 'active' : ''" @click="handleButton(item.value)" :key="item.value" >{
{ item.key }} </span> </div> </template> <script setup lang="ts" name="pitChecked"> import { ref } from "vue"; const buttonList = [ { value: 0, key: "全部" }, { value: 1, key: "井上" }, { value: 2, key: "井下" } ]; const emit = defineEmits(["handleButton"]); const typeIndex = ref(0); const handleButton = (value: any) => { typeIndex.value = value; emit("handleButton", buttonList[value]); }; </script> <style scoped lang="scss"> .pitChecked-box { display: flex; > span { display: flex; justify-content: center; align-items: center; padding: 0 10px; border-radius: 4px; background: rgba(0, 0, 0, 0.2); color: #fff; font-family: PingFang SC; font-size: 12px; margin-left: 8px; cursor: pointer; } .active { background: rgba(0, 117, 255, 1); } } </style>
4、堆叠条形图-定制版
src\views\attendance\components\barChartTen.vue
<template> <div ref="echartsRef" class="content-box"></div> </template> <script setup lang="ts"> import { ref, nextTick, watch, onMounted } from "vue"; import { useEcharts } from "@/hooks/useEcharts"; import * as echarts from "echarts"; // import { dataWrap } from "@/utils/util"; const props = defineProps({ seriesList: { type: Array<Object>, required: true, default: () => { return []; } }, xList: { type: Array<String>, required: true, default: () => { return ["其他"]; } }, colorIndex: { type: Number, required: true, default: 0 }, colors: { type: Array<any>, required: true, default: () => { return []; } } }); watch( () => [props.seriesList], (now, old) => { console.log(now, old); console.log(props.seriesList); console.log(props.colors); nextTick(() => { chartsView(); }); } ); const colorList = ["#0075FF", "#00D1FF", "#FF5D5D", "#FFB443", "#FFF736", "#B1FF81", "#5AFF7F", "#00FFBB", "#A25EFF", "#FF8743"]; const echartsRef = ref<HTMLElement>(); const chartsView = () => { let myChart: echarts.ECharts = echarts.init(echartsRef.value as HTMLElement); let option: echarts.EChartsCoreOption = { color: props.colors, tooltip: { show: true, axisPointer: { type: "shadow" // 'shadow' as default; can also be 'line' or 'shadow' }, trigger: "axis", backgroundColor: "rgba(0, 0, 0, 1)", borderColor: "rgba(0, 0, 0, 1)", padding: [16, 24], textStyle: { color: "#fff" }, formatter: (params: any) => { // console.log(params); // 打印数据 let ele: string = ``; ele += `<div style="font-size:16px;margin-bottom:5px;">${params[0].name}</div>`; for (let i = 0; i < params.length; i++) { if (params[i].data > 0) { ele += `<div style="display:flex;align-items: center;height:30px;font-size:12px;"><div style="width: 8px;height: 8px;background: ${colorList[i]};border-radius: 50%;margin-right: 10px;"></div>${params[i].seriesName}<div style="font-size:20px;font-weight:bold;color:${colorList[i]};margin:0 0px 0 10px;">${params[i].data}</div>人</div>`; } } return ele; } }, legend: { show: false }, grid: { containLabel: true, x: 30, y: 10, x2: 30, y2: 20 }, xAxis: { type: "value", splitLine: { //分割线配置 show: true, lineStyle: { color: "rgba(64, 94, 134, .3)", width: 1 } } }, yAxis: { type: "category", data: props.xList, axisTick: { show: false // 不显示坐标轴刻度线 }, axisLine: { lineStyle: { type: "solid", color: "rgb(64, 94, 134)", width: "1" } }, axisLabel: { // formatter: (params: any) => { // return dataWrap(params, 3); // }, textStyle: { color: "#ADB9C7", fontSize: 11 } } }, series: props.seriesList }; useEcharts(myChart, option); }; onMounted(() => { nextTick(() => { chartsView(); }); }); </script> <style scoped lang="scss"></style>
到此这篇vue3中,echarts使用(四)02——柱状图之堆叠条形图-定制化 & 封装切换tag标签组件 & 封装title组件的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/qdvuejs/10860.html