js,css手写甘特图

甘特图实现代码

<template>  
<div class="box">
  <!-- 头部筛选框 -->
  <div class="boxTitle">
    <div></div>
    <div></div>
    <div class="plantSelect">
      <c-date-picker
        style="width:120px"
        @change="getCalendarData"
        v-model="data.year"
        format='yyyy' value-format='yyyy'
        type="year">
      </c-date-picker>
      <div class="kong"></div>
      <c-select style="width:180px" v-model="data.workshop" @change="getCalendarData"  multiple>
        <c-option key="ASSEMBLY" value="ASSEMBLY" label='Assembly' ></c-option>
        <c-option key="BIW" label='BIW' value="BIW" ></c-option>
      </c-select>
      <div class="kong"></div>
      <c-select style="width:220px" v-model="data.plant" @change="getCalendarData" multiple>
        <c-option
          v-for="plant in plantList"
          :key="plant"
          :value="plant"
        ></c-option>
      </c-select>
    </div>
  </div>
  <!-- 月份信息 -->
  <div class='gantt-title'>
    <div class="project-title">Project</div> 
    <div class="header">  
      <div class="month" v-for="(month,index) in months" :key="index">{{ month }}</div>  
    </div>
  </div>
  <!-- 甘特图实现 --> 
  <div class="gantt-chart">  
    <div class="project">
      <div class="project-item" v-for="(item) in projectList" :key="item">{{item}}</div>
    </div>
    <div class="gantt"> 
      <div class="chart-container-box">
        <div v-for="(item, index) in bars" :key="index" class="chart-container"> 
          <div class="gantt-item" v-for="(item,index) in months" :key='item+index'>
          </div> 
          <div    
            class="bar"
            v-for="(bar, index) in item"  
            :key="bar.buildPhase+index+bar.type" 
          >
            <div 
              v-if="bar.type === '0'"
              class="bar"
              :style="{   
                left: `${getleft(bar.start)}px`,   
                width: `${getwidth(bar.start,bar.end)}px`,  
              }">
              <span class="context">
                <span class="buildPhase">{{bar.buildPhase}}</span>
                <span class="time">{{getShowTime(bar.start)+' - '+getShowTime(bar.end)}}</span>
              </span>
              </div>
            <div 
              v-if="bar.type === '1'"
              class="dropbar"
              :style="{   
                left: `${getleft(bar.start)}px`,   
              }">
              <div class="drop"></div>
              <span class="buildPhase">{{bar.buildPhase}}</span>
              <span class="time">{{getShowTime(bar.start)}}</span>
            </div>
          </div>  
        </div> 
      </div>
    </div> 
  </div>  
</div>
</template>  
  
<script>  
import moment from 'moment';
import { removeDecimalH } from '@/utils/utils.js';//处理小数点方法
export default {  
  data() {  
    return {  
      months: [  
        'January',  
        'February',  
        'March',  
        'April',  
        'May',  
        'June',  
        'July',  
        'August',  
        'September',  
        'October',  
        'November',  
        'December'  
      ],  
      bars: [],
      projectList:[],  
      barWidth: 0, // 根据需要调整条形的宽度  
      data:{
        plant: ["33","44"],
        workshop: ["22","11"],
        year: "2023"
      },
      plantList: ['aa', 'bb', 'cc'],
    };  
  },
  created(){
    this.getCalendarData();
  },  
  mounted() { 
    //获取div宽度信息
    const header = this.$el.querySelector('.header'); 
    //计算每个格子的宽度
    this.barWidth = removeDecimalH(header.offsetWidth/this.months.length)
    //避免误差 重新设置宽度
    header.style.width = header.offsetWidth + 'px'; // 设置容器宽度为总宽度
    const chartContainer = this.$el.querySelector('.chart-container-box'); 
    console.log(header.offsetWidth + 'px')
    //设置甘特图div总体宽度
    chartContainer.style.width = `${header.offsetWidth}px`; // 设置容器宽度为总宽度  
  },
  methods: {  
    getCalendarData: _.debounce(function() {
      //获取数据
    }, 300),
    //获取元素位置
    getleft(start) {  
      let left = 0;
      const date = moment(start); 
      const month = date.month();
      const day = date.date();
      const daysInMonth = date.endOf("month").format("DD")
      
      left = removeDecimalH(month * this.barWidth+(day/daysInMonth*this.barWidth));
      return left;
    },
    //转换日期
    getShowTime(time){
      const date = moment(time); 
      return date.format("MM/DD") 
    },
    //获取元素宽度
    getwidth(start, end) {  
      let width = 0;
      let startwidth = 0;
      let endwidth = 0;
      const startdate = moment(start); 
      const enddata = moment(end); 
      const startmonth = startdate.month();
      const endmonth = enddata.month();
      const startday = startdate.date();
      const endday = enddata.date();
      const startdaysInMonth = startdate.endOf("month").format("DD")
      const enddaysInMonth = enddata.endOf("month").format("DD")
      if(endmonth - startmonth >=2){
        width = parseInt(removeDecimalH((endmonth - startmonth -2) *this.barWidth))
        startwidth = parseInt(removeDecimalH((1-startday/startdaysInMonth)*this.barWidth));
        endwidth = parseInt(removeDecimalH((endday/enddaysInMonth)*this.barWidth));
      }else if(endmonth - startmonth === 1){
        startwidth = parseInt(removeDecimalH((1-startday/startdaysInMonth)*this.barWidth));
        endwidth = parseInt(removeDecimalH((endday/enddaysInMonth)*this.barWidth));
      }else if(endmonth - startmonth === 0){
        let day = endday - startday;
        width = parseInt(removeDecimalH(day*(this.barWidth/startdaysInMonth)));
      }
      return width+startwidth+endwidth
    } 
  } 
};  
</script>  
  
