在表格中显示线条图(兼容任何组件)

先来看看展示效果

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'   //列文字居左还是居右
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容