时间轴组件

时间轴组件:
在这里插入图片描述

<template>
  <div class="timeline-container">
    <h5>套餐详情</h5>
    <div style="display: inline-block">
      <!-- 事件轴 -->
      <div class="scaleline-container">
        <div class="year-container" v-for="(item,indexYear) in lineData.length" :key="indexYear">
          <!-- {
    
    {
    
    `${
      
      minYear + indexYear}`}} -->
          <div class="m-container">
           <div class="month-container" v-for="(item,index) in loopYear(item)" :key="index">
            <div class="name">{
    
    {
    
    `${
      
      minYear + indexYear}${
      
      index +1}`}}</div>
            <div class="name1">
              <div v-for="(item,index) in item" class="line" :key="index"></div>
            </div>
           </div>
          </div>
        </div>
      </div>
      <!-- 边缘线 -->
      <div class="margin-container">
        <div class="no-active" :style="{width: '30%'}"></div>
        <div class="active" :style="{width: '70%'}"></div>
      </div>
      <!-- 今天 -->
      <div class="today-container">
        <div class="before" :style="{width: today+'%'}"></div>
        <div class="triangle"></div>
        <div class="text">{
    
    {
    
    '今天'}}</div>
      </div>
      <!-- 套餐 -->
      <div class="package-container" v-for="(item,index) in packageList" :key="index">
        <div class="prefix-container" :style="{width: item.before+'%'}"></div>
        <div class="content-container">
          <span class="title">
            <span>{
    
    {
    
    `总数: ${
      
      item.channelNum}`}}</span>
          <span>{
    
    {
    
    `(${
      
      item.startTime}&nbsp;&nbsp;${
      
      item.endTime})`}}</span>
          </span>
          
        </div>
        <div class="suffix-container" :style="{width: item.after+'%'}"></div>
      </div>
    </div>
  </div>
