封装的组件
(gantt-chart/index.vue)文章来源地址https://www.toymoban.com/news/detail-518681.html
<template>
<div class="ganttChartClass">
<!-- 顶部标题 -->
<div class="topTitle">
<div style="position:relative" :style="{ width: leftTitleWidth + 'px' }">
<div style="font-size: 12px;margin-left:58px;margin-top:-10px;">年份</div>
<div class="diagonalLine"></div>
<div style="font-size: 12px;margin-left:-54px;margin-top:-30px;">项目</div>
</div>
<div v-for="(item, i) in props.data.title" :key="i"
:style="{ width: 'calc(' + '( 100% - ' + leftTitleWidth + 'px)' + ' * (1 / ' + props.data.title.length + ')' + ')' }">
{{ item }}年
</div>
</div>
<div v-for="(item, i) in props.data.data" :key="i" class="content">
<!-- 左侧标题 -->
<div :style="{ width: leftTitleWidth + 'px' }" class="leftTitle">
<!-- 只有一级题目 -->
<!-- <div>
{{ item.title }}
</div> -->
<div style="display:flex;width:100%;height:100%;text-align: center;">
<!-- 一级题目 -->
<div style="display: flex;justify-content: center;align-items: center;font-size: 16px;"
:style="{ width: item.children[0].subTitle === '' ? '100%' : '40%', paddingRight: item.children[0].subTitle === '' ? '10px' : '0px' }"
class="firstTitleArea">
<div style="display:inline-block;text-align:left;">
{{ item.title }}
</div>
</div>
</div>
</div>
<div
:style="{ width: 'calc(' + '( 100% - ' + leftTitleWidth + 'px)' + ' * (1 / ' + props.data.title.length + ')' + ')' }">
<!-- {{item}} -->
<!-- <div style="height:100%;width:20px;background:red;position: relative;z-index:20;">
</div> -->
<div v-for="(item2, i2) in item.children" :key="i2"
style="width:100%;display: flex;justify-content: flex-start;">
<!-- 二级标题展示 -->
<div style="width:0px;">
<div style="width:84px;height:100%;position:relative;left:-84px;align-items: center;justify-content: center;padding:0 5px; color: #585D79;font-size: 14px;font-weight:600;"
:style="{ borderTop: (0 === i2) ? 'none' : '1px solid #FFE1C5',display:item2.subTitle===''?'none':'flex' }" >
{{ item2.subTitle }}
</div>
</div>
<div style="width:100%;">
<div v-for="(item3, i3) in item2.children" :key="i3" class="lineRow"
style="display:flex;width:100%;">
<div v-for="(ele2, index2) in item3" :key="index2" style="width:100%;flex-shrink:0">
<!-- 这行是占位 -->
<div :style="{ width: 'calc(' + ele2.width + ' - 1px)', background: lineDrawArr[index2 % 4] }"
style="height:100%;position: relative;visibility: hidden;" class="lineDraw">
{{ ele2.name }}
</div>
<!-- 这行才是真正显示 -->
<div :style="{ width: 'calc(' + ele2.width + ' - 1px)', left: ele2.left, background: lineDrawArr[index2 % 4] }"
style="display:flex;align-items:center;justify-content:center;" class="lineDraw">
<div style="text-align:left;display: inline-block;">
{{ ele2.name }}
</div>
</div>
</div>
<div></div>
</div>
</div>
<div></div>
</div>
<div></div>
</div>
<div v-for="item5 in props.data.title.length - 1"
:style="{ width: 'calc(' + '( 100% - ' + leftTitleWidth + 'px)' + ' * (1 / ' + props.data.title.length + ')' + ')' }">
</div>
</div>
</div>
</template>
<script setup lang='ts'>
import { ref } from 'vue'
let props = defineProps<{ data: any }>()
let leftTitleWidth = ref(150)
let lineDrawArr = ['#E4EFFF', '#F3F37E', '#FFDED7', '#CBEEEA']
</script>
<style lang="less" scoped>
@bg: #FEF9F3;
@borderColor: #FFE1C5;
.ganttChartClass {
box-sizing: border-box;
overflow: hidden;
border: 1px solid @borderColor;
border-right: 0px;
.content {
display: flex;
flex-wrap: wrap;
border-top: 1px dashed @borderColor;
&:nth-child(2) {
border-top: 1px solid @borderColor;
}
.leftTitle {
display: flex;
align-items: center;
justify-content: center;
font-weight: 600;
padding: 10px;
padding-right: 0px;
background: @bg;
color: #252631;
.firstTitleArea {
position: relative;
&:after {
display: block;
content: '';
height: calc(100% + 20px);
width: 1px;
background: @borderColor;
position: absolute;
right: 0;
}
}
}
&>div {
position: relative;
// border-right: 1px solid blue;
&::after {
display: block;
content: '';
position: absolute;
height: 100%;
width: 1px;
background: @borderColor;
right: 0;
top: 0;
}
.lineRow {
// height: 30px;
margin-top: 10px;
margin-bottom: 10px;
position: relative;
.lineDraw {
text-align: center;
// line-height: 30px;
z-index: 5;
position: absolute;
padding: 5px 20px;
top: 0;
height: 100%;
.lineDrawText {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
color: #585D79;
font-size: 14px;
&:hover {
cursor: pointer;
}
}
}
}
}
}
.topTitle {
display: flex;
flex-wrap: wrap;
background: @bg;
color: #CE8D51;
&>div {
display: inline-block;
text-align: center;
border-right: 1px solid @borderColor;
height: 50px;
line-height: 50px;
overflow: hidden;
.diagonalLine {
width: 200px;
border-bottom: 1px solid @borderColor;
transform: rotate(17.9deg);
transform-origin: 0 0;
position: absolute;
z-index: 5;
top: 0;
left: 0;
}
}
}
div {
box-sizing: border-box;
}
}
</style>
甘特图组件使用
<template>
<div style="padding:100px;width:80%;">
<GanttChart :data="data"></GanttChart>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import GanttChart from './components/gantt-chart/index.vue'
let data = ref({
data: [
{
title: '1级标题',
children:
[
{
subTitle: '',
children: [
[
{
width: '50%', // 这是占一个列宽度的百分比
left: '150%', // 这是从第一列起,向右移动第一列宽度的百分比
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法' // 这个就是我们展示的文字了
},
{
width: '100%',
left: '200%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
],
[
{
width: '100%',
left: '0%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢...'
},
{
width: '100%',
left: '100%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏rewqtr'
},
{
width: '100%',
left: '200%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性rweqrwqe'
},
]
]
},
]
},
{
title: '1级标题',
children:
[
{
subTitle: '二级标题',
children: [
[
{
width: '50%',
left: '150%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
{
width: '100%',
left: '0%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
],
[
{
width: '100%',
left: '0%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢...'
},
{
width: '100%',
left: '100%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏rewqtr'
},
{
width: '100%',
left: '200%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性rweqrwqe'
},
]
]
},
{
subTitle: '222二级标题',
children: [
[
{
width: '100%',
left: '50%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
{
width: '100%',
left: '200%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病...'
},
{
width: '100%',
left: '200%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
],
[
{
width: '100%',
left: '50%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
{
width: '100%',
left: '200%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
]
]
},
]
}
,
{
title: '11111级标题',
children:
[
{
subTitle: '二级标题',
children: [
[
{
width: '50%',
left: '0%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
{
width: '50%',
left: '50%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
{
width: '50%',
left: '100%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
{
width: '50%',
left: '150%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
{
width: '50%',
left: '200%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
{
width: '50%',
left: '250%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
],
[
{
width: '100%',
left: '50%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
{
width: '100%',
left: '200%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
]
]
},
{
subTitle: '222二级标题',
children: [
[
{
width: '100%',
left: '50%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂疾病及慢性病仍缺乏有效治疗方法'
},
{
width: '60%',
left: '200%',
name: '肿瘤、心脑血管疾病、遗传病等...'
},
],
[
{
width: '20%',
left: '30%',
name: '肿瘤、心脑血管疾病、212312'
},
{
width: '100%',
left: '200%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂4231'
},
{
width: '60%',
left: '100%',
name: '肿瘤、心脑血管疾病、遗传病等许多复杂gerg'
},
]
]
},
]
}
,
]
,
title: [
'2017-2020',
'2021-2025',
'2026-2030'
]
})
</script>
<style lang="less">
</style>
文章来源:https://www.toymoban.com/news/detail-518681.html
到了这里,关于vue3 手写甘特图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!