使用vue 画了一个甘特图,如图所示,目前想支持横向滚动,但是试了之后都不行。

image.png
测试数据为6年的跨度,目前接口中年份跨度较长,需要横向滚动,这里该怎么处理好呢。

<template>
  <div class="skip-chart">
    <div class="chart-header">
      <span v-for="(item,index) of yearList" :key="index" :style="{width: yearWidth + '%'}">{{item}}</span>
    </div>
    <div class="chart-body">
      <el-scrollbar style="height:100%;" class="el-menuscrollbar">
        <div v-for="(item, index) of data" :key="index" class="chart-body__content">
          <div class="chart-body__label">{{item.label}}</div>
          <skip-bar :startStep="item.startStep" :endStep="item.endStep" :yearWidth="yearWidth"></skip-bar>
          <div class="chart-detail" v-for="(item,index) of yearList" :key="index" :style="{width: yearWidth + '%', height: '100%'}">
            <div></div>
          </div>
        </div>
      </el-scrollbar>
    </div>
  </div>
</template>
<script>
import skipBar from './skipBar';

export default {
  name: 'skipChart',
  components: {
    skipBar,
  },
  props: {
    skipList: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      // 测试6年的跨度
      yearList: [2016, 2017, 2018, 2019, 2020, 2021, 2022],
      // 测试数据
      data: [
        {
          label: '项目1项目1项目1',
          startStep: 2017.8,
          endStep: 2019.9,
        },
        {
          label: '项目2项目2项目2',
          startStep: 2017.3,
          endStep: 2019.6,
        },
        {
          label: '项目3项目3项目3',
          startStep: 2016.4,
          endStep: 2018.6,
        },
        {
          label: '项目4项目4项目4',
          startStep: 2018.6,
          endStep: 2021.9,
        },
        {
          label: '项目5项目5项目5',
          startStep: 2016.4,
          endStep: 2019.1,
        },
        {
          label: '项目6项目6项目6',
          startStep: 2017.6,
          endStep: 2021.9,
        },
        {
          label: '项目2项目2项目2',
          startStep: 2017.3,
          endStep: 2019.6,
        },
        {
          label: '项目3项目3项目3',
          startStep: 2016.4,
          endStep: 2018.6,
        },
        {
          label: '项目1项目1项目1',
          startStep: 2017.8,
          endStep: 2019.9,
        },
        {
          label: '项目2项目2项目2',
          startStep: 2017.3,
          endStep: 2019.6,
        },
        {
          label: '项目2项目2项目2',
          startStep: 2017.3,
          endStep: 2019.6,
        },
        {
          label: '项目2项目2项目2',
          startStep: 2017.3,
          endStep: 2019.6,
        },
        {
          label: '项目2项目2项目2',
          startStep: 2017.3,
          endStep: 2019.6,
        },
      ],
    };
  },
  computed: {
    yearWidth() {
      return (100 / this.yearList.length);
    },
  },
};
</script>
<style lang="scss">
.skip-chart {
  width: 100%;
  height: 100%;
  color: #fff;
  font-size: 12px;
  .chart-header {
    height: 30px;
    line-height: 30px;
    width: calc(100% - 125px);
    margin-left: 125px;
    padding-right: 20px;
    display: flex;
    flex-wrap: nowrap;
    span {
      text-align: center;
      display: inline-block;
    }
  }
  .chart-body {
    width: 100%;
    height: calc(100% - 40px);
    padding-bottom: 20px;
    .chart-body__content {
      width: 100%;
      height: 30px;
      line-height: 30px;
      display: flex;
      flex-wrap: nowrap;
      position: relative;
      .chart-body__label {
        min-width: 125px;
      }
      .chart-detail {
        position: relative;
        z-index: 8;
        &>div{
          width: 1px;
          height: 100%;
          background-color: #0166B5;
          position: absolute;
          left: 50%
        }
      }
      .skip-bar {
        position: absolute;
        z-index: 9;
        top: 50%;
        transform: translateY(-50%);
        width: calc(100% - 135px);
        margin-left: 125px;
      }
    }
  }
}
</style>
<style lang="scss">
.el-scrollbar__thumb {
  background-color: #3e97f6;
}
</style>

// 子组件

<template>
  <div class="skip-bar" :style="{'padding-left': yearWidth/2 +'%', 'padding-right': yearWidth/2 +'%'}">
    <el-tooltip placement="top" effect="light">
      <div slot="content">
        <span>项目跨度:{{`${startStep}~${endStep}`}}</span>
      </div>
      <div class="skip-bar-content" :style="{left: startOffest+'%', width: stepLength + '%'}">
        <div class="start-step step">
        </div>
        <div class="step-line">
        </div>
        <div class="end-step step">
        </div>
      </div>
    </el-tooltip>
  </div>
</template>
<script>
export default {
  name: 'skipBar',
  props: {
    startStep: {
      type: Number,
    },
    endStep: {
      type: Number,
    },
    yearWidth: {
      type: Number,
    },
  },
  data() {
    return {
      startYear: 2016,
      endYear: 2022,
    };
  },
  computed: {
    startOffest() {
      const splitWidth = 100 / (this.endYear - this.startYear);
      const startleftOffest = (this.startStep - this.startYear) * splitWidth;
      return startleftOffest;
    },
    stepLength() {
      const splitWidth = 100 / (this.endYear - this.startYear);
      const length = splitWidth * (this.endStep - this.startStep);
      return length;
    },
  },
};
</script>
<style lang="scss">
.skip-bar {
  width: 100%;
  height: 32px;
  line-height: 32px;
  .skip-bar-content {
    position: relative;
    height: 8px;
    display: flex;
    flex-wrap: nowrap;
    align-items:center;
    top: 50%;
    transform: translateY(-50%);
    .start-step {
      background-color: #006CFF;
    }
    .end-step {
      background-color: #F15D07;
    }
    .step-line {
      width: calc(100% - 16px);
      height: 2px;
      background-color: #fff;
    }
    .step {
      width: 8px;
      height: 8px;
      border-radius: 50%;
    }
  }
}
</style>
阅读 3.7k
1 个回答

相当牛逼,异步的话,建议给个箭头之类的,每次点击刷新数据,模拟滚动行不行?同步就简单了,直接把 div 宽度设置到需要的数值,所有数据堆上去不就完了?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题