css绘制动态条状图

160 阅读2分钟

这个代码使用uni-app的,注意元素转换和css单位转换。

  1. 效果图


  2. 绘制注意点
      长度的计算公式

        // 条形长度计算公式:    // diff=max-min    // len = (n-min)/diff

      动画效果的实现使用 

    transition: width 0.5s linear;

      js先设置宽度初始值全部为0,运行完成后设置宽度结束值

     this.$nextTick(() => {      
       setTimeout(() => {        
         this.$set(this.localTrend, 'len', len)    
      }, 100)  
      })
  3. 数据格式和组件调用

      sortTrend: {          'key': ['18日', '1日', '1日', '1日', '1日', '1日', '30日'],          'val': [15, 1045, 37, 15, 455, 137, 15]        },
     <jdd-barchart :trend="sortTrend" unit-type="people" />
    

  4. 组件代码

    <template>  <view class="body">    <view v-if="startDrawing">      <view v-for="(item, index) in localTrend.val" :key="index" class="item">        <text class="x-axis">{{ localTrend.key[index] }}</text>        <text class="strip" :style="{ width:localTrend.len[index]}" />        <text class="tag">{{ localTrend.formatVal[index] }}</text>      </view>    </view>  </view></template><script>let len = []export default {  props: {    trend: {      type: Object,      default: () => {        return {          'key': ['1日'],          'val': [15]        }      }    },    unitType: {      type: String,      default: 'people'    }  },  data () {    return {      startDrawing: false,      localTrend: null    }  },  created () {    // 条形长度计算公式:    // diff=max-min    // len = (n-min)/diff    let formatVal = []    let lenInit = []    len = []    this.localTrend = JSON.parse(JSON.stringify(this.trend))    let { max, min, diff } = this.initial(this.localTrend.val)    // console.log(this.trend)    // console.log(max, min, diff)    this.localTrend.val.map(val => {      let itemval = this.unitType === 'people' ? val + '人' : ('¥' + val + (this.isFloat(val) ? '' : '.00'))      let itemlen = diff === 0 ? '0.00%' : ((val - min) / diff * 100).toFixed(2) + '%'      formatVal.push(itemval)      len.push(itemlen)      lenInit.push('0%')    })    this.$set(this.localTrend, 'formatVal', formatVal)    this.$set(this.localTrend, 'len', lenInit)    this.startDrawing = true    // 这里给宽度重新赋值    this.$nextTick(() => {      setTimeout(() => {        this.$set(this.localTrend, 'len', len)        // console.log(this.localTrend.len)      }, 100)    })  },  methods: {    isFloat (n) {      return n % 1 !== 0    },    initial (arr) {      let copyArr = [...arr]      let max, min, diff      copyArr.sort((a, b) => {        return a - b      })      min = copyArr[0]      max = copyArr[copyArr.length - 1]      diff = max - min      return { max, min, diff }    }  }}</script><style scoped lang="scss">.item{  display: flex;  align-items: center;  padding: 0 30rpx;  height: 45rpx;  font-size: 0;  text{    display: inline-block;  }}.x-axis{  line-height: 45rpx;  min-width: 50rpx;  padding-right: 15rpx;  text-align: right;  border-right: 2rpx solid rgba(185,186,190,1);  font-size:22rpx;  color:rgba(104,107,117,1);}.strip{  width:0%;  height:4rpx;  background:linear-gradient(-90deg,rgba(70,166,255,1),rgba(144,202,255,1));  border-radius:0px 2px 2px 0px;  overflow: hidden;  transition: width 0.5s linear;}.tag{  padding-left: 12rpx;  font-size:22rpx;  color:rgba(70,166,255,1);  flex-shrink:0;  opacity: 0;  animation:mymove 0.5s linear 0.6s;  animation-fill-mode:forwards;}@keyframes mymove{from { opacity: 0;} to { opacity: 1;}}</style>