单独图表组件的开发 --- 热销商品占比(饼图)

Posted So istes immer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单独图表组件的开发 --- 热销商品占比(饼图)相关的知识,希望对你有一定的参考价值。

目录

效果预览

通用代码结构和流程

图表基本功能实现

数据的获取:/api/hotproduct,获取的是三个类别下所有分类的数据
数据的处理:饼图的数据(name、value)、图例的数据
图表的设置:type类型为pie

切换数据的实现

布局和样式:左右两个箭头
点击事件的处理:改变currentIndex,分类名称:计算属性

UI调整

主题的使用:init第二个参数
箭头和分类名称的颜色: css
标题的设置:title
高亮状态显示文字:emphasis
图例的形状和位置:legend
工具提示:tooltip 显示子分类数据

分辨率适配

标题的文字大小
饼图的文字大小
图例的大小
箭头和分类名称的大小 

components/Hot.vue

<template>
  <div class="com-container">
    <div class="com-chart" ref="hot_ref"></div>
    <span class="iconfont arr-left" @click="toLeft" :style="comStyle">&#xe6eb;</span>
    <span class="iconfont arr-right" @click="toRight" :style="comStyle">&#xe6ee;</span>
    <span class="cat-name" :style="comStyle">{{ catName }}</span>
  </div>
</template>

<script>
export default {
  data () {
    return {
      chartInstance: null,
      allData: null,
      currentIndex: 0, // 当前所展示出的一级分类数据
      titleFontSize: 0
    }
  },
  computed: {
    catName () {
      if (!this.allData) {
        return ''
      } else {
        return this.allData[this.currentIndex].name
      }
    },
    comStyle () {
      return {
        fontSize: this.titleFontSize + 'px'
      }
    }
  },
  mounted () {
    this.initChart()
    this.getData()
    window.addEventListener('resize', this.screenAdapter)
    this.screenAdapter()
  },
  destroyed () {
    window.removeEventListener('resize', this.screenAdapter)
  },
  methods: {
    initChart () {
      this.chartInstance = this.$echarts.init(this.$refs.hot_ref, 'chalk')
      const initOption = {
        title: {
          text: '▎ 热销商品的占比',
          left: 20,
          top: 20
        },
        legend: {
          top: '15%',
          icon: 'circle'
        },
        tooltip: {
          show: true,
          formatter: arg => {
            const thirdCategory = arg.data.children
            let total = 0
            thirdCategory.forEach(item => {
              total += item.value
            })
            let retStr = ''
            thirdCategory.forEach(item => {
              retStr += `
              ${item.name}:${parseInt(item.value / total * 100) + '%'}
              </br>
              `
            })
            return retStr
          }
        },
        series: [
          {
            type: 'pie',
            label: {
              show: false
            },
            emphasis: {
              label: {
                show: true
              },
              labelLine: {
                show: false
              }
            }
          }
        ]
      }
      this.chartInstance.setOption(initOption)
    },
    async getData () {
      // 获取服务器的数据,对this.data进行赋值之后,调用updateChart方法更新图表
      const { data: ret } = await this.$http.get('hotproduct')
      this.allData = ret
      this.updateChart()
    },
    updateChart () {
      // 处理图表需要的数据
      const legendData = this.allData[this.currentIndex].children.map(item => {
        return item.name
      })
      const seriesData = this.allData[this.currentIndex].children.map(item => {
        return {
          name: item.name,
          value: item.value,
          children: item.children
        }
      })
      const dataOption = {
        legend: {
          data: legendData
        },
        series: [
          {
            data: seriesData
          }
        ]
      }
      this.chartInstance.setOption(dataOption)
    },
    screenAdapter () {
      this.titleFontSize = this.$refs.hot_ref.offsetWidth / 100 * 3.6
      const adapterOption = {
        title: {
          textStyle: {
            fontSize: this.titleFontSize / 2
          }
        },
        legend: {
          itemWidth: this.titleFontSize / 2,
          itemHeight: this.titleFontSize / 2,
          itemGap: this.titleFontSize / 2,
          textStyle: {
            fontSize: this.titleFontSize / 2
          }
        },
        series: [
          {
            radius: this.titleFontSize * 4.5,
            center: ['50%', '60%']
          }
        ]
      }
      this.chartInstance.setOption(adapterOption)
      this.chartInstance.resize()
    },
    toLeft () {
      this.currentIndex--
      if (this.currentIndex < 0) {
        this.currentIndex = this.allData.length - 1
      }
      this.updateChart()
    },
    toRight () {
      this.currentIndex++
      if (this.currentIndex > this.allData.length - 1) {
        this.currentIndex = 0
      }
      this.updateChart()
    }
  }
}
</script>

<style>
.arr-left {
  position: absolute;
  left: 10%;
  top: 50%;
  cursor: pointer;
  color: white;
}
.arr-right {
  position: absolute;
  right: 10%;
  top: 50%;
  cursor: pointer;
  color: white;
}
.cat-name {
  position: absolute;
  left: 80%;
  bottom: 20px;
  color: white;
}
</style>

views/HotPage.vue 

<template>
  <div class="com-page">
    <hot></hot>
  </div>
</template>

<script>
import Hot from '../components/Hot.vue'
export default {
  components: {
    hot: Hot
  }
}
</script>

<style>
</style>

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import SellerPage from '../views/SellerPage'
import TrendPage from '../views/TrendPage'
import MapPage from '../views/MapPage'
import RankPage from '../views/RankPage'
import HotPage from '../views/HotPage'

Vue.use(VueRouter)

const routes = [
  {
    path: '/sellerpage',
    component: SellerPage
  },
  {
    path: '/trendpage',
    component: TrendPage
  },
  {
    path: '/mappage',
    component: MapPage
  },
  {
    path: '/rankpage',
    component: RankPage
  },
  {
    path: '/hotpage',
    component: HotPage
  }
]

const router = new VueRouter({
  routes
})

export default router

以上是关于单独图表组件的开发 --- 热销商品占比(饼图)的主要内容,如果未能解决你的问题,请参考以下文章

Tableau 图表大全19之饼图(常用于占比)

首页热销爆品开发修改商品值

单独图表组件的开发 --- 销售排行图表

单独图表组件的开发---销量趋势图表(折线图)

单独图表组件的开发---商家销售统计(横向柱状图)

美观实用的环形图,提升数据表达效果