</template>
<script>
import moment from 'moment';
const DAY31 = [30,28,30,29,31,29,31,31,29,31,29,31];
const DAY30 = [30,27,30,30,31,30,31,31,30,31,30,31];
const COMPONENT_NAME = 'timeLine';
export default {
    
    
  name: COMPONENT_NAME,
  props: {
    
    
     packageDetail: {
    
    
      type: Array,
      default: () => ([
        {
    
    
          channelNum: 999999,
          endTime: 1678530041000,
          packageType: 3,
          startTime: 1617287134582,
          status: 0
        },
        {
    
    
        channelNum: 50,
        endTime: 1657849440428,
        packageType: 3,
        startTime: 1655257440428,
        status: 2
       },
       {
    
    
        channelNum: 8,
        endTime: 4102329600000,
        packageType: 1,
        startTime: 1655256659902,
        status: 0
       },{
    
    
        channelNum: 50,
        endTime: 1657849440428,
        packageType: 3,
        startTime: 1655257440428,
        status: 2
       },
       {
    
    
        channelNum: 8,
        endTime: 4102329600000,
        packageType: 1,
        startTime: 1655256659902,
        status: 0
       },{
    
    
        channelNum: 50,
        endTime: 1657849440428,
        packageType: 3,
        startTime: 1655257440428,
        status: 2
       },
       {
    
    
        channelNum: 8,
        endTime: 4102329600000,
        packageType: 1,
        startTime: 1655256659902,
        status: 0
       },
       {
    
    
        channelNum: 50,
        endTime: 1657849440428,
        packageType: 3,
        startTime: 1655257440428,
        status: 2
       },
       {
    
    
        channelNum: 8,
        endTime: 4102329600000,
        packageType: 1,
        startTime: 1655256659902,
        status: 0
       }
      ])
    },
  },
  data() {
    
    
    return {
    
    
      // 套餐
      packageList: [],
      // 最大日期
      maxDate: '',
      maxYear: 0,
      maxMonth: 0,
      maxDay: 0,
      // 最小日期
      minDate: '',
      minYear: 0,
      minMonth: 0,
      minDay: 0,
      // 画多少年?
      manyYear: 0,
      // 刻度线数据
      lineData: [],
      // 总长
      total: 0,
      // 今天
      today: new Date().getTime()
    };
  },
  computed: {
    
     
      
  },
  watch: {
    
    
      
  },
  created() {
    
    
    this.handleData();
    this.handleScaleLine()
  },
  methods: {
    
    
    handleData() {
    
    
      let max = this.packageDetail[0]['endTime'];
      let min = this.packageDetail[0]['startTime'];
      this.packageDetail.forEach( item => {
    
    
        if(item['endTime'] > max ) {
    
    
          max = item['endTime']
        }
        if(item['startTime'] < min) {
    
    
          min = item['startTime']
        }
       this.packageList.push({
    
    
        channelNum: item.channelNum,
        endTime: moment(item['endTime']).format('YYYY-MM-DD HH:mm'),
        packageType: item.packageType,
        startTime: moment(item['startTime']).format('YYYY-MM-DD HH:mm'),
        status: item.status
       });
      })
      
      this.maxDate = moment(max).format('YYYYMMDD')
      this.maxYear = Number(this.maxDate.slice(0,4))
      this.maxMonth = Number(this.maxDate.slice(4,6))
      this.maxDay =  Number(this.maxDate.slice(6,8))

      this.minDate = moment(min).format('YYYYMMDD')
      this.minYear = Number(this.minDate.slice(0,4))
      this.minMonth = Number(this.minDate.slice(4,6))
      this.minDay =  Number(this.minDate.slice(6,8))

      this.total = new Date(`${
      
      this.maxYear}-12-31`).getTime() - new Date(`${
      
      this.minYear}-01-01`).getTime()
      this.today =  ((new Date().getTime() - new Date(`${
      
      this.minYear}-01-01`)) / this.total) * 100

      this.manyYear = (this.maxYear - this.minYear) + 1
      this.handlePackage()
    },
    // 润平年?
    howYear(year) {
    
    
      if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
    
    
        return true // 闰年
      }
      return false // 平年
    },
    // 刻度线
    handleScaleLine() {
    
    
      for (let index = 0; index < this.manyYear; index++) {
    
    
        this.lineData.push(this.howYear(this.minYear+index))
     }
    },
    // 循环那一年的月
    loopYear(flag) {
    
    
      return flag ? DAY31: DAY30
    },
    // 给每个套餐加比例
    handlePackage() {
    
    
      this.packageList.forEach(item => {
    
    
        item.before = ((new Date(item.startTime.slice(0,10)).getTime() - new Date(`${
      
      this.minYear}-01-01`).getTime()) / this.total ) * 100
        item.after = ((new Date(`${
      
      this.maxYear}-12-31`).getTime() - new Date(item.endTime.slice(0,10)).getTime() ) / this.total ) * 100
      })
    }
  }
  
};
</script>
<style scoped lang="less">
.timeline-container {
    
    
  width: 800px;
  height: 200px;
  border: 1px solid #000;
  overflow: auto;
  h5 {
    
    
    margin: 0;
    opacity: 0.7;
    font-family: MicrosoftYaHeiUI;
    font-size: 14px;
    color: #000000;
    letter-spacing: 0;
    line-height: 20px;
    font-weight: 400;
  }
  .scaleline-container {
    
    
    display: inline-block !important;
    height: 28px;
    white-space: nowrap;
    .year-container {
    
    
      display: inline-block !important;
      height: 28px;
      .m-container {
    
    
        display: inline-block !important;
        height: 28px;
      }
      .month-container {
    
    
        height: 28px;
        display: inline-block !important;
        // background-color: antiquewhite;
        border-left: 0.67px solid rgba(151,151,151,1);
        margin-left: 3.5px;
        &:first-child {
    
    
          margin-left: 0;
        }
        .name {
    
    
          font-family: PingFangSC-Regular;
          font-size: 12px;
          color: rgba(0,0,0,.3);
          text-align: center;
          // background-color: aqua;
        }
        .name1 {
    
    
          height: 12px;
          font-family: PingFangSC-Regular;
          font-size: 12px;
          color: rgba(0,0,0,.3);
          // background-color: red;
        }
        .line {
    
    
          display: inline-block;
          height: 100%;
          width: 1px;
          margin-left: 3.5px;
          background-color: rgba(151,151,151,0.3);
        }
      }
      &:last-child {
    
    
       .month-container:last-child {
    
    
        border-right: 0.67px solid rgba(151,151,151,1);
        .line:last-child {
    
    
          display: none;
        }        
       }
      }
    }
  }
  .margin-container {
    
    
      margin-top: -5px;
      height: 10px;
      display: flex;
      .no-active {
    
    
        background: #CACACA;
      }
      .active {
    
    
        background: #9CBDE6;
      }
  }
  .today-container {
    
    
     height: 16px;
     display: flex;
    .before {
    
    
      // background: #f60;
    }
    .triangle {
    
    
      margin-left: -6px;
      width: 12px;
      height: 12px;
      box-sizing: border-box;
      border-top:  6px solid transparent;
      border-left:  6px solid transparent;
      border-right:  6px solid transparent;
      border-bottom:  6px solid rgb(0, 0, 0);
    }
    .text {
    
    
      margin-left: 4px;
      font-family: PingFangSC-Regular;
      font-size: 12px;
      color: #000000;
      letter-spacing: 0;
      font-weight: 400;
    }
  }
  .package-container {
    
    
    height: 24px;
    margin-top: 9px;
    display: flex;
    font-family: PingFangSC-Regular;
    font-size: 12px;
    color: #FFFFFF;
    letter-spacing: 0;
    font-weight: 400;
    &:first-child {
    
    
      margin-top: 19px;
    }
    .content-container {
    
    
      flex: 1;
      width: 2px;
      line-height: 24px;
      padding-left: 6px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow:ellipsis;
      background: #455EEC;
      .title {
    
    
        span:last-child {
    
    
        margin-left: 8px;
      }
      }
    }
  }
}
</style>

猜你喜欢

转载自blog.csdn.net/weixin_43131046/article/details/125811135