<style lang="scss" scoped>
$header-height: 50px;
$item-height:50px;
$gantt-item-height:51px;
$bar-height:30px;
$back-color:  #F7F9FC; 
$border-color:#DBE2F6;
$bar-back-color:#D1E6FD;
.box{
  border-radius: 12px;
  height: 616px;
  background-color: $back-color;
}
.boxTitle{
  border-top-right-radius: 12px;
  border-top-left-radius: 12px;
  height: 60px;
  background-color: $back-color;
  display: flex;
  justify-content: space-between;
  >:nth-child(1){
    flex: 0 0 550px;
  }
  >:nth-child(2){
    flex: 1;
  }
  .plantSelect{
    flex: 0 0 550px;
    display: flex;
    padding: 10px;
    .kong{
      width: 10px;
    }
  }
}
.gantt-title{
  display: flex !important;  
  justify-content: space-between;  
  align-items: flex-start;  
  height: $gantt-item-height;
}
.gantt-chart {  
  display: flex !important;  
  justify-content: space-between;  
  align-items: flex-start;  
  width: 100%; /* 根据需要调整甘特图的宽度 */ 
  width: calc(100% - 8px);
  height: calc(100% - 110px);
  overflow-y: auto;
  padding-right: 8px;
  overflow-x: clip;
  
  border-bottom-right-radius: 12px;
  border-bottom-left-radius: 12px;
}  
.project{
  flex: 0 0 180px;
  
}
.project-title{
  flex: 0 0 180px;
  background-color: $back-color;
  text-align: center;
  line-height: $header-height;
  height: $header-height; /* 根据需要调整头部的height */ 
  border-bottom: 1px $border-color solid; 
}
.project-item{
  background-color: $back-color;
  text-align: center;
  line-height: $item-height;
  height: $item-height; /* 根据需要调整头部的height */ 
  border-bottom: 1px $border-color solid;
  border-right: 1px $border-color solid;
}
.gantt{
  flex: 1;
}
.header {  
  flex: 1;
  display: flex;  
  justify-content: space-between;  
  align-items: center;  
  height: $header-height; /* 根据需要调整头部的height */  
  background-color: $back-color; /* 根据需要调整头部的背景色 */  
  border-bottom: 1px $border-color solid; 
}  
.month {  
  font-weight: bold;  
  /* margin-right: 10px; 根据需要调整月份标签的间距 */ 
  flex: 1; 
  text-align: center;
}  
.chart-container { 
  position: relative; 
  width: 100%;
  display: flex;  
  align-items: flex-start;  
  height: $gantt-item-height; /* 根据需要调整条形的container高度 */  
  background-color: $back-color; /* 根据需要调整条形的container背景色 */
  
}  
.gantt-item{
  background-color: $back-color;
  height: $item-height; /* 根据需要调整头部的height */ 
  border-bottom: 1px $border-color solid;
  border-right: 1px $border-color solid;
  flex: 1;
}  
.bar {  
  top: 5px;
  display: flex; /* 使条形可伸缩 */  
  align-items: center; /* 使条形内的文本垂直居中 */  
  height: $bar-height; /* 根据需要调整条形的height */  
  background-color: $bar-back-color; /* 根据需要调整条形的背景色 */   
  border-radius: 10px; /* 根据需要调整条形的圆角 */ 
  position: absolute;  
}  
.dropbar{
  top: 5px;
  display: flex; /* 使条形可伸缩 */  
  align-items: center; /* 使条形内的文本垂直居中 */  
  height: $bar-height; /* 根据需要调整条形的height */  
  border-radius: 10px; /* 根据需要调整条形的圆角 */ 
  position: absolute;  
  .drop{
    height: 26px;
    width: 26px;
    background-image: url('~@/assets/images/diamond.png');
    background-repeat: no-repeat;
    background-size: 100% 100%;
  }
}
.buildPhase{
  font-weight: bold;
  padding: 0px 2px;
}
.context{
  white-space: nowrap;
}
</style>

