在表格中根据行列数据显示进度图(使表格数据更直观)

先来看看展示效果

image.png

项目需求

  • 展示基础表格
  • 在每一列数据中,如果只有正值,则表格左侧为0坐标,以最大值为表格全部宽度,其他按照比例去展示
  • 有正负值,需要计算0坐标位置,根据最大值最小值去确定坐标位置,根据正负值展示图形
  • 负值图形颜色为红色,正值颜色根据外部传入参数确定颜色,默认蓝色

表格组件

<template>
  <div class="table-content-container">
    <div class="tableHeader">
      <div
        class="fontCommon"
        v-for="(item, index) in data.column"
        :key="index"
        :style="{'width': item.width + 'px','text-align': item.align ? item.align : 'left'}"
      >
        {{ item.name}}
      </div>
    </div>
    <div class="table-content" :style="'height:' + height + 'px'">
      <ul class="ul-scoll">
        <li
          v-for="(item, index) in data.data"
          :key="index"
          @click="handleRow(item, index)"
        >
          <div
            v-for="(list, i) in data.column"
            :key="i"
            :style="'width:' + list.width + 'px'"
          >
            <!--普通表格列-->
            <p
              v-if="list.text"
              class="text"
              :style="{
                    color: changeColor(list, item[list.prop], item),
                    'text-align': list.align ? list.align : 'left',
                  }"
            >
              {{ item[list.prop] }}
            </p>
            <!--包含图表的列-->
            <div
              v-else
              class="text"
              :style="{
                  color: changeColor(list, item[list.prop], item),
                  'text-align': list.align ? list.align : 'left',
                }"
            >
              {{ item[list.prop] || '-' }}
              <!--图形-->
              <div
                class="progress"
                :class="item[list.prop]<0?'red':list.chartClass?list.chartClass:'blue'"
                :style="getProgressStyle(list,item)"
              ></div>
            </div>
          </div>
        </li>
      </ul>
    </div>
  </div>
</template>
<script>
export default {
  name: 'tableContent',
  props: {
    data: {
      type: Object,
      default: () => {
        return {
          column: [],
          data: []
        };
      },
    },
    height: {
      type: Number,
      default: 400,
    },
    loading: {
      type: Boolean,
      default: false,
    }
  },
  watch: {
    data: {
      handler () {
        this.changeData()
      },
      deep: true,
      immediate: true
    }
  },
  mounted () {

  },
  methods: {
    changeData () {
      this.data.column.forEach((item, index) => {
        if (item.hasChart) {
          const arr = this.data.data.map(i => {
            return i[item.prop]
          })
          const maxNum = Math.max(...arr)
          const minNum = Math.min(...arr)
          item.maxNum = maxNum
          item.minNum = minNum
        }
      })
    },
    changeColor (list) {
      return list.color || '#DFDFE0'
    },
    getProgressStyle (list, item) {
      if (list.minNum < 0) {
        const minNum = Math.abs(list.minNum)
        const leftP = minNum / (minNum + list.maxNum)
        const fWidth = leftP * list.width
        const zWidth = list.width - fWidth
        if (Number(item[list.prop]) >= 0) {
          return `left:${ fWidth }px;width:${ Number(item[list.prop]) / list.maxNum * zWidth }px`
        } else {
          const itemW = Math.abs(item[list.prop]) / Math.abs(list.minNum) * fWidth
          return `left:${ fWidth - itemW }px;width:${ itemW }px`
        }
      } else {
        return `left:0;width:${ Number(item[list.prop]) / list.maxNum * list.width }px`
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.table-content-container {
  .tableHeader {
    width: 100%;
    display: flex;
    align-items: center;
    .fontCommon {
      color: #DFDFE0;
      font-size: 14px;
      line-height: 44px;
      border-top: 1px solid #ccc;
      border-right: 1px solid #ccc;
      &:nth-of-type(1) {
        padding-left: 10px;
        border-left: 1px solid #ccc;
      }
    }
  }
  .table-content {
    overflow-y: scroll;
    width: 102%;
    position: relative;
    ul {
      width: 98.2%;
      li {
        width: 100%;
        height: 44px;
        display: flex;
        flex-direction: row;
        &:nth-last-of-type(1) {
          > div {
            border-bottom: 1px solid #ccc;
          }
        }
        > div {
          border-top: 1px solid #ccc;
          border-right: 1px solid #ccc;
          &:nth-of-type(1) {
            padding-left: 10px;
            border-left: 1px solid #ccc;
          }
        }
        .text {
          font-size: 14px;
          color: #cccccc;
          line-height: 44px;
          height: 44px;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
          position: relative;
          padding-right: 6px;
          .progress {
            position: absolute;
            top: 0;
            height: 44px;
            z-index: 1;
            &.red {
              background: linear-gradient(to right, #e75e5e, rgba(231, 94, 94, 0.2));
            }
            &.blue {
              background: linear-gradient(to right, #5eb9e3, rgba(94, 185, 227, 0.2));
            }
            &.origin {
              background: linear-gradient(to right, #e79e5e, rgba(231, 158, 94, 0.2));
            }
            &.green {
              background: linear-gradient(to right, #78db67, rgba(120, 219, 103, 0.2));
            }
          }
          &.pointer {
            cursor: pointer;
          }
        }
      }
    }
  }
  ::-webkit-scrollbar {
    width: 4px;
  }
  ::-webkit-scrollbar-track {
    background: transparent;
    border-radius: 0;
  }
  ::-webkit-scrollbar-thumb {
    background: #475e8f;
    border-radius: 2px;
  }
}
@keyframes loading {
  0% {
    transform: rotate(0);
  }
  50% {
    transform: rotate(180deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>

传入的参数样式

data参数示例:

data:{
  column: [  //表头列明,和列的规则
    {
      name: "分析项目",
      prop: "name",
      width: 140,
      text: true
    },
    {
      name: "入库税金(万元)",
      prop: "value1",
      width: 160,  //列宽
      hasChart: 'true', //是否展示图形
      chartClass: 'origin', //图形正数据的颜色
      align: 'right'   //列文字居左还是居右
    },
    {
      name: "利息(%)",
      prop: "value2",
      width: 160,
      hasChart: 'true',
      chartClass: 'green',
      align: 'right'
    },
    {
      name: "总营业额(万元)",
      prop: "value3",
      width: 160,
      hasChart: 'true',
      chartClass: 'blue',
      align: 'right'
    }
  ],
  data: [
    {
      name: '央行借款',
      value1: 100,
      value2: 0,
      value3: 1000,
    },
    {
      name: '央行借款',
      value1: -20,
      value2: -55,
      value3: 5555
    },
    {
      name: '央行借款',
      value1: 20,
      value2: 23,
      value3: 1937,
    },
    {
      name: '央行借款',
      value1: -50,
      value2: 40,
      value3: 400
    }
  ]
}
  • 表头属性

     name: 表头名称,
      prop:列数据对应的参数名,
      width: 160,  //列宽
      hasChart: 'true', //列是否展示图形
      chartClass: 'origin', //列图形正数据的颜色
      align: 'right'   //列文字居左还是居右
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容