原创代码,转发请注明出处

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 使用CSS代码绘制甘特图样式是通过利用CSS的样式属性和选择器来设置甘特图的外观和布局。 首先,我们可以使用CSS的盒子模型来设置甘特图的宽度、高度和边框等属性。例如,我们可以设置甘特图的宽度为500px,高度为300px,边框为1px实线,并给甘特图设置一个合适的背景色。 其次,我们可以利用CSS的定位属性来布局甘特图的各个任务栏。使用绝对定位或相对定位来设置左、上的距离,从而确定每个任务栏的位置。我们还可以使用CSS的宽度属性来设置每个任务栏的长度,从而表示任务的持续时间。 在样式方面,我们可以利用CSS的背景色或背景图片属性来区分不同类型的任务。通过为不同的任务栏设置不同的背景色或背景图片,可以直观地显示任务的类型。 此外,我们还可以使用CSS的其他样式属性,如字体大小、字体颜色、对齐方式等,来美化和调整甘特图的显示效果。例如,我们可以设置任务名称的字体大小和颜色,使其更加醒目。 最后,为了提高甘特图的可读性,我们还可以使用CSS的伪类选择器来设置鼠标悬停和选中效果。通过设置鼠标悬停时的样式,可以让用户在使用甘特图时有更好的交互体验。 总之,通过合理地使用CSS的样式属性和选择器,我们可以绘制出漂亮且有吸引力的甘特图样式,从而方便用户理解和管理项目的进度。 ### 回答2: 甘特图是一种项目管理工具,用于展示项目任务的时间安排和进度。使用CSS代码绘制甘特图样式可以实现自定义的外观效果,使其更加符合项目需求和视觉美感。 首先,我们可以利用CSS中的盒子模型和定位属性来创建甘特图的时间轴和任务条。通过设置div元素的宽度和高度,以及使用position属性控制元素的位置,我们可以绘制出一个简单的甘特图框架。 接下来,我们可以使用CSS的背景颜色或背景图片属性来给任务条添加不同的样式。根据任务的属性或进度,我们可以自定义任务条的颜色、渐变效果或阴影,以显示不同的状态。 此外,我们还可以利用CSS的伪元素和动画属性来为甘特图添加一些交互效果。例如,在任务条的基础上使用::before或::after 伪元素来添加箭头或标签,以增加可读性和易用性。我们还可以通过CSS的动画属性来实现任务条的平滑过渡效果或进度动画,提升用户体验。 最后,我们应该保持代码的可维护性和可复用性。可以使用CSS预处理器如Sass或Less来管理样式的变量、函数和混合器,使代码更具可读性和易于修改。此外,在编写CSS样式时,注重语义化和模块化也是很重要的,这样可以使代码更易于理解和维护。 总之,使用CSS代码绘制甘特图样式可以实现自定义的外观效果,使其更加符合项目需求和视觉美感。在设计甘特图样式时,考虑到交互效果、可维护性和可复用性等方面,能够使工具更加实用和易于扩展。 ### 回答3: 甘特图是一种项目管理工具,用于展示项目工作项的时间计划和进度。使用CSS代码可以绘制出不同样式的甘特图。 首先,我们可以使用CSS设置甘特图的背景颜色和边框样式,通过设置背景颜色、边框颜色和边框宽度,可以将甘特图的背景和边框样式化。 接下来,我们可以使用CSS设置甘特图中的不同工作项的样式。可以通过设置工作项的颜色、字体样式和大小,来区分不同的工作项。例如,可以用不同的颜色表示不同类型的工作项,比如蓝色表示开发任务,红色表示测试任务等。同时,还可以通过调整字体样式和大小来使甘特图更加清晰和易读。 此外,还可以使用CSS设置甘特图中的时间轴样式。可以通过设置时间轴的颜色、字体样式和大小,来增加甘特图的可读性。可以使用不同的颜色表示不同的时间段,比如将计划时间用灰色表示,实际时间用绿色表示等。 最后,我们还可以使用CSS设置甘特图中的进度样式。可以通过设置进度条的颜色、高度和宽度,来表示工作项的进度。可以使用不同的颜色表示不同的进度,比如将已完成的工作项用绿色表示,未完成的工作项用灰色表示等。 总而言之,使用CSS代码可以实现丰富多样的甘特图样式。通过设置背景颜色和边框样式、工作项样式、时间轴样式和进度样式,可以使甘特图更具吸引力和可读性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值